use of com.nedap.archie.rm.composition.Composition 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());
}
use of com.nedap.archie.rm.composition.Composition in project openEHR_SDK by ehrbase.
the class DefaultRestCompositionEndpointIT method testSaveCompositionEntityNative.
@Test
public void testSaveCompositionEntityNative() {
ehr = openEhrClient.ehrEndpoint().createEhr();
EhrbaseBloodPressureSimpleDeV0Composition bloodPressureSimpleDeV0 = TestData.buildEhrbaseBloodPressureSimpleDeV0();
openEhrClient.compositionEndpoint(ehr).mergeCompositionEntity(bloodPressureSimpleDeV0);
assertThat(bloodPressureSimpleDeV0.getVersionUid()).isNotNull();
assertThat(bloodPressureSimpleDeV0.getVersionUid().getVersion()).isEqualTo(1L);
Optional<Composition> aNative = openEhrClient.compositionEndpoint(ehr).findRaw(bloodPressureSimpleDeV0.getVersionUid().getUuid());
assertThat(aNative).isPresent();
assertThat(aNative.get().getUid().getExtension()).isEqualTo("local.ehrbase.org::1");
VersionUid versionUid = openEhrClient.compositionEndpoint(ehr).mergeRaw(aNative.get());
assertThat(versionUid.getVersion()).isEqualTo(2l);
aNative.get().setUid(null);
versionUid = openEhrClient.compositionEndpoint(ehr).mergeRaw(aNative.get());
assertThat(versionUid.getVersion()).isEqualTo(1L);
}
use of com.nedap.archie.rm.composition.Composition in project openEHR_SDK by ehrbase.
the class DefaultRestCompositionEndpointIT method testSaveCompositionEntityWithAnyProxy.
@Test
public void testSaveCompositionEntityWithAnyProxy() {
ehr = openEhrClient.ehrEndpoint().createEhr();
GECCOSerologischerBefundComposition composition1 = new GECCOSerologischerBefundComposition();
composition1.setLanguage(Language.DE);
composition1.setTerritory(Territory.DE);
composition1.setCategoryDefiningCode(org.ehrbase.client.classgenerator.shareddefinition.Category.EVENT);
composition1.setSettingDefiningCode(Setting.NURSING_HOME_CARE);
composition1.setComposer(new PartyIdentified(null, "Test", null));
composition1.setStartTimeValue(OffsetDateTime.of(2019, 04, 03, 22, 00, 00, 00, ZoneOffset.UTC));
composition1.setParticipations(new ArrayList<>());
composition1.setBefund(new ArrayList<>());
Enhancer enhancerObservation = new Enhancer();
enhancerObservation.setSuperclass(BefundObservation.class);
enhancerObservation.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
if (method.getDeclaringClass() != Object.class && method.getName().equals("getLanguage")) {
return Language.EN;
} else {
return proxy.invokeSuper(obj, args);
}
});
BefundObservation befundObservation = (BefundObservation) enhancerObservation.create();
composition1.getBefund().add(befundObservation);
befundObservation.setSubject(new PartySelf());
befundObservation.setJedesEreignis(new ArrayList<>());
// Read will be overwritten by enhancerObservation
befundObservation.setLanguage(Language.DE);
befundObservation.setAnforderungDefiningCode(AnforderungDefiningCode.SARS_COV2_COVID19_AB_PANEL_SERUM_OR_PLASMA_BY_IMMUNOASSAY);
befundObservation.setOriginValue(OffsetDateTime.of(2019, 04, 03, 22, 00, 00, 00, ZoneOffset.UTC));
BefundJedesEreignisPointEvent event = new BefundJedesEreignisPointEvent();
event.setTimeValue(OffsetDateTime.of(2019, 04, 03, 22, 00, 00, 00, ZoneOffset.UTC));
event.setLabortestBezeichnungDefiningCode(LabortestBezeichnungDefiningCode.SEROLOGIC_TEST_PROCEDURE);
event.setVirusnachweistestDefiningCode(VirusnachweistestDefiningCode.SARS_COV2_COVID19_AB_PRESENCE_IN_SERUM_OR_PLASMA_BY_IMMUNOASSAY);
event.setErgebnisStatusValue("registered");
befundObservation.getJedesEreignis().add(event);
Enhancer enhancerProAnalytQuantitativesErgebnisDvCount = new Enhancer();
enhancerProAnalytQuantitativesErgebnisDvCount.setSuperclass(ProAnalytQuantitativesErgebnisDvCount.class);
enhancerProAnalytQuantitativesErgebnisDvCount.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
if (method.getDeclaringClass() != Object.class && method.getName().equals("getQuantitativesErgebnisMagnitude")) {
return 33l;
} else {
return proxy.invokeSuper(obj, args);
}
});
ProAnalytQuantitativesErgebnisDvCount quantitativesErgebnis = (ProAnalytQuantitativesErgebnisDvCount) enhancerProAnalytQuantitativesErgebnisDvCount.create();
quantitativesErgebnis.setQuantitativesErgebnisMagnitude(22l);
event.setQuantitativesErgebnis(quantitativesErgebnis);
GECCOSerologischerBefundComposition composition = composition1;
composition = openEhrClient.compositionEndpoint(ehr).mergeCompositionEntity(composition);
Optional<GECCOSerologischerBefundComposition> actual = openEhrClient.compositionEndpoint(ehr).find(composition.getVersionUid().getUuid(), GECCOSerologischerBefundComposition.class);
assertThat(actual).isPresent();
assertThat(actual.get().getBefund()).size().isEqualTo(1);
BefundObservation actualObservation = actual.get().getBefund().get(0);
assertThat(actualObservation.getLanguage()).isEqualTo(Language.EN);
assertThat(actualObservation.getJedesEreignis()).size().isEqualTo(1);
assertThat(actualObservation.getJedesEreignis().get(0).getQuantitativesErgebnis()).isNotNull();
assertThat(actualObservation.getJedesEreignis().get(0).getQuantitativesErgebnis().getClass()).isEqualTo(ProAnalytQuantitativesErgebnisDvCount.class);
assertThat(((ProAnalytQuantitativesErgebnisDvCount) actualObservation.getJedesEreignis().get(0).getQuantitativesErgebnis()).getQuantitativesErgebnisMagnitude()).isEqualTo(33L);
}
use of com.nedap.archie.rm.composition.Composition in project openEHR_SDK by ehrbase.
the class RoundTripTest method checkTestCase.
public void checkTestCase(TestCase testCase, SoftAssertions softly) throws IOException {
String value = IOUtils.toString(testCase.simSDTJson.getStream(), UTF_8);
RMDataFormat flatJson = new FlatJasonProvider(new TestDataTemplateProvider()).buildFlatJson(FlatFormat.SIM_SDT, testCase.templateId);
Composition composition = flatJson.unmarshal(value);
Flattener flattener = new Flattener(new TestDataTemplateProvider());
Object flatten = flattener.flatten(composition, testCase.dtoClass);
Unflattener unflattener = new Unflattener(new TestDataTemplateProvider());
RMObject actual = unflattener.unflatten(flatten);
String actualFlat = flatJson.marshal(actual);
List<String> errors = compere(actualFlat, value);
softly.assertThat(errors).filteredOn(s -> s.startsWith("Missing")).as("Test Case %s", testCase.id).containsExactlyInAnyOrder(testCase.missing);
softly.assertThat(errors).filteredOn(s -> s.startsWith("Extra")).as("Test Case %s", testCase.id).containsExactlyInAnyOrder(testCase.extra);
}
use of com.nedap.archie.rm.composition.Composition in project openEHR_SDK by ehrbase.
the class UnflattenerTest method testUnflattenInterval.
@Test
public void testUnflattenInterval() {
TestDataTemplateProvider templateProvider = new TestDataTemplateProvider();
Unflattener cut = new Unflattener(templateProvider);
TestAllTypesEnV1Composition dto = buildTestAllTypesEnV1Composition();
Composition rmObject = (Composition) cut.unflatten(dto);
assertThat(rmObject).isNotNull();
assertThat(rmObject.itemAtPath("/content[openEHR-EHR-EVALUATION.test_all_types.v1]/data[at0001]/items[at0003]/value/upper_included")).isEqualTo(true);
TestAllTypesEnV1Composition actual = new Flattener(new TestDataTemplateProvider()).flatten(rmObject, TestAllTypesEnV1Composition.class);
assertThat(actual.getTestAllTypes2().get(0).isIntervalCountUpperIncluded()).isTrue();
}
Aggregations