use of com.nike.riposte.server.http.HttpProcessingState in project riposte by Nike-Inc.
the class ChannelPipelineFinalizerHandlerTest method finalizeChannelPipeline_should_send_event_to_metricsListener_for_successful_response_and_flush_context.
@Test
public void finalizeChannelPipeline_should_send_event_to_metricsListener_for_successful_response_and_flush_context() throws Exception {
// given
ChannelFuture responseWriterChannelFuture = mock(ChannelFuture.class);
state.setResponseWriterFinalChunkChannelFuture(responseWriterChannelFuture);
HttpProcessingState stateSpy = spy(state);
doReturn(stateSpy).when(stateAttributeMock).get();
ChannelFuture responseWriteFutureResult = mock(ChannelFuture.class);
doReturn(true).when(responseWriteFutureResult).isSuccess();
Assertions.assertThat(stateSpy.isRequestMetricsRecordedOrScheduled()).isFalse();
// when
handler.finalizeChannelPipeline(ctxMock, null, stateSpy, null);
// then
ArgumentCaptor<GenericFutureListener> channelFutureListenerArgumentCaptor = ArgumentCaptor.forClass(GenericFutureListener.class);
verify(responseWriterChannelFuture).addListener(channelFutureListenerArgumentCaptor.capture());
GenericFutureListener futureListener = channelFutureListenerArgumentCaptor.getValue();
assertThat(futureListener, notNullValue());
futureListener.operationComplete(responseWriteFutureResult);
verify(metricsListenerMock).onEvent(eq(ServerMetricsEvent.RESPONSE_SENT), any(HttpProcessingState.class));
verify(ctxMock).flush();
Assertions.assertThat(stateSpy.isRequestMetricsRecordedOrScheduled()).isTrue();
}
use of com.nike.riposte.server.http.HttpProcessingState in project riposte by Nike-Inc.
the class ChannelPipelineFinalizerHandlerTest method finalizeChannelPipeline_should_send_error_response_if_state_indicates_no_response_already_sent.
@Test
public void finalizeChannelPipeline_should_send_error_response_if_state_indicates_no_response_already_sent() throws JsonProcessingException {
// given
state.setResponseWriterFinalChunkChannelFuture(null);
HttpProcessingState stateSpy = spy(state);
doReturn(stateSpy).when(stateAttributeMock).get();
doReturn(false).when(responseInfoMock).isResponseSendingStarted();
Object msg = new Object();
Throwable cause = new Exception("intentional test exception");
RequestInfo<?> requestInfoMock = mock(RequestInfo.class);
ResponseInfo<ErrorResponseBody> errorResponseMock = mock(ResponseInfo.class);
doReturn(requestInfoMock).when(exceptionHandlingHandlerMock).getRequestInfo(stateSpy, msg);
doReturn(errorResponseMock).when(exceptionHandlingHandlerMock).processUnhandledError(eq(stateSpy), eq(msg), any(Throwable.class));
// when
handler.finalizeChannelPipeline(ctxMock, msg, stateSpy, cause);
// then
verify(responseSenderMock).sendErrorResponse(ctxMock, requestInfoMock, errorResponseMock);
verify(metricsListenerMock).onEvent(ServerMetricsEvent.RESPONSE_SENT, stateSpy);
verify(ctxMock).flush();
}
use of com.nike.riposte.server.http.HttpProcessingState in project riposte by Nike-Inc.
the class DTraceStartHandlerTest method beforeMethod.
@Before
public void beforeMethod() {
handler = new DTraceStartHandler(userIdHeaderKeys);
channelMock = mock(Channel.class);
ctxMock = mock(ChannelHandlerContext.class);
stateAttributeMock = mock(Attribute.class);
state = new HttpProcessingState();
httpRequest = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/some/uri");
doReturn(channelMock).when(ctxMock).channel();
doReturn(stateAttributeMock).when(channelMock).attr(ChannelAttributes.HTTP_PROCESSING_STATE_ATTRIBUTE_KEY);
doReturn(state).when(stateAttributeMock).get();
resetTracingAndMdc();
}
use of com.nike.riposte.server.http.HttpProcessingState in project riposte by Nike-Inc.
the class ChannelAttributesTest method getHttpProcessingStateForChannel_works_as_expected.
@Test
public void getHttpProcessingStateForChannel_works_as_expected() {
// given
ChannelHandlerContext ctxMock = mock(ChannelHandlerContext.class);
Channel channelMock = mock(Channel.class);
@SuppressWarnings("unchecked") Attribute<HttpProcessingState> magicAttrMock = mock(Attribute.class);
// and
doReturn(channelMock).when(ctxMock).channel();
doReturn(magicAttrMock).when(channelMock).attr(ChannelAttributes.HTTP_PROCESSING_STATE_ATTRIBUTE_KEY);
// expect
assertThat(ChannelAttributes.getHttpProcessingStateForChannel(ctxMock), is(magicAttrMock));
}
use of com.nike.riposte.server.http.HttpProcessingState in project riposte by Nike-Inc.
the class AsyncNettyHelper method executeOnlyIfChannelIsActive.
/**
* Executes the given runnable only if {@code ctx.channel().isActive()} returns true. If the channel is not active
* then a warning is logged, resources are released, the distributed trace is completed (if appropriate), and the
* runnable is *not* executed. Call this when you're about to do something and it's possible that the channel has
* been closed. Usually this is only necessary when you're manually firing an event on the given {@code ctx} after
* some asynchronous delay (e.g. a future completes, or a timeout was scheduled on the event loop, etc).
*
* @param ctx
* The {@link ChannelHandlerContext} that contains the state for this request.
* @param markerForLogs
* This will be put into the log warning if the channel is not active to help you identify where the problem
* occurred. This is usually some arbitrary "ID" representing the code that is calling this method.
* @param thingToMaybeExecute
* This will be executed if the channel is active, and ignored if the channel is not active.
*
* @return true if the channel was active and the thingToMaybeExecute was executed, false if the channel was not
* active and things were cleaned up as per this method description.
*/
public static boolean executeOnlyIfChannelIsActive(ChannelHandlerContext ctx, String markerForLogs, Runnable thingToMaybeExecute) {
if (ctx.channel().isActive()) {
// The channel is active, so execute the runnable.
thingToMaybeExecute.run();
return true;
} else {
Pair<Deque<Span>, Map<String, String>> origTracingAndMdcPair = linkTracingAndMdcToCurrentThread(ctx);
try {
// The channel is *not* active. Log a warning, release resources,
// and complete any existing distributed trace.
logger.warn("Unable to continue - channel is no longer active. The client may have closed the connection. " + "Releasing resources and stopping request processing. channel_inactive_cannot_continue_marker={}", markerForLogs);
// Gather the stuff we want to try to release resources for.
HttpProcessingState state = ChannelAttributes.getHttpProcessingStateForChannel(ctx).get();
RequestInfo<?> requestInfo = (state == null) ? null : state.getRequestInfo();
ProxyRouterProcessingState proxyRouterState = ChannelAttributes.getProxyRouterProcessingStateForChannel(ctx).get();
// Tell the RequestInfo it can release all its resources.
if (requestInfo != null)
requestInfo.releaseAllResources();
// is closing) and doing this will cause any resources it's holding onto to be released.
if (proxyRouterState != null) {
proxyRouterState.setStreamingFailed();
proxyRouterState.triggerStreamingChannelErrorForChunks(new RuntimeException("Server worker channel closed"));
}
// out a second time.
if (state == null || !state.isTraceCompletedOrScheduled()) {
Tracer.getInstance().completeRequestSpan();
// If we have a state then indicate that the span has already been completed.
if (state != null)
state.setTraceCompletedOrScheduled(true);
}
return false;
} finally {
unlinkTracingAndMdcFromCurrentThread(origTracingAndMdcPair);
}
}
}
Aggregations