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

标签 java xml maven apache-synapse wso2-esb

我正在尝试使用其自己的 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

不用说,我已经编写了两个文本文件,分别包含中介工厂和序列化器类的完全限定类名,并将它们放在 META-INF/services 中。捆绑 jar 文件中的目录。

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

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
在 Dropbox 上使用 Maven 构建的 Jar:TestMediator-1.0.0.jar

最佳答案

显然 WSO2 ESB 本身存在一些错误,这会导致包含中介器及其工厂和序列化器的包在其 list 包含 Fragment-Host 的情况下无法加载定义 我选择了一个稍微复杂的场景来让我的中介使用自定义 XML 配置来运行。

在 bundle 中使用激活器类来确认它没有被加载后,我突然想到我还可以使用激活器来手动注册 MediatorFactoryMediatorSerializer ESB 中的类。

我通过为我的 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 接口(interface)的 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) 方法。

关于java - 如何使用自己的 XML 配置来实现自定义中介器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18675691/

相关文章:

java - 使用 Class.this.field = value 在构造函数中初始化最终字段会出错,而使用 this.field = value 则不会

java - 在继承类中使用私有(private)变量 - Java

java - 如何处理 cxf/camel 生产者模板中的关闭/不可用端点

xml - XML 属性中允许的最大字符数是多少?

java - 在 Neo4j 中将多个参数传递给 forTypesAnd Directions 函数

php - 在 php 脚本中使用 curl

android - 将 float 操作按钮集成到带有工具栏的线性布局中

java - 使用launch4j和maven时不会创建.exe

java - Maven 如何从存储库解析 SNAPSHOT 版本

java - 使用 Runtime 从 Java 运行 Maven 命令