2016-09-01 3 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를 통해 하나를 만들 보일 수있다 :

registering servlet in OSGi that receives parameters

그래서 제 질문은 ... OSGI 내에서 API를 통해 CXF 버스 (및 해당 서블릿)를 가져오고, 만들고, 파괴하는 데 성공한 사람이 있습니까?

덕분에, 랜디

답변

1

CXFNonSpringServlet 소스 코드는이 서블릿 하위 클래스가 요청시 CXF 버스를 생성한다는 것을 보여줍니다. 그래서 제가 취한 접근법은 단순히 CXFNonSpringServlet 클래스의 인스턴스를 만들고 HTTPService에 원하는 별칭으로 등록하는 것입니다.

catch는 BundleActivator 클래스 내에서 호출 할 수 없습니다. 서블릿을 등록하는 데 필요한 HTTPService가 번들 활성화시 존재한다는 보장이 없으므로 BundleActivator 클래스 내에서 호출 할 수 없습니다. 이를 위해 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'별명과 연관시킵니다. 이로 인해 충돌이 발생합니다. 이 중복 된 별칭 예외를 피하는 접근법을 생각해 냈으며이 스레드에서 해당 솔루션을 문서화합니다. –

관련 문제