diff --git a/CITATION.cff b/CITATION.cff index 1cdfc3d3a..263b525b8 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -24,8 +24,8 @@ preferred-citation: doi: 10.3233/SHTI210060 type: proceedings title: "HiGHmed Data Sharing Framework (HiGHmed DSF)" -version: 0.6.0 -date-released: 2022-03-10 +version: 0.7.0 +date-released: 2022-06-21 url: https://github.com/highmed/highmed-dsf/wiki repository-code: https://github.com/highmed/highmed-dsf repository-artifact: https://github.com/highmed/highmed-dsf/releases diff --git a/dsf-bpe/dsf-bpe-process-base/pom.xml b/dsf-bpe/dsf-bpe-process-base/pom.xml index e238650dc..21610d117 100755 --- a/dsf-bpe/dsf-bpe-process-base/pom.xml +++ b/dsf-bpe/dsf-bpe-process-base/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-bpe-pom - 0.6.0 + 0.7.0 @@ -19,6 +19,10 @@ org.highmed.dsf dsf-fhir-auth + + org.highmed.dsf + dsf-fhir-validation + org.highmed.dsf @@ -56,6 +60,10 @@ org.springframework spring-context + + org.springframework + spring-web + org.camunda.bpm camunda-engine @@ -65,11 +73,18 @@ commons-io commons-io + + org.apache.commons + commons-compress + de.hs-heilbronn.mi log4j2-utils - test + + + org.slf4j + jul-to-slf4j diff --git a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/bpe/ConstantsBase.java b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/bpe/ConstantsBase.java index 3798d121e..c3f473e34 100755 --- a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/bpe/ConstantsBase.java +++ b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/bpe/ConstantsBase.java @@ -15,6 +15,7 @@ public interface ConstantsBase String BPMN_EXECUTION_VARIABLE_QUERY_PARAMETERS = "queryParameters"; String BPMN_EXECUTION_VARIABLE_TTP_IDENTIFIER = "ttpIdentifier"; String BPMN_EXECUTION_VARIABLE_LEADING_MEDIC_IDENTIFIER = "leadingMedicIdentifier"; + String BPMN_EXECUTION_VARIABLE_ALTERNATIVE_BUSINESS_KEY = "alternativeBusinessKey"; /** * Used to distinguish if I am at the moment in a process called by another process by a CallActivity or not diff --git a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/task/AbstractTaskMessageSend.java b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/task/AbstractTaskMessageSend.java index ff6efb569..0d76eff6c 100755 --- a/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/task/AbstractTaskMessageSend.java +++ b/dsf-bpe/dsf-bpe-process-base/src/main/java/org/highmed/dsf/fhir/task/AbstractTaskMessageSend.java @@ -1,5 +1,6 @@ package org.highmed.dsf.fhir.task; +import static org.highmed.dsf.bpe.ConstantsBase.BPMN_EXECUTION_VARIABLE_ALTERNATIVE_BUSINESS_KEY; import static org.highmed.dsf.bpe.ConstantsBase.BPMN_EXECUTION_VARIABLE_INSTANTIATES_URI; import static org.highmed.dsf.bpe.ConstantsBase.BPMN_EXECUTION_VARIABLE_MESSAGE_NAME; import static org.highmed.dsf.bpe.ConstantsBase.BPMN_EXECUTION_VARIABLE_PROFILE; @@ -14,6 +15,7 @@ import java.util.Date; import java.util.Objects; +import java.util.UUID; import java.util.stream.Stream; import org.camunda.bpm.engine.delegate.DelegateExecution; @@ -279,6 +281,35 @@ protected Stream getAdditionalInputParameters(DelegateExecut return Stream.empty(); } + /** + * Generates an alternative business-key and stores it as a process variable with name + * {@link ConstantsBase#BPMN_EXECUTION_VARIABLE_ALTERNATIVE_BUSINESS_KEY}
+ *
+ * Use this method in combination with overriding + * {@link #sendTask(Target, String, String, String, String, Stream)} to use an alternative business-key with the + * communication target. + * + *
+	 * @Override
+	 * protected void sendTask(Target target, String instantiatesUri, String messageName, String businessKey,
+	 * 		String profile, Stream<ParameterComponent> additionalInputParameters)
+	 * {
+	 * 	String alternativeBusinesKey = createAndSaveAlternativeBusinessKey();
+	 * 	super.sendTask(target, instantiatesUri, messageName, alternativeBusinesKey, profile,
+	 * 			additionalInputParameters);
+	 * }
+	 * 
+ * + * @return the alternative business-key stored as variable + * {@link ConstantsBase#BPMN_EXECUTION_VARIABLE_ALTERNATIVE_BUSINESS_KEY} + */ + protected final String createAndSaveAlternativeBusinessKey() + { + String alternativeBusinessKey = UUID.randomUUID().toString(); + execution.setVariable(BPMN_EXECUTION_VARIABLE_ALTERNATIVE_BUSINESS_KEY, alternativeBusinessKey); + return alternativeBusinessKey; + } + protected void sendTask(Target target, String instantiatesUri, String messageName, String businessKey, String profile, Stream additionalInputParameters) { diff --git a/dsf-bpe/dsf-bpe-process-base/src/test/java/org/highmed/dsf/bpe/start/ExampleStarter.java b/dsf-bpe/dsf-bpe-process-base/src/test/java/org/highmed/dsf/bpe/start/ExampleStarter.java index 94629a2f8..2cf62b8fc 100644 --- a/dsf-bpe/dsf-bpe-process-base/src/test/java/org/highmed/dsf/bpe/start/ExampleStarter.java +++ b/dsf-bpe/dsf-bpe-process-base/src/test/java/org/highmed/dsf/bpe/start/ExampleStarter.java @@ -130,6 +130,6 @@ public FhirWebserviceClient createClient(String baseUrl) throws Exception ReferenceCleaner referenceCleaner = new ReferenceCleanerImpl(new ReferenceExtractorImpl()); return new FhirWebserviceClientJersey(baseUrl, trustStore, keyStore, certificatePassword, null, null, null, 0, - 0, null, context, referenceCleaner); + 0, false, null, context, referenceCleaner); } } diff --git a/dsf-bpe/dsf-bpe-server-jetty/pom.xml b/dsf-bpe/dsf-bpe-server-jetty/pom.xml index d22336383..346a9ec47 100755 --- a/dsf-bpe/dsf-bpe-server-jetty/pom.xml +++ b/dsf-bpe/dsf-bpe-server-jetty/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-bpe-pom - 0.6.0 + 0.7.0 diff --git a/dsf-bpe/dsf-bpe-server/pom.xml b/dsf-bpe/dsf-bpe-server/pom.xml index c31a3ac68..2f3fce2cb 100755 --- a/dsf-bpe/dsf-bpe-server/pom.xml +++ b/dsf-bpe/dsf-bpe-server/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-bpe-pom - 0.6.0 + 0.7.0 diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/bpe/service/FhirResourceHandlerImpl.java b/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/bpe/service/FhirResourceHandlerImpl.java index d24df8990..81d4fde55 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/bpe/service/FhirResourceHandlerImpl.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/bpe/service/FhirResourceHandlerImpl.java @@ -355,7 +355,7 @@ private Stream getCurrentOrOldResources( List resources = dbResourcesByProcess.get(process); if (resources == null) { - logger.warn("No resources found in BPE DB for process {}", process); + logger.debug("No resources found in BPE DB for process {}", process); resources = Collections.emptyList(); } diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/bpe/spring/config/FhirConfig.java b/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/bpe/spring/config/FhirConfig.java index 2baeb1462..e5aaa995a 100755 --- a/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/bpe/spring/config/FhirConfig.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/bpe/spring/config/FhirConfig.java @@ -36,6 +36,9 @@ import org.highmed.dsf.fhir.websocket.FhirConnector; import org.highmed.dsf.fhir.websocket.FhirConnectorImpl; import org.highmed.dsf.fhir.websocket.LastEventTimeIo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -49,8 +52,10 @@ import de.rwh.utils.crypto.io.PemIo; @Configuration -public class FhirConfig +public class FhirConfig implements InitializingBean { + private static final Logger logger = LoggerFactory.getLogger(FhirConfig.class); + private static final BouncyCastleProvider provider = new BouncyCastleProvider(); @Autowired @@ -98,23 +103,24 @@ public FhirWebsocketClientProvider clientProvider() try { - KeyStore webserviceKeyStore = createKeyStore(propertiesConfig.getWebserviceClientCertificateFile(), - propertiesConfig.getWebserviceClientCertificatePrivateKeyFile(), - propertiesConfig.getWebserviceClientCertificatePrivateKeyFilePassword(), keyStorePassword); - KeyStore webserviceTrustStore = createTrustStore( - propertiesConfig.getWebserviceClientCertificateTrustStoreFile()); + KeyStore webserviceKeyStore = createKeyStore(propertiesConfig.getClientCertificateFile(), + propertiesConfig.getClientCertificatePrivateKeyFile(), + propertiesConfig.getClientCertificatePrivateKeyFilePassword(), keyStorePassword); + KeyStore webserviceTrustStore = createTrustStore(propertiesConfig.getClientCertificateTrustStoreFile()); return new FhirClientProviderImpl(fhirContext(), referenceCleaner(), propertiesConfig.getServerBaseUrl(), propertiesConfig.getWebserviceClientLocalReadTimeout(), propertiesConfig.getWebserviceClientLocalConnectTimeout(), propertiesConfig.getWebserviceClientLocalProxySchemeHostPort(), propertiesConfig.getWebserviceClientLocalProxyUsername(), - propertiesConfig.getWebserviceClientLocalProxyPassword(), webserviceTrustStore, webserviceKeyStore, + propertiesConfig.getWebserviceClientLocalProxyPassword(), + propertiesConfig.getWebserviceClientLocalVerbose(), webserviceTrustStore, webserviceKeyStore, keyStorePassword, propertiesConfig.getWebserviceClientRemoteReadTimeout(), propertiesConfig.getWebserviceClientRemoteConnectTimeout(), propertiesConfig.getWebserviceClientRemoteProxySchemeHostPort(), propertiesConfig.getWebserviceClientRemoteProxyUsername(), - propertiesConfig.getWebserviceClientRemoteProxyPassword(), getWebsocketUrl(), webserviceTrustStore, + propertiesConfig.getWebserviceClientRemoteProxyPassword(), + propertiesConfig.getWebserviceClientRemoteVerbose(), getWebsocketUrl(), webserviceTrustStore, webserviceKeyStore, keyStorePassword, propertiesConfig.getWebsocketClientProxySchemeHostPort(), propertiesConfig.getWebsocketClientProxyUsername(), propertiesConfig.getWebsocketClientProxyPassword()); @@ -211,4 +217,37 @@ public ReadAccessHelper readAccessHelper() { return new ReadAccessHelperImpl(); } + + @Override + public void afterPropertiesSet() throws Exception + { + logger.info( + "Local webservice client config: {trustStorePath: {}, certificatePath: {}, privateKeyPath: {}, privateKeyPassword: {}," + + " proxyUrl {}, proxyUsername {}, proxyPassword {}, serverBase: {}}", + propertiesConfig.getClientCertificateTrustStoreFile(), propertiesConfig.getClientCertificateFile(), + propertiesConfig.getClientCertificatePrivateKeyFile(), + propertiesConfig.getClientCertificatePrivateKeyFilePassword() != null ? "***" : "null", + propertiesConfig.getWebserviceClientLocalProxySchemeHostPort(), + propertiesConfig.getWebserviceClientLocalProxyUsername(), + propertiesConfig.getWebserviceClientLocalProxyPassword() != null ? "***" : "null", + propertiesConfig.getServerBaseUrl()); + logger.info( + "Local websocket client config: {trustStorePath: {}, certificatePath: {}, privateKeyPath: {}, privateKeyPassword: {}," + + " proxyUrl {}, proxyUsername {}, proxyPassword {}, websocketUrl: {}}", + propertiesConfig.getClientCertificateTrustStoreFile(), propertiesConfig.getClientCertificateFile(), + propertiesConfig.getClientCertificatePrivateKeyFile(), + propertiesConfig.getClientCertificatePrivateKeyFilePassword() != null ? "***" : "null", + propertiesConfig.getWebsocketClientProxySchemeHostPort(), + propertiesConfig.getWebsocketClientProxyUsername(), + propertiesConfig.getWebsocketClientProxyPassword() != null ? "***" : "null", getWebsocketUrl()); + logger.info( + "Remote webservice client config: {trustStorePath: {}, certificatePath: {}, privateKeyPath: {}, privateKeyPassword: {}," + + " proxyUrl {}, proxyUsername {}, proxyPassword {}}", + propertiesConfig.getClientCertificateTrustStoreFile(), propertiesConfig.getClientCertificateFile(), + propertiesConfig.getClientCertificatePrivateKeyFile(), + propertiesConfig.getClientCertificatePrivateKeyFilePassword() != null ? "***" : "null", + propertiesConfig.getWebserviceClientRemoteProxySchemeHostPort(), + propertiesConfig.getWebserviceClientRemoteProxyUsername(), + propertiesConfig.getWebserviceClientRemoteProxyPassword() != null ? "***" : "null"); + } } diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/bpe/spring/config/PropertiesConfig.java b/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/bpe/spring/config/PropertiesConfig.java index 41d0d7478..8152a79de 100644 --- a/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/bpe/spring/config/PropertiesConfig.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/bpe/spring/config/PropertiesConfig.java @@ -44,19 +44,19 @@ public class PropertiesConfig @Documentation(required = true, description = "PEM encoded file with one or more trusted root certificates to validate server certificates for https connections to local and remote DSF FHIR servers", recommendation = "Use docker secret file to configure", example = "/run/secrets/app_client_trust_certificates.pem") @Value("${org.highmed.dsf.bpe.fhir.client.trust.certificates}") - private String webserviceClientCertificateTrustStoreFile; + private String clientCertificateTrustStoreFile; @Documentation(required = true, description = "PEM encoded file with local client certificate for https connections to local and remote DSF FHIR servers", recommendation = "Use docker secret file to configure", example = "/run/secrets/app_client_certificate.pem") @Value("${org.highmed.dsf.bpe.fhir.client.certificate}") - private String webserviceClientCertificateFile; + private String clientCertificateFile; @Documentation(required = true, description = "Private key corresponding to the local client certificate as PEM encoded file. Use ${env_variable}_PASSWORD* or *${env_variable}_PASSWORD_FILE* if private key is encrypted", recommendation = "Use docker secret file to configure", example = "/run/secrets/app_client_certificate_private_key.pem") @Value("${org.highmed.dsf.bpe.fhir.client.certificate.private.key}") - private String webserviceClientCertificatePrivateKeyFile; + private String clientCertificatePrivateKeyFile; @Documentation(description = "Password to decrypt the local client certificate encrypted private key", recommendation = "Use docker secret file to configure using *${env_variable}_FILE*", example = "/run/secrets/app_client_certificate_private_key.pem.password") @Value("${org.highmed.dsf.bpe.fhir.client.certificate.private.key.password:#{null}}") - private char[] webserviceClientCertificatePrivateKeyFilePassword; + private char[] clientCertificatePrivateKeyFilePassword; @Documentation(description = "The timeout in milliseconds until a reading a resource from a remote DSF FHIR server is aborted", recommendation = "Change default value only if timeout exceptions occur") @Value("${org.highmed.dsf.bpe.fhir.client.remote.timeout.read:60000}") @@ -78,6 +78,10 @@ public class PropertiesConfig @Value("${org.highmed.dsf.bpe.fhir.client.remote.proxy.password:#{null}}") private char[] webserviceClientRemoteProxyPassword; + @Documentation(description = "To enable verbose logging of requests to and replies from remote DSF FHIR servers, set to `true`") + @Value("${org.highmed.dsf.bpe.fhir.client.remote.verbose:false}") + private boolean webserviceClientRemoteVerbose; + @Documentation(required = true, description = "The base address of the local DSF FHIR server to read/store fhir resources", example = "https://foo.bar/fhir") @Value("${org.highmed.dsf.bpe.fhir.server.base.url}") private String serverBaseUrl; @@ -102,6 +106,10 @@ public class PropertiesConfig @Value("${org.highmed.dsf.bpe.fhir.client.local.proxy.password:#{null}}") private char[] webserviceClientLocalProxyPassword; + @Documentation(description = "To enable verbose logging of requests to and replies from the local DSF FHIR server, set to `true`") + @Value("${org.highmed.dsf.bpe.fhir.client.local.verbose:false}") + private boolean webserviceClientLocalVerbose; + @Documentation(description = "Proxy location, set if the DSF BPE server can reach internal servers via websocket, like the DSF FHIR server, only through a proxy", example = "http://proxy.foo:8080") @Value("${org.highmed.dsf.bpe.fhir.client.local.websocket.proxy.url:#{null}}") private String websocketClientProxySchemeHostPort; @@ -205,24 +213,24 @@ public String getOrganizationIdentifierValue() return organizationIdentifierValue; } - public String getWebserviceClientCertificateTrustStoreFile() + public String getClientCertificateTrustStoreFile() { - return webserviceClientCertificateTrustStoreFile; + return clientCertificateTrustStoreFile; } - public String getWebserviceClientCertificateFile() + public String getClientCertificateFile() { - return webserviceClientCertificateFile; + return clientCertificateFile; } - public String getWebserviceClientCertificatePrivateKeyFile() + public String getClientCertificatePrivateKeyFile() { - return webserviceClientCertificatePrivateKeyFile; + return clientCertificatePrivateKeyFile; } - public char[] getWebserviceClientCertificatePrivateKeyFilePassword() + public char[] getClientCertificatePrivateKeyFilePassword() { - return webserviceClientCertificatePrivateKeyFilePassword; + return clientCertificatePrivateKeyFilePassword; } public int getWebserviceClientRemoteReadTimeout() @@ -250,6 +258,11 @@ public char[] getWebserviceClientRemoteProxyPassword() return webserviceClientRemoteProxyPassword; } + public boolean getWebserviceClientRemoteVerbose() + { + return webserviceClientRemoteVerbose; + } + public String getServerBaseUrl() { return serverBaseUrl; @@ -280,6 +293,11 @@ public char[] getWebserviceClientLocalProxyPassword() return webserviceClientLocalProxyPassword; } + public boolean getWebserviceClientLocalVerbose() + { + return webserviceClientLocalVerbose; + } + public String getWebsocketClientProxySchemeHostPort() { return websocketClientProxySchemeHostPort; diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/fhir/client/FhirClientProviderImpl.java b/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/fhir/client/FhirClientProviderImpl.java index 57dcfa944..09f0285de 100755 --- a/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/fhir/client/FhirClientProviderImpl.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/fhir/client/FhirClientProviderImpl.java @@ -34,6 +34,7 @@ public class FhirClientProviderImpl private final String localWebserviceProxySchemeHostPort; private final String localWebserviceProxyUsername; private final char[] localWebserviceProxyPassword; + private final boolean localWebserviceLogRequests; private final KeyStore webserviceTrustStore; private final KeyStore webserviceKeyStore; @@ -44,6 +45,7 @@ public class FhirClientProviderImpl private final String remoteWebserviceProxySchemeHostPort; private final String remoteWebserviceProxyUsername; private final char[] remoteWebserviceProxyPassword; + private final boolean remoteWebserviceLogRequests; private final String localWebsocketUrl; private final KeyStore localWebsocketTrustStore; @@ -57,10 +59,11 @@ public class FhirClientProviderImpl public FhirClientProviderImpl(FhirContext fhirContext, ReferenceCleaner referenceCleaner, String localWebserviceBaseUrl, int localWebserviceReadTimeout, int localWebserviceConnectTimeout, String localWebserviceProxySchemeHostPort, String localWebserviceProxyUsername, - char[] localWebserviceProxyPassword, KeyStore webserviceTrustStore, KeyStore webserviceKeyStore, - char[] webserviceKeyStorePassword, int remoteWebserviceReadTimeout, int remoteWebserviceConnectTimeout, - String remoteWebserviceProxySchemeHostPort, String remoteWebserviceProxyUsername, - char[] remoteWebserviceProxyPassword, String localWebsocketUrl, KeyStore localWebsocketTrustStore, + char[] localWebserviceProxyPassword, boolean localWebserviceLogRequests, KeyStore webserviceTrustStore, + KeyStore webserviceKeyStore, char[] webserviceKeyStorePassword, int remoteWebserviceReadTimeout, + int remoteWebserviceConnectTimeout, String remoteWebserviceProxySchemeHostPort, + String remoteWebserviceProxyUsername, char[] remoteWebserviceProxyPassword, + boolean remoteWebserviceLogRequests, String localWebsocketUrl, KeyStore localWebsocketTrustStore, KeyStore localWebsocketKeyStore, char[] localWebsocketKeyStorePassword, String localWebsocketProxySchemeHostPort, String localWebsocketProxyUsername, char[] localWebsocketProxyPassword) @@ -74,6 +77,7 @@ public FhirClientProviderImpl(FhirContext fhirContext, ReferenceCleaner referenc this.localWebserviceProxySchemeHostPort = localWebserviceProxySchemeHostPort; this.localWebserviceProxyUsername = localWebserviceProxyUsername; this.localWebserviceProxyPassword = localWebserviceProxyPassword; + this.localWebserviceLogRequests = localWebserviceLogRequests; this.webserviceTrustStore = webserviceTrustStore; this.webserviceKeyStore = webserviceKeyStore; @@ -84,6 +88,7 @@ public FhirClientProviderImpl(FhirContext fhirContext, ReferenceCleaner referenc this.remoteWebserviceProxySchemeHostPort = remoteWebserviceProxySchemeHostPort; this.remoteWebserviceProxyUsername = remoteWebserviceProxyUsername; this.remoteWebserviceProxyPassword = remoteWebserviceProxyPassword; + this.remoteWebserviceLogRequests = remoteWebserviceLogRequests; this.localWebsocketUrl = localWebsocketUrl; this.localWebsocketTrustStore = localWebsocketTrustStore; @@ -103,12 +108,6 @@ public void afterPropertiesSet() throws Exception throw new IllegalArgumentException("localReadTimeout < 0"); if (localWebserviceConnectTimeout < 0) throw new IllegalArgumentException("localConnectTimeout < 0"); - if (localWebserviceProxyPassword == null) - logger.info("localProxyPassword is null"); - if (localWebserviceProxyUsername == null) - logger.info("localProxyUsername is null"); - if (localWebserviceProxySchemeHostPort == null) - logger.info("localProxySchemeHostPort is null"); Objects.requireNonNull(webserviceTrustStore, "webserviceTrustStore"); Objects.requireNonNull(webserviceKeyStore, "webserviceKeyStore"); Objects.requireNonNull(webserviceKeyStorePassword, "webserviceKeyStorePassword"); @@ -116,12 +115,6 @@ public void afterPropertiesSet() throws Exception throw new IllegalArgumentException("remoteReadTimeout < 0"); if (remoteWebserviceConnectTimeout < 0) throw new IllegalArgumentException("remoteConnectTimeout < 0"); - if (remoteWebserviceProxyPassword == null) - logger.info("remoteProxyPassword is null"); - if (remoteWebserviceProxyUsername == null) - logger.info("remoteProxyUsername is null"); - if (remoteWebserviceProxySchemeHostPort == null) - logger.info("remoteProxySchemeHostPort is null"); Objects.requireNonNull(localWebsocketUrl, "localWebsocketUrl"); Objects.requireNonNull(localWebsocketTrustStore, "localWebsocketTrustStore"); Objects.requireNonNull(localWebsocketKeyStore, "localWebsocketKeyStore"); @@ -146,13 +139,14 @@ private FhirWebserviceClient getClient(String webserviceUrl) client = new FhirWebserviceClientJersey(webserviceUrl, webserviceTrustStore, webserviceKeyStore, webserviceKeyStorePassword, localWebserviceProxySchemeHostPort, localWebserviceProxyUsername, localWebserviceProxyPassword, localWebserviceConnectTimeout, - localWebserviceReadTimeout, null, fhirContext, referenceCleaner); + localWebserviceReadTimeout, localWebserviceLogRequests, null, fhirContext, + referenceCleaner); else client = new FhirWebserviceClientJersey(webserviceUrl, webserviceTrustStore, webserviceKeyStore, webserviceKeyStorePassword, remoteWebserviceProxySchemeHostPort, remoteWebserviceProxyUsername, remoteWebserviceProxyPassword, - remoteWebserviceConnectTimeout, remoteWebserviceReadTimeout, null, fhirContext, - referenceCleaner); + remoteWebserviceConnectTimeout, remoteWebserviceReadTimeout, remoteWebserviceLogRequests, + null, fhirContext, referenceCleaner); webserviceClientsByUrl.put(webserviceUrl, client); return client; diff --git a/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/fhir/task/TaskHandler.java b/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/fhir/task/TaskHandler.java index 752a5bfa4..c774f3363 100755 --- a/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/fhir/task/TaskHandler.java +++ b/dsf-bpe/dsf-bpe-server/src/main/java/org/highmed/dsf/fhir/task/TaskHandler.java @@ -1,5 +1,6 @@ package org.highmed.dsf.fhir.task; +import static org.highmed.dsf.bpe.ConstantsBase.BPMN_EXECUTION_VARIABLE_ALTERNATIVE_BUSINESS_KEY; import static org.highmed.dsf.bpe.ConstantsBase.BPMN_EXECUTION_VARIABLE_TASK; import static org.highmed.dsf.bpe.ConstantsBase.CODESYSTEM_HIGHMED_BPMN; import static org.highmed.dsf.bpe.ConstantsBase.CODESYSTEM_HIGHMED_BPMN_VALUE_BUSINESS_KEY; @@ -16,6 +17,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.camunda.bpm.engine.RepositoryService; import org.camunda.bpm.engine.RuntimeService; @@ -23,7 +25,6 @@ import org.camunda.bpm.engine.runtime.MessageCorrelationBuilder; import org.camunda.bpm.engine.runtime.ProcessInstance; import org.camunda.bpm.engine.runtime.ProcessInstanceQuery; -import org.camunda.bpm.engine.variable.Variables; import org.highmed.dsf.fhir.variables.FhirResourceValues; import org.highmed.fhir.client.FhirWebserviceClient; import org.hl7.fhir.r4.model.Task; @@ -159,27 +160,36 @@ protected void onMessage(String businessKey, String correlationKey, String proce else { List instances = getProcessInstanceQuery(processDefinition, businessKey).list(); + List instancesWithAlternativeBusinessKey = getAlternativeProcessInstanceQuery( + processDefinition, businessKey).list(); - if (instances.size() > 1) + if (instances.size() + instancesWithAlternativeBusinessKey.size() > 1) logger.warn("instance-ids {}", - instances.stream().map(ProcessInstance::getId).collect(Collectors.joining(", ", "[", "]"))); + Stream.concat(instances.stream(), instancesWithAlternativeBusinessKey.stream()) + .map(ProcessInstance::getId).collect(Collectors.joining(", ", "[", "]"))); - long instanceCount = getProcessInstanceQuery(processDefinition, businessKey).count(); - - if (instanceCount <= 0) + if (instances.size() + instancesWithAlternativeBusinessKey.size() <= 0) { runtimeService.createMessageCorrelation(messageName).processDefinitionId(processDefinition.getId()) .processInstanceBusinessKey(businessKey).setVariables(variables).correlateStartMessage(); } else { - MessageCorrelationBuilder correlation = runtimeService.createMessageCorrelation(messageName) - .setVariables(variables).processInstanceBusinessKey(businessKey); + MessageCorrelationBuilder correlation; + + if (instances.size() > 0) + correlation = runtimeService.createMessageCorrelation(messageName).setVariables(variables) + .processInstanceBusinessKey(businessKey); + else + correlation = runtimeService.createMessageCorrelation(messageName).setVariables(variables) + .processInstanceVariableEquals(BPMN_EXECUTION_VARIABLE_ALTERNATIVE_BUSINESS_KEY, + businessKey); if (correlationKey != null) - correlation = correlation - .localVariablesEqual(Map.of("correlationKey", Variables.stringValue(correlationKey))); + correlation = correlation.localVariableEquals("correlationKey", correlationKey); + // throws MismatchingMessageCorrelationException - if none or more than one execution or process + // definition is matched by the correlation correlation.correlate(); } } @@ -203,4 +213,11 @@ private ProcessInstanceQuery getProcessInstanceQuery(ProcessDefinition processDe return runtimeService.createProcessInstanceQuery().processDefinitionId(processDefinition.getId()) .processInstanceBusinessKey(businessKey); } + + private ProcessInstanceQuery getAlternativeProcessInstanceQuery(ProcessDefinition processDefinition, + String businessKey) + { + return runtimeService.createProcessInstanceQuery().processDefinitionId(processDefinition.getId()) + .variableValueEquals(BPMN_EXECUTION_VARIABLE_ALTERNATIVE_BUSINESS_KEY, businessKey); + } } diff --git a/dsf-bpe/dsf-bpe-webservice-client/pom.xml b/dsf-bpe/dsf-bpe-webservice-client/pom.xml index 051bab8be..3d1893a3c 100755 --- a/dsf-bpe/dsf-bpe-webservice-client/pom.xml +++ b/dsf-bpe/dsf-bpe-webservice-client/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-bpe-pom - 0.6.0 + 0.7.0 diff --git a/dsf-bpe/pom.xml b/dsf-bpe/pom.xml index 80a293478..f9335c981 100755 --- a/dsf-bpe/pom.xml +++ b/dsf-bpe/pom.xml @@ -8,7 +8,7 @@ org.highmed.dsf dsf-pom - 0.6.0 + 0.7.0 diff --git a/dsf-consent/dsf-consent-client-stub/pom.xml b/dsf-consent/dsf-consent-client-stub/pom.xml index 1399b7156..503255081 100644 --- a/dsf-consent/dsf-consent-client-stub/pom.xml +++ b/dsf-consent/dsf-consent-client-stub/pom.xml @@ -9,7 +9,7 @@ dsf-consent-pom org.highmed.dsf - 0.6.0 + 0.7.0 diff --git a/dsf-consent/dsf-consent-client/pom.xml b/dsf-consent/dsf-consent-client/pom.xml index 607f61137..027058c9b 100644 --- a/dsf-consent/dsf-consent-client/pom.xml +++ b/dsf-consent/dsf-consent-client/pom.xml @@ -9,7 +9,7 @@ dsf-consent-pom org.highmed.dsf - 0.6.0 + 0.7.0 diff --git a/dsf-consent/pom.xml b/dsf-consent/pom.xml index 389043270..8438de4aa 100644 --- a/dsf-consent/pom.xml +++ b/dsf-consent/pom.xml @@ -10,7 +10,7 @@ dsf-pom org.highmed.dsf - 0.6.0 + 0.7.0 diff --git a/dsf-fhir/dsf-fhir-auth/pom.xml b/dsf-fhir/dsf-fhir-auth/pom.xml index 130ddad04..c93e33d7b 100644 --- a/dsf-fhir/dsf-fhir-auth/pom.xml +++ b/dsf-fhir/dsf-fhir-auth/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-fhir-pom - 0.6.0 + 0.7.0 diff --git a/dsf-fhir/dsf-fhir-rest-adapter/pom.xml b/dsf-fhir/dsf-fhir-rest-adapter/pom.xml index f1758d073..58597c8a6 100755 --- a/dsf-fhir/dsf-fhir-rest-adapter/pom.xml +++ b/dsf-fhir/dsf-fhir-rest-adapter/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-fhir-pom - 0.6.0 + 0.7.0 diff --git a/dsf-fhir/dsf-fhir-server-jetty/pom.xml b/dsf-fhir/dsf-fhir-server-jetty/pom.xml index 324a426c8..55f8ff78d 100755 --- a/dsf-fhir/dsf-fhir-server-jetty/pom.xml +++ b/dsf-fhir/dsf-fhir-server-jetty/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-fhir-pom - 0.6.0 + 0.7.0 diff --git a/dsf-fhir/dsf-fhir-server/pom.xml b/dsf-fhir/dsf-fhir-server/pom.xml index d6c203bd4..15329c722 100755 --- a/dsf-fhir/dsf-fhir-server/pom.xml +++ b/dsf-fhir/dsf-fhir-server/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-fhir-pom - 0.6.0 + 0.7.0 diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/authentication/AuthenticationFilterConfigImpl.java b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/authentication/AuthenticationFilterConfigImpl.java index 87096638a..c05293551 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/authentication/AuthenticationFilterConfigImpl.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/authentication/AuthenticationFilterConfigImpl.java @@ -43,12 +43,12 @@ public boolean needsAuthentication(HttpServletRequest request) if (pathsNotRequiringAuthentication.contains(path)) { - logger.debug("Request path: '{}' does not need authentication", path); + logger.trace("Request path: '{}' does not need authentication", path); return false; } else { - logger.debug("Request path: '{}' needs authentication", path); + logger.trace("Request path: '{}' needs authentication", path); return true; } } diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/client/ClientProviderImpl.java b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/client/ClientProviderImpl.java index 2f7a3b526..de88e22e3 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/client/ClientProviderImpl.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/client/ClientProviderImpl.java @@ -28,6 +28,7 @@ public class ClientProviderImpl implements ClientProvider, InitializingBean private final String remoteProxySchemeHostPort; private final String remoteProxyUsername; private final char[] remoteProxyPassword; + private final boolean logRequests; private final FhirContext fhirContext; private final ReferenceCleaner referenceCleaner; private final EndpointDao endpointDao; @@ -36,7 +37,7 @@ public class ClientProviderImpl implements ClientProvider, InitializingBean public ClientProviderImpl(KeyStore webserviceTrustStore, KeyStore webserviceKeyStore, char[] webserviceKeyStorePassword, int remoteReadTimeout, int remoteConnectTimeout, String remoteProxySchemeHostPort, String remoteProxyUsername, char[] remoteProxyPassword, - FhirContext fhirContext, ReferenceCleaner referenceCleaner, EndpointDao endpointDao, + boolean logRequests, FhirContext fhirContext, ReferenceCleaner referenceCleaner, EndpointDao endpointDao, ExceptionHandler exceptionHandler) { this.webserviceTrustStore = webserviceTrustStore; @@ -47,6 +48,7 @@ public ClientProviderImpl(KeyStore webserviceTrustStore, KeyStore webserviceKeyS this.remoteProxySchemeHostPort = remoteProxySchemeHostPort; this.remoteProxyUsername = remoteProxyUsername; this.remoteProxyPassword = remoteProxyPassword; + this.logRequests = logRequests; this.fhirContext = fhirContext; this.referenceCleaner = referenceCleaner; this.endpointDao = endpointDao; @@ -73,7 +75,8 @@ public Optional getClient(String serverBase) { FhirWebserviceClient client = new FhirWebserviceClientJersey(serverBase, webserviceTrustStore, webserviceKeyStore, webserviceKeyStorePassword, remoteProxySchemeHostPort, remoteProxyUsername, - remoteProxyPassword, remoteConnectTimeout, remoteReadTimeout, null, fhirContext, referenceCleaner); + remoteProxyPassword, remoteConnectTimeout, remoteReadTimeout, logRequests, null, fhirContext, + referenceCleaner); return Optional.of(client); } diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/command/CheckReferencesCommand.java b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/command/CheckReferencesCommand.java index c7089aefd..91395cf3d 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/command/CheckReferencesCommand.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/command/CheckReferencesCommand.java @@ -2,6 +2,7 @@ import java.sql.Connection; import java.sql.SQLException; +import java.util.EnumSet; import java.util.Map; import javax.ws.rs.WebApplicationException; @@ -14,23 +15,36 @@ import org.highmed.dsf.fhir.prefer.PreferReturnType; import org.highmed.dsf.fhir.service.ReferenceExtractor; import org.highmed.dsf.fhir.service.ReferenceResolver; +import org.highmed.dsf.fhir.service.ResourceReference; +import org.highmed.dsf.fhir.service.ResourceReference.ReferenceType; import org.highmed.dsf.fhir.validation.SnapshotGenerator; import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent; +import org.hl7.fhir.r4.model.Bundle.HTTPVerb; import org.hl7.fhir.r4.model.IdType; import org.hl7.fhir.r4.model.Resource; +import org.hl7.fhir.r4.model.Task; +import org.hl7.fhir.r4.model.Task.TaskStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class CheckReferencesCommand> extends AbstractCommandWithResource implements Command { + private static final Logger logger = LoggerFactory.getLogger(CheckReferencesCommand.class); + + private final HTTPVerb verb; + public CheckReferencesCommand(int index, User user, PreferReturnType returnType, Bundle bundle, - BundleEntryComponent entry, String serverBase, AuthorizationHelper authorizationHelper, R resource, D dao, - ExceptionHandler exceptionHandler, ParameterConverter parameterConverter, + BundleEntryComponent entry, String serverBase, AuthorizationHelper authorizationHelper, R resource, + HTTPVerb verb, D dao, ExceptionHandler exceptionHandler, ParameterConverter parameterConverter, ResponseGenerator responseGenerator, ReferenceExtractor referenceExtractor, ReferenceResolver referenceResolver) { super(4, index, user, returnType, bundle, entry, serverBase, authorizationHelper, resource, dao, exceptionHandler, parameterConverter, responseGenerator, referenceExtractor, referenceResolver); + + this.verb = verb; } @Override @@ -38,6 +52,31 @@ public void execute(Map idTranslationTable, Connection connectio ValidationHelper validationHelper, SnapshotGenerator snapshotGenerator) throws SQLException, WebApplicationException { - referencesHelper.checkReferences(idTranslationTable, connection); + referencesHelper.checkReferences(idTranslationTable, connection, this::checkReferenceAfterUpdate); + } + + // See also TaskServiceImpl#checkReferenceAfterUpdate + // See also AbstractResourceServiceImpl#checkReferenceAfterUpdate + // See also AbstractResourceServiceImpl#checkReferenceAfterCreate + private boolean checkReferenceAfterUpdate(ResourceReference ref) + { + if (resource instanceof Task && HTTPVerb.PUT.equals(verb)) + { + Task task = (Task) resource; + if (EnumSet.of(TaskStatus.COMPLETED, TaskStatus.FAILED).contains(task.getStatus())) + { + ReferenceType refType = ref.getType(serverBase); + if ("Task.input".equals(ref.getLocation()) && ReferenceType.LITERAL_EXTERNAL.equals(refType)) + { + logger.warn("Skipping check of {} reference '{}' at {} in resource with {}, version {}", refType, + ref.getReference().getReference(), "Task.input", resource.getIdElement().getIdPart(), + // we are checking against the pre-update resource + resource.getIdElement().getVersionIdPartAsLong() + 1); + return false; + } + } + } + + return true; } } diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/command/CommandFactoryImpl.java b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/command/CommandFactoryImpl.java index 41ecac316..4bd0b638b 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/command/CommandFactoryImpl.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/command/CommandFactoryImpl.java @@ -29,6 +29,7 @@ import org.highmed.dsf.fhir.validation.SnapshotGenerator; import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent; +import org.hl7.fhir.r4.model.Bundle.HTTPVerb; import org.hl7.fhir.r4.model.Resource; import org.hl7.fhir.r4.model.StructureDefinition; import org.springframework.beans.factory.InitializingBean; @@ -246,11 +247,11 @@ protected Stream createCommand(int index, User user, PreferReturnType r case POST: // create Command post = post(index, user, returnType, bundle, entry, (Resource) entry.getResource()); return resolveReferences(post, index, user, returnType, bundle, entry, - (Resource) entry.getResource()); + (Resource) entry.getResource(), HTTPVerb.POST); case PUT: // update Command put = put(index, user, returnType, bundle, entry, (Resource) entry.getResource()); return resolveReferences(put, index, user, returnType, bundle, entry, - (Resource) entry.getResource()); + (Resource) entry.getResource(), HTTPVerb.PUT); default: throw new BadBundleException("Request method " + entry.getRequest().getMethod() + " at index " + index + " not supported with resource"); @@ -262,7 +263,7 @@ protected Stream createCommand(int index, User user, PreferReturnType r } private Stream resolveReferences(Command cmd, int index, User user, - PreferReturnType returnType, Bundle bundle, BundleEntryComponent entry, R resource) + PreferReturnType returnType, Bundle bundle, BundleEntryComponent entry, R resource, HTTPVerb verb) { @SuppressWarnings("unchecked") Optional> dao = (Optional>) daoProvider @@ -273,8 +274,8 @@ private Stream resolveReferences(Command cmd, int return dao .map(d -> Stream.of(cmd, new CheckReferencesCommand>(index, user, returnType, bundle, entry, - serverBase, authorizationHelper, resource, d, exceptionHandler, parameterConverter, - responseGenerator, referenceExtractor, referenceResolver))) + serverBase, authorizationHelper, resource, verb, d, exceptionHandler, + parameterConverter, responseGenerator, referenceExtractor, referenceResolver))) .orElseThrow(() -> new IllegalStateException( "Resource of type " + resource.getClass().getName() + " not supported")); } diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/command/ReferencesHelper.java b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/command/ReferencesHelper.java index e74a397f3..57f8969df 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/command/ReferencesHelper.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/command/ReferencesHelper.java @@ -2,9 +2,11 @@ import java.sql.Connection; import java.util.Map; +import java.util.function.Predicate; import javax.ws.rs.WebApplicationException; +import org.highmed.dsf.fhir.service.ResourceReference; import org.hl7.fhir.r4.model.IdType; import org.hl7.fhir.r4.model.Resource; @@ -15,5 +17,6 @@ void resolveTemporaryAndConditionalReferencesOrLiteralInternalRelatedArtifactOrA void resolveLogicalReferences(Connection connection) throws WebApplicationException; - void checkReferences(Map idTranslationTable, Connection connection) throws WebApplicationException; + void checkReferences(Map idTranslationTable, Connection connection, + Predicate checkReference) throws WebApplicationException; } \ No newline at end of file diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/command/ReferencesHelperImpl.java b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/command/ReferencesHelperImpl.java index 40ce75978..7af0b1d7f 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/command/ReferencesHelperImpl.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/command/ReferencesHelperImpl.java @@ -6,6 +6,7 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Predicate; import java.util.function.Supplier; import javax.ws.rs.WebApplicationException; @@ -203,10 +204,10 @@ private Optional resolveLogicalReference(ResourceReference ref } @Override - public void checkReferences(Map idTranslationTable, Connection connection) - throws WebApplicationException + public void checkReferences(Map idTranslationTable, Connection connection, + Predicate checkReference) throws WebApplicationException { - referenceExtractor.getReferences(resource) + referenceExtractor.getReferences(resource).filter(checkReference) .filter(ref -> referenceResolver.referenceCanBeChecked(ref, connection)).forEach(ref -> { Optional outcome = checkReference(idTranslationTable, connection, ref); diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/jdbc/AbstractResourceDaoJdbc.java b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/jdbc/AbstractResourceDaoJdbc.java index 24b19f98d..df33dbe41 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/jdbc/AbstractResourceDaoJdbc.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/dao/jdbc/AbstractResourceDaoJdbc.java @@ -846,7 +846,7 @@ private void getResources(ResultSet result, int columnIndex, List it = array.iterator(); while (it.hasNext()) diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/spring/config/ClientConfig.java b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/spring/config/ClientConfig.java index 4d8bb8bb8..a1d5ac549 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/spring/config/ClientConfig.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/spring/config/ClientConfig.java @@ -17,6 +17,9 @@ import org.bouncycastle.pkcs.PKCSException; import org.highmed.dsf.fhir.client.ClientProvider; import org.highmed.dsf.fhir.client.ClientProviderImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -26,8 +29,10 @@ import de.rwh.utils.crypto.io.PemIo; @Configuration -public class ClientConfig +public class ClientConfig implements InitializingBean { + private static final Logger logger = LoggerFactory.getLogger(ClientConfig.class); + private static final BouncyCastleProvider provider = new BouncyCastleProvider(); @Autowired @@ -62,8 +67,9 @@ public ClientProvider clientProvider() propertiesConfig.getWebserviceClientReadTimeout(), propertiesConfig.getWebserviceClientConnectTimeout(), propertiesConfig.getWebserviceClientProxyUrl(), propertiesConfig.getWebserviceClientProxyUsername(), - propertiesConfig.getWebserviceClientProxyPassword(), fhirConfig.fhirContext(), - referenceConfig.referenceCleaner(), daoConfig.endpointDao(), helperConfig.exceptionHandler()); + propertiesConfig.getWebserviceClientProxyPassword(), propertiesConfig.getWebserviceClientVerbose(), + fhirConfig.fhirContext(), referenceConfig.referenceCleaner(), daoConfig.endpointDao(), + helperConfig.exceptionHandler()); } catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException | PKCSException e) { @@ -101,4 +107,18 @@ private KeyStore createKeyStore(String certificateFile, String privateKeyFile, c return CertificateHelper.toJksKeyStore(privateKey, new Certificate[] { certificate }, subjectCommonName, keyStorePassword); } + + @Override + public void afterPropertiesSet() throws Exception + { + logger.info( + "Remote webservice client config: {trustStorePath: {}, certificatePath: {}, privateKeyPath: {}, privateKeyPassword: {}," + + " proxyUrl {}, proxyUsername {}, proxyPassword {}}", + propertiesConfig.getWebserviceClientCertificateTrustCertificatesFile(), + propertiesConfig.getWebserviceClientCertificateFile(), + propertiesConfig.getWebserviceClientCertificatePrivateKeyFile(), + propertiesConfig.getWebserviceClientCertificatePrivateKeyFilePassword() != null ? "***" : "null", + propertiesConfig.getWebserviceClientProxyUrl(), propertiesConfig.getWebserviceClientProxyUsername(), + propertiesConfig.getWebserviceClientProxyPassword() != null ? "***" : "null"); + } } diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/spring/config/PropertiesConfig.java b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/spring/config/PropertiesConfig.java index b2f15f1f6..6f1a6e39d 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/spring/config/PropertiesConfig.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/spring/config/PropertiesConfig.java @@ -96,6 +96,10 @@ public class PropertiesConfig @Value("${org.highmed.dsf.fhir.client.proxy.password:#{null}}") private char[] webserviceClientProxyPassword; + @Documentation(description = "To enable verbose logging of requests to and replies from remote DSF FHIR servers, set to `true`") + @Value("${org.highmed.dsf.fhir.client.verbose:false}") + private boolean webserviceClientVerbose; + @Documentation(description = "List of allowed CORS origins, used to set the *Access-Control-Allow-Origin* HTTP response header, which indicates whether the response can be shared with requesting code from the given origin; comma or space separated list, YAML block scalars supported") @Value("#{'${org.highmed.dsf.fhir.server.cors.origins:}'.trim().split('(,[ ]?)|(\\n)')}") private List allowedOrigins; @@ -209,6 +213,11 @@ public char[] getWebserviceClientProxyPassword() return webserviceClientProxyPassword; } + public boolean getWebserviceClientVerbose() + { + return webserviceClientVerbose; + } + public List getAllowedOrigins() { return Collections.unmodifiableList(allowedOrigins); diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/webservice/impl/AbstractResourceServiceImpl.java b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/webservice/impl/AbstractResourceServiceImpl.java index ac21ce573..ccdd7f1fc 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/webservice/impl/AbstractResourceServiceImpl.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/webservice/impl/AbstractResourceServiceImpl.java @@ -20,6 +20,7 @@ import java.util.Optional; import java.util.UUID; import java.util.function.Consumer; +import java.util.function.Predicate; import java.util.stream.Collectors; import javax.ws.rs.WebApplicationException; @@ -35,6 +36,7 @@ import org.highmed.dsf.fhir.authorization.AuthorizationRule; import org.highmed.dsf.fhir.authorization.AuthorizationRuleProvider; import org.highmed.dsf.fhir.dao.ResourceDao; +import org.highmed.dsf.fhir.dao.command.CheckReferencesCommand; import org.highmed.dsf.fhir.event.EventGenerator; import org.highmed.dsf.fhir.event.EventHandler; import org.highmed.dsf.fhir.help.ExceptionHandler; @@ -168,7 +170,7 @@ public Response create(R resource, UriInfo uri, HttpHeaders headers) R created = dao.createWithTransactionAndId(connection, resource, UUID.randomUUID()); - checkReferences(resource, connection); + checkReferences(resource, connection, ref -> checkReferenceAfterCreate(resource, ref)); connection.commit(); @@ -198,6 +200,22 @@ public Response create(R resource, UriInfo uri, HttpHeaders headers) .tag(new EntityTag(createdResource.getMeta().getVersionId(), true)).build(); } + /** + * Override this method to exclude references from being checked after a create, add similar rule to + * {@link CheckReferencesCommand} + * + * @param created + * not null + * @param ref + * not null + * @return true if a reference should be checked + * @see CheckReferencesCommand + */ + protected boolean checkReferenceAfterCreate(R created, ResourceReference ref) + { + return true; + } + private URI toLocation(R resource) { return UriBuilder.fromUri(serverBase).path(resource.getResourceType().name()) @@ -236,9 +254,10 @@ private Optional resolveLogicalReference(Resource resource, Re return Optional.of(responseGenerator.referenceTargetNotFoundLocallyByIdentifier(resource, reference)); } - private void checkReferences(Resource resource, Connection connection) throws WebApplicationException + private void checkReferences(Resource resource, Connection connection, Predicate checkReference) + throws WebApplicationException { - referenceExtractor.getReferences(resource) + referenceExtractor.getReferences(resource).filter(checkReference) .filter(ref -> referenceResolver.referenceCanBeChecked(ref, connection)).forEach(ref -> { Optional outcome = checkReference(resource, connection, ref); @@ -494,7 +513,7 @@ public Response update(String id, R resource, UriInfo uri, HttpHeaders headers) R updated = dao.update(resource, ifMatch.orElse(null)); - checkReferences(resource, connection); + checkReferences(resource, connection, ref -> checkReferenceAfterUpdate(updated, ref)); connection.commit(); @@ -525,6 +544,22 @@ public Response update(String id, R resource, UriInfo uri, HttpHeaders headers) .tag(new EntityTag(updatedResource.getMeta().getVersionId(), true)).build(); } + /** + * Override this method to exclude references from being checked after an update, add similar rule to + * {@link CheckReferencesCommand} + * + * @param updated + * not null + * @param ref + * not null + * @return true if a reference should be checked + * @see CheckReferencesCommand + */ + protected boolean checkReferenceAfterUpdate(R updated, ResourceReference ref) + { + return true; + } + /** * Override to modify the given resource before db update, throw {@link WebApplicationException} to interrupt the * normal flow. Path id vs. resource.id.idPart is checked before this method is called diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/webservice/impl/TaskServiceImpl.java b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/webservice/impl/TaskServiceImpl.java index 67da122a4..8b3c7c79f 100755 --- a/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/webservice/impl/TaskServiceImpl.java +++ b/dsf-fhir/dsf-fhir-server/src/main/java/org/highmed/dsf/fhir/webservice/impl/TaskServiceImpl.java @@ -1,5 +1,7 @@ package org.highmed.dsf.fhir.webservice.impl; +import java.util.EnumSet; + import org.highmed.dsf.fhir.authorization.AuthorizationRuleProvider; import org.highmed.dsf.fhir.dao.TaskDao; import org.highmed.dsf.fhir.event.EventGenerator; @@ -11,12 +13,19 @@ import org.highmed.dsf.fhir.service.ReferenceCleaner; import org.highmed.dsf.fhir.service.ReferenceExtractor; import org.highmed.dsf.fhir.service.ReferenceResolver; +import org.highmed.dsf.fhir.service.ResourceReference; +import org.highmed.dsf.fhir.service.ResourceReference.ReferenceType; import org.highmed.dsf.fhir.validation.ResourceValidator; import org.highmed.dsf.fhir.webservice.specification.TaskService; import org.hl7.fhir.r4.model.Task; +import org.hl7.fhir.r4.model.Task.TaskStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class TaskServiceImpl extends AbstractResourceServiceImpl implements TaskService { + private static final Logger logger = LoggerFactory.getLogger(TaskServiceImpl.class); + public TaskServiceImpl(String path, String serverBase, int defaultPageCount, TaskDao dao, ResourceValidator validator, EventHandler eventHandler, ExceptionHandler exceptionHandler, EventGenerator eventGenerator, ResponseGenerator responseGenerator, ParameterConverter parameterConverter, @@ -28,4 +37,23 @@ public TaskServiceImpl(String path, String serverBase, int defaultPageCount, Tas eventGenerator, responseGenerator, parameterConverter, referenceExtractor, referenceResolver, referenceCleaner, authorizationRuleProvider, historyService); } + + // See also CheckReferencesCommand#checkReferenceAfterUpdate + @Override + protected boolean checkReferenceAfterUpdate(Task updated, ResourceReference ref) + { + if (EnumSet.of(TaskStatus.COMPLETED, TaskStatus.FAILED).contains(updated.getStatus())) + { + ReferenceType refType = ref.getType(serverBase); + if ("Task.input".equals(ref.getLocation()) && ReferenceType.LITERAL_EXTERNAL.equals(refType)) + { + logger.warn("Skipping check of {} reference '{}' at {} in resource with {}, version {}", refType, + ref.getReference().getReference(), "Task.input", updated.getIdElement().getIdPart(), + updated.getIdElement().getVersionIdPart()); + return false; + } + } + + return super.checkReferenceAfterUpdate(updated, ref); + } } diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/static/bookmarks.js b/dsf-fhir/dsf-fhir-server/src/main/resources/static/bookmarks.js index 1b3972785..1c97d31c2 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/static/bookmarks.js +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/static/bookmarks.js @@ -95,9 +95,9 @@ function saveBookmarks(bookmarks) { } function getResourceType(url) { - const regex = new RegExp('(?:(?:[A-Za-z0-9\-\\\.\:\%\$]*\/)+)?' + const regex = new RegExp('(?:(?:http|https):\/\/(?:[A-Za-z0-9\-\\\.\:\%\$]*\/)+)?' + '(Account|ActivityDefinition|AdverseEvent|AllergyIntolerance|Appointment|AppointmentResponse|AuditEvent|Basic|Binary|BiologicallyDerivedProduct|BodyStructure|Bundle|CapabilityStatement|CarePlan|CareTeam|CatalogEntry|ChargeItem|ChargeItemDefinition|Claim|ClaimResponse|ClinicalImpression|CodeSystem|Communication|CommunicationRequest|CompartmentDefinition|Composition|ConceptMap|Condition|Consent|Contract|Coverage|CoverageEligibilityRequest|CoverageEligibilityResponse|DetectedIssue|Device|DeviceDefinition|DeviceMetric|DeviceRequest|DeviceUseStatement|DiagnosticReport|DocumentManifest|DocumentReference|EffectEvidenceSynthesis|Encounter|Endpoint|EnrollmentRequest|EnrollmentResponse|EpisodeOfCare|EventDefinition|Evidence|EvidenceVariable|ExampleScenario|ExplanationOfBenefit|FamilyMemberHistory|Flag|Goal|GraphDefinition|Group|GuidanceResponse|HealthcareService|ImagingStudy|Immunization|ImmunizationEvaluation|ImmunizationRecommendation|ImplementationGuide|InsurancePlan|Invoice|Library|Linkage|List|Location|Measure|MeasureReport|Media|Medication|MedicationAdministration|MedicationDispense|MedicationKnowledge|MedicationRequest|MedicationStatement|MedicinalProduct|MedicinalProductAuthorization|MedicinalProductContraindication|MedicinalProductIndication|MedicinalProductIngredient|MedicinalProductInteraction|MedicinalProductManufactured|MedicinalProductPackaged|MedicinalProductPharmaceutical|MedicinalProductUndesirableEffect|MessageDefinition|MessageHeader|MolecularSequence|NamingSystem|NutritionOrder|Observation|ObservationDefinition|OperationDefinition|OperationOutcome|Organization|OrganizationAffiliation|Patient|PaymentNotice|PaymentReconciliation|Person|PlanDefinition|Practitioner|PractitionerRole|Procedure|Provenance|Questionnaire|QuestionnaireResponse|RelatedPerson|RequestGroup|ResearchDefinition|ResearchElementDefinition|ResearchStudy|ResearchSubject|RiskAssessment|RiskEvidenceSynthesis|Schedule|SearchParameter|ServiceRequest|Slot|Specimen|SpecimenDefinition|StructureDefinition|StructureMap|Subscription|Substance|SubstanceNucleicAcid|SubstancePolymer|SubstanceProtein|SubstanceReferenceInformation|SubstanceSourceMaterial|SubstanceSpecification|SupplyDelivery|SupplyRequest|Task|TerminologyCapabilities|TestReport|TestScript|ValueSet|VerificationResult|VisionPrescription)' - + '(?:.*)'); + + '(?:[\/?#](?:.*)?)?$'); const match = regex.exec(url); if (match != null) return match[1]; diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/static/tabs.js b/dsf-fhir/dsf-fhir-server/src/main/resources/static/tabs.js index 564d224e5..56a74d9e0 100644 --- a/dsf-fhir/dsf-fhir-server/src/main/resources/static/tabs.js +++ b/dsf-fhir/dsf-fhir-server/src/main/resources/static/tabs.js @@ -50,36 +50,36 @@ function getDownloadFileName(lang) { } else { //Resource - if (resourceType[0] !== undefined && resourceType[1] === undefined && resourceType[2] === undefined && resourceType[3] === undefined) { - return resourceType[0] + '_Search.' + lang; + if (resourceType[1] !== undefined && resourceType[2] === undefined && resourceType[3] === undefined && resourceType[4] === undefined) { + return resourceType[1] + '_Search.' + lang; } //Resource/_history - else if (resourceType[0] !== undefined && resourceType[1] === undefined && resourceType[2] !== undefined && resourceType[3] === undefined) { - return resourceType[0] + '_History.' + lang; + else if (resourceType[1] !== undefined && resourceType[2] === undefined && resourceType[3] !== undefined && resourceType[4] === undefined) { + return resourceType[1] + '_History.' + lang; } //Resource/id - else if (resourceType[0] !== undefined && resourceType[1] !== undefined && resourceType[2] === undefined && resourceType[3] === undefined) { - return resourceType[0] + '_' + resourceType[1].substring(1) + '.' + lang; + else if (resourceType[1] !== undefined && resourceType[2] !== undefined && resourceType[3] === undefined && resourceType[4] === undefined) { + return resourceType[1] + '_' + resourceType[2].replace('/','') + '.' + lang; } //Resource/id/_history - else if (resourceType[0] !== undefined && resourceType[1] !== undefined && resourceType[2] !== undefined && resourceType[3] === undefined) { - return resourceType[0] + '_' + resourceType[1].substring(1) + '_History.' + lang; + else if (resourceType[1] !== undefined && resourceType[2] !== undefined && resourceType[3] !== undefined && resourceType[4] === undefined) { + return resourceType[1] + '_' + resourceType[2].replace('/','') + '_History.' + lang; } //Resource/id/_history/version - else if (resourceType[0] !== undefined && resourceType[1] !== undefined && resourceType[2] !== undefined && resourceType[3] !== undefined) { - return resourceType[0] + '_' + resourceType[1].substring(1) + '_v' + resourceType[3].substring(1) + '.' + lang; + else if (resourceType[1] !== undefined && resourceType[2] !== undefined && resourceType[3] !== undefined && resourceType[4] !== undefined) { + return resourceType[1] + '_' + resourceType[2].replace('/','') + '_v' + resourceType[4].replace('/','') + '.' + lang; } } } function getResourceTypeForCurrentUrl() { const url = window.location.pathname; - const regex = new RegExp('(([A-Za-z0-9\-\\\.\:\%\$]*\/)+)?' - + '(Account|ActivityDefinition|AdverseEvent|AllergyIntolerance|Appointment|AppointmentResponse|AuditEvent|Basic|Binary|BiologicallyDerivedProduct|BodyStructure|Bundle|CapabilityStatement|CarePlan|CareTeam|CatalogEntry|ChargeItem|ChargeItemDefinition|Claim|ClaimResponse|ClinicalImpression|CodeSystem|Communication|CommunicationRequest|CompartmentDefinition|Composition|ConceptMap|Condition|Consent|Contract|Coverage|CoverageEligibilityRequest|CoverageEligibilityResponse|DetectedIssue|Device|DeviceDefinition|DeviceMetric|DeviceRequest|DeviceUseStatement|DiagnosticReport|DocumentManifest|DocumentReference|EffectEvidenceSynthesis|Encounter|Endpoint|EnrollmentRequest|EnrollmentResponse|EpisodeOfCare|EventDefinition|Evidence|EvidenceVariable|ExampleScenario|ExplanationOfBenefit|FamilyMemberHistory|Flag|Goal|GraphDefinition|Group|GuidanceResponse|HealthcareService|ImagingStudy|Immunization|ImmunizationEvaluation|ImmunizationRecommendation|ImplementationGuide|InsurancePlan|Invoice|Library|Linkage|List|Location|Measure|MeasureReport|Media|Medication|MedicationAdministration|MedicationDispense|MedicationKnowledge|MedicationRequest|MedicationStatement|MedicinalProduct|MedicinalProductAuthorization|MedicinalProductContraindication|MedicinalProductIndication|MedicinalProductIngredient|MedicinalProductInteraction|MedicinalProductManufactured|MedicinalProductPackaged|MedicinalProductPharmaceutical|MedicinalProductUndesirableEffect|MessageDefinition|MessageHeader|MolecularSequence|NamingSystem|NutritionOrder|Observation|ObservationDefinition|OperationDefinition|OperationOutcome|Organization|OrganizationAffiliation|Patient|PaymentNotice|PaymentReconciliation|Person|PlanDefinition|Practitioner|PractitionerRole|Procedure|Provenance|Questionnaire|QuestionnaireResponse|RelatedPerson|RequestGroup|ResearchDefinition|ResearchElementDefinition|ResearchStudy|ResearchSubject|RiskAssessment|RiskEvidenceSynthesis|Schedule|SearchParameter|ServiceRequest|Slot|Specimen|SpecimenDefinition|StructureDefinition|StructureMap|Subscription|Substance|SubstanceNucleicAcid|SubstancePolymer|SubstanceProtein|SubstanceReferenceInformation|SubstanceSourceMaterial|SubstanceSpecification|SupplyDelivery|SupplyRequest|Task|TerminologyCapabilities|TestReport|TestScript|ValueSet|VerificationResult|VisionPrescription)' - + '(\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})?(\/_history)?(\/[0-9]+)?.*'); + const regex = new RegExp('(?:(?:[A-Za-z0-9\-\\\.\:\%\$]*\/)+)?' + + '(Account|ActivityDefinition|AdverseEvent|AllergyIntolerance|Appointment|AppointmentResponse|AuditEvent|Basic|Binary|BiologicallyDerivedProduct|BodyStructure|Bundle|CapabilityStatement|CarePlan|CareTeam|CatalogEntry|ChargeItem|ChargeItemDefinition|Claim|ClaimResponse|ClinicalImpression|CodeSystem|Communication|CommunicationRequest|CompartmentDefinition|Composition|ConceptMap|Condition|Consent|Contract|Coverage|CoverageEligibilityRequest|CoverageEligibilityResponse|DetectedIssue|Device|DeviceDefinition|DeviceMetric|DeviceRequest|DeviceUseStatement|DiagnosticReport|DocumentManifest|DocumentReference|EffectEvidenceSynthesis|Encounter|Endpoint|EnrollmentRequest|EnrollmentResponse|EpisodeOfCare|EventDefinition|Evidence|EvidenceVariable|ExampleScenario|ExplanationOfBenefit|FamilyMemberHistory|Flag|Goal|GraphDefinition|Group|GuidanceResponse|HealthcareService|ImagingStudy|Immunization|ImmunizationEvaluation|ImmunizationRecommendation|ImplementationGuide|InsurancePlan|Invoice|Library|Linkage|List|Location|Measure|MeasureReport|Media|Medication|MedicationAdministration|MedicationDispense|MedicationKnowledge|MedicationRequest|MedicationStatement|MedicinalProduct|MedicinalProductAuthorization|MedicinalProductContraindication|MedicinalProductIndication|MedicinalProductIngredient|MedicinalProductInteraction|MedicinalProductManufactured|MedicinalProductPackaged|MedicinalProductPharmaceutical|MedicinalProductUndesirableEffect|MessageDefinition|MessageHeader|MolecularSequence|NamingSystem|NutritionOrder|Observation|ObservationDefinition|OperationDefinition|OperationOutcome|Organization|OrganizationAffiliation|Patient|PaymentNotice|PaymentReconciliation|Person|PlanDefinition|Practitioner|PractitionerRole|Procedure|Provenance|Questionnaire|QuestionnaireResponse|RelatedPerson|RequestGroup|ResearchDefinition|ResearchElementDefinition|ResearchStudy|ResearchSubject|RiskAssessment|RiskEvidenceSynthesis|Schedule|SearchParameter|ServiceRequest|Slot|Specimen|SpecimenDefinition|StructureDefinition|StructureMap|Subscription|Substance|SubstanceNucleicAcid|SubstancePolymer|SubstanceProtein|SubstanceReferenceInformation|SubstanceSourceMaterial|SubstanceSpecification|SupplyDelivery|SupplyRequest|Task|TerminologyCapabilities|TestReport|TestScript|ValueSet|VerificationResult|VisionPrescription)' + + '(?:(?:\/([A-Za-z0-9\-\.]{1,64}))?(?:\/(_history)(?:\/([0-9]{1,64}))?)?)?(?:\\?.*)?$'); const match = regex.exec(url); - if (match != null && match.length == 7) - return [match[3], match[4], match[5], match[6]]; + if (match != null) + return match; else return null; } \ No newline at end of file diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/org/highmed/dsf/fhir/client/ClientProviderTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/org/highmed/dsf/fhir/client/ClientProviderTest.java index 0296722ba..1078e9e26 100755 --- a/dsf-fhir/dsf-fhir-server/src/test/java/org/highmed/dsf/fhir/client/ClientProviderTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/org/highmed/dsf/fhir/client/ClientProviderTest.java @@ -44,6 +44,7 @@ public void before() throws Exception char[] remoteProxyPassword = null; String remoteProxyUsername = null; String remoteProxySchemeHostPort = null; + boolean logRequests = false; FhirContext fhirContext = mock(FhirContext.class); referenceCleaner = mock(ReferenceCleaner.class); endpointDao = mock(EndpointDao.class); @@ -51,7 +52,7 @@ public void before() throws Exception provider = new ClientProviderImpl(webserviceTrustStore, webserviceKeyStore, webserviceKeyStorePassword, remoteReadTimeout, remoteConnectTimeout, remoteProxySchemeHostPort, remoteProxyUsername, - remoteProxyPassword, fhirContext, referenceCleaner, endpointDao, exceptionHandler); + remoteProxyPassword, logRequests, fhirContext, referenceCleaner, endpointDao, exceptionHandler); } @Test diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/org/highmed/dsf/fhir/integration/AbstractIntegrationTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/org/highmed/dsf/fhir/integration/AbstractIntegrationTest.java index 11dd3b3af..9ab605d77 100755 --- a/dsf-fhir/dsf-fhir-server/src/test/java/org/highmed/dsf/fhir/integration/AbstractIntegrationTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/org/highmed/dsf/fhir/integration/AbstractIntegrationTest.java @@ -155,7 +155,7 @@ private static FhirWebserviceClient createWebserviceClient(KeyStore trustStore, char[] keyStorePassword, FhirContext fhirContext, ReferenceCleaner referenceCleaner) { return new FhirWebserviceClientJersey(BASE_URL, trustStore, keyStore, keyStorePassword, null, null, null, 0, 0, - null, fhirContext, referenceCleaner); + false, null, fhirContext, referenceCleaner); } private static WebsocketClient createWebsocketClient(KeyStore trustStore, KeyStore keyStore, diff --git a/dsf-fhir/dsf-fhir-server/src/test/java/org/highmed/dsf/fhir/integration/TaskIntegrationTest.java b/dsf-fhir/dsf-fhir-server/src/test/java/org/highmed/dsf/fhir/integration/TaskIntegrationTest.java index 8d3c4c6a9..ef9fea0ed 100755 --- a/dsf-fhir/dsf-fhir-server/src/test/java/org/highmed/dsf/fhir/integration/TaskIntegrationTest.java +++ b/dsf-fhir/dsf-fhir-server/src/test/java/org/highmed/dsf/fhir/integration/TaskIntegrationTest.java @@ -1,11 +1,16 @@ package org.highmed.dsf.fhir.integration; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Paths; +import java.sql.Connection; import java.util.Arrays; import java.util.Collections; import java.util.Date; @@ -17,9 +22,16 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response.Status; +import org.apache.commons.dbcp2.BasicDataSource; import org.highmed.dsf.fhir.authentication.OrganizationProvider; +import org.highmed.dsf.fhir.authentication.User; import org.highmed.dsf.fhir.dao.OrganizationDao; import org.highmed.dsf.fhir.dao.TaskDao; +import org.highmed.dsf.fhir.dao.command.ReferencesHelperImpl; +import org.highmed.dsf.fhir.help.ResponseGenerator; +import org.highmed.dsf.fhir.service.ReferenceCleaner; +import org.highmed.dsf.fhir.service.ReferenceExtractor; +import org.highmed.dsf.fhir.service.ReferenceResolver; import org.highmed.fhir.client.FhirWebserviceClient; import org.hl7.fhir.r4.model.ActivityDefinition; import org.hl7.fhir.r4.model.Bundle; @@ -1057,4 +1069,96 @@ public void testSearchByProfile() throws Exception assertEquals(task2.getMeta().getProfile().get(0).getValue(), result6.getEntry().get(0).getResource().getMeta().getProfile().get(0).getValue()); } + + @Test + public void testUpdateTaskFromInProgressToCompletedWithNonExistingInputReferenceToExternalBinary() throws Exception + { + ActivityDefinition ad2 = readActivityDefinition("highmed-test-activity-definition2-0.5.0.xml"); + ActivityDefinition createdAd2 = getWebserviceClient().create(ad2); + assertNotNull(createdAd2); + assertNotNull(createdAd2.getIdElement().getIdPart()); + + StructureDefinition testTaskProfile = readTestTaskProfile(); + StructureDefinition createdTestTaskProfile = getWebserviceClient().create(testTaskProfile); + assertNotNull(createdTestTaskProfile); + assertNotNull(createdTestTaskProfile.getIdElement().getIdPart()); + + Task task = readTestTask("External_Test_Organization", "Test_Organization"); + task.setStatus(TaskStatus.INPROGRESS); + task.addInput().setValue(new Reference("https://localhost:80010/fhir/Binary/" + UUID.randomUUID().toString())) + .getType().getCodingFirstRep().setSystem("http://test.com/fhir/CodeSystem/test").setCode("binary-ref"); + + TaskDao taskDao = getSpringWebApplicationContext().getBean(TaskDao.class); + Task created = taskDao.create(task); + + ReferenceCleaner cleaner = getSpringWebApplicationContext().getBean(ReferenceCleaner.class); + cleaner.cleanLiteralReferences(created); + + created.setStatus(TaskStatus.COMPLETED); + + Task updatedTask = getWebserviceClient().update(created); + assertNotNull(updatedTask); + assertNotNull(updatedTask.getIdElement().getIdPart()); + } + + @Test + public void testUpdateTaskFromInProgressToCompletedWithNonExistingInputReferenceToExternalBinaryViaBundle() + throws Exception + { + ActivityDefinition ad2 = readActivityDefinition("highmed-test-activity-definition2-0.5.0.xml"); + ActivityDefinition createdAd2 = getWebserviceClient().create(ad2); + assertNotNull(createdAd2); + assertNotNull(createdAd2.getIdElement().getIdPart()); + + StructureDefinition testTaskProfile = readTestTaskProfile(); + StructureDefinition createdTestTaskProfile = getWebserviceClient().create(testTaskProfile); + assertNotNull(createdTestTaskProfile); + assertNotNull(createdTestTaskProfile.getIdElement().getIdPart()); + + Task task = readTestTask("External_Test_Organization", "Test_Organization"); + task.setStatus(TaskStatus.INPROGRESS); + task.addInput().setValue(new Reference("https://localhost:80010/fhir/Binary/" + UUID.randomUUID().toString())) + .getType().getCodingFirstRep().setSystem("http://test.com/fhir/CodeSystem/test").setCode("binary-ref"); + + OrganizationProvider organizationProvider = getSpringWebApplicationContext() + .getBean(OrganizationProvider.class); + ReferenceExtractor referenceExtractor = getSpringWebApplicationContext().getBean(ReferenceExtractor.class); + ReferenceResolver referenceResolver = getSpringWebApplicationContext().getBean(ReferenceResolver.class); + ResponseGenerator responseGenerator = getSpringWebApplicationContext().getBean(ResponseGenerator.class); + BasicDataSource dataSource = getSpringWebApplicationContext().getBean("dataSource", BasicDataSource.class); + + ReferencesHelperImpl referencesHelper = new ReferencesHelperImpl<>(0, + User.local(organizationProvider.getLocalOrganization().get()), task, BASE_URL, referenceExtractor, + referenceResolver, responseGenerator); + try (Connection connection = dataSource.getConnection()) + { + System.out.println(fhirContext.newJsonParser().encodeResourceToString(task)); + referencesHelper.resolveLogicalReferences(connection); + System.out.println(fhirContext.newJsonParser().encodeResourceToString(task)); + } + + TaskDao taskDao = getSpringWebApplicationContext().getBean(TaskDao.class); + Task created = taskDao.create(task); + + ReferenceCleaner referenceCleaner = getSpringWebApplicationContext().getBean(ReferenceCleaner.class); + referenceCleaner.cleanLiteralReferences(created); + created.setStatus(TaskStatus.COMPLETED); + + Bundle bundle = new Bundle(); + bundle.setType(BundleType.TRANSACTION); + BundleEntryComponent entry = bundle.addEntry() + .setFullUrl(created.getIdElement().withServerBase(BASE_URL, "Task").toVersionless().getValue()); + entry.setResource(created).getRequest().setMethod(HTTPVerb.PUT) + .setUrl("Task/" + created.getIdElement().getIdPart()); + + Bundle response = getWebserviceClient().postBundle(bundle); + assertNotNull(response); + assertEquals(BundleType.TRANSACTIONRESPONSE, response.getType()); + assertTrue(response.hasEntry()); + assertEquals(1, response.getEntry().size()); + assertTrue(response.getEntryFirstRep().hasResponse()); + assertEquals("200 OK", response.getEntryFirstRep().getResponse().getStatus()); + assertTrue(response.getEntryFirstRep().hasResource()); + assertTrue(response.getEntryFirstRep().getResource() instanceof Task); + } } diff --git a/dsf-fhir/dsf-fhir-validation/pom.xml b/dsf-fhir/dsf-fhir-validation/pom.xml index 1f7420a05..f9ef2bdca 100644 --- a/dsf-fhir/dsf-fhir-validation/pom.xml +++ b/dsf-fhir/dsf-fhir-validation/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-fhir-pom - 0.6.0 + 0.7.0 @@ -93,7 +93,7 @@ - diff --git a/dsf-fhir/dsf-fhir-validation/src/main/java/org/highmed/dsf/fhir/validation/SnapshotGenerator.java b/dsf-fhir/dsf-fhir-validation/src/main/java/org/highmed/dsf/fhir/validation/SnapshotGenerator.java index f2ffe050b..58eadac17 100755 --- a/dsf-fhir/dsf-fhir-validation/src/main/java/org/highmed/dsf/fhir/validation/SnapshotGenerator.java +++ b/dsf-fhir/dsf-fhir-validation/src/main/java/org/highmed/dsf/fhir/validation/SnapshotGenerator.java @@ -1,5 +1,7 @@ package org.highmed.dsf.fhir.validation; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.hl7.fhir.r4.model.StructureDefinition; @@ -7,15 +9,16 @@ public interface SnapshotGenerator { - class SnapshotWithValidationMessages + public class SnapshotWithValidationMessages { private final StructureDefinition snapshot; - private final List messages; + private final List messages = new ArrayList<>(); - SnapshotWithValidationMessages(StructureDefinition snapshot, List messages) + public SnapshotWithValidationMessages(StructureDefinition snapshot, List messages) { this.snapshot = snapshot; - this.messages = messages; + if (messages != null) + this.messages.addAll(messages); } public StructureDefinition getSnapshot() @@ -25,7 +28,7 @@ public StructureDefinition getSnapshot() public List getMessages() { - return messages; + return Collections.unmodifiableList(messages); } } diff --git a/dsf-fhir/dsf-fhir-validation/src/main/java/org/highmed/dsf/fhir/validation/SnapshotGeneratorImpl.java b/dsf-fhir/dsf-fhir-validation/src/main/java/org/highmed/dsf/fhir/validation/SnapshotGeneratorImpl.java index 733501854..1ecdbd06f 100755 --- a/dsf-fhir/dsf-fhir-validation/src/main/java/org/highmed/dsf/fhir/validation/SnapshotGeneratorImpl.java +++ b/dsf-fhir/dsf-fhir-validation/src/main/java/org/highmed/dsf/fhir/validation/SnapshotGeneratorImpl.java @@ -26,7 +26,7 @@ public SnapshotGeneratorImpl(FhirContext fhirContext, IValidationSupport validat worker = createWorker(fhirContext, validationSupport); } - protected HapiWorkerContext createWorker(FhirContext context, IValidationSupport validationSupport) + protected IWorkerContext createWorker(FhirContext context, IValidationSupport validationSupport) { HapiWorkerContext workerContext = new HapiWorkerContext(context, validationSupport); workerContext.setLocale(context.getLocalizer().getLocale()); @@ -65,7 +65,7 @@ public SnapshotWithValidationMessages generateSnapshot(StructureDefinition diffe differential.getIdElement().getIdPart(), differential.getUrl(), differential.getVersion()); else { - logger.warn("Snapshot not generated for StructureDefinition with id {}, url {}, version {}", + logger.warn("Snapshot generated with issues for StructureDefinition with id {}, url {}, version {}", differential.getIdElement().getIdPart(), differential.getUrl(), differential.getVersion()); messages.forEach(m -> logger.warn("Issue while generating snapshot: {} - {} - {}", m.getDisplay(), m.getLine(), m.getMessage())); diff --git a/dsf-fhir/dsf-fhir-webservice-client/pom.xml b/dsf-fhir/dsf-fhir-webservice-client/pom.xml index 33e184523..8a0da2e6e 100755 --- a/dsf-fhir/dsf-fhir-webservice-client/pom.xml +++ b/dsf-fhir/dsf-fhir-webservice-client/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-fhir-pom - 0.6.0 + 0.7.0 diff --git a/dsf-fhir/dsf-fhir-webservice-client/src/main/java/org/highmed/fhir/client/AbstractJerseyClient.java b/dsf-fhir/dsf-fhir-webservice-client/src/main/java/org/highmed/fhir/client/AbstractJerseyClient.java index e1960db07..eef20700e 100644 --- a/dsf-fhir/dsf-fhir-webservice-client/src/main/java/org/highmed/fhir/client/AbstractJerseyClient.java +++ b/dsf-fhir/dsf-fhir-webservice-client/src/main/java/org/highmed/fhir/client/AbstractJerseyClient.java @@ -3,6 +3,7 @@ import java.security.KeyStore; import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.logging.Level; import javax.net.ssl.SSLContext; import javax.ws.rs.client.Client; @@ -15,11 +16,20 @@ import org.glassfish.jersey.client.ClientProperties; import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJaxbJsonProvider; import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJsonProvider; +import org.glassfish.jersey.logging.LoggingFeature; +import org.glassfish.jersey.logging.LoggingFeature.Verbosity; import com.fasterxml.jackson.databind.ObjectMapper; public class AbstractJerseyClient { + private static final java.util.logging.Logger requestDebugLogger; + static + { + requestDebugLogger = java.util.logging.Logger.getLogger(AbstractJerseyClient.class.getName()); + requestDebugLogger.setLevel(Level.INFO); + } + private final Client client; private final String baseUrl; @@ -29,12 +39,12 @@ public AbstractJerseyClient(String baseUrl, KeyStore trustStore, KeyStore keySto ObjectMapper objectMapper, List componentsToRegister) { this(baseUrl, trustStore, keyStore, keyStorePassword, null, null, null, 0, 0, objectMapper, - componentsToRegister); + componentsToRegister, false); } public AbstractJerseyClient(String baseUrl, KeyStore trustStore, KeyStore keyStore, char[] keyStorePassword, String proxySchemeHostPort, String proxyUserName, char[] proxyPassword, int connectTimeout, int readTimeout, - ObjectMapper objectMapper, List componentsToRegister) + ObjectMapper objectMapper, List componentsToRegister, boolean logRequests) { SSLContext sslContext = null; if (trustStore != null && keyStore == null && keyStorePassword == null) @@ -68,6 +78,12 @@ else if (trustStore != null && keyStore != null && keyStorePassword != null) if (componentsToRegister != null) componentsToRegister.forEach(builder::register); + if (logRequests) + { + builder = builder.register(new LoggingFeature(requestDebugLogger, Level.INFO, Verbosity.PAYLOAD_ANY, + LoggingFeature.DEFAULT_MAX_ENTITY_SIZE)); + } + client = builder.build(); this.baseUrl = baseUrl.endsWith("/") ? baseUrl : baseUrl + "/"; diff --git a/dsf-fhir/dsf-fhir-webservice-client/src/main/java/org/highmed/fhir/client/FhirWebserviceClientJersey.java b/dsf-fhir/dsf-fhir-webservice-client/src/main/java/org/highmed/fhir/client/FhirWebserviceClientJersey.java index e9ad1a751..0e676b685 100755 --- a/dsf-fhir/dsf-fhir-webservice-client/src/main/java/org/highmed/fhir/client/FhirWebserviceClientJersey.java +++ b/dsf-fhir/dsf-fhir-webservice-client/src/main/java/org/highmed/fhir/client/FhirWebserviceClientJersey.java @@ -117,10 +117,10 @@ public class FhirWebserviceClientJersey extends AbstractJerseyClient implements public FhirWebserviceClientJersey(String baseUrl, KeyStore trustStore, KeyStore keyStore, char[] keyStorePassword, String proxySchemeHostPort, String proxyUserName, char[] proxyPassword, int connectTimeout, int readTimeout, - ObjectMapper objectMapper, FhirContext fhirContext, ReferenceCleaner referenceCleaner) + boolean logRequests, ObjectMapper objectMapper, FhirContext fhirContext, ReferenceCleaner referenceCleaner) { super(baseUrl, trustStore, keyStore, keyStorePassword, proxySchemeHostPort, proxyUserName, proxyPassword, - connectTimeout, readTimeout, objectMapper, components(fhirContext)); + connectTimeout, readTimeout, objectMapper, components(fhirContext), logRequests); this.referenceCleaner = referenceCleaner; diff --git a/dsf-fhir/dsf-fhir-websocket-client/pom.xml b/dsf-fhir/dsf-fhir-websocket-client/pom.xml index b485da765..f5828e649 100755 --- a/dsf-fhir/dsf-fhir-websocket-client/pom.xml +++ b/dsf-fhir/dsf-fhir-websocket-client/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-fhir-pom - 0.6.0 + 0.7.0 diff --git a/dsf-fhir/dsf-fhir-websocket-client/src/main/java/org/highmed/fhir/client/ClientEndpoint.java b/dsf-fhir/dsf-fhir-websocket-client/src/main/java/org/highmed/fhir/client/ClientEndpoint.java index 057354f67..93b8ba1a5 100755 --- a/dsf-fhir/dsf-fhir-websocket-client/src/main/java/org/highmed/fhir/client/ClientEndpoint.java +++ b/dsf-fhir/dsf-fhir-websocket-client/src/main/java/org/highmed/fhir/client/ClientEndpoint.java @@ -35,7 +35,8 @@ public ClientEndpoint(Runnable reconnector, String subscriptionIdPart) @Override public void onOpen(Session session, EndpointConfig config) { - logger.debug("Websocket onOpen"); + logger.info("Websocket connected {uri: {}, session-id: {}}", session.getRequestURI().toString(), + session.getId()); session.addMessageHandler(new MessageHandler.Whole() // don't use lambda { @@ -77,7 +78,8 @@ else if (domainResourceHandler != null && parserFactory != null) @Override public void onClose(Session session, CloseReason closeReason) { - logger.info("Websocket onClose {}", closeReason.getReasonPhrase()); + logger.info("Websocket closed {uri: {}, session-id: {}}: {}", session.getRequestURI().toString(), + session.getId(), closeReason.getReasonPhrase()); if (CloseReason.CloseCodes.CANNOT_ACCEPT.equals(closeReason.getCloseCode())) { @@ -89,7 +91,8 @@ public void onClose(Session session, CloseReason closeReason) @Override public void onError(Session session, Throwable throwable) { - logger.warn("Websocket onError", throwable); + logger.warn("Websocket closed with error {uri: " + session.getRequestURI().toString() + ", session-id: " + + session.getId() + "}: {}", throwable); } public void setDomainResourceHandler(Consumer handler, Supplier parser) diff --git a/dsf-fhir/dsf-fhir-websocket-client/src/main/java/org/highmed/fhir/client/WebsocketClientTyrus.java b/dsf-fhir/dsf-fhir-websocket-client/src/main/java/org/highmed/fhir/client/WebsocketClientTyrus.java index 8f5801f35..d461da0c7 100755 --- a/dsf-fhir/dsf-fhir-websocket-client/src/main/java/org/highmed/fhir/client/WebsocketClientTyrus.java +++ b/dsf-fhir/dsf-fhir-websocket-client/src/main/java/org/highmed/fhir/client/WebsocketClientTyrus.java @@ -35,15 +35,38 @@ public class WebsocketClientTyrus implements WebsocketClient @Override public boolean onConnectFailure(Exception exception) { - logger.warn("onConnectFailure {}: {}", exception.getClass().getName(), exception.getMessage()); + logger.warn("Websocket connection failed: {}", getMessages(exception)); logger.debug("onConnectFailure", exception); return true; } + private String getMessages(Exception e) + { + StringBuilder b = new StringBuilder(); + if (e != null) + { + if (e.getMessage() != null) + b.append(e.getMessage()); + + Throwable cause = e.getCause(); + while (cause != null) + { + if (cause.getMessage() != null) + { + b.append(' '); + b.append(cause.getMessage()); + } + + cause = cause.getCause(); + } + } + return b.toString(); + } + @Override public boolean onDisconnect(CloseReason closeReason) { - logger.warn("OnDisconnect {}", closeReason.getReasonPhrase()); + logger.debug("onDisconnect {}", closeReason.getReasonPhrase()); return !closed; } }; diff --git a/dsf-fhir/pom.xml b/dsf-fhir/pom.xml index 567afc015..9147cb5ae 100755 --- a/dsf-fhir/pom.xml +++ b/dsf-fhir/pom.xml @@ -8,7 +8,7 @@ org.highmed.dsf dsf-pom - 0.6.0 + 0.7.0 diff --git a/dsf-mpi/dsf-mpi-client-pdq/pom.xml b/dsf-mpi/dsf-mpi-client-pdq/pom.xml index 2046d6edc..a2fd8907a 100644 --- a/dsf-mpi/dsf-mpi-client-pdq/pom.xml +++ b/dsf-mpi/dsf-mpi-client-pdq/pom.xml @@ -9,7 +9,7 @@ dsf-mpi-pom org.highmed.dsf - 0.6.0 + 0.7.0 diff --git a/dsf-mpi/dsf-mpi-client-stub/pom.xml b/dsf-mpi/dsf-mpi-client-stub/pom.xml index f05ecbaa6..50589e69d 100644 --- a/dsf-mpi/dsf-mpi-client-stub/pom.xml +++ b/dsf-mpi/dsf-mpi-client-stub/pom.xml @@ -9,7 +9,7 @@ dsf-mpi-pom org.highmed.dsf - 0.6.0 + 0.7.0 diff --git a/dsf-mpi/dsf-mpi-client/pom.xml b/dsf-mpi/dsf-mpi-client/pom.xml index 9f044b103..b9001f5fa 100644 --- a/dsf-mpi/dsf-mpi-client/pom.xml +++ b/dsf-mpi/dsf-mpi-client/pom.xml @@ -9,7 +9,7 @@ dsf-mpi-pom org.highmed.dsf - 0.6.0 + 0.7.0 diff --git a/dsf-mpi/pom.xml b/dsf-mpi/pom.xml index ac80ddb85..a6a247fd5 100644 --- a/dsf-mpi/pom.xml +++ b/dsf-mpi/pom.xml @@ -10,7 +10,7 @@ dsf-pom org.highmed.dsf - 0.6.0 + 0.7.0 diff --git a/dsf-openehr/dsf-openehr-client-impl/pom.xml b/dsf-openehr/dsf-openehr-client-impl/pom.xml index db821ca68..a06dcb7dc 100644 --- a/dsf-openehr/dsf-openehr-client-impl/pom.xml +++ b/dsf-openehr/dsf-openehr-client-impl/pom.xml @@ -9,7 +9,7 @@ dsf-openehr-pom org.highmed.dsf - 0.6.0 + 0.7.0 diff --git a/dsf-openehr/dsf-openehr-client-stub/pom.xml b/dsf-openehr/dsf-openehr-client-stub/pom.xml index 1552c57d3..64e51b14f 100644 --- a/dsf-openehr/dsf-openehr-client-stub/pom.xml +++ b/dsf-openehr/dsf-openehr-client-stub/pom.xml @@ -8,7 +8,7 @@ dsf-openehr-pom org.highmed.dsf - 0.6.0 + 0.7.0 diff --git a/dsf-openehr/dsf-openehr-client/pom.xml b/dsf-openehr/dsf-openehr-client/pom.xml index e5022a417..68608f0aa 100644 --- a/dsf-openehr/dsf-openehr-client/pom.xml +++ b/dsf-openehr/dsf-openehr-client/pom.xml @@ -8,7 +8,7 @@ dsf-openehr-pom org.highmed.dsf - 0.6.0 + 0.7.0 diff --git a/dsf-openehr/dsf-openehr-model/pom.xml b/dsf-openehr/dsf-openehr-model/pom.xml index 9892557a0..ea657afa1 100644 --- a/dsf-openehr/dsf-openehr-model/pom.xml +++ b/dsf-openehr/dsf-openehr-model/pom.xml @@ -8,7 +8,7 @@ dsf-openehr-pom org.highmed.dsf - 0.6.0 + 0.7.0 diff --git a/dsf-openehr/pom.xml b/dsf-openehr/pom.xml index cf93fe4ee..ebc9f7c79 100755 --- a/dsf-openehr/pom.xml +++ b/dsf-openehr/pom.xml @@ -10,7 +10,7 @@ dsf-pom org.highmed.dsf - 0.6.0 + 0.7.0 diff --git a/dsf-pseudonymization/dsf-pseudonymization-base/pom.xml b/dsf-pseudonymization/dsf-pseudonymization-base/pom.xml index f68fe54df..9af74e8fd 100644 --- a/dsf-pseudonymization/dsf-pseudonymization-base/pom.xml +++ b/dsf-pseudonymization/dsf-pseudonymization-base/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-pseudonymization-pom - 0.6.0 + 0.7.0 diff --git a/dsf-pseudonymization/dsf-pseudonymization-client-stub/pom.xml b/dsf-pseudonymization/dsf-pseudonymization-client-stub/pom.xml index f00ae7876..ab174b257 100644 --- a/dsf-pseudonymization/dsf-pseudonymization-client-stub/pom.xml +++ b/dsf-pseudonymization/dsf-pseudonymization-client-stub/pom.xml @@ -9,7 +9,7 @@ dsf-pseudonymization-pom org.highmed.dsf - 0.6.0 + 0.7.0 diff --git a/dsf-pseudonymization/dsf-pseudonymization-client/pom.xml b/dsf-pseudonymization/dsf-pseudonymization-client/pom.xml index 797a80d45..9ca985988 100644 --- a/dsf-pseudonymization/dsf-pseudonymization-client/pom.xml +++ b/dsf-pseudonymization/dsf-pseudonymization-client/pom.xml @@ -9,7 +9,7 @@ dsf-pseudonymization-pom org.highmed.dsf - 0.6.0 + 0.7.0 diff --git a/dsf-pseudonymization/dsf-pseudonymization-medic/pom.xml b/dsf-pseudonymization/dsf-pseudonymization-medic/pom.xml index 60defdb5c..b522db305 100644 --- a/dsf-pseudonymization/dsf-pseudonymization-medic/pom.xml +++ b/dsf-pseudonymization/dsf-pseudonymization-medic/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-pseudonymization-pom - 0.6.0 + 0.7.0 diff --git a/dsf-pseudonymization/dsf-pseudonymization-ttp/pom.xml b/dsf-pseudonymization/dsf-pseudonymization-ttp/pom.xml index c17ded770..f6d3dbad3 100644 --- a/dsf-pseudonymization/dsf-pseudonymization-ttp/pom.xml +++ b/dsf-pseudonymization/dsf-pseudonymization-ttp/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-pseudonymization-pom - 0.6.0 + 0.7.0 diff --git a/dsf-pseudonymization/pom.xml b/dsf-pseudonymization/pom.xml index 08a475225..b7c6ed798 100644 --- a/dsf-pseudonymization/pom.xml +++ b/dsf-pseudonymization/pom.xml @@ -8,7 +8,7 @@ org.highmed.dsf dsf-pom - 0.6.0 + 0.7.0 diff --git a/dsf-tools/dsf-tools-build-info-reader/pom.xml b/dsf-tools/dsf-tools-build-info-reader/pom.xml index 347886924..972e812d8 100644 --- a/dsf-tools/dsf-tools-build-info-reader/pom.xml +++ b/dsf-tools/dsf-tools-build-info-reader/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-tools-pom - 0.6.0 + 0.7.0 diff --git a/dsf-tools/dsf-tools-bundle-generator/pom.xml b/dsf-tools/dsf-tools-bundle-generator/pom.xml index 2e83f1ee0..2bf548612 100755 --- a/dsf-tools/dsf-tools-bundle-generator/pom.xml +++ b/dsf-tools/dsf-tools-bundle-generator/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-tools-pom - 0.6.0 + 0.7.0 diff --git a/dsf-tools/dsf-tools-db-migration/pom.xml b/dsf-tools/dsf-tools-db-migration/pom.xml index 454b45aa9..2306a5d5d 100755 --- a/dsf-tools/dsf-tools-db-migration/pom.xml +++ b/dsf-tools/dsf-tools-db-migration/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-tools-pom - 0.6.0 + 0.7.0 diff --git a/dsf-tools/dsf-tools-docker-secrets-reader/pom.xml b/dsf-tools/dsf-tools-docker-secrets-reader/pom.xml index 2a8711a06..c6fd2658a 100644 --- a/dsf-tools/dsf-tools-docker-secrets-reader/pom.xml +++ b/dsf-tools/dsf-tools-docker-secrets-reader/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-tools-pom - 0.6.0 + 0.7.0 diff --git a/dsf-tools/dsf-tools-documentation-generator/pom.xml b/dsf-tools/dsf-tools-documentation-generator/pom.xml index 8f7f56dc4..309c9ac11 100644 --- a/dsf-tools/dsf-tools-documentation-generator/pom.xml +++ b/dsf-tools/dsf-tools-documentation-generator/pom.xml @@ -9,7 +9,7 @@ org.highmed.dsf dsf-tools-pom - 0.6.0 + 0.7.0 diff --git a/dsf-tools/dsf-tools-proxy-test/pom.xml b/dsf-tools/dsf-tools-proxy-test/pom.xml index 5686405d5..34306cce3 100755 --- a/dsf-tools/dsf-tools-proxy-test/pom.xml +++ b/dsf-tools/dsf-tools-proxy-test/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-tools-pom - 0.6.0 + 0.7.0 diff --git a/dsf-tools/dsf-tools-proxy-test/src/main/java/org/highmed/dsf/tools/proxy/TestClient.java b/dsf-tools/dsf-tools-proxy-test/src/main/java/org/highmed/dsf/tools/proxy/TestClient.java index d6e8f24fe..ffefe0978 100755 --- a/dsf-tools/dsf-tools-proxy-test/src/main/java/org/highmed/dsf/tools/proxy/TestClient.java +++ b/dsf-tools/dsf-tools-proxy-test/src/main/java/org/highmed/dsf/tools/proxy/TestClient.java @@ -15,7 +15,8 @@ public class TestClient extends AbstractJerseyClient public TestClient(String baseUrl, String proxySchemeHostPort, String proxyUserName, char[] proxyPassword) { - super(baseUrl, null, null, null, proxySchemeHostPort, proxyUserName, proxyPassword, 5_000, 5_000, null, null); + super(baseUrl, null, null, null, proxySchemeHostPort, proxyUserName, proxyPassword, 5_000, 5_000, null, null, + true); logger.info("baseUrl: {}", baseUrl); logger.info("proxySchemeHostPort: {}", proxySchemeHostPort); diff --git a/dsf-tools/dsf-tools-test-data-generator/pom.xml b/dsf-tools/dsf-tools-test-data-generator/pom.xml index d02e2d6ea..8d4968fd8 100755 --- a/dsf-tools/dsf-tools-test-data-generator/pom.xml +++ b/dsf-tools/dsf-tools-test-data-generator/pom.xml @@ -7,7 +7,7 @@ org.highmed.dsf dsf-tools-pom - 0.6.0 + 0.7.0 diff --git a/dsf-tools/pom.xml b/dsf-tools/pom.xml index bdbccb3e4..d61f03611 100755 --- a/dsf-tools/pom.xml +++ b/dsf-tools/pom.xml @@ -8,7 +8,7 @@ org.highmed.dsf dsf-pom - 0.6.0 + 0.7.0 diff --git a/pom.xml b/pom.xml index 2068ed28e..916f78483 100755 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.highmed.dsf dsf-pom - 0.6.0 + 0.7.0 pom @@ -30,7 +30,7 @@ 9.4.46.v20220331 2.35 1.18 - 5.3.19 + 5.3.21 5.1.0 2.3 @@ -131,7 +131,7 @@ org.postgresql postgresql - 42.3.4 + 42.3.6 @@ -206,12 +206,12 @@ com.fasterxml.jackson.core jackson-databind - 2.13.2.2 + 2.13.3 com.fasterxml.jackson.core jackson-annotations - 2.13.2 + 2.13.3 @@ -342,6 +342,12 @@ guava 31.1-jre + + com.google.code.gson + gson + 2.9.0 + +