@Test public void two_arg_constructor_fails_with_IllegalArgumentException_if_factory_is_null() { // when Throwable ex = catchThrowable(() -> new SignalFxEndpointMetricsHandler(null, metricRegistryMock)); // then assertThat(ex).isInstanceOf(IllegalArgumentException.class) .hasMessage("SignalFxReporterFactory cannot be null"); }
/** * Create a new instance for the given {@link SignalFxReporter} reporting with the given frequency. The default * metric dimension configurator will be used to set up the endpoint timer dimensions: * {@link #DEFAULT_REQUEST_LATENCY_TIMER_DIMENSION_CONFIGURATOR}. * * <p>IMPORTANT NOTE: The given {@code reportingFrequency} must match whatever you used when starting the given * {@link SignalFxReporter} (see {@link SignalFxReporter#start(long, TimeUnit)}), or else the data reported to * SignalFx may not make sense. * * @param signalFxReporter The {@link SignalFxReporter} to use for metric metadata. Cannot be null. * @param reportingFrequency The frequency that the given {@code signalFxReporter} reports its data to SignalFx. * Cannot be null, and the individual values inside the pair cannot be null. * @param metricRegistry The {@link MetricRegistry} being used for the application that the endpoint timers should * be registered under. Cannot be null. */ public SignalFxEndpointMetricsHandler(SignalFxReporter signalFxReporter, Pair<Long, TimeUnit> reportingFrequency, MetricRegistry metricRegistry) { this(extractMetricMetadataFromSignalFxReporter(signalFxReporter), metricRegistry, generateDefaultTimerMetricBuilder(reportingFrequency), null); }
@Test public void setupEndpointsMetrics_does_nothing() { // given ServerConfig serverConfigMock = mock(ServerConfig.class); // when handler.setupEndpointsMetrics(serverConfigMock, metricRegistryMock); // then verifyZeroInteractions( serverConfigMock, metricMetadataMock, metricRegistryMock, requestTimerBuilderMock, dimensionConfiguratorMock ); }
@Test public void handleRequest_works_as_expected() { // given int statusCode = 242; int statusCodeXXValue = 2; long elapsedTimeMillis = 42; // when handler.handleRequest( requestInfoMock, responseInfoMock, httpStateMock, statusCode, statusCodeXXValue, elapsedTimeMillis ); // then verify(metricMetadataMock).forBuilder(requestTimerBuilderMock); verify(dimensionConfiguratorMock).setupMetricWithDimensions( timerBuilderTaggerMock, requestInfoMock, responseInfoMock, httpStateMock, statusCode, statusCodeXXValue, elapsedTimeMillis, endpointMock, endpointMock.getClass().getName(), httpMethod.name(), matchingPathTemplate ); verify(timerBuilderTaggerMock).createOrGet(metricRegistryMock); verify(timerMock).update(elapsedTimeMillis, TimeUnit.MILLISECONDS); }
/** * The default recommended constructor when you don't have any special customizations you want to do. This will * setup the endpoint timer with the default dimensions (using {@link * #DEFAULT_REQUEST_LATENCY_TIMER_DIMENSION_CONFIGURATOR}), and will set it up to use a {@link * SlidingTimeWindowReservoir} that matches the given {@link SignalFxReporterFactory#getInterval()} and * {@link SignalFxReporterFactory#getTimeUnit()} reporting rate so that the values seen in SignalFx will be accurate * and sensible. * * <p>For more flexibility, please see the {@link * SignalFxEndpointMetricsHandler#SignalFxEndpointMetricsHandler(MetricMetadata, MetricRegistry, MetricBuilder, * MetricDimensionConfigurator)} constructor. * * @param signalFxReporterFactory The {@link SignalFxReporterFactory} that will be used for this application. * Cannot be null. * @param metricRegistry The {@link MetricRegistry} being used for the application that the endpoint timers should * be registered under. Cannot be null. */ public SignalFxEndpointMetricsHandler(SignalFxReporterFactory signalFxReporterFactory, MetricRegistry metricRegistry) { this(extractSignalFxReporterFromFactory(signalFxReporterFactory, metricRegistry), Pair.of(signalFxReporterFactory.getInterval(), signalFxReporterFactory.getTimeUnit()), metricRegistry ); }
handler.handleRequest( requestInfoMock, responseInfoMock, httpStateMock, statusCode, statusCodeXXValue, elapsedTimeMillis );
@Test public void kitchen_sink_constructor_defaults_requestTimerDimensionConfigurator_if_passed_null() { // when SignalFxEndpointMetricsHandler instance = new SignalFxEndpointMetricsHandler( metricMetadataMock, metricRegistryMock, requestTimerBuilderMock, null ); // then assertThat(instance.requestTimerDimensionConfigurator) .isSameAs(DEFAULT_REQUEST_LATENCY_TIMER_DIMENSION_CONFIGURATOR); }
@Test public void two_arg_constructor_fails_with_IllegalArgumentException_if_metricRegistry_is_null() { // given SignalFxReporterFactory reporterFactoryMock = mock(SignalFxReporterFactory.class); wireUpReporterFactoryMockForConstructor(reporterFactoryMock, metricRegistryMock); // when Throwable ex = catchThrowable(() -> new SignalFxEndpointMetricsHandler(reporterFactoryMock, null)); // then assertThat(ex).isInstanceOf(IllegalArgumentException.class) .hasMessage("MetricRegistry cannot be null"); }
@Test public void three_arg_constructor_fails_with_IllegalArgumentException_if_reportingFrequency_is_null() { // given SignalFxReporter reporterMock = mock(SignalFxReporter.class); wireUpReporterForConstructor(reporterMock); // when Throwable ex = catchThrowable( () -> new SignalFxEndpointMetricsHandler(reporterMock, null, metricRegistryMock) ); // then assertThat(ex).isInstanceOf(IllegalArgumentException.class) .hasMessage("reportingFrequency cannot be null"); }
@Test public void three_arg_constructor_fails_with_IllegalArgumentException_if_reporter_is_null() { // when Throwable ex = catchThrowable( () -> new SignalFxEndpointMetricsHandler(null, Pair.of(42L, TimeUnit.DAYS), metricRegistryMock) ); // then assertThat(ex).isInstanceOf(IllegalArgumentException.class) .hasMessage("SignalFxReporter cannot be null"); }
@Test public void three_arg_constructor_fails_with_IllegalArgumentException_if_metricRegistry_is_null() { // given SignalFxReporter reporterMock = mock(SignalFxReporter.class); wireUpReporterForConstructor(reporterMock); // when Throwable ex = catchThrowable( () -> new SignalFxEndpointMetricsHandler(reporterMock, Pair.of(42L, TimeUnit.DAYS), null) ); // then assertThat(ex).isInstanceOf(IllegalArgumentException.class) .hasMessage("metricRegistry cannot be null"); }
@Test public void kitchen_sink_constructor_sets_fields_as_expected() { // when SignalFxEndpointMetricsHandler instance = new SignalFxEndpointMetricsHandler( metricMetadataMock, metricRegistryMock, requestTimerBuilderMock, dimensionConfiguratorMock ); // then assertThat(instance.metricMetadata).isSameAs(metricMetadataMock); assertThat(instance.metricRegistry).isSameAs(metricRegistryMock); assertThat(instance.requestTimerBuilder).isSameAs(requestTimerBuilderMock); assertThat(instance.requestTimerDimensionConfigurator).isSameAs(dimensionConfiguratorMock); }
@Before public void beforeMethod() { metricMetadataMock = mock(MetricMetadata.class); metricRegistryMock = mock(MetricRegistry.class); requestTimerBuilderMock = mock(MetricBuilder.class); dimensionConfiguratorMock = mock(MetricDimensionConfigurator.class); handler = new SignalFxEndpointMetricsHandler( metricMetadataMock, metricRegistryMock, requestTimerBuilderMock, dimensionConfiguratorMock ); requestInfoMock = mock(RequestInfo.class); responseInfoMock = mock(ResponseInfo.class); httpStateMock = mock(HttpProcessingState.class); endpointMock = mock(Endpoint.class); requestStartTime = Instant.now().minus(42, ChronoUnit.MILLIS); httpMethod = HttpMethod.PATCH; matchingPathTemplate = "/" + UUID.randomUUID().toString(); doReturn(requestStartTime).when(httpStateMock).getRequestStartTime(); doReturn(endpointMock).when(httpStateMock).getEndpointForExecution(); doReturn(httpMethod).when(requestInfoMock).getMethod(); doReturn(matchingPathTemplate).when(httpStateMock).getMatchingPathTemplate(); timerBuilderTaggerMock = mock(BuilderTagger.class); doReturn(timerBuilderTaggerMock).when(metricMetadataMock).forBuilder(requestTimerBuilderMock); doReturn(timerBuilderTaggerMock).when(dimensionConfiguratorMock).setupMetricWithDimensions( eq(timerBuilderTaggerMock), eq(requestInfoMock), eq(responseInfoMock), eq(httpStateMock), anyInt(), anyInt(), anyLong(), any(Endpoint.class), anyString(), anyString(), anyString() ); timerMock = mock(Timer.class); doReturn(timerMock).when(timerBuilderTaggerMock).createOrGet(metricRegistryMock); }
@DataProvider(value = { "true | false | false | signalFxReporterMetricMetadata cannot be null", "false | true | false | metricRegistry cannot be null", "false | false | true | requestTimerBuilder cannot be null" }, splitBy = "\\|") @Test public void kitchen_sink_constructor_fails_with_IllegalArgumentException_if_certain_args_are_null( boolean metadataIsNull, boolean registryIsNull, boolean timerBuilderIsNull, String expectedMessage ) { // given MetricMetadata metricMetadata = (metadataIsNull) ? null : metricMetadataMock; MetricRegistry registry = (registryIsNull) ? null : metricRegistryMock; MetricBuilder<Timer> timerBuilder = (timerBuilderIsNull) ? null : requestTimerBuilderMock; // when Throwable ex = catchThrowable( () -> new SignalFxEndpointMetricsHandler(metricMetadata, registry, timerBuilder, null) ); // then assertThat(ex).isInstanceOf(IllegalArgumentException.class) .hasMessage(expectedMessage); }
@DataProvider(value = { "true | false", "false | true" }, splitBy = "\\|") @Test public void two_arg_constructor_fails_with_IllegalArgumentException_if_reporting_frequency_args_are_null( boolean amountIsNull, boolean timeUnitIsNull ) { // given SignalFxReporterFactory reporterFactoryMock = mock(SignalFxReporterFactory.class); wireUpReporterFactoryMockForConstructor(reporterFactoryMock, metricRegistryMock); if (amountIsNull) doReturn(null).when(reporterFactoryMock).getInterval(); if (timeUnitIsNull) doReturn(null).when(reporterFactoryMock).getTimeUnit(); // when Throwable ex = catchThrowable(() -> new SignalFxEndpointMetricsHandler(reporterFactoryMock, metricRegistryMock)); // then if (amountIsNull) { assertThat(ex).isInstanceOf(IllegalArgumentException.class) .hasMessage("reportingFrequency amount cannot be null"); } if (timeUnitIsNull) { assertThat(ex).isInstanceOf(IllegalArgumentException.class) .hasMessage("reportingFrequency TimeUnit cannot be null"); } }
@DataProvider(value = { "true | false", "false | true" }, splitBy = "\\|") @Test public void three_arg_constructor_fails_with_IllegalArgumentException_if_reporting_frequency_args_are_null( boolean amountIsNull, boolean timeUnitIsNull ) { // given SignalFxReporter reporterMock = mock(SignalFxReporter.class); wireUpReporterForConstructor(reporterMock); Long amount = (amountIsNull) ? null : 42L; TimeUnit timeUnit = (timeUnitIsNull) ? null : TimeUnit.DAYS; // when Throwable ex = catchThrowable( () -> new SignalFxEndpointMetricsHandler(reporterMock, Pair.of(amount, timeUnit), metricRegistryMock) ); // then if (amountIsNull) { assertThat(ex).isInstanceOf(IllegalArgumentException.class) .hasMessage("reportingFrequency amount cannot be null"); } if (timeUnitIsNull) { assertThat(ex).isInstanceOf(IllegalArgumentException.class) .hasMessage("reportingFrequency TimeUnit cannot be null"); } }
@Test public void three_arg_constructor_sets_fields_as_expected() { // given SignalFxReporter reporterMock = mock(SignalFxReporter.class); MetricMetadata expectedMetricMetadata = wireUpReporterForConstructor(reporterMock); Pair<Long, TimeUnit> reportingFrequency = Pair.of(42L, TimeUnit.DAYS); // when SignalFxEndpointMetricsHandler instance = new SignalFxEndpointMetricsHandler(reporterMock, reportingFrequency, metricRegistryMock); // then assertThat(instance.metricMetadata).isSameAs(expectedMetricMetadata); assertThat(instance.metricRegistry).isSameAs(metricRegistryMock); assertThat(instance.requestTimerBuilder).isInstanceOf(RollingWindowTimerBuilder.class); RollingWindowTimerBuilder rwtb = (RollingWindowTimerBuilder) instance.requestTimerBuilder; assertThat(rwtb.amount).isEqualTo(reportingFrequency.getLeft()); assertThat(rwtb.timeUnit).isEqualTo(reportingFrequency.getRight()); assertThat(instance.requestTimerDimensionConfigurator) .isSameAs(DEFAULT_REQUEST_LATENCY_TIMER_DIMENSION_CONFIGURATOR); }
@Test public void two_arg_constructor_sets_fields_as_expected() { // given SignalFxReporterFactory reporterFactoryMock = mock(SignalFxReporterFactory.class); Pair<Pair<SignalFxReporter, MetricMetadata>, Pair<Long, TimeUnit>> wiredUpMocksAndData = wireUpReporterFactoryMockForConstructor(reporterFactoryMock, metricRegistryMock); MetricMetadata expectedMetricMetadata = wiredUpMocksAndData.getLeft().getRight(); long expectedReportingInterval = wiredUpMocksAndData.getRight().getLeft(); TimeUnit expectedReportingTimeUnit = wiredUpMocksAndData.getRight().getRight(); // when SignalFxEndpointMetricsHandler instance = new SignalFxEndpointMetricsHandler(reporterFactoryMock, metricRegistryMock); // then assertThat(instance.metricMetadata).isSameAs(expectedMetricMetadata); assertThat(instance.metricRegistry).isSameAs(metricRegistryMock); assertThat(instance.requestTimerBuilder).isInstanceOf(RollingWindowTimerBuilder.class); RollingWindowTimerBuilder rwtb = (RollingWindowTimerBuilder) instance.requestTimerBuilder; assertThat(rwtb.amount).isEqualTo(expectedReportingInterval); assertThat(rwtb.timeUnit).isEqualTo(expectedReportingTimeUnit); assertThat(instance.requestTimerDimensionConfigurator) .isSameAs(DEFAULT_REQUEST_LATENCY_TIMER_DIMENSION_CONFIGURATOR); }