package com.codahale.metrics.httpclient;

import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.MetricRegistryListener;
import com.codahale.metrics.Timer;
import org.apache.http.HttpRequest;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class InstrumentedHttpClientsTest {
    private final HttpClientMetricNameStrategy metricNameStrategy =
            mock(HttpClientMetricNameStrategy.class);
    private final MetricRegistryListener registryListener =
            mock(MetricRegistryListener.class);
    private final MetricRegistry metricRegistry = new MetricRegistry();
    private final HttpClient client =
            InstrumentedHttpClients.custom(metricRegistry, metricNameStrategy).disableAutomaticRetries().build();

    @Before
    public void setUp() throws Exception {
        metricRegistry.addListener(registryListener);
    }

    @Test
    public void registersExpectedMetricsGivenNameStrategy() throws Exception {
        final HttpGet get = new HttpGet("http://example.com?q=anything");
        final String metricName = "some.made.up.metric.name";

        when(metricNameStrategy.getNameFor(any(), any(HttpRequest.class)))
                .thenReturn(metricName);

        client.execute(get);

        verify(registryListener).onTimerAdded(eq(metricName), any(Timer.class));
    }

    @Test
    public void registersExpectedExceptionMetrics() throws Exception {
        ServerSocket server = new ServerSocket();
        server.bind(new InetSocketAddress("localhost", 0));
        final HttpGet get = new HttpGet("http://localhost:" + server.getLocalPort() + "/");
        final String requestMetricName = "request";
        final String exceptionMetricName = "exception";

        Thread serverThread = new Thread(() -> {
            try {
                final Socket socket = server.accept();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        serverThread.start();

        when(metricNameStrategy.getNameFor(any(), any(HttpRequest.class)))
                .thenReturn(requestMetricName);
        when(metricNameStrategy.getNameFor(any(), any(Exception.class)))
                .thenReturn(exceptionMetricName);

        try {
            client.execute(get);
            fail();
        } catch (NoHttpResponseException expected) {
            assertThat(metricRegistry.getMeters()).containsKey("exception");
        } finally {
            serverThread.interrupt();
            serverThread.join();
        }
    }
}

@@ -162,24 +162,110 @@
 rics.Timer;%0A
+import com.sun.net.httpserver.HttpExchange;%0Aimport com.sun.net.httpserver.HttpServer;%0A
 import org.a
@@ -490,111 +490,29 @@
 ava.
-io.IOException;%0Aimport java.net.InetSocketAddress;%0Aimport java.net.ServerSocket;%0Aimport java.net.Socket
+net.InetSocketAddress
 ;%0A%0Ai
@@ -1991,30 +1991,32 @@
     
+Http
 Server
-Socket s
+ httpS
 erver = 
 new 
@@ -2015,47 +2015,25 @@
 r = 
-new 
+Http
 Server
-Socket();%0A        server.bind
+.create
 (new
@@ -2055,25 +2055,16 @@
 ess(
-%22localhost%22
+0)
 , 0)
-)
 ;
+%0A
 %0A   
@@ -2122,17 +2122,21 @@
 ost:%22 + 
-s
+httpS
 erver.ge
@@ -2140,13 +2140,21 @@
 .get
-Local
+Address().get
 Port
@@ -2285,151 +2285,57 @@
     
-Thread serverThread = new Thread(() -%3E %7B%0A            try %7B%0A                final Socket socket = server.accept();%0A                socket.
+httpServer.createContext(%22/%22, HttpExchange::
 close
-(
 );%0A 
@@ -2345,121 +2345,18 @@
     
-    %7D catch (IOException e) %7B%0A                e.printStackTrace();%0A            %7D%0A        %7D);%0A        serverThread
+httpServer
 .sta
@@ -2842,64 +2842,25 @@
     
-serverThread.interrupt();%0A            serverThread.join(
+httpServer.stop(0
 );%0A 

Use a real HTTP server in tests for the HTTP client