如何使用自己的XML配置实现自定义中介?

时间:2013-09-07 16:55:05

标签: java xml maven wso2esb synapse

我正在尝试使用自己的XML配置为WSO2 ESB(4.5.1)实现自定义中介。我可以使用中介作为类中介使用以下配置:

<class name="test.synapse.mediator.TestMediator"/>

然而,我想要实现的是能够使用如下语法调用中介:

<t:TestMediator xmlns:t="test:mediator" />

在WSO2 ESB关于此事的可用帮助后,我在尝试使用具有自己的XML配置的中介创建代理时收到以下错误:

ERROR - MediatorFactoryFinder Unknown mediator referenced by configuration element : {test:mediator}TestMediator

毋庸置疑,我已经分别编写了包含中介工厂和序列化程序类的完全限定类名的两个文本文件,并将它们放在bundle jar文件的META-INF/services目录中。

这是我的中介类的源代码:

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文件有点冗长:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>test.synapse.mediator.TestMediator</groupId>
  <artifactId>TestMediator</artifactId>
  <version>1.0.0</version>
  <packaging>bundle</packaging>
  <name>TestMediator</name>
  <description>TestMediator</description>
  <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.0</version>
            <configuration>
                <source>1.5</source>
                <target>1.5</target>
            </configuration>
        </plugin>
        <plugin>
        <groupId>org.apache.felix</groupId>
        <artifactId>maven-bundle-plugin</artifactId>
        <version>2.3.4</version>
        <extensions>true</extensions>
        <configuration>
          <instructions>
            <Bundle-SymbolicName>TestMediator</Bundle-SymbolicName>
            <Bundle-Name>TestMediator</Bundle-Name>
            <Bundle-ClassPath>.</Bundle-ClassPath>
            <Export-Package>test.synapse.mediator</Export-Package>
            <Import-Package>*; resolution:=optional</Import-Package>
            <Fragment-Host>synapse-core</Fragment-Host>
          </instructions>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-eclipse-plugin</artifactId>
        <version>2.9</version>
        <configuration>
          <buildcommands>
            <buildcommand>org.eclipse.jdt.core.javabuilder</buildcommand>
          </buildcommands>
          <projectnatures>
            <projectnature>org.wso2.developerstudio.eclipse.artifact.mediator.project.nature</projectnature>
            <projectnature>org.eclipse.jdt.core.javanature</projectnature>
          </projectnatures>
        </configuration>
      </plugin>
    </plugins>
    <resources>
        <resource>
            <directory>src/main/resources/services</directory>
            <targetPath>META-INF/services</targetPath>
        </resource>
    </resources>
  </build>
  <repositories>
    <repository>
      <releases>
        <updatePolicy>daily</updatePolicy>
        <checksumPolicy>ignore</checksumPolicy>
      </releases>
      <id>wso2-nexus</id>
      <url>http://maven.wso2.org/nexus/content/groups/wso2-public/</url>
    </repository>
  </repositories>
  <pluginRepositories>
    <pluginRepository>
      <releases>
        <updatePolicy>daily</updatePolicy>
        <checksumPolicy>ignore</checksumPolicy>
      </releases>
      <id>wso2-nexus</id>
      <url>http://maven.wso2.org/nexus/content/groups/wso2-public/</url>
    </pluginRepository>
  </pluginRepositories>
  <dependencies>
    <dependency>
      <groupId>commons-httpclient.wso2</groupId>
      <artifactId>commons-httpclient</artifactId>
      <version>3.1.0.wso2v2</version>
    </dependency>
    <dependency>
      <groupId>commons-codec.wso2</groupId>
      <artifactId>commons-codec</artifactId>
      <version>1.4.0.wso2v1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.synapse</groupId>
      <artifactId>synapse-core</artifactId>
      <version>2.1.0-wso2v7</version>
    </dependency>
    <dependency>
      <groupId>wsdl4j.wso2</groupId>
      <artifactId>wsdl4j</artifactId>
      <version>1.6.2.wso2v4</version>
    </dependency>
    <dependency>
      <groupId>org.apache.ws.commons.schema.wso2</groupId>
      <artifactId>XmlSchema</artifactId>
      <version>1.4.7.wso2v2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.abdera.wso2</groupId>
      <artifactId>abdera</artifactId>
      <version>1.0.0.wso2v3</version>
    </dependency>
    <dependency>
      <groupId>org.apache.geronimo.specs.wso2</groupId>
      <artifactId>geronimo-stax-api_1.0_spec</artifactId>
      <version>1.0.1.wso2v2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.httpcomponents.wso2</groupId>
      <artifactId>httpcore</artifactId>
      <version>4.1.0-wso2v1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.neethi.wso2</groupId>
      <artifactId>neethi</artifactId>
      <version>2.0.4.wso2v4</version>
    </dependency>
    <dependency>
      <groupId>org.apache.axis2.wso2</groupId>
      <artifactId>axis2</artifactId>
      <version>1.6.1.wso2v6</version>
    </dependency>
    <dependency>
      <groupId>org.apache.woden.wso2</groupId>
      <artifactId>woden</artifactId>
      <version>1.0.0.M8-wso2v1</version>
    </dependency>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1.1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.ws.commons.axiom.wso2</groupId>
      <artifactId>axiom</artifactId>
      <version>1.2.11.wso2v3</version>
    </dependency>
    <dependency>
      <groupId>commons-io.wso2</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.0.0.wso2v2</version>
    </dependency>
  </dependencies>
  <properties>
    <CApp.type>lib/synapse/mediator</CApp.type>
  </properties>
</project>

我一直在尝试改变pom文件和代码的各个方面。我注意到,如果我省略配置的Fragment-Host部分,我可以使用类调解器调用调解器。如果存在Fragment-Host元素,则无法调用调解器。

正如预期的那样,我使用apache Maven来构建项目的jar文件。我将jar放到<ESB_HOME>/repository/components/dropins目录。

我尝试使用WSO2 ESB 4.5.1和4.7.0,结果完全相同。

我必须更改什么才能使自定义XML配置生效?

非常感谢任何输入!

附件:
Dropbox的压缩源:TestMediator.zip
Jar在Dropbox使用maven构建:TestMediator-1.0.0.jar

1 个答案:

答案 0 :(得分:2)

看到WSO2 ESB本身显然存在一些错误,导致包含调解器及其工厂和序列化程序的bundle在其清单包含Fragment-Host定义的情况下不会被加载使用自定义XML配置让我的中介运行起来稍微复杂一些。

在捆绑包中使用了一个激活器类来确认它没有被加载,我发现我还可以使用激活器在ESB中手动注册MediatorFactoryMediatorSerializer

我是通过为我的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<javax.xml.namespace.QName, java.lang.Class> mediatorFactoryMap = MediatorFactoryFinder.getInstance().getFactoryMap();
            mediatorFactoryMap.put(TestMediatorFactory.QNAME, TestMediatorFactory.class);
        }
        {
            Map<String, MediatorSerializer> 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-Activator>test.Activator</Bundle-Activator>

使用这种手动注册工厂和序列化程序类的方式,不需要org.apache.synapse.config.xml.MediatorFactoryorg.apache.synapse.config.xml.MediatorSerializer文件,可以从最终的jar中删除。

此外,需要从同一父节点中删除Fragment-Host元素,以实际调用激活器类'start方法。

还需要添加包含BundleActivator接口的osgi核心依赖项。

通过这样做,我们留下了以下完整的pom.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>test.synapse.mediator.TestMediator</groupId>
  <artifactId>TestMediator</artifactId>
  <version>1.0.0</version>
  <packaging>bundle</packaging>
  <name>TestMediator</name>
  <description>TestMediator</description>
  <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.0</version>
            <configuration>
                <source>1.5</source>
                <target>1.5</target>
            </configuration>
        </plugin>
        <plugin>
        <groupId>org.apache.felix</groupId>
        <artifactId>maven-bundle-plugin</artifactId>
        <version>2.3.4</version>
        <extensions>true</extensions>
        <configuration>
          <instructions>
            <Bundle-SymbolicName>TestMediator</Bundle-SymbolicName>
            <Bundle-Name>TestMediator</Bundle-Name>
            <Bundle-ClassPath>.</Bundle-ClassPath>
            <Bundle-Activator>test.Activator</Bundle-Activator>
            <Export-Package>test.synapse.mediator</Export-Package>
            <Import-Package>*; resolution:=optional</Import-Package>
            <!-- <Fragment-Host>synapse-core</Fragment-Host> -->
          </instructions>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-eclipse-plugin</artifactId>
        <version>2.9</version>
        <configuration>
          <buildcommands>
            <buildcommand>org.eclipse.jdt.core.javabuilder</buildcommand>
          </buildcommands>
          <projectnatures>
            <projectnature>org.wso2.developerstudio.eclipse.artifact.mediator.project.nature</projectnature>
            <projectnature>org.eclipse.jdt.core.javanature</projectnature>
          </projectnatures>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <repositories>
    <repository>
      <releases>
        <updatePolicy>daily</updatePolicy>
        <checksumPolicy>ignore</checksumPolicy>
      </releases>
      <id>wso2-nexus</id>
      <url>http://maven.wso2.org/nexus/content/groups/wso2-public/</url>
    </repository>
  </repositories>
  <pluginRepositories>
    <pluginRepository>
      <releases>
        <updatePolicy>daily</updatePolicy>
        <checksumPolicy>ignore</checksumPolicy>
      </releases>
      <id>wso2-nexus</id>
      <url>http://maven.wso2.org/nexus/content/groups/wso2-public/</url>
    </pluginRepository>
  </pluginRepositories>
  <dependencies>
    <dependency>
      <groupId>commons-httpclient.wso2</groupId>
      <artifactId>commons-httpclient</artifactId>
      <version>3.1.0.wso2v2</version>
    </dependency>
    <dependency>
      <groupId>commons-codec.wso2</groupId>
      <artifactId>commons-codec</artifactId>
      <version>1.4.0.wso2v1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.synapse</groupId>
      <artifactId>synapse-core</artifactId>
      <version>2.1.0-wso2v7</version>
    </dependency>
    <dependency>
      <groupId>wsdl4j.wso2</groupId>
      <artifactId>wsdl4j</artifactId>
      <version>1.6.2.wso2v4</version>
    </dependency>
    <dependency>
      <groupId>org.apache.ws.commons.schema.wso2</groupId>
      <artifactId>XmlSchema</artifactId>
      <version>1.4.7.wso2v2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.abdera.wso2</groupId>
      <artifactId>abdera</artifactId>
      <version>1.0.0.wso2v3</version>
    </dependency>
    <dependency>
      <groupId>org.apache.geronimo.specs.wso2</groupId>
      <artifactId>geronimo-stax-api_1.0_spec</artifactId>
      <version>1.0.1.wso2v2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.httpcomponents.wso2</groupId>
      <artifactId>httpcore</artifactId>
      <version>4.1.0-wso2v1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.neethi.wso2</groupId>
      <artifactId>neethi</artifactId>
      <version>2.0.4.wso2v4</version>
    </dependency>
    <dependency>
      <groupId>org.apache.axis2.wso2</groupId>
      <artifactId>axis2</artifactId>
      <version>1.6.1.wso2v6</version>
    </dependency>
    <dependency>
      <groupId>org.apache.woden.wso2</groupId>
      <artifactId>woden</artifactId>
      <version>1.0.0.M8-wso2v1</version>
    </dependency>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1.1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.ws.commons.axiom.wso2</groupId>
      <artifactId>axiom</artifactId>
      <version>1.2.11.wso2v3</version>
    </dependency>
    <dependency>
      <groupId>commons-io.wso2</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.0.0.wso2v2</version>
    </dependency>
    <dependency>
      <groupId>org.osgi</groupId>
      <artifactId>org.osgi.core</artifactId>
      <version>5.0.0</version>
    </dependency>
  </dependencies>
  <properties>
    <CApp.type>lib/synapse/mediator</CApp.type>
  </properties>
</project>

完成这些修改并将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)方法。