Опитвам се да накарам 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) и валидна, но изглежда, че по някакъв начин конфигурацията не е налична за зависимия пакет. Някой идея? Помощта е много ценена.