#510 - Added Spring Integration dynamic service activator based on PluginRegistry.
See the ticket or test config file for usage.
This commit is contained in:
13
org.synyx.hera.si/.springBeans
Normal file
13
org.synyx.hera.si/.springBeans
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beansProjectDescription>
|
||||
<version>1</version>
|
||||
<pluginVersion><![CDATA[2.6.0.201104111100-PATCH]]></pluginVersion>
|
||||
<configSuffixes>
|
||||
<configSuffix><![CDATA[xml]]></configSuffix>
|
||||
</configSuffixes>
|
||||
<enableImports><![CDATA[false]]></enableImports>
|
||||
<configs>
|
||||
</configs>
|
||||
<configSets>
|
||||
</configSets>
|
||||
</beansProjectDescription>
|
||||
58
org.synyx.hera.si/pom.xml
Normal file
58
org.synyx.hera.si/pom.xml
Normal file
@@ -0,0 +1,58 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>org.synyx.hera</artifactId>
|
||||
<groupId>org.synyx.hera</groupId>
|
||||
<version>0.7.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
<groupId>org.synyx.hera</groupId>
|
||||
<artifactId>org.synyx.hera.si</artifactId>
|
||||
<version>0.7.0.BUILD-SNAPSHOT</version>
|
||||
<name>Hera Spring Integration integration</name>
|
||||
|
||||
<properties>
|
||||
<spring.integration.version>2.0.3.RELEASE</spring.integration.version>
|
||||
<spring.version>3.0.5.RELEASE</spring.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>org.synyx.hera.core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-core</artifactId>
|
||||
<version>${spring.integration.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright 2011 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.synyx.hera.si;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.MessageHandlingException;
|
||||
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.synyx.hera.core.Plugin;
|
||||
import org.synyx.hera.core.PluginRegistry;
|
||||
|
||||
/**
|
||||
* Dynamic service activator that uses a {@link PluginRegistry} to delegate execution to one or more plugins matching a
|
||||
* delimiter.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class PluginRegistryAwareMessageHandler extends AbstractReplyProducingMessageHandler {
|
||||
|
||||
private enum InvocationMethod {
|
||||
ONE, ALL;
|
||||
}
|
||||
|
||||
private final PluginRegistry<? extends Plugin<?>, Object> registry;
|
||||
private final Class<? extends Plugin<?>> pluginType;
|
||||
private final Class<?> delimitzerType;
|
||||
private final SpelExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
private Expression delimiterExpression;
|
||||
private Expression invocationArgumentsExpression;
|
||||
private String serviceMethodName;
|
||||
private InvocationMethod invocationMethod = InvocationMethod.ONE;
|
||||
|
||||
/**
|
||||
* Creates a new {@link PluginRegistryAwareMessageHandler} for the given {@link PluginRegistry}, pluginType and a
|
||||
* method name to call.
|
||||
*
|
||||
* @param registry
|
||||
* @param pluginType
|
||||
* @param serviceMethodName
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public PluginRegistryAwareMessageHandler(PluginRegistry<? extends Plugin<?>, ?> registry,
|
||||
Class<? extends Plugin<?>> pluginType, String serviceMethodName) {
|
||||
|
||||
Assert.notNull(registry);
|
||||
Assert.notNull(pluginType);
|
||||
Assert.hasText(serviceMethodName);
|
||||
|
||||
this.registry = (PluginRegistry<? extends Plugin<?>, Object>) registry;
|
||||
this.serviceMethodName = serviceMethodName;
|
||||
this.pluginType = pluginType;
|
||||
this.delimitzerType = GenericTypeResolver.resolveTypeArgument(pluginType, Plugin.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the SpEL expression to extract the delimiter from the {@link Message}.
|
||||
*
|
||||
* @param delimiterExpression the delimiterExpression to set
|
||||
*/
|
||||
public void setDelimiterExpression(String expression) {
|
||||
Assert.hasText(expression);
|
||||
this.delimiterExpression = parser.parseExpression(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the SpEL expression to extract the method arguments for the actual plugin method invocation from the
|
||||
* {@link Message}.
|
||||
*
|
||||
* @param invocationArgumentsExpression the invocationArgumentsExpression to set
|
||||
*/
|
||||
public void setInvocationArgumentsExpression(String expression) {
|
||||
Assert.hasText(expression);
|
||||
this.invocationArgumentsExpression = parser.parseExpression(expression);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.integration.handler.AbstractReplyProducingMessageHandler#handleRequestMessage(org.springframework.integration.Message)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected Object handleRequestMessage(Message<?> requestMessage) {
|
||||
|
||||
Object delimiter = getDelimiter(requestMessage);
|
||||
|
||||
switch (invocationMethod) {
|
||||
case ALL:
|
||||
return invokePlugins(registry.getPluginsFor(delimiter), requestMessage);
|
||||
case ONE:
|
||||
default:
|
||||
List<Object> results = invokePlugins(Arrays.asList(registry.getPluginFor(delimiter)), requestMessage);
|
||||
return results.isEmpty() ? null : results.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Object> invokePlugins(Iterable<? extends Plugin<?>> plugins, Message<?> message) {
|
||||
List<Object> results = new ArrayList<Object>();
|
||||
|
||||
for (Plugin<?> plugin : plugins) {
|
||||
|
||||
Object[] invocationArguments = getInvocationArguments(message);
|
||||
Class<?>[] types = getTypes(invocationArguments);
|
||||
|
||||
Method businessMethod = ReflectionUtils.findMethod(pluginType, serviceMethodName, types);
|
||||
|
||||
if (businessMethod == null) {
|
||||
throw new MessageHandlingException(message, String.format(
|
||||
"Did not find a method %s on %s taking the following parameters %s", serviceMethodName,
|
||||
pluginType.getName(), Arrays.toString(types)));
|
||||
}
|
||||
|
||||
Object result = ReflectionUtils.invokeMethod(businessMethod, plugin, invocationArguments);
|
||||
|
||||
if (!businessMethod.getReturnType().equals(void.class)) {
|
||||
results.add(result);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the delimiter object to be used for the given {@link Message}. Will use the configured delimiter expression
|
||||
* if configured.
|
||||
*
|
||||
* @param message
|
||||
* @return
|
||||
*/
|
||||
private Object getDelimiter(Message<?> message) {
|
||||
|
||||
Object delimiter = message;
|
||||
|
||||
if (delimiterExpression != null) {
|
||||
StandardEvaluationContext context = new StandardEvaluationContext(message);
|
||||
delimiter = delimiterExpression.getValue(context);
|
||||
}
|
||||
|
||||
Assert.isInstanceOf(delimitzerType, delimiter, String.format("Delimiter expression did "
|
||||
+ "not return a suitable delimiter! Make sure the expression evaluates to a suitable "
|
||||
+ "type! Got %s but need %s", delimiter.getClass(), delimitzerType));
|
||||
|
||||
return delimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the actual arguments to be used for the plugin method invocation. Will apply the configured invocation
|
||||
* argument expression to the given {@link Message}.
|
||||
*
|
||||
* @param message
|
||||
* @return
|
||||
*/
|
||||
private Object[] getInvocationArguments(Message<?> message) {
|
||||
|
||||
if (invocationArgumentsExpression == null) {
|
||||
return new Object[] { message };
|
||||
}
|
||||
|
||||
StandardEvaluationContext context = new StandardEvaluationContext(message);
|
||||
Object result = delimiterExpression.getValue(context);
|
||||
|
||||
return ObjectUtils.isArray(result) ? ObjectUtils.toObjectArray(result) : new Object[] { result };
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of types for the given objects. Inspects each element of the array for its type. will return
|
||||
* {@literal null} for {@literal null} source values.
|
||||
*
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
private Class<?>[] getTypes(Object[] source) {
|
||||
Class<?>[] result = new Class<?>[source.length];
|
||||
for (int i = 0; i < source.length; i++) {
|
||||
Object sourceElement = source[i];
|
||||
result[i] = sourceElement == null ? null : sourceElement.getClass();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2011 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.synyx.hera.si.config;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.config.xml.AbstractConsumerEndpointParser;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.synyx.hera.core.support.PluginRegistryFactoryBean;
|
||||
import org.synyx.hera.si.PluginRegistryAwareMessageHandler;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* {@link BeanDefinitionParser} to create {@link PluginRegistryAwareMessageHandler} beans.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class DynamicServiceActivatorParser extends AbstractConsumerEndpointParser {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.integration.config.xml.AbstractConsumerEndpointParser#parseHandler(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
|
||||
*/
|
||||
@Override
|
||||
protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) {
|
||||
|
||||
Object source = parserContext.extractSource(element);
|
||||
|
||||
String pluginType = element.getAttribute("plugin-type");
|
||||
String method = element.getAttribute("method");
|
||||
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(PluginRegistryAwareMessageHandler.class);
|
||||
builder.addConstructorArgValue(getRegistryBeanDefinition(pluginType, source));
|
||||
builder.addConstructorArgValue(pluginType);
|
||||
builder.addConstructorArgValue(method);
|
||||
|
||||
String delimiter = element.getAttribute("delimiter");
|
||||
|
||||
if (StringUtils.hasText(delimiter)) {
|
||||
builder.addPropertyValue("delimiterExpression", delimiter);
|
||||
}
|
||||
|
||||
String invocationArguments = element.getAttribute("invocation-arguments");
|
||||
|
||||
if (StringUtils.hasText(invocationArguments)) {
|
||||
builder.addPropertyValue("invocationArgumentsExpression", invocationArguments);
|
||||
}
|
||||
|
||||
AbstractBeanDefinition definition = builder.getBeanDefinition();
|
||||
definition.setSource(source);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link BeanDefinition} for a {@link PluginRegistryFactoryBean}.
|
||||
*
|
||||
* @param pluginType
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
private AbstractBeanDefinition getRegistryBeanDefinition(String pluginType, Object source) {
|
||||
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(PluginRegistryFactoryBean.class);
|
||||
builder.addPropertyValue("type", pluginType);
|
||||
|
||||
AbstractBeanDefinition definition = builder.getBeanDefinition();
|
||||
definition.setSource(source);
|
||||
return definition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2011 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.synyx.hera.si.config;
|
||||
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.NamespaceHandler;
|
||||
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
||||
|
||||
/**
|
||||
* {@link NamespaceHandler} to register {@link BeanDefinitionParser}s.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class HeraSpringIntegrationNamespaceHandler extends NamespaceHandlerSupport {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.xml.NamespaceHandler#init()
|
||||
*/
|
||||
public void init() {
|
||||
registerBeanDefinitionParser("dynamic-service-activator", new DynamicServiceActivatorParser());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
http\://schemas.synyx.org/hera/si=org.synyx.hera.si.config.HeraSpringIntegrationNamespaceHandler
|
||||
@@ -0,0 +1 @@
|
||||
http\://schemas.synyx.org/hera/si/hera-si.xsd=org/synyx/hera/si/config/hera-si.xsd
|
||||
@@ -0,0 +1,4 @@
|
||||
# Tooling related information for the Hera namespace
|
||||
http\://schemas.synyx.org/hera/si@name=Hera Spring Integration Namespace
|
||||
http\://schemas.synyx.org/hera/si@prefix=int-hera
|
||||
http\://schemas.synyx.org/hera/si@icon=org/springframework/beans/factory/xml/spring-beans.gif
|
||||
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<xsd:schema xmlns="http://schemas.synyx.org/hera/si" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:tool="http://www.springframework.org/schema/tool"
|
||||
targetNamespace="http://schemas.synyx.org/hera/si" elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool" />
|
||||
|
||||
<xsd:element name="dynamic-service-activator">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
This service activator will be backed by a Hera Plugin registry that
|
||||
allows dynamic invocation of Spring beans implementing the plugin
|
||||
interface defined in "plugin-type". We will dynamically pick up all
|
||||
Spring beans implementing that interface and create a PluginRegistry
|
||||
of those. See org.synyx.hera.si.PluginRegistryAwareMessageHandler for
|
||||
details.
|
||||
</xsd:documentation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="input-channel" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>The input channel to listen to.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="plugin-type" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>The type of Spring beans to dynamically pick up.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="method" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>The method to be invoked on the plugin(s) selected.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="output-channel" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>The output channel to publish invocation results to.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="delimiter" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
A SpEL expression to extract the delimiter to be used from the
|
||||
incoming Message. If not set the entire Message will be used as
|
||||
delimiter.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="invocation-arguments" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
A SpEL expression to extract the arguments for the actual method
|
||||
invocation.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2011 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.synyx.hera.si;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.MessageHandlingException;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.synyx.hera.core.OrderAwarePluginRegistry;
|
||||
import org.synyx.hera.core.PluginRegistry;
|
||||
import org.synyx.hera.si.sample.FirstSamplePluginImpl;
|
||||
import org.synyx.hera.si.sample.SamplePlugin;
|
||||
import org.synyx.hera.si.sample.SecondSamplePluginImpl;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link PluginRegistryAwareMessageHandler}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class PluginRegistryAwareMessageHandlerUnitTest {
|
||||
|
||||
PluginRegistry<SamplePlugin, String> registry = OrderAwarePluginRegistry.create(Arrays.asList(
|
||||
new FirstSamplePluginImpl(), new SecondSamplePluginImpl()));
|
||||
PluginRegistryAwareMessageHandler handler = new PluginRegistryAwareMessageHandler(registry, SamplePlugin.class,
|
||||
"myBusinessMethod");
|
||||
|
||||
@Test
|
||||
public void routesInvocationToFirstpluginIfConfiguredToDoSo() {
|
||||
|
||||
handler.setDelimiterExpression("payload");
|
||||
handler.setInvocationArgumentsExpression("payload");
|
||||
|
||||
Message<String> message = MessageBuilder.withPayload("FOO").build();
|
||||
handler.handleMessage(message);
|
||||
}
|
||||
|
||||
@Test(expected=MessageHandlingException.class)
|
||||
public void failsHandlingMessageIfDelimiterTypeDoesNotMatch() {
|
||||
|
||||
Message<String> message = MessageBuilder.withPayload("FOO").build();
|
||||
handler.handleMessage(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2011 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.synyx.hera.si.config;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.MessageChannel;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* Integration test for the namespace.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("classpath:dynamic-service-activator-test-context.xml")
|
||||
public class DynamicServiceActivatorNamespaceIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("sampleChannel")
|
||||
MessageChannel channel;
|
||||
|
||||
@Test
|
||||
public void invokesPluginBasedOnPayload() {
|
||||
|
||||
Message<String> message = MessageBuilder.withPayload("FOO").build();
|
||||
channel.send(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.synyx.hera.si.sample;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class FirstSamplePluginImpl implements SamplePlugin {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.synyx.hera.core.Plugin#supports(java.lang.Object)
|
||||
*/
|
||||
public boolean supports(String delimiter) {
|
||||
return "FOO".equals(delimiter);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.synyx.hera.si.sample.SamplePlugin#myBusinessMethod()
|
||||
*/
|
||||
public void myBusinessMethod(String message) {
|
||||
System.out.println("First plugin invoked! " + message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.synyx.hera.si.sample;
|
||||
|
||||
import org.synyx.hera.core.Plugin;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface SamplePlugin extends Plugin<String> {
|
||||
|
||||
void myBusinessMethod(String message);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.synyx.hera.si.sample;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class SecondSamplePluginImpl implements SamplePlugin {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.synyx.hera.core.Plugin#supports(java.lang.Object)
|
||||
*/
|
||||
public boolean supports(String delimiter) {
|
||||
return "BAR".equals(delimiter);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.synyx.hera.si.sample.SamplePlugin#myBusinessMethod()
|
||||
*/
|
||||
public void myBusinessMethod(String message) {
|
||||
System.out.println("Second plugin invoked! " + message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?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:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-hera="http://schemas.synyx.org/hera/si"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://schemas.synyx.org/hera/si http://schemas.synyx.org/hera/si/hera-si.xsd">
|
||||
|
||||
<bean class="org.synyx.hera.si.sample.FirstSamplePluginImpl" />
|
||||
<bean class="org.synyx.hera.si.sample.SecondSamplePluginImpl" />
|
||||
|
||||
<int-hera:dynamic-service-activator
|
||||
input-channel="sampleChannel"
|
||||
output-channel="foo"
|
||||
plugin-type="org.synyx.hera.si.sample.SamplePlugin"
|
||||
method="myBusinessMethod"
|
||||
delimiter="payload"
|
||||
invocation-arguments="payload" />
|
||||
|
||||
<int:channel id="sampleChannel" />
|
||||
|
||||
<int:channel id="foo" />
|
||||
|
||||
</beans>
|
||||
13
org.synyx.hera.si/template.mf
Normal file
13
org.synyx.hera.si/template.mf
Normal file
@@ -0,0 +1,13 @@
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-SymbolicName: ${project.artifactId}
|
||||
Bundle-Name: ${project.name}
|
||||
Bundle-Vendor: Synyx GmbH & Co. KG
|
||||
Bundle-Version: ${project.version}
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Export-Template:
|
||||
${project.artifactId}.*;version="${project.version}"
|
||||
Import-Template:
|
||||
org.synyx.hera.core.*;version="${project.version:[=.=.=.=,+1.0.0)}",
|
||||
org.springframework.*;version="${spring.version:[=.=.=.=,+2.0.0)}",
|
||||
org.springframework.integration.*;version="${spring.integration.version:[=.=.=.=,+1.0.0)}",
|
||||
org.w3c.dom.*;version="0"
|
||||
Reference in New Issue
Block a user