Skip to content

Commit

Permalink
Merge pull request #125 from medizininformatik-initiative/119-improve…
Browse files Browse the repository at this point in the history
…-error-logs-on-connection-test-failure

Improve store client logging
  • Loading branch information
EmteZogaf authored Sep 11, 2024
2 parents 9760926 + c93aa38 commit 1afa9ef
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,19 @@ public void onProcessesDeployed(List<String> processes) {
try {
var statement = storeClient.capabilities().ofType(CapabilityStatement.class)
.execute();
logger.info("Connection test OK ({} - {})", statement.getSoftware().getName(),
statement.getSoftware().getVersion());
logger.info("Feasibility plugin connection test to FHIR store ({} - {}) SUCCEEDED.",
statement.getSoftware().getName(), statement.getSoftware().getVersion());
} catch (Exception e) {
logger.error("Connection test FAILED - error: {} - {}", e.getClass().getName(), e.getMessage());
logger.error("Feasibility plugin connection test to FHIR store FAILED. Error: {} - {}",
e.getClass().getName(), e.getMessage());
}
} else {
try {
flareWebserviceClient.testConnection();
logger.info("Connection test OK (flare)");
logger.info("Feasibility plugin connection test to flare SUCCEEDED.");
} catch (Exception e) {
logger.error("Connection test FAILED (flare) - error: {} - {}", e.getClass().getName(),
e.getMessage());
logger.error("Feasibility plugin connection test to flare FAILED. Error: {} - {}",
e.getClass().getName(), e.getMessage());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import org.apache.http.message.BasicHeader;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
Expand All @@ -44,6 +46,8 @@
@Import({ BaseConfig.class, EvaluationConfig.class })
public class FlareWebserviceClientSpringConfig {

private static final Logger logger = LoggerFactory.getLogger(FlareWebserviceClientSpringConfig.class);

@Value("${de.medizininformatik_initiative.feasibility_dsf_process.client.flare.base_url:}")
private String flareBaseUrl;

Expand Down Expand Up @@ -100,6 +104,9 @@ private FlareWebserviceClient createFlareClient(HttpClient httpClient) {
public HttpClient flareHttpClient(@Qualifier("base-client") SSLContext sslContext,
EvaluationSettingsProvider evaluationSettingsProvider) {
if (EvaluationStrategy.STRUCTURED_QUERY == evaluationSettingsProvider.evaluationStrategy()) {
logger.info("Setting up store client for indirect access over flare using {}.",
EvaluationStrategy.STRUCTURED_QUERY);

var clientFactory = new TlsClientFactory(null, sslContext);
clientFactory.setConnectTimeout(connectTimeout);
clientFactory.setConnectionRequestTimeout(connectTimeout);
Expand All @@ -111,17 +118,23 @@ public HttpClient flareHttpClient(@Qualifier("base-client") SSLContext sslContex
if (!isNullOrEmpty(proxyHost) && proxyPort != null) {
var proxy = new HttpHost(proxyHost, proxyPort);
builder.setProxy(proxy);
logger.info("Setting proxy (host: '{}', port: '{}') for store client.", proxyHost, proxyPort);
if (!isNullOrEmpty(proxyUsername) && !isNullOrEmpty(proxyPassword)) {
logger.info("Setting proxy credentials (username: '{}', password: '***') for store client.",
proxyUsername);
builder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy());
credentialsProvider.setCredentials(new AuthScope(proxy),
new UsernamePasswordCredentials(proxyUsername, proxyPassword));
}
}
if (!isNullOrEmpty(basicAuthUsername) && !isNullOrEmpty(basicAuthPassword)) {
logger.info("Setting basic authentication (username: '{}', password: '***') for store client.",
basicAuthUsername);
var flareUri = URI.create(flareBaseUrl);
credentialsProvider.setCredentials(new AuthScope(new HttpHost(flareUri.getHost(), flareUri.getPort())),
new UsernamePasswordCredentials(basicAuthUsername, basicAuthPassword));
} else if (!isNullOrEmpty(bearerAuthToken)) {
logger.info("Setting bearer token '***' for store client.");
return new BearerHttpClient(builder.setDefaultCredentialsProvider(credentialsProvider).build());
}
return builder.setDefaultCredentialsProvider(credentialsProvider).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
import ca.uhn.fhir.rest.client.impl.RestfulClientFactory;
import ca.uhn.fhir.rest.client.interceptor.BasicAuthInterceptor;
import ca.uhn.fhir.rest.client.interceptor.BearerTokenAuthInterceptor;
import de.medizininformatik_initiative.process.feasibility.EvaluationStrategy;
import de.medizininformatik_initiative.process.feasibility.spring.config.BaseConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
Expand All @@ -19,11 +22,14 @@

import static com.google.common.base.Strings.isNullOrEmpty;
import static de.medizininformatik_initiative.process.feasibility.variables.ConstantsFeasibility.CLIENT_TIMEOUT_DEFAULT;
import static java.util.Objects.nonNull;

@Configuration
@Import(BaseConfig.class)
public class StoreClientSpringConfig {

private static final Logger logger = LoggerFactory.getLogger(StoreClientSpringConfig.class);

@Value("${de.medizininformatik_initiative.feasibility_dsf_process.client.store.proxy.host:#{null}}")
private String proxyHost;

Expand Down Expand Up @@ -64,7 +70,7 @@ public class StoreClientSpringConfig {
private String oauthClientId;

@Value("${de.medizininformatik_initiative.feasibility_dsf_process.client.store.auth.oauth.issuer.url:#{null}}")
private String oauthTokenUrl;
private String oauthIssuerUrl;

@Value("${de.medizininformatik_initiative.feasibility_dsf_process.client.store.auth.oauth.proxy.host:#{null}}")
private String oauthProxyHost;
Expand All @@ -82,30 +88,47 @@ public class StoreClientSpringConfig {
@Qualifier("store-client")
IGenericClient client(@Qualifier("store-client") FhirContext fhirContext,
@Qualifier("store-client") RestfulClientFactory clientFactory) {
logger.info("Setting up store client for direct access using {}.",
EvaluationStrategy.CQL);

clientFactory.setServerValidationMode(ServerValidationModeEnum.NEVER);
clientFactory.setConnectTimeout(connectTimeout);
clientFactory.setConnectionRequestTimeout(connectRequestTimeout);
clientFactory.setSocketTimeout(socketTimeout);

if (proxyHost != null) {
logger.info("Setting proxy (host: '{}', port: '{}') for store client.", proxyHost, proxyPort);
clientFactory.setProxy(proxyHost, proxyPort);

if (proxyUsername != null || proxyPassword != null) {
logger.info("Setting proxy credentials (username: '{}', password: '***') for store client.",
proxyUsername);
clientFactory.setProxyCredentials(proxyUsername, proxyPassword);
}
}
fhirContext.setRestfulClientFactory(clientFactory);
var client = fhirContext.newRestfulGenericClient(storeBaseUrl);
if (bearerAuthToken != null) {
logger.info("Setting bearer token '***' for store client.");
client.registerInterceptor(new BearerTokenAuthInterceptor(bearerAuthToken));
} else if (!isNullOrEmpty(oauthClientId) && !isNullOrEmpty(oauthClientSecret)
&& !isNullOrEmpty(oauthTokenUrl)) {
client.registerInterceptor(new OAuthInterceptor(oauthClientId, oauthClientSecret, oauthTokenUrl,
&& !isNullOrEmpty(oauthIssuerUrl)) {
logger.info("Setting OAuth2.0 authentication (issuer url: '{}', client id: '{}', password: '***')"
+ " for store client.", oauthIssuerUrl, oauthClientId);
if (nonNull(oauthProxyHost) && nonNull(oauthProxyPort)) {
logger.info("Setting proxy (host: '{}', port: '{}', username: {},"
+ " password {}) for OAuth2.0 authentication.", oauthProxyHost, oauthProxyPassword,
Optional.ofNullable(oauthProxyUsername).map(u -> "'" + u + "'").orElse("none"),
Optional.ofNullable(oauthProxyPassword).map(p -> "'***'").orElse("none"));
}
client.registerInterceptor(new OAuthInterceptor(oauthClientId, oauthClientSecret, oauthIssuerUrl,
Optional.ofNullable(oauthProxyHost), Optional.ofNullable(oauthProxyPort),
Optional.ofNullable(oauthProxyUsername), Optional.ofNullable(oauthProxyPassword)));
}

if (basicAuthUsername != null || basicAuthPassword != null) {
logger.info("Setting basic authentication (username: '{}', password: '***') for store client.",
basicAuthUsername);
client.registerInterceptor(new BasicAuthInterceptor(basicAuthUsername, basicAuthPassword));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ void flareClientConnectionTestSucceeds() throws Exception {
listener.onProcessesDeployed(List.of(FEASIBILITY_EXECUTE_PROCESS_ID));

verify(flareClient).testConnection();
assertThat(out.toString(), containsString("Connection test OK (flare)"));
assertThat(out.toString(), containsString("Feasibility plugin connection test to flare SUCCEEDED."));
}

@Test
Expand All @@ -107,7 +107,8 @@ void storeClientConnectionTestSucceeds() throws Exception {

listener.onProcessesDeployed(List.of(FEASIBILITY_EXECUTE_PROCESS_ID));
assertThat(out.toString(),
containsString(format("Connection test OK (%s - %s)", softwareName, softwareVersion)));
containsString(format("Feasibility plugin connection test to FHIR store (%s - %s) SUCCEEDED.",
softwareName, softwareVersion)));
}

@Test
Expand All @@ -121,7 +122,8 @@ void flareClientConnectionTestFails() throws Exception {

listener.onProcessesDeployed(List.of(FEASIBILITY_EXECUTE_PROCESS_ID));

assertThat(out.toString(), containsString(format("Connection test FAILED (flare) - error: %s - %s",
assertThat(out.toString(),
containsString(format("Feasibility plugin connection test to flare FAILED. Error: %s - %s",
exception.getClass().getName(), errorMessage)));
}

Expand All @@ -139,8 +141,8 @@ void storeClientConnectionTestFails() throws Exception {

listener.onProcessesDeployed(List.of(FEASIBILITY_EXECUTE_PROCESS_ID));
assertThat(out.toString(),
containsString(format("Connection test FAILED - error: %s - %s", exception.getClass().getName(),
errorMessage)));
containsString(format("Feasibility plugin connection test to FHIR store FAILED. Error: %s - %s",
exception.getClass().getName(), errorMessage)));

}
}

0 comments on commit 1afa9ef

Please sign in to comment.