Използване на Felix Dependency Manager за създаване на Configuration Dependery

Опитвам се да накарам FelixDependencyManager да работи. Използвам Karaf 3 и тествам с 2 пакета, един за предоставяне на конфигурационната информация и един за прилагане на ManagedService-Interface и в зависимост от тази информация. Така че всичко се свежда до 3 класа:

Зависимият пакет има 2 класа: първият разширява класа DependencyActivatorBase, необходим за използване на Felix DependencyManager и имплементира метода init, където компонентът се създава и конфигурира:

public class ConfigAdminTester extends DependencyActivatorBase{

@Override
public void init(BundleContext context, DependencyManager manager)
        throws Exception {
    manager.add(createComponent()
            .setImplementation(ConfigTestImpl.class)
            .add(createConfigurationDependency()
            .setPid("test.configadmintest.testconfig"))
            .setCallbacks(null, "start", null, null)
            );
    System.out.println("ConfigAdminTester init finished");       
}

@Override
public void destroy(BundleContext context, DependencyManager manager)
        throws Exception {
}
}

Вторият клас в пакета е този, който трябва да се актуализира от ConfigAdmin-Service. Той имплементира ManagedService и има актуализиран метод, който трябва да бъде извикан при внедряване на пакета и при актуализиране на конфигурацията:

public class ConfigTestImpl implements ManagedService{
    String host;
    String port;
    int id;
    String password;

    public void start(){
    System.out.println("Host, Port, Id, Password: " + host + ", " +   port +", " + id + ", " + password);
    }
    @Override
    public void updated(@SuppressWarnings("rawtypes") Dictionary properties) throws  ConfigurationException {
        if (properties != null) {
            host= ((String)properties.get("host"));
            if (host == null) {
            throw new ConfigurationException("host", "must be specified");
            }
            port=((String)properties.get("port"));
            if (port == null) {
            throw new ConfigurationException("port", "must be specified");
            }
            id=((Integer)properties.get("id"));
            password=((String)properties.get("password"));
            System.out.println("Configuration in Bundle HttpServer was updated");
        }
        else {
            System.out.println("Properties are null");
        }    
    }

}

Вторият пакет има само един клас, който имплементира BundleActivator, получава препратка към ConfigAdmin-Service и създава нова конфигурация със същия pid, който използва другият пакет:

public class ConfigCreator implements BundleActivator{
    public void start(BundleContext context) throws Exception {

    @SuppressWarnings("rawtypes")
    ServiceReference serviceRef = context.getServiceReference(ConfigurationAdmin.class.getName());
    @SuppressWarnings("unchecked")
    ConfigurationAdmin configAdmin = (ConfigurationAdmin) context.getService(serviceRef);
    Configuration config = configAdmin.getConfiguration("test.configadmintest.testconfig", null);
    Dictionary <String, Object> properties = new Hashtable <String, Object>();
    properties.put("host", "test");
    properties.put("port", "test");
    properties.put("id", 1);
    properties.put("password", "test!");
    config.update(properties);
    System.out.println("config updated");
}

Проблемът сега е, че актуализираният метод никога не се извиква. Получавам резултата, че инициализацията на ConfigAdminTest е завършена и пакетът се активира, но методът за обратно извикване start в ConfigtestImpl никога не се извиква. Ако просто декларирам компонента без зависимостта на конфигурацията, всичко работи добре, методът за обратно извикване се изпълнява както трябва. Конфигурацията е публикувана, налична (проверих с командата config:list) и валидна, но изглежда, че по някакъв начин конфигурацията не е налична за зависимия пакет. Някой идея? Помощта е много ценена.


person user3207080    schedule 04.02.2014    source източник


Отговори (1)


Буквално копирах трите класа, които предоставихте в моята IDE, и направих два пакета от тях. Също така включих пакет, който имплементира ConfigurationAdmin и DependencyManager. Когато започнах всичко, веднага получих съобщението:

Configuration in Bundle HttpServer was updated

Така че не съм сигурен какво се е объркало тук, но вашият код изглежда е абсолютно правилен! Нека ви покажа пълния резултат от моето изпълнение, включително командите на GoGo shell и DM shell:

ConfigAdminTester init finished
config updated
Configuration in Bundle HttpServer was updated
Host, Port, Id, Password: test, test, 1, test!
____________________________
Welcome to Apache Felix Gogo

g! lb
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (4.2.1)
    1|Active     |    1|Apache Felix Configuration Admin Service (1.8.0)
    2|Active     |    1|Apache Felix Dependency Manager (3.1.0)
    3|Active     |    1|Apache Felix Dependency Manager Shell (3.0.1)
    4|Active     |    1|Apache Felix Gogo Command (0.12.0)
    5|Active     |    1|Apache Felix Gogo Runtime (0.10.0)
    6|Active     |    1|Apache Felix Gogo Shell (0.10.0)
    7|Active     |    1|osgi.cmpn (4.3.1.201210102024)
    8|Active     |    1|xxx.stackoverflow.b1 (0.0.0)
    9|Active     |    1|xxx.stackoverflow.b2 (0.0.0)
g! dm
[8] xxx.stackoverflow.b1
  class b1.ConfigTestImpl registered
    test.configadmintest.testconfig configuration required available

g! 

Само за да съм сигурен, поставих кода в два различни пакета. Примерът, който предоставихте, не показва пакети или импортирания, но не можете да използвате пакета по подразбиране (празен) в OSGi. Друга грешка може да е грешен импорт. Както и да е, ако все още сте блокирани, уведомете ме и ще се радвам да предоставя пълния изходен код.

person Marcel Offermans    schedule 06.02.2014