
001package org.hl7.fhir.convertors.txClient; 002 003import java.io.IOException; 004import java.net.URISyntaxException; 005import java.util.EnumSet; 006import java.util.HashMap; 007import java.util.Map; 008 009import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50; 010import org.hl7.fhir.exceptions.FHIRException; 011import org.hl7.fhir.r4.model.Resource; 012import org.hl7.fhir.r4.utils.client.EFhirClientException; 013import org.hl7.fhir.r4.utils.client.FHIRToolingClient; 014import org.hl7.fhir.r5.formats.IParser.OutputStyle; 015import org.hl7.fhir.r5.formats.JsonParser; 016import org.hl7.fhir.r5.model.Bundle; 017import org.hl7.fhir.r5.model.CanonicalResource; 018import org.hl7.fhir.r5.model.CapabilityStatement; 019import org.hl7.fhir.r5.model.OperationOutcome; 020import org.hl7.fhir.r5.model.Parameters; 021import org.hl7.fhir.r5.model.TerminologyCapabilities; 022import org.hl7.fhir.r5.model.ValueSet; 023import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent; 024import org.hl7.fhir.r5.terminologies.client.ITerminologyClient; 025import org.hl7.fhir.r5.utils.client.network.ClientHeaders; 026import org.hl7.fhir.utilities.FhirPublication; 027import org.hl7.fhir.utilities.ToolingClientLogger; 028import org.hl7.fhir.utilities.Utilities; 029import org.hl7.fhir.utilities.http.HTTPHeader; 030 031public class TerminologyClientR4 implements ITerminologyClient { 032 033 private final FHIRToolingClient client; 034 private ClientHeaders clientHeaders; 035 private String id; 036 private ITerminologyConversionLogger logger; 037 038 public TerminologyClientR4(String id, String address, String userAgent) throws URISyntaxException { 039 this.client = new FHIRToolingClient(address, userAgent); 040 setClientHeaders(new ClientHeaders()); 041 this.id = id; 042 } 043 044 public TerminologyClientR4(String id, String address, String userAgent, ClientHeaders clientHeaders) throws URISyntaxException { 045 this.client = new FHIRToolingClient(address, userAgent); 046 setClientHeaders(clientHeaders); 047 this.id = id; 048 } 049 050 @Override 051 public String getId() { 052 return id; 053 } 054 055 056 057 public EnumSet<FhirPublication> supportableVersions() { 058 // todo 059 return EnumSet.range(FhirPublication.STU3, FhirPublication.R5); 060 } 061 062 public void setAllowedVersions(EnumSet<FhirPublication> versions) { 063 // todo 064 } 065 066 public EnumSet<FhirPublication> getAllowedVersions() { 067 return null; // todo 068 } 069 070 public FhirPublication getActualVersion() { 071 return FhirPublication.R4; 072 } 073 074 075 @Override 076 public TerminologyCapabilities getTerminologyCapabilities() throws FHIRException { 077 return (TerminologyCapabilities) convertResource("getTerminologyCapabilities.response", client.getTerminologyCapabilities()); 078 } 079 080 @Override 081 public String getAddress() { 082 return client.getAddress(); 083 } 084 085 @Override 086 public ValueSet expandValueset(ValueSet vs, Parameters p) throws FHIRException { 087 org.hl7.fhir.r4.model.ValueSet vs2 = vs == null ? null : (org.hl7.fhir.r4.model.ValueSet) convertResource("expandValueset.valueset", vs); 088 org.hl7.fhir.r4.model.Parameters p2 = p == null ? null : (org.hl7.fhir.r4.model.Parameters) convertResource("expandValueset.parameters", p); 089 try { 090 vs2 = client.expandValueset(vs2, p2); // todo: second parameter 091 return (ValueSet) convertResource("expandValueset.response", vs2); 092 } catch (org.hl7.fhir.r4.utils.client.EFhirClientException e) { 093 if (e.getServerErrors().size() > 0) { 094 throw new org.hl7.fhir.r5.utils.client.EFhirClientException(e.getCode(), e.getMessage(), (org.hl7.fhir.r5.model.OperationOutcome) convertResource("expandValueset.error", e.getServerErrors().get(0))); 095 } else { 096 throw new org.hl7.fhir.r5.utils.client.EFhirClientException(e.getCode(), e.getMessage()); 097 } 098 } 099 } 100 101 102 @Override 103 public Parameters validateCS(Parameters pin) throws FHIRException { 104 try { 105 org.hl7.fhir.r4.model.Parameters p2 = (org.hl7.fhir.r4.model.Parameters) convertResource("validateCS.request", pin); 106 p2 = client.operateType(org.hl7.fhir.r4.model.CodeSystem.class, "validate-code", p2); 107 return (Parameters) convertResource("validateCS.response", p2); 108 } catch (EFhirClientException e) { 109 if (e.getServerErrors().size() == 1) { 110 OperationOutcome op = (OperationOutcome) convertResource("validateCS.error", e.getServerErrors().get(0)); 111 throw new org.hl7.fhir.r5.utils.client.EFhirClientException(e.getCode(), e.getMessage(), op, e); 112 } else { 113 throw new org.hl7.fhir.r5.utils.client.EFhirClientException(e.getCode(), e.getMessage(), e); 114 } 115 } catch (IOException e) { 116 throw new FHIRException(e); 117 } 118 } 119 120 121 @Override 122 public Parameters subsumes(Parameters pin) throws FHIRException { 123 try { 124 org.hl7.fhir.r4.model.Parameters p2 = (org.hl7.fhir.r4.model.Parameters) convertResource("subsumes.request", pin); 125 p2 = client.operateType(org.hl7.fhir.r4.model.CodeSystem.class, "subsumes", p2); 126 return (Parameters) convertResource("subsumes.response", p2); 127 } catch (EFhirClientException e) { 128 if (e.getServerErrors().size() == 1) { 129 OperationOutcome op = (OperationOutcome) convertResource("subsumes.error", e.getServerErrors().get(0)); 130 throw new org.hl7.fhir.r5.utils.client.EFhirClientException(e.getCode(), e.getMessage(), op, e); 131 } else { 132 throw new org.hl7.fhir.r5.utils.client.EFhirClientException(e.getCode(), e.getMessage(), e); 133 } 134 } catch (IOException e) { 135 throw new FHIRException(e); 136 } 137 } 138 139 @Override 140 public Parameters validateVS(Parameters pin) throws FHIRException { 141 try { 142 org.hl7.fhir.r4.model.Parameters p2 = (org.hl7.fhir.r4.model.Parameters) convertResource("validateVS.request", pin); 143 p2 = client.operateType(org.hl7.fhir.r4.model.ValueSet.class, "validate-code", p2); 144 return (Parameters) convertResource("validateVS.response", p2); 145 } catch (EFhirClientException e) { 146 if (e.getServerErrors().size() == 1) { 147 OperationOutcome op = (OperationOutcome) convertResource("validateVS.error", e.getServerErrors().get(0)); 148 throw new org.hl7.fhir.r5.utils.client.EFhirClientException(e.getCode(), e.getMessage(), op, e); 149 } else { 150 throw new org.hl7.fhir.r5.utils.client.EFhirClientException(e.getCode(), e.getMessage(), e); 151 } 152 } catch (IOException e) { 153 throw new FHIRException(e); 154 } 155 } 156 157 @Override 158 public ITerminologyClient setTimeoutFactor(int i) { 159 client.setTimeoutFactor(i); 160 return this; 161 } 162 163 @Override 164 public ToolingClientLogger getLogger() { 165 return client.getLogger(); 166 } 167 168 @Override 169 public ITerminologyClient setLogger(ToolingClientLogger txLog) { 170 client.setLogger(txLog); 171 return this; 172 } 173 174 @Override 175 public ITerminologyClient setRetryCount(int retryCount) throws FHIRException { 176 client.setRetryCount(retryCount); 177 return this; 178 } 179 180 @Override 181 public CapabilityStatement getCapabilitiesStatementQuick() throws FHIRException { 182 return (CapabilityStatement) convertResource("getCapabilitiesStatementQuick.response", client.getCapabilitiesStatementQuick()); 183 } 184 185 @Override 186 public CapabilityStatement getCapabilitiesStatement() throws FHIRException { 187 return (CapabilityStatement) convertResource("getCapabilitiesStatement.response", client.getCapabilitiesStatement()); 188 } 189 190 @Override 191 public Parameters lookupCode(Map<String, String> params) throws FHIRException { 192 return (Parameters) convertResource("lookupCode.response", client.lookupCode(params)); 193 } 194 195 @Override 196 public Parameters lookupCode(Parameters params) throws FHIRException { 197 return (Parameters) convertResource("lookupCode.response", client.lookupCode((org.hl7.fhir.r4.model.Parameters) convertResource("lookupCode.request", params))); 198 } 199 200 @Override 201 public int getRetryCount() throws FHIRException { 202 return client.getRetryCount(); 203 } 204 205 @Override 206 public Bundle validateBatch(Bundle batch) { 207 org.hl7.fhir.r4.model.Bundle result = client.transaction((org.hl7.fhir.r4.model.Bundle) convertResource("validateBatch.request", batch)); 208 return result == null ? null : (Bundle) convertResource("validateBatch.response", result); 209 } 210 211 @Override 212 public CanonicalResource read(String type, String id) { 213 Class<Resource> t; 214 try { 215 t = (Class<Resource>) Class.forName("org.hl7.fhir.r4.model." + type);// todo: do we have to deal with any resource renaming? Use cases are limited... 216 } catch (ClassNotFoundException e) { 217 throw new FHIRException("Unable to fetch resources of type " + type + " in R2"); 218 } 219 org.hl7.fhir.r4.model.Resource r4 = client.read(t, id); 220 if (r4 == null) { 221 throw new FHIRException("Unable to fetch resource " + Utilities.pathURL(getAddress(), type, id)); 222 } 223 org.hl7.fhir.r5.model.Resource r5 = convertResource("read.result", r4); 224 if (r5 == null) { 225 throw new FHIRException("Unable to convert resource " + Utilities.pathURL(getAddress(), type, id) + " to R5 (internal representation)"); 226 } 227 if (!(r5 instanceof CanonicalResource)) { 228 throw new FHIRException("Unable to convert resource " + Utilities.pathURL(getAddress(), type, id) + " to R5 canonical resource (internal representation)"); 229 } 230 return (CanonicalResource) r5; 231 } 232 233 @Override 234 public Iterable<HTTPHeader> getClientHeaders() { 235 return clientHeaders.headers(); 236 } 237 238 @Override 239 public ITerminologyClient setClientHeaders(ClientHeaders clientHeaders) { 240 this.clientHeaders = clientHeaders; 241 if (this.clientHeaders != null) { 242 this.client.setClientHeaders(this.clientHeaders.headers()); 243 } 244 this.client.setVersionInMimeTypes(true); 245 return this; 246 } 247 248 @Override 249 public ITerminologyClient setUserAgent(String userAgent) { 250 client.setUserAgent(userAgent); 251 return this; 252 } 253 254 @Override 255 public String getUserAgent() { 256 return client.getUserAgent(); 257 } 258 259 @Override 260 public String getServerVersion() { 261 return client.getServerVersion(); 262 } 263 264 265 @Override 266 public ITerminologyClient setAcceptLanguage(String lang) { 267 client.setAcceptLanguage(lang); 268 return this; 269 } 270 271 @Override 272 public ITerminologyClient setContentLanguage(String lang) { 273 client.setContentLanguage(lang); 274 return this; 275 } 276 277 @Override 278 public int getUseCount() { 279 return client.getUseCount(); 280 } 281 282 @Override 283 public Bundle search(String type, String criteria) { 284 org.hl7.fhir.r4.model.Bundle result = client.search(type, criteria); 285 return result == null ? null : (Bundle) convertResource("search.result", result); 286 } 287 288 @Override 289 public Parameters translate(Parameters params) throws FHIRException { 290 return (Parameters) convertResource("translate.response", client.translate((org.hl7.fhir.r4.model.Parameters) convertResource("translate.request", params))); 291 } 292 293 private org.hl7.fhir.r4.model.Resource convertResource(String name, org.hl7.fhir.r5.model.Resource resource) { 294 if (logger != null) { 295 try { 296 logger.log(name, resource.fhirType(), "r5", new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).composeBytes(resource)); 297 } catch (IOException e) { 298 throw new FHIRException(e); 299 } 300 } 301 org.hl7.fhir.r4.model.Resource res = VersionConvertorFactory_40_50.convertResource(resource); 302 if (logger != null) { 303 try { 304 logger.log(name, resource.fhirType(), "r4", new org.hl7.fhir.r4.formats.JsonParser().setOutputStyle(org.hl7.fhir.r4.formats.IParser.OutputStyle.PRETTY).composeBytes(res)); 305 } catch (IOException e) { 306 throw new FHIRException(e); 307 } 308 } 309 return res; 310 } 311 312 private org.hl7.fhir.r5.model.Resource convertResource(String name, org.hl7.fhir.r4.model.Resource resource) { 313 if (logger != null && name != null) { 314 try { 315 logger.log(name, resource.fhirType(), "r4", new org.hl7.fhir.r4.formats.JsonParser().setOutputStyle(org.hl7.fhir.r4.formats.IParser.OutputStyle.PRETTY).composeBytes(resource)); 316 } catch (IOException e) { 317 throw new FHIRException(e); 318 } 319 } 320 org.hl7.fhir.r5.model.Resource res = VersionConvertorFactory_40_50.convertResource(resource); 321 if (logger != null && name != null) { 322 try { 323 logger.log(name, resource.fhirType(), "r5", new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).composeBytes(res)); 324 } catch (IOException e) { 325 throw new FHIRException(e); 326 } 327 } 328 return res; 329 } 330 331 @Override 332 public void setConversionLogger(ITerminologyConversionLogger logger) { 333 this.logger = logger; 334 } 335 336}