Skip to content

Commit

Permalink
WS-Addressing EMs support SmartEndpointInterceptor
Browse files Browse the repository at this point in the history
All WS-Addressing EndpointsMappings now support endpoint interceptors
registered via a <sws:interceptors/> block (i.e.
SmartEndpointInteceptors).

Issue: SWS-874
  • Loading branch information
Arjen Poutsma committed Apr 23, 2014
1 parent bbc6bf5 commit d43b880
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
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;

Expand All @@ -37,8 +35,7 @@
* @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";
Expand All @@ -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() {
Expand Down Expand Up @@ -85,11 +81,6 @@ public void setFaultActionSuffix(String faultActionSuffix) {
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();
Expand Down Expand Up @@ -143,8 +134,8 @@ protected void registerEndpoint(URI action, Object endpoint) throws BeansExcepti

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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -64,7 +72,7 @@
* @since 1.5.0
*/
public abstract class AbstractAddressingEndpointMapping extends TransformerObjectSupport
implements SoapEndpointMapping, InitializingBean, Ordered {
implements SoapEndpointMapping, ApplicationContextAware, InitializingBean, Ordered {

private String[] actorsOrRoles;

Expand All @@ -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


Expand Down Expand Up @@ -115,7 +128,17 @@ public final void setUltimateReceiver(boolean ultimateReceiver) {
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;
}
Expand Down Expand Up @@ -210,12 +233,21 @@ public final void setVersions(AddressingVersion[] versions) {
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 {
Expand Down Expand Up @@ -253,15 +285,17 @@ private EndpointInvocationChain getEndpointInvocationChain(Object endpoint,
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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -23,24 +23,24 @@
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;
Expand All @@ -55,31 +55,23 @@ public void setUp() throws Exception {
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 {
Expand All @@ -97,21 +89,19 @@ private MessageContext createMessageContext() throws SOAPException, IOException
}

@Endpoint
private static class Endpoint1 {
@Address("mailto:joe@fabrikam123.example")
private static class MyEndpoint {

@Action("http://fabrikam123.example/mail/Delete")
public void doIt() {

}
}

@Endpoint
@Address("mailto:joe@fabrikam123.example")
private static class Endpoint2 {
private static class MyInterceptor extends DelegatingSmartEndpointInterceptor {

@Action("http://fabrikam123.example/mail/Delete")
public void doIt() {

}
}
public MyInterceptor() {
super(new PayloadLoggingInterceptor());
}
}
}

0 comments on commit d43b880

Please sign in to comment.