From 5b6993dbdd0f25f0590eecd87851df23b1e06977 Mon Sep 17 00:00:00 2001 From: Daniel Hillwig Date: Wed, 16 Dec 2020 13:05:35 +0100 Subject: [PATCH] feat: implementation --- api/agencyadminservice.yaml | 10 ++- .../ApiResponseEntityExceptionHandler.java | 23 ++++++- .../controller/AgencyAdminController.java | 18 ++++++ .../api/admin/service/AgencyAdminService.java | 60 +++++++++++++++++- .../service/UpdateAgencyLinkBuilder.java | 61 ++++++++++++++++++ .../api/admin/validation/AgencyValidator.java | 54 +++++++++++++++- .../AgencyConsultingTypeValidator.java | 14 +++-- .../validators/AgencyDioceseValidator.java | 16 +++-- .../AgencyOfflineStatusValidator.java | 63 +++++++++++++++++++ .../validators/AgencyPostcodeValidator.java | 16 +++-- .../validators/ConcreteAgencyValidator.java | 4 +- .../annotation/CreateAgencyValidator.java | 11 ++++ .../annotation/UpdateAgencyValidator.java | 11 ++++ .../validators/model/ValidateAgencyDto.java | 27 ++++++++ .../HttpStatusExceptionReason.java | 3 +- .../InvalidOfflineStatusException.java | 14 +++++ .../httpresponses/NotFoundException.java | 11 ++++ .../AgencyPostCodeRangeRepository.java | 8 +++ .../resources/application-local.properties | 4 +- .../AgencyAdminControllerAuthorizationIT.java | 3 +- .../AgencyConsultingTypeValidatorTest.java | 13 ++-- .../AgencyDioceseValidatorTest.java | 14 ++--- .../AgencyPostcodeValidatorTest.java | 18 +++--- 23 files changed, 422 insertions(+), 54 deletions(-) create mode 100644 src/main/java/de/caritas/cob/agencyservice/api/admin/service/UpdateAgencyLinkBuilder.java create mode 100644 src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyOfflineStatusValidator.java create mode 100644 src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/annotation/CreateAgencyValidator.java create mode 100644 src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/annotation/UpdateAgencyValidator.java create mode 100644 src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/model/ValidateAgencyDto.java create mode 100644 src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/InvalidOfflineStatusException.java create mode 100644 src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/NotFoundException.java diff --git a/api/agencyadminservice.yaml b/api/agencyadminservice.yaml index ec652108..1b4893aa 100644 --- a/api/agencyadminservice.yaml +++ b/api/agencyadminservice.yaml @@ -191,7 +191,7 @@ paths: operationId: updateAgency requestBody: content: - 'application/hal+json': + 'application/json': schema: $ref: '#/components/schemas/UpdateAgencyDTO' required: true @@ -207,11 +207,13 @@ paths: 200: description: OK - agency was updated successfully content: - 'application/json': + 'application/hal+json': schema: $ref: '#/components/schemas/UpdateAgencyResponseDTO' 400: description: BAD REQUEST - invalid/incomplete request + 404: + description: NOT FOUND - agency not found 401: description: UNAUTHORIZED - no/invalid role/authorization 500: @@ -627,15 +629,19 @@ components: name: type: string example: "Beratungstelle" + minLength: 1 + maxLength: 100 description: type: string example: "Beschreibung Beratungstelle..." + maxLength: 10000 postcode: type: string example: "79106" city: type: string example: "Muenchen" + maxLength: 100 offline: type: boolean example: false diff --git a/src/main/java/de/caritas/cob/agencyservice/api/ApiResponseEntityExceptionHandler.java b/src/main/java/de/caritas/cob/agencyservice/api/ApiResponseEntityExceptionHandler.java index b57148bd..c14d13c9 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/ApiResponseEntityExceptionHandler.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/ApiResponseEntityExceptionHandler.java @@ -7,7 +7,9 @@ import de.caritas.cob.agencyservice.api.exception.httpresponses.InternalServerErrorException; import de.caritas.cob.agencyservice.api.exception.httpresponses.InvalidConsultingTypeException; import de.caritas.cob.agencyservice.api.exception.httpresponses.InvalidDioceseException; +import de.caritas.cob.agencyservice.api.exception.httpresponses.InvalidOfflineStatusException; import de.caritas.cob.agencyservice.api.exception.httpresponses.InvalidPostcodeException; +import de.caritas.cob.agencyservice.api.exception.httpresponses.NotFoundException; import de.caritas.cob.agencyservice.api.service.LogService; import java.net.UnknownHostException; import javax.validation.ConstraintViolationException; @@ -162,7 +164,7 @@ public ResponseEntity handleInternal( * @return a ResponseEntity instance */ @ExceptionHandler({InvalidPostcodeException.class, InvalidConsultingTypeException.class, - InvalidDioceseException.class + InvalidDioceseException.class, InvalidOfflineStatusException.class }) public ResponseEntity handleInternal( final CustomValidationHttpStatusException ex, final WebRequest request) { @@ -175,4 +177,23 @@ public ResponseEntity handleInternal( HttpStatus.BAD_REQUEST, request); } + + /** + * 404 - Not found. + * + * @param ex {@link NotFoundException} + * @param request WebRequest + * @return a ResponseEntity instance + */ + @ExceptionHandler({NotFoundException.class}) + public ResponseEntity handleInternal( + final NotFoundException ex, final WebRequest request) { + + return handleExceptionInternal( + null, + null, + new HttpHeaders(), + HttpStatus.NOT_FOUND, + request); + } } diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/controller/AgencyAdminController.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/controller/AgencyAdminController.java index 22ddae5e..523ed0c6 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/controller/AgencyAdminController.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/controller/AgencyAdminController.java @@ -12,6 +12,8 @@ import de.caritas.cob.agencyservice.api.model.CreateAgencyResponseDTO; import de.caritas.cob.agencyservice.api.model.DioceseAdminResultDTO; import de.caritas.cob.agencyservice.api.model.RootDTO; +import de.caritas.cob.agencyservice.api.model.UpdateAgencyDTO; +import de.caritas.cob.agencyservice.api.model.UpdateAgencyResponseDTO; import de.caritas.cob.agencyservice.generated.api.admin.controller.AgencyadminApi; import io.swagger.annotations.Api; import javax.validation.Valid; @@ -114,4 +116,20 @@ public ResponseEntity getAgencyPostcodeRanges(@Pa return ResponseEntity.ok(postCodeRangesForAgency); } + /** + * Entry point to update a specific agency. + * + * @param agencyId Agency Id (required) + * @param updateAgencyDTO (required) + * @return a {@link CreateAgencyResponseDTO} entity + */ + @Override + public ResponseEntity updateAgency(@PathVariable Long agencyId, + @Valid UpdateAgencyDTO updateAgencyDTO) { + + agencyValidator.validate(agencyId, updateAgencyDTO); + UpdateAgencyResponseDTO updateAgencyResponseDTO = agencyAdminService.updateAgency(agencyId, updateAgencyDTO); + + return new ResponseEntity<>(updateAgencyResponseDTO, HttpStatus.OK); + } } diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java index c990d444..6c9d2269 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/AgencyAdminService.java @@ -4,19 +4,23 @@ import de.caritas.cob.agencyservice.api.admin.service.agency.AgencyAdminResponseDTOBuilder; import de.caritas.cob.agencyservice.api.exception.httpresponses.BadRequestException; import de.caritas.cob.agencyservice.api.exception.httpresponses.InternalServerErrorException; +import de.caritas.cob.agencyservice.api.exception.httpresponses.NotFoundException; import de.caritas.cob.agencyservice.api.model.AgencyAdminResponseDTO; import de.caritas.cob.agencyservice.api.model.AgencyDTO; import de.caritas.cob.agencyservice.api.model.CreateAgencyResponseDTO; import de.caritas.cob.agencyservice.api.model.CreateLinks; +import de.caritas.cob.agencyservice.api.model.UpdateAgencyDTO; +import de.caritas.cob.agencyservice.api.model.UpdateAgencyResponseDTO; +import de.caritas.cob.agencyservice.api.model.UpdateLinks; import de.caritas.cob.agencyservice.api.repository.agency.Agency; import de.caritas.cob.agencyservice.api.repository.agency.AgencyRepository; import de.caritas.cob.agencyservice.api.repository.agency.ConsultingType; import de.caritas.cob.agencyservice.api.service.LogService; import java.time.LocalDateTime; import java.time.ZoneOffset; -import lombok.NonNull; import lombok.RequiredArgsConstructor; import org.springframework.dao.DataAccessException; +import org.springframework.lang.NonNull; import org.springframework.stereotype.Service; /** @@ -70,9 +74,61 @@ private Agency fromAgencyDTO(AgencyDTO agencyDTO) { .teamAgency(agencyDTO.getTeamAgency()) .consultingType( ConsultingType.valueOf(agencyDTO.getConsultingType()) - .orElseThrow(() -> new BadRequestException("Consulting type of agency dto does not exist"))) + .orElseThrow( + () -> new BadRequestException("Consulting type of agency dto does not exist"))) .createDate(LocalDateTime.now(ZoneOffset.UTC)) .updateDate(LocalDateTime.now(ZoneOffset.UTC)) .build(); } + + /** + * Updates an agency in the database. + * + * @param updateAgencyDTO (required) + * @return an {@link UpdateAgencyResponseDTO} instance + */ + public UpdateAgencyResponseDTO updateAgency(Long agencyId, UpdateAgencyDTO updateAgencyDTO) { + Agency updatedAgency; + try { + Agency agency = agencyRepository.findById(agencyId) + .orElseThrow(NotFoundException::new); + updatedAgency = agencyRepository.save(mergeAgencies(agency, updateAgencyDTO)); + } catch (DataAccessException ex) { + throw new InternalServerErrorException( + LogService::logDatabaseError, "Database error while saving agency"); + } + + UpdateLinks updateLinks = + UpdateAgencyLinkBuilder.getInstance(updatedAgency).buildUpdateAgencyLinks(); + + return new UpdateAgencyResponseDTO() + .embedded(new AgencyAdminResponseDTOBuilder(updatedAgency).fromAgency()) + .links(updateLinks); + + } + + /** + * Converts a {@link UpdateAgencyDTO} to an {@link Agency}. + * + * @param updateAgencyDTO (required) + * @return an {@link Agency} instance + */ + private Agency mergeAgencies(Agency agency, UpdateAgencyDTO updateAgencyDTO) { + + return Agency.builder() + .id(agency.getId()) + .dioceseId(updateAgencyDTO.getDioceseId()) + .name(updateAgencyDTO.getName()) + .description(updateAgencyDTO.getDescription()) + .postCode(updateAgencyDTO.getPostcode()) + .city(updateAgencyDTO.getCity()) + .offline(updateAgencyDTO.getOffline()) + .teamAgency(agency.isTeamAgency()) + .consultingType(agency.getConsultingType()) + .createDate(agency.getCreateDate()) + .updateDate(LocalDateTime.now(ZoneOffset.UTC)) + .deleteDate(agency.getDeleteDate()) + .build(); + } + } diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/service/UpdateAgencyLinkBuilder.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/UpdateAgencyLinkBuilder.java new file mode 100644 index 00000000..1f562c6a --- /dev/null +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/service/UpdateAgencyLinkBuilder.java @@ -0,0 +1,61 @@ +package de.caritas.cob.agencyservice.api.admin.service; + +import static java.util.Objects.requireNonNull; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; + +import de.caritas.cob.agencyservice.api.admin.hallink.CreateAgencyLinkBuilder; +import de.caritas.cob.agencyservice.api.admin.hallink.HalLinkBuilder; +import de.caritas.cob.agencyservice.api.model.HalLink; +import de.caritas.cob.agencyservice.api.model.HalLink.MethodEnum; +import de.caritas.cob.agencyservice.api.model.UpdateLinks; +import de.caritas.cob.agencyservice.api.repository.agency.Agency; +import de.caritas.cob.agencyservice.generated.api.admin.controller.AgencyadminApi; + +/** + * Link builder to create hal links for update agency results. + */ +public class UpdateAgencyLinkBuilder implements HalLinkBuilder { + + private final Agency agency; + + private UpdateAgencyLinkBuilder(Agency agency) { + this.agency = agency; + } + + /** + * Creates an {@link CreateAgencyLinkBuilder} instance. + * + * @return a instance of {@link CreateAgencyLinkBuilder} + */ + public static UpdateAgencyLinkBuilder getInstance(Agency agency) { + requireNonNull(agency); + return new UpdateAgencyLinkBuilder(agency); + } + + /** + * Creates the {@link CreateAgencyLinkBuilder}. + * + * @return the generated {@link CreateAgencyLinkBuilder} + */ + public UpdateLinks buildUpdateAgencyLinks() { + return new UpdateLinks() + .self(buildSelfLink()) + .delete(buildDeleteHalLink()) + .agency(buildAgencyLink()); + } + + private HalLink buildAgencyLink() { + return buildHalLink(methodOn(AgencyadminApi.class).getAgency(agency.getId()), MethodEnum.GET); + } + + private HalLink buildDeleteHalLink() { + return buildHalLink( + methodOn(AgencyadminApi.class).deleteAgency(agency.getId()), MethodEnum.DELETE); + } + + private HalLink buildSelfLink() { + return buildHalLink( + methodOn(AgencyadminApi.class).updateAgency(agency.getId(), null), MethodEnum.PUT); + } + +} diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/AgencyValidator.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/AgencyValidator.java index ddaa7728..e76b5a54 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/AgencyValidator.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/AgencyValidator.java @@ -1,7 +1,14 @@ package de.caritas.cob.agencyservice.api.admin.validation; import de.caritas.cob.agencyservice.api.admin.validation.validators.ConcreteAgencyValidator; +import de.caritas.cob.agencyservice.api.admin.validation.validators.annotation.CreateAgencyValidator; +import de.caritas.cob.agencyservice.api.admin.validation.validators.annotation.UpdateAgencyValidator; +import de.caritas.cob.agencyservice.api.admin.validation.validators.model.ValidateAgencyDto; +import de.caritas.cob.agencyservice.api.exception.httpresponses.NotFoundException; import de.caritas.cob.agencyservice.api.model.AgencyDTO; +import de.caritas.cob.agencyservice.api.model.UpdateAgencyDTO; +import de.caritas.cob.agencyservice.api.repository.agency.Agency; +import de.caritas.cob.agencyservice.api.repository.agency.AgencyRepository; import lombok.NonNull; import lombok.RequiredArgsConstructor; import org.springframework.context.ApplicationContext; @@ -14,17 +21,58 @@ @RequiredArgsConstructor public class AgencyValidator { + private final @NonNull AgencyRepository agencyRepository; private final @NonNull ApplicationContext applicationContext; /** * Validates an {@link AgencyDTO}. * - * @param agencyDTO (required) + * @param agencyDto (required) */ - public void validate(AgencyDTO agencyDTO) { + public void validate(AgencyDTO agencyDto) { this.applicationContext .getBeansOfType(ConcreteAgencyValidator.class) .values() - .forEach(validator -> validator.validate(agencyDTO)); + .stream() + .filter(c -> c.getClass().isAnnotationPresent(CreateAgencyValidator.class)) + .forEach(validator -> validator.validate(fromAgencyDto(agencyDto))); + } + + /** + * Validates an {@link UpdateAgencyDTO}. + * + * @param updateAgencyDTO (required) + */ + public void validate(Long agencyId, UpdateAgencyDTO updateAgencyDTO) { + this.applicationContext + .getBeansOfType(ConcreteAgencyValidator.class) + .values() + .stream() + .filter(c -> c.getClass().isAnnotationPresent(UpdateAgencyValidator.class)) + .forEach(validator -> validator.validate(fromUpdateAgencyDto(agencyId, updateAgencyDTO))); + } + + private ValidateAgencyDto fromAgencyDto(AgencyDTO agencyDto) { + return ValidateAgencyDto.builder() + .dioceseId(agencyDto.getDioceseId()) + .name(agencyDto.getName()) + .description(agencyDto.getDescription()) + .postcode(agencyDto.getPostcode()) + .city(agencyDto.getCity()) + .teamAgency(agencyDto.getTeamAgency()) + .consultingType(agencyDto.getConsultingType()) + .build(); + } + + private ValidateAgencyDto fromUpdateAgencyDto(Long agencyId, UpdateAgencyDTO updateAgencyDTO) { + return ValidateAgencyDto.builder() + .id(agencyId) + .dioceseId(updateAgencyDTO.getDioceseId()) + .name(updateAgencyDTO.getName()) + .description(updateAgencyDTO.getDescription()) + .postcode(updateAgencyDTO.getPostcode()) + .city(updateAgencyDTO.getCity()) + .offline(updateAgencyDTO.getOffline()) + .build(); } } diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyConsultingTypeValidator.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyConsultingTypeValidator.java index bf2fc7b0..990ebfaf 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyConsultingTypeValidator.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyConsultingTypeValidator.java @@ -1,23 +1,25 @@ package de.caritas.cob.agencyservice.api.admin.validation.validators; +import de.caritas.cob.agencyservice.api.admin.validation.validators.annotation.CreateAgencyValidator; +import de.caritas.cob.agencyservice.api.admin.validation.validators.model.ValidateAgencyDto; import de.caritas.cob.agencyservice.api.exception.httpresponses.InvalidConsultingTypeException; -import de.caritas.cob.agencyservice.api.model.AgencyDTO; import de.caritas.cob.agencyservice.api.repository.agency.ConsultingType; import org.springframework.stereotype.Component; /** - * Consulting type validator for an {@link AgencyDTO}. + * Consulting type validator for an {@link ValidateAgencyDto}. */ @Component +@CreateAgencyValidator public class AgencyConsultingTypeValidator implements ConcreteAgencyValidator { /** - * Validates the diocese id of an {@link AgencyDTO}. + * Validates the diocese id of an {@link ValidateAgencyDto}. * - * @param agencyDTO (required) + * @param validateAgencyDto (required) */ - public void validate(AgencyDTO agencyDTO) { - if (!ConsultingType.valueOf(agencyDTO.getConsultingType()).isPresent()) { + public void validate(ValidateAgencyDto validateAgencyDto) { + if (!ConsultingType.valueOf(validateAgencyDto.getConsultingType()).isPresent()) { throw new InvalidConsultingTypeException(); } } diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDioceseValidator.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDioceseValidator.java index 57ff64ad..bfd941a1 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDioceseValidator.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDioceseValidator.java @@ -1,28 +1,32 @@ package de.caritas.cob.agencyservice.api.admin.validation.validators; +import de.caritas.cob.agencyservice.api.admin.validation.validators.annotation.CreateAgencyValidator; +import de.caritas.cob.agencyservice.api.admin.validation.validators.annotation.UpdateAgencyValidator; +import de.caritas.cob.agencyservice.api.admin.validation.validators.model.ValidateAgencyDto; import de.caritas.cob.agencyservice.api.exception.httpresponses.InvalidDioceseException; -import de.caritas.cob.agencyservice.api.model.AgencyDTO; import de.caritas.cob.agencyservice.api.repository.diocese.DioceseRepository; import lombok.NonNull; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; /* -* Diocese validator for an {@link AgencyDTO}. +* Diocese validator for an {@link ValidateAgencyDto}. */ @Component @RequiredArgsConstructor +@CreateAgencyValidator +@UpdateAgencyValidator public class AgencyDioceseValidator implements ConcreteAgencyValidator { private final @NonNull DioceseRepository dioceseRepository; /** - * Validates the diocese id of an {@link AgencyDTO}. + * Validates the diocese id of an {@link ValidateAgencyDto}. * - * @param agencyDTO (required) + * @param validateAgencyDto (required) */ - public void validate(AgencyDTO agencyDTO) { - if (!dioceseRepository.findById(agencyDTO.getDioceseId()).isPresent()) { + public void validate(ValidateAgencyDto validateAgencyDto) { + if (!dioceseRepository.findById(validateAgencyDto.getDioceseId()).isPresent()) { throw new InvalidDioceseException(); } } diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyOfflineStatusValidator.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyOfflineStatusValidator.java new file mode 100644 index 00000000..55a951a3 --- /dev/null +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyOfflineStatusValidator.java @@ -0,0 +1,63 @@ +package de.caritas.cob.agencyservice.api.admin.validation.validators; + +import static java.util.Objects.nonNull; + +import de.caritas.cob.agencyservice.api.admin.validation.validators.annotation.UpdateAgencyValidator; +import de.caritas.cob.agencyservice.api.admin.validation.validators.model.ValidateAgencyDto; +import de.caritas.cob.agencyservice.api.exception.httpresponses.InvalidOfflineStatusException; +import de.caritas.cob.agencyservice.api.exception.httpresponses.NotFoundException; +import de.caritas.cob.agencyservice.api.helper.WhiteSpotHelper; +import de.caritas.cob.agencyservice.api.repository.agency.AgencyRepository; +import de.caritas.cob.agencyservice.api.repository.agency.ConsultingType; +import de.caritas.cob.agencyservice.api.repository.agencypostcoderange.AgencyPostCodeRangeRepository; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +/* + * Offline status validator for an {@link ValidateAgencyDto}. + */ +@Component +@RequiredArgsConstructor +@UpdateAgencyValidator +public class AgencyOfflineStatusValidator implements ConcreteAgencyValidator { + + private final @NonNull AgencyRepository agencyRepository; + private final @NonNull AgencyPostCodeRangeRepository agencyPostCodeRangeRepository; + private final @NonNull WhiteSpotHelper whiteSpotHelper; + + /** + * Validates the offline status of an {@link ValidateAgencyDto}. + * + * @param validateAgencyDto (required) + */ + @Override + public void validate(ValidateAgencyDto validateAgencyDto) { + if (!isWhiteSpotAgency(validateAgencyDto) + && !isValidOfflineStatus(validateAgencyDto)) { + throw new InvalidOfflineStatusException(); + } + } + + private boolean isValidOfflineStatus(ValidateAgencyDto validateAgencyDto) { + return Boolean.TRUE.equals(validateAgencyDto.getOffline()) + || agencyPostCodeRangeRepository.countAllByAgencyId(validateAgencyDto.getId()) > 0; + } + + private boolean isWhiteSpotAgency(ValidateAgencyDto validateAgencyDto) { + ConsultingType consultingType = obtainConsultingTypeOfAgency(validateAgencyDto); + return nonNull(getWhiteSpotAgencyIdForConsultingType(consultingType)) + && getWhiteSpotAgencyIdForConsultingType(consultingType) + .equals(validateAgencyDto.getId()); + } + + private Long getWhiteSpotAgencyIdForConsultingType(ConsultingType consultingType) { + return whiteSpotHelper.getWhiteSpotAgenciesMap() + .get(consultingType.getValue()); + } + + private ConsultingType obtainConsultingTypeOfAgency(ValidateAgencyDto validateAgencyDto) { + return agencyRepository.findById(validateAgencyDto.getId()) + .orElseThrow(NotFoundException::new).getConsultingType(); + } +} diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyPostcodeValidator.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyPostcodeValidator.java index be531868..c3ec82d4 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyPostcodeValidator.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyPostcodeValidator.java @@ -2,23 +2,27 @@ import static java.util.Objects.nonNull; +import de.caritas.cob.agencyservice.api.admin.validation.validators.annotation.CreateAgencyValidator; +import de.caritas.cob.agencyservice.api.admin.validation.validators.annotation.UpdateAgencyValidator; +import de.caritas.cob.agencyservice.api.admin.validation.validators.model.ValidateAgencyDto; import de.caritas.cob.agencyservice.api.exception.httpresponses.InvalidPostcodeException; -import de.caritas.cob.agencyservice.api.model.AgencyDTO; import org.springframework.stereotype.Component; /** - * Postcode validator for an {@link AgencyDTO}. + * Postcode validator for an {@link ValidateAgencyDto}. */ @Component +@CreateAgencyValidator +@UpdateAgencyValidator public class AgencyPostcodeValidator implements ConcreteAgencyValidator { /** - * Validates the postcode of an {@link AgencyDTO}. + * Validates the postcode of an {@link ValidateAgencyDto}. * - * @param agencyDTO (required) + * @param validateAgencyDto (required) */ - public void validate(AgencyDTO agencyDTO) { - if (nonNull(agencyDTO.getPostcode()) && !agencyDTO.getPostcode().matches("^[0-9]{5}$")) { + public void validate(ValidateAgencyDto validateAgencyDto) { + if (nonNull(validateAgencyDto.getPostcode()) && !validateAgencyDto.getPostcode().matches("^[0-9]{5}$")) { throw new InvalidPostcodeException(); } } diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/ConcreteAgencyValidator.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/ConcreteAgencyValidator.java index b8d35239..9bc9e45e 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/ConcreteAgencyValidator.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/ConcreteAgencyValidator.java @@ -1,8 +1,8 @@ package de.caritas.cob.agencyservice.api.admin.validation.validators; -import de.caritas.cob.agencyservice.api.model.AgencyDTO; +import de.caritas.cob.agencyservice.api.admin.validation.validators.model.ValidateAgencyDto; public interface ConcreteAgencyValidator { - void validate(AgencyDTO agencyDTO); + void validate(ValidateAgencyDto validateAgencyDto); } diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/annotation/CreateAgencyValidator.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/annotation/CreateAgencyValidator.java new file mode 100644 index 00000000..cdc8fb92 --- /dev/null +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/annotation/CreateAgencyValidator.java @@ -0,0 +1,11 @@ +package de.caritas.cob.agencyservice.api.admin.validation.validators.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface CreateAgencyValidator { +} diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/annotation/UpdateAgencyValidator.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/annotation/UpdateAgencyValidator.java new file mode 100644 index 00000000..86b9df4b --- /dev/null +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/annotation/UpdateAgencyValidator.java @@ -0,0 +1,11 @@ +package de.caritas.cob.agencyservice.api.admin.validation.validators.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface UpdateAgencyValidator { +} diff --git a/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/model/ValidateAgencyDto.java b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/model/ValidateAgencyDto.java new file mode 100644 index 00000000..050c3c20 --- /dev/null +++ b/src/main/java/de/caritas/cob/agencyservice/api/admin/validation/validators/model/ValidateAgencyDto.java @@ -0,0 +1,27 @@ +package de.caritas.cob.agencyservice.api.admin.validation.validators.model; + +import de.caritas.cob.agencyservice.api.repository.agency.Agency; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import de.caritas.cob.agencyservice.api.admin.validation.AgencyValidator; + +/** + * Validation dto for {@link AgencyValidator}. + */ +@Builder +@Getter +@Setter +public class ValidateAgencyDto { + + private Long id; + private Long dioceseId; + private String name; + private String description; + private String postcode; + private String city; + private Boolean teamAgency; + private Integer consultingType; + private Boolean offline; + +} diff --git a/src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/HttpStatusExceptionReason.java b/src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/HttpStatusExceptionReason.java index a664520c..93ac62df 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/HttpStatusExceptionReason.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/HttpStatusExceptionReason.java @@ -3,5 +3,6 @@ public enum HttpStatusExceptionReason { INVALID_POSTCODE, INVALID_DIOCESE, - INVALID_CONSULTING_TYPE + INVALID_CONSULTING_TYPE, + INVALID_OFFLINE_STATUS } diff --git a/src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/InvalidOfflineStatusException.java b/src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/InvalidOfflineStatusException.java new file mode 100644 index 00000000..9bc53087 --- /dev/null +++ b/src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/InvalidOfflineStatusException.java @@ -0,0 +1,14 @@ +package de.caritas.cob.agencyservice.api.exception.httpresponses; + +/** + * Exception, when the offline status of an agency is invalid. + */ +public class InvalidOfflineStatusException extends CustomValidationHttpStatusException { + + /* + * InvalidOfflineStatusException - BAD REQUEST 400. + */ + public InvalidOfflineStatusException() { + super(HttpStatusExceptionReason.INVALID_OFFLINE_STATUS); + } +} diff --git a/src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/NotFoundException.java b/src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/NotFoundException.java new file mode 100644 index 00000000..2a4ba5d7 --- /dev/null +++ b/src/main/java/de/caritas/cob/agencyservice/api/exception/httpresponses/NotFoundException.java @@ -0,0 +1,11 @@ +package de.caritas.cob.agencyservice.api.exception.httpresponses; + +import lombok.NoArgsConstructor; + +/** + * 404 - Not found http exception + */ +@NoArgsConstructor +public class NotFoundException extends RuntimeException { + +} diff --git a/src/main/java/de/caritas/cob/agencyservice/api/repository/agencypostcoderange/AgencyPostCodeRangeRepository.java b/src/main/java/de/caritas/cob/agencyservice/api/repository/agencypostcoderange/AgencyPostCodeRangeRepository.java index c7eb98fc..5da188c4 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/repository/agencypostcoderange/AgencyPostCodeRangeRepository.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/repository/agencypostcoderange/AgencyPostCodeRangeRepository.java @@ -18,4 +18,12 @@ public interface AgencyPostCodeRangeRepository extends CrudRepository findAllByAgencyId(Long agencyId, Pageable pageable); + /** + * Count the amount of agency postcode ranges for a given agency id. + * + * @param agencyId the agency id + * @return the amount of postcode ranges + */ + long countAllByAgencyId(Long agencyId); + } diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index 82a342c6..2ac36c91 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -26,7 +26,7 @@ spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDB103Dialect # Caritas settings sucht.white.spot.agency.id=98 -u25.white.spot.agency.id= +u25.white.spot.agency.id=1704 pregnancy.white.spot.agency.id=777 parenting.white.spot.agency.id=1620 cure.white.spot.agency.id=1005 @@ -52,4 +52,4 @@ spring.liquibase.user= spring.liquibase.password= spring.jpa.show-sql=true -spring.jpa.properties.hibernate.format_sql=true \ No newline at end of file +spring.jpa.properties.hibernate.format_sql=true diff --git a/src/test/java/de/caritas/cob/agencyservice/api/admin/controller/AgencyAdminControllerAuthorizationIT.java b/src/test/java/de/caritas/cob/agencyservice/api/admin/controller/AgencyAdminControllerAuthorizationIT.java index 236312ba..b701cac8 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/admin/controller/AgencyAdminControllerAuthorizationIT.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/admin/controller/AgencyAdminControllerAuthorizationIT.java @@ -22,6 +22,7 @@ import de.caritas.cob.agencyservice.api.admin.service.agency.AgencyAdminSearchService; import de.caritas.cob.agencyservice.api.admin.service.agencypostcoderange.AgencyPostCodeRangeAdminService; import de.caritas.cob.agencyservice.api.admin.validation.AgencyValidator; +import de.caritas.cob.agencyservice.api.model.AgencyDTO; import javax.servlet.http.Cookie; import org.junit.Test; import org.junit.runner.RunWith; @@ -217,7 +218,7 @@ public void createAgency_Should_ReturnCreatedAndCallAgencyAdminServiceAndAgencyV .header(CSRF_HEADER, CSRF_VALUE)) .andExpect(status().isCreated()); - verify(this.agencyValidator, times(1)).validate(Mockito.any()); + verify(this.agencyValidator, times(1)).validate(Mockito.any(AgencyDTO.class)); verify(this.agencyAdminService, times(1)).saveAgency(Mockito.any()); } diff --git a/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyConsultingTypeValidatorTest.java b/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyConsultingTypeValidatorTest.java index 4ed003f7..159bbdd8 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyConsultingTypeValidatorTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyConsultingTypeValidatorTest.java @@ -2,6 +2,7 @@ import static de.caritas.cob.agencyservice.testHelper.TestConstants.CONSULTING_TYPE_AIDS; +import de.caritas.cob.agencyservice.api.admin.validation.validators.model.ValidateAgencyDto; import de.caritas.cob.agencyservice.api.exception.httpresponses.InvalidConsultingTypeException; import de.caritas.cob.agencyservice.api.model.AgencyDTO; import org.jeasy.random.EasyRandom; @@ -10,24 +11,24 @@ public class AgencyConsultingTypeValidatorTest { - private AgencyDTO agencyDTO; + private ValidateAgencyDto validateAgencyDto; @Before public void setup() { EasyRandom easyRandom = new EasyRandom(); - this.agencyDTO = easyRandom.nextObject(AgencyDTO.class); + this.validateAgencyDto = easyRandom.nextObject(ValidateAgencyDto.class); } @Test(expected = InvalidConsultingTypeException.class) public void validate_Should_ThrowInvalidConsultingTypeException_WhenConsultingTypeIsInvalid() { - this.agencyDTO.setConsultingType(-1); - new AgencyConsultingTypeValidator().validate(agencyDTO); + this.validateAgencyDto.setConsultingType(-1); + new AgencyConsultingTypeValidator().validate(validateAgencyDto); } @Test public void validate_Should_ThrowNoException_WhenConsultingTypeIsValid() { - this.agencyDTO.setConsultingType(CONSULTING_TYPE_AIDS.getValue()); - new AgencyConsultingTypeValidator().validate(agencyDTO); + this.validateAgencyDto.setConsultingType(CONSULTING_TYPE_AIDS.getValue()); + new AgencyConsultingTypeValidator().validate(validateAgencyDto); } } diff --git a/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDioceseValidatorTest.java b/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDioceseValidatorTest.java index 7e369323..229c8884 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDioceseValidatorTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyDioceseValidatorTest.java @@ -2,8 +2,8 @@ import static org.mockito.Mockito.when; +import de.caritas.cob.agencyservice.api.admin.validation.validators.model.ValidateAgencyDto; import de.caritas.cob.agencyservice.api.exception.httpresponses.InvalidDioceseException; -import de.caritas.cob.agencyservice.api.model.AgencyDTO; import de.caritas.cob.agencyservice.api.repository.diocese.Diocese; import de.caritas.cob.agencyservice.api.repository.diocese.DioceseRepository; import java.util.Optional; @@ -24,27 +24,27 @@ public class AgencyDioceseValidatorTest { DioceseRepository dioceseRepository; Long dioceseId = 1L; - private AgencyDTO agencyDTO; + private ValidateAgencyDto validateAgencyDto; private final Diocese diocese = new Diocese(); @Before public void setup() { EasyRandom easyRandom = new EasyRandom(); - this.agencyDTO = easyRandom.nextObject(AgencyDTO.class); + this.validateAgencyDto = easyRandom.nextObject(ValidateAgencyDto.class); } @Test(expected = InvalidDioceseException.class) public void validate_Should_ThrowInvalidDioceseException_WhenDioceseIsInvalid() { when(dioceseRepository.findById(dioceseId)).thenReturn(Optional.empty()); - this.agencyDTO.setDioceseId(dioceseId); - agencyDioceseValidator.validate(agencyDTO); + this.validateAgencyDto.setDioceseId(dioceseId); + agencyDioceseValidator.validate(validateAgencyDto); } @Test public void validate_Should_ThrowNoException_WhenDioceseIsValid() { when(dioceseRepository.findById(dioceseId)).thenReturn(Optional.of(this.diocese)); - this.agencyDTO.setDioceseId(dioceseId); - agencyDioceseValidator.validate(agencyDTO); + this.validateAgencyDto.setDioceseId(dioceseId); + agencyDioceseValidator.validate(validateAgencyDto); } } diff --git a/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyPostcodeValidatorTest.java b/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyPostcodeValidatorTest.java index e295894f..43eefa13 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyPostcodeValidatorTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/admin/validation/validators/AgencyPostcodeValidatorTest.java @@ -3,37 +3,37 @@ import static de.caritas.cob.agencyservice.testHelper.TestConstants.INVALID_POSTCODE; import static de.caritas.cob.agencyservice.testHelper.TestConstants.VALID_FULL_POSTCODE; +import de.caritas.cob.agencyservice.api.admin.validation.validators.model.ValidateAgencyDto; import de.caritas.cob.agencyservice.api.exception.httpresponses.InvalidPostcodeException; -import de.caritas.cob.agencyservice.api.model.AgencyDTO; import org.jeasy.random.EasyRandom; import org.junit.Before; import org.junit.Test; public class AgencyPostcodeValidatorTest { - private AgencyDTO agencyDTO; + private ValidateAgencyDto validateAgencyDto; @Before public void setup() { EasyRandom easyRandom = new EasyRandom(); - this.agencyDTO = easyRandom.nextObject(AgencyDTO.class); + this.validateAgencyDto = easyRandom.nextObject(ValidateAgencyDto.class); } @Test(expected = InvalidPostcodeException.class) public void validate_Should_ThrowInvalidPostcodeException_WhenPostcodeIsInvalid() { - this.agencyDTO.setPostcode(INVALID_POSTCODE); - new AgencyPostcodeValidator().validate(agencyDTO); + this.validateAgencyDto.setPostcode(INVALID_POSTCODE); + new AgencyPostcodeValidator().validate(validateAgencyDto); } @Test public void validate_Should_ThrowNoException_WhenPostcodeIsValid() { - this.agencyDTO.setPostcode(VALID_FULL_POSTCODE); - new AgencyPostcodeValidator().validate(agencyDTO); + this.validateAgencyDto.setPostcode(VALID_FULL_POSTCODE); + new AgencyPostcodeValidator().validate(validateAgencyDto); } @Test public void validate_ShouldNot_ThrowInvalidPostcodeException_WhenPostcodeIsNull() { - this.agencyDTO.setPostcode(null); - new AgencyPostcodeValidator().validate(agencyDTO); + this.validateAgencyDto.setPostcode(null); + new AgencyPostcodeValidator().validate(validateAgencyDto); } }