use of ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException in project gpconnect-demonstrator by nhsconnect.
the class AppointmentResourceProvider method updateAppointment.
@Update
public MethodOutcome updateAppointment(@IdParam IdType appointmentId, @ResourceParam Appointment appointment) {
MethodOutcome methodOutcome = new MethodOutcome();
OperationOutcome operationalOutcome = new OperationOutcome();
AppointmentDetail appointmentDetail = appointmentResourceConverterToAppointmentDetail(appointment);
// URL ID and Resource ID must be the same
if (!Objects.equals(appointmentId.getIdPartAsLong(), appointmentDetail.getId())) {
operationalOutcome.addIssue().setSeverity(IssueSeverity.ERROR).setDiagnostics("Id in URL (" + appointmentId.getIdPart() + ") should match Id in Resource (" + appointmentDetail.getId() + ")");
methodOutcome.setOperationOutcome(operationalOutcome);
return methodOutcome;
}
// Make sure there is an existing appointment to be amended
AppointmentDetail oldAppointmentDetail = appointmentSearch.findAppointmentByID(appointmentId.getIdPartAsLong());
if (oldAppointmentDetail == null) {
operationalOutcome.addIssue().setSeverity(IssueSeverity.ERROR).setDiagnostics("No appointment details found for ID: " + appointmentId.getIdPart());
methodOutcome.setOperationOutcome(operationalOutcome);
return methodOutcome;
}
String oldAppointmentVersionId = String.valueOf(oldAppointmentDetail.getLastUpdated().getTime());
String newAppointmentVersionId = appointmentId.getVersionIdPart();
if (newAppointmentVersionId != null && !newAppointmentVersionId.equalsIgnoreCase(oldAppointmentVersionId)) {
throw new ResourceVersionConflictException("The specified version (" + newAppointmentVersionId + ") did not match the current resource version (" + oldAppointmentVersionId + ")");
}
// Determin if it is a cancel or an amend
if (appointmentDetail.getCancellationReason() != null) {
if (appointmentDetail.getCancellationReason().isEmpty()) {
operationalOutcome.addIssue().setSeverity(IssueSeverity.ERROR).setDiagnostics("The cancellation reason can not be blank");
methodOutcome.setOperationOutcome(operationalOutcome);
return methodOutcome;
}
// This is a Cancellation - so copy across fields which can be
// altered
boolean cancelComparisonResult = compareAppointmentsForInvalidPropertyCancel(oldAppointmentDetail, appointmentDetail);
if (cancelComparisonResult) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnclassifiedServerFailureException(400, "Invalid Appointment property has been amended (cancellation)"), SystemCode.BAD_REQUEST, IssueType.FORBIDDEN);
}
oldAppointmentDetail.setCancellationReason(appointmentDetail.getCancellationReason());
String oldStatus = oldAppointmentDetail.getStatus();
appointmentDetail = oldAppointmentDetail;
appointmentDetail.setStatus("cancelled");
if (!"cancelled".equalsIgnoreCase(oldStatus)) {
for (Long slotId : appointmentDetail.getSlotIds()) {
SlotDetail slotDetail = slotSearch.findSlotByID(slotId);
// slotDetail.setAppointmentId(null);
slotDetail.setFreeBusyType("FREE");
slotDetail.setLastUpdated(new Date());
slotStore.saveSlot(slotDetail);
}
}
} else {
if (appointment.getStatus().equals("cancelled")) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnclassifiedServerFailureException(400, "Appointment has been cancelled and cannot be amended"), SystemCode.BAD_REQUEST, IssueType.FORBIDDEN);
}
boolean amendComparisonResult = compareAppointmentsForInvalidPropertyAmend(appointmentDetail, oldAppointmentDetail);
if (amendComparisonResult) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnclassifiedServerFailureException(403, "Invalid Appointment property has been amended"), SystemCode.BAD_REQUEST, IssueType.FORBIDDEN);
}
// This is an Amend
oldAppointmentDetail.setComment(appointmentDetail.getComment());
oldAppointmentDetail.setReasonCode(appointmentDetail.getReasonCode());
oldAppointmentDetail.setDescription(appointmentDetail.getDescription());
oldAppointmentDetail.setReasonDisplay(appointmentDetail.getReasonDisplay());
oldAppointmentDetail.setTypeCode(appointmentDetail.getTypeCode());
oldAppointmentDetail.setTypeDisplay(appointmentDetail.getTypeDisplay());
appointmentDetail = oldAppointmentDetail;
}
List<SlotDetail> slots = new ArrayList<>();
for (Long slotId : appointmentDetail.getSlotIds()) {
SlotDetail slotDetail = slotSearch.findSlotByID(slotId);
if (slotDetail == null) {
throw new UnprocessableEntityException("Slot resource reference is not a valid resource");
}
slots.add(slotDetail);
}
// Update version and
appointmentDetail.setLastUpdated(new Date());
// lastUpdated timestamp
appointmentDetail = appointmentStore.saveAppointment(appointmentDetail, slots);
methodOutcome.setId(new IdDt("Appointment", appointmentDetail.getId()));
methodOutcome.setResource(appointmentDetailToAppointmentResourceConverter(appointmentDetail));
return methodOutcome;
}
use of ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException in project gpconnect-demonstrator by nhsconnect.
the class FhirRequestGenericIntercepter method preProcessOutgoingException.
/**
* Listens for any exceptions thrown. In the case of invalid parameters, we
* need to catch this and throw it as a UnprocessableEntityException.
*
* @param theRequestDetails
* @param theException
* @param theServletRequest
* @return UnprocessableEntityException if a InvalidRequestException was
* thrown.
* @throws javax.servlet.ServletException
*/
@Override
public BaseServerResponseException preProcessOutgoingException(RequestDetails theRequestDetails, Throwable theException, HttpServletRequest theServletRequest) throws ServletException {
LOG.info("Response Exception");
LOG.info(theException.getMessage());
LOG.info("stackTrace: ", theException);
// how else to pick up on just the relevant exceptions!
if (theException instanceof InvalidRequestException && theException.getMessage().contains("Invalid attribute value")) {
return OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException(theException.getMessage()), SystemCode.INVALID_PARAMETER, IssueType.INVALID);
}
if (theException instanceof InvalidRequestException && theException.getMessage().contains("Unknown resource in URI")) {
return OperationOutcomeFactory.buildOperationOutcomeException(new ResourceNotFoundException(theException.getMessage()), SystemCode.BAD_REQUEST, IssueType.INVALID);
}
if (theException instanceof InvalidRequestException && theException.getMessage().contains("Can not have multiple date range parameters for the same param ")) {
return OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException(theException.getMessage()), SystemCode.INVALID_PARAMETER, IssueType.INVALID);
}
if (theException instanceof DataFormatException) {
return OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException(theException.getMessage()), SystemCode.INVALID_PARAMETER, IssueType.INVALID);
}
if (theException instanceof MethodNotAllowedException && theException.getMessage().contains("request must use HTTP GET")) {
return OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException(theException.getMessage()), SystemCode.BAD_REQUEST, IssueType.INVALID);
}
if (theException instanceof InvalidRequestException && theException.getMessage().startsWith("Failed to parse request body as JSON resource. Error was: ")) {
// #250 422 INVALID_RESOURCE not 400 BAD_REQUEST
return OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException(theException.getMessage()), SystemCode.INVALID_RESOURCE, IssueType.INVALID);
}
if (theException instanceof InvalidRequestException && theException.getMessage().startsWith("Invalid request: ")) {
return OperationOutcomeFactory.buildOperationOutcomeException(new InvalidRequestException(theException.getMessage()), SystemCode.BAD_REQUEST, IssueType.INVALID);
}
if (theException instanceof InvalidRequestException && theException.getMessage().contains("non-repeatable parameter")) {
return OperationOutcomeFactory.buildOperationOutcomeException(new InvalidRequestException(theException.getMessage()), SystemCode.BAD_REQUEST, IssueType.INVALID);
}
if (theException instanceof InvalidRequestException && theException.getMessage().contains("header blank")) {
return OperationOutcomeFactory.buildOperationOutcomeException(new InvalidRequestException(theException.getMessage()), SystemCode.BAD_REQUEST, IssueType.INVALID);
}
if (theException instanceof InvalidRequestException && theException.getMessage().contains("InvalidResourceType")) {
return OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException(theException.getMessage()), SystemCode.INVALID_RESOURCE, IssueType.INVALID);
}
if (theException instanceof InvalidRequestException && theException.getMessage().contains("Can not create resource with ID")) {
return OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException(theException.getMessage()), SystemCode.BAD_REQUEST, IssueType.INVALID);
}
if (theException instanceof ResourceNotFoundException && theException.getMessage().contains("Unknown resource type")) {
return OperationOutcomeFactory.buildOperationOutcomeException((ResourceNotFoundException) theException, SystemCode.BAD_REQUEST, IssueType.INVALID);
}
// }
if (theException instanceof ResourceVersionConflictException && theException.getMessage().contains("Slot is already in use.")) {
ResourceVersionConflictException exception = (ResourceVersionConflictException) theException;
return OperationOutcomeFactory.buildOperationOutcomeException(exception, SystemCode.DUPLICATE_REJECTED, IssueType.CONFLICT);
}
if (theException instanceof ResourceVersionConflictException) {
ResourceVersionConflictException exception = (ResourceVersionConflictException) theException;
return OperationOutcomeFactory.buildOperationOutcomeException(exception, SystemCode.FHIR_CONSTRAINT_VIOLATION, IssueType.CONFLICT);
}
if (theException instanceof BaseServerResponseException) {
BaseServerResponseException baseServerResponseException = (BaseServerResponseException) theException;
// If the OperationalOutcome is already set, just return it.
return null == baseServerResponseException.getOperationOutcome() ? OperationOutcomeFactory.buildOperationOutcomeException(baseServerResponseException, SystemCode.BAD_REQUEST, IssueType.INVALID) : baseServerResponseException;
}
// Default catch all.
return OperationOutcomeFactory.buildOperationOutcomeException(new InvalidRequestException(theException.getMessage()), SystemCode.BAD_REQUEST, IssueType.INVALID);
}
Aggregations