
001/* 002 * #%L 003 * HAPI FHIR - Client Framework 004 * %% 005 * Copyright (C) 2014 - 2023 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.rest.client.apache; 021 022import ca.uhn.fhir.context.FhirContext; 023import ca.uhn.fhir.rest.api.RequestTypeEnum; 024import ca.uhn.fhir.rest.client.api.Header; 025import ca.uhn.fhir.rest.client.api.IHttpClient; 026import ca.uhn.fhir.rest.client.impl.RestfulClientFactory; 027import org.apache.http.HttpHost; 028import org.apache.http.auth.AuthScope; 029import org.apache.http.auth.UsernamePasswordCredentials; 030import org.apache.http.client.CredentialsProvider; 031import org.apache.http.client.HttpClient; 032import org.apache.http.client.config.RequestConfig; 033import org.apache.http.impl.client.BasicCredentialsProvider; 034import org.apache.http.impl.client.HttpClientBuilder; 035import org.apache.http.impl.client.HttpClients; 036import org.apache.http.impl.client.ProxyAuthenticationStrategy; 037import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; 038 039import java.util.List; 040import java.util.Map; 041import java.util.concurrent.TimeUnit; 042 043import static org.apache.commons.lang3.StringUtils.isNotBlank; 044 045/** 046 * A Restful Factory to create clients, requests and responses based on the Apache httpclient library. 047 * 048 * @author Peter Van Houte | peter.vanhoute@agfa.com | Agfa Healthcare 049 */ 050public class ApacheRestfulClientFactory extends RestfulClientFactory { 051 052 private HttpClient myHttpClient; 053 private HttpHost myProxy; 054 055 /** 056 * Constructor 057 */ 058 public ApacheRestfulClientFactory() { 059 super(); 060 } 061 062 /** 063 * Constructor 064 * 065 * @param theContext 066 * The context 067 */ 068 public ApacheRestfulClientFactory(FhirContext theContext) { 069 super(theContext); 070 } 071 072 @Override 073 protected synchronized IHttpClient getHttpClient(String theServerBase) { 074 return getHttpClient(new StringBuilder(theServerBase), null, null, null, null); 075 } 076 077 @Override 078 public synchronized IHttpClient getHttpClient(StringBuilder theUrl, Map<String, List<String>> theIfNoneExistParams, 079 String theIfNoneExistString, RequestTypeEnum theRequestType, List<Header> theHeaders) { 080 return new ApacheHttpClient(getNativeHttpClient(), theUrl, theIfNoneExistParams, theIfNoneExistString, theRequestType, theHeaders); 081 } 082 083 public HttpClient getNativeHttpClient() { 084 if (myHttpClient == null) { 085 086 //TODO: Use of a deprecated method should be resolved. 087 RequestConfig defaultRequestConfig = 088 RequestConfig.custom() 089 .setSocketTimeout(getSocketTimeout()) 090 .setConnectTimeout(getConnectTimeout()) 091 .setConnectionRequestTimeout(getConnectionRequestTimeout()) 092 .setStaleConnectionCheckEnabled(true) 093 .setProxy(myProxy) 094 .build(); 095 096 HttpClientBuilder builder = getHttpClientBuilder() 097 .useSystemProperties() 098 .setDefaultRequestConfig(defaultRequestConfig) 099 .disableCookieManagement(); 100 101 PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS); 102 connectionManager.setMaxTotal(getPoolMaxTotal()); 103 connectionManager.setDefaultMaxPerRoute(getPoolMaxPerRoute()); 104 builder.setConnectionManager(connectionManager); 105 106 if (myProxy != null && isNotBlank(getProxyUsername()) && isNotBlank(getProxyPassword())) { 107 CredentialsProvider credsProvider = new BasicCredentialsProvider(); 108 credsProvider.setCredentials(new AuthScope(myProxy.getHostName(), myProxy.getPort()), 109 new UsernamePasswordCredentials(getProxyUsername(), getProxyPassword())); 110 builder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy()); 111 builder.setDefaultCredentialsProvider(credsProvider); 112 } 113 114 myHttpClient = builder.build(); 115 116 } 117 118 return myHttpClient; 119 } 120 121 protected HttpClientBuilder getHttpClientBuilder() { 122 return HttpClients.custom(); 123 } 124 125 @Override 126 protected void resetHttpClient() { 127 this.myHttpClient = null; 128 } 129 130 /** 131 * Only allows to set an instance of type org.apache.http.client.HttpClient 132 * @see ca.uhn.fhir.rest.client.api.IRestfulClientFactory#setHttpClient(Object) 133 */ 134 @Override 135 public synchronized void setHttpClient(Object theHttpClient) { 136 this.myHttpClient = (HttpClient) theHttpClient; 137 } 138 139 @Override 140 public void setProxy(String theHost, Integer thePort) { 141 if (theHost != null) { 142 myProxy = new HttpHost(theHost, thePort, "http"); 143 } else { 144 myProxy = null; 145 } 146 } 147 148}