SWS-670 - sws:interceptors

This commit is contained in:
Arjen Poutsma
2010-12-17 13:41:37 +00:00
parent df9d82ac0f
commit 16dfd55af0
15 changed files with 801 additions and 68 deletions

View File

@@ -0,0 +1,125 @@
/*
* Copyright 2005-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.config;
import java.util.List;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.xml.DomUtils;
import org.springframework.ws.server.SmartEndpointInterceptor;
import org.springframework.ws.server.endpoint.interceptor.DelegatingSmartEndpointInterceptor;
import org.springframework.ws.server.endpoint.interceptor.PayloadRootSmartEndpointInterceptor;
import org.springframework.ws.soap.server.endpoint.interceptor.SoapActionSmartEndpointInterceptor;
import org.w3c.dom.Element;
/**
* Parser for the {@code <sws:interceptors/>} element.
*
* @author Arjen Poutsma
* @since 2.0
*/
class InterceptorsBeanDefinitionParser implements BeanDefinitionParser {
public BeanDefinition parse(Element element, ParserContext parserContext) {
CompositeComponentDefinition compDefinition =
new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
parserContext.pushContainingComponent(compDefinition);
List<Element> childElements = DomUtils.getChildElements(element);
for (Element childElement : childElements) {
if ("bean".equals(childElement.getLocalName())) {
RootBeanDefinition smartInterceptorDef =
createSmartInterceptorDefinition(DelegatingSmartEndpointInterceptor.class, childElement,
parserContext);
BeanDefinitionHolder interceptorDef = createInterceptorDefinition(parserContext, childElement);
smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorDef);
registerSmartInterceptor(parserContext, smartInterceptorDef);
}
else if ("payloadRoot".equals(childElement.getLocalName())) {
List<Element> beanElements = DomUtils.getChildElementsByTagName(childElement, "bean");
for (Element beanElement : beanElements) {
RootBeanDefinition smartInterceptorDef =
createSmartInterceptorDefinition(PayloadRootSmartEndpointInterceptor.class, childElement,
parserContext);
BeanDefinitionHolder interceptorDef = createInterceptorDefinition(parserContext, beanElement);
String namespaceUri = childElement.getAttribute("namespaceUri");
String localPart = childElement.getAttribute("localPart");
smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorDef);
smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, namespaceUri);
smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(2, localPart);
registerSmartInterceptor(parserContext, smartInterceptorDef);
}
}
else if ("soapAction".equals(childElement.getLocalName())) {
List<Element> beanElements = DomUtils.getChildElementsByTagName(childElement, "bean");
for (Element beanElement : beanElements) {
RootBeanDefinition smartInterceptorDef =
createSmartInterceptorDefinition(SoapActionSmartEndpointInterceptor.class, childElement,
parserContext);
BeanDefinitionHolder interceptorDef = createInterceptorDefinition(parserContext, beanElement);
String soapAction = childElement.getAttribute("value");
smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, interceptorDef);
smartInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, soapAction);
registerSmartInterceptor(parserContext, smartInterceptorDef);
}
}
}
parserContext.popAndRegisterContainingComponent();
return null;
}
private void registerSmartInterceptor(ParserContext parserContext, RootBeanDefinition smartInterceptorDef) {
String mappedInterceptorName =
parserContext.getReaderContext().registerWithGeneratedName(smartInterceptorDef);
parserContext
.registerComponent(new BeanComponentDefinition(smartInterceptorDef, mappedInterceptorName));
}
private BeanDefinitionHolder createInterceptorDefinition(ParserContext parserContext, Element element) {
BeanDefinitionHolder interceptorDef =
parserContext.getDelegate().parseBeanDefinitionElement(element);
interceptorDef =
parserContext.getDelegate().decorateBeanDefinitionIfRequired(element, interceptorDef);
return interceptorDef;
}
private RootBeanDefinition createSmartInterceptorDefinition(Class<? extends SmartEndpointInterceptor> interceptorClass,
Element element,
ParserContext parserContext) {
RootBeanDefinition smartInterceptorDef = new RootBeanDefinition(interceptorClass);
smartInterceptorDef.setSource(parserContext.extractSource(element));
smartInterceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
return smartInterceptorDef;
}
}

View File

@@ -29,9 +29,10 @@ public class WebServicesNamespaceHandler extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
registerBeanDefinitionParser("marshalling-endpoints", new MarshallingEndpointsBeanDefinitionParser());
registerBeanDefinitionParser("xpath-endpoints", new XPathEndpointsBeanDefinitionParser());
registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser());
registerBeanDefinitionParser("static-wsdl", new StaticWsdlBeanDefinitionParser());
registerBeanDefinitionParser("dynamic-wsdl", new DynamicWsdlBeanDefinitionParser());
registerBeanDefinitionParser("marshalling-endpoints", new MarshallingEndpointsBeanDefinitionParser());
registerBeanDefinitionParser("xpath-endpoints", new XPathEndpointsBeanDefinitionParser());
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2005-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.server;
import org.springframework.ws.context.MessageContext;
/**
* Extension of the {@link EndpointInterceptor} interface that adds a way to
* @author Arjen Poutsma
* @since 2.0
*/
public interface SmartEndpointInterceptor extends EndpointInterceptor {
/**
* Indicates whether this interceptor should intercept the given message context.
*
* @param messageContext contains the incoming request message
* @param endpoint chosen endpoint to invoke
* @return {@code true} to indicate that this interceptor applies; {@code false} otherwise
*/
boolean shouldIntercept(MessageContext messageContext, Object endpoint);
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright 2005-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.server.endpoint.interceptor;
import org.springframework.util.Assert;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.EndpointInterceptor;
import org.springframework.ws.server.SmartEndpointInterceptor;
/**
* Implementation of the {@link SmartEndpointInterceptor} interface that delegates to a delegate {@link
* EndpointInterceptor}.
*
* @author Arjen Poutsma
* @since 2.0
*/
public class DelegatingSmartEndpointInterceptor implements SmartEndpointInterceptor {
private final EndpointInterceptor delegate;
/**
* Creates a new instance of the {@code DelegatingSmartEndpointInterceptor} with the given delegate.
*
* @param delegate the endpoint interceptor to delegate to.
*/
public DelegatingSmartEndpointInterceptor(EndpointInterceptor delegate) {
Assert.notNull(delegate, "'delegate' must not be null");
this.delegate = delegate;
}
/**
* {@inheritDoc}
* <p/>
* This implementation delegates to {@link #shouldIntercept(WebServiceMessage, Object)}.
*/
public boolean shouldIntercept(MessageContext messageContext, Object endpoint) {
WebServiceMessage request = messageContext.getRequest();
return request != null && shouldIntercept(request, endpoint);
}
/**
* Indicates whether this interceptor should intercept the given request message.
* <p/>
* This implementation always returns {@code true}.
*
* @param request the request message
* @param endpoint chosen endpoint to invoke
* @return {@code true} to indicate that this interceptor applies; {@code false} otherwise
*/
protected boolean shouldIntercept(WebServiceMessage request, Object endpoint) {
return true;
}
public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
return delegate.handleRequest(messageContext, endpoint);
}
public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
return delegate.handleResponse(messageContext, endpoint);
}
public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
return delegate.handleFault(messageContext, endpoint);
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright 2005-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.server.endpoint.interceptor;
import javax.xml.namespace.QName;
import javax.xml.transform.TransformerException;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.server.EndpointInterceptor;
import org.springframework.ws.server.endpoint.support.PayloadRootUtils;
import org.springframework.xml.transform.TransformerHelper;
/**
* Implementation of the {@link org.springframework.ws.server.SmartEndpointInterceptor} interface that only intercepts
* requests that have a specified namespace URI or local part (or both) as payload root.
*
* @author Arjen Poutsma
* @since 2.0
*/
public class PayloadRootSmartEndpointInterceptor extends DelegatingSmartEndpointInterceptor {
private TransformerHelper transformerHelper = new TransformerHelper();
private final String namespaceUri;
private final String localPart;
public PayloadRootSmartEndpointInterceptor(EndpointInterceptor delegate, String namespaceUri, String localPart) {
super(delegate);
Assert.hasLength(namespaceUri, "namespaceUri can not be empty");
this.namespaceUri = namespaceUri;
this.localPart = localPart;
}
public void setTransformerHelper(TransformerHelper transformerHelper) {
this.transformerHelper = transformerHelper;
}
@Override
protected boolean shouldIntercept(WebServiceMessage request, Object endpoint) {
try {
QName payloadRootName = PayloadRootUtils.getPayloadRootQName(request.getPayloadSource(), transformerHelper);
return !(StringUtils.hasLength(namespaceUri) && !namespaceUri.equals(payloadRootName.getNamespaceURI()) ||
StringUtils.hasLength(localPart) && !localPart.equals(payloadRootName.getLocalPart()));
}
catch (TransformerException e) {
return false;
}
}
}

View File

@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -57,6 +57,7 @@ public abstract class AbstractAnnotationMethodEndpointMapping<T> extends Abstrac
@Override
protected final void initApplicationContext() throws BeansException {
super.initApplicationContext();
if (logger.isDebugEnabled()) {
logger.debug("Looking for endpoints in application context: " + getApplicationContext());
}

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2005 the original author or authors.
* Copyright 2005-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,12 +16,20 @@
package org.springframework.ws.server.endpoint.mapping;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.core.Ordered;
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;
/**
* Abstract base class for EndpointMapping implementations. Supports a default endpoint, and endpoint interceptors.
@@ -39,6 +47,8 @@ public abstract class AbstractEndpointMapping extends ApplicationObjectSupport i
private EndpointInterceptor[] interceptors;
private SmartEndpointInterceptor[] smartInterceptors;
/**
* Returns the the endpoint interceptors to apply to all endpoints mapped by this endpoint mapping.
*
@@ -72,6 +82,30 @@ public abstract class AbstractEndpointMapping extends ApplicationObjectSupport i
this.order = order;
}
/**
* Initializes the interceptors.
*
* @see #initInterceptors()
*/
@Override
protected void initApplicationContext() throws BeansException {
initInterceptors();
}
/**
* Initialize the specified interceptors, adapting them where necessary.
*
* @see #setInterceptors
*/
protected void initInterceptors() {
Map<String, SmartEndpointInterceptor> smartInterceptors = BeanFactoryUtils
.beansOfTypeIncludingAncestors(getApplicationContext(), SmartEndpointInterceptor.class, true, false);
if (!smartInterceptors.isEmpty()) {
this.smartInterceptors =
smartInterceptors.values().toArray(new SmartEndpointInterceptor[smartInterceptors.size()]);
}
}
/**
* Look up an endpoint for the given message context, falling back to the default endpoint if no specific one is
* found.
@@ -94,7 +128,22 @@ public abstract class AbstractEndpointMapping extends ApplicationObjectSupport i
return null;
}
}
return createEndpointInvocationChain(messageContext, endpoint, interceptors);
List<EndpointInterceptor> interceptors = new ArrayList<EndpointInterceptor>();
if (this.interceptors != null) {
interceptors.addAll(Arrays.asList(this.interceptors));
}
if (this.smartInterceptors != null) {
for (SmartEndpointInterceptor smartInterceptor : smartInterceptors) {
if (smartInterceptor.shouldIntercept(messageContext, endpoint)) {
interceptors.add(smartInterceptor);
}
}
}
return createEndpointInvocationChain(messageContext, endpoint,
interceptors.toArray(new EndpointInterceptor[interceptors.size()]));
}
/**
@@ -139,7 +188,7 @@ public abstract class AbstractEndpointMapping extends ApplicationObjectSupport i
* context.
*
* @param endpointName the endpoint name
* @return the resolved enpoint, or <code>null</code> if the name could not be resolved
* @return the resolved endpoint, or <code>null</code> if the name could not be resolved
*/
protected Object resolveStringEndpoint(String endpointName) {
if (getApplicationContext().containsBean(endpointName)) {

View File

@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -167,6 +167,7 @@ public abstract class AbstractMapBasedEndpointMapping extends AbstractEndpointMa
*/
@Override
protected final void initApplicationContext() throws BeansException {
super.initApplicationContext();
for (String key : temporaryEndpointMap.keySet()) {
Object endpoint = temporaryEndpointMap.get(key);
if (!validateLookupKey(key)) {

View File

@@ -0,0 +1,57 @@
/*
* Copyright 2005-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.soap.server.endpoint.interceptor;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.server.EndpointInterceptor;
import org.springframework.ws.server.endpoint.interceptor.DelegatingSmartEndpointInterceptor;
import org.springframework.ws.soap.SoapMessage;
/**
* Implementation of the {@link org.springframework.ws.server.SmartEndpointInterceptor} interface that only intercepts
* requests that have a specified soap action.
*
* @author Arjen Poutsma
* @since 2.0
*/
public class SoapActionSmartEndpointInterceptor extends DelegatingSmartEndpointInterceptor {
private final String soapAction;
public SoapActionSmartEndpointInterceptor(EndpointInterceptor delegate, String soapAction) {
super(delegate);
Assert.hasLength(soapAction, "soapAction can not be empty");
this.soapAction = soapAction;
}
@Override
protected boolean shouldIntercept(WebServiceMessage request, Object endpoint) {
if (request instanceof SoapMessage) {
String soapAction = ((SoapMessage) request).getSoapAction();
if (StringUtils.hasLength(soapAction) && soapAction.charAt(0) == '"' &&
soapAction.charAt(soapAction.length() - 1) == '"') {
soapAction = soapAction.substring(1, soapAction.length() - 1);
}
return this.soapAction.equals(soapAction);
}
else {
return false;
}
}
}

View File

@@ -53,6 +53,64 @@
</xsd:complexType>
</xsd:element>
<xsd:element name="interceptors">
<xsd:annotation>
<xsd:documentation>
The ordered set of interceptors that intercept web service messages handled by endpoints.
Interceptors allow requests to be pre/post processed before/after handling.
Each interceptor must implement the org.springframework.ws.server.EndpointInterceptor interface.
The interceptors in this set are automatically configured on each registered EndpointMapping.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element ref="beans:bean">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.ws.server.endpoint.interceptor.DelegatingSmartEndpointInterceptor">
Registers an interceptor that intercepts every request.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="payloadRoot">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.ws.server.endpoint.interceptor.DelegatingSmartEndpointInterceptor"><![CDATA[
Registers an interceptor that intercepts requests that have the specified namespace URI and local part as
payload root.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence maxOccurs="unbounded">
<xsd:element ref="beans:bean">
<xsd:annotation>
<xsd:documentation>The interceptor's bean definition.</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="namespaceUri" type="xsd:anyURI" use="required" />
<xsd:attribute name="localPart" type="xsd:anyURI" />
</xsd:complexType>
</xsd:element>
<xsd:element name="soapAction">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.ws.server.endpoint.interceptor.DelegatingSmartEndpointInterceptor"><![CDATA[
Registers an interceptor that intercepts requests that have the specified SOAP Action.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence maxOccurs="unbounded">
<xsd:element ref="beans:bean">
<xsd:annotation>
<xsd:documentation>The interceptor's bean definition.</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="value" type="xsd:anyURI" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
<xsd:element name="static-wsdl">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.ws.wsdl.wsdl11.SimpleWsdl11Definition"><![CDATA[

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2005-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.config;
import java.util.Map;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.ws.server.endpoint.interceptor.DelegatingSmartEndpointInterceptor;
import org.springframework.ws.server.endpoint.interceptor.PayloadRootSmartEndpointInterceptor;
import org.springframework.ws.soap.server.endpoint.interceptor.SoapActionSmartEndpointInterceptor;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class InterceptorsBeanDefinitionParserTest {
private ApplicationContext applicationContext;
@Before
public void setUp() throws Exception {
applicationContext = new ClassPathXmlApplicationContext("interceptorsBeanDefinitionParserTest.xml", getClass());
}
@Test
public void namespace() throws Exception {
Map<String, ?> result = applicationContext.getBeansOfType(DelegatingSmartEndpointInterceptor.class);
assertEquals("no smart interceptors found", 5, result.size());
result = applicationContext.getBeansOfType(PayloadRootSmartEndpointInterceptor.class);
assertEquals("no interceptors found", 2, result.size());
result = applicationContext.getBeansOfType(SoapActionSmartEndpointInterceptor.class);
assertEquals("no interceptors found", 2, result.size());
}
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright 2005-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.server.endpoint.interceptor;
import org.springframework.ws.MockWebServiceMessage;
import org.springframework.ws.MockWebServiceMessageFactory;
import org.springframework.ws.context.DefaultMessageContext;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.EndpointInterceptor;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class PayloadRootSmartEndpointInterceptorTest {
private EndpointInterceptor delegate;
private String namespaceUri;
private String localPart;
private MessageContext messageContext;
@Before
public void setUp() {
delegate = new EndpointInterceptorAdapter();
namespaceUri = "http://springframework.org/spring-ws";
localPart = "element";
MockWebServiceMessage request = new MockWebServiceMessage("<" + localPart + " xmlns=\"" + namespaceUri + "\" />");
messageContext = new DefaultMessageContext(request, new MockWebServiceMessageFactory());
}
@Test(expected = IllegalArgumentException.class)
public void neitherNamespaceNorLocalPart() {
new PayloadRootSmartEndpointInterceptor(delegate, null, null);
}
@Test
public void shouldInterceptFullMatch() throws Exception {
PayloadRootSmartEndpointInterceptor interceptor =
new PayloadRootSmartEndpointInterceptor(delegate, namespaceUri, localPart);
boolean result = interceptor.shouldIntercept(messageContext, null);
assertTrue("Interceptor should apply", result);
}
@Test
public void shouldInterceptFullNonMatch() throws Exception {
PayloadRootSmartEndpointInterceptor interceptor =
new PayloadRootSmartEndpointInterceptor(delegate, "http://springframework.org/other", localPart);
boolean result = interceptor.shouldIntercept(messageContext, null);
assertFalse("Interceptor should apply", result);
}
@Test
public void shouldInterceptNamespaceUriMatch() throws Exception {
PayloadRootSmartEndpointInterceptor interceptor =
new PayloadRootSmartEndpointInterceptor(delegate, namespaceUri, null);
boolean result = interceptor.shouldIntercept(messageContext, null);
assertTrue("Interceptor should apply", result);
}
@Test
public void shouldInterceptLocalPartMatch() throws Exception {
PayloadRootSmartEndpointInterceptor interceptor =
new PayloadRootSmartEndpointInterceptor(delegate, null, localPart);
boolean result = interceptor.shouldIntercept(messageContext, null);
assertTrue("Interceptor should apply", result);
}
}

View File

@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,90 +17,108 @@
package org.springframework.ws.server.endpoint.mapping;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.ws.MockWebServiceMessageFactory;
import org.springframework.ws.context.DefaultMessageContext;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.EndpointInterceptor;
import org.springframework.ws.server.EndpointInvocationChain;
import org.springframework.ws.server.endpoint.interceptor.DelegatingSmartEndpointInterceptor;
import org.springframework.ws.server.endpoint.interceptor.EndpointInterceptorAdapter;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import static org.easymock.EasyMock.*;
import static org.junit.Assert.*;
/**
* Test case for {@link AbstractEndpointMapping}.
*/
public class EndpointMappingTest {
private MessageContext mockContext;
private MessageContext messageContext;
@Before
public void setUp() throws Exception {
mockContext = createMock(MessageContext.class);
messageContext = new DefaultMessageContext(new MockWebServiceMessageFactory());
}
@Test
public void testDefaultEndpoint() throws Exception {
public void defaultEndpoint() throws Exception {
Object defaultEndpoint = new Object();
AbstractEndpointMapping mapping = new AbstractEndpointMapping() {
@Override
protected Object getEndpointInternal(MessageContext givenRequest) throws Exception {
Assert.assertEquals("Invalid request passed", mockContext, givenRequest);
assertEquals("Invalid request passed", messageContext, givenRequest);
return null;
}
};
mapping.setDefaultEndpoint(defaultEndpoint);
replay(mockContext);
EndpointInvocationChain result = mapping.getEndpoint(mockContext);
Assert.assertNotNull("No EndpointInvocatioChain returned", result);
Assert.assertEquals("Default Endpoint not returned", defaultEndpoint, result.getEndpoint());
verify(mockContext);
EndpointInvocationChain result = mapping.getEndpoint(messageContext);
assertNotNull("No EndpointInvocatioChain returned", result);
assertEquals("Default Endpoint not returned", defaultEndpoint, result.getEndpoint());
}
@Test
public void testEndpoint() throws Exception {
public void endpoint() throws Exception {
final Object endpoint = new Object();
AbstractEndpointMapping mapping = new AbstractEndpointMapping() {
@Override
protected Object getEndpointInternal(MessageContext givenRequest) throws Exception {
Assert.assertEquals("Invalid request passed", mockContext, givenRequest);
assertEquals("Invalid request passed", messageContext, givenRequest);
return endpoint;
}
};
replay(mockContext);
EndpointInvocationChain result = mapping.getEndpoint(mockContext);
Assert.assertNotNull("No EndpointInvocatioChain returned", result);
Assert.assertEquals("Unexpected Endpoint returned", endpoint, result.getEndpoint());
verify(mockContext);
EndpointInvocationChain result = mapping.getEndpoint(messageContext);
assertNotNull("No EndpointInvocationChain returned", result);
assertEquals("Unexpected Endpoint returned", endpoint, result.getEndpoint());
}
@Test
public void testEndpointInterceptors() throws Exception {
public void endpointInterceptors() throws Exception {
final Object endpoint = new Object();
EndpointInterceptor interceptor = new EndpointInterceptorAdapter();
AbstractEndpointMapping mapping = new AbstractEndpointMapping() {
@Override
protected Object getEndpointInternal(MessageContext givenRequest) throws Exception {
Assert.assertEquals("Invalid request passed", mockContext, givenRequest);
assertEquals("Invalid request passed", messageContext, givenRequest);
return endpoint;
}
};
replay(mockContext);
mapping.setInterceptors(new EndpointInterceptor[]{interceptor});
EndpointInvocationChain result = mapping.getEndpoint(mockContext);
Assert.assertEquals("Unexpected amount of EndpointInterceptors returned", 1, result.getInterceptors().length);
Assert.assertEquals("Unexpected EndpointInterceptor returned", interceptor, result.getInterceptors()[0]);
verify(mockContext);
EndpointInvocationChain result = mapping.getEndpoint(messageContext);
assertEquals("Unexpected amount of EndpointInterceptors returned", 1, result.getInterceptors().length);
assertEquals("Unexpected EndpointInterceptor returned", interceptor, result.getInterceptors()[0]);
}
@Test
public void testEndpointBeanName() throws Exception {
public void smartEndpointInterceptors() throws Exception {
StaticApplicationContext applicationContext = new StaticApplicationContext();
applicationContext.registerSingleton("smartInterceptor", MySmartEndpointInterceptor.class);
final Object endpoint = new Object();
EndpointInterceptor interceptor = new EndpointInterceptorAdapter();
AbstractEndpointMapping mapping = new AbstractEndpointMapping() {
@Override
protected Object getEndpointInternal(MessageContext givenRequest) throws Exception {
assertEquals("Invalid request passed", messageContext, givenRequest);
return endpoint;
}
};
mapping.setApplicationContext(applicationContext);
mapping.setInterceptors(new EndpointInterceptor[]{interceptor});
EndpointInvocationChain result = mapping.getEndpoint(messageContext);
assertEquals("Unexpected amount of EndpointInterceptors returned", 2, result.getInterceptors().length);
assertEquals("Unexpected EndpointInterceptor returned", interceptor, result.getInterceptors()[0]);
assertTrue("Unexpected EndpointInterceptor returned",
result.getInterceptors()[1] instanceof MySmartEndpointInterceptor);
}
@Test
public void endpointBeanName() throws Exception {
StaticApplicationContext applicationContext = new StaticApplicationContext();
applicationContext.registerSingleton("endpoint", Object.class);
@@ -108,22 +126,18 @@ public class EndpointMappingTest {
@Override
protected Object getEndpointInternal(MessageContext message) throws Exception {
Assert.assertEquals("Invalid request", mockContext, message);
assertEquals("Invalid request", messageContext, message);
return "endpoint";
}
};
mapping.setApplicationContext(applicationContext);
replay(mockContext);
EndpointInvocationChain result = mapping.getEndpoint(mockContext);
Assert.assertNotNull("No endpoint returned", result);
verify(mockContext);
EndpointInvocationChain result = mapping.getEndpoint(messageContext);
assertNotNull("No endpoint returned", result);
}
@Test
public void testEndpointInvalidBeanName() throws Exception {
public void endpointInvalidBeanName() throws Exception {
StaticApplicationContext applicationContext = new StaticApplicationContext();
applicationContext.registerSingleton("endpoint", Object.class);
@@ -131,23 +145,19 @@ public class EndpointMappingTest {
@Override
protected Object getEndpointInternal(MessageContext message) throws Exception {
Assert.assertEquals("Invalid request", mockContext, message);
assertEquals("Invalid request", messageContext, message);
return "noSuchBean";
}
};
mapping.setApplicationContext(applicationContext);
replay(mockContext);
EndpointInvocationChain result = mapping.getEndpoint(messageContext);
EndpointInvocationChain result = mapping.getEndpoint(mockContext);
Assert.assertNull("No endpoint returned", result);
verify(mockContext);
assertNull("No endpoint returned", result);
}
@Test
public void testEndpointPrototype() throws Exception {
public void endpointPrototype() throws Exception {
StaticApplicationContext applicationContext = new StaticApplicationContext();
applicationContext.registerPrototype("endpoint", MyEndpoint.class);
@@ -155,29 +165,32 @@ public class EndpointMappingTest {
@Override
protected Object getEndpointInternal(MessageContext message) throws Exception {
Assert.assertEquals("Invalid request", mockContext, message);
assertEquals("Invalid request", messageContext, message);
return "endpoint";
}
};
mapping.setApplicationContext(applicationContext);
replay(mockContext);
EndpointInvocationChain result = mapping.getEndpoint(mockContext);
Assert.assertNotNull("No endpoint returned", result);
result = mapping.getEndpoint(mockContext);
Assert.assertNotNull("No endpoint returned", result);
Assert.assertEquals("Prototype endpoint was not constructed twice", 2, MyEndpoint.constrCount);
verify(mockContext);
EndpointInvocationChain result = mapping.getEndpoint(messageContext);
assertNotNull("No endpoint returned", result);
result = mapping.getEndpoint(messageContext);
assertNotNull("No endpoint returned", result);
assertEquals("Prototype endpoint was not constructed twice", 2, MyEndpoint.constructorCount);
}
private static class MyEndpoint {
private static int constrCount;
private static int constructorCount;
private MyEndpoint() {
constrCount++;
constructorCount++;
}
}
private static class MySmartEndpointInterceptor extends DelegatingSmartEndpointInterceptor {
private MySmartEndpointInterceptor() {
super(new EndpointInterceptorAdapter());
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright 2005-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.soap.server.endpoint.interceptor;
import org.springframework.ws.context.DefaultMessageContext;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.EndpointInterceptor;
import org.springframework.ws.server.endpoint.interceptor.EndpointInterceptorAdapter;
import org.springframework.ws.soap.saaj.SaajSoapMessage;
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class SoapActionSmartEndpointInterceptorTest {
private EndpointInterceptor delegate;
private String soapAction;
private MessageContext messageContext;
@Before
public void setUp() {
delegate = new EndpointInterceptorAdapter();
soapAction = "http://springframework.org/spring-ws";
SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory();
messageFactory.afterPropertiesSet();
SaajSoapMessage request = messageFactory.createWebServiceMessage();
request.setSoapAction(soapAction);
messageContext = new DefaultMessageContext(request, messageFactory);
}
@Test(expected = IllegalArgumentException.class)
public void neitherNamespaceNorLocalPart() {
new SoapActionSmartEndpointInterceptor(delegate, null);
}
@Test
public void shouldInterceptMatch() throws Exception {
SoapActionSmartEndpointInterceptor interceptor = new SoapActionSmartEndpointInterceptor(delegate, soapAction);
boolean result = interceptor.shouldIntercept(messageContext, null);
assertTrue("Interceptor should apply", result);
}
@Test
public void shouldInterceptNonMatch() throws Exception {
SoapActionSmartEndpointInterceptor interceptor =
new SoapActionSmartEndpointInterceptor(delegate, "http://springframework.org/other");
boolean result = interceptor.shouldIntercept(messageContext, null);
assertFalse("Interceptor should apply", result);
}
}

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sws="http://www.springframework.org/schema/web-services"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/web-services http://static.springframework.org/schema/web-services/web-services-2.0.xsd">
<sws:interceptors>
<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
<sws:payloadRoot namespaceUri="http://www.springframework.org/spring-ws">
<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
</sws:payloadRoot>
<sws:soapAction value="mySoapAction">
<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
</sws:soapAction>
</sws:interceptors>
</beans>