通过API创建新的CXF总线

时间:2016-09-01 17:46:29

标签: osgi cxf

我正在尝试将Apache CXF与OSGI enRoute一起使用。扭曲的是我不想使用cfg.xml文件,而是通过API启动我的服务端点。以下是这样一个例子:

    InvolvedPartySoap12EndpointImpl involvedPartyServiceImpl = new InvolvedPartySoap12EndpointImpl();
    ServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
    svrFactory.setServiceClass(InvolvedPartyPortType.class);
    svrFactory.setAddress("/bin/InvolvedParty");
    svrFactory.setBus(bus);
    svrFactory.setServiceBean(involvedPartyServiceImpl);
    _server = svrFactory.create();

我遇到的问题是为每个OSGI包创建一个不同的CXF总线,因此每次激活/停用相应的包时,我都可以创建/销毁总线。复制以下Karaf命令也是一个目标:

https://access.redhat.com/documentation/en-US/Red_Hat_JBoss_Fuse/6.2/html/API_Reference/files/cxf/org/apache/cxf/karaf/commands/CXFController.html

问题是我没有看到用于创建和销毁CXF总线的API。上面列出的Karaf代码似乎不适用于enRoute。

我想可以在bundle中创建一个cfg.xml文件来创建总线,但是我没有看到用于获取具有给定别名的总线的API。啊。

以下链接看起来很有希望,但是当适应CXFNonSpringServlet的子类时...我没有得到相应的CXF总线,我似乎也无法通过API创建一个:

registering servlet in OSGi that receives parameters

所以我的问题是......有没有人成功通过OSGI内的API获取,创建和销毁CXF总线(以及相应的servlet)?

谢谢, 好色

2 个答案:

答案 0 :(得分:1)

CXFNonSpringServlet源代码显示此servlet子类根据需要创建CXF总线。因此,我采用的方法是简单地创建一个CXFNonSpringServlet类的实例,并将其注册到具有所需别名的HTTPService。

catch是在BundleActivator类中无法调用的以下代码,因为无法保证在bundle激活时注册servlet所需的HTTPService。为此,我创建了一个带有HTTPService引用的组件,并在组件激活期间注册了servlet。我进一步将该组件作为“直接组件”,以确保在启动期间进行服务注册。

@Component(immediate = true)
public class SoapBootstrap
{
    private static final long serialVersionUID = 1L;
    private static final String Alias = "/party";

    private HttpService _httpService;
    private CXFNonSpringServlet _servlet;

    @Reference
    public void setHttpService(HttpService theHttpService)
    {
        try {
            _httpService = theHttpService;
            _servlet = new CXFNonSpringServlet();
            _httpService.registerServlet(Alias, _servlet, null, null);
            registerEndpoints();
        } catch (NamespaceException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ServletException e) {
            e.printStackTrace();
        }
    }

    private void registerEndpoints()
    {
        try {
            XyzSoap12EndpointImpl xyzServiceImpl = new XyzSoap12EndpointImpl();
            ServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
            svrFactory.setServiceClass(XyzPortType.class);
            svrFactory.setAddress("/xyz");
            svrFactory.setBus(_servlet.getBus());
            svrFactory.setServiceBean(xyzServiceImpl);
            svrFactory.create();
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
        }
    }


    @Activate
    void activate(BundleContext context)
    {
    }


    @Deactivate
    void deactivate(BundleContext context)
    {
        _httpService.unregister(Alias);
    }

欢迎将此代码移至Bundle Activator类的建议,但请注意,在调用Bundle Activator时,必须确保HTTPService可用。

答案 1 :(得分:0)

您可以实现Bundle-Activator,在bundle start / stop上注册/取消注册CXF总线。

要创建总线,您可以使用BusFactory类。创建的总线必须注册为服务。已注册的服务保存在列表中,以便能够在捆绑停止时取消注册。

以下(也许不是太美)的例子应该给你一个想法:

import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
...


public class MyBundleActivator implements BundleActivator {

   private final List<ServiceRegistration> serviceReferences = new ArrayList<>();

   private Bus cxfBus;
   private BundleContext bundleContext;

   @Override
   public void start(BundleContext bundleContext) throws Exception {
      this.bundleContext = bundleContext;
      createAndRegisterCxfBus();
   }

   private void createAndRegisterCxfBus() {
      cxfBus = BusFactory.newInstance().createBus();
      cxfBus.setExtension(MyBundleActivator.class.getClassLoader(), ClassLoader.class);
      registerService(Bus.class.getName(), cxfBus);
   }

   private void registerService(String serviceTypeName, Object service) {
      Dictionary properties = new Properties();
      ServiceRegistration serviceReference = bundleContext.registerService(serviceTypeName, service, properties);
      serviceReferences.add(serviceReference);
   }

   @Override
   public void stop(BundleContext bundleContext) throws Exception {
      unregisterServices();
   }

   private void unregisterServices() {
      for (ServiceRegistration serviceReference : serviceReferences) {
         serviceReference.unregister();
      }
   }
} 

对于JAX-RS服务,您现在可以继续这样:

  JAXRSServerFactoryBean serviceFactory = new JAXRSServerFactoryBean();
  serviceFactory.setBus(cxfBus);

  ... configure with providers etc using factory API ....

  Server server = serviceFactory.create();

有关详细信息,请参阅http://cxf.apache.org/docs/jaxrs-services-configuration.html