use of com.nike.riposte.server.http.Endpoint in project riposte by Nike-Inc.
the class RoutingHandler method doChannelRead.
@Override
public PipelineContinuationBehavior doChannelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof HttpRequest) {
HttpProcessingState state = ChannelAttributes.getHttpProcessingStateForChannel(ctx).get();
RequestInfo request = state.getRequestInfo();
Pair<Endpoint<?>, String> endpointForExecution = findSingleEndpointForExecution(request);
throwExceptionIfContentLengthHeaderIsLargerThanConfiguredMaxRequestSize((HttpRequest) msg, endpointForExecution.getLeft());
request.setPathParamsBasedOnPathTemplate(endpointForExecution.getRight());
state.setEndpointForExecution(endpointForExecution.getLeft(), endpointForExecution.getRight());
}
return PipelineContinuationBehavior.CONTINUE;
}
use of com.nike.riposte.server.http.Endpoint in project riposte by Nike-Inc.
the class EndpointMetricsHandlerDefaultImplTest method setupEndpointsMetrics_sets_up_metrics_as_expected.
@DataProvider(value = { "true", "false" })
@Test
public void setupEndpointsMetrics_sets_up_metrics_as_expected(boolean customizeTimerCreation) {
// given
EndpointMetricsHandlerDefaultImpl newImpl = spy(new EndpointMetricsHandlerDefaultImpl());
String expectedTimerPrefix = customizeTimerCreation ? UUID.randomUUID().toString() + newImpl.prefix : newImpl.prefix;
doAnswer(invocation -> {
if (!customizeTimerCreation)
return invocation.callRealMethod();
String name = invocation.getArgumentAt(0, String.class);
name = name.replace(newImpl.prefix, expectedTimerPrefix);
MetricRegistry registry = invocation.getArgumentAt(1, MetricRegistry.class);
return registry.register(name, mock(Timer.class));
}).when(newImpl).createAndRegisterRequestTimer(anyString(), any(MetricRegistry.class));
// when
newImpl.setupEndpointsMetrics(serverConfig, metricRegistryMock);
// then
// Verify aggregate overall requests and responses metrics are setup with expected names
assertThat(newImpl.getRequests()).isSameAs(newImpl.requests);
assertThat(newImpl.requests).isEqualTo(registeredTimers.get(name(expectedTimerPrefix, "requests")));
assertThat(mockingDetails(newImpl.requests).isMock()).isEqualTo(customizeTimerCreation);
assertThat(newImpl.getResponses()).isSameAs(newImpl.responses);
assertThat(newImpl.responses.length).isEqualTo(5);
assertThat(newImpl.responses).isEqualTo(new Meter[] { registeredMeterMocks.get(name(newImpl.prefix, "1xx-responses")), registeredMeterMocks.get(name(newImpl.prefix, "2xx-responses")), registeredMeterMocks.get(name(newImpl.prefix, "3xx-responses")), registeredMeterMocks.get(name(newImpl.prefix, "4xx-responses")), registeredMeterMocks.get(name(newImpl.prefix, "5xx-responses")) });
// Verify aggregate HTTP-method request metrics are setup with expected names
assertThat(newImpl.getGetRequests()).isSameAs(newImpl.getRequests);
assertThat(newImpl.getRequests).isEqualTo(registeredTimers.get(name(expectedTimerPrefix, "get-requests")));
assertThat(mockingDetails(newImpl.getRequests).isMock()).isEqualTo(customizeTimerCreation);
assertThat(newImpl.getPostRequests()).isSameAs(newImpl.postRequests);
assertThat(newImpl.postRequests).isEqualTo(registeredTimers.get(name(expectedTimerPrefix, "post-requests")));
assertThat(mockingDetails(newImpl.postRequests).isMock()).isEqualTo(customizeTimerCreation);
assertThat(newImpl.getPutRequests()).isSameAs(newImpl.putRequests);
assertThat(newImpl.putRequests).isEqualTo(registeredTimers.get(name(expectedTimerPrefix, "put-requests")));
assertThat(mockingDetails(newImpl.putRequests).isMock()).isEqualTo(customizeTimerCreation);
assertThat(newImpl.getDeleteRequests()).isSameAs(newImpl.deleteRequests);
assertThat(newImpl.deleteRequests).isEqualTo(registeredTimers.get(name(expectedTimerPrefix, "delete-requests")));
assertThat(mockingDetails(newImpl.deleteRequests).isMock()).isEqualTo(customizeTimerCreation);
assertThat(newImpl.getOtherRequests()).isSameAs(newImpl.otherRequests);
assertThat(newImpl.otherRequests).isEqualTo(registeredTimers.get(name(expectedTimerPrefix, "other-requests")));
assertThat(mockingDetails(newImpl.otherRequests).isMock()).isEqualTo(customizeTimerCreation);
// Verify per-endpoint request and response metrics are setup with expected names
serverConfig.appEndpoints().forEach(endpoint -> {
String timerAndMeterMapKeyForEndpoint = newImpl.getTimerAndMeterMapKeyForEndpoint(endpoint);
String name = name(newImpl.prefix, "endpoints." + endpoint.getClass().getName().replace(".", "-") + "-" + timerAndMeterMapKeyForEndpoint);
String timerName = name.replace(newImpl.prefix, expectedTimerPrefix);
Timer expectedTimer = registeredTimers.get(timerName);
assertThat(expectedTimer).isNotNull();
assertThat(newImpl.endpointRequestsTimers.get(timerAndMeterMapKeyForEndpoint)).isSameAs(expectedTimer);
assertThat(mockingDetails(expectedTimer).isMock()).isEqualTo(customizeTimerCreation);
Meter[] expectedMeters = new Meter[5];
for (int i = 0; i < 5; i++) {
String nextMeterName = name(name, (i + 1) + "xx-responses");
Meter nextMeter = registeredMeterMocks.get(nextMeterName);
assertThat(nextMeter).isNotNull();
expectedMeters[i] = nextMeter;
}
assertThat(newImpl.endpointResponsesMeters.get(timerAndMeterMapKeyForEndpoint)).isEqualTo(expectedMeters);
});
// Ditto for aggregate metrics for 404, 405, 500, and other short-circuit type responses that never hit an endpoint
// 404 metrics
{
String notFoundNameId = name(newImpl.prefix, "endpoints." + ENDPOINT_NOT_FOUND_MAP_KEY);
String timerNotFoundNameId = notFoundNameId.replace(newImpl.prefix, expectedTimerPrefix);
Timer expected404Timer = registeredTimers.get(timerNotFoundNameId);
assertThat(expected404Timer).isNotNull();
assertThat(newImpl.endpointRequestsTimers.get(ENDPOINT_NOT_FOUND_MAP_KEY)).isSameAs(expected404Timer);
assertThat(mockingDetails(expected404Timer).isMock()).isEqualTo(customizeTimerCreation);
Meter expected404Meter = registeredMeterMocks.get(name(notFoundNameId, "4xx-responses"));
assertThat(expected404Meter).isNotNull();
assertThat(newImpl.endpointResponsesMeters.get(ENDPOINT_NOT_FOUND_MAP_KEY)).isEqualTo(new Meter[] { expected404Meter });
}
// 405 metrics
{
String methodNotAllowedNameId = name(newImpl.prefix, "endpoints." + METHOD_NOT_ALLOWED_MAP_KEY);
String timerMethodNotAllowedNameId = methodNotAllowedNameId.replace(newImpl.prefix, expectedTimerPrefix);
Timer expected405Timer = registeredTimers.get(timerMethodNotAllowedNameId);
assertThat(expected405Timer).isNotNull();
assertThat(newImpl.endpointRequestsTimers.get(METHOD_NOT_ALLOWED_MAP_KEY)).isSameAs(expected405Timer);
assertThat(mockingDetails(expected405Timer).isMock()).isEqualTo(customizeTimerCreation);
Meter expected405Meter = registeredMeterMocks.get(name(methodNotAllowedNameId, "4xx-responses"));
assertThat(expected405Meter).isNotNull();
assertThat(newImpl.endpointResponsesMeters.get(METHOD_NOT_ALLOWED_MAP_KEY)).isEqualTo(new Meter[] { expected405Meter });
}
// 500 routing error metrics
{
String routingErrorNameId = name(newImpl.prefix, "endpoints." + ROUTING_ERROR_MAP_KEY);
String timerRoutingErrorNameId = routingErrorNameId.replace(newImpl.prefix, expectedTimerPrefix);
Timer expected500Timer = registeredTimers.get(timerRoutingErrorNameId);
assertThat(expected500Timer).isNotNull();
assertThat(newImpl.endpointRequestsTimers.get(ROUTING_ERROR_MAP_KEY)).isSameAs(expected500Timer);
assertThat(mockingDetails(expected500Timer).isMock()).isEqualTo(customizeTimerCreation);
Meter expected500Meter = registeredMeterMocks.get(name(routingErrorNameId, "5xx-responses"));
assertThat(expected500Meter).isNotNull();
assertThat(newImpl.endpointResponsesMeters.get(ROUTING_ERROR_MAP_KEY)).isEqualTo(new Meter[] { expected500Meter });
}
// Misc no-endpoint short-circuit response metrics
{
String shortCircuitNameId = name(newImpl.prefix, "endpoints." + NO_ENDPOINT_SHORT_CIRCUIT_KEY);
String timerShortCircuitNameId = shortCircuitNameId.replace(newImpl.prefix, expectedTimerPrefix);
Timer expectedShortCircuitTimer = registeredTimers.get(timerShortCircuitNameId);
assertThat(expectedShortCircuitTimer).isNotNull();
assertThat(newImpl.endpointRequestsTimers.get(NO_ENDPOINT_SHORT_CIRCUIT_KEY)).isSameAs(expectedShortCircuitTimer);
assertThat(mockingDetails(expectedShortCircuitTimer).isMock()).isEqualTo(customizeTimerCreation);
Meter[] expectedShortCircuitMeters = new Meter[5];
for (int i = 0; i < 5; i++) {
String nextMeterName = name(shortCircuitNameId, (i + 1) + "xx-responses");
Meter nextMeter = registeredMeterMocks.get(nextMeterName);
assertThat(nextMeter).isNotNull();
expectedShortCircuitMeters[i] = nextMeter;
}
assertThat(newImpl.endpointResponsesMeters.get(NO_ENDPOINT_SHORT_CIRCUIT_KEY)).isEqualTo(expectedShortCircuitMeters);
}
}
use of com.nike.riposte.server.http.Endpoint in project riposte by Nike-Inc.
the class EndpointMetricsHandlerDefaultImplTest method handleRequest_works_as_expected_for_request_that_hit_an_endpoint.
@DataProvider(value = { "GET | 99", "GET | 142", "GET | 242", "GET | 342", "GET | 404", "GET | 405", "GET | 442", "GET | 500", "GET | 542", "GET | 600", "POST | 99", "POST | 142", "POST | 242", "POST | 342", "POST | 404", "POST | 405", "POST | 442", "POST | 500", "POST | 542", "POST | 600", "PUT | 99", "PUT | 142", "PUT | 242", "PUT | 342", "PUT | 404", "PUT | 405", "PUT | 442", "PUT | 500", "PUT | 542", "PUT | 600", "DELETE | 99", "DELETE | 142", "DELETE | 242", "DELETE | 342", "DELETE | 404", "DELETE | 405", "DELETE | 442", "DELETE | 500", "DELETE | 542", "DELETE | 600", "PATCH | 99", "PATCH | 142", "PATCH | 242", "PATCH | 342", "PATCH | 404", "PATCH | 405", "PATCH | 442", "PATCH | 500", "PATCH | 542", "PATCH | 600", "null | 99", "null | 142", "null | 242", "null | 342", "null | 404", "null | 405", "null | 442", "null | 500", "null | 542", "null | 600" }, splitBy = "\\|")
@Test
public void handleRequest_works_as_expected_for_request_that_hit_an_endpoint(String requestMethodStr, int responseStatusCode) throws InterruptedException {
// given
HttpMethod requestMethod = (requestMethodStr == null) ? null : HttpMethod.valueOf(requestMethodStr);
doReturn(requestMethod).when(requestInfoMock).getMethod();
Endpoint<?> endpoint = serverConfig.appEndpoints().iterator().next();
String matchingPathTemplate = "/" + UUID.randomUUID().toString();
state.setEndpointForExecution(endpoint, matchingPathTemplate);
String endpointTimerAndMeterKey = instance.getTimerAndMeterMapKeyForEndpoint(endpoint);
int responseHttpStatusCodeXXValue = responseStatusCode / 100;
long elapsedTimeMillis = 42;
// when
instance.handleRequest(requestInfoMock, responseInfoMock, state, responseStatusCode, responseHttpStatusCodeXXValue, elapsedTimeMillis);
// then
// The all-requests timer should be updated with the elapsed time of the request
verify(instance.requests).update(elapsedTimeMillis, TimeUnit.MILLISECONDS);
// The timer for the relevant HTTP method for this request should be updated with the elapsed time of the request
verify(expectedRequestTimer(requestMethod, instance)).update(elapsedTimeMillis, TimeUnit.MILLISECONDS);
{
// The timer for the endpoint for this request should be updated with the elapsed time of the request
Timer expectedEndpointTimerUsed = instance.endpointRequestsTimers.get(endpointTimerAndMeterKey);
assertThat(expectedEndpointTimerUsed).isNotNull();
verify(expectedEndpointTimerUsed).update(elapsedTimeMillis, TimeUnit.MILLISECONDS);
}
final int httpStatusCodeXXValue = responseStatusCode / 100;
if (httpStatusCodeXXValue >= 1 && httpStatusCodeXXValue <= 5) {
// Inside the normal 1xx-5xx response codes.
// The correct 1xx, 2xx, 3xx, 4xx, or 5xx meter for all requests should be marked.
verify(instance.responses[httpStatusCodeXXValue - 1]).mark();
// The correct 1xx, 2xx, 3xx, 4xx, or 5xx meter for this request's endpoint should be marked.
Meter[] endpointResponseMeterArray = instance.endpointResponsesMeters.get(endpointTimerAndMeterKey);
assertThat(endpointResponseMeterArray).isNotNull();
verify(endpointResponseMeterArray[httpStatusCodeXXValue - 1]).mark();
} else {
// Outside the normal 1xx-5xx response codes, so none of the response meters should have been modified.
instance.endpointResponsesMeters.values().forEach(meterArray -> Stream.of(meterArray).forEach(Mockito::verifyZeroInteractions));
}
}
use of com.nike.riposte.server.http.Endpoint in project riposte by Nike-Inc.
the class CodahaleMetricsListenerTest method onEvent_works_as_expected_for_RESPONSE_SENT_with_endpoint.
@DataProvider(value = { "GET | 99", "GET | 142", "GET | 242", "GET | 342", "GET | 404", "GET | 405", "GET | 442", "GET | 500", "GET | 542", "GET | 600", "POST | 99", "POST | 142", "POST | 242", "POST | 342", "POST | 404", "POST | 405", "POST | 442", "POST | 500", "POST | 542", "POST | 600", "PUT | 99", "PUT | 142", "PUT | 242", "PUT | 342", "PUT | 404", "PUT | 405", "PUT | 442", "PUT | 500", "PUT | 542", "PUT | 600", "DELETE | 99", "DELETE | 142", "DELETE | 242", "DELETE | 342", "DELETE | 404", "DELETE | 405", "DELETE | 442", "DELETE | 500", "DELETE | 542", "DELETE | 600", "PATCH | 99", "PATCH | 142", "PATCH | 242", "PATCH | 342", "PATCH | 404", "PATCH | 405", "PATCH | 442", "PATCH | 500", "PATCH | 542", "PATCH | 600", "null | 99", "null | 142", "null | 242", "null | 342", "null | 404", "null | 405", "null | 442", "null | 500", "null | 542", "null | 600" }, splitBy = "\\|")
@Test
public void onEvent_works_as_expected_for_RESPONSE_SENT_with_endpoint(String requestMethodStr, int responseStatusCode) throws InterruptedException {
// given
ServerMetricsEvent event = ServerMetricsEvent.RESPONSE_SENT;
HttpMethod requestMethod = (requestMethodStr == null) ? null : HttpMethod.valueOf(requestMethodStr);
doReturn(requestMethod).when(requestInfoMock).getMethod();
Endpoint<?> endpoint = serverConfig.appEndpoints().iterator().next();
String matchingPathTemplate = "/" + UUID.randomUUID().toString();
state.setEndpointForExecution(endpoint, matchingPathTemplate);
doReturn(responseStatusCode).when(responseInfoMock).getHttpStatusCodeWithDefault(ResponseSender.DEFAULT_HTTP_STATUS_CODE);
int requestRawContentLengthBytes = (int) (Math.random() * 10000);
doReturn(requestRawContentLengthBytes).when(requestInfoMock).getRawContentLengthInBytes();
long finalResponseContentLength = (long) (Math.random() * 10000);
doReturn(finalResponseContentLength).when(responseInfoMock).getFinalContentLength();
Thread.sleep((long) (Math.random() * 25));
// when
long beforeCallTime = System.currentTimeMillis();
listener.onEvent(event, state);
long afterCallTime = System.currentTimeMillis();
// then
// Inflight requests counter decremented
verify(listener.inflightRequests).dec();
// Processed requests counter incremented
verify(listener.processedRequests).inc();
// If response code is greater than or equal to 400, then the failed requests counter should be incremented.
if (responseStatusCode >= 400)
verify(listener.failedRequests).inc();
// Request and response size histograms should be updated with the relevant values from the request and response.
verify(listener.requestSizes).update(requestRawContentLengthBytes);
verify(listener.responseSizes).update(finalResponseContentLength);
// The EndpointMetricsHandler should have been notified
int responseHttpStatusCodeXXValue = responseStatusCode / 100;
long expectedElapsedTimeMillisLowerBound = beforeCallTime - requestStartTime.toEpochMilli();
long expectedElapsedTimeMillisUpperBound = afterCallTime - requestStartTime.toEpochMilli();
ArgumentCaptor<Long> elapsedTimeMillisArgCaptor = ArgumentCaptor.forClass(Long.class);
verify(endpointMetricsHandlerMock).handleRequest(eq(requestInfoMock), eq(responseInfoMock), eq(state), eq(responseStatusCode), eq(responseHttpStatusCodeXXValue), elapsedTimeMillisArgCaptor.capture());
assertThat(elapsedTimeMillisArgCaptor.getValue()).isBetween(expectedElapsedTimeMillisLowerBound, expectedElapsedTimeMillisUpperBound);
}
use of com.nike.riposte.server.http.Endpoint in project riposte by Nike-Inc.
the class SignalFxEndpointMetricsHandlerTest method MetricDimensionConfigurator_chainedWith_returns_ChainedMetricDimensionConfigurator_with_correct_args.
@Test
public void MetricDimensionConfigurator_chainedWith_returns_ChainedMetricDimensionConfigurator_with_correct_args() {
// given
MetricDimensionConfigurator orig = (rawBuilder, requestInfo, responseInfo, httpState, responseHttpStatusCode, responseHttpStatusCodeXXValue, elapsedTimeMillis, endpoint, endpointClass, method, matchingPathTemplate) -> null;
MetricDimensionConfigurator chainMe = mock(MetricDimensionConfigurator.class);
// when
MetricDimensionConfigurator result = orig.chainedWith(chainMe);
// then
assertThat(result).isInstanceOf(ChainedMetricDimensionConfigurator.class);
ChainedMetricDimensionConfigurator cmdc = (ChainedMetricDimensionConfigurator) result;
assertThat(cmdc.firstConfigurator).isSameAs(orig);
assertThat(cmdc.secondConfigurator).isSameAs(chainMe);
}
Aggregations