Skip to content

Commit

Permalink
API CRUD Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
amengus87 committed May 27, 2024
1 parent e169936 commit 3556e22
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package ai.dragon.controller.api.backendapi.repository;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.springframework.http.HttpStatus;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.server.ResponseStatusException;

import ai.dragon.entity.IAbstractEntity;
import ai.dragon.entity.SiloEntity;
import ai.dragon.repository.AbstractRepository;

abstract class AbstractCrudBackendApiController<T extends IAbstractEntity> {
public T update(String uuid, Map<String, Object> fields, AbstractRepository<T> repository) {
T entityToUpdate = repository.getByUuid(uuid);
if (entityToUpdate == null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Entity not found");
}

fields.forEach((k, v) -> {
Field field = ReflectionUtils.findField(SiloEntity.class, k);
if (field != null) {
field.setAccessible(true);
ReflectionUtils.setField(field, entityToUpdate, v);
}
});

if (!uuid.equals(entityToUpdate.getUuid().toString())) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "UUID must not be changed.");
}

repository.save(entityToUpdate);

return entityToUpdate;
}

public List<T> list(AbstractRepository<T> repository) {
return repository.find().toList();
}

public T create(AbstractRepository<T> repository) throws Exception {
Class<T> clazz = repository.getGenericSuperclass();
Constructor<T> cons = clazz.getConstructor();
T entity = cons.newInstance();
repository.save(entity);
return entity;
}

public T get(String uuid, AbstractRepository<T> repository) {
return Optional.ofNullable(repository.getByUuid(uuid))
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Entity not found."));
}

public void delete(String uuid, AbstractRepository<T> repository) {
if (!repository.exists(uuid)) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Entity not found.");
}
repository.delete(uuid);
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
package ai.dragon.controller.api.backendapi.repository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;

import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import ai.dragon.entity.SiloEntity;
import ai.dragon.repository.SiloRepository;
Expand All @@ -29,65 +26,47 @@
@RestController
@RequestMapping("/api/backendapi/repository/silo")
@Tag(name = "Silo Repository", description = "Silo Repository Management API Endpoints")
public class SiloBackendApiController {
public class SiloBackendApiController extends AbstractCrudBackendApiController<SiloEntity> {
@Autowired
private SiloRepository siloRepository;

@GetMapping("/")
@ApiResponse(responseCode = "200", description = "List has been successfully retrieved.")
@Operation(summary = "List all Silos", description = "Returns all Silo entities stored in the database.")
public List<SiloEntity> list() {
return siloRepository.find().toList();
return super.list(siloRepository);
}

@PostMapping("/")
@ApiResponse(responseCode = "200", description = "Silo has been successfully created.")
@Operation(summary = "Create a new Silo", description = "Creates one Silo entity in the database.")
public SiloEntity create() {
String siloName = String.format("Silo %s",
LocalDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));

SiloEntity silo = new SiloEntity();
silo.setName(siloName);
siloRepository.save(silo);
return silo;
public SiloEntity create() throws Exception {
return super.create(siloRepository);
}

@GetMapping("/{uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}}")
@ApiResponse(responseCode = "200", description = "Silo has been successfully retrieved.")
@ApiResponse(responseCode = "404", description = "Silo not found.", content = @Content)
@Operation(summary = "Retrieve one Silo", description = "Returns one Silo entity from its UUID stored in the database.")
public SiloEntity get(@PathVariable("uuid") @Parameter(description = "Identifier of the Silo") String uuid) {
return Optional.ofNullable(siloRepository.getByUuid(uuid))
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Silo not found."));
return super.get(uuid, siloRepository);
}

@PatchMapping("/{uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}}")
@ApiResponse(responseCode = "200", description = "Silo has been successfully created.")
@ApiResponse(responseCode = "404", description = "Silo not found.", content = @Content)
@Operation(summary = "Update a Silo", description = "Updates one Silo entity in the database.")
public SiloEntity update(@PathVariable("uuid") @Parameter(description = "Identifier of the Silo", required = true) String uuid,
SiloEntity silo) throws JsonMappingException {
if (!siloRepository.exists(uuid) || silo == null || !uuid.equals(silo.getUuid().toString())) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Silo not found");
}

SiloEntity siloToUpdate = siloRepository.getByUuid(uuid);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.updateValue(siloToUpdate, silo);
siloRepository.save(siloToUpdate);

return siloToUpdate;
public SiloEntity update(
@PathVariable("uuid") @Parameter(description = "Identifier of the Silo", required = true) String uuid,
@RequestBody Map<String, Object> fields) throws JsonMappingException {
return super.update(uuid, fields, siloRepository);
}

@DeleteMapping("/{uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}}")
@ApiResponse(responseCode = "200", description = "Silo has been successfully deleted.")
@ApiResponse(responseCode = "404", description = "Silo not found.", content = @Content)
@Operation(summary = "Delete a Silo", description = "Deletes one Silo entity from its UUID stored in the database.")
public void delete(@PathVariable("uuid") @Parameter(description = "Identifier of the Silo") String uuid) {
if (!siloRepository.exists(uuid)) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Silo not found.");
}
siloRepository.delete(uuid);
super.delete(uuid, siloRepository);
}
}
2 changes: 2 additions & 0 deletions backend/src/main/java/ai/dragon/entity/SiloEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public class SiloEntity implements IAbstractEntity {
@Schema(description = "Name of the Silo")
private String name;

private String embeddingStoreClass;

public SiloEntity() {
this.uuid = UUID.randomUUID();
this.name = String.format("Silo %s", this.uuid.toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import jakarta.validation.Validator;

@Component
abstract class AbstractRepository<T extends IAbstractEntity> {
public abstract class AbstractRepository<T extends IAbstractEntity> {
@Autowired
private DatabaseService databaseService;

Expand Down Expand Up @@ -121,7 +121,7 @@ public void unsubscribe(CollectionEventListener listener) {
}

@SuppressWarnings("unchecked")
private Class<T> getGenericSuperclass() {
public Class<T> getGenericSuperclass() {
ParameterizedType superclass = (ParameterizedType) getClass().getGenericSuperclass();

return (Class<T>) superclass.getActualTypeArguments()[0];
Expand Down

0 comments on commit 3556e22

Please sign in to comment.