package org.stagemonitor.web.monitor; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.MockFilterChain; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.stagemonitor.configuration.ConfigurationRegistry; import org.stagemonitor.core.Stagemonitor; import org.stagemonitor.core.metrics.metrics2.Metric2Registry; import org.stagemonitor.tracing.RequestMonitor; import org.stagemonitor.tracing.TracingPlugin; import org.stagemonitor.tracing.utils.SpanUtils; import org.stagemonitor.tracing.wrapper.AbstractSpanEventListener; import org.stagemonitor.tracing.wrapper.SpanEventListenerFactory; import org.stagemonitor.tracing.wrapper.SpanWrapper; import org.stagemonitor.tracing.wrapper.SpanWrappingTracer; import org.stagemonitor.web.WebPlugin; import org.stagemonitor.web.monitor.filter.StatusExposingByteCountingServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.List; import io.opentracing.Span; import io.opentracing.mock.MockSpan; import io.opentracing.tag.Tags; import static junit.framework.Assert.assertNull; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class MonitoredHttpRequestTest { private ConfigurationRegistry configuration; private String operationName; private io.opentracing.mock.MockTracer tracer; @Before public void setUp() throws Exception { configuration = mock(ConfigurationRegistry.class); final TracingPlugin tracingPlugin = mock(TracingPlugin.class); final WebPlugin webPlugin = new WebPlugin(); when(configuration.getConfig(TracingPlugin.class)).thenReturn(tracingPlugin); when(configuration.getConfig(WebPlugin.class)).thenReturn(webPlugin); final List<SpanEventListenerFactory> spanEventListenerFactories = new ArrayList<>(); spanEventListenerFactories.add(() -> new AbstractSpanEventListener() { @Override public void onFinish(SpanWrapper spanWrapper, String operationName, long durationNanos) { MonitoredHttpRequestTest.this.operationName = operationName; } }); spanEventListenerFactories.add(new MonitoredHttpRequest.HttpSpanEventListener(webPlugin, tracingPlugin, new Metric2Registry())); tracer = new io.opentracing.mock.MockTracer(); when(tracingPlugin.getTracer()).thenReturn(new SpanWrappingTracer(tracer, spanEventListenerFactories)); final RequestMonitor requestMonitor = mock(RequestMonitor.class); when(tracingPlugin.getRequestMonitor()).thenReturn(requestMonitor); } @After public void tearDown() throws Exception { Stagemonitor.reset(); } @Test public void testGetRequestName() throws Exception { final MonitoredHttpRequest monitoredHttpRequest = createMonitoredHttpRequest(new MockHttpServletRequest("GET", "/test.js")); assertEquals("GET *.js", monitoredHttpRequest.getRequestName()); } @Test public void testCreateSpan() throws Exception { final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/test.js"); request.addParameter("foo", "bar"); request.addParameter("bla", "blubb"); request.addParameter("pwd", "secret"); request.addParameter("creditCard", "123456789"); request.addHeader("Cookie", "foobar"); request.addHeader("Accept", "application/json"); final MonitoredHttpRequest monitoredHttpRequest = createMonitoredHttpRequest(request); final Span span = monitoredHttpRequest.createSpan(); span.finish(); assertEquals(1, tracer.finishedSpans().size()); final MockSpan mockSpan = tracer.finishedSpans().get(0); assertEquals("/test.js", mockSpan.tags().get(Tags.HTTP_URL.getKey())); assertEquals("GET *.js", operationName); assertEquals("GET", mockSpan.tags().get("method")); assertEquals("application/json", mockSpan.tags().get(SpanUtils.HTTP_HEADERS_PREFIX + "accept")); assertFalse(mockSpan.tags().containsKey(SpanUtils.HTTP_HEADERS_PREFIX + "cookie")); assertFalse(mockSpan.tags().containsKey(SpanUtils.HTTP_HEADERS_PREFIX + "Cookie")); assertEquals("bar", mockSpan.tags().get(SpanUtils.PARAMETERS_PREFIX + "foo")); assertEquals("blubb", mockSpan.tags().get(SpanUtils.PARAMETERS_PREFIX + "bla")); assertEquals("XXXX", mockSpan.tags().get(SpanUtils.PARAMETERS_PREFIX + "pwd")); assertEquals("XXXX", mockSpan.tags().get(SpanUtils.PARAMETERS_PREFIX + "creditCard")); assertFalse(mockSpan.tags().containsKey(Tags.ERROR.getKey())); } @Test public void testReferringSite() throws Exception { final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/test.js"); request.addHeader("Referer", "https://www.github.com/stagemonitor/stagemonitor"); final MonitoredHttpRequest monitoredHttpRequest = createMonitoredHttpRequest(request); monitoredHttpRequest.createSpan().finish(); assertEquals(1, tracer.finishedSpans().size()); final MockSpan mockSpan = tracer.finishedSpans().get(0); assertEquals("www.github.com", mockSpan.tags().get("http.referring_site")); } @Test public void testReferringSameHostSite() throws Exception { final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/test.js"); request.addHeader("Referer", "https://www.myapp.com:8080/categories"); request.setServerName("www.myapp.com"); final MonitoredHttpRequest monitoredHttpRequest = createMonitoredHttpRequest(request); monitoredHttpRequest.createSpan().finish(); assertEquals(1, tracer.finishedSpans().size()); final MockSpan mockSpan = tracer.finishedSpans().get(0); assertNull(mockSpan.tags().get("http.referring_site")); } private MonitoredHttpRequest createMonitoredHttpRequest(MockHttpServletRequest request) throws IOException { return new MonitoredHttpRequest( request, new StatusExposingByteCountingServletResponse(new MockHttpServletResponse()), new MockFilterChain(), configuration); } }