use of ca.uhn.fhir.rest.server.exceptions.UnclassifiedServerFailureException 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.UnclassifiedServerFailureException in project gpconnect-demonstrator by nhsconnect.
the class CertificateValidator method validateRequest.
public void validateRequest(HttpServletRequest request) {
try {
if (request.isSecure() && !HttpMethod.OPTIONS.name().equals(request.getMethod()) && (env.getProperty("clientAuth") == null || !env.getProperty("clientAuth").equals("false"))) {
X509Certificate[] certificates = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
if (certificates == null) {
throw new CertificateException("No certificate found!", 496);
}
X509Certificate certificate = certificates[0];
if (logCertsToConsole) {
System.out.println("Known Certs: ");
for (X509Certificate knownCert : storeCertificates) {
System.out.println(knownCert.toString());
}
System.out.println("Recieved Cert: ");
System.out.println(certificate.toString());
}
if (!storeCertificates.contains(certificate)) {
String message = getCertificateError(certificate);
throw new CertificateException(message, 495);
}
}
} catch (CertificateException certificateException) {
StringBuilder requestURL = new StringBuilder(request.getRequestURL());
String queryString = request.getQueryString();
if (null != queryString) {
requestURL.append('?').append(queryString);
}
String warningMsg = "Bad signature detected for " + request.getMethod() + " to " + requestURL + ": " + certificateException.getMessage();
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnclassifiedServerFailureException(certificateException.getStatusCode(), warningMsg), SystemCode.BAD_REQUEST, IssueType.FORBIDDEN);
} catch (InvalidNameException ex) {
java.util.logging.Logger.getLogger(CertificateValidator.class.getName()).log(Level.SEVERE, null, ex);
}
}
use of ca.uhn.fhir.rest.server.exceptions.UnclassifiedServerFailureException in project gpconnect-demonstrator by nhsconnect.
the class PatientResourceProvider method registerPatient.
@Operation(name = REGISTER_PATIENT_OPERATION_NAME)
public Bundle registerPatient(@ResourceParam Parameters params) {
Patient registeredPatient = null;
validateParameterNames(params, registerPatientParams);
Patient unregisteredPatient = params.getParameter().stream().filter(param -> "registerPatient".equalsIgnoreCase(param.getName())).map(ParametersParameterComponent::getResource).map(Patient.class::cast).findFirst().orElse(null);
String nnn = nhsNumber.fromPatientResource(unregisteredPatient);
// if its patient 14 spoof not on PDS and return the required error
if (nnn.equals(patientNotOnSpine)) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new InvalidRequestException(String.format("Patient (NHS number - %s) not present on PDS", nnn)), SystemCode.INVALID_PATIENT_DEMOGRAPHICS, IssueType.INVALID);
} else if (nnn.equals(patientSuperseded)) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new InvalidRequestException(String.format("Patient (NHS number - %s) is superseded", nnn)), SystemCode.INVALID_NHS_NUMBER, IssueType.INVALID);
}
if (unregisteredPatient != null) {
validatePatient(unregisteredPatient);
// check if the patient already exists
PatientDetails patientDetails = patientSearch.findPatient(nhsNumber.fromPatientResource(unregisteredPatient));
if (patientDetails == null || IsInactiveTemporaryPatient(patientDetails)) {
if (patientDetails == null) {
patientDetails = registerPatientResourceConverterToPatientDetail(unregisteredPatient);
patientStore.create(patientDetails);
} else {
// reactivate inactive non temporary patient
patientDetails.setRegistrationStatus(ACTIVE_REGISTRATION_STATUS);
updateAddressAndTelecom(unregisteredPatient, patientDetails);
patientStore.update(patientDetails);
}
try {
registeredPatient = patientDetailsToRegisterPatientResourceConverter(patientSearch.findPatient(unregisteredPatient.getIdentifierFirstRep().getValue()));
addPreferredBranchSurgeryExtension(registeredPatient);
} catch (FHIRException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if (patientDetails.isDeceased() || patientDetails.isSensitive()) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new InvalidRequestException(String.format("Patient (NHS number - %s) has invalid demographics", nnn)), SystemCode.INVALID_PATIENT_DEMOGRAPHICS, IssueType.INVALID);
} else {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnclassifiedServerFailureException(409, String.format("Patient (NHS number - %s) already exists", nnn)), SystemCode.DUPLICATE_REJECTED, IssueType.INVALID);
}
} else {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException("Patient record not found"), SystemCode.INVALID_PARAMETER, IssueType.INVALID);
}
Bundle bundle = new Bundle().setType(BundleType.SEARCHSET);
bundle.getMeta().addProfile(SystemURL.SD_GPC_SRCHSET_BUNDLE);
bundle.addEntry().setResource(registeredPatient);
return bundle;
}
use of ca.uhn.fhir.rest.server.exceptions.UnclassifiedServerFailureException in project gpconnect-demonstrator by nhsconnect.
the class WebTokenFactory method getWebToken.
/**
* @param requestDetails Hapi Fhir object describing request
* @param futureRequestLeeway JWT time leeway in seconds
* @return populated WebToken object
*/
WebToken getWebToken(RequestDetails requestDetails, int futureRequestLeeway) {
WebToken webToken = null;
String authorizationHeader = requestDetails.getHeader(HttpHeaders.AUTHORIZATION);
if (null == authorizationHeader) {
throwInvalidRequest400_BadRequestException(HttpHeaders.AUTHORIZATION + " header missing");
}
String[] authorizationHeaderComponents = authorizationHeader.split(" ");
if (authorizationHeaderComponents.length != 2 || !"Bearer".equalsIgnoreCase(authorizationHeaderComponents[0])) {
throwInvalidRequest400_BadRequestException(HttpHeaders.AUTHORIZATION + " header invalid");
}
String contentType = requestDetails.getHeader(HttpHeaders.CONTENT_TYPE);
if (contentType == null) {
if (Arrays.asList(RequestTypeEnum.POST, RequestTypeEnum.PUT).contains(requestDetails.getRequestType())) {
// NB Issue type is Incomplete not Invalid
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnclassifiedServerFailureException(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, "No content media type set"), SystemCode.BAD_REQUEST, IssueType.INCOMPLETE);
}
} else if (!CONTENT_TYPES.contains(contentType.split(";")[0])) {
throwUnsupportedMedia415_BadRequestException("Unsupported content media type");
}
String[] formatParam = requestDetails.getParameters().get("_format");
String acceptHeader = null == formatParam ? requestDetails.getHeader(HttpHeaders.ACCEPT) : formatParam[0];
// If it's still null, use the Content-Type header value
if (null == acceptHeader) {
acceptHeader = contentType;
}
if (acceptHeader == null || !CONTENT_TYPES.contains(acceptHeader.split(";")[0])) {
throwUnsupportedMedia415_BadRequestException("Unsupported accept media type");
}
try {
if (authorizationHeaderComponents[1].contains("==") || authorizationHeaderComponents[1].contains("/") || authorizationHeaderComponents[1].contains("+")) {
throwInvalidRequest400_BadRequestException("JWT must be encoded using Base64URL. Padding is not allowed");
}
String[] jWTParts = authorizationHeaderComponents[1].split("\\.");
if (jWTParts.length == 2) {
String headerJsonString = new String(Base64.getUrlDecoder().decode(jWTParts[0]));
validateJWTHeader(headerJsonString);
String claimsJsonString = new String(Base64.getUrlDecoder().decode(jWTParts[1]));
// This magically populates the WebToken data object
webToken = new ObjectMapper().readValue(claimsJsonString, WebToken.class);
jwtParseResourcesValidation(claimsJsonString);
} else {
throwInvalidRequest400_BadRequestException("Invalid number of JWT base 64 blocks " + jWTParts.length);
}
} catch (IllegalArgumentException iae) {
throwInvalidRequest400_BadRequestException("JWT is not Base 64");
} catch (JsonParseException ex) {
throwInvalidRequest400_BadRequestException(String.format("Invalid WebToken: JSON is not valid - %s", ex.getMessage()));
} catch (IOException ex) {
throwInvalidRequest400_BadRequestException("Invalid WebToken");
}
WebTokenValidator.validateWebToken(webToken, futureRequestLeeway);
return webToken;
}
Aggregations