@Override public PipelineContinuationBehavior doExceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // Exceptions should always execute filters. executeResponseFilters(ctx); return PipelineContinuationBehavior.CONTINUE; }
public ResponseFilterHandler(List<RequestAndResponseFilter> filtersInRequestProcessingOrder) { this.filtersInResponseProcessingOrder = (filtersInRequestProcessingOrder == null) ? Collections.emptyList() : reverseList(new ArrayList<>(filtersInRequestProcessingOrder)); }
@Override public PipelineContinuationBehavior doChannelRead(ChannelHandlerContext ctx, Object msg) { if (shouldHandleDoChannelReadMessage(msg)) { executeResponseFilters(ctx); } return PipelineContinuationBehavior.CONTINUE; }
@Test public void constructor_uses_empty_list_if_passed_null() { // when ResponseFilterHandler handler = new ResponseFilterHandler(null); // then assertThat(handler.filtersInResponseProcessingOrder).isEqualTo(Collections.emptyList()); }
@Test public void doChannelRead_does_nothing_and_returns_CONTINUE_if_msg_is_not_a_first_chunk() throws Exception { // given Object msg = new OutboundMessage() {}; // when PipelineContinuationBehavior result = handlerSpy.doChannelRead(ctxMock, msg); // then assertThat(result).isEqualTo(CONTINUE); verify(handlerSpy, never()).executeResponseFilters(any()); }
@Test public void doExceptionCaught_delegates_to_executeResponseFilters_and_returns_CONTINUE() throws Exception { // given Throwable ex = mock(Throwable.class); doNothing().when(handlerSpy).executeResponseFilters(any()); // when PipelineContinuationBehavior result = handlerSpy.doExceptionCaught(ctxMock, ex); // then assertThat(result).isEqualTo(CONTINUE); verify(handlerSpy).executeResponseFilters(ctxMock); }
@Override protected boolean argsAreEligibleForLinkingAndUnlinkingDistributedTracingInfo( HandlerMethodToExecute methodToExecute, ChannelHandlerContext ctx, Object msgOrEvt, Throwable cause ) { return shouldHandleDoChannelReadMessage(msgOrEvt) || (methodToExecute == DO_EXCEPTION_CAUGHT); } }
for (RequestAndResponseFilter filter : filtersInResponseProcessingOrder) { try { currentResponseInfo = responseInfoUpdateNoNulls( filter, currentResponseInfo,
@Test public void constructor_uses_reversed_copy_of_passed_in_filter_list() { // given List<RequestAndResponseFilter> origListCopy = new ArrayList<>(filtersList); // when ResponseFilterHandler handler = new ResponseFilterHandler(filtersList); // then assertThat(handler.filtersInResponseProcessingOrder).isEqualTo(reversedFiltersList); assertThat(filtersList).isEqualTo(origListCopy); assertThat(filtersList).isNotEqualTo(reversedFiltersList); }
@DataProvider(value = { "true", "false" }, splitBy = "\\|") @Test public void doChannelRead_delegates_to_executeResponseFilters_and_returns_CONTINUE_if_msg_is_first_chunk_of_response(boolean chunkedResponse) throws Exception { // given OutboundMessage msg = (chunkedResponse) ? mock(OutboundMessageSendHeadersChunkFromResponseInfo.class) : mock(LastOutboundMessageSendFullResponseInfo.class); doNothing().when(handlerSpy).executeResponseFilters(any()); // when PipelineContinuationBehavior result = handlerSpy.doChannelRead(ctxMock, msg); // then assertThat(result).isEqualTo(CONTINUE); verify(handlerSpy).executeResponseFilters(ctxMock); }
@Override protected boolean argsAreEligibleForLinkingAndUnlinkingDistributedTracingInfo( HandlerMethodToExecute methodToExecute, ChannelHandlerContext ctx, Object msgOrEvt, Throwable cause ) { return shouldHandleDoChannelReadMessage(msgOrEvt) || (methodToExecute == DO_EXCEPTION_CAUGHT); } }
for (RequestAndResponseFilter filter : filtersInResponseProcessingOrder) { try { currentResponseInfo = responseInfoUpdateNoNulls( filter, currentResponseInfo,
@Override public PipelineContinuationBehavior doExceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // Exceptions should always execute filters. executeResponseFilters(ctx); return PipelineContinuationBehavior.CONTINUE; }
@Override public PipelineContinuationBehavior doChannelRead(ChannelHandlerContext ctx, Object msg) { if (shouldHandleDoChannelReadMessage(msg)) { executeResponseFilters(ctx); } return PipelineContinuationBehavior.CONTINUE; }
@Before public void beforeMethod() { channelMock = mock(Channel.class); ctxMock = mock(ChannelHandlerContext.class); stateAttributeMock = mock(Attribute.class); state = new HttpProcessingState(); requestInfoMock = mock(RequestInfo.class); doReturn(channelMock).when(ctxMock).channel(); doReturn(stateAttributeMock).when(channelMock).attr(ChannelAttributes.HTTP_PROCESSING_STATE_ATTRIBUTE_KEY); doReturn(state).when(stateAttributeMock).get(); chunkedResponseMsg = mock(OutboundMessageSendHeadersChunkFromResponseInfo.class); fullResponseMsg = mock(LastOutboundMessageSendFullResponseInfo.class); filter1Mock = mock(RequestAndResponseFilter.class); filter2Mock = mock(RequestAndResponseFilter.class); filtersList = Arrays.asList(filter1Mock, filter2Mock); reversedFiltersList = new ArrayList<>(filtersList); Collections.reverse(reversedFiltersList); handlerSpy = spy(new ResponseFilterHandler(filtersList)); chunkedResponseInfoMock = mock(ChunkedResponseInfo.class); fullResponseInfoMock = mock(FullResponseInfo.class); origErrorForOrigResponseInfoMock = mock(Throwable.class); state.setResponseInfo(fullResponseInfoMock, origErrorForOrigResponseInfoMock); state.setRequestInfo(requestInfoMock); }
public ResponseFilterHandler(List<RequestAndResponseFilter> filtersInRequestProcessingOrder) { this.filtersInResponseProcessingOrder = (filtersInRequestProcessingOrder == null) ? Collections.emptyList() : reverseList(new ArrayList<>(filtersInRequestProcessingOrder)); }
@DataProvider(value = { "true", "false" }, splitBy = "\\|") @Test public void executeResponseFilters_does_nothing_if_something_blows_up_before_filters_are_executed(boolean useChunkedResponse) throws Exception { // given ResponseInfo<?> responseInfoToUse = (useChunkedResponse) ? chunkedResponseInfoMock : fullResponseInfoMock; state.setResponseInfo(responseInfoToUse, origErrorForOrigResponseInfoMock); doThrow(new RuntimeException("kaboom")).when(ctxMock).channel(); // when handlerSpy.executeResponseFilters(ctxMock); // then reversedFiltersList.forEach(filter -> verify(filter, never()).filterResponse(any(), any(), any())); }
cachedResponseFilterHandler = (hasReqResFilters) ? new ResponseFilterHandler(requestAndResponseFilters) : null; this.userIdHeaderKeys = userIdHeaderKeys; this.responseCompressionThresholdBytes = responseCompressionThresholdBytes;
@DataProvider(value = { "true", "false" }, splitBy = "\\|") @Test public void executeResponseFilters_does_nothing_if_the_first_chunk_of_the_response_is_already_sent(boolean useChunkedResponse) throws Exception { // given ResponseInfo<?> responseInfoToUse = (useChunkedResponse) ? chunkedResponseInfoMock : fullResponseInfoMock; state.setResponseInfo(responseInfoToUse, origErrorForOrigResponseInfoMock); doReturn(true).when(responseInfoToUse).isResponseSendingStarted(); // when handlerSpy.executeResponseFilters(ctxMock); // then reversedFiltersList.forEach(filter -> verify(filter, never()).filterResponse(any(), any(), any())); }
cachedResponseFilterHandler = (hasReqResFilters) ? new ResponseFilterHandler(requestAndResponseFilters) : null; this.userIdHeaderKeys = userIdHeaderKeys; this.responseCompressionThresholdBytes = responseCompressionThresholdBytes;