use of com.nike.riposte.server.http.filter.RequestAndResponseFilter in project riposte by Nike-Inc.
the class RequestFilterHandler method doChannelRead.
@Override
public PipelineContinuationBehavior doChannelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof HttpRequest) {
HttpProcessingState state = ChannelAttributes.getHttpProcessingStateForChannel(ctx).get();
handlerUtils.createRequestInfoFromNettyHttpRequestAndHandleStateSetupIfNecessary((HttpRequest) msg, state);
// If the Netty HttpRequest is invalid, we shouldn't process any of the filters.
handlerUtils.throwExceptionIfNotSuccessfullyDecoded((HttpRequest) msg);
// The HttpRequest is valid, so process the filters.
BiFunction<RequestAndResponseFilter, RequestInfo, RequestInfo> normalFilterCall = (filter, request) -> filter.filterRequestFirstChunkNoPayload(request, ctx);
BiFunction<RequestAndResponseFilter, RequestInfo, Pair<RequestInfo, Optional<ResponseInfo<?>>>> shortCircuitFilterCall = (filter, request) -> filter.filterRequestFirstChunkWithOptionalShortCircuitResponse(request, ctx);
return handleFilterLogic(ctx, msg, state, normalFilterCall, shortCircuitFilterCall);
}
if (msg instanceof LastHttpContent) {
HttpProcessingState state = ChannelAttributes.getHttpProcessingStateForChannel(ctx).get();
BiFunction<RequestAndResponseFilter, RequestInfo, RequestInfo> normalFilterCall = (filter, request) -> filter.filterRequestLastChunkWithFullPayload(request, ctx);
BiFunction<RequestAndResponseFilter, RequestInfo, Pair<RequestInfo, Optional<ResponseInfo<?>>>> shortCircuitFilterCall = (filter, request) -> filter.filterRequestLastChunkWithOptionalShortCircuitResponse(request, ctx);
return handleFilterLogic(ctx, msg, state, normalFilterCall, shortCircuitFilterCall);
}
// Not the first or last chunk. No filters were executed, so continue normally.
return PipelineContinuationBehavior.CONTINUE;
}
use of com.nike.riposte.server.http.filter.RequestAndResponseFilter in project riposte by Nike-Inc.
the class ResponseFilterHandler method executeResponseFilters.
protected void executeResponseFilters(ChannelHandlerContext ctx) {
try {
HttpProcessingState state = ChannelAttributes.getHttpProcessingStateForChannel(ctx).get();
// (for example).
if (state.isResponseSendingStarted())
return;
// RequestHasBeenHandledVerificationHandler should have made sure that state.getResponseInfo() is not null,
// and ExceptionHandlingHandler should have made sure that state.getRequestInfo() is not null
// (even if no exception has occurred).
ResponseInfo<?> currentResponseInfo = state.getResponseInfo();
for (RequestAndResponseFilter filter : filtersInResponseProcessingOrder) {
try {
currentResponseInfo = responseInfoUpdateNoNulls(filter, currentResponseInfo, filter.filterResponse(currentResponseInfo, state.getRequestInfo(), ctx));
} catch (Throwable ex) {
logger.error("An error occurred while processing a request filter. This error will be ignored and the " + "filtering/processing will continue normally, however this error should be fixed (filters " + "should never throw errors). filter_class={}", filter.getClass().getName(), ex);
}
}
// Set the ResponseInfo on our HttpPrcessingState, but propagate any error already set on the state -
// we don't want to override the originating error simply because the filter wants to adjust the
// response.
state.setResponseInfo(currentResponseInfo, state.getErrorThatTriggeredThisResponse());
} catch (Throwable ex) {
logger.error("An error occurred while setting up to process response filters. This error will be ignored and the " + "pipeline will continue normally without any filtering having occurred, however this error should be " + "fixed (it should be impossible to reach here).", ex);
}
}
use of com.nike.riposte.server.http.filter.RequestAndResponseFilter in project riposte by Nike-Inc.
the class RequestFilterHandlerTest method doChannelRead_delegates_to_handleFilterLogic_with_first_chunk_method_references_when_msg_is_HttpRequest.
@DataProvider(value = { "CONTINUE", "DO_NOT_FIRE_CONTINUE_EVENT" }, splitBy = "\\|")
@Test
public void doChannelRead_delegates_to_handleFilterLogic_with_first_chunk_method_references_when_msg_is_HttpRequest(PipelineContinuationBehavior expectedPipelineContinuationBehavior) throws Exception {
// given
doReturn(expectedPipelineContinuationBehavior).when(handlerSpy).handleFilterLogic(any(), any(), any(), any(), any());
// when
PipelineContinuationBehavior result = handlerSpy.doChannelRead(ctxMock, firstChunkMsgMock);
// then
assertThat(result).isEqualTo(expectedPipelineContinuationBehavior);
ArgumentCaptor<BiFunction> normalFilterCallCaptor = ArgumentCaptor.forClass(BiFunction.class);
ArgumentCaptor<BiFunction> shortCircuitFilterCallCaptor = ArgumentCaptor.forClass(BiFunction.class);
verify(handlerSpy).handleFilterLogic(eq(ctxMock), eq(firstChunkMsgMock), eq(state), normalFilterCallCaptor.capture(), shortCircuitFilterCallCaptor.capture());
BiFunction<RequestAndResponseFilter, RequestInfo, RequestInfo> normalFilterCall = normalFilterCallCaptor.getValue();
BiFunction<RequestAndResponseFilter, RequestInfo, Pair<RequestInfo, Optional<ResponseInfo<?>>>> shortCircuitFilterCall = shortCircuitFilterCallCaptor.getValue();
RequestAndResponseFilter filterForNormalCallMock = mock(RequestAndResponseFilter.class);
normalFilterCall.apply(filterForNormalCallMock, requestInfoMock);
verify(filterForNormalCallMock).filterRequestFirstChunkNoPayload(requestInfoMock, ctxMock);
RequestAndResponseFilter filterForShortCircuitCallMock = mock(RequestAndResponseFilter.class);
shortCircuitFilterCall.apply(filterForShortCircuitCallMock, requestInfoMock);
verify(filterForShortCircuitCallMock).filterRequestFirstChunkWithOptionalShortCircuitResponse(requestInfoMock, ctxMock);
}
use of com.nike.riposte.server.http.filter.RequestAndResponseFilter in project riposte by Nike-Inc.
the class RequestFilterHandlerTest method doChannelRead_delegates_to_handleFilterLogic_with_last_chunk_method_references_when_msg_is_LastHttpContent.
@DataProvider(value = { "CONTINUE", "DO_NOT_FIRE_CONTINUE_EVENT" }, splitBy = "\\|")
@Test
public void doChannelRead_delegates_to_handleFilterLogic_with_last_chunk_method_references_when_msg_is_LastHttpContent(PipelineContinuationBehavior expectedPipelineContinuationBehavior) throws Exception {
// given
doReturn(expectedPipelineContinuationBehavior).when(handlerSpy).handleFilterLogic(any(), any(), any(), any(), any());
// when
PipelineContinuationBehavior result = handlerSpy.doChannelRead(ctxMock, lastChunkMsgMock);
// then
assertThat(result).isEqualTo(expectedPipelineContinuationBehavior);
ArgumentCaptor<BiFunction> normalFilterCallCaptor = ArgumentCaptor.forClass(BiFunction.class);
ArgumentCaptor<BiFunction> shortCircuitFilterCallCaptor = ArgumentCaptor.forClass(BiFunction.class);
verify(handlerSpy).handleFilterLogic(eq(ctxMock), eq(lastChunkMsgMock), eq(state), normalFilterCallCaptor.capture(), shortCircuitFilterCallCaptor.capture());
BiFunction<RequestAndResponseFilter, RequestInfo, RequestInfo> normalFilterCall = normalFilterCallCaptor.getValue();
BiFunction<RequestAndResponseFilter, RequestInfo, Pair<RequestInfo, Optional<ResponseInfo<?>>>> shortCircuitFilterCall = shortCircuitFilterCallCaptor.getValue();
RequestAndResponseFilter filterForNormalCallMock = mock(RequestAndResponseFilter.class);
normalFilterCall.apply(filterForNormalCallMock, requestInfoMock);
verify(filterForNormalCallMock).filterRequestLastChunkWithFullPayload(requestInfoMock, ctxMock);
RequestAndResponseFilter filterForShortCircuitCallMock = mock(RequestAndResponseFilter.class);
shortCircuitFilterCall.apply(filterForShortCircuitCallMock, requestInfoMock);
verify(filterForShortCircuitCallMock).filterRequestLastChunkWithOptionalShortCircuitResponse(requestInfoMock, ctxMock);
}
use of com.nike.riposte.server.http.filter.RequestAndResponseFilter in project riposte by Nike-Inc.
the class RequestFilterHandlerTest method handleFilterLogic_short_circuits_as_expected_if_filter_returns_valid_response.
@DataProvider(value = { "true | 0 | true", "true | 0 | false", "true | 1 | true", "true | 1 | false", "false | 0 | true", "false | 0 | false", "false | 1 | true", "false | 1 | false" }, splitBy = "\\|")
@Test
public void handleFilterLogic_short_circuits_as_expected_if_filter_returns_valid_response(boolean isFirstChunk, int shortCircuitingFilterIndex, boolean filterReturnsModifiedRequestInfo) {
// given
HandleFilterLogicMethodCallArgs args = new HandleFilterLogicMethodCallArgs(isFirstChunk);
RequestAndResponseFilter shortCircuitingFilter = filtersList.get(shortCircuitingFilterIndex);
doReturn(true).when(shortCircuitingFilter).isShortCircuitRequestFilter();
RequestInfo<?> modifiedRequestInfoMock = mock(RequestInfo.class);
RequestInfo<?> returnedRequestInfo = (filterReturnsModifiedRequestInfo) ? modifiedRequestInfoMock : null;
ResponseInfo<?> returnedResponseInfoMock = mock(ResponseInfo.class);
doReturn(Pair.of(returnedRequestInfo, Optional.of(returnedResponseInfoMock))).when(shortCircuitingFilter).filterRequestFirstChunkWithOptionalShortCircuitResponse(any(), any());
doReturn(Pair.of(returnedRequestInfo, Optional.of(returnedResponseInfoMock))).when(shortCircuitingFilter).filterRequestLastChunkWithOptionalShortCircuitResponse(any(), any());
// when
PipelineContinuationBehavior result = handlerSpy.handleFilterLogic(ctxMock, args.msg, args.httpState, args.normalFilterCall, args.shortCircuitFilterCall);
// then
// Pipeline stops for the given msg event.
assertThat(result).isEqualTo(DO_NOT_FIRE_CONTINUE_EVENT);
// The filter's short-circuit-capable method was called.
if (isFirstChunk)
verify(shortCircuitingFilter).filterRequestFirstChunkWithOptionalShortCircuitResponse(requestInfoMock, ctxMock);
else
verify(shortCircuitingFilter).filterRequestLastChunkWithOptionalShortCircuitResponse(requestInfoMock, ctxMock);
// The state is updated with the correct RequestInfo depending on what the filter returned.
if (filterReturnsModifiedRequestInfo)
assertThat(state.getRequestInfo()).isSameAs(modifiedRequestInfoMock);
else
assertThat(state.getRequestInfo()).isSameAs(requestInfoMock);
// The state is updated with the ResponseInfo returned by the filter.
assertThat(state.getResponseInfo()).isSameAs(returnedResponseInfoMock);
// The short circuiting "we're all done, return the response to the caller" event is fired down the pipeline.
verify(ctxMock).fireChannelRead(LastOutboundMessageSendFullResponseInfo.INSTANCE);
}
Aggregations