
001package org.hl7.fhir.dstu2.utils.client; 002 003/* 004 Copyright (c) 2011+, HL7, Inc. 005 All rights reserved. 006 007 Redistribution and use in source and binary forms, with or without modification, 008 are permitted provided that the following conditions are met: 009 010 * Redistributions of source code must retain the above copyright notice, this 011 list of conditions and the following disclaimer. 012 * Redistributions in binary form must reproduce the above copyright notice, 013 this list of conditions and the following disclaimer in the documentation 014 and/or other materials provided with the distribution. 015 * Neither the name of HL7 nor the names of its contributors may be used to 016 endorse or promote products derived from this software without specific 017 prior written permission. 018 019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 022 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 023 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 024 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 025 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 026 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 027 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 028 POSSIBILITY OF SUCH DAMAGE. 029 030*/ 031 032import java.net.URI; 033import java.net.URISyntaxException; 034import java.util.HashMap; 035import java.util.List; 036import java.util.Map; 037 038import org.apache.http.Header; 039import org.apache.http.HttpHost; 040import org.hl7.fhir.dstu2.model.Bundle; 041import org.hl7.fhir.dstu2.model.Coding; 042import org.hl7.fhir.dstu2.model.ConceptMap; 043import org.hl7.fhir.dstu2.model.Conformance; 044import org.hl7.fhir.dstu2.model.OperationOutcome; 045import org.hl7.fhir.dstu2.model.Parameters; 046import org.hl7.fhir.dstu2.model.Parameters.ParametersParameterComponent; 047import org.hl7.fhir.dstu2.model.PrimitiveType; 048import org.hl7.fhir.dstu2.model.Resource; 049import org.hl7.fhir.dstu2.model.StringType; 050import org.hl7.fhir.dstu2.model.ValueSet; 051import org.hl7.fhir.utilities.FHIRBaseToolingClient; 052import org.hl7.fhir.utilities.ToolingClientLogger; 053import org.hl7.fhir.utilities.Utilities; 054 055/** 056 * Very Simple RESTful client. This is purely for use in the standalone tools 057 * jar packages. It doesn't support many features, only what the tools need. 058 * 059 * To use, initialize class and set base service URI as follows: 060 * 061 * <pre> 062 * <code> 063 * FHIRSimpleClient fhirClient = new FHIRSimpleClient(); 064 * fhirClient.initialize("http://my.fhir.domain/myServiceRoot"); 065 * </code> 066 * </pre> 067 * 068 * Default Accept and Content-Type headers are application/xml+fhir and 069 * application/j+fhir. 070 * 071 * These can be changed by invoking the following setter functions: 072 * 073 * <pre> 074 * <code> 075 * setPreferredResourceFormat() 076 * setPreferredFeedFormat() 077 * </code> 078 * </pre> 079 * 080 * TODO Review all sad paths. 081 * 082 * @author Claude Nanjo 083 * 084 */ 085@Deprecated 086public class FHIRToolingClient extends FHIRBaseToolingClient { 087 088 public static final String DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ssK"; 089 public static final String DATE_FORMAT = "yyyy-MM-dd"; 090 public static final String hostKey = "http.proxyHost"; 091 public static final String portKey = "http.proxyPort"; 092 093 private String base; 094 private ResourceAddress resourceAddress; 095 private ResourceFormat preferredResourceFormat; 096 private HttpHost proxy; 097 private int maxResultSetSize = -1;// _count 098 private Conformance conf; 099 private ClientUtils utils = null; 100 private int useCount; 101 102 protected ClientUtils getClientUtils() { 103 return new ClientUtils(); 104 } 105 106 // Pass enpoint for client - URI 107 public FHIRToolingClient(String baseServiceUrl, String userAgent) throws URISyntaxException { 108 preferredResourceFormat = ResourceFormat.RESOURCE_XML; 109 utils = getClientUtils(); 110 utils.setUserAgent(userAgent); 111 initialize(baseServiceUrl); 112 } 113 114 public void initialize(String baseServiceUrl) throws URISyntaxException { 115 base = baseServiceUrl; 116 resourceAddress = new ResourceAddress(baseServiceUrl); 117 this.maxResultSetSize = -1; 118 checkConformance(); 119 } 120 121 private void checkConformance() { 122 try { 123 conf = getConformanceStatementQuick(); 124 } catch (Throwable e) { 125 } 126 } 127 128 public String getPreferredResourceFormat() { 129 return preferredResourceFormat.getHeader(); 130 } 131 132 public void setPreferredResourceFormat(ResourceFormat resourceFormat) { 133 preferredResourceFormat = resourceFormat; 134 } 135 136 public int getMaximumRecordCount() { 137 return maxResultSetSize; 138 } 139 140 public void setMaximumRecordCount(int maxResultSetSize) { 141 this.maxResultSetSize = maxResultSetSize; 142 } 143 144 public Conformance getConformanceStatement() throws EFhirClientException { 145 if (conf != null) 146 return conf; 147 return getConformanceStatement(false); 148 } 149 150 public Conformance getConformanceStatement(boolean useOptionsVerb) { 151 Conformance conformance = null; 152 try { 153 if (useOptionsVerb) { 154 conformance = (Conformance) utils 155 .issueOptionsRequest(resourceAddress.getBaseServiceUri(), withVer(getPreferredResourceFormat(), "1.0"), timeoutNormal) 156 .getReference();// TODO fix this 157 } else { 158 conformance = (Conformance) utils.issueGetResourceRequest(resourceAddress.resolveMetadataUri(false), 159 withVer(getPreferredResourceFormat(), "1.0"), timeoutNormal).getReference(); 160 } 161 } catch (Exception e) { 162 handleException("An error has occurred while trying to fetch the server's conformance statement", e); 163 } 164 return conformance; 165 } 166 167 public Conformance getConformanceStatementQuick() throws EFhirClientException { 168 if (conf != null) 169 return conf; 170 return getConformanceStatementQuick(false); 171 } 172 173 public Conformance getConformanceStatementQuick(boolean useOptionsVerb) { 174 Conformance conformance = null; 175 try { 176 if (useOptionsVerb) { 177 conformance = (Conformance) utils 178 .issueOptionsRequest(resourceAddress.getBaseServiceUri(), withVer(getPreferredResourceFormat(), "1.0"), timeoutNormal) 179 .getReference();// TODO fix this 180 } else { 181 conformance = (Conformance) utils.issueGetResourceRequest(resourceAddress.resolveMetadataUri(true), 182 withVer(getPreferredResourceFormat(), "1.0"), timeoutNormal).getReference(); 183 } 184 } catch (Exception e) { 185 handleException("An error has occurred while trying to fetch the server's conformance statement", e); 186 } 187 return conformance; 188 } 189 190 public <T extends Resource> T read(Class<T> resourceClass, String id) {// TODO Change this to AddressableResource 191 recordUse(); 192 ResourceRequest<T> result = null; 193 try { 194 result = utils.issueGetResourceRequest(resourceAddress.resolveGetUriFromResourceClassAndId(resourceClass, id), 195 withVer(getPreferredResourceFormat(), "1.0"), timeoutNormal); 196 result.addErrorStatus(410);// gone 197 result.addErrorStatus(404);// unknown 198 result.addSuccessStatus(200);// Only one for now 199 if (result.isUnsuccessfulRequest()) { 200 throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), 201 (OperationOutcome) result.getPayload()); 202 } 203 } catch (Exception e) { 204 handleException("An error has occurred while trying to read this resource", e); 205 } 206 return result.getPayload(); 207 } 208 209 public <T extends Resource> T vread(Class<T> resourceClass, String id, String version) { 210 recordUse(); 211 ResourceRequest<T> result = null; 212 try { 213 result = utils.issueGetResourceRequest( 214 resourceAddress.resolveGetUriFromResourceClassAndIdAndVersion(resourceClass, id, version), 215 withVer(getPreferredResourceFormat(), "1.0"), timeoutNormal); 216 result.addErrorStatus(410);// gone 217 result.addErrorStatus(404);// unknown 218 result.addErrorStatus(405);// unknown 219 result.addSuccessStatus(200);// Only one for now 220 if (result.isUnsuccessfulRequest()) { 221 throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), 222 (OperationOutcome) result.getPayload()); 223 } 224 } catch (Exception e) { 225 handleException("An error has occurred while trying to read this version of the resource", e); 226 } 227 return result.getPayload(); 228 } 229 230 // GET 231 // fhir/ValueSet?url=http://hl7.org/fhir/ValueSet/clinical-findings&version=0.8 232 233 public <T extends Resource> T getCanonical(Class<T> resourceClass, String canonicalURL) { 234 recordUse(); 235 ResourceRequest<T> result = null; 236 try { 237 result = utils.issueGetResourceRequest( 238 resourceAddress.resolveGetUriFromResourceClassAndCanonical(resourceClass, canonicalURL), 239 withVer(getPreferredResourceFormat(), "1.0"), timeoutNormal); 240 result.addErrorStatus(410);// gone 241 result.addErrorStatus(404);// unknown 242 result.addErrorStatus(405);// unknown 243 result.addSuccessStatus(200);// Only one for now 244 if (result.isUnsuccessfulRequest()) { 245 throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), 246 (OperationOutcome) result.getPayload()); 247 } 248 } catch (Exception e) { 249 handleException("An error has occurred while trying to read this version of the resource", e); 250 } 251 Bundle bnd = (Bundle) result.getPayload(); 252 if (bnd.getEntry().size() == 0) 253 throw new EFhirClientException("No matching resource found for canonical URL '" + canonicalURL + "'"); 254 if (bnd.getEntry().size() > 1) 255 throw new EFhirClientException("Multiple matching resources found for canonical URL '" + canonicalURL + "'"); 256 return (T) bnd.getEntry().get(0).getResource(); 257 } 258 259 public Resource update(Resource resource) { 260 recordUse(); 261 ResourceRequest<Resource> result = null; 262 try { 263 264 result = utils.issuePutRequest( 265 resourceAddress.resolveGetUriFromResourceClassAndId(resource.getClass(), resource.getId()), 266 utils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), 267 withVer(getPreferredResourceFormat(), "1.0"), null, timeoutOperation); 268 result.addErrorStatus(410);// gone 269 result.addErrorStatus(404);// unknown 270 result.addErrorStatus(405); 271 result.addErrorStatus(422);// Unprocessable Entity 272 result.addSuccessStatus(200); 273 result.addSuccessStatus(201); 274 if (result.isUnsuccessfulRequest()) { 275 throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), 276 (OperationOutcome) result.getPayload()); 277 } 278 } catch (Exception e) { 279 throw new EFhirClientException("An error has occurred while trying to update this resource", e); 280 } 281 // TODO oe 26.1.2015 could be made nicer if only OperationOutcome locationheader 282 // is returned with an operationOutcome would be returned (and not the resource 283 // also) we make another read 284 try { 285 OperationOutcome operationOutcome = (OperationOutcome) result.getPayload(); 286 ResourceAddress.ResourceVersionedIdentifier resVersionedIdentifier = ResourceAddress 287 .parseCreateLocation(result.getLocation()); 288 return this.vread(resource.getClass(), resVersionedIdentifier.getId(), resVersionedIdentifier.getVersionId()); 289 } catch (ClassCastException e) { 290 // if we fall throught we have the correct type already in the create 291 } 292 293 return result.getPayload(); 294 } 295 296 public <T extends Resource> T update(Class<T> resourceClass, T resource, String id) { 297 recordUse(); 298 ResourceRequest<T> result = null; 299 try { 300 result = utils.issuePutRequest( 301 resourceAddress.resolveGetUriFromResourceClassAndId(resourceClass, id), 302 utils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), 303 withVer(getPreferredResourceFormat(), "1.0"), 304 null, 305 timeoutOperation); 306 result.addErrorStatus(410);// gone 307 result.addErrorStatus(404);// unknown 308 result.addErrorStatus(405); 309 result.addErrorStatus(422);// Unprocessable Entity 310 result.addSuccessStatus(200); 311 result.addSuccessStatus(201); 312 if (result.isUnsuccessfulRequest()) { 313 throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), 314 (OperationOutcome) result.getPayload()); 315 } 316 } catch (Exception e) { 317 throw new EFhirClientException("An error has occurred while trying to update this resource", e); 318 } 319 // TODO oe 26.1.2015 could be made nicer if only OperationOutcome locationheader 320 // is returned with an operationOutcome would be returned (and not the resource 321 // also) we make another read 322 try { 323 OperationOutcome operationOutcome = (OperationOutcome) result.getPayload(); 324 ResourceAddress.ResourceVersionedIdentifier resVersionedIdentifier = ResourceAddress 325 .parseCreateLocation(result.getLocation()); 326 return this.vread(resourceClass, resVersionedIdentifier.getId(), resVersionedIdentifier.getVersionId()); 327 } catch (ClassCastException e) { 328 // if we fall throught we have the correct type already in the create 329 } 330 331 return result.getPayload(); 332 } 333 334 335 336 public <T extends Resource> Parameters operateType(Class<T> resourceClass, String name, Parameters params) { 337 recordUse(); 338 boolean complex = false; 339 for (ParametersParameterComponent p : params.getParameter()) 340 complex = complex || !(p.getValue() instanceof PrimitiveType); 341 Parameters searchResults = null; 342 String ps = ""; 343 if (!complex) 344 for (ParametersParameterComponent p : params.getParameter()) 345 if (p.getValue() instanceof PrimitiveType) 346 ps += p.getName() + "=" + Utilities.encodeUriParam(((PrimitiveType) p.getValue()).asStringValue()) + "&"; 347 ResourceRequest<T> result; 348 if (complex) 349 result = utils.issuePostRequest(resourceAddress.resolveOperationURLFromClass(resourceClass, name, ps), 350 utils.getResourceAsByteArray(params, false, isJson(getPreferredResourceFormat())), 351 withVer(getPreferredResourceFormat(), "1.0"), timeoutLong); 352 else 353 result = utils.issueGetResourceRequest(resourceAddress.resolveOperationURLFromClass(resourceClass, name, ps), 354 withVer(getPreferredResourceFormat(), "1.0"), timeoutLong); 355 result.addErrorStatus(410);// gone 356 result.addErrorStatus(404);// unknown 357 result.addSuccessStatus(200);// Only one for now 358 if (result.isUnsuccessfulRequest()) 359 throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), 360 (OperationOutcome) result.getPayload()); 361 if (result.getPayload() instanceof Parameters) 362 return (Parameters) result.getPayload(); 363 else { 364 Parameters p_out = new Parameters(); 365 p_out.addParameter().setName("return").setResource(result.getPayload()); 366 return p_out; 367 } 368 } 369 370 public Bundle transaction(Bundle batch) { 371 recordUse(); 372 Bundle transactionResult = null; 373 try { 374 transactionResult = utils.postBatchRequest(resourceAddress.getBaseServiceUri(), 375 utils.getFeedAsByteArray(batch, false, isJson(getPreferredResourceFormat())), withVer(getPreferredResourceFormat(), "1.0"), 376 timeoutNormal + batch.getEntry().size()); 377 } catch (Exception e) { 378 handleException("An error occurred trying to process this transaction request", e); 379 } 380 return transactionResult; 381 } 382 383 @SuppressWarnings("unchecked") 384 public <T extends Resource> OperationOutcome validate(Class<T> resourceClass, T resource, String id) { 385 recordUse(); 386 ResourceRequest<T> result = null; 387 try { 388 result = utils.issuePostRequest(resourceAddress.resolveValidateUri(resourceClass, id), 389 utils.getResourceAsByteArray(resource, false, isJson(getPreferredResourceFormat())), 390 withVer(getPreferredResourceFormat(), "1.0"), 3); 391 result.addErrorStatus(400);// gone 392 result.addErrorStatus(422);// Unprocessable Entity 393 result.addSuccessStatus(200);// OK 394 if (result.isUnsuccessfulRequest()) { 395 throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), 396 (OperationOutcome) result.getPayload()); 397 } 398 } catch (Exception e) { 399 handleException("An error has occurred while trying to validate this resource", e); 400 } 401 return (OperationOutcome) result.getPayload(); 402 } 403 404 405 /** 406 * Helper method to prevent nesting of previously thrown EFhirClientExceptions. If the e param is an instance of 407 * EFhirClientException, it will be rethrown. Otherwise, a new EFhirClientException will be thrown with e as the 408 * cause. 409 * 410 * @param message The EFhirClientException message. 411 * @param e The exception. 412 * @throws EFhirClientException representing the exception. 413 */ 414 protected void handleException(String message, Exception e) throws EFhirClientException { 415 if (e instanceof EFhirClientException) { 416 throw (EFhirClientException) e; 417 } else { 418 throw new EFhirClientException(message, e); 419 } 420 } 421 422 /** 423 * Helper method to determine whether desired resource representation is Json or 424 * XML. 425 * 426 * @param format the format to check 427 * @return true if JSON, false if XML 428 */ 429 protected boolean isJson(String format) { 430 boolean isJson = false; 431 if (format.toLowerCase().contains("json")) { 432 isJson = true; 433 } 434 return isJson; 435 } 436 437 public Bundle fetchFeed(String url) { 438 recordUse(); 439 Bundle feed = null; 440 try { 441 feed = utils.issueGetFeedRequest(new URI(url), getPreferredResourceFormat()); 442 } catch (Exception e) { 443 handleException("An error has occurred while trying to read a bundle", e); 444 } 445 return feed; 446 } 447 448 public Parameters lookupCode(Map<String, String> params) { 449 recordUse(); 450 ResourceRequest<Resource> result = utils.issueGetResourceRequest( 451 resourceAddress.resolveOperationUri(ValueSet.class, "lookup", params), withVer(getPreferredResourceFormat(), "1.0"), 452 timeoutNormal); 453 result.addErrorStatus(410);// gone 454 result.addErrorStatus(404);// unknown 455 result.addErrorStatus(405); 456 result.addErrorStatus(422);// Unprocessable Entity 457 result.addSuccessStatus(200); 458 result.addSuccessStatus(201); 459 if (result.isUnsuccessfulRequest()) { 460 throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), 461 (OperationOutcome) result.getPayload()); 462 } 463 return (Parameters) result.getPayload(); 464 } 465 466 public Parameters lookupCode(Parameters p) { 467 recordUse(); 468 ResourceRequest<Resource> result = utils.issuePostRequest( 469 resourceAddress.resolveOperationUri(ValueSet.class, "lookup"), 470 utils.getResourceAsByteArray(p, false, isJson(getPreferredResourceFormat())), 471 withVer(getPreferredResourceFormat(), "1.0"), 472 timeoutNormal); 473 result.addErrorStatus(410);// gone 474 result.addErrorStatus(404);// unknown 475 result.addErrorStatus(405); 476 result.addErrorStatus(422);// Unprocessable Entity 477 result.addSuccessStatus(200); 478 result.addSuccessStatus(201); 479 if (result.isUnsuccessfulRequest()) { 480 throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), 481 (OperationOutcome) result.getPayload()); 482 } 483 return (Parameters) result.getPayload(); 484 } 485 486 public Parameters translate(Parameters p) { 487 recordUse(); 488 ResourceRequest<Resource> result = utils.issuePostRequest( 489 resourceAddress.resolveOperationUri(ConceptMap.class, "translate"), 490 utils.getResourceAsByteArray(p, false, isJson(getPreferredResourceFormat())), 491 withVer(getPreferredResourceFormat(), "1.0"), 492 timeoutNormal); 493 result.addErrorStatus(410);// gone 494 result.addErrorStatus(404);// unknown 495 result.addErrorStatus(405); 496 result.addErrorStatus(422);// Unprocessable Entity 497 result.addSuccessStatus(200); 498 result.addSuccessStatus(201); 499 if (result.isUnsuccessfulRequest()) { 500 throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), 501 (OperationOutcome) result.getPayload()); 502 } 503 return (Parameters) result.getPayload(); 504 } 505 506 public ValueSet expandValueset(ValueSet source, Parameters expParams) { 507 recordUse(); 508 509 Parameters p = expParams == null ? new Parameters() : expParams.copy(); 510 p.addParameter().setName("valueSet").setResource(source); 511 ResourceRequest<Resource> result = utils.issuePostRequest( 512 resourceAddress.resolveOperationUri(ValueSet.class, "expand"), 513 utils.getResourceAsByteArray(p, false, isJson(getPreferredResourceFormat())), withVer(getPreferredResourceFormat(), "1.0"), 514 null, 4); 515 result.addErrorStatus(410); // gone 516 result.addErrorStatus(404); // unknown 517 result.addErrorStatus(405); 518 result.addErrorStatus(422); // Unprocessable Entity 519 result.addSuccessStatus(200); 520 result.addSuccessStatus(201); 521 if (result.isUnsuccessfulRequest()) { 522 throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), 523 (OperationOutcome) result.getPayload()); 524 } 525 return (ValueSet) result.getPayload(); 526 } 527 528 public String getAddress() { 529 return base; 530 } 531 532 public ConceptMap initializeClosure(String name) { 533 recordUse(); 534 Parameters params = new Parameters(); 535 params.addParameter().setName("name").setValue(new StringType(name)); 536 537 ResourceRequest<Resource> result = utils.issuePostRequest( 538 resourceAddress.resolveOperationUri(null, "closure", new HashMap<String, String>()), 539 utils.getResourceAsByteArray(params, false, isJson(getPreferredResourceFormat())), withVer(getPreferredResourceFormat(), "1.0"), 540 null, timeoutNormal); 541 result.addErrorStatus(410);// gone 542 result.addErrorStatus(404);// unknown 543 result.addErrorStatus(405); 544 result.addErrorStatus(422);// Unprocessable Entity 545 result.addSuccessStatus(200); 546 result.addSuccessStatus(201); 547 if (result.isUnsuccessfulRequest()) { 548 throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), 549 (OperationOutcome) result.getPayload()); 550 } 551 return (ConceptMap) result.getPayload(); 552 } 553 554 public ConceptMap updateClosure(String name, Coding coding) { 555 recordUse(); 556 Parameters params = new Parameters(); 557 params.addParameter().setName("name").setValue(new StringType(name)); 558 params.addParameter().setName("concept").setValue(coding); 559 560 ResourceRequest<Resource> result = utils.issuePostRequest( 561 resourceAddress.resolveOperationUri(null, "closure", new HashMap<String, String>()), 562 utils.getResourceAsByteArray(params, false, isJson(getPreferredResourceFormat())), withVer(getPreferredResourceFormat(), "1.0"), 563 null, timeoutOperation); 564 result.addErrorStatus(410);// gone 565 result.addErrorStatus(404);// unknown 566 result.addErrorStatus(405); 567 result.addErrorStatus(422);// Unprocessable Entity 568 result.addSuccessStatus(200); 569 result.addSuccessStatus(201); 570 if (result.isUnsuccessfulRequest()) { 571 throw new EFhirClientException("Server returned error code " + result.getHttpStatus(), 572 (OperationOutcome) result.getPayload()); 573 } 574 return (ConceptMap) result.getPayload(); 575 } 576 577 public int getTimeout() { 578 return utils.getTimeout(); 579 } 580 581 public void setTimeout(int timeout) { 582 utils.setTimeout(timeout); 583 } 584 585 public Parameters getTerminologyCapabilities() { 586 return (Parameters) utils 587 .issueGetResourceRequest(resourceAddress.resolveMetadataTxCaps(), withVer(getPreferredResourceFormat(), "1.0"), timeoutNormal) 588 .getReference(); 589 } 590 591 public org.hl7.fhir.utilities.ToolingClientLogger getLogger() { 592 return utils.getLogger(); 593 } 594 595 public void setLogger(ToolingClientLogger logger) { 596 utils.setLogger(logger); 597 } 598 599 public int getRetryCount() { 600 return utils.getRetryCount(); 601 } 602 603 public void setRetryCount(int retryCount) { 604 utils.setRetryCount(retryCount); 605 } 606 607 public String getUserAgent() { 608 return utils.getUserAgent(); 609 } 610 611 public void setUserAgent(String userAgent) { 612 utils.setUserAgent(userAgent); 613 } 614 615 public String getServerVersion() { 616 return conf == null ? null : conf.getSoftware().getVersion(); 617 } 618 619 public void setContentLanguage(String lang) { 620 utils.setContentLanguage(lang); 621 } 622 623 public void setAcceptLanguage(String lang) { 624 utils.setAcceptLanguage(lang); 625 } 626 627 public int getUseCount() { 628 return useCount; 629 } 630 631 private void recordUse() { 632 useCount++; 633 } 634 635 public Bundle search(String type, String criteria) { 636 recordUse(); 637 return fetchFeed(Utilities.pathURL(base, type+criteria)); 638 } 639 640}