2016-09-01 2 views
0

Я пытаюсь использовать Apache CXF с OSGI enRoute. Твист заключается в том, что я бы предпочел не использовать файлы cfg.xml и вместо этого расширять конечные точки службы через API. Ниже приводится такой пример:Создайте новую шину CXF через 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(); 

вопрос, который я имею создает отдельную шину CXF для каждого OSGI пучка, что позволяет мне создавать/уничтожить автобус каждый раз, когда соответствующий пакет активируется/деактивируется. Репликация следующих команд 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

Проблема заключается в том, что я просто не вижу API-интерфейсов для создания и уничтожения CXF Bus. И код Karaf, указанный выше, не работает для enRoute.

Я полагаю, что можно создать файл cfg.xml в комплекте для создания шины, но тогда я не вижу API для извлечения шины с заданным псевдонимом. Тьфу.

Следующая ссылка казалось многообещающим, но при адаптации к подклассу CXFNonSpringServlet ... Я не получить соответствующий CXF автобус, и я не могу показаться, чтобы создать с помощью API:

registering servlet in OSGi that receives parameters

Итак, мой вопрос: кто-нибудь был успешным в сборе, создании и уничтожении автобусов CXF (и соответствующих сервлетов) через API в OSGI?

Спасибо, Рэнди

ответ

1

Исходный код CXFNonSpringServlet показывает, что этот подкласс сервлета создает по требованию CXF Bus. Таким образом, подход, который я сделал, - это просто создать экземпляр класса 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); 
    } 

Предложение о перекладке этого кода класса Bundle Активатора можно только приветствовать, но обратите внимание, что необходимо для обеспечения HTTPService доступно, когда Bundle Активатор вызывается.

0

Вы могли бы реализовать Bundle-Activator, который регистрирует/отменяет регистрацию автобуса CXF на старте расслоения/остановка.

Для создания автобуса вы можете использовать класс BusFactory. Созданная шина должна быть зарегистрирована как услуга. Зарегистрированные службы хранятся в списке, чтобы иметь возможность отменить регистрацию на остановке пучка.

После (возможно, не слишком Beautyful) пример должен дать Вам идею:

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 для дальнейшего Информация.

+0

Я действительно пробовал что-то подобное, но безуспешно. Кажется, что вызов функции BusFactory.newInstance(). CreateBus() до активации пакетов HTTPService и/или CXF приводит к тому, что новая шина автоматически связана с псевдонимом '/ cxf'. Когда пакеты CXF впоследствии загружаются позднее, этот код также создает новый пакет и связывает его с псевдонимом '/ cxf'. Это вызывает конфликт. Я придумал подход, который позволяет избежать этого дублирующего псевдонима и будет документировать это решение в этом потоке. –

Смежные вопросы