Search in sources :

Example 1 with PreconditionFailedException

use of org.ehrbase.api.exception.PreconditionFailedException in project ehrbase by ehrbase.

the class OpenehrEhrStatusController method updateEhrStatus.

/**
 * {@inheritDoc}
 */
@Override
@PutMapping
@PreAuthorize("checkAbacPre(@openehrEhrStatusController.EHR_STATUS, @ehrService.getSubjectExtRef(#ehrIdString))")
public ResponseEntity<EhrStatusResponseData> updateEhrStatus(@PathVariable("ehr_id") UUID ehrId, @RequestHeader(name = IF_MATCH) String versionUid, @RequestHeader(name = PREFER, required = false) String prefer, @RequestHeader(name = HttpHeaders.ACCEPT, required = false) String accept, @RequestHeader(name = HttpHeaders.CONTENT_TYPE, required = false) String contentType, @RequestBody EhrStatus ehrStatus) {
    assertEhrExists(ehrId);
    // If-Match header check
    String latestVersionUid = ehrService.getLatestVersionUidOfStatus(ehrId);
    if (!latestVersionUid.equals(versionUid)) {
        throw new PreconditionFailedException("Given If-Match header does not match latest existing version");
    }
    // update EHR_STATUS and check for success
    Optional<EhrStatus> updateStatus = ehrService.updateStatus(ehrId, ehrStatus, null);
    EhrStatus status = updateStatus.orElseThrow(() -> new InvalidApiParameterException("Could not update EHR_STATUS"));
    // update and prepare current version number
    String newLatestVersionUid = ehrService.getLatestVersionUidOfStatus(ehrId);
    String[] split = latestVersionUid.split("::");
    if (latestVersionUid.equals(newLatestVersionUid) || split.length != 3) {
        throw new InvalidApiParameterException("Update of EHR_STATUS failed");
    }
    int version = Integer.parseInt(split[split.length - 1]) + 1;
    List<String> headerList = Arrays.asList(CONTENT_TYPE, LOCATION, ETAG, // whatever is required by REST spec
    LAST_MODIFIED);
    // variable to overload with more specific object if requested
    Optional<InternalResponse<EhrStatusResponseData>> respData;
    UUID statusUid = UUID.fromString(status.getUid().getValue().split("::")[0]);
    respData = buildEhrStatusResponseData(EhrStatusResponseData::new, ehrId, statusUid, version, accept, headerList);
    return respData.map(i -> ResponseEntity.ok().headers(i.getHeaders()).body(i.getResponseData())).orElse(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build());
}
Also used : InvalidApiParameterException(org.ehrbase.api.exception.InvalidApiParameterException) PathVariable(org.springframework.web.bind.annotation.PathVariable) Arrays(java.util.Arrays) RequestParam(org.springframework.web.bind.annotation.RequestParam) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize) ObjectNotFoundException(org.ehrbase.api.exception.ObjectNotFoundException) RequestMapping(org.springframework.web.bind.annotation.RequestMapping) EhrService(org.ehrbase.api.service.EhrService) Supplier(java.util.function.Supplier) RequestBody(org.springframework.web.bind.annotation.RequestBody) PutMapping(org.springframework.web.bind.annotation.PutMapping) GetMapping(org.springframework.web.bind.annotation.GetMapping) URI(java.net.URI) PreconditionFailedException(org.ehrbase.api.exception.PreconditionFailedException) HttpHeaders(org.springframework.http.HttpHeaders) Timestamp(java.sql.Timestamp) MediaType(org.springframework.http.MediaType) UUID(java.util.UUID) RestController(org.springframework.web.bind.annotation.RestController) BaseController(org.ehrbase.rest.BaseController) HttpStatus(org.springframework.http.HttpStatus) List(java.util.List) OffsetDateTime(java.time.OffsetDateTime) InternalServerException(org.ehrbase.api.exception.InternalServerException) EhrStatusResponseData(org.ehrbase.response.openehr.EhrStatusResponseData) InvalidApiParameterException(org.ehrbase.api.exception.InvalidApiParameterException) InternalResponse(org.ehrbase.rest.util.InternalResponse) Optional(java.util.Optional) ResponseEntity(org.springframework.http.ResponseEntity) RequestHeader(org.springframework.web.bind.annotation.RequestHeader) OriginalVersion(com.nedap.archie.rm.changecontrol.OriginalVersion) EhrStatusApiSpecification(org.ehrbase.rest.openehr.specification.EhrStatusApiSpecification) EhrStatus(com.nedap.archie.rm.ehr.EhrStatus) EhrStatus(com.nedap.archie.rm.ehr.EhrStatus) PreconditionFailedException(org.ehrbase.api.exception.PreconditionFailedException) InternalResponse(org.ehrbase.rest.util.InternalResponse) UUID(java.util.UUID) PutMapping(org.springframework.web.bind.annotation.PutMapping) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Example 2 with PreconditionFailedException

use of org.ehrbase.api.exception.PreconditionFailedException in project ehrbase by ehrbase.

the class OpenehrCompositionController method updateComposition.

@PutMapping("/{ehr_id}/composition/{versioned_object_uid}")
// checkAbacPre /-Post attributes (type, subject, payload, content type)
@PreAuthorize("checkAbacPre(@openehrCompositionController.COMPOSITION, " + "@ehrService.getSubjectExtRef(#ehrIdString), #composition, #contentType)")
@Override
public ResponseEntity updateComposition(String openehrVersion, @RequestHeader(value = "openEHR-AUDIT_DETAILS", required = false) String openehrAuditDetails, @RequestHeader(value = CONTENT_TYPE, required = false) String contentType, @RequestHeader(value = ACCEPT, required = false) String accept, @RequestHeader(value = PREFER, required = false) String prefer, @RequestHeader(value = IF_MATCH) String ifMatch, @PathVariable(value = "ehr_id") String ehrIdString, @PathVariable(value = "versioned_object_uid") String versionedObjectUidString, @RequestBody String composition, HttpServletRequest request) {
    UUID ehrId = getEhrUuid(ehrIdString);
    UUID versionedObjectUid = getCompositionVersionedObjectUidString(versionedObjectUidString);
    CompositionFormat compositionFormat = extractCompositionFormat(contentType);
    // check if composition ID path variable is valid
    compositionService.exists(versionedObjectUid);
    // If the If-Match is not the latest latest existing version, throw error
    if (!((versionedObjectUid + "::" + compositionService.getServerConfig().getNodename() + "::" + compositionService.getLastVersionNumber(extractVersionedObjectUidFromVersionUid(versionedObjectUid.toString()))).equals(ifMatch))) {
        throw new PreconditionFailedException("If-Match header does not match latest existing version");
    }
    // If body already contains a composition uid it must match the {versioned_object_uid} in request url
    Optional<String> inputUuid = Optional.ofNullable(compositionService.getUidFromInputComposition(composition, compositionFormat));
    inputUuid.ifPresent(id -> {
        // TODO it is further unclear what exactly the REST spec's "match" means, see: https://github.com/openEHR/specifications-ITS-REST/issues/83
        if (!versionedObjectUid.equals(extractVersionedObjectUidFromVersionUid(id))) {
            throw new PreconditionFailedException("UUID from input must match given versioned_object_uid in request URL");
        }
    });
    // variable to overload with more specific object if requested
    Optional<InternalResponse<CompositionResponseData>> respData = Optional.empty();
    try {
        Composition compoObj = compositionService.buildComposition(composition, compositionFormat, null);
        // TODO should have EHR as parameter and check for existence as precondition - see EHR-245 (no direct EHR access in this controller)
        // ifMatch header has to be tested for correctness already above
        Optional<CompositionDto> dtoOptional = compositionService.update(ehrId, new ObjectVersionId(ifMatch), compoObj);
        var compositionVersionUid = dtoOptional.orElseThrow(() -> new InternalServerException("Failed to create composition")).getComposition().getUid().toString();
        var uri = URI.create(this.encodePath(getBaseEnvLinkURL() + "/rest/openehr/v1/ehr/" + ehrId.toString() + "/composition/" + compositionVersionUid));
        List<String> headerList = Arrays.asList(LOCATION, ETAG, // whatever is required by REST spec - CONTENT_TYPE only needed for 200, so handled separately
        LAST_MODIFIED);
        UUID compositionId = extractVersionedObjectUidFromVersionUid(compositionVersionUid);
        if (RETURN_REPRESENTATION.equals(prefer)) {
            // both options extract needed info from versionUid
            respData = buildCompositionResponseData(compositionId, extractVersionFromVersionUid(compositionVersionUid), accept, uri, headerList, () -> new CompositionResponseData(null, null));
        } else {
            // "minimal" is default fallback
            respData = buildCompositionResponseData(compositionId, extractVersionFromVersionUid(compositionVersionUid), accept, uri, headerList, () -> null);
        }
        // Enriches request attributes with current compositionId for later audit processing
        request.setAttribute(OpenEhrAuditInterceptor.EHR_ID_ATTRIBUTE, Collections.singleton(ehrId));
        request.setAttribute(CompositionAuditInterceptor.COMPOSITION_ID_ATTRIBUTE, compositionId);
    } catch (ObjectNotFoundException e) {
        // composition not found
        return ResponseEntity.notFound().build();
    }
    // returns 200 with body + headers, 204 only with headers or 500 error depending on what processing above yields
    return respData.map(i -> Optional.ofNullable(i.getResponseData()).map(StructuredString::getValue).map(j -> ResponseEntity.ok().headers(i.getHeaders()).body(j)).orElse(ResponseEntity.noContent().headers(i.getHeaders()).build())).orElse(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build());
}
Also used : CompositionResponseData(org.ehrbase.response.openehr.CompositionResponseData) PathVariable(org.springframework.web.bind.annotation.PathVariable) Arrays(java.util.Arrays) RequestParam(org.springframework.web.bind.annotation.RequestParam) Composition(com.nedap.archie.rm.composition.Composition) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize) ZonedDateTime(java.time.ZonedDateTime) LocalDateTime(java.time.LocalDateTime) ObjectNotFoundException(org.ehrbase.api.exception.ObjectNotFoundException) Autowired(org.springframework.beans.factory.annotation.Autowired) RequestMapping(org.springframework.web.bind.annotation.RequestMapping) Supplier(java.util.function.Supplier) RequestBody(org.springframework.web.bind.annotation.RequestBody) HttpServletRequest(javax.servlet.http.HttpServletRequest) PutMapping(org.springframework.web.bind.annotation.PutMapping) CompositionResponseData(org.ehrbase.response.openehr.CompositionResponseData) CompositionAuditInterceptor(org.ehrbase.rest.openehr.audit.CompositionAuditInterceptor) GetMapping(org.springframework.web.bind.annotation.GetMapping) URI(java.net.URI) PreconditionFailedException(org.ehrbase.api.exception.PreconditionFailedException) ObjectVersionId(com.nedap.archie.rm.support.identification.ObjectVersionId) ResponseStatus(org.springframework.web.bind.annotation.ResponseStatus) DeleteMapping(org.springframework.web.bind.annotation.DeleteMapping) PostMapping(org.springframework.web.bind.annotation.PostMapping) HttpHeaders(org.springframework.http.HttpHeaders) MediaType(org.springframework.http.MediaType) CompositionDto(org.ehrbase.response.ehrscape.CompositionDto) PostAuthorize(org.springframework.security.access.prepost.PostAuthorize) UUID(java.util.UUID) RestController(org.springframework.web.bind.annotation.RestController) ZoneId(java.time.ZoneId) StructuredString(org.ehrbase.response.ehrscape.StructuredString) BaseController(org.ehrbase.rest.BaseController) Objects(java.util.Objects) HttpStatus(org.springframework.http.HttpStatus) List(java.util.List) OffsetDateTime(java.time.OffsetDateTime) CompositionService(org.ehrbase.api.service.CompositionService) InternalServerException(org.ehrbase.api.exception.InternalServerException) OpenEhrAuditInterceptor(org.ehrbase.rest.openehr.audit.OpenEhrAuditInterceptor) InternalResponse(org.ehrbase.rest.util.InternalResponse) Optional(java.util.Optional) CompositionApiSpecification(org.ehrbase.rest.openehr.specification.CompositionApiSpecification) ResponseEntity(org.springframework.http.ResponseEntity) RequestHeader(org.springframework.web.bind.annotation.RequestHeader) Collections(java.util.Collections) CompositionFormat(org.ehrbase.response.ehrscape.CompositionFormat) CompositionFormat(org.ehrbase.response.ehrscape.CompositionFormat) Composition(com.nedap.archie.rm.composition.Composition) InternalServerException(org.ehrbase.api.exception.InternalServerException) StructuredString(org.ehrbase.response.ehrscape.StructuredString) InternalResponse(org.ehrbase.rest.util.InternalResponse) ObjectVersionId(com.nedap.archie.rm.support.identification.ObjectVersionId) ObjectNotFoundException(org.ehrbase.api.exception.ObjectNotFoundException) CompositionDto(org.ehrbase.response.ehrscape.CompositionDto) StructuredString(org.ehrbase.response.ehrscape.StructuredString) PreconditionFailedException(org.ehrbase.api.exception.PreconditionFailedException) UUID(java.util.UUID) PutMapping(org.springframework.web.bind.annotation.PutMapping) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Example 3 with PreconditionFailedException

use of org.ehrbase.api.exception.PreconditionFailedException in project ehrbase by ehrbase.

the class OpenehrDirectoryController method checkDirectoryVersionConflicts.

private void checkDirectoryVersionConflicts(ObjectVersionId requestedFolderId, UUID ehrId) {
    UUID directoryUuid = ehrService.getDirectoryId(ehrId);
    int latestVersion = folderService.getLastVersionNumber(new ObjectVersionId(directoryUuid.toString()));
    // TODO: Change column 'directory' in EHR to String with ObjectVersionId
    String directoryId = String.format("%s::%s::%d", directoryUuid, ehrService.getServerConfig().getNodename(), latestVersion);
    if (requestedFolderId != null && !requestedFolderId.toString().equals(directoryId)) {
        throw new PreconditionFailedException("If-Match version_uid does not match latest version.", directoryId, encodePath(getBaseEnvLinkURL() + "/rest/openehr/v1/ehr/" + ehrId.toString() + "/directory/" + directoryId));
    }
}
Also used : PreconditionFailedException(org.ehrbase.api.exception.PreconditionFailedException) ObjectVersionId(com.nedap.archie.rm.support.identification.ObjectVersionId) UUID(java.util.UUID)

Aggregations

UUID (java.util.UUID)3 PreconditionFailedException (org.ehrbase.api.exception.PreconditionFailedException)3 ObjectVersionId (com.nedap.archie.rm.support.identification.ObjectVersionId)2 URI (java.net.URI)2 OffsetDateTime (java.time.OffsetDateTime)2 Arrays (java.util.Arrays)2 List (java.util.List)2 Optional (java.util.Optional)2 Supplier (java.util.function.Supplier)2 InternalServerException (org.ehrbase.api.exception.InternalServerException)2 ObjectNotFoundException (org.ehrbase.api.exception.ObjectNotFoundException)2 BaseController (org.ehrbase.rest.BaseController)2 InternalResponse (org.ehrbase.rest.util.InternalResponse)2 HttpHeaders (org.springframework.http.HttpHeaders)2 HttpStatus (org.springframework.http.HttpStatus)2 MediaType (org.springframework.http.MediaType)2 ResponseEntity (org.springframework.http.ResponseEntity)2 PreAuthorize (org.springframework.security.access.prepost.PreAuthorize)2 GetMapping (org.springframework.web.bind.annotation.GetMapping)2 PathVariable (org.springframework.web.bind.annotation.PathVariable)2