Skip to content

Commit

Permalink
Issue #2431 - add support for headers in RemoteTermServiceProvider (#…
Browse files Browse the repository at this point in the history
…2435)

* Issue #2431 - add support for headers in RemoteTermServiceProvider

Signed-off-by: John T.E. Timm <johntimm@us.ibm.com>

* Issue #2431 - update docs

Signed-off-by: John T.E. Timm <johntimm@us.ibm.com>

* Issue #2432 - add dependsOnMethods to annotation

Signed-off-by: John T.E. Timm <johntimm@us.ibm.com>

* Issue #2431 - minor tweak

Signed-off-by: John T.E. Timm <johntimm@us.ibm.com>

* Issue #2431 - fix integration test

Signed-off-by: John T.E. Timm <johntimm@us.ibm.com>
  • Loading branch information
JohnTimm authored May 26, 2021
1 parent 3b3d9c5 commit 567eff3
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 4 deletions.
4 changes: 4 additions & 0 deletions docs/src/pages/guides/FHIRServerUsersGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -1972,6 +1972,9 @@ This section contains reference information about each of the configuration prop
|`fhirServer/term/remoteTermServiceProviders/hostnameVerificationEnabled`|boolean|Indicates whether hostname verification should be performed when using SSL transport|
|`fhirServer/term/remoteTermServiceProviders/basicAuth/username`|string|The basic authentication username for this remote term service provider|
|`fhirServer/term/remoteTermServiceProviders/basicAuth/password`|string|The basic authentication password for this remote term service provider|
|`fhirServer/term/remoteTermServiceProviders/headers`|array of objects|The `headers` element is an array of objects|
|`fhirServer/term/remoteTermServiceProviders/headers/name`|string|The HTTP header name that will be added to requests by this remote term service provider|
|`fhirServer/term/remoteTermServiceProviders/headers/value`|string|The HTTP header value that will be added to requests by this remote term service provider|
|`fhirServer/term/remoteTermServiceProviders/httpTimeout`|integer|The HTTP read timeout for this remote term service provider (in milliseconds)|
|`fhirServer/term/remoteTermServiceProviders/supports`|array of objects|The `supports` element is an array of objects|
|`fhirServer/term/remoteTermServiceProviders/supports/system`|string|The system URI supported by this remote term service provider|
Expand Down Expand Up @@ -2246,6 +2249,7 @@ must restart the server for that change to take effect.
|`fhirServer/term/remoteTermServiceProviders/trustStore`|N|N|
|`fhirServer/term/remoteTermServiceProviders/hostnameVerificationEnabled`|N|N|
|`fhirServer/term/remoteTermServiceProviders/basicAuth`|N|N|
|`fhirServer/term/remoteTermServiceProviders/headers`|N|N|
|`fhirServer/term/remoteTermServiceProviders/httpTimeout`|N|N|
|`fhirServer/term/remoteTermServiceProviders/supports`|N|N|
|`fhirServer/resources/open`|Y|Y|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.ibm.fhir.term.remote.provider.RemoteTermServiceProvider;
import com.ibm.fhir.term.remote.provider.RemoteTermServiceProvider.Configuration;
import com.ibm.fhir.term.remote.provider.RemoteTermServiceProvider.Configuration.BasicAuth;
import com.ibm.fhir.term.remote.provider.RemoteTermServiceProvider.Configuration.Header;
import com.ibm.fhir.term.remote.provider.RemoteTermServiceProvider.Configuration.Supports;
import com.ibm.fhir.term.remote.provider.RemoteTermServiceProvider.Configuration.TrustStore;
import com.ibm.fhir.term.util.CodeSystemSupport;
Expand All @@ -47,11 +48,19 @@ public void testCreateCodeSystem() throws Exception {
CodeSystem codeSystem = TestUtil.readLocalResource("CodeSystem-test.json");
Entity<CodeSystem> entity = Entity.entity(codeSystem, FHIRMediaType.APPLICATION_FHIR_JSON);

Response response = target.path("CodeSystem").path("test").request().put(entity);
Response response = target.path("CodeSystem").path("test")
.request()
.header("X-FHIR-TENANT-ID", "tenant1")
.header("X-FHIR-DSID", "profile")
.put(entity);
int status = response.getStatus();
assertTrue(status == Response.Status.CREATED.getStatusCode() || status == Response.Status.OK.getStatusCode());

response = target.path("CodeSystem").path("test").request(FHIRMediaType.APPLICATION_FHIR_JSON).get();
response = target.path("CodeSystem").path("test")
.request(FHIRMediaType.APPLICATION_FHIR_JSON)
.header("X-FHIR-TENANT-ID", "tenant1")
.header("X-FHIR-DSID", "profile")
.get();
assertResponse(response, Response.Status.OK.getStatusCode());

CodeSystem responseCodeSystem = response.readEntity(CodeSystem.class);
Expand All @@ -60,7 +69,7 @@ public void testCreateCodeSystem() throws Exception {
this.codeSystem = responseCodeSystem;
}

@Test
@Test(dependsOnMethods = { "testCreateCodeSystem" })
public void testCreateRemoteTermServiceProvider() {
Configuration configuration = Configuration.builder()
.base(getRestBaseURL())
Expand All @@ -72,6 +81,14 @@ public void testCreateRemoteTermServiceProvider() {
.username(getFhirUser())
.password(getFhirPassword())
.build())
.headers(Header.builder()
.name("X-FHIR-TENANT-ID")
.value("tenant1")
.build(),
Header.builder()
.name("X-FHIR-DSID")
.value("profile")
.build())
.supports(Supports.builder()
.system(codeSystem.getUrl().getValue())
.version(codeSystem.getVersion().getValue())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
import com.ibm.fhir.term.remote.provider.RemoteTermServiceProvider;
import com.ibm.fhir.term.remote.provider.RemoteTermServiceProvider.Configuration;
import com.ibm.fhir.term.remote.provider.RemoteTermServiceProvider.Configuration.BasicAuth;
import com.ibm.fhir.term.remote.provider.RemoteTermServiceProvider.Configuration.Header;
import com.ibm.fhir.term.remote.provider.RemoteTermServiceProvider.Configuration.Supports;
import com.ibm.fhir.term.remote.provider.RemoteTermServiceProvider.Configuration.TrustStore;
import com.ibm.fhir.term.service.FHIRTermService;
Expand Down Expand Up @@ -330,6 +331,17 @@ private void configureTermServiceCapabilities(PropertyGroup fhirConfig) throws E
.build());
}

Object[] headersArray = remoteTermServiceProviderPropertyGroup.getArrayProperty("headers");
if (headersArray != null) {
for (Object headerObject : headersArray) {
PropertyGroup headerPropertyGroup = (PropertyGroup) headerObject;
builder.headers(Header.builder()
.name(headerPropertyGroup.getStringProperty("name"))
.value(headerPropertyGroup.getStringProperty("value"))
.build());
}
}

builder.httpTimeout(remoteTermServiceProviderPropertyGroup.getIntProperty("httpTimeout", Configuration.DEFAULT_HTTP_TIMEOUT));

Object[] supportsArray = remoteTermServiceProviderPropertyGroup.getArrayProperty("supports");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

Expand Down Expand Up @@ -96,11 +98,13 @@ public class RemoteTermServiceProvider extends AbstractTermServiceProvider {

private final Configuration configuration;
private final String base;
private final MultivaluedMap<String, Object> headersMap;
private Client client;

public RemoteTermServiceProvider(Configuration configuration) {
this.configuration = Objects.requireNonNull(configuration, "configuration");
this.base = configuration.getBase();
headersMap = buildHeadersMap(configuration.getHeaders());
try {
log.info("Creating client...");

Expand Down Expand Up @@ -185,11 +189,13 @@ public Concept getConcept(CodeSystem codeSystem, Code code) {
.queryParam("version", codeSystem.getVersion().getValue())
.queryParam("code", code.getValue())
.request(FHIRMediaType.APPLICATION_FHIR_JSON)
.headers(headersMap)
.get() :
target.path(CODE_SYSTEM_LOOKUP)
.queryParam("system", codeSystem.getUrl().getValue())
.queryParam("code", code.getValue())
.request(FHIRMediaType.APPLICATION_FHIR_JSON)
.headers(headersMap)
.get();

log(GET, uri(CODE_SYSTEM_LOOKUP), response.getStatus(), elapsed(start));
Expand Down Expand Up @@ -240,6 +246,7 @@ public <R> Set<R> getConcepts(CodeSystem codeSystem, List<Filter> filters, Funct

response = target.path(VALUE_SET_EXPAND)
.request(FHIRMediaType.APPLICATION_FHIR_JSON)
.headers(headersMap)
.post(Entity.entity(parameters, FHIRMediaType.APPLICATION_FHIR_JSON));

log(POST, uri(VALUE_SET_EXPAND), response.getStatus(), elapsed(start));
Expand Down Expand Up @@ -294,11 +301,13 @@ public boolean hasConcept(CodeSystem codeSystem, Code code) {
.queryParam("version", codeSystem.getVersion().getValue())
.queryParam("code", code.getValue())
.request(FHIRMediaType.APPLICATION_FHIR_JSON)
.headers(headersMap)
.get() :
target.path(CODE_SYSTEM_VALIDATE_CODE)
.queryParam("url", codeSystem.getUrl().getValue())
.queryParam("code", code.getValue())
.request(FHIRMediaType.APPLICATION_FHIR_JSON)
.headers(headersMap)
.get();

log(GET, uri(CODE_SYSTEM_VALIDATE_CODE), response.getStatus(), elapsed(start));
Expand Down Expand Up @@ -359,12 +368,14 @@ public boolean subsumes(CodeSystem codeSystem, Code codeA, Code codeB) {
.queryParam("codeA", codeA.getValue())
.queryParam("codeB", codeB.getValue())
.request(FHIRMediaType.APPLICATION_FHIR_JSON)
.headers(headersMap)
.get() :
target.path(CODE_SYSTEM_SUBSUMES)
.queryParam("system", codeSystem.getUrl().getValue())
.queryParam("codeA", codeA.getValue())
.queryParam("codeB", codeB.getValue())
.request(FHIRMediaType.APPLICATION_FHIR_JSON)
.headers(headersMap)
.get();

log(GET, uri(CODE_SYSTEM_SUBSUMES), response.getStatus(), elapsed(start));
Expand All @@ -386,6 +397,14 @@ public boolean subsumes(CodeSystem codeSystem, Code codeA, Code codeB) {
}
}

private MultivaluedMap<String, Object> buildHeadersMap(List<Configuration.Header> headers) {
MultivaluedMap<String, Object> headersMap = new MultivaluedHashMap<>();
for (Configuration.Header header : headers) {
headersMap.putSingle(header.getName(), header.getValue());
}
return headersMap;
}

private double elapsed(long start) {
return (System.currentTimeMillis() - start) / 1000.0;
}
Expand Down Expand Up @@ -594,6 +613,7 @@ public static class Configuration {
private final TrustStore trustStore;
private final boolean hostnameVerificationEnabled;
private final BasicAuth basicAuth;
private final List<Header> headers;
private final int httpTimeout;
private final List<Supports> supports;

Expand All @@ -602,6 +622,7 @@ private Configuration(Builder builder) {
trustStore = builder.trustStore;
hostnameVerificationEnabled = builder.hostnameVerificationEnabled;
basicAuth = builder.basicAuth;
headers = Collections.unmodifiableList(builder.headers);
httpTimeout = builder.httpTimeout;
supports = Collections.unmodifiableList(builder.supports);
}
Expand All @@ -622,6 +643,10 @@ public BasicAuth getBasicAuth() {
return basicAuth;
}

public List<Header> getHeaders() {
return headers;
}

public int getHttpTimeout() {
return httpTimeout;
}
Expand All @@ -646,13 +671,14 @@ public boolean equals(Object obj) {
Objects.equals(trustStore, other.trustStore) &&
Objects.equals(hostnameVerificationEnabled, other.hostnameVerificationEnabled) &&
Objects.equals(basicAuth, other.basicAuth) &&
Objects.equals(headers, other.headers) &&
Objects.equals(httpTimeout, other.httpTimeout) &&
Objects.equals(supports, other.supports);
}

@Override
public int hashCode() {
return Objects.hash(base, trustStore, hostnameVerificationEnabled, basicAuth, httpTimeout, supports);
return Objects.hash(base, trustStore, hostnameVerificationEnabled, basicAuth, headers, httpTimeout, supports);
}

public Builder toBuilder() {
Expand All @@ -668,6 +694,7 @@ public static class Builder {
private TrustStore trustStore;
private boolean hostnameVerificationEnabled = DEFAULT_HOSTNAME_VERIFICATION_ENABLED;
private BasicAuth basicAuth;
private List<Header> headers = new ArrayList<>();
private int httpTimeout = DEFAULT_HTTP_TIMEOUT;
private List<Supports> supports = new ArrayList<>();

Expand All @@ -693,6 +720,18 @@ public Builder basicAuth(BasicAuth basicAuth) {
return this;
}

public Builder headers(Header... headers) {
for (Header value : headers) {
this.headers.add(value);
}
return this;
}

public Builder headers(Collection<Header> headers) {
this.headers = new ArrayList<>(headers);
return this;
}

public Builder httpTimeout(int httpTimeout) {
this.httpTimeout = httpTimeout;
return this;
Expand All @@ -719,6 +758,7 @@ protected Builder from(Configuration configuration) {
trustStore = configuration.trustStore;
hostnameVerificationEnabled = configuration.hostnameVerificationEnabled;
basicAuth = configuration.basicAuth;
headers = configuration.headers;
httpTimeout = configuration.httpTimeout;
supports.addAll(configuration.supports);
return this;
Expand Down Expand Up @@ -895,6 +935,83 @@ protected Builder from(BasicAuth basicAuth) {
}
}

/**
* A class that represents the HTTP header(s) supported by a remote term service provider
*/
public static class Header {
private final String name;
private final Object value;

public Header(Builder builder) {
name = Objects.requireNonNull(builder.name, "name");
value = Objects.requireNonNull(builder.value, "value");
}

public String getName() {
return name;
}

public Object getValue() {
return value;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Header other = (Header) obj;
return Objects.equals(name, other.name) &&
Objects.equals(value, other.value);
}

@Override
public int hashCode() {
return Objects.hash(name, value);
}

public Builder toBuilder() {
return new Builder().from(this);
}

public static Builder builder() {
return new Builder();
}

public static class Builder {
private String name;
private Object value;

private Builder() { }

public Builder name(String name) {
this.name = name;
return this;
}

public Builder value(Object value) {
this.value = value;
return this;
}

public Header build() {
return new Header(this);
}

protected Builder from(Header header) {
name = header.name;
value = header.value;
return this;
}
}
}

/**
* A class that represents the code system(s) supported by a remote term service provider
*/
Expand Down

0 comments on commit 567eff3

Please sign in to comment.