Skip to content

Commit 6bd78f3

Browse files
committed
SWS-754 - EndpointInterceptor.afterCompletion is not always invoked
1 parent adfd74f commit 6bd78f3

File tree

2 files changed

+93
-35
lines changed

2 files changed

+93
-35
lines changed

core/src/main/java/org/springframework/ws/server/MessageDispatcher.java

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2005-2011 the original author or authors.
2+
* Copyright 2005-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -29,6 +29,7 @@
2929
import org.springframework.context.ApplicationContext;
3030
import org.springframework.context.ApplicationContextAware;
3131
import org.springframework.core.OrderComparator;
32+
import org.springframework.util.CollectionUtils;
3233
import org.springframework.util.ObjectUtils;
3334
import org.springframework.web.servlet.DispatcherServlet;
3435
import org.springframework.ws.FaultAwareWebServiceMessage;
@@ -206,46 +207,54 @@ protected final void dispatch(MessageContext messageContext) throws Exception {
206207
EndpointInvocationChain mappedEndpoint = null;
207208
int interceptorIndex = -1;
208209
try {
209-
// Determine endpoint for the current context
210-
mappedEndpoint = getEndpoint(messageContext);
211-
if (mappedEndpoint == null || mappedEndpoint.getEndpoint() == null) {
212-
throw new NoEndpointFoundException(messageContext.getRequest());
213-
}
214-
if (!handleRequest(mappedEndpoint, messageContext)) {
215-
return;
216-
}
217-
// Apply handleRequest of registered interceptors
218-
if (mappedEndpoint.getInterceptors() != null) {
219-
for (int i = 0; i < mappedEndpoint.getInterceptors().length; i++) {
220-
EndpointInterceptor interceptor = mappedEndpoint.getInterceptors()[i];
221-
interceptorIndex = i;
222-
if (!interceptor.handleRequest(messageContext, mappedEndpoint.getEndpoint())) {
223-
triggerHandleResponse(mappedEndpoint, interceptorIndex, messageContext);
224-
triggerAfterCompletion(mappedEndpoint, interceptorIndex, messageContext, null);
225-
return;
210+
try {
211+
// Determine endpoint for the current context
212+
mappedEndpoint = getEndpoint(messageContext);
213+
if (mappedEndpoint == null || mappedEndpoint.getEndpoint() == null) {
214+
throw new NoEndpointFoundException(messageContext.getRequest());
215+
}
216+
if (!handleRequest(mappedEndpoint, messageContext)) {
217+
return;
218+
}
219+
// Apply handleRequest of registered interceptors
220+
if (mappedEndpoint.getInterceptors() != null) {
221+
for (int i = 0; i < mappedEndpoint.getInterceptors().length; i++) {
222+
EndpointInterceptor interceptor = mappedEndpoint.getInterceptors()[i];
223+
interceptorIndex = i;
224+
if (!interceptor.handleRequest(messageContext, mappedEndpoint.getEndpoint())) {
225+
triggerHandleResponse(mappedEndpoint, interceptorIndex, messageContext);
226+
triggerAfterCompletion(mappedEndpoint, interceptorIndex, messageContext, null);
227+
return;
228+
}
226229
}
227230
}
228-
}
229-
// Actually invoke the endpoint
230-
EndpointAdapter endpointAdapter = getEndpointAdapter(mappedEndpoint.getEndpoint());
231-
endpointAdapter.invoke(messageContext, mappedEndpoint.getEndpoint());
231+
// Actually invoke the endpoint
232+
EndpointAdapter endpointAdapter = getEndpointAdapter(mappedEndpoint.getEndpoint());
233+
endpointAdapter.invoke(messageContext, mappedEndpoint.getEndpoint());
232234

235+
}
236+
catch (NoEndpointFoundException ex) {
237+
// No triggering of interceptors if no endpoint is found
238+
if (endpointNotFoundLogger.isWarnEnabled()) {
239+
endpointNotFoundLogger.warn("No endpoint mapping found for [" + messageContext.getRequest() + "]");
240+
}
241+
throw ex;
242+
}
243+
catch (Exception ex) {
244+
Object endpoint = mappedEndpoint != null ? mappedEndpoint.getEndpoint() : null;
245+
processEndpointException(messageContext, endpoint, ex);
246+
}
233247
// Apply handleResponse methods of registered interceptors
234248
triggerHandleResponse(mappedEndpoint, interceptorIndex, messageContext);
235249
triggerAfterCompletion(mappedEndpoint, interceptorIndex, messageContext, null);
236250
}
237251
catch (NoEndpointFoundException ex) {
238-
// No triggering of interceptors if no endpoint is found
239-
if (endpointNotFoundLogger.isWarnEnabled()) {
240-
endpointNotFoundLogger.warn("No endpoint mapping found for [" + messageContext.getRequest() + "]");
241-
}
242252
throw ex;
243253
}
244254
catch (Exception ex) {
245-
Object endpoint = mappedEndpoint != null ? mappedEndpoint.getEndpoint() : null;
246-
processEndpointException(messageContext, endpoint, ex);
247-
triggerHandleResponse(mappedEndpoint, interceptorIndex, messageContext);
255+
// Trigger after-completion for thrown exception.
248256
triggerAfterCompletion(mappedEndpoint, interceptorIndex, messageContext, ex);
257+
throw ex;
249258
}
250259
}
251260

@@ -316,12 +325,14 @@ protected boolean handleRequest(EndpointInvocationChain mappedEndpoint, MessageC
316325
*/
317326
protected void processEndpointException(MessageContext messageContext, Object endpoint, Exception ex)
318327
throws Exception {
319-
for (EndpointExceptionResolver resolver : getEndpointExceptionResolvers()) {
320-
if (resolver.resolveException(messageContext, endpoint, ex)) {
321-
if (logger.isDebugEnabled()) {
322-
logger.debug("Endpoint invocation resulted in exception - responding with Fault", ex);
328+
if (!CollectionUtils.isEmpty(getEndpointExceptionResolvers())) {
329+
for (EndpointExceptionResolver resolver : getEndpointExceptionResolvers()) {
330+
if (resolver.resolveException(messageContext, endpoint, ex)) {
331+
if (logger.isDebugEnabled()) {
332+
logger.debug("Endpoint invocation resulted in exception - responding with Fault", ex);
333+
}
334+
return;
323335
}
324-
return;
325336
}
326337
}
327338
// exception not resolved

core/src/test/java/org/springframework/ws/server/MessageDispatcherTest.java

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,54 @@ public void testInterceptedResponseFlow() throws Exception {
298298

299299
verify(mappingMock, interceptorMock1, interceptorMock2, adapterMock, factoryMock);
300300
}
301-
301+
302+
@Test
303+
public void testResolveExceptionsWithInterceptors() throws Exception {
304+
EndpointAdapter adapterMock = createMock(EndpointAdapter.class);
305+
dispatcher.setEndpointAdapters(Collections.singletonList(adapterMock));
306+
307+
Object endpoint = new Object();
308+
expect(adapterMock.supports(endpoint)).andReturn(true);
309+
310+
EndpointMapping mappingMock = createMock(EndpointMapping.class);
311+
dispatcher.setEndpointMappings(Collections.singletonList(mappingMock));
312+
313+
EndpointExceptionResolver resolverMock = createMock(EndpointExceptionResolver.class);
314+
dispatcher.setEndpointExceptionResolvers(Collections.singletonList(resolverMock));
315+
316+
EndpointInterceptor interceptorMock = createStrictMock("interceptor1", EndpointInterceptor.class);
317+
318+
expect(interceptorMock.handleRequest(messageContext, endpoint)).andReturn(true);
319+
320+
adapterMock.invoke(messageContext, endpoint);
321+
RuntimeException exception = new RuntimeException();
322+
expectLastCall().andThrow(exception);
323+
324+
expect(resolverMock.resolveException(messageContext, endpoint, exception)).andReturn(true);
325+
326+
expect(interceptorMock.handleResponse(messageContext, endpoint)).andReturn(true);
327+
328+
interceptorMock.afterCompletion(messageContext, endpoint, null);
329+
330+
EndpointInvocationChain chain =
331+
new EndpointInvocationChain(endpoint, new EndpointInterceptor[]{interceptorMock});
332+
333+
expect(mappingMock.getEndpoint(messageContext)).andReturn(chain);
334+
expect(factoryMock.createWebServiceMessage()).andReturn(new MockWebServiceMessage());
335+
336+
replay(mappingMock, interceptorMock, adapterMock, factoryMock, resolverMock);
337+
338+
// response required for interceptor invocation
339+
messageContext.getResponse();
340+
try {
341+
dispatcher.dispatch(messageContext);
342+
} catch (RuntimeException ex) {
343+
344+
}
345+
346+
verify(mappingMock, interceptorMock, adapterMock, factoryMock, resolverMock);
347+
}
348+
302349
@Test
303350
public void testFaultFlow() throws Exception {
304351
EndpointAdapter adapterMock = createMock(EndpointAdapter.class);

0 commit comments

Comments
 (0)