diff options
3 files changed, 52 insertions, 3 deletions
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java index a33278c7e02..ef552d87cff 100644 --- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java +++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/JettyHttpServer.java @@ -71,6 +71,7 @@ public class JettyHttpServer extends AbstractServerProvider { String METHOD_DIMENSION = "httpMethod"; String SCHEME_DIMENSION = "scheme"; String REQUEST_TYPE_DIMENSION = "requestType"; + String CLIENT_IP_DIMENSION = "clientIp"; String NUM_OPEN_CONNECTIONS = "serverNumOpenConnections"; String NUM_CONNECTIONS_OPEN_MAX = "serverConnectionsOpenMax"; diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/SslHandshakeFailedListener.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/SslHandshakeFailedListener.java index 75df82036a2..9ced933105d 100644 --- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/SslHandshakeFailedListener.java +++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/server/jetty/SslHandshakeFailedListener.java @@ -6,6 +6,7 @@ import com.yahoo.jdisc.http.server.jetty.JettyHttpServer.Metrics; import org.eclipse.jetty.io.ssl.SslHandshakeListener; import javax.net.ssl.SSLHandshakeException; +import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.function.Predicate; @@ -38,11 +39,16 @@ class SslHandshakeFailedListener implements SslHandshakeListener { String metricName = SslHandshakeFailure.fromSslHandshakeException((SSLHandshakeException) throwable) .map(SslHandshakeFailure::metricName) .orElse(Metrics.SSL_HANDSHAKE_FAILURE_UNKNOWN); - metric.add(metricName, 1L, metric.createContext(createDimensions())); + metric.add(metricName, 1L, metric.createContext(createDimensions(event))); } - private Map<String, Object> createDimensions() { - return Map.of(Metrics.NAME_DIMENSION, connectorName, Metrics.PORT_DIMENSION, listenPort); + private Map<String, Object> createDimensions(Event event) { + Map<String, Object> dimensions = new HashMap<>(); + dimensions.put(Metrics.NAME_DIMENSION, connectorName); + dimensions.put(Metrics.PORT_DIMENSION, listenPort); + Optional.ofNullable(event.getSSLEngine().getPeerHost()) + .ifPresent(clientIp -> dimensions.put(Metrics.CLIENT_IP_DIMENSION, clientIp)); + return Map.copyOf(dimensions); } private enum SslHandshakeFailure { diff --git a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/SslHandshakeFailedListenerTest.java b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/SslHandshakeFailedListenerTest.java new file mode 100644 index 00000000000..20f050d715d --- /dev/null +++ b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/server/jetty/SslHandshakeFailedListenerTest.java @@ -0,0 +1,42 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.jdisc.http.server.jetty; + +import com.yahoo.jdisc.Metric; +import org.eclipse.jetty.io.ssl.SslHandshakeListener; +import org.junit.Test; + +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLHandshakeException; +import java.util.Map; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * @author mortent + */ +public class SslHandshakeFailedListenerTest { + + private Metric metrics = mock(Metric.class); + SslHandshakeFailedListener listener = new SslHandshakeFailedListener(metrics, "connector", 1234); + + @Test + public void includes_client_ip_dimension_present_when_peer_available() { + listener.handshakeFailed(handshakeEvent(true), new SSLHandshakeException("Empty server certificate chain")); + verify(metrics).createContext(eq(Map.of("clientIp", "127.0.0.1", "serverName", "connector", "serverPort", 1234))); + } + + @Test + public void does_not_include_client_ip_dimension_present_when_peer_unavailable() { + listener.handshakeFailed(handshakeEvent(false), new SSLHandshakeException("Empty server certificate chain")); + verify(metrics).createContext(eq(Map.of("serverName", "connector", "serverPort", 1234))); + } + + private SslHandshakeListener.Event handshakeEvent(boolean includePeer) { + var sslEngine = mock(SSLEngine.class); + if(includePeer) when(sslEngine.getPeerHost()).thenReturn("127.0.0.1"); + return new SslHandshakeListener.Event(sslEngine); + } +} |