WS-Addressing EMs support SmartEndpointInterceptor

All WS-Addressing EndpointsMappings now support endpoint interceptors
registered via a <sws:interceptors/> block (i.e.
SmartEndpointInteceptors).

Issue: SWS-874
This commit is contained in:
Arjen Poutsma
2014-04-23 14:21:45 +02:00
parent bbc6bf5f60
commit d43b880637
3 changed files with 80 additions and 65 deletions

View File

@@ -21,8 +21,6 @@ import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;
import org.springframework.ws.soap.addressing.core.MessageAddressingProperties;
@@ -37,8 +35,7 @@ import org.springframework.ws.soap.addressing.core.MessageAddressingProperties;
* @author Arjen Poutsma
* @since 1.5.0
*/
public abstract class AbstractActionEndpointMapping extends AbstractAddressingEndpointMapping
implements ApplicationContextAware {
public abstract class AbstractActionEndpointMapping extends AbstractAddressingEndpointMapping {
/** The defaults suffix to add to the request {@code Action} for reply messages. */
public static final String DEFAULT_OUTPUT_ACTION_SUFFIX = "Response";
@@ -53,7 +50,6 @@ public abstract class AbstractActionEndpointMapping extends AbstractAddressingEn
private String faultActionSuffix = DEFAULT_OUTPUT_ACTION_SUFFIX;
private ApplicationContext applicationContext;
/** Returns the suffix to add to request {@code Action}s for reply messages. */
public String getOutputActionSuffix() {
@@ -85,11 +81,6 @@ public abstract class AbstractActionEndpointMapping extends AbstractAddressingEn
this.faultActionSuffix = faultActionSuffix;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
protected final Object getEndpointInternal(MessageAddressingProperties map) {
URI action = map.getAction();
@@ -143,8 +134,8 @@ public abstract class AbstractActionEndpointMapping extends AbstractAddressingEn
if (endpoint instanceof String) {
String endpointName = (String) endpoint;
if (applicationContext.isSingleton(endpointName)) {
resolvedEndpoint = applicationContext.getBean(endpointName);
if (getApplicationContext().isSingleton(endpointName)) {
resolvedEndpoint = getApplicationContext().getBean(endpointName);
}
}
Object mappedEndpoint = this.endpointMap.get(action);

View File

@@ -17,17 +17,25 @@
package org.springframework.ws.soap.addressing.server;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.transform.TransformerException;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.Ordered;
import org.springframework.util.Assert;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.EndpointInterceptor;
import org.springframework.ws.server.EndpointInvocationChain;
import org.springframework.ws.server.EndpointMapping;
import org.springframework.ws.server.SmartEndpointInterceptor;
import org.springframework.ws.soap.SoapHeader;
import org.springframework.ws.soap.SoapHeaderElement;
import org.springframework.ws.soap.SoapMessage;
@@ -64,7 +72,7 @@ import org.springframework.xml.transform.TransformerObjectSupport;
* @since 1.5.0
*/
public abstract class AbstractAddressingEndpointMapping extends TransformerObjectSupport
implements SoapEndpointMapping, InitializingBean, Ordered {
implements SoapEndpointMapping, ApplicationContextAware, InitializingBean, Ordered {
private String[] actorsOrRoles;
@@ -80,6 +88,11 @@ public abstract class AbstractAddressingEndpointMapping extends TransformerObjec
private EndpointInterceptor[] postInterceptors = new EndpointInterceptor[0];
private SmartEndpointInterceptor[] smartInterceptors =
new SmartEndpointInterceptor[0];
private ApplicationContext applicationContext;
private int order = Integer.MAX_VALUE; // default: same as non-Ordered
@@ -115,7 +128,17 @@ public abstract class AbstractAddressingEndpointMapping extends TransformerObjec
this.isUltimateReceiver = ultimateReceiver;
}
@Override
public ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public final int getOrder() {
return order;
}
@@ -210,12 +233,21 @@ public abstract class AbstractAddressingEndpointMapping extends TransformerObjec
this.versions = versions;
}
@Override
public void afterPropertiesSet() throws Exception {
if (logger.isInfoEnabled()) {
logger.info("Supporting " + Arrays.asList(versions));
}
}
@Override
public void afterPropertiesSet() throws Exception {
if (logger.isInfoEnabled()) {
logger.info("Supporting " + Arrays.asList(versions));
}
if (getApplicationContext() != null) {
Map<String, SmartEndpointInterceptor> smartInterceptors = BeanFactoryUtils
.beansOfTypeIncludingAncestors(getApplicationContext(),
SmartEndpointInterceptor.class, true, false);
if (!smartInterceptors.isEmpty()) {
this.smartInterceptors = smartInterceptors.values()
.toArray(new SmartEndpointInterceptor[smartInterceptors.size()]);
}
}
}
@Override
public final EndpointInvocationChain getEndpoint(MessageContext messageContext) throws TransformerException {
@@ -253,15 +285,17 @@ public abstract class AbstractAddressingEndpointMapping extends TransformerObjec
WebServiceMessageSender[] messageSenders = getMessageSenders(endpoint);
MessageIdStrategy messageIdStrategy = getMessageIdStrategy(endpoint);
EndpointInterceptor[] interceptors =
new EndpointInterceptor[preInterceptors.length + postInterceptors.length +
1];
System.arraycopy(preInterceptors, 0, interceptors, 0, preInterceptors.length);
AddressingEndpointInterceptor interceptor = new AddressingEndpointInterceptor(version, messageIdStrategy,
messageSenders, responseAction, faultAction);
interceptors[preInterceptors.length] = interceptor;
System.arraycopy(postInterceptors, 0, interceptors, preInterceptors.length + 1, postInterceptors.length);
return new SoapEndpointInvocationChain(endpoint, interceptors, actorsOrRoles, isUltimateReceiver);
List<EndpointInterceptor> interceptors = new ArrayList<EndpointInterceptor>(preInterceptors.length + postInterceptors.length + smartInterceptors.length + 1);
AddressingEndpointInterceptor addressingInterceptor = new AddressingEndpointInterceptor(version, messageIdStrategy,
messageSenders, responseAction, faultAction);
interceptors.addAll(Arrays.asList(preInterceptors));
interceptors.add(addressingInterceptor);
interceptors.addAll(Arrays.asList(postInterceptors));
interceptors.addAll(Arrays.asList(smartInterceptors));
return new SoapEndpointInvocationChain(endpoint,
interceptors.toArray(new EndpointInterceptor[interceptors.size()]), actorsOrRoles, isUltimateReceiver);
}
private boolean supports(AddressingVersion version, SoapMessage request) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2005-2010 the original author or authors.
* Copyright 2005-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,24 +23,24 @@ import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPException;
import org.custommonkey.xmlunit.XMLUnit;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.ws.context.DefaultMessageContext;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.EndpointInvocationChain;
import org.springframework.ws.server.endpoint.MethodEndpoint;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.interceptor.DelegatingSmartEndpointInterceptor;
import org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor;
import org.springframework.ws.soap.addressing.server.annotation.Action;
import org.springframework.ws.soap.addressing.server.annotation.Address;
import org.springframework.ws.soap.saaj.SaajSoapMessage;
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
import org.custommonkey.xmlunit.XMLUnit;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;
public class AnnotationActionMethodEndpointMappingTest {
private StaticApplicationContext applicationContext;
@@ -55,31 +55,23 @@ public class AnnotationActionMethodEndpointMappingTest {
XMLUnit.setIgnoreWhitespace(true);
applicationContext = new StaticApplicationContext();
applicationContext.registerSingleton("mapping", AnnotationActionEndpointMapping.class);
applicationContext.registerSingleton("interceptor", MyInterceptor.class);
applicationContext.registerSingleton("endpoint", MyEndpoint.class);
applicationContext.refresh();
mapping = (AnnotationActionEndpointMapping) applicationContext.getBean("mapping");
}
@Test
public void testNoAddress() throws Exception {
applicationContext.registerSingleton("endpoint", Endpoint1.class);
applicationContext.refresh();
public void mapping() throws Exception {
MessageContext messageContext = createMessageContext();
EndpointInvocationChain chain = mapping.getEndpoint(messageContext);
Assert.assertNotNull("MethodEndpoint not registered", chain);
MethodEndpoint expected = new MethodEndpoint(applicationContext.getBean("endpoint"), "doIt", new Class[0]);
Assert.assertEquals("Invalid endpoint registered", expected, chain.getEndpoint());
}
@Test
public void testAddress() throws Exception {
applicationContext.registerSingleton("endpoint", Endpoint2.class);
applicationContext.refresh();
MessageContext messageContext = createMessageContext();
EndpointInvocationChain chain = mapping.getEndpoint(messageContext);
Assert.assertNotNull("MethodEndpoint not registered", chain);
MethodEndpoint expected = new MethodEndpoint(applicationContext.getBean("endpoint"), "doIt", new Class[0]);
Assert.assertEquals("Invalid endpoint registered", expected, chain.getEndpoint());
assertNotNull("MethodEndpoint not registered", chain);
MethodEndpoint expected = new MethodEndpoint(applicationContext.getBean("endpoint"), "doIt");
assertEquals("Invalid endpoint registered", expected, chain.getEndpoint());
assertEquals("No smart interceptors registered", 2, chain.getInterceptors().length);
assertTrue(chain.getInterceptors()[0] instanceof AddressingEndpointInterceptor);
assertTrue(chain.getInterceptors()[1] instanceof MyInterceptor);
}
private MessageContext createMessageContext() throws SOAPException, IOException {
@@ -96,22 +88,20 @@ public class AnnotationActionMethodEndpointMappingTest {
}
}
@Endpoint
private static class Endpoint1 {
@Action("http://fabrikam123.example/mail/Delete")
public void doIt() {
}
}
@Endpoint
@Address("mailto:joe@fabrikam123.example")
private static class Endpoint2 {
private static class MyEndpoint {
@Action("http://fabrikam123.example/mail/Delete")
public void doIt() {
}
}
private static class MyInterceptor extends DelegatingSmartEndpointInterceptor {
public MyInterceptor() {
super(new PayloadLoggingInterceptor());
}
}
}