Skip to content

Commit

Permalink
Admin: Implement internal storage and translation CRUD and management
Browse files Browse the repository at this point in the history
  • Loading branch information
GeoffreyKarnbach authored and rekt-hard committed Oct 23, 2024
1 parent a9a9395 commit aa8b435
Show file tree
Hide file tree
Showing 35 changed files with 1,945 additions and 117 deletions.
6 changes: 6 additions & 0 deletions docker/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,9 @@ services:
depends_on:
- damap-fe
- damap-be

# Uncomment the following block to persist postgres data.
# volumes:
# - damap-db-data:/var/lib/postgresql/data
#volumes:
# damap-db-data:
Original file line number Diff line number Diff line change
Expand Up @@ -405,10 +405,19 @@ public void storageInformation() {
// written in section 5
if (!distVar.toString().isEmpty()) {
String storageDescription = "";
storageDescription =
internalStorageTranslationRepo
.getInternalStorageById(((Storage) host).getInternalStorageId().id, "eng")
.getDescription();
InternalStorageTranslation storageTranslation =
internalStorageTranslationRepo.getInternalStorageById(
((Storage) host).getInternalStorageId().id, "eng");

if (storageTranslation == null) {
storageTranslation =
internalStorageTranslationRepo
.getAllInternalStorageTranslationsByStorageId(
((Storage) host).getInternalStorageId().id)
.get(0);
}

storageDescription = storageTranslation.getDescription();
storageVar =
storageVar.concat(
distVar
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/org/damap/base/domain/InternalStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,7 @@ public class InternalStorage extends PanacheEntity {

@Column(name = "backup_location")
private String backupLocation;

@Column(name = "active")
private boolean active;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.damap.base.exception;

import jakarta.validation.ConstraintViolationException;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import java.util.List;
import java.util.Map;

@Provider
public class ConstraintViolationExceptionMapper
implements ExceptionMapper<ConstraintViolationException> {

@Override
public Response toResponse(ConstraintViolationException exception) {
// Extract the constraint violations and format them into a response-friendly structure
List<Map<String, String>> violations =
exception.getConstraintViolations().stream()
.map(
violation ->
Map.of(
"path", violation.getPropertyPath().toString(),
"message", violation.getMessage(),
"invalidValue", String.valueOf(violation.getInvalidValue())))
.toList();

// Create the response body with the violations
Map<String, Object> responseBody =
Map.of("exception", "ConstraintViolationException", "violations", violations);

// Build and return the response
return Response.status(Response.Status.BAD_REQUEST)
.entity(responseBody)
.type(MediaType.APPLICATION_JSON)
.build();
}
}
4 changes: 2 additions & 2 deletions src/main/java/org/damap/base/repo/InternalStorageRepo.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package org.damap.base.repo;

import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped;
import java.util.List;
import org.damap.base.domain.InternalStorage;
import org.damap.base.repo.base.RepoSearch;

/** InternalStorageRepo class. */
@ApplicationScoped
public class InternalStorageRepo implements PanacheRepository<InternalStorage> {
public class InternalStorageRepo implements RepoSearch<InternalStorage> {

/**
* getAll.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,30 @@ public InternalStorageTranslation getInternalStorageById(Long storageId, String
Parameters.with("storageId", storageId).and("languageCode", languageCode))
.firstResult();
}

public List<InternalStorageTranslation> getAllInternalStorageTranslationsByStorageId(
Long storageId) {
return list(
"select storage from InternalStorageTranslation storage"
+ " where storage.internalStorageId.id = :storageId ",
Parameters.with("storageId", storageId));
}

public boolean existsTranslationForStorageIdAndLanguageCode(Long storageId, String languageCode) {
return count("internalStorageId.id = ?1 and languageCode = ?2", storageId, languageCode) > 0;
}

public boolean existsTranslationForStorageIdAndLanguageCodeExceptId(
Long storageId, String languageCode, Long id) {
return count(
"internalStorageId.id = ?1 and languageCode = ?2 and id != ?3",
storageId,
languageCode,
id)
> 0;
}

public void deleteAllTranslationsForInternalStorage(Long storageId) {
delete("internalStorageId.id", storageId);
}
}
16 changes: 16 additions & 0 deletions src/main/java/org/damap/base/repo/StorageRepo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.damap.base.repo;

import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped;
import java.util.List;
import org.damap.base.domain.InternalStorage;
import org.damap.base.domain.Storage;

/** InternalStorageRepo class. */
@ApplicationScoped
public class StorageRepo implements PanacheRepository<Storage> {

public List<Storage> findByInternalStorageId(InternalStorage internalStorage) {
return list("internalStorageId", internalStorage);
}
}
55 changes: 55 additions & 0 deletions src/main/java/org/damap/base/repo/base/RepoSearch.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.damap.base.repo.base;

import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.ws.rs.core.MultivaluedMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public interface RepoSearch<T> extends PanacheRepository<T> {

// TODO: Add pagination
/**
* Search by parameters. Automatically generates a query based on the parameters and values in the
* query parameters.
*
* @param queryParams a {@link jakarta.ws.rs.core.MultivaluedMap} object, containing the attribute
* as key and the values as values in an array
* @return a {@link java.util.List} object, containing the results
*/
default List<T> searchByParameters(MultivaluedMap<String, Object> queryParams) {

StringBuilder query = new StringBuilder();

Map<String, Object> params = new HashMap<>();

int counter = 0;

for (Map.Entry<String, List<Object>> entry : queryParams.entrySet()) {
String key = entry.getKey();
List<Object> values = entry.getValue();

if (values.isEmpty()) {
continue;
}

if (counter != 0) {
query.append(" AND ");
}

query.append(" ( ");

query.append(key).append(" = :").append(key).append("0");
params.put(key + "0", values.get(0));
for (int i = 1; i < values.size(); i++) {
query.append(" OR %s = :%s".formatted(key, key + i));
params.put(key + i, values.get(i));
}
query.append(" )");

counter++;
}

return list(query.toString(), params);
}
}
126 changes: 112 additions & 14 deletions src/main/java/org/damap/base/rest/InternalStorageResource.java
Original file line number Diff line number Diff line change
@@ -1,36 +1,134 @@
package org.damap.base.rest;

import io.quarkus.security.Authenticated;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import java.util.List;
import jakarta.validation.Valid;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.*;
import lombok.extern.jbosslog.JBossLog;
import org.damap.base.rest.base.ResultList;
import org.damap.base.rest.base.resource.ResourceCreate;
import org.damap.base.rest.base.resource.ResourceDelete;
import org.damap.base.rest.base.resource.ResourceRead;
import org.damap.base.rest.base.resource.ResourceSearch;
import org.damap.base.rest.base.resource.ResourceUpdate;
import org.damap.base.rest.storage.InternalStorageDO;
import org.damap.base.rest.storage.InternalStorageService;
import org.jboss.resteasy.reactive.RestPath;

/** InternalStorageResource class. */
@Path("/api/storages")
@Authenticated
@Produces(MediaType.APPLICATION_JSON)
@JBossLog
public class InternalStorageResource {
public class InternalStorageResource
implements ResourceRead<InternalStorageDO>,
ResourceCreate<InternalStorageDO, InternalStorageDO>,
ResourceUpdate<InternalStorageDO, InternalStorageDO>,
ResourceDelete,
ResourceSearch<InternalStorageDO> {

@Inject InternalStorageService internalStorageService;

/**
* getAllByLanguage.
* create a new internal storage option.
*
* @param languageCode a {@link java.lang.String} object
* @return a {@link java.util.List} object
* @param data a {@link org.damap.base.rest.storage.InternalStorageDO} object
* @return a {@link org.damap.base.rest.storage.InternalStorageDO} object, with the ID set
*/
@Override
@POST
@Path("")
@Consumes(MediaType.APPLICATION_JSON)
@RolesAllowed("Damap Admin")
public InternalStorageDO create(@Valid InternalStorageDO data) {
log.debug("Create internal storage option");
log.debug(data);

try {
return internalStorageService.create(data);
} catch (ClientErrorException e) {
throw new ClientErrorException(
Response.status(Response.Status.BAD_REQUEST)
.entity("{\"message\":\"" + e.getMessage() + "\"}")
.type(MediaType.APPLICATION_JSON)
.build());
}
}

/**
* read a specific internal storage option.
*
* @param id a {@link java.lang.String} object
* @param uriInfo a {@link jakarta.ws.rs.core.UriInfo} object
* @return a {@link org.damap.base.rest.storage.InternalStorageDO} object
*/
@Override
@GET
@Path("/{id}")
public InternalStorageDO read(@PathParam("id") String id, @Context UriInfo uriInfo) {
log.debug("Read internal storage option with id " + id);

try {
return internalStorageService.read(id, uriInfo.getQueryParameters());
} catch (NumberFormatException e) {
log.error("Invalid internal storage ID: " + id);
throw new ClientErrorException(
Response.status(Response.Status.BAD_REQUEST)
.entity(
"{\"message\":\"Invalid internal storage ID: " + id + " - must be a number\"}")
.type(MediaType.APPLICATION_JSON)
.build());
}
}

/**
* update an existing internal storage option.
*
* @param id a {@link java.lang.String} object representing the ID of the internal storage option
* to update
* @param data a {@link org.damap.base.rest.storage.InternalStorageDO} object representing the new
* data
* @return a {@link org.damap.base.rest.storage.InternalStorageDO} object, with the updated data
*/
@Override
@PUT
@Path("/{id}")
@Consumes(MediaType.APPLICATION_JSON)
@RolesAllowed("Damap Admin")
public InternalStorageDO update(@PathParam("id") String id, @Valid InternalStorageDO data) {
log.debug("Update internal storage option with id " + id);
log.debug(data);
return internalStorageService.update(id, data);
}

/**
* delete an existing internal storage option.
*
* @param id a {@link java.lang.String} object, representing the ID of the internal storage option
* to delete
*/
@Override
@DELETE
@RolesAllowed("Damap Admin")
@Path("/{id}")
public void delete(@PathParam("id") String id) {
log.debug("Delete internal storage option with id " + id);
internalStorageService.delete(id);
}

/**
* search for internal storage options.
*
* @param uriInfo a {@link jakarta.ws.rs.core.UriInfo} object, representing the query parameters
* @return a ResultList of {@link org.damap.base.rest.storage.InternalStorageDO} objects, that
* match the criteria
*/
@Override
@GET
@Path("/{languageCode}")
public List<InternalStorageDO> getAllByLanguage(@RestPath String languageCode) {
log.debug("Return all internal storage options for language " + languageCode);
return internalStorageService.getAllByLanguage(languageCode);
@Consumes(MediaType.APPLICATION_JSON)
public ResultList<InternalStorageDO> search(@Context UriInfo uriInfo) {
log.debug("Search internal storage options");
return internalStorageService.search(uriInfo.getQueryParameters());
}
}
Loading

0 comments on commit aa8b435

Please sign in to comment.