001package ca.uhn.fhir.jaxrs.client; 002 003import ca.uhn.fhir.i18n.Msg; 004import java.util.List; 005import java.util.Map; 006 007import javax.ws.rs.client.Client; 008import javax.ws.rs.client.ClientBuilder; 009 010/* 011 * #%L 012 * HAPI FHIR JAX-RS Server 013 * %% 014 * Copyright (C) 2014 - 2022 Smile CDR, Inc. 015 * %% 016 * Licensed under the Apache License, Version 2.0 (the "License"); 017 * you may not use this file except in compliance with the License. 018 * You may obtain a copy of the License at 019 * 020 * http://www.apache.org/licenses/LICENSE-2.0 021 * 022 * Unless required by applicable law or agreed to in writing, software 023 * distributed under the License is distributed on an "AS IS" BASIS, 024 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 025 * See the License for the specific language governing permissions and 026 * limitations under the License. 027 * #L% 028 */ 029 030import ca.uhn.fhir.context.FhirContext; 031import ca.uhn.fhir.rest.api.RequestTypeEnum; 032import ca.uhn.fhir.rest.client.api.Header; 033import ca.uhn.fhir.rest.client.api.IHttpClient; 034import ca.uhn.fhir.rest.client.impl.RestfulClientFactory; 035 036/** 037 * A Restful Client Factory, based on Jax Rs 038 * Default Jax-Rs client is NOT thread safe in static context, you should create a new factory every time or 039 * use a specific Jax-Rs client implementation which managed connection pool. 040 * @author Peter Van Houte | peter.vanhoute@agfa.com | Agfa Healthcare 041 */ 042public class JaxRsRestfulClientFactory extends RestfulClientFactory { 043 044 private Client myNativeClient; 045 private List<Class<?>> registeredComponents; 046 047 /** 048 * Constructor. Note that you must set the {@link FhirContext} manually using {@link #setFhirContext(FhirContext)} if this constructor is used! 049 */ 050 public JaxRsRestfulClientFactory() { 051 super(); 052 } 053 054 /** 055 * Constructor 056 * 057 * @param theFhirContext 058 * The context 059 */ 060 public JaxRsRestfulClientFactory(FhirContext theFhirContext) { 061 super(theFhirContext); 062 } 063 064 public synchronized Client getNativeClientClient() { 065 if (myNativeClient == null) { 066 ClientBuilder builder = ClientBuilder.newBuilder(); 067 myNativeClient = builder.build(); 068 } 069 070 if (registeredComponents != null && !registeredComponents.isEmpty()) { 071 for (Class<?> c : registeredComponents) { 072 myNativeClient = myNativeClient.register(c); 073 } 074 } 075 076 return myNativeClient; 077 } 078 079 @Override 080 public synchronized IHttpClient getHttpClient(StringBuilder url, Map<String, List<String>> theIfNoneExistParams, String theIfNoneExistString, RequestTypeEnum theRequestType, List<Header> theHeaders) { 081 Client client = getNativeClientClient(); 082 return new JaxRsHttpClient(client, url, theIfNoneExistParams, theIfNoneExistString, theRequestType, theHeaders); 083 } 084 085 /*** 086 * Not supported with default Jax-Rs client implementation 087 * @param theHost 088 * The host (or null to disable proxying, as is the default) 089 * @param thePort 090 */ 091 @Override 092 public void setProxy(String theHost, Integer thePort) { 093 throw new UnsupportedOperationException(Msg.code(605) + "Proxies are not supported yet in JAX-RS client"); 094 } 095 096 /** 097 * Only accept clients of type javax.ws.rs.client.Client 098 * Can be used to set a specific Client implementation 099 * @param theHttpClient 100 */ 101 @Override 102 public synchronized void setHttpClient(Object theHttpClient) { 103 this.myNativeClient = (Client) theHttpClient; 104 } 105 106 /** 107 * Register a list of Jax-Rs component (provider, filter...) 108 * @param components list of Jax-Rs components to register 109 */ 110 public void register(List<Class<?>> components) { 111 registeredComponents = components; 112 } 113 114 115 @Override 116 protected synchronized JaxRsHttpClient getHttpClient(String theServerBase) { 117 return new JaxRsHttpClient(getNativeClientClient(), new StringBuilder(theServerBase), null, null, null, null); 118 } 119 120 @Override 121 protected void resetHttpClient() { 122 if (myNativeClient != null) 123 myNativeClient.close(); // close client to avoid memory leak 124 myNativeClient = null; 125 } 126 127}