2016-09-01 6 views
0

OSGI enRouteでApache CXFを使用しようとしています。私がcfg.xmlファイルを使用せず、代わりにAPIを使用してサービスエンドポイントをスピンアップすることを望んでいるというのはひどいことです。以下はそのような例である:API経由で新しいCXFバスを作成

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バスを作成しています。

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コマンドを複製することも目標となります。上記のKarafコードはenRouteで動作しないようです。

バス内にcfg.xmlファイルを作成してバスを作成することは可能ですが、特定のエイリアスを持つバスをフェッチするためのAPIは表示されません。ああ。

次のリンクは有望に見えたが、CXFNonSpringServletのサブクラスに適応したときに...私は、対応するCXFバスを得ることはありません、また私は、APIを介して1を作成するように見えることができます。

registering servlet in OSGi that receives parameters

ですから、私の質問は... OSGI内のAPIを介してCXFバス(および対応するサーブレット)をフェッチ、作成、破棄することに成功した人はいますか?

おかげで、 ランディ

答えて

1

CXFNonSpringServletソースコードは、このサーブレットサブクラスが要求に応じてCXFバスを作成することを示しています。だから私が取ったアプローチは、単にCXFNonSpringServletクラスのインスタンスを作成し、それをHTTPServiceに目的のエイリアスで登録することです。

BundleActivatorクラス内で呼び出すことはできません。バンドルのアクティブ化時にサーブレットの登録に必要なHTTPServiceが存在するとは限りません。このために、私はHTTPServiceリファレンスを持つコンポーネントを作成し、コンポーネントのアクティブ化中にサーブレットを登録しました。私はさらに、起動時にサービス登録が確実に行われるように、コンポーネントを「即時コンポーネント」にしました。バンドルアクティベータクラスにこのコードを動かす上

@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); 
    } 

提案は歓迎されているが、バンドルアクティベータが呼び出されたときに、HTTPServiceが使用可能であることを確認する必要があることに注意します。

0

あなたが登録するバンドル・アクティベーターを実装できる/バンドル開始/停止のCXFバスは、登録を解除します。

バスを作成するには、BusFactoryクラスを使用します。作成されたバスをサービスとして登録する必要があります。登録されたサービスはリストに保存され、バンドルストップ時に登録を解除できます。

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を参照してください:あなたは今、このように行くことができるJAX-RSサービスについては

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(); 
     } 
    } 
} 

(おそらくあまりにもbeautyfulない)の例では、あなたのアイデアを与える必要があります後情報。

+0

私は実際にこのようなものを試しましたが、成功しませんでした。 HTTPServiceおよび/またはCXFバンドルがアクティブになる前にBusFactory.newInstance()。createBus()を呼び出すと、新しいバスが自動的に '/ cxf'エイリアスに関連付けられます。後でCXFバンドルがロードされると、そのコードは新しいバンドルを作成し、そのバンドルを '/ cxf'エイリアスに関連付けます。これにより競合が発生します。私は、この重複したエイリアス例外を回避し、このスレッドでその解決策を記録するアプローチを考え出しました。 –

関連する問題