【问题标题】:How to implement a custom mediator with its own XML configuration?如何使用自己的 XML 配置实现自定义中介?
【发布时间】:2013-09-11 14:40:32
【问题描述】:

我正在尝试使用自己的 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 放到&lt;ESB_HOME&gt;/repository/components/dropins-目录中。

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

我必须更改什么才能使自定义 XML 配置正常工作?

任何意见将不胜感激!

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

【问题讨论】:

  • 我现在已经确认在 Maven 配置中添加 Fragment-Host 部分会导致创建的 OSGI 包无法启动。我通过在包中添加一个激活器类来做到这一点。只有在 Fragment-Host 元素不存在时才会调用激活器。

标签: java xml maven wso2esb synapse


【解决方案1】:

WSO2 ESB 本身显然存在一些错误,这会导致包含调解器及其工厂和序列化程序的包在其清单包含 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 类定义为捆绑包的激活器。这是通过在 Instructions 元素下的 pom.xml 捆绑插件配置中添加以下节点来完成的:

<Bundle-Activator>test.Activator</Bundle-Activator>

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

此外,Fragment-Host 元素需要从同一个父节点中移除,才能真正调用激活器类的启动方法。

还需要添加包含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) 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-07
    • 2014-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多