如何使用自己的XML配置实现自定义中介?
我正在尝试使用自己的XML配置为WSO2 ESB(4.5.1)实现自定义中介。 我可以使用中介作为类中介使用以下配置:
但是,我想要实现的是能够使用如下语法调用中介:
在WSO2 ESB关于此问题的可用帮助之后,我遇到以下错误,因为我尝试使用具有自己的XML配置的介体创建代理:
ERROR - MediatorFactoryFinder Unknown mediator referenced by configuration element : {test:mediator}TestMediator
不用说,我已经编写了两个文本文件,分别包含介体工厂和序列化程序类的完全限定类名,并将它们放在bundle jar文件的META-INF/services
目录中。
这是我的mediator类的源代码:
package test.synapse.mediator; import org.apache.synapse.MessageContext; import org.apache.synapse.mediators.AbstractMediator; public class TestMediator extends AbstractMediator { public boolean mediate(MessageContext context) { System.out.println("TestMediator mediating!"); return true; } }
这是我的中介工厂的代码:
package test.synapse.mediator; import java.util.Properties; import javax.xml.namespace.QName; import org.apache.axiom.om.OMElement; import org.apache.synapse.Mediator; import org.apache.synapse.config.xml.MediatorFactory; public class TestMediatorFactory implements MediatorFactory { public static final QName QNAME = new QName("test:mediator", "TestMediator"); @Override public Mediator createMediator(OMElement omElement, Properties properties) { return new TestMediator(); } @Override public QName getTagQName() { return QNAME; } }
以下是我的中介序列化程序的代码:
package test.synapse.mediator; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMFactory; import org.apache.synapse.Mediator; import org.apache.synapse.config.xml.MediatorSerializer; public class TestMediatorSerializer implements MediatorSerializer { public static final String MEDIATOR_CLASS_NAME = TestMediator.class.getName(); @Override public String getMediatorClassName() { return MEDIATOR_CLASS_NAME; } @Override public OMElement serializeMediator(OMElement parent, Mediator mediator) { OMFactory factory = OMAbstractFactory.getOMFactory(); OMElement element = factory.createOMElement(TestMediatorFactory.QNAME); parent.addChild(element); return element; } }
最后,项目的pom.xml文件有点冗长的内容:
4.0.0 test.synapse.mediator.TestMediator TestMediator 1.0.0 bundle TestMediator TestMediator org.apache.maven.plugins maven-compiler-plugin 2.0 1.5 1.5 org.apache.felix maven-bundle-plugin 2.3.4 true TestMediator TestMediator . test.synapse.mediator *; resolution:=optional synapse-core maven-eclipse-plugin 2.9 org.eclipse.jdt.core.javabuilder org.wso2.developerstudio.eclipse.artifact.mediator.project.nature org.eclipse.jdt.core.javanature src/main/resources/services META-INF/services daily ignore wso2-nexus http://maven.wso2.org/nexus/content/groups/wso2-public/ daily ignore wso2-nexus http://maven.wso2.org/nexus/content/groups/wso2-public/ commons-httpclient.wso2 commons-httpclient 3.1.0.wso2v2 commons-codec.wso2 commons-codec 1.4.0.wso2v1 org.apache.synapse synapse-core 2.1.0-wso2v7 wsdl4j.wso2 wsdl4j 1.6.2.wso2v4 org.apache.ws.commons.schema.wso2 XmlSchema 1.4.7.wso2v2 org.apache.abdera.wso2 abdera 1.0.0.wso2v3 org.apache.geronimo.specs.wso2 geronimo-stax-api_1.0_spec 1.0.1.wso2v2 org.apache.httpcomponents.wso2 httpcore 4.1.0-wso2v1 org.apache.neethi.wso2 neethi 2.0.4.wso2v4 org.apache.axis2.wso2 axis2 1.6.1.wso2v6 org.apache.woden.wso2 woden 1.0.0.M8-wso2v1 commons-logging commons-logging 1.1.1 org.apache.ws.commons.axiom.wso2 axiom 1.2.11.wso2v3 commons-io.wso2 commons-io 2.0.0.wso2v2 lib/synapse/mediator
我一直在尝试改变pom文件和代码的各个方面。 我注意到,如果我省略配置的Fragment-Host
部分,我可以使用类中介来调用中介。 如果存在Fragment-Host
元素,则调用调解器的方式都不起作用。
正如预期的那样,我正在使用apache Maven来构建项目的jar文件。 我将jar放到/repository/components/dropins
-directory中。
我尝试使用WSO2 ESB 4.5.1和4.7.0,结果完全相同。
我必须更改什么才能使自定义XML配置生效?
任何投入将不胜感激!
附件:
Dropbox: TestMediator.zip上的压缩源代码
Jar在Dropbox上使用maven构建: TestMediator-1.0.0.jar
看来WSO2 ESB本身显然存在一些错误,这导致包含中介及其工厂和序列化程序的包在其清单包含Fragment-Host
定义的情况下不会被加载我去了一个稍微复杂的场景让我的中介使用自定义XML配置来运行。
在捆绑包中使用了一个激活器类来确认它没有被加载,我发现我也可以使用激活MediatorSerializer
在ESB中手动注册MediatorFactory
和MediatorSerializer
类。
我通过为我的OSGI包编写以下激活器来完成此操作:
package test; import java.text.MessageFormat; import java.util.Map; import org.apache.synapse.config.xml.MediatorFactoryFinder; import org.apache.synapse.config.xml.MediatorSerializer; import org.apache.synapse.config.xml.MediatorSerializerFinder; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import test.synapse.mediator.TestMediator; import test.synapse.mediator.TestMediatorFactory; import test.synapse.mediator.TestMediatorSerializer; public class Activator implements BundleActivator { public void start(BundleContext context) throws Exception { { Map mediatorFactoryMap = MediatorFactoryFinder.getInstance().getFactoryMap(); mediatorFactoryMap.put(TestMediatorFactory.QNAME, TestMediatorFactory.class); } { Map mediatorSerializerMap = MediatorSerializerFinder.getInstance().getSerializerMap(); mediatorSerializerMap.put(TestMediator.class.getName(), TestMediatorSerializer.class.newInstance()); } } public void stop(BundleContext context) throws Exception { // Maybe undo what was done in the start(BundleContext) method..? System.out.println(this.getClass().getName() + ".stop(BundleContext) called"); } }
显然,需要将Activator类定义为bundle的激活器。 这是通过将以下节点添加到Instructions元素下的pom.xml bundle plugin配置来完成的:
test.Activator
使用这种手动注册工厂和序列化程序类的方法,不需要org.apache.synapse.config.xml.MediatorFactory
和org.apache.synapse.config.xml.MediatorSerializer
文件,可以从最终的jar中删除。
此外,需要从同一父节点中删除Fragment-Host
元素,以实际调用激活器类的start方法。
还需要添加包含BundleActivator
接口的osgi核心依赖项。
通过这样做,我们留下了以下完整的pom.xml文件:
4.0.0 test.synapse.mediator.TestMediator TestMediator 1.0.0 bundle TestMediator TestMediator org.apache.maven.plugins maven-compiler-plugin 2.0 1.5 1.5 org.apache.felix maven-bundle-plugin 2.3.4 true TestMediator TestMediator . test.Activator test.synapse.mediator *; resolution:=optional maven-eclipse-plugin 2.9 org.eclipse.jdt.core.javabuilder org.wso2.developerstudio.eclipse.artifact.mediator.project.nature org.eclipse.jdt.core.javanature daily ignore wso2-nexus http://maven.wso2.org/nexus/content/groups/wso2-public/ daily ignore wso2-nexus http://maven.wso2.org/nexus/content/groups/wso2-public/ commons-httpclient.wso2 commons-httpclient 3.1.0.wso2v2 commons-codec.wso2 commons-codec 1.4.0.wso2v1 org.apache.synapse synapse-core 2.1.0-wso2v7 wsdl4j.wso2 wsdl4j 1.6.2.wso2v4 org.apache.ws.commons.schema.wso2 XmlSchema 1.4.7.wso2v2 org.apache.abdera.wso2 abdera 1.0.0.wso2v3 org.apache.geronimo.specs.wso2 geronimo-stax-api_1.0_spec 1.0.1.wso2v2 org.apache.httpcomponents.wso2 httpcore 4.1.0-wso2v1 org.apache.neethi.wso2 neethi 2.0.4.wso2v4 org.apache.axis2.wso2 axis2 1.6.1.wso2v6 org.apache.woden.wso2 woden 1.0.0.M8-wso2v1 commons-logging commons-logging 1.1.1 org.apache.ws.commons.axiom.wso2 axiom 1.2.11.wso2v3 commons-io.wso2 commons-io 2.0.0.wso2v2 org.osgi org.osgi.core 5.0.0 lib/synapse/mediator
完成这些修改并将Maven构建的jar放到/ repository / components / dropins目录后,中介最终使用其自定义配置。
我已经压缩了完整的最终项目源代码。 该存档也可以在Dropbox: TestMediator-final.zip上找到
编辑
经过进一步的实验,很明显上述方法在WSO2 ESB 4.5.1中不起作用,这是我最初尝试使用它的平台。 代码在WSO2 4.7.0中按预期执行。
无论我尝试过什么,我都无法让WSO2 ESB 4.5.1(或4.6.0)调用激活器的start(BundleContext)
方法。