diff --git a/commons/ihe/fhir/r4/chppqm/src/main/groovy/org/openehealth/ipf/commons/ihe/fhir/chppqm/translation/XacmlToFhirTranslator.groovy b/commons/ihe/fhir/r4/chppqm/src/main/groovy/org/openehealth/ipf/commons/ihe/fhir/chppqm/translation/XacmlToFhirTranslator.groovy index 843f215353..e6745a2503 100644 --- a/commons/ihe/fhir/r4/chppqm/src/main/groovy/org/openehealth/ipf/commons/ihe/fhir/chppqm/translation/XacmlToFhirTranslator.groovy +++ b/commons/ihe/fhir/r4/chppqm/src/main/groovy/org/openehealth/ipf/commons/ihe/fhir/chppqm/translation/XacmlToFhirTranslator.groovy @@ -31,6 +31,7 @@ import org.hl7.fhir.r4.model.Consent import org.hl7.fhir.r4.model.IdType import org.hl7.fhir.r4.model.OperationOutcome import org.openehealth.ipf.commons.ihe.fhir.chppqm.ChPpqmUtils +import org.openehealth.ipf.commons.ihe.xacml20.Xacml20Status import org.openehealth.ipf.commons.ihe.xacml20.Xacml20Utils import org.openehealth.ipf.commons.ihe.xacml20.model.PpqConstants import org.openehealth.ipf.commons.ihe.xacml20.stub.UnknownPolicySetIdFaultMessage @@ -254,15 +255,15 @@ class XacmlToFhirTranslator { } static final Map SAML_STATUS_CODE_TO_FHIR_ISSUE_TYPE_CODE_MAPPING = [ - 'urn:oasis:names:tc:SAML:2.0:status:Requester' : OperationOutcome.IssueType.INVALID, - 'urn:oasis:names:tc:SAML:2.0:status:Responder' : OperationOutcome.IssueType.INVALID, - 'urn:oasis:names:tc:SAML:2.0:status:VersionMismatch': OperationOutcome.IssueType.STRUCTURE, + (Xacml20Status.REQUESTER_ERROR.code) : OperationOutcome.IssueType.INVALID, + (Xacml20Status.RESPONDER_ERROR.code) : OperationOutcome.IssueType.INVALID, + (Xacml20Status.VERSION_MISMATCH.code): OperationOutcome.IssueType.STRUCTURE, ] static final Map SAML_STATUS_CODE_TO_HTTP_STATUS_CODE_MAPPING = [ - 'urn:oasis:names:tc:SAML:2.0:status:Requester' : 400, - 'urn:oasis:names:tc:SAML:2.0:status:Responder' : 500, - 'urn:oasis:names:tc:SAML:2.0:status:VersionMismatch': 500, + (Xacml20Status.REQUESTER_ERROR.code) : 400, + (Xacml20Status.RESPONDER_ERROR.code) : 500, + (Xacml20Status.VERSION_MISMATCH.code): 500, ] /** @@ -270,7 +271,7 @@ class XacmlToFhirTranslator { */ static List translatePpq2To5Response(ResponseType ppq2Response) { def statusCode = ppq2Response.status.statusCode.value - if (statusCode == Xacml20Utils.SAML20_STATUS_SUCCESS) { + if (statusCode == Xacml20Status.SUCCESS.code) { def assertion = ppq2Response.assertionOrEncryptedAssertion[0] as AssertionType def statement = assertion.statementOrAuthnStatementOrAuthzDecisionStatement[0] as XACMLPolicyStatementType return statement.policyOrPolicySet.collect { toConsent(it as PolicySetType) } diff --git a/commons/ihe/fhir/r4/chppqm/src/test/java/org/openehealth/ipf/commons/ihe/fhir/chppqm/TranslationTest.java b/commons/ihe/fhir/r4/chppqm/src/test/java/org/openehealth/ipf/commons/ihe/fhir/chppqm/TranslationTest.java index f2ef58051d..433e5c5bc2 100644 --- a/commons/ihe/fhir/r4/chppqm/src/test/java/org/openehealth/ipf/commons/ihe/fhir/chppqm/TranslationTest.java +++ b/commons/ihe/fhir/r4/chppqm/src/test/java/org/openehealth/ipf/commons/ihe/fhir/chppqm/TranslationTest.java @@ -35,9 +35,7 @@ import org.openehealth.ipf.commons.ihe.fhir.chppqm.chppq4.ChPpq4Validator; import org.openehealth.ipf.commons.ihe.fhir.chppqm.translation.FhirToXacmlTranslator; import org.openehealth.ipf.commons.ihe.fhir.chppqm.translation.XacmlToFhirTranslator; -import org.openehealth.ipf.commons.ihe.xacml20.ChPpqMessageCreator; -import org.openehealth.ipf.commons.ihe.xacml20.Xacml20MessageValidator; -import org.openehealth.ipf.commons.ihe.xacml20.Xacml20Utils; +import org.openehealth.ipf.commons.ihe.xacml20.*; import org.openehealth.ipf.commons.ihe.xacml20.model.PpqConstants; import org.openehealth.ipf.commons.ihe.xacml20.stub.ehealthswiss.AddPolicyRequest; import org.openehealth.ipf.commons.ihe.xacml20.stub.ehealthswiss.DeletePolicyRequest; @@ -259,7 +257,7 @@ public void testPpq2To5ResponseTranslation1() { public void testPpq2To5ResponseTranslation2() { boolean correct = false; try { - ResponseType ppq2Response = PPQ_MESSAGE_CREATOR.createNegativePolicyQueryResponse("urn:oasis:names:tc:SAML:2.0:status:Requester"); + ResponseType ppq2Response = PPQ_MESSAGE_CREATOR.createNegativePolicyQueryResponse(new Xacml20Exception(Xacml20Status.REQUESTER_ERROR)); XacmlToFhirTranslator.translatePpq2To5Response(ppq2Response); } catch (UnclassifiedServerFailureException e) { assertEquals(400, e.getStatusCode()); diff --git a/commons/ihe/xacml20/impl/src/main/groovy/org/openehealth/ipf/commons/ihe/xacml20/ChPpqMessageCreator.groovy b/commons/ihe/xacml20/impl/src/main/groovy/org/openehealth/ipf/commons/ihe/xacml20/ChPpqMessageCreator.groovy index 7d638f95a9..6657f63a24 100644 --- a/commons/ihe/xacml20/impl/src/main/groovy/org/openehealth/ipf/commons/ihe/xacml20/ChPpqMessageCreator.groovy +++ b/commons/ihe/xacml20/impl/src/main/groovy/org/openehealth/ipf/commons/ihe/xacml20/ChPpqMessageCreator.groovy @@ -53,7 +53,7 @@ class ChPpqMessageCreator { private final String homeCommunityId ChPpqMessageCreator(String homeCommunityId) { - this.homeCommunityId = Validate.notEmpty(homeCommunityId) + this.homeCommunityId = Validate.notEmpty(homeCommunityId as String, 'Home community ID shall be provided') } private AssertionType createAssertion() { @@ -143,32 +143,35 @@ class ChPpqMessageCreator { return query } - ResponseType createPositivePolicyQueryResponse(List policySets) { - def assertion = createAssertion() - assertion.statementOrAuthnStatementOrAuthzDecisionStatement << new XACMLPolicyStatementType( - policyOrPolicySet: policySets, - ) + private static ResponseType createResponse(Xacml20Status status, String statusMessage, AssertionType assertion) { return new ResponseType( ID: '_' + UUID.randomUUID(), issueInstant: XML_OBJECT_FACTORY.newXMLGregorianCalendar(new GregorianCalendar()), version: '2.0', status: new StatusType( - statusCode: new StatusCodeType(value: Xacml20Utils.SAML20_STATUS_SUCCESS), + statusCode: new StatusCodeType(value: status.code), + statusMessage: statusMessage, ), assertionOrEncryptedAssertion: [assertion], ) } - ResponseType createNegativePolicyQueryResponse(String statusCode) { - return new ResponseType( - ID: '_' + UUID.randomUUID(), - issueInstant: XML_OBJECT_FACTORY.newXMLGregorianCalendar(new GregorianCalendar()), - version: '2.0', - status: new StatusType( - statusCode: new StatusCodeType(value: statusCode), - ), - assertionOrEncryptedAssertion: [createAssertion()], + ResponseType createPositivePolicyQueryResponse(List policySets) { + def assertion = createAssertion() + assertion.statementOrAuthnStatementOrAuthzDecisionStatement << new XACMLPolicyStatementType( + policyOrPolicySet: policySets, ) + return createResponse(Xacml20Status.SUCCESS, null, assertion) + } + + ResponseType createNegativePolicyQueryResponse(Xacml20Status status, String statusMessage) { + return createResponse(status, statusMessage, createAssertion()) + } + + ResponseType createNegativePolicyQueryResponse(Exception exception) { + return (exception instanceof Xacml20Exception) + ? createNegativePolicyQueryResponse(exception.status, exception.message) + : createNegativePolicyQueryResponse(Xacml20Status.RESPONDER_ERROR, exception.message) } } diff --git a/commons/ihe/xacml20/impl/src/main/java/org/openehealth/ipf/commons/ihe/xacml20/Xacml20Exception.java b/commons/ihe/xacml20/impl/src/main/java/org/openehealth/ipf/commons/ihe/xacml20/Xacml20Exception.java new file mode 100644 index 0000000000..26f410e9cf --- /dev/null +++ b/commons/ihe/xacml20/impl/src/main/java/org/openehealth/ipf/commons/ihe/xacml20/Xacml20Exception.java @@ -0,0 +1,45 @@ +/* + * Copyright 2023 the original author or authors. + * + * 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 + * + * http://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.openehealth.ipf.commons.ihe.xacml20; + +import lombok.Getter; + +import java.util.Objects; + +public class Xacml20Exception extends Exception { + + @Getter + private final Xacml20Status status; + + public Xacml20Exception(Xacml20Status status, String message, Throwable cause) { + super(message, cause); + this.status = Objects.requireNonNull(status, "Status code shall be provided"); + } + + public Xacml20Exception(Xacml20Status status) { + this(status, null, null); + } + + public Xacml20Exception(Xacml20Status status, String message) { + this(status, message, null); + } + + public Xacml20Exception(Xacml20Status status, Throwable cause) { + this(status, cause.getMessage(), cause); + } + +} diff --git a/commons/ihe/xacml20/impl/src/main/java/org/openehealth/ipf/commons/ihe/xacml20/Xacml20Status.java b/commons/ihe/xacml20/impl/src/main/java/org/openehealth/ipf/commons/ihe/xacml20/Xacml20Status.java new file mode 100644 index 0000000000..2a74adb295 --- /dev/null +++ b/commons/ihe/xacml20/impl/src/main/java/org/openehealth/ipf/commons/ihe/xacml20/Xacml20Status.java @@ -0,0 +1,34 @@ +/* + * Copyright 2023 the original author or authors. + * + * 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 + * + * http://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.openehealth.ipf.commons.ihe.xacml20; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum Xacml20Status { + + SUCCESS("urn:oasis:names:tc:SAML:2.0:status:Success"), + REQUESTER_ERROR("urn:oasis:names:tc:SAML:2.0:status:Requester"), + RESPONDER_ERROR("urn:oasis:names:tc:SAML:2.0:status:Responder"), + VERSION_MISMATCH("urn:oasis:names:tc:SAML:2.0:status:VersionMismatch"), + ; + + @Getter + private final String code; + +} diff --git a/commons/ihe/xacml20/impl/src/main/java/org/openehealth/ipf/commons/ihe/xacml20/Xacml20Utils.java b/commons/ihe/xacml20/impl/src/main/java/org/openehealth/ipf/commons/ihe/xacml20/Xacml20Utils.java index e17e6b2382..4c191d89b6 100644 --- a/commons/ihe/xacml20/impl/src/main/java/org/openehealth/ipf/commons/ihe/xacml20/Xacml20Utils.java +++ b/commons/ihe/xacml20/impl/src/main/java/org/openehealth/ipf/commons/ihe/xacml20/Xacml20Utils.java @@ -24,16 +24,10 @@ import org.openehealth.ipf.commons.ihe.xacml20.herasaf.Hl7v3DataTypesInitializer; import org.openehealth.ipf.commons.ihe.xacml20.herasaf.Hl7v3FunctionsInitializer; import org.openehealth.ipf.commons.ihe.xacml20.herasaf.types.IiDataTypeAttribute; -import org.openehealth.ipf.commons.ihe.xacml20.stub.ehealthswiss.AddPolicyRequest; -import org.openehealth.ipf.commons.ihe.xacml20.stub.ehealthswiss.AssertionBasedRequestType; -import org.openehealth.ipf.commons.ihe.xacml20.stub.ehealthswiss.DeletePolicyRequest; -import org.openehealth.ipf.commons.ihe.xacml20.stub.ehealthswiss.UpdatePolicyRequest; -import org.openehealth.ipf.commons.ihe.xacml20.stub.ehealthswiss.XACMLPolicySetIdReferenceStatementType; +import org.openehealth.ipf.commons.ihe.xacml20.stub.ehealthswiss.*; import org.openehealth.ipf.commons.ihe.xacml20.stub.hl7v3.II; import org.openehealth.ipf.commons.ihe.xacml20.stub.saml20.assertion.AssertionType; import org.openehealth.ipf.commons.ihe.xacml20.stub.saml20.protocol.ResponseType; -import org.openehealth.ipf.commons.ihe.xacml20.stub.saml20.protocol.StatusCodeType; -import org.openehealth.ipf.commons.ihe.xacml20.stub.saml20.protocol.StatusType; import org.openehealth.ipf.commons.ihe.xacml20.stub.xacml20.saml.assertion.XACMLPolicyStatementType; import org.openehealth.ipf.commons.ihe.xacml20.stub.xacml20.saml.protocol.XACMLPolicyQueryType; @@ -52,8 +46,6 @@ */ public class Xacml20Utils { - public static final String SAML20_STATUS_SUCCESS = "urn:oasis:names:tc:SAML:2.0:status:Success"; - public static final String ATTRIBUTE_TYPE_PATIENT_ID = "urn:e-health-suisse:2015:epr-spid"; public static final String ELEMENT_NAME_PATIENT_ID = "InstanceIdentifier"; @@ -99,16 +91,6 @@ public static void initializeHerasaf(Initializer... customInitializers) { InitializerExecutor.runInitializers(); } - public static ResponseType createXacmlQueryResponse(String status) { - var statusCodeType = new StatusCodeType(); - statusCodeType.setValue(status); - var statusType = new StatusType(); - statusType.setStatusCode(statusCodeType); - var responseType = new ResponseType(); - responseType.setStatus(statusType); - return responseType; - } - /** * Creates a stream of all policies and policy sets contained in the given PPQ response object. * diff --git a/commons/ihe/xacml20/impl/src/main/java/org/openehealth/ipf/commons/ihe/xacml20/chppq2/ChPpq2AuditStrategy.java b/commons/ihe/xacml20/impl/src/main/java/org/openehealth/ipf/commons/ihe/xacml20/chppq2/ChPpq2AuditStrategy.java index 6f78b87570..e64feeb408 100644 --- a/commons/ihe/xacml20/impl/src/main/java/org/openehealth/ipf/commons/ihe/xacml20/chppq2/ChPpq2AuditStrategy.java +++ b/commons/ihe/xacml20/impl/src/main/java/org/openehealth/ipf/commons/ihe/xacml20/chppq2/ChPpq2AuditStrategy.java @@ -29,6 +29,7 @@ import org.openehealth.ipf.commons.audit.types.ParticipantObjectIdType; import org.openehealth.ipf.commons.ihe.core.atna.AuditStrategySupport; import org.openehealth.ipf.commons.ihe.core.atna.event.QueryInformationBuilder; +import org.openehealth.ipf.commons.ihe.xacml20.Xacml20Status; import org.openehealth.ipf.commons.ihe.xacml20.Xacml20Utils; import org.openehealth.ipf.commons.ihe.xacml20.audit.ChPpqAuditDataset; import org.openehealth.ipf.commons.ihe.xacml20.audit.codes.PpqEventTypeCodes; @@ -86,7 +87,7 @@ public boolean enrichAuditDatasetFromResponse(ChPpqAuditDataset auditDataset, Ob public EventOutcomeIndicator getEventOutcomeIndicator(ChPpqAuditDataset auditDataset, Object responseObject) { var response = (ResponseType) responseObject; try { - if (!Xacml20Utils.SAML20_STATUS_SUCCESS.equals(response.getStatus().getStatusCode().getValue())) { + if (!Xacml20Status.SUCCESS.getCode().equals(response.getStatus().getStatusCode().getValue())) { return EventOutcomeIndicator.SeriousFailure; } if (response.getAssertionOrEncryptedAssertion().isEmpty()) { diff --git a/commons/ihe/xacml20/impl/src/test/resources/messages/chppq2/ppq-query-backend-response.xml b/commons/ihe/xacml20/impl/src/test/resources/messages/chppq2/ppq-query-backend-response.xml index 66e7d78a78..6c6a7ddb87 100644 --- a/commons/ihe/xacml20/impl/src/test/resources/messages/chppq2/ppq-query-backend-response.xml +++ b/commons/ihe/xacml20/impl/src/test/resources/messages/chppq2/ppq-query-backend-response.xml @@ -24,7 +24,7 @@ - urn:oid:2.999.1 + urn:oid:1.2.3 parameters) { - return new Xacml20Endpoint(uri, remaining, this, parameters, ChPpq2Service.class) { - @Override - public AbstractWsProducer, ?, ?> getProducer(AbstractWsEndpoint> endpoint, JaxWsClientFactory clientFactory) { - return new SimpleWsProducer<>(this, clientFactory, XACMLPolicyQueryType.class, ResponseType.class); - } - }; + return new ChPpq2Endpoint(uri, remaining, this, parameters); } } diff --git a/platform-camel/ihe/xacml20/src/main/java/org/openehealth/ipf/platform/camel/ihe/xacml20/chppq2/ChPpq2Endpoint.java b/platform-camel/ihe/xacml20/src/main/java/org/openehealth/ipf/platform/camel/ihe/xacml20/chppq2/ChPpq2Endpoint.java new file mode 100644 index 0000000000..973125970a --- /dev/null +++ b/platform-camel/ihe/xacml20/src/main/java/org/openehealth/ipf/platform/camel/ihe/xacml20/chppq2/ChPpq2Endpoint.java @@ -0,0 +1,51 @@ +/* + * Copyright 2023 the original author or authors. + * + * 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 + * + * http://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.openehealth.ipf.platform.camel.ihe.xacml20.chppq2; + +import org.openehealth.ipf.commons.ihe.ws.JaxWsClientFactory; +import org.openehealth.ipf.commons.ihe.ws.WsInteractionId; +import org.openehealth.ipf.commons.ihe.ws.WsTransactionConfiguration; +import org.openehealth.ipf.commons.ihe.xacml20.audit.ChPpqAuditDataset; +import org.openehealth.ipf.commons.ihe.xacml20.stub.saml20.protocol.ResponseType; +import org.openehealth.ipf.commons.ihe.xacml20.stub.xacml20.saml.protocol.XACMLPolicyQueryType; +import org.openehealth.ipf.platform.camel.ihe.ws.*; +import org.openehealth.ipf.platform.camel.ihe.xacml20.Xacml20Endpoint; + +import java.util.Map; + +public class ChPpq2Endpoint extends Xacml20Endpoint { + + public ChPpq2Endpoint( + String endpointUri, + String address, + AbstractWsComponent, ? extends WsInteractionId>> component, + Map parameters) + { + super(endpointUri, address, component, parameters, ChPpq2Service.class); + } + + @Override + protected AbstractWebService getCustomServiceInstance(AbstractWsEndpoint> endpoint) { + return new ChPpq2Service(endpoint.getHomeCommunityId()); + } + + @Override + public AbstractWsProducer, ?, ?> getProducer(AbstractWsEndpoint> endpoint, JaxWsClientFactory clientFactory) { + return new SimpleWsProducer<>(this, clientFactory, XACMLPolicyQueryType.class, ResponseType.class); + } + +} diff --git a/platform-camel/ihe/xacml20/src/main/java/org/openehealth/ipf/platform/camel/ihe/xacml20/chppq2/ChPpq2Service.java b/platform-camel/ihe/xacml20/src/main/java/org/openehealth/ipf/platform/camel/ihe/xacml20/chppq2/ChPpq2Service.java index 8738d28ce7..7e2f8776fd 100644 --- a/platform-camel/ihe/xacml20/src/main/java/org/openehealth/ipf/platform/camel/ihe/xacml20/chppq2/ChPpq2Service.java +++ b/platform-camel/ihe/xacml20/src/main/java/org/openehealth/ipf/platform/camel/ihe/xacml20/chppq2/ChPpq2Service.java @@ -16,7 +16,7 @@ package org.openehealth.ipf.platform.camel.ihe.xacml20.chppq2; import lombok.extern.slf4j.Slf4j; -import org.openehealth.ipf.commons.ihe.xacml20.Xacml20Utils; +import org.openehealth.ipf.commons.ihe.xacml20.ChPpqMessageCreator; import org.openehealth.ipf.commons.ihe.xacml20.chppq2.ChPpq2PortType; import org.openehealth.ipf.commons.ihe.xacml20.stub.saml20.protocol.ResponseType; import org.openehealth.ipf.commons.ihe.xacml20.stub.xacml20.saml.protocol.XACMLPolicyQueryType; @@ -30,15 +30,19 @@ @Slf4j public class ChPpq2Service extends AbstractWebService implements ChPpq2PortType { + private final ChPpqMessageCreator messageCreator; + + public ChPpq2Service(String homeCommunityId) { + this.messageCreator = new ChPpqMessageCreator(homeCommunityId); + } + @Override public ResponseType policyQuery(XACMLPolicyQueryType request) { var result = process(request); var exception = Exchanges.extractException(result); if (exception != null) { log.debug(getClass().getSimpleName() + " service failed", exception); - var response = Xacml20Utils.createXacmlQueryResponse("urn:oasis:names:tc:SAML:2.0:status:Responder"); - response.getStatus().setStatusMessage(exception.getMessage()); - return response; + return messageCreator.createNegativePolicyQueryResponse(exception); } return result.getMessage().getBody(ResponseType.class); } diff --git a/platform-camel/ihe/xacml20/src/test/java/org/openehealth/ipf/platform/camel/ihe/xacml20/chppq2/ChPpq2Test.java b/platform-camel/ihe/xacml20/src/test/java/org/openehealth/ipf/platform/camel/ihe/xacml20/chppq2/ChPpq2Test.java index ac682a763c..793ab19d2e 100644 --- a/platform-camel/ihe/xacml20/src/test/java/org/openehealth/ipf/platform/camel/ihe/xacml20/chppq2/ChPpq2Test.java +++ b/platform-camel/ihe/xacml20/src/test/java/org/openehealth/ipf/platform/camel/ihe/xacml20/chppq2/ChPpq2Test.java @@ -25,7 +25,9 @@ import org.openehealth.ipf.commons.audit.codes.ParticipantObjectTypeCodeRole; import org.openehealth.ipf.commons.audit.model.AuditMessage; import org.openehealth.ipf.commons.audit.types.CodedValueType; +import org.openehealth.ipf.commons.ihe.xacml20.Xacml20Status; import org.openehealth.ipf.commons.ihe.xacml20.Xacml20Utils; +import org.openehealth.ipf.commons.ihe.xacml20.stub.saml20.assertion.AssertionType; import org.openehealth.ipf.commons.ihe.xacml20.stub.saml20.protocol.ResponseType; import org.openehealth.ipf.platform.camel.ihe.ws.StandardTestContainer; @@ -77,17 +79,19 @@ private static void checkCodeValueType(CodedValueType value, String[]... allowed @Test public void testQueryPerPatientIdSuccess() throws Exception { - testQueryPerPatientId("success", "urn:oasis:names:tc:SAML:2.0:status:Success", EventOutcomeIndicator.Success); + testQueryPerPatientId("success", Xacml20Status.SUCCESS, EventOutcomeIndicator.Success, "urn:oid:1.2.3"); } @Test public void testQueryPerPatientIdFailure() throws Exception { - testQueryPerPatientId("failure", "urn:oasis:names:tc:SAML:2.0:status:Responder", EventOutcomeIndicator.SeriousFailure); + testQueryPerPatientId("failure", Xacml20Status.RESPONDER_ERROR, EventOutcomeIndicator.SeriousFailure, "urn:oid:1.2.4"); } - private void testQueryPerPatientId(String suffix, String statusCode, EventOutcomeIndicator outcomeIndicator) throws Exception { + private void testQueryPerPatientId(String suffix, Xacml20Status status, EventOutcomeIndicator outcomeIndicator, String homeCommunityId) throws Exception { var response = (ResponseType) send(getUri(suffix), loadFile("query-per-patient-id.xml"), ResponseType.class); - assertEquals(statusCode, response.getStatus().getStatusCode().getValue()); + assertEquals(status.getCode(), response.getStatus().getStatusCode().getValue()); + var assertion = (AssertionType) response.getAssertionOrEncryptedAssertion().get(0); + assertEquals(homeCommunityId, assertion.getIssuer().getValue()); List messages = getAuditSender().getMessages(); assertEquals(2, messages.size()); @@ -128,17 +132,17 @@ private void testQueryPerPatientId(String suffix, String statusCode, EventOutcom @Test public void testQueryPerPolicyIdSuccess() throws Exception { - testQueryPerPolicyId("success", "urn:oasis:names:tc:SAML:2.0:status:Success", EventOutcomeIndicator.Success); + testQueryPerPolicyId("success", Xacml20Status.SUCCESS, EventOutcomeIndicator.Success); } @Test public void testQueryPerPolicyIdFailure() throws Exception { - testQueryPerPolicyId("failure", "urn:oasis:names:tc:SAML:2.0:status:Responder", EventOutcomeIndicator.SeriousFailure); + testQueryPerPolicyId("failure", Xacml20Status.RESPONDER_ERROR, EventOutcomeIndicator.SeriousFailure); } - private void testQueryPerPolicyId(String suffix, String statusCode, EventOutcomeIndicator outcomeIndicator) throws Exception { + private void testQueryPerPolicyId(String suffix, Xacml20Status status, EventOutcomeIndicator outcomeIndicator) throws Exception { var response = (ResponseType) send(getUri(suffix), loadFile("query-per-policy-id.xml"), ResponseType.class); - assertEquals(statusCode, response.getStatus().getStatusCode().getValue()); + assertEquals(status.getCode(), response.getStatus().getStatusCode().getValue()); List messages = getAuditSender().getMessages(); assertEquals(2, messages.size()); diff --git a/platform-camel/ihe/xacml20/src/test/java/org/openehealth/ipf/platform/camel/ihe/xacml20/chppq2/ChPpq2TestRouteBuilder.java b/platform-camel/ihe/xacml20/src/test/java/org/openehealth/ipf/platform/camel/ihe/xacml20/chppq2/ChPpq2TestRouteBuilder.java index b589921aca..0acf06c8a2 100644 --- a/platform-camel/ihe/xacml20/src/test/java/org/openehealth/ipf/platform/camel/ihe/xacml20/chppq2/ChPpq2TestRouteBuilder.java +++ b/platform-camel/ihe/xacml20/src/test/java/org/openehealth/ipf/platform/camel/ihe/xacml20/chppq2/ChPpq2TestRouteBuilder.java @@ -35,7 +35,7 @@ public class ChPpq2TestRouteBuilder extends RouteBuilder { public void configure() throws Exception { // sends a correct response with status "success" - from("ch-ppq2:ch-ppq-success") + from("ch-ppq2:ch-ppq-success?homeCommunityId=urn:oid:1.2.3") .process(chPpq2RequestValidator()) .process(exchange -> { var stream = ChPpq2TestRouteBuilder.class.getClassLoader().getResourceAsStream("messages/chppq2/ppq-query-backend-response.xml"); @@ -51,7 +51,7 @@ public void configure() throws Exception { .process(chPpq2ResponseValidator()); // sends a correct response with status "failure" - from("ch-ppq2:ch-ppq-failure") + from("ch-ppq2:ch-ppq-failure?homeCommunityId=urn:oid:1.2.4") .process(chPpq2RequestValidator()) .throwException(new RuntimeException("Alles schlimm...")); diff --git a/src/site/changes.xml b/src/site/changes.xml index 1883362d8f..d77f677355 100644 --- a/src/site/changes.xml +++ b/src/site/changes.xml @@ -24,6 +24,12 @@ + + Fix error handling in CH:PPQ-2 + + + Relaxed CXi validation in XDS according to CP-ITI-1292 + Add Spring Boot starter for CH:PPQ