Skip to content

Commit

Permalink
Added Organization repository v2
Browse files Browse the repository at this point in the history
  • Loading branch information
cgendreau committed Feb 20, 2025
1 parent d795e97 commit a560e0d
Show file tree
Hide file tree
Showing 7 changed files with 480 additions and 43 deletions.
3 changes: 0 additions & 3 deletions src/main/java/ca/gc/aafc/agent/api/dto/OrganizationDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
import java.util.List;
import java.util.UUID;

import com.fasterxml.jackson.annotation.JsonInclude;

import org.javers.core.metamodel.annotation.Id;
import org.javers.core.metamodel.annotation.PropertyName;
import org.javers.core.metamodel.annotation.TypeName;
Expand Down Expand Up @@ -35,7 +33,6 @@ public class OrganizationDto {
private String createdBy;
private OffsetDateTime createdOn;

@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<OrganizationName> names;

}
29 changes: 29 additions & 0 deletions src/main/java/ca/gc/aafc/agent/api/mapper/OrganizationMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package ca.gc.aafc.agent.api.mapper;

import java.util.Set;

import org.mapstruct.BeanMapping;
import org.mapstruct.Context;
import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
import org.mapstruct.NullValuePropertyMappingStrategy;
import org.mapstruct.factory.Mappers;

import ca.gc.aafc.agent.api.dto.OrganizationDto;
import ca.gc.aafc.agent.api.entities.Organization;
import ca.gc.aafc.dina.mapper.DinaMapperV2;

@Mapper
public interface OrganizationMapper extends DinaMapperV2<OrganizationDto, Organization> {

OrganizationMapper INSTANCE = Mappers.getMapper(OrganizationMapper.class);

OrganizationDto toDto(Organization entity, @Context Set<String> provided, @Context String scope);

Organization toEntity(OrganizationDto dto, @Context Set<String> provided, @Context String scope);

@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
void patchEntity(@MappingTarget Organization entity, OrganizationDto dto, @Context Set<String> provided, @Context String scope);

}

Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package ca.gc.aafc.agent.api.repository;

import org.springframework.boot.info.BuildProperties;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.IanaLinkRelations;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.RepresentationModel;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package ca.gc.aafc.agent.api.repository;

import org.springframework.boot.info.BuildProperties;
import org.springframework.hateoas.IanaLinkRelations;
import org.springframework.hateoas.RepresentationModel;
import org.springframework.http.ResponseEntity;
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 com.fasterxml.jackson.databind.ObjectMapper;
import com.toedter.spring.hateoas.jsonapi.JsonApiModelBuilder;

import ca.gc.aafc.agent.api.dto.OrganizationDto;
import ca.gc.aafc.agent.api.entities.Organization;
import ca.gc.aafc.agent.api.mapper.OrganizationMapper;
import ca.gc.aafc.agent.api.security.UpdateDeleteSuperUserOnly;
import ca.gc.aafc.dina.dto.JsonApiDto;
import ca.gc.aafc.dina.exception.ResourceNotFoundException;
import ca.gc.aafc.dina.jsonapi.JsonApiDocument;
import ca.gc.aafc.dina.repository.DinaRepositoryV2;
import ca.gc.aafc.dina.security.DinaAuthenticatedUser;
import ca.gc.aafc.dina.service.AuditService;
import ca.gc.aafc.dina.service.DinaService;

import static com.toedter.spring.hateoas.jsonapi.MediaTypes.JSON_API_VALUE;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;

import java.net.URI;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import lombok.NonNull;

@RestController
@RequestMapping(value = "/api/v1", produces = JSON_API_VALUE)
public class OrganizationRepositoryV2 extends DinaRepositoryV2<OrganizationDto, Organization> {

private static final String TYPE = OrganizationDto.TYPENAME + "v2";

// Bean does not exist with keycloak disabled.
private final DinaAuthenticatedUser authenticatedUser;

public OrganizationRepositoryV2(
@NonNull DinaService<Organization> dinaService,
@NonNull UpdateDeleteSuperUserOnly authorizationService,
Optional<DinaAuthenticatedUser> authenticatedUser,
@NonNull BuildProperties props,
@NonNull AuditService auditService,
@NonNull ObjectMapper objMapper
) {
super(
dinaService,
authorizationService,
Optional.of(auditService),
OrganizationMapper.INSTANCE,
OrganizationDto.class,
Organization.class,
props, objMapper);

this.authenticatedUser = authenticatedUser.orElse(null);
}

@GetMapping(TYPE + "/{id}")
public ResponseEntity<RepresentationModel<?>> handleFindOne(@PathVariable UUID id, HttpServletRequest req) throws
ResourceNotFoundException {
String queryString = decodeQueryString(req);

JsonApiDto<OrganizationDto> jsonApiDto = getOne(id, queryString);
if (jsonApiDto == null) {
return ResponseEntity.notFound().build();
}

JsonApiModelBuilder builder = createJsonApiModelBuilder(jsonApiDto);

return ResponseEntity.ok(builder.build());
}

@GetMapping(TYPE)
public ResponseEntity<RepresentationModel<?>> handleFindAll(HttpServletRequest req) {
String queryString = decodeQueryString(req);

PagedResource<JsonApiDto<OrganizationDto>> dtos;
try {
dtos = getAll(queryString);
} catch (IllegalArgumentException iaEx) {
return ResponseEntity.badRequest().build();
}

JsonApiModelBuilder builder = createJsonApiModelBuilder(dtos);

return ResponseEntity.ok(builder.build());
}

@PostMapping(TYPE)
@Transactional
public ResponseEntity<RepresentationModel<?>> handleCreate(@RequestBody
JsonApiDocument postedDocument)
throws ResourceNotFoundException {

if (postedDocument == null) {
return ResponseEntity.badRequest().build();
}

UUID uuid = create(postedDocument, (dto) -> {
if (authenticatedUser != null) {
dto.setCreatedBy(authenticatedUser.getUsername());
}
});

// reload dto
JsonApiDto<OrganizationDto> jsonApiDto = getOne(uuid, null);
if (jsonApiDto == null) {
return ResponseEntity.notFound().build();
}
JsonApiModelBuilder builder = createJsonApiModelBuilder(jsonApiDto);

builder.link(linkTo(methodOn(OrganizationRepositoryV2.class).handleFindOne(jsonApiDto.getDto().getUuid(), null)).withSelfRel());
RepresentationModel<?> model = builder.build();

URI uri = model.getRequiredLink(IanaLinkRelations.SELF).toUri();

return ResponseEntity.created(uri).body(model);
}

@PatchMapping(TYPE + "/{id}")
@Transactional
public ResponseEntity<RepresentationModel<?>> handleUpdate(@RequestBody
JsonApiDocument partialPatchDto,
@PathVariable UUID id) throws ResourceNotFoundException {

// Sanity check
if (!Objects.equals(id, partialPatchDto.getId())) {
return ResponseEntity.badRequest().build();
}

update(partialPatchDto);

// reload dto
JsonApiDto<OrganizationDto> jsonApiDto = getOne(partialPatchDto.getId(), null);
if (jsonApiDto == null) {
return ResponseEntity.notFound().build();
}
JsonApiModelBuilder builder = createJsonApiModelBuilder(jsonApiDto);

return ResponseEntity.ok().body(builder.build());
}

@DeleteMapping(TYPE + "/{id}")
@Transactional
public ResponseEntity<RepresentationModel<?>> handleDelete(@PathVariable UUID id) throws ResourceNotFoundException {
delete(id);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package ca.gc.aafc.agent.api.repository;

import java.util.UUID;
import javax.inject.Inject;

import org.junit.jupiter.api.Test;
Expand All @@ -22,7 +21,7 @@ public class IdentifierTypeRepositoryIT extends BaseIntegrationTest {
private AgentIdentifierTypeRepository agentIdentifierTypeRepository;

@Test
@WithMockKeycloakUser(username = "user", groupRole = {"group 1:DINA_ADMIN"})
@WithMockKeycloakUser(username = "user", adminRole = {"DINA_ADMIN"})
public void agentIdentifierTypeRepository_onCreate_noException() {
AgentIdentifierTypeDto dto = AgentIdentifierTypeTestFixture.newAgentIdentifierType();

Expand Down
Loading

0 comments on commit a560e0d

Please sign in to comment.