-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MODELINKS-2 Create PUT endpoint (#2)
* MODELINKS-2 Create PUT endpoint Co-authored-by: Shans Kaluhin <[email protected]>
- Loading branch information
1 parent
8b7a026
commit 3367001
Showing
25 changed files
with
1,352 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ target/ | |
!**/src/test/**/target/ | ||
bin/ | ||
.checkstyle | ||
.jpb | ||
|
||
### STS ### | ||
.apt_generated | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
133 changes: 133 additions & 0 deletions
133
src/main/java/org/folio/entlinks/controller/ApiErrorHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
package org.folio.entlinks.controller; | ||
|
||
import static java.util.Collections.emptyList; | ||
import static org.apache.logging.log4j.Level.DEBUG; | ||
import static org.apache.logging.log4j.Level.WARN; | ||
import static org.folio.entlinks.model.type.ErrorCode.UNKNOWN_ERROR; | ||
import static org.folio.entlinks.model.type.ErrorCode.VALIDATION_ERROR; | ||
import static org.springframework.http.HttpStatus.BAD_REQUEST; | ||
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; | ||
import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
import javax.validation.ConstraintViolationException; | ||
import lombok.extern.log4j.Log4j2; | ||
import org.apache.logging.log4j.Level; | ||
import org.folio.entlinks.exception.RequestBodyValidationException; | ||
import org.folio.entlinks.model.type.ErrorCode; | ||
import org.folio.tenant.domain.dto.Error; | ||
import org.folio.tenant.domain.dto.Errors; | ||
import org.folio.tenant.domain.dto.Parameter; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.http.converter.HttpMessageNotReadableException; | ||
import org.springframework.validation.FieldError; | ||
import org.springframework.web.bind.MethodArgumentNotValidException; | ||
import org.springframework.web.bind.MissingServletRequestParameterException; | ||
import org.springframework.web.bind.annotation.ExceptionHandler; | ||
import org.springframework.web.bind.annotation.RestControllerAdvice; | ||
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; | ||
|
||
@Log4j2 | ||
@RestControllerAdvice | ||
public class ApiErrorHandler { | ||
|
||
private static ResponseEntity<Errors> buildResponseEntity(Exception e, HttpStatus status, ErrorCode code) { | ||
var errors = new Errors() | ||
.errors(List.of(new Error() | ||
.message(e.getMessage()) | ||
.type(e.getClass().getSimpleName()) | ||
.code(code.getValue()))) | ||
.totalRecords(1); | ||
return buildResponseEntity(errors, status); | ||
} | ||
|
||
private static ResponseEntity<Errors> buildResponseEntity(Errors errorResponse, HttpStatus status) { | ||
return ResponseEntity.status(status).body(errorResponse); | ||
} | ||
|
||
private static void logException(Level logLevel, Exception e) { | ||
log.log(logLevel, "Handling e", e); | ||
} | ||
|
||
private static Errors buildValidationError(Exception e, List<Parameter> parameters) { | ||
var error = new Error() | ||
.type(e.getClass().getSimpleName()) | ||
.code(VALIDATION_ERROR.getValue()) | ||
.message(e.getMessage()) | ||
.parameters(parameters); | ||
return new Errors().errors(List.of(error)).totalRecords(1); | ||
} | ||
|
||
@ExceptionHandler(Exception.class) | ||
public ResponseEntity<Errors> handleGlobalExceptions(Exception e) { | ||
logException(WARN, e); | ||
return buildResponseEntity(e, INTERNAL_SERVER_ERROR, UNKNOWN_ERROR); | ||
} | ||
|
||
@ExceptionHandler(RequestBodyValidationException.class) | ||
public ResponseEntity<Errors> handleRequestValidationException(RequestBodyValidationException e) { | ||
logException(DEBUG, e); | ||
var errorResponse = buildValidationError(e, e.getInvalidParameters()); | ||
return buildResponseEntity(errorResponse, UNPROCESSABLE_ENTITY); | ||
} | ||
|
||
@ExceptionHandler(MethodArgumentNotValidException.class) | ||
public ResponseEntity<Errors> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { | ||
logException(DEBUG, e); | ||
var errors = Optional.of(e.getBindingResult()) | ||
.map(org.springframework.validation.Errors::getAllErrors) | ||
.orElse(emptyList()) | ||
.stream() | ||
.map(error -> new Error() | ||
.message(error.getDefaultMessage()) | ||
.code(VALIDATION_ERROR.getValue()) | ||
.type(MethodArgumentNotValidException.class.getSimpleName()) | ||
.addParametersItem(new Parameter() | ||
.key(((FieldError) error).getField()) | ||
.value(String.valueOf(((FieldError) error).getRejectedValue())))) | ||
.toList(); | ||
|
||
var errorResponse = new Errors().errors(errors).totalRecords(errors.size()); | ||
return buildResponseEntity(errorResponse, UNPROCESSABLE_ENTITY); | ||
} | ||
|
||
@ExceptionHandler(ConstraintViolationException.class) | ||
public ResponseEntity<Errors> handleConstraintViolation(ConstraintViolationException e) { | ||
logException(DEBUG, e); | ||
var errors = e.getConstraintViolations().stream() | ||
.map(constraintViolation -> new Error() | ||
.message(String.format("%s %s", constraintViolation.getPropertyPath(), constraintViolation.getMessage())) | ||
.code(VALIDATION_ERROR.getValue()) | ||
.type(ConstraintViolationException.class.getSimpleName())) | ||
.toList(); | ||
|
||
var errorResponse = new Errors().errors(errors).totalRecords(errors.size()); | ||
return buildResponseEntity(errorResponse, BAD_REQUEST); | ||
} | ||
|
||
@ExceptionHandler({ | ||
MethodArgumentTypeMismatchException.class, | ||
MissingServletRequestParameterException.class, | ||
IllegalArgumentException.class | ||
}) | ||
public ResponseEntity<Errors> handleValidationException(Exception e) { | ||
logException(DEBUG, e); | ||
return buildResponseEntity(e, BAD_REQUEST, VALIDATION_ERROR); | ||
} | ||
|
||
@ExceptionHandler(HttpMessageNotReadableException.class) | ||
public ResponseEntity<Errors> handlerHttpMessageNotReadableException(HttpMessageNotReadableException e) { | ||
return Optional.ofNullable(e.getCause()) | ||
.map(Throwable::getCause) | ||
.filter(IllegalArgumentException.class::isInstance) | ||
.map(IllegalArgumentException.class::cast) | ||
.map(this::handleValidationException) | ||
.orElseGet(() -> { | ||
logException(DEBUG, e); | ||
return buildResponseEntity(e, BAD_REQUEST, VALIDATION_ERROR); | ||
}); | ||
} | ||
|
||
} |
22 changes: 22 additions & 0 deletions
22
src/main/java/org/folio/entlinks/controller/InstanceLinksController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package org.folio.entlinks.controller; | ||
|
||
import java.util.UUID; | ||
import lombok.RequiredArgsConstructor; | ||
import org.folio.entlinks.service.InstanceLinkService; | ||
import org.folio.qm.domain.dto.InstanceLinkDtoCollection; | ||
import org.folio.qm.rest.resource.InstanceLinksApi; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
public class InstanceLinksController implements InstanceLinksApi { | ||
|
||
private final InstanceLinkService instanceLinkService; | ||
|
||
@Override | ||
public ResponseEntity<Void> updateInstanceLinks(UUID instanceId, InstanceLinkDtoCollection instanceLinkCollection) { | ||
instanceLinkService.updateInstanceLinks(instanceId, instanceLinkCollection); | ||
return ResponseEntity.noContent().build(); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
src/main/java/org/folio/entlinks/exception/BaseException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package org.folio.entlinks.exception; | ||
|
||
import lombok.Getter; | ||
import org.folio.entlinks.model.type.ErrorCode; | ||
|
||
/** | ||
* Base exception class that is used for all exceptional situations | ||
*/ | ||
@Getter | ||
public abstract class BaseException extends RuntimeException { | ||
|
||
private final ErrorCode errorCode; | ||
|
||
/** | ||
* Initialize exception with provided message and error code. | ||
* | ||
* @param message exception message | ||
* @param errorCode exception code {@link ErrorCode} | ||
*/ | ||
protected BaseException(String message, ErrorCode errorCode) { | ||
super(message); | ||
this.errorCode = errorCode; | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
src/main/java/org/folio/entlinks/exception/RequestBodyValidationException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package org.folio.entlinks.exception; | ||
|
||
import java.util.List; | ||
import lombok.Getter; | ||
import org.folio.entlinks.model.type.ErrorCode; | ||
import org.folio.tenant.domain.dto.Parameter; | ||
|
||
/** | ||
* Exception for situations when request body is invalid | ||
*/ | ||
@Getter | ||
public class RequestBodyValidationException extends BaseException { | ||
|
||
private final transient List<Parameter> invalidParameters; | ||
|
||
/** | ||
* Initialize exception with provided message, error code and invalid parameters. | ||
* | ||
* @param message exception message | ||
* @param invalidParameters list of invalid parameters {@link Parameter} | ||
*/ | ||
public RequestBodyValidationException(String message, List<Parameter> invalidParameters) { | ||
super(message, ErrorCode.VALIDATION_ERROR); | ||
this.invalidParameters = invalidParameters; | ||
} | ||
|
||
} |
13 changes: 13 additions & 0 deletions
13
src/main/java/org/folio/entlinks/model/converter/InstanceLinkMapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package org.folio.entlinks.model.converter; | ||
|
||
import org.folio.entlinks.model.entity.InstanceLink; | ||
import org.folio.qm.domain.dto.InstanceLinkDto; | ||
import org.mapstruct.Mapper; | ||
|
||
@Mapper(componentModel = "spring") | ||
public interface InstanceLinkMapper { | ||
|
||
InstanceLinkDto convert(InstanceLink source); | ||
|
||
InstanceLink convert(InstanceLinkDto source); | ||
} |
81 changes: 81 additions & 0 deletions
81
src/main/java/org/folio/entlinks/model/entity/InstanceLink.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package org.folio.entlinks.model.entity; | ||
|
||
import com.vladmihalcea.hibernate.type.array.ListArrayType; | ||
import java.util.List; | ||
import java.util.Objects; | ||
import java.util.UUID; | ||
import javax.persistence.Column; | ||
import javax.persistence.Entity; | ||
import javax.persistence.GeneratedValue; | ||
import javax.persistence.GenerationType; | ||
import javax.persistence.Id; | ||
import javax.persistence.Index; | ||
import javax.persistence.Table; | ||
import javax.validation.constraints.NotNull; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
import lombok.ToString; | ||
import org.hibernate.Hibernate; | ||
import org.hibernate.annotations.Type; | ||
import org.hibernate.annotations.TypeDef; | ||
|
||
@Getter | ||
@Setter | ||
@ToString | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
@Builder | ||
@Entity | ||
@Table(name = "instance_link", indexes = { | ||
@Index(name = "idx_instancelink_authority_id", columnList = "authority_id"), | ||
@Index(name = "idx_instancelink_instance_id", columnList = "instance_id") | ||
}) | ||
@TypeDef(name = "list-array", typeClass = ListArrayType.class) | ||
public class InstanceLink { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Column(name = "id", nullable = false) | ||
private Long id; | ||
|
||
@NotNull | ||
@Column(name = "authority_id", nullable = false) | ||
private UUID authorityId; | ||
|
||
@NotNull | ||
@Column(name = "authority_natural_id", nullable = false, length = 100) | ||
private String authorityNaturalId; | ||
|
||
@NotNull | ||
@Column(name = "instance_id", nullable = false) | ||
private UUID instanceId; | ||
|
||
@Column(name = "bib_record_tag", length = 3) | ||
private String bibRecordTag; | ||
|
||
@Type(type = "list-array") | ||
@Column(name = "bib_record_subfields") | ||
private List<String> bibRecordSubfields; | ||
|
||
@Override | ||
public int hashCode() { | ||
return getClass().hashCode(); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { return true; } | ||
if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) { return false; } | ||
InstanceLink instanceLink = (InstanceLink) o; | ||
return id != null && Objects.equals(id, instanceLink.id); | ||
} | ||
|
||
public boolean isSameLink(InstanceLink link) { | ||
return authorityId.equals(link.authorityId) | ||
&& instanceId.equals(link.instanceId) | ||
&& bibRecordTag.equals(link.bibRecordTag); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
src/main/java/org/folio/entlinks/model/type/ErrorCode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package org.folio.entlinks.model.type; | ||
|
||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Getter | ||
@RequiredArgsConstructor | ||
public enum ErrorCode { | ||
|
||
VALIDATION_ERROR("validation"), | ||
UNKNOWN_ERROR("unknown"); | ||
|
||
private final String value; | ||
} |
12 changes: 12 additions & 0 deletions
12
src/main/java/org/folio/entlinks/repository/InstanceLinkRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package org.folio.entlinks.repository; | ||
|
||
import java.util.List; | ||
import java.util.UUID; | ||
import org.folio.entlinks.model.entity.InstanceLink; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface InstanceLinkRepository extends JpaRepository<InstanceLink, Long> { | ||
|
||
List<InstanceLink> findByInstanceId(UUID instanceId); | ||
|
||
} |
Oops, something went wrong.