standardise terminology client across versions

This commit is contained in:
Grahame Grieve 2020-06-07 08:42:14 +10:00
parent 6bc790d98b
commit 94467b270a
61 changed files with 1901 additions and 1191 deletions

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>org.hl7.fhir.core</artifactId>
<version>5.0.6-SNAPSHOT</version>
<version>5.0.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -42,6 +42,10 @@ import java.util.Locale;
import java.util.Set;
import java.util.TimeZone;
import org.hl7.fhir.convertors.loaders.R2016MayToR4Loader;
import org.hl7.fhir.convertors.loaders.R2ToR4Loader;
import org.hl7.fhir.convertors.loaders.R3ToR4Loader;
import org.hl7.fhir.convertors.misc.IGR2ConvertorAdvisor;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r4.conformance.ProfileUtilities;

View File

@ -48,6 +48,7 @@ import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.hl7.fhir.convertors.loaders.R2ToR3Loader;
import org.hl7.fhir.dstu3.context.SimpleWorkerContext;
import org.hl7.fhir.dstu3.elementmodel.Manager;
import org.hl7.fhir.dstu3.elementmodel.Manager.FhirFormat;

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors;
package org.hl7.fhir.convertors.loaders;
public abstract class BaseLoader {

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors;
package org.hl7.fhir.convertors.loaders;
/*
Copyright (c) 2011+, HL7, Inc.
@ -37,6 +37,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.hl7.fhir.convertors.VersionConvertorAdvisor40;
import org.hl7.fhir.convertors.VersionConvertor_14_40;
import org.hl7.fhir.dstu2016may.formats.JsonParser;
import org.hl7.fhir.dstu2016may.formats.XmlParser;
import org.hl7.fhir.dstu2016may.model.Resource;

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors;
package org.hl7.fhir.convertors.loaders;
/*
Copyright (c) 2011+, HL7, Inc.
@ -37,6 +37,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.hl7.fhir.convertors.VersionConvertorAdvisor50;
import org.hl7.fhir.convertors.VersionConvertor_14_50;
import org.hl7.fhir.dstu2016may.formats.JsonParser;
import org.hl7.fhir.dstu2016may.formats.XmlParser;
import org.hl7.fhir.dstu2016may.model.Resource;

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors;
package org.hl7.fhir.convertors.loaders;
/*
Copyright (c) 2011+, HL7, Inc.
@ -37,6 +37,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.hl7.fhir.convertors.VersionConvertorAdvisor30;
import org.hl7.fhir.convertors.VersionConvertor_10_30;
import org.hl7.fhir.dstu2.formats.JsonParser;
import org.hl7.fhir.dstu2.formats.XmlParser;
import org.hl7.fhir.dstu2.model.Resource;

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors;
package org.hl7.fhir.convertors.loaders;
/*
Copyright (c) 2011+, HL7, Inc.
@ -37,6 +37,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.hl7.fhir.convertors.VersionConvertorAdvisor40;
import org.hl7.fhir.convertors.VersionConvertor_10_40;
import org.hl7.fhir.dstu2.formats.JsonParser;
import org.hl7.fhir.dstu2.formats.XmlParser;
import org.hl7.fhir.dstu2.model.Resource;

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors;
package org.hl7.fhir.convertors.loaders;
/*
Copyright (c) 2011+, HL7, Inc.
@ -37,6 +37,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.hl7.fhir.convertors.VersionConvertorAdvisor50;
import org.hl7.fhir.convertors.VersionConvertor_10_50;
import org.hl7.fhir.dstu2.formats.JsonParser;
import org.hl7.fhir.dstu2.formats.XmlParser;
import org.hl7.fhir.dstu2.model.Resource;

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors;
package org.hl7.fhir.convertors.loaders;
/*
Copyright (c) 2011+, HL7, Inc.
@ -37,6 +37,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.hl7.fhir.convertors.VersionConvertorAdvisor40;
import org.hl7.fhir.convertors.VersionConvertor_30_40;
import org.hl7.fhir.dstu3.formats.JsonParser;
import org.hl7.fhir.dstu3.formats.XmlParser;
import org.hl7.fhir.dstu3.model.Resource;

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors;
package org.hl7.fhir.convertors.loaders;
/*
Copyright (c) 2011+, HL7, Inc.
@ -37,6 +37,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.hl7.fhir.convertors.VersionConvertorAdvisor50;
import org.hl7.fhir.convertors.VersionConvertor_30_50;
import org.hl7.fhir.dstu3.formats.JsonParser;
import org.hl7.fhir.dstu3.formats.XmlParser;
import org.hl7.fhir.dstu3.model.Resource;

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors;
package org.hl7.fhir.convertors.loaders;
/*
Copyright (c) 2011+, HL7, Inc.
@ -37,6 +37,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.hl7.fhir.convertors.VersionConvertorAdvisor50;
import org.hl7.fhir.convertors.VersionConvertor_40_50;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r4.formats.JsonParser;
import org.hl7.fhir.r4.formats.XmlParser;

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors;
package org.hl7.fhir.convertors.loaders;
/*
Copyright (c) 2011+, HL7, Inc.
@ -37,6 +37,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.hl7.fhir.convertors.VersionConvertorAdvisor50;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.formats.JsonParser;
import org.hl7.fhir.r5.formats.XmlParser;

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors;
package org.hl7.fhir.convertors.misc;
/*
Copyright (c) 2011+, HL7, Inc.
@ -38,6 +38,8 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import org.hl7.fhir.convertors.VersionConvertorAdvisor30;
import org.hl7.fhir.convertors.VersionConvertor_10_30;
import org.hl7.fhir.dstu2.model.Resource;
import org.hl7.fhir.dstu3.formats.IParser.OutputStyle;
import org.hl7.fhir.dstu3.model.Bundle;

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors;
package org.hl7.fhir.convertors.misc;
/*
Copyright (c) 2011+, HL7, Inc.
@ -35,6 +35,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.hl7.fhir.convertors.VersionConvertor_14_30;
import org.hl7.fhir.dstu3.formats.IParser.OutputStyle;
public class IGPackConverter140 {

View File

@ -1,4 +1,6 @@
package org.hl7.fhir.convertors;
package org.hl7.fhir.convertors.misc;
import org.hl7.fhir.convertors.VersionConvertorAdvisor40;
/*
Copyright (c) 2011+, HL7, Inc.

View File

@ -1,4 +1,6 @@
package org.hl7.fhir.convertors;
package org.hl7.fhir.convertors.misc;
import org.hl7.fhir.convertors.VersionConvertorAdvisor50;
/*
Copyright (c) 2011+, HL7, Inc.

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors;
package org.hl7.fhir.convertors.misc;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
@ -17,6 +17,16 @@ import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
import org.hl7.fhir.dstu2.model.ClaimResponse.ErrorsComponent;
import org.hl7.fhir.convertors.VersionConvertorAdvisor40;
import org.hl7.fhir.convertors.VersionConvertor_10_30;
import org.hl7.fhir.convertors.VersionConvertor_10_40;
import org.hl7.fhir.convertors.VersionConvertor_10_50;
import org.hl7.fhir.convertors.VersionConvertor_14_30;
import org.hl7.fhir.convertors.VersionConvertor_14_40;
import org.hl7.fhir.convertors.VersionConvertor_14_50;
import org.hl7.fhir.convertors.VersionConvertor_30_40;
import org.hl7.fhir.convertors.VersionConvertor_30_50;
import org.hl7.fhir.convertors.VersionConvertor_40_50;
import org.hl7.fhir.dstu2.model.Resource;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors;
package org.hl7.fhir.convertors.txClient;
/*
Copyright (c) 2011+, HL7, Inc.
@ -35,7 +35,6 @@ import java.net.URISyntaxException;
import org.hl7.fhir.r5.model.FhirPublication;
import org.hl7.fhir.r5.terminologies.TerminologyClient;
import org.hl7.fhir.r5.terminologies.TerminologyClientR5;
import org.hl7.fhir.utilities.Utilities;
public class TerminologyClientFactory {

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors;
package org.hl7.fhir.convertors.txClient;
/*
Copyright (c) 2011+, HL7, Inc.
@ -34,6 +34,7 @@ package org.hl7.fhir.convertors;
import java.net.URISyntaxException;
import java.util.Map;
import org.hl7.fhir.convertors.VersionConvertor_10_50;
import org.hl7.fhir.dstu2.utils.client.FHIRToolingClient;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.model.CapabilityStatement;
@ -41,7 +42,7 @@ import org.hl7.fhir.r5.model.Parameters;
import org.hl7.fhir.r5.model.TerminologyCapabilities;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.terminologies.TerminologyClient;
import org.hl7.fhir.r5.utils.client.ToolingClientLogger;
import org.hl7.fhir.utilities.ToolingClientLogger;
public class TerminologyClientR2 implements TerminologyClient {
@ -84,13 +85,21 @@ public class TerminologyClientR2 implements TerminologyClient {
}
@Override
public void setTimeout(int i) {
// ignored in this version - need to roll R4 internal changes back to R2 if desired
public TerminologyClient setTimeout(int i) {
client.setTimeout(i);
return this;
}
@Override
public void setLogger(ToolingClientLogger txLog) {
// ignored in this version - need to roll R4 internal changes back to R2 if desired
public TerminologyClient setLogger(ToolingClientLogger txLog) {
client.setLogger(txLog);
return this;
}
@Override
public TerminologyClient setRetryCount(int retryCount) throws FHIRException {
client.setRetryCount(retryCount);
return this;
}
@Override
@ -102,4 +111,6 @@ public class TerminologyClientR2 implements TerminologyClient {
public Parameters lookupCode(Map<String, String> params) throws FHIRException {
return (Parameters) VersionConvertor_10_50.convertResource(client.lookupCode(params));
}
}

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors;
package org.hl7.fhir.convertors.txClient;
/*
Copyright (c) 2011+, HL7, Inc.
@ -34,6 +34,7 @@ package org.hl7.fhir.convertors;
import java.net.URISyntaxException;
import java.util.Map;
import org.hl7.fhir.convertors.VersionConvertor_30_50;
import org.hl7.fhir.dstu3.utils.client.FHIRToolingClient;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.model.CapabilityStatement;
@ -41,7 +42,7 @@ import org.hl7.fhir.r5.model.Parameters;
import org.hl7.fhir.r5.model.TerminologyCapabilities;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.terminologies.TerminologyClient;
import org.hl7.fhir.r5.utils.client.ToolingClientLogger;
import org.hl7.fhir.utilities.ToolingClientLogger;
public class TerminologyClientR3 implements TerminologyClient {
@ -84,13 +85,21 @@ public class TerminologyClientR3 implements TerminologyClient {
}
@Override
public void setTimeout(int i) {
// ignored in this version - need to roll R4 internal changes back to R2 if desired
public TerminologyClient setTimeout(int i) {
client.setTimeout(i);
return this;
}
@Override
public void setLogger(ToolingClientLogger txLog) {
// ignored in this version - need to roll R4 internal changes back to R2 if desired
public TerminologyClient setLogger(ToolingClientLogger txLog) {
client.setLogger(txLog);
return this;
}
@Override
public TerminologyClient setRetryCount(int retryCount) throws FHIRException {
client.setRetryCount(retryCount);
return this;
}
@Override

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.convertors;
package org.hl7.fhir.convertors.txClient;
/*
Copyright (c) 2011+, HL7, Inc.
@ -34,6 +34,7 @@ package org.hl7.fhir.convertors;
import java.net.URISyntaxException;
import java.util.Map;
import org.hl7.fhir.convertors.VersionConvertor_40_50;
import org.hl7.fhir.convertors.conv40_50.TerminologyCapabilities40_50;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r4.utils.client.FHIRToolingClient;
@ -42,7 +43,7 @@ import org.hl7.fhir.r5.model.Parameters;
import org.hl7.fhir.r5.model.TerminologyCapabilities;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.terminologies.TerminologyClient;
import org.hl7.fhir.r5.utils.client.ToolingClientLogger;
import org.hl7.fhir.utilities.ToolingClientLogger;
public class TerminologyClientR4 implements TerminologyClient {
@ -85,13 +86,21 @@ public class TerminologyClientR4 implements TerminologyClient {
}
@Override
public void setTimeout(int i) {
// ignored in this version - need to roll R4 internal changes back to R2 if desired
public TerminologyClient setTimeout(int i) {
client.setTimeout(i);
return this;
}
@Override
public void setLogger(ToolingClientLogger txLog) {
// ignored in this version - need to roll R4 internal changes back to R2 if desired
public TerminologyClient setLogger(ToolingClientLogger txLog) {
client.setLogger(txLog);
return this;
}
@Override
public TerminologyClient setRetryCount(int retryCount) throws FHIRException {
client.setRetryCount(retryCount);
return this;
}
@Override

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.r5.terminologies;
package org.hl7.fhir.convertors.txClient;
/*
Copyright (c) 2011+, HL7, Inc.
@ -34,13 +34,15 @@ package org.hl7.fhir.r5.terminologies;
import java.net.URISyntaxException;
import java.util.Map;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.model.CapabilityStatement;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.Parameters;
import org.hl7.fhir.r5.model.TerminologyCapabilities;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.terminologies.TerminologyClient;
import org.hl7.fhir.r5.utils.client.FHIRToolingClient;
import org.hl7.fhir.r5.utils.client.ToolingClientLogger;
import org.hl7.fhir.utilities.ToolingClientLogger;
public class TerminologyClientR5 implements TerminologyClient {
@ -76,13 +78,15 @@ public class TerminologyClientR5 implements TerminologyClient {
}
@Override
public void setTimeout(int i) {
public TerminologyClient setTimeout(int i) {
client.setTimeout(i);
return this;
}
@Override
public void setLogger(ToolingClientLogger txLog) {
public TerminologyClient setLogger(ToolingClientLogger txLog) {
client.setLogger(txLog);
return this;
}
@Override
@ -95,4 +99,10 @@ public class TerminologyClientR5 implements TerminologyClient {
return client.lookupCode(params);
}
@Override
public TerminologyClient setRetryCount(int retryCount) throws FHIRException {
client.setRetryCount(retryCount);
return this;
}
}

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>org.hl7.fhir.core</artifactId>
<version>5.0.6-SNAPSHOT</version>
<version>5.0.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -7,19 +7,19 @@ package org.hl7.fhir.dstu2.utils.client;
/*
Copyright (c) 2011+, HL7, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to
* Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
@ -30,29 +30,33 @@ package org.hl7.fhir.dstu2.utils.client;
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
*/
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
@ -68,6 +72,8 @@ import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.hl7.fhir.dstu2.formats.IParser;
import org.hl7.fhir.dstu2.formats.IParser.OutputStyle;
import org.hl7.fhir.dstu2.formats.JsonParser;
@ -79,6 +85,7 @@ import org.hl7.fhir.dstu2.model.OperationOutcome.OperationOutcomeIssueComponent;
import org.hl7.fhir.dstu2.model.Resource;
import org.hl7.fhir.dstu2.model.ResourceType;
import org.hl7.fhir.dstu2.utils.ResourceUtilities;
import org.hl7.fhir.utilities.ToolingClientLogger;
/**
* Helper class handling lower level HTTP transport concerns.
@ -86,393 +93,429 @@ import org.hl7.fhir.dstu2.utils.ResourceUtilities;
* @author Claude Nanjo
*/
public class ClientUtils {
public static String DEFAULT_CHARSET = "UTF-8";
public static final String HEADER_LOCATION = "location";
public static <T extends Resource> ResourceRequest<T> issueOptionsRequest(URI optionsUri, String resourceFormat, HttpHost proxy) {
HttpOptions options = new HttpOptions(optionsUri);
return issueResourceRequest(resourceFormat, options, proxy);
}
public static <T extends Resource> ResourceRequest<T> issueGetResourceRequest(URI resourceUri, String resourceFormat, HttpHost proxy) {
HttpGet httpget = new HttpGet(resourceUri);
return issueResourceRequest(resourceFormat, httpget, proxy);
}
public static <T extends Resource> ResourceRequest<T> issuePutRequest(URI resourceUri, byte[] payload, String resourceFormat, List<Header> headers, HttpHost proxy) {
HttpPut httpPut = new HttpPut(resourceUri);
return issueResourceRequest(resourceFormat, httpPut, payload, headers, proxy);
}
public static <T extends Resource> ResourceRequest<T> issuePutRequest(URI resourceUri, byte[] payload, String resourceFormat, HttpHost proxy) {
HttpPut httpPut = new HttpPut(resourceUri);
return issueResourceRequest(resourceFormat, httpPut, payload, null, proxy);
}
public static <T extends Resource> ResourceRequest<T> issuePostRequest(URI resourceUri, byte[] payload, String resourceFormat, List<Header> headers, HttpHost proxy) {
HttpPost httpPost = new HttpPost(resourceUri);
return issueResourceRequest(resourceFormat, httpPost, payload, headers, proxy);
}
public static <T extends Resource> ResourceRequest<T> issuePostRequest(URI resourceUri, byte[] payload, String resourceFormat, HttpHost proxy) {
return issuePostRequest(resourceUri, payload, resourceFormat, null, proxy);
}
public static Bundle issueGetFeedRequest(URI resourceUri, String resourceFormat, HttpHost proxy) {
HttpGet httpget = new HttpGet(resourceUri);
configureFhirRequest(httpget, resourceFormat);
HttpResponse response = sendRequest(httpget, proxy);
return unmarshalReference(response, resourceFormat);
}
public static Bundle postBatchRequest(URI resourceUri, byte[] payload, String resourceFormat, HttpHost proxy) {
HttpPost httpPost = new HttpPost(resourceUri);
configureFhirRequest(httpPost, resourceFormat);
HttpResponse response = sendPayload(httpPost, payload, proxy);
return unmarshalFeed(response, resourceFormat);
}
public static boolean issueDeleteRequest(URI resourceUri, HttpHost proxy) {
HttpDelete deleteRequest = new HttpDelete(resourceUri);
HttpResponse response = sendRequest(deleteRequest, proxy);
int responseStatusCode = response.getStatusLine().getStatusCode();
boolean deletionSuccessful = false;
if(responseStatusCode == 204) {
deletionSuccessful = true;
}
return deletionSuccessful;
}
/***********************************************************
* Request/Response Helper methods
***********************************************************/
protected static <T extends Resource> ResourceRequest<T> issueResourceRequest(String resourceFormat, HttpUriRequest request, HttpHost proxy) {
return issueResourceRequest(resourceFormat, request, null, proxy);
}
/**
* @param resourceFormat
* @param options
* @return
*/
protected static <T extends Resource> ResourceRequest<T> issueResourceRequest(String resourceFormat, HttpUriRequest request, byte[] payload, HttpHost proxy) {
return issueResourceRequest(resourceFormat, request, payload, null, proxy);
}
/**
* @param resourceFormat
* @param options
* @return
*/
protected static <T extends Resource> ResourceRequest<T> issueResourceRequest(String resourceFormat, HttpUriRequest request, byte[] payload, List<Header> headers, HttpHost proxy) {
configureFhirRequest(request, resourceFormat, headers);
HttpResponse response = null;
if(request instanceof HttpEntityEnclosingRequest && payload != null) {
response = sendPayload((HttpEntityEnclosingRequestBase)request, payload, proxy);
} else if (request instanceof HttpEntityEnclosingRequest && payload == null){
throw new EFhirClientException("PUT and POST requests require a non-null payload");
} else {
response = sendRequest(request, proxy);
}
T resource = unmarshalReference(response, resourceFormat);
return new ResourceRequest<T>(resource, response.getStatusLine().getStatusCode(), ClientUtils.getLocationHeader(response));
}
/**
* Method adds required request headers.
* TODO handle JSON request as well.
*
* @param request
*/
protected static void configureFhirRequest(HttpRequest request, String format) {
configureFhirRequest(request, format, null);
}
/**
* Method adds required request headers.
* TODO handle JSON request as well.
*
* @param request
*/
protected static void configureFhirRequest(HttpRequest request, String format, List<Header> headers) {
request.addHeader("User-Agent", "Java FHIR Client for FHIR");
if (format != null) {
request.addHeader("Accept",format);
request.addHeader("Content-Type", format + ";charset=" + DEFAULT_CHARSET);
}
request.addHeader("Accept-Charset", DEFAULT_CHARSET);
if(headers != null) {
for(Header header : headers) {
request.addHeader(header);
}
}
}
/**
* Method posts request payload
*
* @param request
* @param payload
* @return
*/
protected static HttpResponse sendPayload(HttpEntityEnclosingRequestBase request, byte[] payload, HttpHost proxy) {
HttpResponse response = null;
try {
HttpClient httpclient = new DefaultHttpClient();
if(proxy != null) {
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
}
request.setEntity(new ByteArrayEntity(payload));
response = httpclient.execute(request);
} catch(IOException ioe) {
throw new EFhirClientException("Error sending HTTP Post/Put Payload", ioe);
}
return response;
}
/**
*
* @param request
* @param payload
* @return
*/
protected static HttpResponse sendRequest(HttpUriRequest request, HttpHost proxy) {
HttpResponse response = null;
try {
HttpClient httpclient = new DefaultHttpClient();
if(proxy != null) {
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
}
response = httpclient.execute(request);
} catch(IOException ioe) {
throw new EFhirClientException("Error sending Http Request", ioe);
}
return response;
}
/**
* Unmarshals a resource from the response stream.
*
* @param response
* @return
*/
@SuppressWarnings("unchecked")
protected static <T extends Resource> T unmarshalReference(HttpResponse response, String format) {
T resource = null;
OperationOutcome error = null;
InputStream instream = null;
HttpEntity entity = response.getEntity();
if (entity != null && entity.getContentLength() > 0) {
try {
instream = entity.getContent();
// System.out.println(writeInputStreamAsString(instream));
resource = (T)getParser(format).parse(instream);
if (resource instanceof OperationOutcome && hasError((OperationOutcome)resource)) {
error = (OperationOutcome) resource;
}
} catch(IOException ioe) {
throw new EFhirClientException("Error unmarshalling entity from Http Response", ioe);
} catch(Exception e) {
throw new EFhirClientException("Error parsing response message", e);
} finally {
try{instream.close();}catch(IOException ioe){/* TODO log error */}
}
}
if(error != null) {
throw new EFhirClientException("Error unmarshalling resource: "+ResourceUtilities.getErrorDescription(error), error);
}
return resource;
}
/**
* Unmarshals Bundle from response stream.
*
* @param response
* @return
*/
protected static Bundle unmarshalFeed(HttpResponse response, String format) {
Bundle feed = null;
InputStream instream = null;
HttpEntity entity = response.getEntity();
String contentType = response.getHeaders("Content-Type")[0].getValue();
OperationOutcome error = null;
try {
if (entity != null) {
instream = entity.getContent();
if(contentType.contains(ResourceFormat.RESOURCE_XML.getHeader()) || contentType.contains("text/xml+fhir")) {
// error = (OperationOutcome)getParser(ResourceFormat.RESOURCE_XML.getHeader()).parse(instream);
// } else {
Resource rf = getParser(format).parse(instream);
if (rf instanceof Bundle)
feed = (Bundle) rf;
else if (rf instanceof OperationOutcome && hasError((OperationOutcome) rf)) {
error = (OperationOutcome) rf;
} else {
throw new EFhirClientException("Error unmarshalling feed from Http Response: a resource was returned instead");
}
}
instream.close();
}
} catch(IOException ioe) {
throw new EFhirClientException("Error unmarshalling feed from Http Response", ioe);
} catch(Exception e) {
throw new EFhirClientException("Error parsing response message", e);
} finally {
try{instream.close();}catch(IOException ioe){/* TODO log error */}
}
if(error != null) {
throw new EFhirClientException("Error unmarshalling feed: "+ResourceUtilities.getErrorDescription(error), error);
}
return feed;
}
private static boolean hasError(OperationOutcome oo) {
for (OperationOutcomeIssueComponent t : oo.getIssue())
if (t.getSeverity() == IssueSeverity.ERROR || t.getSeverity() == IssueSeverity.FATAL)
return true;
return false;
public static final String DEFAULT_CHARSET = "UTF-8";
public static final String HEADER_LOCATION = "location";
private HttpHost proxy;
private int timeout = 5000;
private String username;
private String password;
private ToolingClientLogger logger;
private int retryCount;
public HttpHost getProxy() {
return proxy;
}
protected static String getLocationHeader(HttpResponse response) {
String location = null;
if(response.getHeaders("location").length > 0) {//TODO Distinguish between both cases if necessary
location = response.getHeaders("location")[0].getValue();
} else if(response.getHeaders("content-location").length > 0) {
location = response.getHeaders("content-location")[0].getValue();
}
return location;
}
/*****************************************************************
* Client connection methods
* ***************************************************************/
public static HttpURLConnection buildConnection(URI baseServiceUri, String tail) {
try {
HttpURLConnection client = (HttpURLConnection) baseServiceUri.resolve(tail).toURL().openConnection();
return client;
} catch(MalformedURLException mue) {
throw new EFhirClientException("Invalid Service URL", mue);
} catch(IOException ioe) {
throw new EFhirClientException("Unable to establish connection to server: " + baseServiceUri.toString() + tail, ioe);
}
}
public static HttpURLConnection buildConnection(URI baseServiceUri, ResourceType resourceType, String id) {
return buildConnection(baseServiceUri, ResourceAddress.buildRelativePathFromResourceType(resourceType, id));
}
/******************************************************************
* Other general helper methods
* ****************************************************************/
public static <T extends Resource> byte[] getResourceAsByteArray(T resource, boolean pretty, boolean isJson) {
ByteArrayOutputStream baos = null;
byte[] byteArray = null;
try {
baos = new ByteArrayOutputStream();
IParser parser = null;
if(isJson) {
parser = new JsonParser();
} else {
parser = new XmlParser();
}
public void setProxy(HttpHost proxy) {
this.proxy = proxy;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public <T extends Resource> ResourceRequest<T> issueOptionsRequest(URI optionsUri, String resourceFormat) {
HttpOptions options = new HttpOptions(optionsUri);
return issueResourceRequest(resourceFormat, options);
}
public <T extends Resource> ResourceRequest<T> issueGetResourceRequest(URI resourceUri, String resourceFormat) {
HttpGet httpget = new HttpGet(resourceUri);
return issueResourceRequest(resourceFormat, httpget);
}
public <T extends Resource> ResourceRequest<T> issuePutRequest(URI resourceUri, byte[] payload, String resourceFormat, List<Header> headers) {
HttpPut httpPut = new HttpPut(resourceUri);
return issueResourceRequest(resourceFormat, httpPut, payload, headers);
}
public <T extends Resource> ResourceRequest<T> issuePutRequest(URI resourceUri, byte[] payload, String resourceFormat) {
HttpPut httpPut = new HttpPut(resourceUri);
return issueResourceRequest(resourceFormat, httpPut, payload, null);
}
public <T extends Resource> ResourceRequest<T> issuePostRequest(URI resourceUri, byte[] payload, String resourceFormat, List<Header> headers) {
HttpPost httpPost = new HttpPost(resourceUri);
return issueResourceRequest(resourceFormat, httpPost, payload, headers);
}
public <T extends Resource> ResourceRequest<T> issuePostRequest(URI resourceUri, byte[] payload, String resourceFormat) {
return issuePostRequest(resourceUri, payload, resourceFormat, null);
}
public Bundle issueGetFeedRequest(URI resourceUri, String resourceFormat) {
HttpGet httpget = new HttpGet(resourceUri);
configureFhirRequest(httpget, resourceFormat);
HttpResponse response = sendRequest(httpget);
return unmarshalReference(response, resourceFormat);
}
private void setAuth(HttpRequest httpget) {
if (password != null) {
try {
byte[] b = Base64.encodeBase64((username+":"+password).getBytes("ASCII"));
String b64 = new String(b, StandardCharsets.US_ASCII);
httpget.setHeader("Authorization", "Basic " + b64);
} catch (UnsupportedEncodingException e) {
}
}
}
public Bundle postBatchRequest(URI resourceUri, byte[] payload, String resourceFormat) {
HttpPost httpPost = new HttpPost(resourceUri);
configureFhirRequest(httpPost, resourceFormat);
HttpResponse response = sendPayload(httpPost, payload, proxy);
return unmarshalFeed(response, resourceFormat);
}
public boolean issueDeleteRequest(URI resourceUri) {
HttpDelete deleteRequest = new HttpDelete(resourceUri);
HttpResponse response = sendRequest(deleteRequest);
int responseStatusCode = response.getStatusLine().getStatusCode();
boolean deletionSuccessful = false;
if(responseStatusCode == 204) {
deletionSuccessful = true;
}
return deletionSuccessful;
}
/***********************************************************
* Request/Response Helper methods
***********************************************************/
protected <T extends Resource> ResourceRequest<T> issueResourceRequest(String resourceFormat, HttpUriRequest request) {
return issueResourceRequest(resourceFormat, request, null);
}
/**
* @param resourceFormat
* @param options
* @return
*/
protected <T extends Resource> ResourceRequest<T> issueResourceRequest(String resourceFormat, HttpUriRequest request, byte[] payload) {
return issueResourceRequest(resourceFormat, request, payload, null);
}
/**
* @param resourceFormat
* @param options
* @return
*/
protected <T extends Resource> ResourceRequest<T> issueResourceRequest(String resourceFormat, HttpUriRequest request, byte[] payload, List<Header> headers) {
configureFhirRequest(request, resourceFormat, headers);
HttpResponse response = null;
if(request instanceof HttpEntityEnclosingRequest && payload != null) {
response = sendPayload((HttpEntityEnclosingRequestBase)request, payload, proxy);
} else if (request instanceof HttpEntityEnclosingRequest && payload == null){
throw new EFhirClientException("PUT and POST requests require a non-null payload");
} else {
response = sendRequest(request);
}
T resource = unmarshalReference(response, resourceFormat);
return new ResourceRequest<T>(resource, response.getStatusLine().getStatusCode(), getLocationHeader(response));
}
/**
* Method adds required request headers.
* TODO handle JSON request as well.
*
* @param request
*/
protected void configureFhirRequest(HttpRequest request, String format) {
configureFhirRequest(request, format, null);
}
/**
* Method adds required request headers.
* TODO handle JSON request as well.
*
* @param request
*/
protected void configureFhirRequest(HttpRequest request, String format, List<Header> headers) {
request.addHeader("User-Agent", "Java FHIR Client for FHIR");
if (format != null) {
request.addHeader("Accept",format);
request.addHeader("Content-Type", format + ";charset=" + DEFAULT_CHARSET);
}
request.addHeader("Accept-Charset", DEFAULT_CHARSET);
if(headers != null) {
for(Header header : headers) {
request.addHeader(header);
}
}
setAuth(request);
}
/**
* Method posts request payload
*
* @param request
* @param payload
* @return
*/
protected HttpResponse sendPayload(HttpEntityEnclosingRequestBase request, byte[] payload, HttpHost proxy) {
HttpResponse response = null;
boolean ok = false;
int tryCount = 0;
while (!ok) {
try {
tryCount++;
HttpClient httpclient = new DefaultHttpClient();
if(proxy != null) {
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
}
request.setEntity(new ByteArrayEntity(payload));
log(request);
response = httpclient.execute(request);
ok = true;
} catch(IOException ioe) {
if (tryCount <= retryCount) {
ok = false;
} else {
throw new EFhirClientException("Error sending HTTP Post/Put Payload: "+ioe.getMessage(), ioe);
}
}
}
return response;
}
/**
*
* @param request
* @param payload
* @return
*/
protected HttpResponse sendRequest(HttpUriRequest request) {
HttpResponse response = null;
try {
HttpClient httpclient = new DefaultHttpClient();
log(request);
HttpParams params = httpclient.getParams();
HttpConnectionParams.setConnectionTimeout(params, timeout);
HttpConnectionParams.setSoTimeout(params, timeout);
if(proxy != null) {
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
}
response = httpclient.execute(request);
} catch(IOException ioe) {
throw new EFhirClientException("Error sending Http Request: "+ioe.getMessage(), ioe);
}
return response;
}
/**
* Unmarshals a resource from the response stream.
*
* @param response
* @return
*/
@SuppressWarnings("unchecked")
protected <T extends Resource> T unmarshalReference(HttpResponse response, String format) {
T resource = null;
OperationOutcome error = null;
byte[] cnt = log(response);
if (cnt != null) {
try {
resource = (T)getParser(format).parse(cnt);
if (resource instanceof OperationOutcome && hasError((OperationOutcome)resource)) {
error = (OperationOutcome) resource;
}
} catch(IOException ioe) {
throw new EFhirClientException("Error reading Http Response: "+ioe.getMessage(), ioe);
} catch(Exception e) {
throw new EFhirClientException("Error parsing response message: "+e.getMessage(), e);
}
}
if(error != null) {
throw new EFhirClientException("Error from server: "+ResourceUtilities.getErrorDescription(error), error);
}
return resource;
}
/**
* Unmarshals Bundle from response stream.
*
* @param response
* @return
*/
protected Bundle unmarshalFeed(HttpResponse response, String format) {
Bundle feed = null;
byte[] cnt = log(response);
String contentType = response.getHeaders("Content-Type")[0].getValue();
OperationOutcome error = null;
try {
if (cnt != null) {
if(contentType.contains(ResourceFormat.RESOURCE_XML.getHeader()) || contentType.contains("text/xml+fhir")) {
Resource rf = getParser(format).parse(cnt);
if (rf instanceof Bundle)
feed = (Bundle) rf;
else if (rf instanceof OperationOutcome && hasError((OperationOutcome) rf)) {
error = (OperationOutcome) rf;
} else {
throw new EFhirClientException("Error reading server response: a resource was returned instead");
}
}
}
} catch(IOException ioe) {
throw new EFhirClientException("Error reading Http Response", ioe);
} catch(Exception e) {
throw new EFhirClientException("Error parsing response message", e);
}
if(error != null) {
throw new EFhirClientException("Error from server: "+ResourceUtilities.getErrorDescription(error), error);
}
return feed;
}
private boolean hasError(OperationOutcome oo) {
for (OperationOutcomeIssueComponent t : oo.getIssue())
if (t.getSeverity() == IssueSeverity.ERROR || t.getSeverity() == IssueSeverity.FATAL)
return true;
return false;
}
protected String getLocationHeader(HttpResponse response) {
String location = null;
if(response.getHeaders("location").length > 0) {//TODO Distinguish between both cases if necessary
location = response.getHeaders("location")[0].getValue();
} else if(response.getHeaders("content-location").length > 0) {
location = response.getHeaders("content-location")[0].getValue();
}
return location;
}
/*****************************************************************
* Client connection methods
* ***************************************************************/
public HttpURLConnection buildConnection(URI baseServiceUri, String tail) {
try {
HttpURLConnection client = (HttpURLConnection) baseServiceUri.resolve(tail).toURL().openConnection();
return client;
} catch(MalformedURLException mue) {
throw new EFhirClientException("Invalid Service URL", mue);
} catch(IOException ioe) {
throw new EFhirClientException("Unable to establish connection to server: " + baseServiceUri.toString() + tail, ioe);
}
}
public HttpURLConnection buildConnection(URI baseServiceUri, ResourceType resourceType, String id) {
return buildConnection(baseServiceUri, ResourceAddress.buildRelativePathFromResourceType(resourceType, id));
}
/******************************************************************
* Other general helper methods
* ****************************************************************/
public <T extends Resource> byte[] getResourceAsByteArray(T resource, boolean pretty, boolean isJson) {
ByteArrayOutputStream baos = null;
byte[] byteArray = null;
try {
baos = new ByteArrayOutputStream();
IParser parser = null;
if(isJson) {
parser = new JsonParser();
} else {
parser = new XmlParser();
}
parser.setOutputStyle(pretty ? OutputStyle.PRETTY : OutputStyle.NORMAL);
parser.compose(baos, resource);
baos.close();
byteArray = baos.toByteArray();
baos.close();
} catch (Exception e) {
try{
baos.close();
}catch(Exception ex) {
throw new EFhirClientException("Error closing output stream", ex);
}
throw new EFhirClientException("Error converting output stream to byte array", e);
}
return byteArray;
}
public static byte[] getFeedAsByteArray(Bundle feed, boolean pretty, boolean isJson) {
ByteArrayOutputStream baos = null;
byte[] byteArray = null;
try {
baos = new ByteArrayOutputStream();
IParser parser = null;
if(isJson) {
parser = new JsonParser();
} else {
parser = new XmlParser();
}
parser.compose(baos, resource);
baos.close();
byteArray = baos.toByteArray();
baos.close();
} catch (Exception e) {
try{
baos.close();
}catch(Exception ex) {
throw new EFhirClientException("Error closing output stream", ex);
}
throw new EFhirClientException("Error converting output stream to byte array", e);
}
return byteArray;
}
public byte[] getFeedAsByteArray(Bundle feed, boolean pretty, boolean isJson) {
ByteArrayOutputStream baos = null;
byte[] byteArray = null;
try {
baos = new ByteArrayOutputStream();
IParser parser = null;
if(isJson) {
parser = new JsonParser();
} else {
parser = new XmlParser();
}
parser.setOutputStyle(pretty ? OutputStyle.PRETTY : OutputStyle.NORMAL);
parser.compose(baos, feed);
baos.close();
byteArray = baos.toByteArray();
baos.close();
} catch (Exception e) {
try{
baos.close();
}catch(Exception ex) {
throw new EFhirClientException("Error closing output stream", ex);
}
throw new EFhirClientException("Error converting output stream to byte array", e);
}
return byteArray;
}
public static Calendar getLastModifiedResponseHeaderAsCalendarObject(URLConnection serverConnection) {
String dateTime = null;
try {
dateTime = serverConnection.getHeaderField("Last-Modified");
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
Date lastModifiedTimestamp = format.parse(dateTime);
Calendar calendar=Calendar.getInstance();
calendar.setTime(lastModifiedTimestamp);
return calendar;
} catch(ParseException pe) {
throw new EFhirClientException("Error parsing Last-Modified response header " + dateTime, pe);
}
}
protected static IParser getParser(String format) {
if(StringUtils.isBlank(format)) {
format = ResourceFormat.RESOURCE_XML.getHeader();
}
if(format.equalsIgnoreCase("json") || format.equalsIgnoreCase(ResourceFormat.RESOURCE_JSON.getHeader()) || format.equalsIgnoreCase(ResourceFormat.RESOURCE_JSON.getHeader())) {
return new JsonParser();
} else if(format.equalsIgnoreCase("xml") || format.equalsIgnoreCase(ResourceFormat.RESOURCE_XML.getHeader()) || format.equalsIgnoreCase(ResourceFormat.RESOURCE_XML.getHeader())) {
return new XmlParser();
} else {
throw new EFhirClientException("Invalid format: " + format);
}
}
/**
* Used for debugging
*
* @param instream
* @return
*/
protected static String writeInputStreamAsString(InputStream instream) {
String value = null;
try {
value = IOUtils.toString(instream, "UTF-8");
System.out.println(value);
} catch(IOException ioe) {
//Do nothing
}
return value;
}
public static Bundle issuePostFeedRequest(URI resourceUri, Map<String, String> parameters, String resourceName, Resource resource, String resourceFormat) throws IOException {
parser.compose(baos, feed);
baos.close();
byteArray = baos.toByteArray();
baos.close();
} catch (Exception e) {
try{
baos.close();
}catch(Exception ex) {
throw new EFhirClientException("Error closing output stream", ex);
}
throw new EFhirClientException("Error converting output stream to byte array", e);
}
return byteArray;
}
public Calendar getLastModifiedResponseHeaderAsCalendarObject(URLConnection serverConnection) {
String dateTime = null;
try {
dateTime = serverConnection.getHeaderField("Last-Modified");
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", new Locale("en", "US"));
Date lastModifiedTimestamp = format.parse(dateTime);
Calendar calendar=Calendar.getInstance();
calendar.setTime(lastModifiedTimestamp);
return calendar;
} catch(ParseException pe) {
throw new EFhirClientException("Error parsing Last-Modified response header " + dateTime, pe);
}
}
protected IParser getParser(String format) {
if(StringUtils.isBlank(format)) {
format = ResourceFormat.RESOURCE_XML.getHeader();
}
if(format.equalsIgnoreCase("json") || format.equalsIgnoreCase(ResourceFormat.RESOURCE_JSON.getHeader()) || format.equalsIgnoreCase(ResourceFormat.RESOURCE_JSON.getHeader())) {
return new JsonParser();
} else if(format.equalsIgnoreCase("xml") || format.equalsIgnoreCase(ResourceFormat.RESOURCE_XML.getHeader()) || format.equalsIgnoreCase(ResourceFormat.RESOURCE_XML.getHeader())) {
return new XmlParser();
} else {
throw new EFhirClientException("Invalid format: " + format);
}
}
public Bundle issuePostFeedRequest(URI resourceUri, Map<String, String> parameters, String resourceName, Resource resource, String resourceFormat) throws IOException {
HttpPost httppost = new HttpPost(resourceUri);
String boundary = "----WebKitFormBoundarykbMUo6H8QaUnYtRy";
httppost.addHeader("Content-Type", "multipart/form-data; boundary="+boundary);
@ -481,8 +524,8 @@ public class ClientUtils {
HttpResponse response = sendPayload(httppost, encodeFormSubmission(parameters, resourceName, resource, boundary));
return unmarshalFeed(response, resourceFormat);
}
private static byte[] encodeFormSubmission(Map<String, String> parameters, String resourceName, Resource resource, String boundary) throws IOException {
private byte[] encodeFormSubmission(Map<String, String> parameters, String resourceName, Resource resource, String boundary) throws IOException {
ByteArrayOutputStream b = new ByteArrayOutputStream();
OutputStreamWriter w = new OutputStreamWriter(b, "UTF-8");
for (String name : parameters.keySet()) {
@ -514,17 +557,99 @@ public class ClientUtils {
* @param payload
* @return
*/
protected static HttpResponse sendPayload(HttpEntityEnclosingRequestBase request, byte[] payload) {
protected HttpResponse sendPayload(HttpEntityEnclosingRequestBase request, byte[] payload) {
HttpResponse response = null;
try {
log(request);
HttpClient httpclient = new DefaultHttpClient();
request.setEntity(new ByteArrayEntity(payload));
response = httpclient.execute(request);
log(response);
} catch(IOException ioe) {
throw new EFhirClientException("Error sending HTTP Post/Put Payload: "+ioe.getMessage(), ioe);
}
return response;
}
private void log(HttpUriRequest request) {
if (logger != null) {
List<String> headers = new ArrayList<>();
for (Header h : request.getAllHeaders()) {
headers.add(h.toString());
}
logger.logRequest(request.getMethod(), request.getURI().toString(), headers, null);
}
}
private void log(HttpEntityEnclosingRequestBase request) {
if (logger != null) {
List<String> headers = new ArrayList<>();
for (Header h : request.getAllHeaders()) {
headers.add(h.toString());
}
byte[] cnt = null;
InputStream s;
try {
s = request.getEntity().getContent();
cnt = IOUtils.toByteArray(s);
s.close();
} catch (Exception e) {
}
logger.logRequest(request.getMethod(), request.getURI().toString(), headers, cnt);
}
}
private byte[] log(HttpResponse response) {
byte[] cnt = null;
try {
InputStream s = response.getEntity().getContent();
cnt = IOUtils.toByteArray(s);
s.close();
} catch (Exception e) {
}
if (logger != null) {
List<String> headers = new ArrayList<>();
for (Header h : response.getAllHeaders()) {
headers.add(h.toString());
}
logger.logResponse(response.getStatusLine().toString(), headers, cnt);
}
return cnt;
}
public ToolingClientLogger getLogger() {
return logger;
}
public void setLogger(ToolingClientLogger logger) {
this.logger = logger;
}
/**
* Used for debugging
*
* @param instream
* @return
*/
protected String writeInputStreamAsString(InputStream instream) {
String value = null;
try {
value = IOUtils.toString(instream, "UTF-8");
System.out.println(value);
} catch(IOException ioe) {
//Do nothing
}
return value;
}
public int getRetryCount() {
return retryCount;
}
public void setRetryCount(int retryCount) {
this.retryCount = retryCount;
}
}

View File

@ -52,6 +52,7 @@ import org.hl7.fhir.dstu2.model.PrimitiveType;
import org.hl7.fhir.dstu2.model.Resource;
import org.hl7.fhir.dstu2.model.StringType;
import org.hl7.fhir.dstu2.model.ValueSet;
import org.hl7.fhir.utilities.ToolingClientLogger;
import org.hl7.fhir.utilities.Utilities;
/**
@ -84,6 +85,8 @@ public class FHIRToolingClient {
public static final String DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ssK";
public static final String DATE_FORMAT = "yyyy-MM-dd";
public static final String hostKey = "http.proxyHost";
public static final String portKey = "http.proxyPort";
private String base;
private ResourceAddress resourceAddress;
@ -91,15 +94,42 @@ public class FHIRToolingClient {
private HttpHost proxy;
private int maxResultSetSize = -1;//_count
private Conformance conf;
private ClientUtils utils = new ClientUtils();
//Pass enpoint for client - URI
public FHIRToolingClient(String baseServiceUrl) throws URISyntaxException {
preferredResourceFormat = ResourceFormat.RESOURCE_XML;
detectProxy();
initialize(baseServiceUrl);
}
public FHIRToolingClient(String baseServiceUrl, String username, String password) throws URISyntaxException {
preferredResourceFormat = ResourceFormat.RESOURCE_XML;
utils.setUsername(username);
utils.setPassword(password);
detectProxy();
initialize(baseServiceUrl);
}
public void configureProxy(String proxyHost, int proxyPort) {
proxy = new HttpHost(proxyHost, proxyPort);
utils.setProxy(new HttpHost(proxyHost, proxyPort));
}
public void detectProxy() {
String host = System.getenv(hostKey);
String port = System.getenv(portKey);
if(host==null) {
host = System.getProperty(hostKey);
}
if(port==null) {
port = System.getProperty(portKey);
}
if(host!=null && port!=null) {
this.configureProxy(host, Integer.parseInt(port));
}
}
public void initialize(String baseServiceUrl) throws URISyntaxException {
@ -142,9 +172,9 @@ public class FHIRToolingClient {
Conformance conformance = null;
try {
if(useOptionsVerb) {
conformance = (Conformance)ClientUtils.issueOptionsRequest(resourceAddress.getBaseServiceUri(), getPreferredResourceFormat(), proxy).getReference();//TODO fix this
conformance = (Conformance)utils.issueOptionsRequest(resourceAddress.getBaseServiceUri(), getPreferredResourceFormat()).getReference();//TODO fix this
} else {
conformance = (Conformance)ClientUtils.issueGetResourceRequest(resourceAddress.resolveMetadataUri(false), getPreferredResourceFormat(), proxy).getReference();
conformance = (Conformance)utils.issueGetResourceRequest(resourceAddress.resolveMetadataUri(false), getPreferredResourceFormat()).getReference();
}
} catch(Exception e) {
handleException("An error has occurred while trying to fetch the server's conformance statement", e);
@ -162,9 +192,9 @@ public class FHIRToolingClient {
Conformance conformance = null;
try {
if(useOptionsVerb) {
conformance = (Conformance)ClientUtils.issueOptionsRequest(resourceAddress.getBaseServiceUri(), getPreferredResourceFormat(), proxy).getReference();//TODO fix this
conformance = (Conformance)utils.issueOptionsRequest(resourceAddress.getBaseServiceUri(), getPreferredResourceFormat()).getReference();//TODO fix this
} else {
conformance = (Conformance)ClientUtils.issueGetResourceRequest(resourceAddress.resolveMetadataUri(true), getPreferredResourceFormat(), proxy).getReference();
conformance = (Conformance)utils.issueGetResourceRequest(resourceAddress.resolveMetadataUri(true), getPreferredResourceFormat()).getReference();
}
} catch(Exception e) {
handleException("An error has occurred while trying to fetch the server's conformance statement", e);
@ -175,7 +205,7 @@ public class FHIRToolingClient {
public <T extends Resource> T read(Class<T> resourceClass, String id) {//TODO Change this to AddressableResource
ResourceRequest<T> result = null;
try {
result = ClientUtils.issueGetResourceRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resourceClass, id), getPreferredResourceFormat(), proxy);
result = utils.issueGetResourceRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resourceClass, id), getPreferredResourceFormat());
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addSuccessStatus(200);//Only one for now
@ -191,7 +221,7 @@ public class FHIRToolingClient {
public <T extends Resource> T vread(Class<T> resourceClass, String id, String version) {
ResourceRequest<T> result = null;
try {
result = ClientUtils.issueGetResourceRequest(resourceAddress.resolveGetUriFromResourceClassAndIdAndVersion(resourceClass, id, version), getPreferredResourceFormat(), proxy);
result = utils.issueGetResourceRequest(resourceAddress.resolveGetUriFromResourceClassAndIdAndVersion(resourceClass, id, version), getPreferredResourceFormat());
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);//unknown
@ -205,40 +235,93 @@ public class FHIRToolingClient {
return result.getPayload();
}
//
// public <T extends Resource> T update(Class<T> resourceClass, T resource, String id) {
// ResourceRequest<T> result = null;
// try {
// List<Header> headers = null;
// result = ClientUtils.issuePutRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resourceClass, id),ClientUtils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers, proxy);
// result.addErrorStatus(410);//gone
// result.addErrorStatus(404);//unknown
// result.addErrorStatus(405);
// result.addErrorStatus(422);//Unprocessable Entity
// result.addSuccessStatus(200);
// result.addSuccessStatus(201);
// if(result.isUnsuccessfulRequest()) {
// throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), (OperationOutcome)result.getPayload());
// }
// } catch(Exception e) {
// throw new EFhirClientException("An error has occurred while trying to update this resource", e);
// }
// // TODO oe 26.1.2015 could be made nicer if only OperationOutcome locationheader is returned with an operationOutcome would be returned (and not the resource also) we make another read
// try {
// OperationOutcome operationOutcome = (OperationOutcome)result.getPayload();
// ResourceAddress.ResourceVersionedIdentifier resVersionedIdentifier = ResourceAddress.parseCreateLocation(result.getLocation());
// return this.vread(resourceClass, resVersionedIdentifier.getId(),resVersionedIdentifier.getVersionId());
// } catch(ClassCastException e) {
// // if we fall throught we have the correct type already in the create
// }
//
// return result.getPayload();
// }
// GET fhir/ValueSet?url=http://hl7.org/fhir/ValueSet/clinical-findings&version=0.8
public <T extends Resource> T getCanonical(Class<T> resourceClass, String canonicalURL) {
ResourceRequest<T> result = null;
try {
result = utils.issueGetResourceRequest(resourceAddress.resolveGetUriFromResourceClassAndCanonical(resourceClass, canonicalURL), getPreferredResourceFormat());
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);//unknown
result.addSuccessStatus(200);//Only one for now
if(result.isUnsuccessfulRequest()) {
throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), (OperationOutcome)result.getPayload());
}
} catch (Exception e) {
handleException("An error has occurred while trying to read this version of the resource", e);
}
Bundle bnd = (Bundle) result.getPayload();
if (bnd.getEntry().size() == 0)
throw new EFhirClientException("No matching resource found for canonical URL '"+canonicalURL+"'");
if (bnd.getEntry().size() > 1)
throw new EFhirClientException("Multiple matching resources found for canonical URL '"+canonicalURL+"'");
return (T) bnd.getEntry().get(0).getResource();
}
public Resource update(Resource resource) {
ResourceRequest<Resource> result = null;
try {
List<Header> headers = null;
result = utils.issuePutRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resource.getClass(), resource.getId()),utils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers);
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);
result.addErrorStatus(422);//Unprocessable Entity
result.addSuccessStatus(200);
result.addSuccessStatus(201);
if(result.isUnsuccessfulRequest()) {
throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), (OperationOutcome)result.getPayload());
}
} catch(Exception e) {
throw new EFhirClientException("An error has occurred while trying to update this resource", e);
}
// TODO oe 26.1.2015 could be made nicer if only OperationOutcome locationheader is returned with an operationOutcome would be returned (and not the resource also) we make another read
try {
OperationOutcome operationOutcome = (OperationOutcome)result.getPayload();
ResourceAddress.ResourceVersionedIdentifier resVersionedIdentifier = ResourceAddress.parseCreateLocation(result.getLocation());
return this.vread(resource.getClass(), resVersionedIdentifier.getId(),resVersionedIdentifier.getVersionId());
} catch(ClassCastException e) {
// if we fall throught we have the correct type already in the create
}
return result.getPayload();
}
public <T extends Resource> T update(Class<T> resourceClass, T resource, String id) {
ResourceRequest<T> result = null;
try {
List<Header> headers = null;
result = utils.issuePutRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resourceClass, id),utils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers);
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);
result.addErrorStatus(422);//Unprocessable Entity
result.addSuccessStatus(200);
result.addSuccessStatus(201);
if(result.isUnsuccessfulRequest()) {
throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), (OperationOutcome)result.getPayload());
}
} catch(Exception e) {
throw new EFhirClientException("An error has occurred while trying to update this resource", e);
}
// TODO oe 26.1.2015 could be made nicer if only OperationOutcome locationheader is returned with an operationOutcome would be returned (and not the resource also) we make another read
try {
OperationOutcome operationOutcome = (OperationOutcome)result.getPayload();
ResourceAddress.ResourceVersionedIdentifier resVersionedIdentifier = ResourceAddress.parseCreateLocation(result.getLocation());
return this.vread(resourceClass, resVersionedIdentifier.getId(),resVersionedIdentifier.getVersionId());
} catch(ClassCastException e) {
// if we fall throught we have the correct type already in the create
}
return result.getPayload();
}
//
// public <T extends Resource> boolean delete(Class<T> resourceClass, String id) {
// try {
// return ClientUtils.issueDeleteRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resourceClass, id), proxy);
// return utils.issueDeleteRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resourceClass, id), proxy);
// } catch(Exception e) {
// throw new EFhirClientException("An error has occurred while trying to delete this resource", e);
// }
@ -250,7 +333,7 @@ public class FHIRToolingClient {
// ResourceRequest<T> resourceRequest = null;
// try {
// List<Header> headers = null;
// resourceRequest = ClientUtils.issuePostRequest(resourceAddress.resolveGetUriFromResourceClass(resourceClass),ClientUtils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers, proxy);
// resourceRequest = utils.issuePostRequest(resourceAddress.resolveGetUriFromResourceClass(resourceClass),utils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers, proxy);
// resourceRequest.addSuccessStatus(201);
// if(resourceRequest.isUnsuccessfulRequest()) {
// throw new EFhirClientException("Server responded with HTTP error code " + resourceRequest.getHttpStatus(), (OperationOutcome)resourceRequest.getPayload());
@ -283,7 +366,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle history(Calendar lastUpdate, Class<T> resourceClass, String id) {
// Bundle history = null;
// try {
// history = ClientUtils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceId(resourceClass, id, lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// history = utils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceId(resourceClass, id, lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("An error has occurred while trying to retrieve history information for this resource", e);
// }
@ -294,7 +377,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle history(Date lastUpdate, Class<T> resourceClass, String id) {
// Bundle history = null;
// try {
// history = ClientUtils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceId(resourceClass, id, lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// history = utils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceId(resourceClass, id, lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("An error has occurred while trying to retrieve history information for this resource", e);
// }
@ -305,7 +388,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle history(Calendar lastUpdate, Class<T> resourceClass) {
// Bundle history = null;
// try {
// history = ClientUtils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceType(resourceClass, lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// history = utils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceType(resourceClass, lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("An error has occurred while trying to retrieve history information for this resource type", e);
// }
@ -316,7 +399,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle history(Date lastUpdate, Class<T> resourceClass) {
// Bundle history = null;
// try {
// history = ClientUtils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceType(resourceClass, lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// history = utils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceType(resourceClass, lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("An error has occurred while trying to retrieve history information for this resource type", e);
// }
@ -327,7 +410,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle history(Class<T> resourceClass) {
// Bundle history = null;
// try {
// history = ClientUtils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceType(resourceClass, maxResultSetSize), getPreferredResourceFormat(), proxy);
// history = utils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceType(resourceClass, maxResultSetSize), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("An error has occurred while trying to retrieve history information for this resource type", e);
// }
@ -338,7 +421,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle history(Class<T> resourceClass, String id) {
// Bundle history = null;
// try {
// history = ClientUtils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceId(resourceClass, id, maxResultSetSize), getPreferredResourceFormat(), proxy);
// history = utils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceId(resourceClass, id, maxResultSetSize), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("An error has occurred while trying to retrieve history information for this resource", e);
// }
@ -349,7 +432,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle history(Date lastUpdate) {
// Bundle history = null;
// try {
// history = ClientUtils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForAllResources(lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// history = utils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForAllResources(lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("An error has occurred while trying to retrieve history since last update",e);
// }
@ -360,7 +443,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle history(Calendar lastUpdate) {
// Bundle history = null;
// try {
// history = ClientUtils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForAllResources(lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// history = utils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForAllResources(lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("An error has occurred while trying to retrieve history since last update",e);
// }
@ -371,7 +454,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle history() {
// Bundle history = null;
// try {
// history = ClientUtils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForAllResources(maxResultSetSize), getPreferredResourceFormat(), proxy);
// history = utils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForAllResources(maxResultSetSize), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("An error has occurred while trying to retrieve history since last update",e);
// }
@ -382,7 +465,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle search(Class<T> resourceClass, Map<String, String> parameters) {
// Bundle searchResults = null;
// try {
// searchResults = ClientUtils.issueGetFeedRequest(resourceAddress.resolveSearchUri(resourceClass, parameters), getPreferredResourceFormat(), proxy);
// searchResults = utils.issueGetFeedRequest(resourceAddress.resolveSearchUri(resourceClass, parameters), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("Error performing search with parameters " + parameters, e);
// }
@ -393,7 +476,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle searchPost(Class<T> resourceClass, T resource, Map<String, String> parameters) {
// Bundle searchResults = null;
// try {
// searchResults = ClientUtils.issuePostFeedRequest(resourceAddress.resolveSearchUri(resourceClass, new HashMap<String, String>()), parameters, "src", resource, getPreferredResourceFormat());
// searchResults = utils.issuePostFeedRequest(resourceAddress.resolveSearchUri(resourceClass, new HashMap<String, String>()), parameters, "src", resource, getPreferredResourceFormat());
// } catch (Exception e) {
// handleException("Error performing search with parameters " + parameters, e);
// }
@ -414,9 +497,9 @@ public class FHIRToolingClient {
ps += p.getName() + "=" + Utilities.encodeUri(((PrimitiveType) p.getValue()).asStringValue())+"&";
ResourceRequest<T> result;
if (complex)
result = ClientUtils.issuePostRequest(resourceAddress.resolveOperationURLFromClass(resourceClass, name, ps), ClientUtils.getResourceAsByteArray(params, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), proxy);
result = utils.issuePostRequest(resourceAddress.resolveOperationURLFromClass(resourceClass, name, ps), utils.getResourceAsByteArray(params, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat());
else
result = ClientUtils.issueGetResourceRequest(resourceAddress.resolveOperationURLFromClass(resourceClass, name, ps), getPreferredResourceFormat(), proxy);
result = utils.issueGetResourceRequest(resourceAddress.resolveOperationURLFromClass(resourceClass, name, ps), getPreferredResourceFormat());
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addSuccessStatus(200);//Only one for now
@ -439,7 +522,7 @@ public class FHIRToolingClient {
public Bundle transaction(Bundle batch) {
Bundle transactionResult = null;
try {
transactionResult = ClientUtils.postBatchRequest(resourceAddress.getBaseServiceUri(), ClientUtils.getFeedAsByteArray(batch, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), proxy);
transactionResult = utils.postBatchRequest(resourceAddress.getBaseServiceUri(), utils.getFeedAsByteArray(batch, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat());
} catch (Exception e) {
handleException("An error occurred trying to process this transaction request", e);
}
@ -451,7 +534,7 @@ public class FHIRToolingClient {
public <T extends Resource> OperationOutcome validate(Class<T> resourceClass, T resource, String id) {
ResourceRequest<T> result = null;
try {
result = ClientUtils.issuePostRequest(resourceAddress.resolveValidateUri(resourceClass, id), ClientUtils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), proxy);
result = utils.issuePostRequest(resourceAddress.resolveValidateUri(resourceClass, id), utils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat());
result.addErrorStatus(400);//gone
result.addErrorStatus(422);//Unprocessable Entity
result.addSuccessStatus(200);//OK
@ -469,7 +552,7 @@ public class FHIRToolingClient {
public List<Coding> getAllTags() {
TagListRequest result = null;
try {
result = ClientUtils.issueGetRequestForTagList(resourceAddress.resolveGetAllTags(), getPreferredResourceFormat(), null, proxy);
result = utils.issueGetRequestForTagList(resourceAddress.resolveGetAllTags(), getPreferredResourceFormat(), null, proxy);
} catch (Exception e) {
handleException("An error has occurred while trying to retrieve all tags", e);
}
@ -480,7 +563,7 @@ public class FHIRToolingClient {
public <T extends Resource> List<Coding> getAllTagsForResourceType(Class<T> resourceClass) {
TagListRequest result = null;
try {
result = ClientUtils.issueGetRequestForTagList(resourceAddress.resolveGetAllTagsForResourceType(resourceClass), getPreferredResourceFormat(), null, proxy);
result = utils.issueGetRequestForTagList(resourceAddress.resolveGetAllTagsForResourceType(resourceClass), getPreferredResourceFormat(), null, proxy);
} catch (Exception e) {
handleException("An error has occurred while trying to retrieve tags for this resource type", e);
}
@ -491,7 +574,7 @@ public class FHIRToolingClient {
public <T extends Resource> List<Coding> getTagsForReference(Class<T> resource, String id) {
TagListRequest result = null;
try {
result = ClientUtils.issueGetRequestForTagList(resourceAddress.resolveGetTagsForReference(resource, id), getPreferredResourceFormat(), null, proxy);
result = utils.issueGetRequestForTagList(resourceAddress.resolveGetTagsForReference(resource, id), getPreferredResourceFormat(), null, proxy);
} catch (Exception e) {
handleException("An error has occurred while trying to retrieve tags for this resource", e);
}
@ -502,7 +585,7 @@ public class FHIRToolingClient {
public <T extends Resource> List<Coding> getTagsForResourceVersion(Class<T> resource, String id, String versionId) {
TagListRequest result = null;
try {
result = ClientUtils.issueGetRequestForTagList(resourceAddress.resolveGetTagsForResourceVersion(resource, id, versionId), getPreferredResourceFormat(), null, proxy);
result = utils.issueGetRequestForTagList(resourceAddress.resolveGetTagsForResourceVersion(resource, id, versionId), getPreferredResourceFormat(), null, proxy);
} catch (Exception e) {
handleException("An error has occurred while trying to retrieve tags for this resource version", e);
}
@ -512,7 +595,7 @@ public class FHIRToolingClient {
//
// public <T extends Resource> boolean deleteTagsForReference(Class<T> resourceClass, String id) {
// try {
// return ClientUtils.issueDeleteRequest(resourceAddress.resolveGetTagsForReference(resourceClass, id), proxy);
// return utils.issueDeleteRequest(resourceAddress.resolveGetTagsForReference(resourceClass, id), proxy);
// } catch(Exception e) {
// handleException("An error has occurred while trying to retrieve tags for this resource version", e);
// throw new EFhirClientException("An error has occurred while trying to delete this resource", e);
@ -523,7 +606,7 @@ public class FHIRToolingClient {
//
// public <T extends Resource> boolean deleteTagsForResourceVersion(Class<T> resourceClass, String id, List<Coding> tags, String version) {
// try {
// return ClientUtils.issueDeleteRequest(resourceAddress.resolveGetTagsForResourceVersion(resourceClass, id, version), proxy);
// return utils.issueDeleteRequest(resourceAddress.resolveGetTagsForResourceVersion(resourceClass, id, version), proxy);
// } catch(Exception e) {
// handleException("An error has occurred while trying to retrieve tags for this resource version", e);
// throw new EFhirClientException("An error has occurred while trying to delete this resource", e);
@ -534,7 +617,7 @@ public class FHIRToolingClient {
public <T extends Resource> List<Coding> createTags(List<Coding> tags, Class<T> resourceClass, String id) {
TagListRequest request = null;
try {
request = ClientUtils.issuePostRequestForTagList(resourceAddress.resolveGetTagsForReference(resourceClass, id),ClientUtils.getTagListAsByteArray(tags, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), null, proxy);
request = utils.issuePostRequestForTagList(resourceAddress.resolveGetTagsForReference(resourceClass, id),utils.getTagListAsByteArray(tags, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), null, proxy);
request.addSuccessStatus(201);
request.addSuccessStatus(200);
if(request.isUnsuccessfulRequest()) {
@ -550,7 +633,7 @@ public class FHIRToolingClient {
public <T extends Resource> List<Coding> createTags(List<Coding> tags, Class<T> resourceClass, String id, String version) {
TagListRequest request = null;
try {
request = ClientUtils.issuePostRequestForTagList(resourceAddress.resolveGetTagsForResourceVersion(resourceClass, id, version),ClientUtils.getTagListAsByteArray(tags, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), null, proxy);
request = utils.issuePostRequestForTagList(resourceAddress.resolveGetTagsForResourceVersion(resourceClass, id, version),utils.getTagListAsByteArray(tags, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), null, proxy);
request.addSuccessStatus(201);
request.addSuccessStatus(200);
if(request.isUnsuccessfulRequest()) {
@ -566,7 +649,7 @@ public class FHIRToolingClient {
public <T extends Resource> List<Coding> deleteTags(List<Coding> tags, Class<T> resourceClass, String id, String version) {
TagListRequest request = null;
try {
request = ClientUtils.issuePostRequestForTagList(resourceAddress.resolveDeleteTagsForResourceVersion(resourceClass, id, version),ClientUtils.getTagListAsByteArray(tags, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), null, proxy);
request = utils.issuePostRequestForTagList(resourceAddress.resolveDeleteTagsForResourceVersion(resourceClass, id, version),utils.getTagListAsByteArray(tags, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), null, proxy);
request.addSuccessStatus(201);
request.addSuccessStatus(200);
if(request.isUnsuccessfulRequest()) {
@ -611,7 +694,7 @@ public class FHIRToolingClient {
public Bundle fetchFeed(String url) {
Bundle feed = null;
try {
feed = ClientUtils.issueGetFeedRequest(new URI(url), getPreferredResourceFormat(), proxy);
feed = utils.issueGetFeedRequest(new URI(url), getPreferredResourceFormat());
} catch (Exception e) {
handleException("An error has occurred while trying to retrieve history since last update",e);
}
@ -620,8 +703,8 @@ public class FHIRToolingClient {
public ValueSet expandValueset(ValueSet source) {
List<Header> headers = null;
ResourceRequest<Resource> result = ClientUtils.issuePostRequest(resourceAddress.resolveOperationUri(ValueSet.class, "expand"),
ClientUtils.getResourceAsByteArray(source, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers, proxy);
ResourceRequest<Resource> result = utils.issuePostRequest(resourceAddress.resolveOperationUri(ValueSet.class, "expand"),
utils.getResourceAsByteArray(source, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers);
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);
@ -636,7 +719,7 @@ public class FHIRToolingClient {
public Parameters lookupCode(Map<String, String> params) {
ResourceRequest<Resource> result = ClientUtils.issueGetResourceRequest(resourceAddress.resolveOperationUri(ValueSet.class, "lookup", params), getPreferredResourceFormat(), proxy);
ResourceRequest<Resource> result = utils.issueGetResourceRequest(resourceAddress.resolveOperationUri(ValueSet.class, "lookup", params), getPreferredResourceFormat());
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);
@ -656,8 +739,8 @@ public class FHIRToolingClient {
for (String n : params.keySet())
p.addParameter().setName(n).setValue(new StringType(params.get(n)));
ResourceRequest<Resource> result = ClientUtils.issuePostRequest(resourceAddress.resolveOperationUri(ValueSet.class, "expand", params),
ClientUtils.getResourceAsByteArray(p, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers, proxy);
ResourceRequest<Resource> result = utils.issuePostRequest(resourceAddress.resolveOperationUri(ValueSet.class, "expand", params),
utils.getResourceAsByteArray(p, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers);
result.addErrorStatus(410); //gone
result.addErrorStatus(404); //unknown
result.addErrorStatus(405);
@ -670,6 +753,22 @@ public class FHIRToolingClient {
return (ValueSet) result.getPayload();
}
// public ValueSet expandValueset(ValueSet source, ExpansionProfile profile, Map<String, String> params) {
// List<Header> headers = null;
// ResourceRequest<Resource> result = utils.issuePostRequest(resourceAddress.resolveOperationUri(ValueSet.class, "expand", params),
// utils.getResourceAsByteArray(source, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers, proxy);
// result.addErrorStatus(410);//gone
// result.addErrorStatus(404);//unknown
// result.addErrorStatus(405);
// result.addErrorStatus(422);//Unprocessable Entity
// result.addSuccessStatus(200);
// result.addSuccessStatus(201);
// if(result.isUnsuccessfulRequest()) {
// throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), (OperationOutcome)result.getPayload());
// }
// return (ValueSet) result.getPayload();
// }
public String getAddress() {
return base;
@ -679,8 +778,8 @@ public class FHIRToolingClient {
Parameters params = new Parameters();
params.addParameter().setName("name").setValue(new StringType(name));
List<Header> headers = null;
ResourceRequest<Resource> result = ClientUtils.issuePostRequest(resourceAddress.resolveOperationUri(null, "closure", new HashMap<String, String>()),
ClientUtils.getResourceAsByteArray(params, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers, proxy);
ResourceRequest<Resource> result = utils.issuePostRequest(resourceAddress.resolveOperationUri(null, "closure", new HashMap<String, String>()),
utils.getResourceAsByteArray(params, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers);
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);
@ -698,8 +797,8 @@ public class FHIRToolingClient {
params.addParameter().setName("name").setValue(new StringType(name));
params.addParameter().setName("concept").setValue(coding);
List<Header> headers = null;
ResourceRequest<Resource> result = ClientUtils.issuePostRequest(resourceAddress.resolveOperationUri(null, "closure", new HashMap<String, String>()),
ClientUtils.getResourceAsByteArray(params, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers, proxy);
ResourceRequest<Resource> result = utils.issuePostRequest(resourceAddress.resolveOperationUri(null, "closure", new HashMap<String, String>()),
utils.getResourceAsByteArray(params, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers);
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);
@ -712,8 +811,51 @@ public class FHIRToolingClient {
return (ConceptMap) result.getPayload();
}
public Parameters getTerminologyCapabilities() {
return (Parameters) ClientUtils.issueGetResourceRequest(resourceAddress.resolveMetadataTxCaps(), getPreferredResourceFormat(), proxy).getReference();
public int getTimeout() {
return utils.getTimeout();
}
public void setTimeout(int timeout) {
utils.setTimeout(timeout);
}
public String getUsername() {
return utils.getUsername();
}
public void setUsername(String username) {
utils.setUsername(username);
}
public String getPassword() {
return utils.getPassword();
}
public void setPassword(String password) {
utils.setPassword(password);
}
public Parameters getTerminologyCapabilities() {
return (Parameters) utils.issueGetResourceRequest(resourceAddress.resolveMetadataTxCaps(), getPreferredResourceFormat()).getReference();
}
public org.hl7.fhir.utilities.ToolingClientLogger getLogger() {
return utils.getLogger();
}
public void setLogger(ToolingClientLogger logger) {
utils.setLogger(logger);
}
public int getRetryCount() {
return utils.getRetryCount();
}
public void setRetryCount(int retryCount) {
utils.setRetryCount(retryCount);
}
}

View File

@ -40,6 +40,7 @@ import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
@ -78,23 +79,28 @@ public class ResourceAddress {
}
public <T extends Resource> URI resolveOperationURLFromClass(Class<T> resourceClass, String name, String parameters) {
return baseServiceUri.resolve(nameForClass(resourceClass) +"/$"+name+"?"+ parameters);
return baseServiceUri.resolve(nameForClassWithSlash(resourceClass) +"$"+name+"?"+ parameters);
}
public <T extends Resource> URI resolveSearchUri(Class<T> resourceClass, Map<String,String> parameters) {
return appendHttpParameters(baseServiceUri.resolve(nameForClass(resourceClass) +"/_search"), parameters);
return appendHttpParameters(baseServiceUri.resolve(nameForClassWithSlash(resourceClass) +"_search"), parameters);
}
private <T extends Resource> String nameForClassWithSlash(Class<T> resourceClass) {
String n = nameForClass(resourceClass);
return n == null ? "" : n +"/";
}
public <T extends Resource> URI resolveOperationUri(Class<T> resourceClass, String opName) {
return baseServiceUri.resolve(nameForClass(resourceClass) +"/$"+opName);
return baseServiceUri.resolve(nameForClassWithSlash(resourceClass) +"/"+opName);
}
public <T extends Resource> URI resolveOperationUri(Class<T> resourceClass, String opName, Map<String,String> parameters) {
return appendHttpParameters(baseServiceUri.resolve(nameForClass(resourceClass) +"/$"+opName), parameters);
return appendHttpParameters(baseServiceUri.resolve(nameForClassWithSlash(resourceClass) +"$"+opName), parameters);
}
public <T extends Resource> URI resolveValidateUri(Class<T> resourceClass, String id) {
return baseServiceUri.resolve(nameForClass(resourceClass) +"/_validate/"+id);
return baseServiceUri.resolve(nameForClassWithSlash(resourceClass) +"$validate/"+id);
}
public <T extends Resource> URI resolveGetUriFromResourceClass(Class<T> resourceClass) {
@ -109,6 +115,13 @@ public class ResourceAddress {
return baseServiceUri.resolve(nameForClass(resourceClass) +"/"+id+"/_history/"+version);
}
public <T extends Resource> URI resolveGetUriFromResourceClassAndCanonical(Class<T> resourceClass, String canonicalUrl) {
if (canonicalUrl.contains("|"))
return baseServiceUri.resolve(nameForClass(resourceClass)+"?url="+canonicalUrl.substring(0, canonicalUrl.indexOf("|"))+"&version="+canonicalUrl.substring(canonicalUrl.indexOf("|")+1));
else
return baseServiceUri.resolve(nameForClass(resourceClass)+"?url="+canonicalUrl);
}
public URI resolveGetHistoryForAllResources(int count) {
if(count > 0) {
return appendHttpParameter(baseServiceUri.resolve("_history"), "_count", ""+count);
@ -195,6 +208,8 @@ public class ResourceAddress {
public <T extends Resource> String nameForClass(Class<T> resourceClass) {
if (resourceClass == null)
return null;
String res = resourceClass.getSimpleName();
if (res.equals("List_"))
return "List";
@ -206,6 +221,11 @@ public class ResourceAddress {
return baseServiceUri.resolve(quick ? "metadata?_summary=true" : "metadata");
}
public URI resolveMetadataTxCaps() {
return baseServiceUri.resolve("metadata?mode=terminology");
}
/**
* For now, assume this type of location header structure.
* Generalize later: http://hl7connect.healthintersections.com.au/svc/fhir/318/_history/1
@ -379,7 +399,7 @@ public class ResourceAddress {
}
public static String getCalendarDateInIsoTimeFormat(Calendar calendar) {
SimpleDateFormat format = new SimpleDateFormat("YYYY-MM-dd'T'hh:mm:ss");//TODO Move out
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss", new Locale("en", "US"));//TODO Move out
format.setTimeZone(TimeZone.getTimeZone("GMT"));
return format.format(calendar.getTime());
}
@ -410,8 +430,4 @@ public class ResourceAddress {
}
}
public URI resolveMetadataTxCaps() {
return baseServiceUri.resolve("metadata?mode=terminology");
}
}

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>org.hl7.fhir.core</artifactId>
<version>5.0.6-SNAPSHOT</version>
<version>5.0.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -134,7 +134,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
params.put("_limit", "10000");
params.put("_incomplete", "true");
params.put("profile", "http://www.healthintersections.com.au/fhir/expansion/no-details");
ValueSet result = txServer.expandValueset(vs, params);
ValueSet result = txServer.expandValueset(vs, null, params);
return new ValueSetExpansionOutcome(result);
} catch (Exception e) {
return new ValueSetExpansionOutcome("Error expanding ValueSet \""+vs.getUrl()+": "+e.getMessage());

View File

@ -38,21 +38,25 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
@ -81,6 +85,7 @@ import org.hl7.fhir.dstu2016may.model.OperationOutcome.OperationOutcomeIssueComp
import org.hl7.fhir.dstu2016may.model.Resource;
import org.hl7.fhir.dstu2016may.model.ResourceType;
import org.hl7.fhir.dstu2016may.utils.ResourceUtilities;
import org.hl7.fhir.utilities.ToolingClientLogger;
/**
* Helper class handling lower level HTTP transport concerns.
@ -92,53 +97,103 @@ public class ClientUtils {
public static String DEFAULT_CHARSET = "UTF-8";
public static final String HEADER_LOCATION = "location";
public static <T extends Resource> ResourceRequest<T> issueOptionsRequest(URI optionsUri, String resourceFormat, HttpHost proxy) {
private HttpHost proxy;
private int timeout = 5000;
private String username;
private String password;
private ToolingClientLogger logger;
private int retryCount;
public HttpHost getProxy() {
return proxy;
}
public void setProxy(HttpHost proxy) {
this.proxy = proxy;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public <T extends Resource> ResourceRequest<T> issueOptionsRequest(URI optionsUri, String resourceFormat) {
HttpOptions options = new HttpOptions(optionsUri);
return issueResourceRequest(resourceFormat, options, proxy);
return issueResourceRequest(resourceFormat, options);
}
public static <T extends Resource> ResourceRequest<T> issueGetResourceRequest(URI resourceUri, String resourceFormat, HttpHost proxy) {
public <T extends Resource> ResourceRequest<T> issueGetResourceRequest(URI resourceUri, String resourceFormat) {
HttpGet httpget = new HttpGet(resourceUri);
return issueResourceRequest(resourceFormat, httpget, proxy);
return issueResourceRequest(resourceFormat, httpget);
}
public static <T extends Resource> ResourceRequest<T> issuePutRequest(URI resourceUri, byte[] payload, String resourceFormat, List<Header> headers, HttpHost proxy) {
public <T extends Resource> ResourceRequest<T> issuePutRequest(URI resourceUri, byte[] payload, String resourceFormat, List<Header> headers) {
HttpPut httpPut = new HttpPut(resourceUri);
return issueResourceRequest(resourceFormat, httpPut, payload, headers, proxy);
return issueResourceRequest(resourceFormat, httpPut, payload, headers);
}
public static <T extends Resource> ResourceRequest<T> issuePutRequest(URI resourceUri, byte[] payload, String resourceFormat, HttpHost proxy) {
public <T extends Resource> ResourceRequest<T> issuePutRequest(URI resourceUri, byte[] payload, String resourceFormat) {
HttpPut httpPut = new HttpPut(resourceUri);
return issueResourceRequest(resourceFormat, httpPut, payload, null, proxy);
return issueResourceRequest(resourceFormat, httpPut, payload, null);
}
public static <T extends Resource> ResourceRequest<T> issuePostRequest(URI resourceUri, byte[] payload, String resourceFormat, List<Header> headers, HttpHost proxy) {
public <T extends Resource> ResourceRequest<T> issuePostRequest(URI resourceUri, byte[] payload, String resourceFormat, List<Header> headers) {
HttpPost httpPost = new HttpPost(resourceUri);
return issueResourceRequest(resourceFormat, httpPost, payload, headers, proxy);
return issueResourceRequest(resourceFormat, httpPost, payload, headers);
}
public static <T extends Resource> ResourceRequest<T> issuePostRequest(URI resourceUri, byte[] payload, String resourceFormat, HttpHost proxy) {
return issuePostRequest(resourceUri, payload, resourceFormat, null, proxy);
public <T extends Resource> ResourceRequest<T> issuePostRequest(URI resourceUri, byte[] payload, String resourceFormat) {
return issuePostRequest(resourceUri, payload, resourceFormat, null);
}
public static Bundle issueGetFeedRequest(URI resourceUri, String resourceFormat, HttpHost proxy) {
public Bundle issueGetFeedRequest(URI resourceUri, String resourceFormat) {
HttpGet httpget = new HttpGet(resourceUri);
configureFhirRequest(httpget, resourceFormat);
HttpResponse response = sendRequest(httpget, proxy);
HttpResponse response = sendRequest(httpget);
return unmarshalReference(response, resourceFormat);
}
public static Bundle postBatchRequest(URI resourceUri, byte[] payload, String resourceFormat, HttpHost proxy) {
private void setAuth(HttpRequest httpget) {
if (password != null) {
try {
byte[] b = Base64.encodeBase64((username+":"+password).getBytes("ASCII"));
String b64 = new String(b, StandardCharsets.US_ASCII);
httpget.setHeader("Authorization", "Basic " + b64);
} catch (UnsupportedEncodingException e) {
}
}
}
public Bundle postBatchRequest(URI resourceUri, byte[] payload, String resourceFormat) {
HttpPost httpPost = new HttpPost(resourceUri);
configureFhirRequest(httpPost, resourceFormat);
HttpResponse response = sendPayload(httpPost, payload, proxy);
return unmarshalFeed(response, resourceFormat);
}
public static boolean issueDeleteRequest(URI resourceUri, HttpHost proxy) {
public boolean issueDeleteRequest(URI resourceUri) {
HttpDelete deleteRequest = new HttpDelete(resourceUri);
HttpResponse response = sendRequest(deleteRequest, proxy);
HttpResponse response = sendRequest(deleteRequest);
int responseStatusCode = response.getStatusLine().getStatusCode();
boolean deletionSuccessful = false;
if(responseStatusCode == 204) {
@ -151,8 +206,8 @@ public class ClientUtils {
* Request/Response Helper methods
***********************************************************/
protected static <T extends Resource> ResourceRequest<T> issueResourceRequest(String resourceFormat, HttpUriRequest request, HttpHost proxy) {
return issueResourceRequest(resourceFormat, request, null, proxy);
protected <T extends Resource> ResourceRequest<T> issueResourceRequest(String resourceFormat, HttpUriRequest request) {
return issueResourceRequest(resourceFormat, request, null);
}
/**
@ -160,8 +215,8 @@ public class ClientUtils {
* @param options
* @return
*/
protected static <T extends Resource> ResourceRequest<T> issueResourceRequest(String resourceFormat, HttpUriRequest request, byte[] payload, HttpHost proxy) {
return issueResourceRequest(resourceFormat, request, payload, null, proxy);
protected <T extends Resource> ResourceRequest<T> issueResourceRequest(String resourceFormat, HttpUriRequest request, byte[] payload) {
return issueResourceRequest(resourceFormat, request, payload, null);
}
/**
@ -169,7 +224,7 @@ public class ClientUtils {
* @param options
* @return
*/
protected static <T extends Resource> ResourceRequest<T> issueResourceRequest(String resourceFormat, HttpUriRequest request, byte[] payload, List<Header> headers, HttpHost proxy) {
protected <T extends Resource> ResourceRequest<T> issueResourceRequest(String resourceFormat, HttpUriRequest request, byte[] payload, List<Header> headers) {
configureFhirRequest(request, resourceFormat, headers);
HttpResponse response = null;
if(request instanceof HttpEntityEnclosingRequest && payload != null) {
@ -177,10 +232,10 @@ public class ClientUtils {
} else if (request instanceof HttpEntityEnclosingRequest && payload == null){
throw new EFhirClientException("PUT and POST requests require a non-null payload");
} else {
response = sendRequest(request, proxy);
response = sendRequest(request);
}
T resource = unmarshalReference(response, resourceFormat);
return new ResourceRequest<T>(resource, response.getStatusLine().getStatusCode(), ClientUtils.getLocationHeader(response));
return new ResourceRequest<T>(resource, response.getStatusLine().getStatusCode(), getLocationHeader(response));
}
@ -190,7 +245,7 @@ public class ClientUtils {
*
* @param request
*/
protected static void configureFhirRequest(HttpRequest request, String format) {
protected void configureFhirRequest(HttpRequest request, String format) {
configureFhirRequest(request, format, null);
}
@ -200,7 +255,7 @@ public class ClientUtils {
*
* @param request
*/
protected static void configureFhirRequest(HttpRequest request, String format, List<Header> headers) {
protected void configureFhirRequest(HttpRequest request, String format, List<Header> headers) {
request.addHeader("User-Agent", "Java FHIR Client for FHIR");
if (format != null) {
@ -213,6 +268,7 @@ public class ClientUtils {
request.addHeader(header);
}
}
setAuth(request);
}
/**
@ -222,17 +278,28 @@ public class ClientUtils {
* @param payload
* @return
*/
protected static HttpResponse sendPayload(HttpEntityEnclosingRequestBase request, byte[] payload, HttpHost proxy) {
protected HttpResponse sendPayload(HttpEntityEnclosingRequestBase request, byte[] payload, HttpHost proxy) {
HttpResponse response = null;
boolean ok = false;
int tryCount = 0;
while (!ok) {
try {
tryCount++;
HttpClient httpclient = new DefaultHttpClient();
if(proxy != null) {
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
}
request.setEntity(new ByteArrayEntity(payload));
log(request);
response = httpclient.execute(request);
ok = true;
} catch(IOException ioe) {
throw new EFhirClientException("Error sending HTTP Post/Put Payload", ioe);
if (tryCount <= retryCount) {
ok = false;
} else {
throw new EFhirClientException("Error sending HTTP Post/Put Payload: "+ioe.getMessage(), ioe);
}
}
}
return response;
}
@ -243,20 +310,20 @@ public class ClientUtils {
* @param payload
* @return
*/
protected static HttpResponse sendRequest(HttpUriRequest request, HttpHost proxy) {
protected HttpResponse sendRequest(HttpUriRequest request) {
HttpResponse response = null;
try {
HttpClient httpclient = new DefaultHttpClient();
log(request);
HttpParams params = httpclient.getParams();
HttpConnectionParams.setConnectionTimeout(params, 5000);
HttpConnectionParams.setSoTimeout(params, 5000);
HttpConnectionParams.setConnectionTimeout(params, timeout);
HttpConnectionParams.setSoTimeout(params, timeout);
if(proxy != null) {
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
}
response = httpclient.execute(request);
} catch(IOException ioe) {
throw new EFhirClientException("Error sending Http Request", ioe);
throw new EFhirClientException("Error sending Http Request: "+ioe.getMessage(), ioe);
}
return response;
}
@ -268,29 +335,24 @@ public class ClientUtils {
* @return
*/
@SuppressWarnings("unchecked")
protected static <T extends Resource> T unmarshalReference(HttpResponse response, String format) {
protected <T extends Resource> T unmarshalReference(HttpResponse response, String format) {
T resource = null;
OperationOutcome error = null;
InputStream instream = null;
HttpEntity entity = response.getEntity();
if (entity != null && entity.getContentLength() != 0) {
try {
instream = entity.getContent();
// System.out.println(writeInputStreamAsString(instream));
resource = (T)getParser(format).parse(instream);
byte[] cnt = log(response);
if (cnt != null) {
try {
resource = (T)getParser(format).parse(cnt);
if (resource instanceof OperationOutcome && hasError((OperationOutcome)resource)) {
error = (OperationOutcome) resource;
}
} catch(IOException ioe) {
throw new EFhirClientException("Error unmarshalling entity from Http Response", ioe);
throw new EFhirClientException("Error reading Http Response: "+ioe.getMessage(), ioe);
} catch(Exception e) {
throw new EFhirClientException("Error parsing response message", e);
} finally {
try{instream.close();}catch(IOException ioe){/* TODO log error */}
throw new EFhirClientException("Error parsing response message: "+e.getMessage(), e);
}
}
if(error != null) {
throw new EFhirClientException("Error unmarshalling resource: "+ResourceUtilities.getErrorDescription(error), error);
throw new EFhirClientException("Error from server: "+ResourceUtilities.getErrorDescription(error), error);
}
return resource;
}
@ -301,50 +363,43 @@ public class ClientUtils {
* @param response
* @return
*/
protected static Bundle unmarshalFeed(HttpResponse response, String format) {
protected Bundle unmarshalFeed(HttpResponse response, String format) {
Bundle feed = null;
InputStream instream = null;
HttpEntity entity = response.getEntity();
byte[] cnt = log(response);
String contentType = response.getHeaders("Content-Type")[0].getValue();
OperationOutcome error = null;
try {
if (entity != null) {
instream = entity.getContent();
if (cnt != null) {
if(contentType.contains(ResourceFormat.RESOURCE_XML.getHeader()) || contentType.contains("text/xml+fhir")) {
// error = (OperationOutcome)getParser(ResourceFormat.RESOURCE_XML.getHeader()).parse(instream);
// } else {
Resource rf = getParser(format).parse(instream);
Resource rf = getParser(format).parse(cnt);
if (rf instanceof Bundle)
feed = (Bundle) rf;
else if (rf instanceof OperationOutcome && hasError((OperationOutcome) rf)) {
error = (OperationOutcome) rf;
} else {
throw new EFhirClientException("Error unmarshalling feed from Http Response: a resource was returned instead");
throw new EFhirClientException("Error reading server response: a resource was returned instead");
}
}
instream.close();
}
} catch(IOException ioe) {
throw new EFhirClientException("Error unmarshalling feed from Http Response", ioe);
throw new EFhirClientException("Error reading Http Response", ioe);
} catch(Exception e) {
throw new EFhirClientException("Error parsing response message", e);
} finally {
try{instream.close();}catch(IOException ioe){/* TODO log error */}
}
if(error != null) {
throw new EFhirClientException("Error unmarshalling feed: "+ResourceUtilities.getErrorDescription(error), error);
throw new EFhirClientException("Error from server: "+ResourceUtilities.getErrorDescription(error), error);
}
return feed;
}
private static boolean hasError(OperationOutcome oo) {
private boolean hasError(OperationOutcome oo) {
for (OperationOutcomeIssueComponent t : oo.getIssue())
if (t.getSeverity() == IssueSeverity.ERROR || t.getSeverity() == IssueSeverity.FATAL)
return true;
return false;
}
protected static String getLocationHeader(HttpResponse response) {
protected String getLocationHeader(HttpResponse response) {
String location = null;
if(response.getHeaders("location").length > 0) {//TODO Distinguish between both cases if necessary
location = response.getHeaders("location")[0].getValue();
@ -359,7 +414,7 @@ public class ClientUtils {
* Client connection methods
* ***************************************************************/
public static HttpURLConnection buildConnection(URI baseServiceUri, String tail) {
public HttpURLConnection buildConnection(URI baseServiceUri, String tail) {
try {
HttpURLConnection client = (HttpURLConnection) baseServiceUri.resolve(tail).toURL().openConnection();
return client;
@ -370,7 +425,7 @@ public class ClientUtils {
}
}
public static HttpURLConnection buildConnection(URI baseServiceUri, ResourceType resourceType, String id) {
public HttpURLConnection buildConnection(URI baseServiceUri, ResourceType resourceType, String id) {
return buildConnection(baseServiceUri, ResourceAddress.buildRelativePathFromResourceType(resourceType, id));
}
@ -379,7 +434,7 @@ public class ClientUtils {
* ****************************************************************/
public static <T extends Resource> byte[] getResourceAsByteArray(T resource, boolean pretty, boolean isJson) {
public <T extends Resource> byte[] getResourceAsByteArray(T resource, boolean pretty, boolean isJson) {
ByteArrayOutputStream baos = null;
byte[] byteArray = null;
try {
@ -406,7 +461,7 @@ public class ClientUtils {
return byteArray;
}
public static byte[] getFeedAsByteArray(Bundle feed, boolean pretty, boolean isJson) {
public byte[] getFeedAsByteArray(Bundle feed, boolean pretty, boolean isJson) {
ByteArrayOutputStream baos = null;
byte[] byteArray = null;
try {
@ -433,11 +488,11 @@ public class ClientUtils {
return byteArray;
}
public static Calendar getLastModifiedResponseHeaderAsCalendarObject(URLConnection serverConnection) {
public Calendar getLastModifiedResponseHeaderAsCalendarObject(URLConnection serverConnection) {
String dateTime = null;
try {
dateTime = serverConnection.getHeaderField("Last-Modified");
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", new Locale("en", "US"));
Date lastModifiedTimestamp = format.parse(dateTime);
Calendar calendar=Calendar.getInstance();
calendar.setTime(lastModifiedTimestamp);
@ -447,7 +502,7 @@ public class ClientUtils {
}
}
protected static IParser getParser(String format) {
protected IParser getParser(String format) {
if(StringUtils.isBlank(format)) {
format = ResourceFormat.RESOURCE_XML.getHeader();
}
@ -460,25 +515,7 @@ public class ClientUtils {
}
}
/**
* Used for debugging
*
* @param instream
* @return
*/
protected static String writeInputStreamAsString(InputStream instream) {
String value = null;
try {
value = IOUtils.toString(instream, "UTF-8");
System.out.println(value);
} catch(IOException ioe) {
//Do nothing
}
return value;
}
public static Bundle issuePostFeedRequest(URI resourceUri, Map<String, String> parameters, String resourceName, Resource resource, String resourceFormat) throws IOException {
public Bundle issuePostFeedRequest(URI resourceUri, Map<String, String> parameters, String resourceName, Resource resource, String resourceFormat) throws IOException {
HttpPost httppost = new HttpPost(resourceUri);
String boundary = "----WebKitFormBoundarykbMUo6H8QaUnYtRy";
httppost.addHeader("Content-Type", "multipart/form-data; boundary="+boundary);
@ -488,7 +525,7 @@ public class ClientUtils {
return unmarshalFeed(response, resourceFormat);
}
private static byte[] encodeFormSubmission(Map<String, String> parameters, String resourceName, Resource resource, String boundary) throws IOException {
private byte[] encodeFormSubmission(Map<String, String> parameters, String resourceName, Resource resource, String boundary) throws IOException {
ByteArrayOutputStream b = new ByteArrayOutputStream();
OutputStreamWriter w = new OutputStreamWriter(b, "UTF-8");
for (String name : parameters.keySet()) {
@ -520,17 +557,99 @@ public class ClientUtils {
* @param payload
* @return
*/
protected static HttpResponse sendPayload(HttpEntityEnclosingRequestBase request, byte[] payload) {
protected HttpResponse sendPayload(HttpEntityEnclosingRequestBase request, byte[] payload) {
HttpResponse response = null;
try {
log(request);
HttpClient httpclient = new DefaultHttpClient();
request.setEntity(new ByteArrayEntity(payload));
response = httpclient.execute(request);
log(response);
} catch(IOException ioe) {
throw new EFhirClientException("Error sending HTTP Post/Put Payload: "+ioe.getMessage(), ioe);
}
return response;
}
private void log(HttpUriRequest request) {
if (logger != null) {
List<String> headers = new ArrayList<>();
for (Header h : request.getAllHeaders()) {
headers.add(h.toString());
}
logger.logRequest(request.getMethod(), request.getURI().toString(), headers, null);
}
}
private void log(HttpEntityEnclosingRequestBase request) {
if (logger != null) {
List<String> headers = new ArrayList<>();
for (Header h : request.getAllHeaders()) {
headers.add(h.toString());
}
byte[] cnt = null;
InputStream s;
try {
s = request.getEntity().getContent();
cnt = IOUtils.toByteArray(s);
s.close();
} catch (Exception e) {
}
logger.logRequest(request.getMethod(), request.getURI().toString(), headers, cnt);
}
}
private byte[] log(HttpResponse response) {
byte[] cnt = null;
try {
InputStream s = response.getEntity().getContent();
cnt = IOUtils.toByteArray(s);
s.close();
} catch (Exception e) {
}
if (logger != null) {
List<String> headers = new ArrayList<>();
for (Header h : response.getAllHeaders()) {
headers.add(h.toString());
}
logger.logResponse(response.getStatusLine().toString(), headers, cnt);
}
return cnt;
}
public ToolingClientLogger getLogger() {
return logger;
}
public void setLogger(ToolingClientLogger logger) {
this.logger = logger;
}
/**
* Used for debugging
*
* @param instream
* @return
*/
protected String writeInputStreamAsString(InputStream instream) {
String value = null;
try {
value = IOUtils.toString(instream, "UTF-8");
System.out.println(value);
} catch(IOException ioe) {
//Do nothing
}
return value;
}
public int getRetryCount() {
return retryCount;
}
public void setRetryCount(int retryCount) {
this.retryCount = retryCount;
}
}

View File

@ -52,6 +52,7 @@ import org.hl7.fhir.dstu2016may.model.PrimitiveType;
import org.hl7.fhir.dstu2016may.model.Resource;
import org.hl7.fhir.dstu2016may.model.StringType;
import org.hl7.fhir.dstu2016may.model.ValueSet;
import org.hl7.fhir.utilities.ToolingClientLogger;
import org.hl7.fhir.utilities.Utilities;
/**
@ -93,6 +94,7 @@ public class FHIRToolingClient {
private HttpHost proxy;
private int maxResultSetSize = -1;//_count
private Conformance conf;
private ClientUtils utils = new ClientUtils();
//Pass enpoint for client - URI
public FHIRToolingClient(String baseServiceUrl) throws URISyntaxException {
@ -101,8 +103,16 @@ public class FHIRToolingClient {
initialize(baseServiceUrl);
}
public FHIRToolingClient(String baseServiceUrl, String username, String password) throws URISyntaxException {
preferredResourceFormat = ResourceFormat.RESOURCE_XML;
utils.setUsername(username);
utils.setPassword(password);
detectProxy();
initialize(baseServiceUrl);
}
public void configureProxy(String proxyHost, int proxyPort) {
proxy = new HttpHost(proxyHost, proxyPort);
utils.setProxy(new HttpHost(proxyHost, proxyPort));
}
public void detectProxy() {
@ -162,9 +172,9 @@ public class FHIRToolingClient {
Conformance conformance = null;
try {
if(useOptionsVerb) {
conformance = (Conformance)ClientUtils.issueOptionsRequest(resourceAddress.getBaseServiceUri(), getPreferredResourceFormat(), proxy).getReference();//TODO fix this
conformance = (Conformance)utils.issueOptionsRequest(resourceAddress.getBaseServiceUri(), getPreferredResourceFormat()).getReference();//TODO fix this
} else {
conformance = (Conformance)ClientUtils.issueGetResourceRequest(resourceAddress.resolveMetadataUri(false), getPreferredResourceFormat(), proxy).getReference();
conformance = (Conformance)utils.issueGetResourceRequest(resourceAddress.resolveMetadataUri(false), getPreferredResourceFormat()).getReference();
}
} catch(Exception e) {
handleException("An error has occurred while trying to fetch the server's conformance statement", e);
@ -182,9 +192,9 @@ public class FHIRToolingClient {
Conformance conformance = null;
try {
if(useOptionsVerb) {
conformance = (Conformance)ClientUtils.issueOptionsRequest(resourceAddress.getBaseServiceUri(), getPreferredResourceFormat(), proxy).getReference();//TODO fix this
conformance = (Conformance)utils.issueOptionsRequest(resourceAddress.getBaseServiceUri(), getPreferredResourceFormat()).getReference();//TODO fix this
} else {
conformance = (Conformance)ClientUtils.issueGetResourceRequest(resourceAddress.resolveMetadataUri(true), getPreferredResourceFormat(), proxy).getReference();
conformance = (Conformance)utils.issueGetResourceRequest(resourceAddress.resolveMetadataUri(true), getPreferredResourceFormat()).getReference();
}
} catch(Exception e) {
handleException("An error has occurred while trying to fetch the server's conformance statement", e);
@ -195,7 +205,7 @@ public class FHIRToolingClient {
public <T extends Resource> T read(Class<T> resourceClass, String id) {//TODO Change this to AddressableResource
ResourceRequest<T> result = null;
try {
result = ClientUtils.issueGetResourceRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resourceClass, id), getPreferredResourceFormat(), proxy);
result = utils.issueGetResourceRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resourceClass, id), getPreferredResourceFormat());
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addSuccessStatus(200);//Only one for now
@ -211,7 +221,7 @@ public class FHIRToolingClient {
public <T extends Resource> T vread(Class<T> resourceClass, String id, String version) {
ResourceRequest<T> result = null;
try {
result = ClientUtils.issueGetResourceRequest(resourceAddress.resolveGetUriFromResourceClassAndIdAndVersion(resourceClass, id, version), getPreferredResourceFormat(), proxy);
result = utils.issueGetResourceRequest(resourceAddress.resolveGetUriFromResourceClassAndIdAndVersion(resourceClass, id, version), getPreferredResourceFormat());
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);//unknown
@ -225,40 +235,93 @@ public class FHIRToolingClient {
return result.getPayload();
}
//
// public <T extends Resource> T update(Class<T> resourceClass, T resource, String id) {
// ResourceRequest<T> result = null;
// try {
// List<Header> headers = null;
// result = ClientUtils.issuePutRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resourceClass, id),ClientUtils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers, proxy);
// result.addErrorStatus(410);//gone
// result.addErrorStatus(404);//unknown
// result.addErrorStatus(405);
// result.addErrorStatus(422);//Unprocessable Entity
// result.addSuccessStatus(200);
// result.addSuccessStatus(201);
// if(result.isUnsuccessfulRequest()) {
// throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), (OperationOutcome)result.getPayload());
// }
// } catch(Exception e) {
// throw new EFhirClientException("An error has occurred while trying to update this resource", e);
// }
// // TODO oe 26.1.2015 could be made nicer if only OperationOutcome locationheader is returned with an operationOutcome would be returned (and not the resource also) we make another read
// try {
// OperationOutcome operationOutcome = (OperationOutcome)result.getPayload();
// ResourceAddress.ResourceVersionedIdentifier resVersionedIdentifier = ResourceAddress.parseCreateLocation(result.getLocation());
// return this.vread(resourceClass, resVersionedIdentifier.getId(),resVersionedIdentifier.getVersionId());
// } catch(ClassCastException e) {
// // if we fall throught we have the correct type already in the create
// }
//
// return result.getPayload();
// }
// GET fhir/ValueSet?url=http://hl7.org/fhir/ValueSet/clinical-findings&version=0.8
public <T extends Resource> T getCanonical(Class<T> resourceClass, String canonicalURL) {
ResourceRequest<T> result = null;
try {
result = utils.issueGetResourceRequest(resourceAddress.resolveGetUriFromResourceClassAndCanonical(resourceClass, canonicalURL), getPreferredResourceFormat());
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);//unknown
result.addSuccessStatus(200);//Only one for now
if(result.isUnsuccessfulRequest()) {
throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), (OperationOutcome)result.getPayload());
}
} catch (Exception e) {
handleException("An error has occurred while trying to read this version of the resource", e);
}
Bundle bnd = (Bundle) result.getPayload();
if (bnd.getEntry().size() == 0)
throw new EFhirClientException("No matching resource found for canonical URL '"+canonicalURL+"'");
if (bnd.getEntry().size() > 1)
throw new EFhirClientException("Multiple matching resources found for canonical URL '"+canonicalURL+"'");
return (T) bnd.getEntry().get(0).getResource();
}
public Resource update(Resource resource) {
ResourceRequest<Resource> result = null;
try {
List<Header> headers = null;
result = utils.issuePutRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resource.getClass(), resource.getId()),utils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers);
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);
result.addErrorStatus(422);//Unprocessable Entity
result.addSuccessStatus(200);
result.addSuccessStatus(201);
if(result.isUnsuccessfulRequest()) {
throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), (OperationOutcome)result.getPayload());
}
} catch(Exception e) {
throw new EFhirClientException("An error has occurred while trying to update this resource", e);
}
// TODO oe 26.1.2015 could be made nicer if only OperationOutcome locationheader is returned with an operationOutcome would be returned (and not the resource also) we make another read
try {
OperationOutcome operationOutcome = (OperationOutcome)result.getPayload();
ResourceAddress.ResourceVersionedIdentifier resVersionedIdentifier = ResourceAddress.parseCreateLocation(result.getLocation());
return this.vread(resource.getClass(), resVersionedIdentifier.getId(),resVersionedIdentifier.getVersionId());
} catch(ClassCastException e) {
// if we fall throught we have the correct type already in the create
}
return result.getPayload();
}
public <T extends Resource> T update(Class<T> resourceClass, T resource, String id) {
ResourceRequest<T> result = null;
try {
List<Header> headers = null;
result = utils.issuePutRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resourceClass, id),utils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers);
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);
result.addErrorStatus(422);//Unprocessable Entity
result.addSuccessStatus(200);
result.addSuccessStatus(201);
if(result.isUnsuccessfulRequest()) {
throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), (OperationOutcome)result.getPayload());
}
} catch(Exception e) {
throw new EFhirClientException("An error has occurred while trying to update this resource", e);
}
// TODO oe 26.1.2015 could be made nicer if only OperationOutcome locationheader is returned with an operationOutcome would be returned (and not the resource also) we make another read
try {
OperationOutcome operationOutcome = (OperationOutcome)result.getPayload();
ResourceAddress.ResourceVersionedIdentifier resVersionedIdentifier = ResourceAddress.parseCreateLocation(result.getLocation());
return this.vread(resourceClass, resVersionedIdentifier.getId(),resVersionedIdentifier.getVersionId());
} catch(ClassCastException e) {
// if we fall throught we have the correct type already in the create
}
return result.getPayload();
}
//
// public <T extends Resource> boolean delete(Class<T> resourceClass, String id) {
// try {
// return ClientUtils.issueDeleteRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resourceClass, id), proxy);
// return utils.issueDeleteRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resourceClass, id), proxy);
// } catch(Exception e) {
// throw new EFhirClientException("An error has occurred while trying to delete this resource", e);
// }
@ -270,7 +333,7 @@ public class FHIRToolingClient {
// ResourceRequest<T> resourceRequest = null;
// try {
// List<Header> headers = null;
// resourceRequest = ClientUtils.issuePostRequest(resourceAddress.resolveGetUriFromResourceClass(resourceClass),ClientUtils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers, proxy);
// resourceRequest = utils.issuePostRequest(resourceAddress.resolveGetUriFromResourceClass(resourceClass),utils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers, proxy);
// resourceRequest.addSuccessStatus(201);
// if(resourceRequest.isUnsuccessfulRequest()) {
// throw new EFhirClientException("Server responded with HTTP error code " + resourceRequest.getHttpStatus(), (OperationOutcome)resourceRequest.getPayload());
@ -303,7 +366,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle history(Calendar lastUpdate, Class<T> resourceClass, String id) {
// Bundle history = null;
// try {
// history = ClientUtils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceId(resourceClass, id, lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// history = utils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceId(resourceClass, id, lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("An error has occurred while trying to retrieve history information for this resource", e);
// }
@ -314,7 +377,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle history(Date lastUpdate, Class<T> resourceClass, String id) {
// Bundle history = null;
// try {
// history = ClientUtils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceId(resourceClass, id, lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// history = utils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceId(resourceClass, id, lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("An error has occurred while trying to retrieve history information for this resource", e);
// }
@ -325,7 +388,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle history(Calendar lastUpdate, Class<T> resourceClass) {
// Bundle history = null;
// try {
// history = ClientUtils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceType(resourceClass, lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// history = utils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceType(resourceClass, lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("An error has occurred while trying to retrieve history information for this resource type", e);
// }
@ -336,7 +399,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle history(Date lastUpdate, Class<T> resourceClass) {
// Bundle history = null;
// try {
// history = ClientUtils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceType(resourceClass, lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// history = utils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceType(resourceClass, lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("An error has occurred while trying to retrieve history information for this resource type", e);
// }
@ -347,7 +410,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle history(Class<T> resourceClass) {
// Bundle history = null;
// try {
// history = ClientUtils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceType(resourceClass, maxResultSetSize), getPreferredResourceFormat(), proxy);
// history = utils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceType(resourceClass, maxResultSetSize), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("An error has occurred while trying to retrieve history information for this resource type", e);
// }
@ -358,7 +421,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle history(Class<T> resourceClass, String id) {
// Bundle history = null;
// try {
// history = ClientUtils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceId(resourceClass, id, maxResultSetSize), getPreferredResourceFormat(), proxy);
// history = utils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForResourceId(resourceClass, id, maxResultSetSize), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("An error has occurred while trying to retrieve history information for this resource", e);
// }
@ -369,7 +432,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle history(Date lastUpdate) {
// Bundle history = null;
// try {
// history = ClientUtils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForAllResources(lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// history = utils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForAllResources(lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("An error has occurred while trying to retrieve history since last update",e);
// }
@ -380,7 +443,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle history(Calendar lastUpdate) {
// Bundle history = null;
// try {
// history = ClientUtils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForAllResources(lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// history = utils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForAllResources(lastUpdate, maxResultSetSize), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("An error has occurred while trying to retrieve history since last update",e);
// }
@ -391,7 +454,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle history() {
// Bundle history = null;
// try {
// history = ClientUtils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForAllResources(maxResultSetSize), getPreferredResourceFormat(), proxy);
// history = utils.issueGetFeedRequest(resourceAddress.resolveGetHistoryForAllResources(maxResultSetSize), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("An error has occurred while trying to retrieve history since last update",e);
// }
@ -402,7 +465,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle search(Class<T> resourceClass, Map<String, String> parameters) {
// Bundle searchResults = null;
// try {
// searchResults = ClientUtils.issueGetFeedRequest(resourceAddress.resolveSearchUri(resourceClass, parameters), getPreferredResourceFormat(), proxy);
// searchResults = utils.issueGetFeedRequest(resourceAddress.resolveSearchUri(resourceClass, parameters), getPreferredResourceFormat(), proxy);
// } catch (Exception e) {
// handleException("Error performing search with parameters " + parameters, e);
// }
@ -413,7 +476,7 @@ public class FHIRToolingClient {
// public <T extends Resource> Bundle searchPost(Class<T> resourceClass, T resource, Map<String, String> parameters) {
// Bundle searchResults = null;
// try {
// searchResults = ClientUtils.issuePostFeedRequest(resourceAddress.resolveSearchUri(resourceClass, new HashMap<String, String>()), parameters, "src", resource, getPreferredResourceFormat());
// searchResults = utils.issuePostFeedRequest(resourceAddress.resolveSearchUri(resourceClass, new HashMap<String, String>()), parameters, "src", resource, getPreferredResourceFormat());
// } catch (Exception e) {
// handleException("Error performing search with parameters " + parameters, e);
// }
@ -434,9 +497,9 @@ public class FHIRToolingClient {
ps += p.getName() + "=" + Utilities.encodeUri(((PrimitiveType) p.getValue()).asStringValue())+"&";
ResourceRequest<T> result;
if (complex)
result = ClientUtils.issuePostRequest(resourceAddress.resolveOperationURLFromClass(resourceClass, name, ps), ClientUtils.getResourceAsByteArray(params, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), proxy);
result = utils.issuePostRequest(resourceAddress.resolveOperationURLFromClass(resourceClass, name, ps), utils.getResourceAsByteArray(params, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat());
else
result = ClientUtils.issueGetResourceRequest(resourceAddress.resolveOperationURLFromClass(resourceClass, name, ps), getPreferredResourceFormat(), proxy);
result = utils.issueGetResourceRequest(resourceAddress.resolveOperationURLFromClass(resourceClass, name, ps), getPreferredResourceFormat());
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addSuccessStatus(200);//Only one for now
@ -459,7 +522,7 @@ public class FHIRToolingClient {
public Bundle transaction(Bundle batch) {
Bundle transactionResult = null;
try {
transactionResult = ClientUtils.postBatchRequest(resourceAddress.getBaseServiceUri(), ClientUtils.getFeedAsByteArray(batch, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), proxy);
transactionResult = utils.postBatchRequest(resourceAddress.getBaseServiceUri(), utils.getFeedAsByteArray(batch, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat());
} catch (Exception e) {
handleException("An error occurred trying to process this transaction request", e);
}
@ -471,7 +534,7 @@ public class FHIRToolingClient {
public <T extends Resource> OperationOutcome validate(Class<T> resourceClass, T resource, String id) {
ResourceRequest<T> result = null;
try {
result = ClientUtils.issuePostRequest(resourceAddress.resolveValidateUri(resourceClass, id), ClientUtils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), proxy);
result = utils.issuePostRequest(resourceAddress.resolveValidateUri(resourceClass, id), utils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat());
result.addErrorStatus(400);//gone
result.addErrorStatus(422);//Unprocessable Entity
result.addSuccessStatus(200);//OK
@ -489,7 +552,7 @@ public class FHIRToolingClient {
public List<Coding> getAllTags() {
TagListRequest result = null;
try {
result = ClientUtils.issueGetRequestForTagList(resourceAddress.resolveGetAllTags(), getPreferredResourceFormat(), null, proxy);
result = utils.issueGetRequestForTagList(resourceAddress.resolveGetAllTags(), getPreferredResourceFormat(), null, proxy);
} catch (Exception e) {
handleException("An error has occurred while trying to retrieve all tags", e);
}
@ -500,7 +563,7 @@ public class FHIRToolingClient {
public <T extends Resource> List<Coding> getAllTagsForResourceType(Class<T> resourceClass) {
TagListRequest result = null;
try {
result = ClientUtils.issueGetRequestForTagList(resourceAddress.resolveGetAllTagsForResourceType(resourceClass), getPreferredResourceFormat(), null, proxy);
result = utils.issueGetRequestForTagList(resourceAddress.resolveGetAllTagsForResourceType(resourceClass), getPreferredResourceFormat(), null, proxy);
} catch (Exception e) {
handleException("An error has occurred while trying to retrieve tags for this resource type", e);
}
@ -511,7 +574,7 @@ public class FHIRToolingClient {
public <T extends Resource> List<Coding> getTagsForReference(Class<T> resource, String id) {
TagListRequest result = null;
try {
result = ClientUtils.issueGetRequestForTagList(resourceAddress.resolveGetTagsForReference(resource, id), getPreferredResourceFormat(), null, proxy);
result = utils.issueGetRequestForTagList(resourceAddress.resolveGetTagsForReference(resource, id), getPreferredResourceFormat(), null, proxy);
} catch (Exception e) {
handleException("An error has occurred while trying to retrieve tags for this resource", e);
}
@ -522,7 +585,7 @@ public class FHIRToolingClient {
public <T extends Resource> List<Coding> getTagsForResourceVersion(Class<T> resource, String id, String versionId) {
TagListRequest result = null;
try {
result = ClientUtils.issueGetRequestForTagList(resourceAddress.resolveGetTagsForResourceVersion(resource, id, versionId), getPreferredResourceFormat(), null, proxy);
result = utils.issueGetRequestForTagList(resourceAddress.resolveGetTagsForResourceVersion(resource, id, versionId), getPreferredResourceFormat(), null, proxy);
} catch (Exception e) {
handleException("An error has occurred while trying to retrieve tags for this resource version", e);
}
@ -532,7 +595,7 @@ public class FHIRToolingClient {
//
// public <T extends Resource> boolean deleteTagsForReference(Class<T> resourceClass, String id) {
// try {
// return ClientUtils.issueDeleteRequest(resourceAddress.resolveGetTagsForReference(resourceClass, id), proxy);
// return utils.issueDeleteRequest(resourceAddress.resolveGetTagsForReference(resourceClass, id), proxy);
// } catch(Exception e) {
// handleException("An error has occurred while trying to retrieve tags for this resource version", e);
// throw new EFhirClientException("An error has occurred while trying to delete this resource", e);
@ -543,7 +606,7 @@ public class FHIRToolingClient {
//
// public <T extends Resource> boolean deleteTagsForResourceVersion(Class<T> resourceClass, String id, List<Coding> tags, String version) {
// try {
// return ClientUtils.issueDeleteRequest(resourceAddress.resolveGetTagsForResourceVersion(resourceClass, id, version), proxy);
// return utils.issueDeleteRequest(resourceAddress.resolveGetTagsForResourceVersion(resourceClass, id, version), proxy);
// } catch(Exception e) {
// handleException("An error has occurred while trying to retrieve tags for this resource version", e);
// throw new EFhirClientException("An error has occurred while trying to delete this resource", e);
@ -554,7 +617,7 @@ public class FHIRToolingClient {
public <T extends Resource> List<Coding> createTags(List<Coding> tags, Class<T> resourceClass, String id) {
TagListRequest request = null;
try {
request = ClientUtils.issuePostRequestForTagList(resourceAddress.resolveGetTagsForReference(resourceClass, id),ClientUtils.getTagListAsByteArray(tags, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), null, proxy);
request = utils.issuePostRequestForTagList(resourceAddress.resolveGetTagsForReference(resourceClass, id),utils.getTagListAsByteArray(tags, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), null, proxy);
request.addSuccessStatus(201);
request.addSuccessStatus(200);
if(request.isUnsuccessfulRequest()) {
@ -570,7 +633,7 @@ public class FHIRToolingClient {
public <T extends Resource> List<Coding> createTags(List<Coding> tags, Class<T> resourceClass, String id, String version) {
TagListRequest request = null;
try {
request = ClientUtils.issuePostRequestForTagList(resourceAddress.resolveGetTagsForResourceVersion(resourceClass, id, version),ClientUtils.getTagListAsByteArray(tags, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), null, proxy);
request = utils.issuePostRequestForTagList(resourceAddress.resolveGetTagsForResourceVersion(resourceClass, id, version),utils.getTagListAsByteArray(tags, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), null, proxy);
request.addSuccessStatus(201);
request.addSuccessStatus(200);
if(request.isUnsuccessfulRequest()) {
@ -586,7 +649,7 @@ public class FHIRToolingClient {
public <T extends Resource> List<Coding> deleteTags(List<Coding> tags, Class<T> resourceClass, String id, String version) {
TagListRequest request = null;
try {
request = ClientUtils.issuePostRequestForTagList(resourceAddress.resolveDeleteTagsForResourceVersion(resourceClass, id, version),ClientUtils.getTagListAsByteArray(tags, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), null, proxy);
request = utils.issuePostRequestForTagList(resourceAddress.resolveDeleteTagsForResourceVersion(resourceClass, id, version),utils.getTagListAsByteArray(tags, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), null, proxy);
request.addSuccessStatus(201);
request.addSuccessStatus(200);
if(request.isUnsuccessfulRequest()) {
@ -631,7 +694,7 @@ public class FHIRToolingClient {
public Bundle fetchFeed(String url) {
Bundle feed = null;
try {
feed = ClientUtils.issueGetFeedRequest(new URI(url), getPreferredResourceFormat(), proxy);
feed = utils.issueGetFeedRequest(new URI(url), getPreferredResourceFormat());
} catch (Exception e) {
handleException("An error has occurred while trying to retrieve history since last update",e);
}
@ -640,8 +703,8 @@ public class FHIRToolingClient {
public ValueSet expandValueset(ValueSet source) {
List<Header> headers = null;
ResourceRequest<Resource> result = ClientUtils.issuePostRequest(resourceAddress.resolveOperationUri(ValueSet.class, "expand"),
ClientUtils.getResourceAsByteArray(source, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers, proxy);
ResourceRequest<Resource> result = utils.issuePostRequest(resourceAddress.resolveOperationUri(ValueSet.class, "expand"),
utils.getResourceAsByteArray(source, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers);
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);
@ -656,7 +719,7 @@ public class FHIRToolingClient {
public Parameters lookupCode(Map<String, String> params) {
ResourceRequest<Resource> result = ClientUtils.issueGetResourceRequest(resourceAddress.resolveOperationUri(ValueSet.class, "lookup", params), getPreferredResourceFormat(), proxy);
ResourceRequest<Resource> result = utils.issueGetResourceRequest(resourceAddress.resolveOperationUri(ValueSet.class, "lookup", params), getPreferredResourceFormat());
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);
@ -668,10 +731,16 @@ public class FHIRToolingClient {
}
return (Parameters) result.getPayload();
}
public ValueSet expandValueset(ValueSet source, Map<String, String> params) {
public ValueSet expandValueset(ValueSet source, Parameters expParams,Map<String, String> params) {
List<Header> headers = null;
ResourceRequest<Resource> result = ClientUtils.issuePostRequest(resourceAddress.resolveOperationUri(ValueSet.class, "expand", params),
ClientUtils.getResourceAsByteArray(source, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers, proxy);
Parameters p = expParams == null ? new Parameters() : expParams.copy();
p.addParameter().setName("valueSet").setResource(source);
for (String n : params.keySet())
p.addParameter().setName(n).setValue(new StringType(params.get(n)));
ResourceRequest<Resource> result = utils.issuePostRequest(resourceAddress.resolveOperationUri(ValueSet.class, "expand", params),
utils.getResourceAsByteArray(p, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers);
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);
@ -684,6 +753,22 @@ public class FHIRToolingClient {
return (ValueSet) result.getPayload();
}
// public ValueSet expandValueset(ValueSet source, ExpansionProfile profile, Map<String, String> params) {
// List<Header> headers = null;
// ResourceRequest<Resource> result = utils.issuePostRequest(resourceAddress.resolveOperationUri(ValueSet.class, "expand", params),
// utils.getResourceAsByteArray(source, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers, proxy);
// result.addErrorStatus(410);//gone
// result.addErrorStatus(404);//unknown
// result.addErrorStatus(405);
// result.addErrorStatus(422);//Unprocessable Entity
// result.addSuccessStatus(200);
// result.addSuccessStatus(201);
// if(result.isUnsuccessfulRequest()) {
// throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), (OperationOutcome)result.getPayload());
// }
// return (ValueSet) result.getPayload();
// }
public String getAddress() {
return base;
@ -693,8 +778,8 @@ public class FHIRToolingClient {
Parameters params = new Parameters();
params.addParameter().setName("name").setValue(new StringType(name));
List<Header> headers = null;
ResourceRequest<Resource> result = ClientUtils.issuePostRequest(resourceAddress.resolveOperationUri(null, "closure", new HashMap<String, String>()),
ClientUtils.getResourceAsByteArray(params, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers, proxy);
ResourceRequest<Resource> result = utils.issuePostRequest(resourceAddress.resolveOperationUri(null, "closure", new HashMap<String, String>()),
utils.getResourceAsByteArray(params, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers);
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);
@ -712,8 +797,8 @@ public class FHIRToolingClient {
params.addParameter().setName("name").setValue(new StringType(name));
params.addParameter().setName("concept").setValue(coding);
List<Header> headers = null;
ResourceRequest<Resource> result = ClientUtils.issuePostRequest(resourceAddress.resolveOperationUri(null, "closure", new HashMap<String, String>()),
ClientUtils.getResourceAsByteArray(params, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers, proxy);
ResourceRequest<Resource> result = utils.issuePostRequest(resourceAddress.resolveOperationUri(null, "closure", new HashMap<String, String>()),
utils.getResourceAsByteArray(params, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers);
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);
@ -726,4 +811,51 @@ public class FHIRToolingClient {
return (ConceptMap) result.getPayload();
}
public int getTimeout() {
return utils.getTimeout();
}
public void setTimeout(int timeout) {
utils.setTimeout(timeout);
}
public String getUsername() {
return utils.getUsername();
}
public void setUsername(String username) {
utils.setUsername(username);
}
public String getPassword() {
return utils.getPassword();
}
public void setPassword(String password) {
utils.setPassword(password);
}
public Parameters getTerminologyCapabilities() {
return (Parameters) utils.issueGetResourceRequest(resourceAddress.resolveMetadataTxCaps(), getPreferredResourceFormat()).getReference();
}
public org.hl7.fhir.utilities.ToolingClientLogger getLogger() {
return utils.getLogger();
}
public void setLogger(ToolingClientLogger logger) {
utils.setLogger(logger);
}
public int getRetryCount() {
return utils.getRetryCount();
}
public void setRetryCount(int retryCount) {
utils.setRetryCount(retryCount);
}
}

View File

@ -40,6 +40,7 @@ import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
@ -114,6 +115,13 @@ public class ResourceAddress {
return baseServiceUri.resolve(nameForClass(resourceClass) +"/"+id+"/_history/"+version);
}
public <T extends Resource> URI resolveGetUriFromResourceClassAndCanonical(Class<T> resourceClass, String canonicalUrl) {
if (canonicalUrl.contains("|"))
return baseServiceUri.resolve(nameForClass(resourceClass)+"?url="+canonicalUrl.substring(0, canonicalUrl.indexOf("|"))+"&version="+canonicalUrl.substring(canonicalUrl.indexOf("|")+1));
else
return baseServiceUri.resolve(nameForClass(resourceClass)+"?url="+canonicalUrl);
}
public URI resolveGetHistoryForAllResources(int count) {
if(count > 0) {
return appendHttpParameter(baseServiceUri.resolve("_history"), "_count", ""+count);
@ -213,6 +221,11 @@ public class ResourceAddress {
return baseServiceUri.resolve(quick ? "metadata?_summary=true" : "metadata");
}
public URI resolveMetadataTxCaps() {
return baseServiceUri.resolve("metadata?mode=terminology");
}
/**
* For now, assume this type of location header structure.
* Generalize later: http://hl7connect.healthintersections.com.au/svc/fhir/318/_history/1
@ -386,7 +399,7 @@ public class ResourceAddress {
}
public static String getCalendarDateInIsoTimeFormat(Calendar calendar) {
SimpleDateFormat format = new SimpleDateFormat("YYYY-MM-dd'T'hh:mm:ss");//TODO Move out
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss", new Locale("en", "US"));//TODO Move out
format.setTimeZone(TimeZone.getTimeZone("GMT"));
return format.format(calendar.getTime());
}

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>org.hl7.fhir.core</artifactId>
<version>5.0.6-SNAPSHOT</version>
<version>5.0.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -7,19 +7,19 @@ package org.hl7.fhir.dstu3.utils.client;
/*
Copyright (c) 2011+, HL7, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to
* Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
@ -30,7 +30,7 @@ package org.hl7.fhir.dstu3.utils.client;
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
@ -50,6 +50,7 @@ import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.codec.binary.Base64;
@ -84,6 +85,7 @@ import org.hl7.fhir.dstu3.model.OperationOutcome.OperationOutcomeIssueComponent;
import org.hl7.fhir.dstu3.model.Resource;
import org.hl7.fhir.dstu3.model.ResourceType;
import org.hl7.fhir.dstu3.utils.ResourceUtilities;
import org.hl7.fhir.utilities.ToolingClientLogger;
/**
* Helper class handling lower level HTTP transport concerns.
@ -91,15 +93,16 @@ import org.hl7.fhir.dstu3.utils.ResourceUtilities;
* @author Claude Nanjo
*/
public class ClientUtils {
public static final String DEFAULT_CHARSET = "UTF-8";
public static final String HEADER_LOCATION = "location";
public static final String HEADER_LOCATION = "location";
private HttpHost proxy;
private int timeout = 5000;
private String username;
private String password;
private ToolingClientLogger logger;
private int retryCount;
public HttpHost getProxy() {
return proxy;
@ -134,42 +137,42 @@ public class ClientUtils {
}
public <T extends Resource> ResourceRequest<T> issueOptionsRequest(URI optionsUri, String resourceFormat) {
HttpOptions options = new HttpOptions(optionsUri);
HttpOptions options = new HttpOptions(optionsUri);
return issueResourceRequest(resourceFormat, options);
}
}
public <T extends Resource> ResourceRequest<T> issueGetResourceRequest(URI resourceUri, String resourceFormat) {
HttpGet httpget = new HttpGet(resourceUri);
HttpGet httpget = new HttpGet(resourceUri);
return issueResourceRequest(resourceFormat, httpget);
}
}
public <T extends Resource> ResourceRequest<T> issuePutRequest(URI resourceUri, byte[] payload, String resourceFormat, List<Header> headers) {
HttpPut httpPut = new HttpPut(resourceUri);
HttpPut httpPut = new HttpPut(resourceUri);
return issueResourceRequest(resourceFormat, httpPut, payload, headers);
}
}
public <T extends Resource> ResourceRequest<T> issuePutRequest(URI resourceUri, byte[] payload, String resourceFormat) {
HttpPut httpPut = new HttpPut(resourceUri);
HttpPut httpPut = new HttpPut(resourceUri);
return issueResourceRequest(resourceFormat, httpPut, payload, null);
}
}
public <T extends Resource> ResourceRequest<T> issuePostRequest(URI resourceUri, byte[] payload, String resourceFormat, List<Header> headers) {
HttpPost httpPost = new HttpPost(resourceUri);
HttpPost httpPost = new HttpPost(resourceUri);
return issueResourceRequest(resourceFormat, httpPost, payload, headers);
}
}
public <T extends Resource> ResourceRequest<T> issuePostRequest(URI resourceUri, byte[] payload, String resourceFormat) {
return issuePostRequest(resourceUri, payload, resourceFormat, null);
}
}
public Bundle issueGetFeedRequest(URI resourceUri, String resourceFormat) {
HttpGet httpget = new HttpGet(resourceUri);
configureFhirRequest(httpget, resourceFormat);
HttpGet httpget = new HttpGet(resourceUri);
configureFhirRequest(httpget, resourceFormat);
HttpResponse response = sendRequest(httpget);
return unmarshalReference(response, resourceFormat);
}
return unmarshalReference(response, resourceFormat);
}
private void setAuth(HttpRequest httpget) {
if (password != null) {
try {
@ -182,326 +185,336 @@ public class ClientUtils {
}
public Bundle postBatchRequest(URI resourceUri, byte[] payload, String resourceFormat) {
HttpPost httpPost = new HttpPost(resourceUri);
configureFhirRequest(httpPost, resourceFormat);
HttpResponse response = sendPayload(httpPost, payload, proxy);
return unmarshalFeed(response, resourceFormat);
}
HttpPost httpPost = new HttpPost(resourceUri);
configureFhirRequest(httpPost, resourceFormat);
HttpResponse response = sendPayload(httpPost, payload, proxy);
return unmarshalFeed(response, resourceFormat);
}
public boolean issueDeleteRequest(URI resourceUri) {
HttpDelete deleteRequest = new HttpDelete(resourceUri);
HttpDelete deleteRequest = new HttpDelete(resourceUri);
HttpResponse response = sendRequest(deleteRequest);
int responseStatusCode = response.getStatusLine().getStatusCode();
boolean deletionSuccessful = false;
if(responseStatusCode == 204) {
deletionSuccessful = true;
}
return deletionSuccessful;
}
/***********************************************************
* Request/Response Helper methods
***********************************************************/
int responseStatusCode = response.getStatusLine().getStatusCode();
boolean deletionSuccessful = false;
if(responseStatusCode == 204) {
deletionSuccessful = true;
}
return deletionSuccessful;
}
/***********************************************************
* Request/Response Helper methods
***********************************************************/
protected <T extends Resource> ResourceRequest<T> issueResourceRequest(String resourceFormat, HttpUriRequest request) {
return issueResourceRequest(resourceFormat, request, null);
}
/**
* @param resourceFormat
* @param options
* @return
*/
}
/**
* @param resourceFormat
* @param options
* @return
*/
protected <T extends Resource> ResourceRequest<T> issueResourceRequest(String resourceFormat, HttpUriRequest request, byte[] payload) {
return issueResourceRequest(resourceFormat, request, payload, null);
}
/**
* @param resourceFormat
* @param options
* @return
*/
protected <T extends Resource> ResourceRequest<T> issueResourceRequest(String resourceFormat, HttpUriRequest request, byte[] payload, List<Header> headers) {
configureFhirRequest(request, resourceFormat, headers);
HttpResponse response = null;
if(request instanceof HttpEntityEnclosingRequest && payload != null) {
response = sendPayload((HttpEntityEnclosingRequestBase)request, payload, proxy);
} else if (request instanceof HttpEntityEnclosingRequest && payload == null){
throw new EFhirClientException("PUT and POST requests require a non-null payload");
} else {
response = sendRequest(request);
}
T resource = unmarshalReference(response, resourceFormat);
return new ResourceRequest<T>(resource, response.getStatusLine().getStatusCode(), getLocationHeader(response));
}
/**
* Method adds required request headers.
* TODO handle JSON request as well.
*
* @param request
*/
protected void configureFhirRequest(HttpRequest request, String format) {
configureFhirRequest(request, format, null);
}
/**
* Method adds required request headers.
* TODO handle JSON request as well.
*
* @param request
*/
protected void configureFhirRequest(HttpRequest request, String format, List<Header> headers) {
request.addHeader("User-Agent", "Java FHIR Client for FHIR");
}
if (format != null) {
request.addHeader("Accept",format);
request.addHeader("Content-Type", format + ";charset=" + DEFAULT_CHARSET);
}
/**
* @param resourceFormat
* @param options
* @return
*/
protected <T extends Resource> ResourceRequest<T> issueResourceRequest(String resourceFormat, HttpUriRequest request, byte[] payload, List<Header> headers) {
configureFhirRequest(request, resourceFormat, headers);
HttpResponse response = null;
if(request instanceof HttpEntityEnclosingRequest && payload != null) {
response = sendPayload((HttpEntityEnclosingRequestBase)request, payload, proxy);
} else if (request instanceof HttpEntityEnclosingRequest && payload == null){
throw new EFhirClientException("PUT and POST requests require a non-null payload");
} else {
response = sendRequest(request);
}
T resource = unmarshalReference(response, resourceFormat);
return new ResourceRequest<T>(resource, response.getStatusLine().getStatusCode(), getLocationHeader(response));
}
/**
* Method adds required request headers.
* TODO handle JSON request as well.
*
* @param request
*/
protected void configureFhirRequest(HttpRequest request, String format) {
configureFhirRequest(request, format, null);
}
/**
* Method adds required request headers.
* TODO handle JSON request as well.
*
* @param request
*/
protected void configureFhirRequest(HttpRequest request, String format, List<Header> headers) {
request.addHeader("User-Agent", "Java FHIR Client for FHIR");
if (format != null) {
request.addHeader("Accept",format);
request.addHeader("Content-Type", format + ";charset=" + DEFAULT_CHARSET);
}
request.addHeader("Accept-Charset", DEFAULT_CHARSET);
if(headers != null) {
for(Header header : headers) {
request.addHeader(header);
}
}
if(headers != null) {
for(Header header : headers) {
request.addHeader(header);
}
}
setAuth(request);
}
/**
* Method posts request payload
*
* @param request
* @param payload
* @return
*/
}
/**
* Method posts request payload
*
* @param request
* @param payload
* @return
*/
protected HttpResponse sendPayload(HttpEntityEnclosingRequestBase request, byte[] payload, HttpHost proxy) {
HttpResponse response = null;
try {
HttpClient httpclient = new DefaultHttpClient();
if(proxy != null) {
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
}
request.setEntity(new ByteArrayEntity(payload));
log(request);
response = httpclient.execute(request);
} catch(IOException ioe) {
throw new EFhirClientException("Error sending HTTP Post/Put Payload", ioe);
}
return response;
}
/**
*
* @param request
* @param payload
* @return
*/
HttpResponse response = null;
boolean ok = false;
int tryCount = 0;
while (!ok) {
try {
tryCount++;
HttpClient httpclient = new DefaultHttpClient();
if(proxy != null) {
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
}
request.setEntity(new ByteArrayEntity(payload));
log(request);
response = httpclient.execute(request);
ok = true;
} catch(IOException ioe) {
if (tryCount <= retryCount) {
ok = false;
} else {
throw new EFhirClientException("Error sending HTTP Post/Put Payload: "+ioe.getMessage(), ioe);
}
}
}
return response;
}
/**
*
* @param request
* @param payload
* @return
*/
protected HttpResponse sendRequest(HttpUriRequest request) {
HttpResponse response = null;
try {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = null;
try {
HttpClient httpclient = new DefaultHttpClient();
log(request);
HttpParams params = httpclient.getParams();
HttpConnectionParams.setConnectionTimeout(params, timeout);
HttpConnectionParams.setSoTimeout(params, timeout);
if(proxy != null) {
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
}
response = httpclient.execute(request);
} catch(IOException ioe) {
throw new EFhirClientException("Error sending Http Request: "+ioe.getMessage(), ioe);
}
return response;
}
/**
* Unmarshals a resource from the response stream.
*
* @param response
* @return
*/
@SuppressWarnings("unchecked")
HttpParams params = httpclient.getParams();
HttpConnectionParams.setConnectionTimeout(params, timeout);
HttpConnectionParams.setSoTimeout(params, timeout);
if(proxy != null) {
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
}
response = httpclient.execute(request);
} catch(IOException ioe) {
throw new EFhirClientException("Error sending Http Request: "+ioe.getMessage(), ioe);
}
return response;
}
/**
* Unmarshals a resource from the response stream.
*
* @param response
* @return
*/
@SuppressWarnings("unchecked")
protected <T extends Resource> T unmarshalReference(HttpResponse response, String format) {
T resource = null;
OperationOutcome error = null;
T resource = null;
OperationOutcome error = null;
byte[] cnt = log(response);
if (cnt != null) {
try {
resource = (T)getParser(format).parse(cnt);
if (resource instanceof OperationOutcome && hasError((OperationOutcome)resource)) {
error = (OperationOutcome) resource;
}
} catch(IOException ioe) {
if (resource instanceof OperationOutcome && hasError((OperationOutcome)resource)) {
error = (OperationOutcome) resource;
}
} catch(IOException ioe) {
throw new EFhirClientException("Error reading Http Response: "+ioe.getMessage(), ioe);
} catch(Exception e) {
throw new EFhirClientException("Error parsing response message: "+e.getMessage(), e);
}
}
if(error != null) {
} catch(Exception e) {
throw new EFhirClientException("Error parsing response message: "+e.getMessage(), e);
}
}
if(error != null) {
throw new EFhirClientException("Error from server: "+ResourceUtilities.getErrorDescription(error), error);
}
return resource;
}
/**
* Unmarshals Bundle from response stream.
*
* @param response
* @return
*/
}
return resource;
}
/**
* Unmarshals Bundle from response stream.
*
* @param response
* @return
*/
protected Bundle unmarshalFeed(HttpResponse response, String format) {
Bundle feed = null;
byte[] cnt = log(response);
String contentType = response.getHeaders("Content-Type")[0].getValue();
OperationOutcome error = null;
try {
String contentType = response.getHeaders("Content-Type")[0].getValue();
OperationOutcome error = null;
try {
if (cnt != null) {
if(contentType.contains(ResourceFormat.RESOURCE_XML.getHeader()) || contentType.contains("text/xml+fhir")) {
if(contentType.contains(ResourceFormat.RESOURCE_XML.getHeader()) || contentType.contains("text/xml+fhir")) {
Resource rf = getParser(format).parse(cnt);
if (rf instanceof Bundle)
feed = (Bundle) rf;
else if (rf instanceof OperationOutcome && hasError((OperationOutcome) rf)) {
error = (OperationOutcome) rf;
} else {
if (rf instanceof Bundle)
feed = (Bundle) rf;
else if (rf instanceof OperationOutcome && hasError((OperationOutcome) rf)) {
error = (OperationOutcome) rf;
} else {
throw new EFhirClientException("Error reading server response: a resource was returned instead");
}
}
}
} catch(IOException ioe) {
}
}
}
} catch(IOException ioe) {
throw new EFhirClientException("Error reading Http Response", ioe);
} catch(Exception e) {
throw new EFhirClientException("Error parsing response message", e);
}
if(error != null) {
} catch(Exception e) {
throw new EFhirClientException("Error parsing response message", e);
}
if(error != null) {
throw new EFhirClientException("Error from server: "+ResourceUtilities.getErrorDescription(error), error);
}
return feed;
}
}
return feed;
}
private boolean hasError(OperationOutcome oo) {
for (OperationOutcomeIssueComponent t : oo.getIssue())
if (t.getSeverity() == IssueSeverity.ERROR || t.getSeverity() == IssueSeverity.FATAL)
return true;
return false;
for (OperationOutcomeIssueComponent t : oo.getIssue())
if (t.getSeverity() == IssueSeverity.ERROR || t.getSeverity() == IssueSeverity.FATAL)
return true;
return false;
}
protected String getLocationHeader(HttpResponse response) {
String location = null;
if(response.getHeaders("location").length > 0) {//TODO Distinguish between both cases if necessary
location = response.getHeaders("location")[0].getValue();
} else if(response.getHeaders("content-location").length > 0) {
location = response.getHeaders("content-location")[0].getValue();
}
return location;
}
/*****************************************************************
* Client connection methods
* ***************************************************************/
String location = null;
if(response.getHeaders("location").length > 0) {//TODO Distinguish between both cases if necessary
location = response.getHeaders("location")[0].getValue();
} else if(response.getHeaders("content-location").length > 0) {
location = response.getHeaders("content-location")[0].getValue();
}
return location;
}
/*****************************************************************
* Client connection methods
* ***************************************************************/
public HttpURLConnection buildConnection(URI baseServiceUri, String tail) {
try {
HttpURLConnection client = (HttpURLConnection) baseServiceUri.resolve(tail).toURL().openConnection();
return client;
} catch(MalformedURLException mue) {
throw new EFhirClientException("Invalid Service URL", mue);
} catch(IOException ioe) {
throw new EFhirClientException("Unable to establish connection to server: " + baseServiceUri.toString() + tail, ioe);
}
}
try {
HttpURLConnection client = (HttpURLConnection) baseServiceUri.resolve(tail).toURL().openConnection();
return client;
} catch(MalformedURLException mue) {
throw new EFhirClientException("Invalid Service URL", mue);
} catch(IOException ioe) {
throw new EFhirClientException("Unable to establish connection to server: " + baseServiceUri.toString() + tail, ioe);
}
}
public HttpURLConnection buildConnection(URI baseServiceUri, ResourceType resourceType, String id) {
return buildConnection(baseServiceUri, ResourceAddress.buildRelativePathFromResourceType(resourceType, id));
}
/******************************************************************
* Other general helper methods
* ****************************************************************/
return buildConnection(baseServiceUri, ResourceAddress.buildRelativePathFromResourceType(resourceType, id));
}
/******************************************************************
* Other general helper methods
* ****************************************************************/
public <T extends Resource> byte[] getResourceAsByteArray(T resource, boolean pretty, boolean isJson) {
ByteArrayOutputStream baos = null;
byte[] byteArray = null;
try {
baos = new ByteArrayOutputStream();
IParser parser = null;
if(isJson) {
parser = new JsonParser();
} else {
parser = new XmlParser();
}
ByteArrayOutputStream baos = null;
byte[] byteArray = null;
try {
baos = new ByteArrayOutputStream();
IParser parser = null;
if(isJson) {
parser = new JsonParser();
} else {
parser = new XmlParser();
}
parser.setOutputStyle(pretty ? OutputStyle.PRETTY : OutputStyle.NORMAL);
parser.compose(baos, resource);
baos.close();
byteArray = baos.toByteArray();
baos.close();
} catch (Exception e) {
try{
baos.close();
}catch(Exception ex) {
throw new EFhirClientException("Error closing output stream", ex);
}
throw new EFhirClientException("Error converting output stream to byte array", e);
}
return byteArray;
}
parser.compose(baos, resource);
baos.close();
byteArray = baos.toByteArray();
baos.close();
} catch (Exception e) {
try{
baos.close();
}catch(Exception ex) {
throw new EFhirClientException("Error closing output stream", ex);
}
throw new EFhirClientException("Error converting output stream to byte array", e);
}
return byteArray;
}
public byte[] getFeedAsByteArray(Bundle feed, boolean pretty, boolean isJson) {
ByteArrayOutputStream baos = null;
byte[] byteArray = null;
try {
baos = new ByteArrayOutputStream();
IParser parser = null;
if(isJson) {
parser = new JsonParser();
} else {
parser = new XmlParser();
}
ByteArrayOutputStream baos = null;
byte[] byteArray = null;
try {
baos = new ByteArrayOutputStream();
IParser parser = null;
if(isJson) {
parser = new JsonParser();
} else {
parser = new XmlParser();
}
parser.setOutputStyle(pretty ? OutputStyle.PRETTY : OutputStyle.NORMAL);
parser.compose(baos, feed);
baos.close();
byteArray = baos.toByteArray();
baos.close();
} catch (Exception e) {
try{
baos.close();
}catch(Exception ex) {
throw new EFhirClientException("Error closing output stream", ex);
}
throw new EFhirClientException("Error converting output stream to byte array", e);
}
return byteArray;
}
parser.compose(baos, feed);
baos.close();
byteArray = baos.toByteArray();
baos.close();
} catch (Exception e) {
try{
baos.close();
}catch(Exception ex) {
throw new EFhirClientException("Error closing output stream", ex);
}
throw new EFhirClientException("Error converting output stream to byte array", e);
}
return byteArray;
}
public Calendar getLastModifiedResponseHeaderAsCalendarObject(URLConnection serverConnection) {
String dateTime = null;
try {
dateTime = serverConnection.getHeaderField("Last-Modified");
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
Date lastModifiedTimestamp = format.parse(dateTime);
Calendar calendar=Calendar.getInstance();
calendar.setTime(lastModifiedTimestamp);
return calendar;
} catch(ParseException pe) {
throw new EFhirClientException("Error parsing Last-Modified response header " + dateTime, pe);
}
}
String dateTime = null;
try {
dateTime = serverConnection.getHeaderField("Last-Modified");
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", new Locale("en", "US"));
Date lastModifiedTimestamp = format.parse(dateTime);
Calendar calendar=Calendar.getInstance();
calendar.setTime(lastModifiedTimestamp);
return calendar;
} catch(ParseException pe) {
throw new EFhirClientException("Error parsing Last-Modified response header " + dateTime, pe);
}
}
protected IParser getParser(String format) {
if(StringUtils.isBlank(format)) {
format = ResourceFormat.RESOURCE_XML.getHeader();
}
if(format.equalsIgnoreCase("json") || format.equalsIgnoreCase(ResourceFormat.RESOURCE_JSON.getHeader()) || format.equalsIgnoreCase(ResourceFormat.RESOURCE_JSON.getHeader())) {
return new JsonParser();
} else if(format.equalsIgnoreCase("xml") || format.equalsIgnoreCase(ResourceFormat.RESOURCE_XML.getHeader()) || format.equalsIgnoreCase(ResourceFormat.RESOURCE_XML.getHeader())) {
return new XmlParser();
} else {
throw new EFhirClientException("Invalid format: " + format);
}
}
if(StringUtils.isBlank(format)) {
format = ResourceFormat.RESOURCE_XML.getHeader();
}
if(format.equalsIgnoreCase("json") || format.equalsIgnoreCase(ResourceFormat.RESOURCE_JSON.getHeader()) || format.equalsIgnoreCase(ResourceFormat.RESOURCE_JSON.getHeader())) {
return new JsonParser();
} else if(format.equalsIgnoreCase("xml") || format.equalsIgnoreCase(ResourceFormat.RESOURCE_XML.getHeader()) || format.equalsIgnoreCase(ResourceFormat.RESOURCE_XML.getHeader())) {
return new XmlParser();
} else {
throw new EFhirClientException("Invalid format: " + format);
}
}
public Bundle issuePostFeedRequest(URI resourceUri, Map<String, String> parameters, String resourceName, Resource resource, String resourceFormat) throws IOException {
HttpPost httppost = new HttpPost(resourceUri);
String boundary = "----WebKitFormBoundarykbMUo6H8QaUnYtRy";
@ -511,7 +524,7 @@ public class ClientUtils {
HttpResponse response = sendPayload(httppost, encodeFormSubmission(parameters, resourceName, resource, boundary));
return unmarshalFeed(response, resourceFormat);
}
private byte[] encodeFormSubmission(Map<String, String> parameters, String resourceName, Resource resource, String boundary) throws IOException {
ByteArrayOutputStream b = new ByteArrayOutputStream();
OutputStreamWriter w = new OutputStreamWriter(b, "UTF-8");
@ -557,7 +570,7 @@ public class ClientUtils {
}
return response;
}
private void log(HttpUriRequest request) {
if (logger != null) {
List<String> headers = new ArrayList<>();
@ -584,7 +597,7 @@ public class ClientUtils {
logger.logRequest(request.getMethod(), request.getURI().toString(), headers, cnt);
}
}
private byte[] log(HttpResponse response) {
byte[] cnt = null;
try {
@ -611,7 +624,7 @@ public class ClientUtils {
this.logger = logger;
}
/**
* Used for debugging
*
@ -630,5 +643,13 @@ public class ClientUtils {
return value;
}
public int getRetryCount() {
return retryCount;
}
public void setRetryCount(int retryCount) {
this.retryCount = retryCount;
}
}

View File

@ -54,6 +54,7 @@ import org.hl7.fhir.dstu3.model.PrimitiveType;
import org.hl7.fhir.dstu3.model.Resource;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.dstu3.model.ValueSet;
import org.hl7.fhir.utilities.ToolingClientLogger;
import org.hl7.fhir.utilities.Utilities;
/**
@ -92,6 +93,7 @@ public class FHIRToolingClient {
private String base;
private ResourceAddress resourceAddress;
private ResourceFormat preferredResourceFormat;
private HttpHost proxy;
private int maxResultSetSize = -1;//_count
private CapabilityStatement capabilities;
@ -217,6 +219,31 @@ public class FHIRToolingClient {
return result.getPayload();
}
// GET fhir/ValueSet?url=http://hl7.org/fhir/ValueSet/clinical-findings&version=0.8
public <T extends Resource> T getCanonical(Class<T> resourceClass, String canonicalURL) {
ResourceRequest<T> result = null;
try {
result = utils.issueGetResourceRequest(resourceAddress.resolveGetUriFromResourceClassAndCanonical(resourceClass, canonicalURL), getPreferredResourceFormat());
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);//unknown
result.addSuccessStatus(200);//Only one for now
if(result.isUnsuccessfulRequest()) {
throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), (OperationOutcome)result.getPayload());
}
} catch (Exception e) {
handleException("An error has occurred while trying to read this version of the resource", e);
}
Bundle bnd = (Bundle) result.getPayload();
if (bnd.getEntry().size() == 0)
throw new EFhirClientException("No matching resource found for canonical URL '"+canonicalURL+"'");
if (bnd.getEntry().size() > 1)
throw new EFhirClientException("Multiple matching resources found for canonical URL '"+canonicalURL+"'");
return (T) bnd.getEntry().get(0).getResource();
}
public Resource update(Resource resource) {
ResourceRequest<Resource> result = null;
try {
@ -246,35 +273,34 @@ public class FHIRToolingClient {
return result.getPayload();
}
//
// public <T extends Resource> T update(Class<T> resourceClass, T resource, String id) {
// ResourceRequest<T> result = null;
// try {
// List<Header> headers = null;
// result = utils.issuePutRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resourceClass, id),utils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers, proxy);
// result.addErrorStatus(410);//gone
// result.addErrorStatus(404);//unknown
// result.addErrorStatus(405);
// result.addErrorStatus(422);//Unprocessable Entity
// result.addSuccessStatus(200);
// result.addSuccessStatus(201);
// if(result.isUnsuccessfulRequest()) {
// throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), (OperationOutcome)result.getPayload());
// }
// } catch(Exception e) {
// throw new EFhirClientException("An error has occurred while trying to update this resource", e);
// }
// // TODO oe 26.1.2015 could be made nicer if only OperationOutcome locationheader is returned with an operationOutcome would be returned (and not the resource also) we make another read
// try {
// OperationOutcome operationOutcome = (OperationOutcome)result.getPayload();
// ResourceAddress.ResourceVersionedIdentifier resVersionedIdentifier = ResourceAddress.parseCreateLocation(result.getLocation());
// return this.vread(resourceClass, resVersionedIdentifier.getId(),resVersionedIdentifier.getVersionId());
// } catch(ClassCastException e) {
// // if we fall throught we have the correct type already in the create
// }
//
// return result.getPayload();
// }
public <T extends Resource> T update(Class<T> resourceClass, T resource, String id) {
ResourceRequest<T> result = null;
try {
List<Header> headers = null;
result = utils.issuePutRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resourceClass, id),utils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers);
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);
result.addErrorStatus(422);//Unprocessable Entity
result.addSuccessStatus(200);
result.addSuccessStatus(201);
if(result.isUnsuccessfulRequest()) {
throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), (OperationOutcome)result.getPayload());
}
} catch(Exception e) {
throw new EFhirClientException("An error has occurred while trying to update this resource", e);
}
// TODO oe 26.1.2015 could be made nicer if only OperationOutcome locationheader is returned with an operationOutcome would be returned (and not the resource also) we make another read
try {
OperationOutcome operationOutcome = (OperationOutcome)result.getPayload();
ResourceAddress.ResourceVersionedIdentifier resVersionedIdentifier = ResourceAddress.parseCreateLocation(result.getLocation());
return this.vread(resourceClass, resVersionedIdentifier.getId(),resVersionedIdentifier.getVersionId());
} catch(ClassCastException e) {
// if we fall throught we have the correct type already in the create
}
return result.getPayload();
}
//
// public <T extends Resource> boolean delete(Class<T> resourceClass, String id) {
@ -802,4 +828,22 @@ public class FHIRToolingClient {
return (Parameters) utils.issueGetResourceRequest(resourceAddress.resolveMetadataTxCaps(), getPreferredResourceFormat()).getReference();
}
public org.hl7.fhir.utilities.ToolingClientLogger getLogger() {
return utils.getLogger();
}
public void setLogger(ToolingClientLogger logger) {
utils.setLogger(logger);
}
public int getRetryCount() {
return utils.getRetryCount();
}
public void setRetryCount(int retryCount) {
utils.setRetryCount(retryCount);
}
}

View File

@ -40,6 +40,7 @@ import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
@ -114,6 +115,13 @@ public class ResourceAddress {
return baseServiceUri.resolve(nameForClass(resourceClass) +"/"+id+"/_history/"+version);
}
public <T extends Resource> URI resolveGetUriFromResourceClassAndCanonical(Class<T> resourceClass, String canonicalUrl) {
if (canonicalUrl.contains("|"))
return baseServiceUri.resolve(nameForClass(resourceClass)+"?url="+canonicalUrl.substring(0, canonicalUrl.indexOf("|"))+"&version="+canonicalUrl.substring(canonicalUrl.indexOf("|")+1));
else
return baseServiceUri.resolve(nameForClass(resourceClass)+"?url="+canonicalUrl);
}
public URI resolveGetHistoryForAllResources(int count) {
if(count > 0) {
return appendHttpParameter(baseServiceUri.resolve("_history"), "_count", ""+count);
@ -213,6 +221,11 @@ public class ResourceAddress {
return baseServiceUri.resolve(quick ? "metadata?_summary=true" : "metadata");
}
public URI resolveMetadataTxCaps() {
return baseServiceUri.resolve("metadata?mode=terminology");
}
/**
* For now, assume this type of location header structure.
* Generalize later: http://hl7connect.healthintersections.com.au/svc/fhir/318/_history/1
@ -386,7 +399,7 @@ public class ResourceAddress {
}
public static String getCalendarDateInIsoTimeFormat(Calendar calendar) {
SimpleDateFormat format = new SimpleDateFormat("YYYY-MM-dd'T'hh:mm:ss");//TODO Move out
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss", new Locale("en", "US"));//TODO Move out
format.setTimeZone(TimeZone.getTimeZone("GMT"));
return format.format(calendar.getTime());
}
@ -417,8 +430,5 @@ public class ResourceAddress {
}
}
public URI resolveMetadataTxCaps() {
return baseServiceUri.resolve("metadata?mode=terminology");
}
}

View File

@ -1,40 +0,0 @@
package org.hl7.fhir.dstu3.utils.client;
/*
Copyright (c) 2011+, HL7, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.List;
public interface ToolingClientLogger {
public void logRequest(String method, String url, List<String> headers, byte[] body);
public void logResponse(String outcome, List<String> headers, byte[] body);
}

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>org.hl7.fhir.core</artifactId>
<version>5.0.6-SNAPSHOT</version>
<version>5.0.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -37,7 +37,7 @@ import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.hl7.fhir.r4.utils.client.ToolingClientLogger;
import org.hl7.fhir.utilities.ToolingClientLogger;
import org.hl7.fhir.utilities.Utilities;
public class HTMLClientLogger implements ToolingClientLogger {

View File

@ -53,7 +53,6 @@ import org.hl7.fhir.r4.model.Bundle.BundleType;
import org.hl7.fhir.r4.model.Bundle.HTTPVerb;
import org.hl7.fhir.r4.model.Resource;
import org.hl7.fhir.r4.utils.client.FHIRToolingClient;
import org.hl7.fhir.r4.utils.client.ToolingClientLogger;
import org.hl7.fhir.utilities.IniFile;
import org.hl7.fhir.utilities.Utilities;

View File

@ -50,6 +50,7 @@ import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.codec.binary.Base64;
@ -84,6 +85,7 @@ import org.hl7.fhir.r4.model.OperationOutcome.OperationOutcomeIssueComponent;
import org.hl7.fhir.r4.model.Resource;
import org.hl7.fhir.r4.model.ResourceType;
import org.hl7.fhir.r4.utils.ResourceUtilities;
import org.hl7.fhir.utilities.ToolingClientLogger;
/**
* Helper class handling lower level HTTP transport concerns.
@ -100,6 +102,7 @@ public class ClientUtils {
private String username;
private String password;
private ToolingClientLogger logger;
private int retryCount;
public HttpHost getProxy() {
return proxy;
@ -277,16 +280,26 @@ public class ClientUtils {
*/
protected HttpResponse sendPayload(HttpEntityEnclosingRequestBase request, byte[] payload, HttpHost proxy) {
HttpResponse response = null;
try {
HttpClient httpclient = new DefaultHttpClient();
if(proxy != null) {
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
boolean ok = false;
int tryCount = 0;
while (!ok) {
try {
tryCount++;
HttpClient httpclient = new DefaultHttpClient();
if(proxy != null) {
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
}
request.setEntity(new ByteArrayEntity(payload));
log(request);
response = httpclient.execute(request);
ok = true;
} catch(IOException ioe) {
if (tryCount <= retryCount) {
ok = false;
} else {
throw new EFhirClientException("Error sending HTTP Post/Put Payload: "+ioe.getMessage(), ioe);
}
}
request.setEntity(new ByteArrayEntity(payload));
log(request);
response = httpclient.execute(request);
} catch(IOException ioe) {
throw new EFhirClientException("Error sending HTTP Post/Put Payload", ioe);
}
return response;
}
@ -480,7 +493,7 @@ public class ClientUtils {
String dateTime = null;
try {
dateTime = serverConnection.getHeaderField("Last-Modified");
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", new Locale("en", "US"));
Date lastModifiedTimestamp = format.parse(dateTime);
Calendar calendar=Calendar.getInstance();
calendar.setTime(lastModifiedTimestamp);
@ -585,7 +598,7 @@ public class ClientUtils {
logger.logRequest(request.getMethod(), request.getURI().toString(), headers, cnt);
}
}
private byte[] log(HttpResponse response) {
byte[] cnt = null;
try {
@ -612,7 +625,7 @@ public class ClientUtils {
this.logger = logger;
}
/**
* Used for debugging
*
@ -631,5 +644,13 @@ public class ClientUtils {
return value;
}
public int getRetryCount() {
return retryCount;
}
public void setRetryCount(int retryCount) {
this.retryCount = retryCount;
}
}

View File

@ -54,6 +54,7 @@ import org.hl7.fhir.r4.model.Resource;
import org.hl7.fhir.r4.model.StringType;
import org.hl7.fhir.r4.model.TerminologyCapabilities;
import org.hl7.fhir.r4.model.ValueSet;
import org.hl7.fhir.utilities.ToolingClientLogger;
import org.hl7.fhir.utilities.Utilities;
/**
@ -829,5 +830,13 @@ public class FHIRToolingClient {
utils.setLogger(logger);
}
public int getRetryCount() {
return utils.getRetryCount();
}
public void setRetryCount(int retryCount) {
utils.setRetryCount(retryCount);
}
}

View File

@ -40,6 +40,7 @@ import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
@ -397,7 +398,7 @@ public class ResourceAddress {
}
public static String getCalendarDateInIsoTimeFormat(Calendar calendar) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");//TODO Move out
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss", new Locale("en", "US"));//TODO Move out
format.setTimeZone(TimeZone.getTimeZone("GMT"));
return format.format(calendar.getTime());
}

View File

@ -1,40 +0,0 @@
package org.hl7.fhir.r4.utils.client;
/*
Copyright (c) 2011+, HL7, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.List;
public interface ToolingClientLogger {
public void logRequest(String method, String url, List<String> headers, byte[] body);
public void logResponse(String outcome, List<String> headers, byte[] body);
}

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>org.hl7.fhir.core</artifactId>
<version>5.0.6-SNAPSHOT</version>
<version>5.0.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -94,8 +94,8 @@ import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorCla
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
import org.hl7.fhir.r5.terminologies.ValueSetExpanderSimple;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.client.ToolingClientLogger;
import org.hl7.fhir.utilities.OIDUtils;
import org.hl7.fhir.utilities.ToolingClientLogger;
import org.hl7.fhir.utilities.TranslationServices;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities;

View File

@ -37,7 +37,7 @@ import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.hl7.fhir.r5.utils.client.ToolingClientLogger;
import org.hl7.fhir.utilities.ToolingClientLogger;
import org.hl7.fhir.utilities.Utilities;
public class HTMLClientLogger implements ToolingClientLogger {

View File

@ -37,7 +37,7 @@ import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.hl7.fhir.r5.utils.client.ToolingClientLogger;
import org.hl7.fhir.utilities.ToolingClientLogger;
import org.hl7.fhir.utilities.Utilities;
public class TextClientLogger implements ToolingClientLogger {

View File

@ -38,7 +38,7 @@ import org.hl7.fhir.r5.model.CapabilityStatement;
import org.hl7.fhir.r5.model.Parameters;
import org.hl7.fhir.r5.model.TerminologyCapabilities;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.utils.client.ToolingClientLogger;
import org.hl7.fhir.utilities.ToolingClientLogger;
public interface TerminologyClient {
public String getAddress();
@ -46,8 +46,9 @@ public interface TerminologyClient {
public ValueSet expandValueset(ValueSet vs, Parameters p, Map<String, String> params) throws FHIRException;
public Parameters validateCS(Parameters pin) throws FHIRException;
public Parameters validateVS(Parameters pin) throws FHIRException;
public void setTimeout(int i) throws FHIRException;
public void setLogger(ToolingClientLogger txLog) throws FHIRException;
public TerminologyClient setTimeout(int i) throws FHIRException;
public TerminologyClient setLogger(ToolingClientLogger txLog) throws FHIRException;
public TerminologyClient setRetryCount(int retryCount) throws FHIRException;
public CapabilityStatement getCapabilitiesStatementQuick() throws FHIRException;
public Parameters lookupCode(Map<String, String> params) throws FHIRException;
}

View File

@ -85,6 +85,7 @@ import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.ResourceType;
import org.hl7.fhir.r5.utils.ResourceUtilities;
import org.hl7.fhir.utilities.ToolingClientLogger;
/**
* Helper class handling lower level HTTP transport concerns.
@ -101,6 +102,7 @@ public class ClientUtils {
private String username;
private String password;
private ToolingClientLogger logger;
private int retryCount;
public HttpHost getProxy() {
return proxy;
@ -278,7 +280,11 @@ public class ClientUtils {
*/
protected HttpResponse sendPayload(HttpEntityEnclosingRequestBase request, byte[] payload, HttpHost proxy) {
HttpResponse response = null;
boolean ok = false;
int tryCount = 0;
while (!ok) {
try {
tryCount++;
HttpClient httpclient = new DefaultHttpClient();
if(proxy != null) {
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
@ -286,9 +292,15 @@ public class ClientUtils {
request.setEntity(new ByteArrayEntity(payload));
log(request);
response = httpclient.execute(request);
ok = true;
} catch(IOException ioe) {
throw new EFhirClientException("Error sending HTTP Post/Put Payload", ioe);
if (tryCount <= retryCount) {
ok = false;
} else {
throw new EFhirClientException("Error sending HTTP Post/Put Payload: "+ioe.getMessage(), ioe);
}
}
}
return response;
}
@ -632,5 +644,13 @@ public class ClientUtils {
return value;
}
public int getRetryCount() {
return retryCount;
}
public void setRetryCount(int retryCount) {
this.retryCount = retryCount;
}
}

View File

@ -1,9 +1,5 @@
package org.hl7.fhir.r5.utils.client;
/*
Copyright (c) 2011+, HL7, Inc.
All rights reserved.
@ -54,6 +50,7 @@ import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.r5.model.TerminologyCapabilities;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.utilities.ToolingClientLogger;
import org.hl7.fhir.utilities.Utilities;
/**
@ -245,35 +242,64 @@ public class FHIRToolingClient {
return (T) bnd.getEntry().get(0).getResource();
}
//
// public <T extends Resource> T update(Class<T> resourceClass, T resource, String id) {
// ResourceRequest<T> result = null;
// try {
// List<Header> headers = null;
// result = utils.issuePutRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resourceClass, id),utils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers, proxy);
// result.addErrorStatus(410);//gone
// result.addErrorStatus(404);//unknown
// result.addErrorStatus(405);
// result.addErrorStatus(422);//Unprocessable Entity
// result.addSuccessStatus(200);
// result.addSuccessStatus(201);
// if(result.isUnsuccessfulRequest()) {
// throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), (OperationOutcome)result.getPayload());
// }
// } catch(Exception e) {
// throw new EFhirClientException("An error has occurred while trying to update this resource", e);
// }
// // TODO oe 26.1.2015 could be made nicer if only OperationOutcome locationheader is returned with an operationOutcome would be returned (and not the resource also) we make another read
// try {
// OperationOutcome operationOutcome = (OperationOutcome)result.getPayload();
// ResourceAddress.ResourceVersionedIdentifier resVersionedIdentifier = ResourceAddress.parseCreateLocation(result.getLocation());
// return this.vread(resourceClass, resVersionedIdentifier.getId(),resVersionedIdentifier.getVersionId());
// } catch(ClassCastException e) {
// // if we fall throught we have the correct type already in the create
// }
//
// return result.getPayload();
// }
public Resource update(Resource resource) {
ResourceRequest<Resource> result = null;
try {
List<Header> headers = null;
result = utils.issuePutRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resource.getClass(), resource.getId()),utils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers);
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);
result.addErrorStatus(422);//Unprocessable Entity
result.addSuccessStatus(200);
result.addSuccessStatus(201);
if(result.isUnsuccessfulRequest()) {
throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), (OperationOutcome)result.getPayload());
}
} catch(Exception e) {
throw new EFhirClientException("An error has occurred while trying to update this resource", e);
}
// TODO oe 26.1.2015 could be made nicer if only OperationOutcome locationheader is returned with an operationOutcome would be returned (and not the resource also) we make another read
try {
OperationOutcome operationOutcome = (OperationOutcome)result.getPayload();
ResourceAddress.ResourceVersionedIdentifier resVersionedIdentifier = ResourceAddress.parseCreateLocation(result.getLocation());
return this.vread(resource.getClass(), resVersionedIdentifier.getId(),resVersionedIdentifier.getVersionId());
} catch(ClassCastException e) {
// if we fall throught we have the correct type already in the create
}
return result.getPayload();
}
public <T extends Resource> T update(Class<T> resourceClass, T resource, String id) {
ResourceRequest<T> result = null;
try {
List<Header> headers = null;
result = utils.issuePutRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resourceClass, id),utils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), getPreferredResourceFormat(), headers);
result.addErrorStatus(410);//gone
result.addErrorStatus(404);//unknown
result.addErrorStatus(405);
result.addErrorStatus(422);//Unprocessable Entity
result.addSuccessStatus(200);
result.addSuccessStatus(201);
if(result.isUnsuccessfulRequest()) {
throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), (OperationOutcome)result.getPayload());
}
} catch(Exception e) {
throw new EFhirClientException("An error has occurred while trying to update this resource", e);
}
// TODO oe 26.1.2015 could be made nicer if only OperationOutcome locationheader is returned with an operationOutcome would be returned (and not the resource also) we make another read
try {
OperationOutcome operationOutcome = (OperationOutcome)result.getPayload();
ResourceAddress.ResourceVersionedIdentifier resVersionedIdentifier = ResourceAddress.parseCreateLocation(result.getLocation());
return this.vread(resourceClass, resVersionedIdentifier.getId(),resVersionedIdentifier.getVersionId());
} catch(ClassCastException e) {
// if we fall throught we have the correct type already in the create
}
return result.getPayload();
}
//
// public <T extends Resource> boolean delete(Class<T> resourceClass, String id) {
@ -800,5 +826,13 @@ public class FHIRToolingClient {
utils.setLogger(logger);
}
public int getRetryCount() {
return utils.getRetryCount();
}
public void setRetryCount(int retryCount) {
utils.setRetryCount(retryCount);
}
}

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>org.hl7.fhir.core</artifactId>
<version>5.0.6-SNAPSHOT</version>
<version>5.0.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>org.hl7.fhir.core</artifactId>
<version>5.0.6-SNAPSHOT</version>
<version>5.0.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.r5.utils.client;
package org.hl7.fhir.utilities;
/*
Copyright (c) 2011+, HL7, Inc.

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>org.hl7.fhir.core</artifactId>
<version>5.0.6-SNAPSHOT</version>
<version>5.0.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>org.hl7.fhir.core</artifactId>
<version>5.0.6-SNAPSHOT</version>
<version>5.0.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -2,6 +2,11 @@ package org.hl7.fhir.validation;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.convertors.*;
import org.hl7.fhir.convertors.loaders.R2016MayToR5Loader;
import org.hl7.fhir.convertors.loaders.R2ToR5Loader;
import org.hl7.fhir.convertors.loaders.R3ToR5Loader;
import org.hl7.fhir.convertors.loaders.R4ToR5Loader;
import org.hl7.fhir.convertors.txClient.TerminologyClientFactory;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.conformance.ProfileUtilities;
@ -823,7 +828,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
res = new org.hl7.fhir.dstu2.formats.JsonParser().parse(new ByteArrayInputStream(content));
else
throw new Exception("Unsupported format for "+fn);
VersionConvertorAdvisor50 advisor = new org.hl7.fhir.convertors.IGR2ConvertorAdvisor5();
VersionConvertorAdvisor50 advisor = new org.hl7.fhir.convertors.misc.IGR2ConvertorAdvisor5();
r = VersionConvertor_10_50.convertResource(res, advisor);
} else if (version.equals(Constants.VERSION) || "current".equals(version)) {
if (fn.endsWith(".xml") && !fn.endsWith("template.xml"))
@ -1687,7 +1692,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
else
throw new Exception("Unsupported format for "+fn);
} else if (version.startsWith("1.0")) {
VersionConvertorAdvisor50 advisor = new org.hl7.fhir.convertors.IGR2ConvertorAdvisor5();
VersionConvertorAdvisor50 advisor = new org.hl7.fhir.convertors.misc.IGR2ConvertorAdvisor5();
org.hl7.fhir.dstu2.model.Resource res = VersionConvertor_10_50.convertResource(r, advisor);
if (fn.endsWith(".xml") && !fn.endsWith("template.xml"))
new org.hl7.fhir.dstu2.formats.JsonParser().setOutputStyle(org.hl7.fhir.dstu2.formats.IParser.OutputStyle.PRETTY).compose(s, res);

View File

@ -1,7 +1,8 @@
package org.hl7.fhir.conversion.tests;
import com.google.gson.*;
import org.hl7.fhir.convertors.R3ToR4Loader;
import org.hl7.fhir.convertors.loaders.R3ToR4Loader;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;

View File

@ -46,10 +46,10 @@ import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.fhir.ucum.UcumEssenceService;
import org.hl7.fhir.convertors.R2016MayToR5Loader;
import org.hl7.fhir.convertors.R2ToR5Loader;
import org.hl7.fhir.convertors.R3ToR5Loader;
import org.hl7.fhir.convertors.R4ToR5Loader;
import org.hl7.fhir.convertors.loaders.R2016MayToR5Loader;
import org.hl7.fhir.convertors.loaders.R2ToR5Loader;
import org.hl7.fhir.convertors.loaders.R3ToR5Loader;
import org.hl7.fhir.convertors.loaders.R4ToR5Loader;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.context.SimpleWorkerContext;
import org.hl7.fhir.r5.context.IWorkerContext.IContextResourceLoader;

View File

@ -13,7 +13,7 @@
each other. It is fine to bump the point version of this POM without affecting
HAPI FHIR.
-->
<version>5.0.6-SNAPSHOT</version>
<version>5.0.7-SNAPSHOT</version>
<properties>
<hapi_fhir_version>5.0.0</hapi_fhir_version>

View File

@ -1,7 +1,7 @@
@echo off
set oldver=5.0.5
set newver=5.0.6
set oldver=5.0.6
set newver=5.0.7
echo ..
echo =========================================================================