# Migration to Apache HttpClient 5.0 classic APIs

HttpClient 5.0 releases can be co-located with earlier major versions on the same classpath due to versioned package
namespace and Maven module coordinates.

HttpClient 5.0 classic APIs are largely compatible with HttpClient 4.0 APIs. Major differences are related to connection
management configuration, SSL/TLS and timeout settings when building HttpClient instances.

## Migration steps

-  Add HttpClient 5.0 as a new dependency to the project and optionally remove HttpClient 4.x

-  Remove old `org.apache.http` imports and re-import HttpClient classes from
   `org.apache.hc.httpclient5` package namespace. Most old interfaces and classes should resolve automatically. One
   notable exception is `HttpEntityEnclosingRequest` interface In HttpClient 5.0 one can enclose a request entity with
   any HTTP method even if violates semantic of the method.

-  There will be compilation errors due to API incompatibilities between version series 4.x and 5.x mostly related to
   SSL/TLS and timeout settings and `CloseableHttpClient` instance creation. Several modifications are likely to be
   necessary.

-  Use `PoolingHttpClientConnectionManagerBuilder` class to create connection managers with custom parameters

-  Use `SSLConnectionSocketFactoryBuilder` class to create SSL connection socket factories with custom parameters

-  Explicitly specify TLSv1.2 or TLSv1.3 in order to disable older less secure versions of the SSL/TLS protocol. Please note
   all SSL versions are excluded by default.

-  Use `Timeout` class to define timeouts.

-  Use `TimeValue` class to define time values (duration).

-  Optionally choose a connection pool concurrency policy: `STRICT` for strict connection max limit guarantees; `LAX`
   for higher concurrency but with lax connection maximum limit guarantees. With `LAX` policy HttpClient can exceed the
   per route maximum limit under high load and does not enforce the total maximum limit.

-  Optionally choose a connection pool re-use policy: `FILO` to re-use as few connections as possible making it possible
   for connections to become idle and expire; `LIFO` to re-use all connections equally preventing them from becoming
   idle and expiring.

   ```java
   PoolingHttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create()
         .setSSLSocketFactory(SSLConnectionSocketFactoryBuilder.create()
                 .setSslContext(SSLContexts.createSystemDefault())
                 .setTlsVersions(TLS.V_1_3, TLS.V_1_2)
                 .build())
         .setDefaultSocketConfig(SocketConfig.custom()
                 .setSoTimeout(Timeout.ofSeconds(5))
                 .build())
         .setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT)
         .setConnPoolPolicy(PoolReusePolicy.LIFO)
         .setConnectionTimeToLive(TimeValue.ofMinutes(1L))
         .build();
   ```

-  Favor `standard-strict` cookie policy when using HttpClient 5.0.

-  Use response timeout to define the maximum period of inactivity until receipt of response data.

-  All base principles and good practices of HttpClient programing still apply. Always re-use client instances. Client
   instances are expensive to create and are thread safe in both HttpClient 4.x and 5.0 series.

   ```java
   CloseableHttpClient client = HttpClients.custom()
         .setConnectionManager(connectionManager)
         .setDefaultRequestConfig(RequestConfig.custom()
                 .setConnectTimeout(Timeout.ofSeconds(5))
                 .setResponseTimeout(Timeout.ofSeconds(5))
                 .setCookieSpec(StandardCookieSpec.STRICT)
                 .build())
         .build();
   
   CookieStore cookieStore = new BasicCookieStore();
   
   CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
   
   HttpClientContext clientContext = HttpClientContext.create();
   clientContext.setCookieStore(cookieStore);
   clientContext.setCredentialsProvider(credentialsProvider);
   clientContext.setRequestConfig(RequestConfig.custom()
         .setConnectTimeout(Timeout.ofSeconds(10))
         .setResponseTimeout(Timeout.ofSeconds(10))
         .build());
   
   JsonFactory jsonFactory = new JsonFactory();
   ObjectMapper objectMapper = new ObjectMapper(jsonFactory);
   
   HttpPost httpPost = new HttpPost("https://httpbin.org/post");
   
   List<NameValuePair> requestData = Arrays.asList(
         new BasicNameValuePair("name1", "value1"),
         new BasicNameValuePair("name2", "value2"));
   httpPost.setEntity(HttpEntities.create(outstream -> {
     objectMapper.writeValue(outstream, requestData);
     outstream.flush();
   }, ContentType.APPLICATION_JSON));
   ```

-  HTTP response messages in HttpClient 5.x no longer have a status line. Use response code directly.

   ```java
   JsonNode responseData = client.execute(httpPost, response -> {
     if (response.getCode() >= 300) {
         throw new ClientProtocolException(new StatusLine(response).toString());
     }
     final HttpEntity responseEntity = response.getEntity();
     if (responseEntity == null) {
         return null;
     }
     try (InputStream inputStream = responseEntity.getContent()) {
         return objectMapper.readTree(inputStream);
     }
   });
   System.out.println(responseData);
   ```

-  `CloseableHttpClient` instances should be closed when no longer needed or about to go out of score.

   ```java
   client.close();
   ```
