All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ehrbase.rest.openehr.OpenehrEhrStatusController Maven / Gradle / Ivy

There is a newer version: 2.11.0
Show newest version
/*
 * Copyright (c) 2024 vitasystems GmbH.
 *
 * This file is part of project EHRbase
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.ehrbase.rest.openehr;

import static org.ehrbase.api.rest.HttpRestContext.DIRECTORY_ID;
import static org.ehrbase.api.rest.HttpRestContext.EHR_ID;
import static org.springframework.web.util.UriComponentsBuilder.fromPath;

import com.nedap.archie.rm.changecontrol.OriginalVersion;
import com.nedap.archie.rm.datavalues.quantity.datetime.DvDateTime;
import com.nedap.archie.rm.support.identification.ObjectVersionId;
import java.net.URI;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalQueries;
import java.util.UUID;
import org.ehrbase.api.dto.EhrStatusDto;
import org.ehrbase.api.exception.InvalidApiParameterException;
import org.ehrbase.api.exception.ObjectNotFoundException;
import org.ehrbase.api.rest.HttpRestContext;
import org.ehrbase.api.service.EhrService;
import org.ehrbase.rest.BaseController;
import org.ehrbase.rest.openehr.specification.EhrStatusApiSpecification;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * Controller for /ehr/{ehrId}/ehr_status resource of openEHR REST API
 */
@ConditionalOnMissingBean(name = "primaryopenehrehrstatuscontroller")
@RestController
@RequestMapping(path = BaseController.API_CONTEXT_PATH_WITH_VERSION + "/ehr/{ehr_id}/ehr_status")
public class OpenehrEhrStatusController extends BaseController implements EhrStatusApiSpecification {

    private final EhrService ehrService;

    public OpenehrEhrStatusController(EhrService ehrService) {
        this.ehrService = ehrService;
    }

    @Override
    @GetMapping(produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
    public ResponseEntity getEhrStatusVersionByTime(
            @PathVariable(name = "ehr_id") UUID ehrId,
            @RequestParam(name = "version_at_time", required = false) String versionAtTime) {

        final ObjectVersionId objectVersionId;

        if (versionAtTime != null) {
            OffsetDateTime time = decodeVersionAtTime(versionAtTime).orElseThrow();
            objectVersionId = ehrService.getEhrStatusVersionByTimestamp(ehrId, time);
        } else {
            objectVersionId = ehrService.getLatestVersionUidOfStatus(ehrId);
        }

        UUID ehrStatusId = extractVersionedObjectUidFromVersionUid(objectVersionId.getValue());
        int version = extractVersionFromVersionUid(objectVersionId.getValue()).orElseThrow();

        OriginalVersion originalVersion = ehrStatusVersion(ehrId, ehrStatusId, version);
        return responseBuilder(HttpStatus.OK, ehrId, originalVersion).body(originalVersion.getData());
    }

    @Override
    @GetMapping(
            path = "/{version_uid}",
            produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
    public ResponseEntity getEhrStatusByVersionId(
            @PathVariable(name = "ehr_id") UUID ehrId, @PathVariable(name = "version_uid") String versionUid) {

        UUID ehrStatusId = extractVersionedObjectUidFromVersionUid(versionUid);
        int version = extractVersionFromVersionUid(versionUid)
                .orElseThrow(
                        () -> new InvalidApiParameterException("VERSION UID parameter does not contain a version"));

        OriginalVersion originalVersion = ehrStatusVersion(ehrId, ehrStatusId, version);
        return responseBuilder(HttpStatus.OK, ehrId, originalVersion).body(originalVersion.getData());
    }

    @Override
    @PutMapping(
            consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE},
            produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
    public ResponseEntity updateEhrStatus(
            @PathVariable("ehr_id") UUID ehrId,
            @RequestHeader(name = IF_MATCH) String versionUid,
            @RequestHeader(name = PREFER, required = false) String prefer,
            @RequestBody EhrStatusDto ehrStatusDto) {

        HttpRestContext.register(EHR_ID, ehrId);

        // update EHR_STATUS and check for success
        ObjectVersionId targetObjId = new ObjectVersionId(versionUid);
        EhrService.EhrResult ehrResult = ehrService.updateStatus(ehrId, ehrStatusDto, targetObjId, null, null);
        ObjectVersionId statusUid = ehrResult.statusVersionId();

        // update and prepare current version number
        int version = extractVersionFromVersionUid(statusUid.getValue()).orElseThrow();
        UUID ehrStatusId = UUID.fromString(statusUid.getObjectId().getValue());

        // load status
        OriginalVersion originalVersion = ehrStatusVersion(ehrId, ehrStatusId, version);

        // return either representation body or only the created response
        if (RETURN_REPRESENTATION.equals(prefer)) {
            return responseBuilder(HttpStatus.OK, ehrId, originalVersion).body(originalVersion.getData());
        } else {
            return responseBuilder(HttpStatus.NO_CONTENT, ehrId, originalVersion)
                    .build();
        }
    }

    private ResponseEntity.BodyBuilder responseBuilder(
            HttpStatus status, UUID ehrId, OriginalVersion originalVersion) {

        createRestContext(ehrId, originalVersion.getUid());

        ObjectVersionId versionId = originalVersion.getUid();
        URI uri = createLocationUri(EHR, ehrId.toString(), EHR_STATUS, versionId.getValue());
        return ResponseEntity.status(status)
                .location(uri)
                .eTag("\"" + versionId.getValue() + "\"")
                .lastModified(lastModifiedValue(originalVersion.getCommitAudit().getTimeCommitted()));
    }

    private OriginalVersion ehrStatusVersion(UUID ehrId, UUID ehrStatusId, int version) {
        return ehrService
                .getEhrStatusAtVersion(ehrId, ehrStatusId, version)
                .orElseThrow(() -> new ObjectNotFoundException(
                        "EHR_STATUS",
                        "Could not find EhrStatus[id=%s, version=%s]".formatted(ehrStatusId.toString(), version)));
    }

    private static Instant lastModifiedValue(DvDateTime dvDateTime) {
        TemporalAccessor timeCommitted = dvDateTime.getValue();
        if (timeCommitted.query(TemporalQueries.zone()) != null) {
            return ZonedDateTime.from(timeCommitted).toInstant();
        } else {
            return LocalDateTime.from(timeCommitted).toInstant(ZoneOffset.UTC);
        }
    }

    private void createRestContext(UUID ehrId, ObjectVersionId versionId) {

        HttpRestContext.register(
                EHR_ID,
                ehrId,
                DIRECTORY_ID,
                versionId.getValue(),
                HttpRestContext.LOCATION,
                fromPath("")
                        .pathSegment(EHR, ehrId.toString(), EHR_STATUS, versionId.getValue())
                        .build()
                        .toString());
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy