CELIX-343: Fix some issues in config admin. Among others unbind configuration 
when bundles are removed


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/4705f772
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/4705f772
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/4705f772

Branch: refs/heads/release/celix-2.0.0
Commit: 4705f77269da4824e29e19137a734b4b69875516
Parents: c4a34a9
Author: Pepijn Noltes <[email protected]>
Authored: Thu Feb 4 16:12:29 2016 +0100
Committer: Pepijn Noltes <[email protected]>
Committed: Thu Feb 4 16:12:29 2016 +0100

----------------------------------------------------------------------
 config_admin/config_admin_tst/config_admin_test.cpp       |  2 +-
 .../config_admin_tst/example_test/private/src/activator.c |  9 +++++----
 config_admin/example/private/src/bundle_activator.c       |  2 +-
 config_admin/readme.md                                    | 10 +++++++++-
 config_admin/service/private/src/configuration_impl.c     |  7 ++++---
 config_admin/service/private/src/configuration_store.c    |  2 +-
 .../service/private/src/managed_service_tracker.c         |  9 +++++++++
 7 files changed, 30 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/4705f772/config_admin/config_admin_tst/config_admin_test.cpp
----------------------------------------------------------------------
diff --git a/config_admin/config_admin_tst/config_admin_test.cpp 
b/config_admin/config_admin_tst/config_admin_test.cpp
index 8539c76..80f1480 100644
--- a/config_admin/config_admin_tst/config_admin_test.cpp
+++ b/config_admin/config_admin_tst/config_admin_test.cpp
@@ -337,7 +337,7 @@ tst2_service_pt test2Serv = NULL;
                        testServ->get_second_type(testServ->handle, value);
                        CHECK_TEXT("my_second_value", value);
                        printf("end: %s\n", __func__);
-                }
+       }
 }
 
 

http://git-wip-us.apache.org/repos/asf/celix/blob/4705f772/config_admin/config_admin_tst/example_test/private/src/activator.c
----------------------------------------------------------------------
diff --git a/config_admin/config_admin_tst/example_test/private/src/activator.c 
b/config_admin/config_admin_tst/example_test/private/src/activator.c
index 2507e4e..bae4daf 100644
--- a/config_admin/config_admin_tst/example_test/private/src/activator.c
+++ b/config_admin/config_admin_tst/example_test/private/src/activator.c
@@ -123,13 +123,11 @@ celix_status_t bundleActivator_start(void * userData, 
bundle_context_pt ctx) {
                                printf("[ TEST ]: ConfigAdminService not 
available\n");
                        } else {
                                char *pid = "base.device1";
-                               properties_pt dictionary;
                                configuration_pt configuration;
                                /* ------------------ get Configuration 
-------------------*/
                                
(*confAdminServ->getConfiguration)(confAdminServ->configAdmin,pid, 
&configuration);
                                act->configAdminServ = confAdminServ;
                                act->configAdminServRef = ref;
-
                                managed_service_pt managedService;
                                status = managedServiceImpl_create(ctx, 
&managedService);
                                if (status != CELIX_SUCCESS){
@@ -147,19 +145,20 @@ celix_status_t bundleActivator_start(void * userData, 
bundle_context_pt ctx) {
 
                                act->mgmServ->managedService = managedService;
                                act->mgmServ->updated = 
managedServiceImpl_updated;
-
+                               properties_pt dictionary;
                                
configuration->configuration_getProperties(configuration->handle, &dictionary);
                                if (dictionary == NULL) {
                                        dictionary = properties_create();
                                        properties_set(dictionary, (char *) 
OSGI_FRAMEWORK_SERVICE_PID, pid);
                                        properties_set(dictionary, (char *) 
"type", (char*)"default_value");
                                }
+                               // the service has to be registered with a 
properties/dictionary structure that at least contains a pid to assure it
+                               // is picked up by the managedServiceTracker of 
the configuration Admin
                                status = bundleContext_registerService(ctx, 
(char *) MANAGED_SERVICE_SERVICE_NAME, act->mgmServ, dictionary, &act->mgmReg);
                                if (status != CELIX_SUCCESS){
                                        printf("[ ERROR ]: Managed Service not 
registered \n");
                                        return status;
                                }
-
                                status = bundleContext_registerService(ctx, 
(char *)TST_SERVICE_NAME, act->tstServ, NULL, &act->tstReg);
 
                        }
@@ -186,8 +185,10 @@ celix_status_t bundleActivator_stop(void * userData, 
bundle_context_pt context)
 
 celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt 
context) {
        struct activator *act = (struct activator *)userData;
+
        managedServiceImpl_destroy(&act->mgmServ->managedService);
        managedService_destroy(act->mgmServ);
+
        free(act->tstServ);
        free(act);
        return CELIX_SUCCESS;

http://git-wip-us.apache.org/repos/asf/celix/blob/4705f772/config_admin/example/private/src/bundle_activator.c
----------------------------------------------------------------------
diff --git a/config_admin/example/private/src/bundle_activator.c 
b/config_admin/example/private/src/bundle_activator.c
index 55bc11e..3e4622f 100644
--- a/config_admin/example/private/src/bundle_activator.c
+++ b/config_admin/example/private/src/bundle_activator.c
@@ -44,7 +44,7 @@ celix_status_t bundleActivator_start(void *userData, 
bundle_context_pt context)
         properties_set(props, "service.pid", "org.example.config.admin"); 
         activator->managed->managedService = (void *)activator->example;
         activator->managed->updated = (void *)example_updated;
-               bundleContext_registerService(context, (char *)  
MANAGED_SERVICE_SERVICE_NAME, activator->managed, NULL, 
&activator->managedServiceRegistry);
+               bundleContext_registerService(context, (char *)  
MANAGED_SERVICE_SERVICE_NAME, activator->managed, props, 
&activator->managedServiceRegistry);
        }
 
        return status;

http://git-wip-us.apache.org/repos/asf/celix/blob/4705f772/config_admin/readme.md
----------------------------------------------------------------------
diff --git a/config_admin/readme.md b/config_admin/readme.md
index 900d8a7..db13504 100644
--- a/config_admin/readme.md
+++ b/config_admin/readme.md
@@ -11,6 +11,11 @@ When compared to config.properties it adds the option to 
update configuration da
 ## Design
 
 The config_admin bundle implements the configuration_admin service, the 
interface to configuration objects and the interface of a managed service. At 
the moment, the implementation uses a config_admin_factory to generate 
config_admin services for each bundle that wants to use this service. This is 
an inheritance of the original design and not needed.
+The configuration data is stored persistently in a subdirectory store of the 
current bundle directory. 
+The filenames have the name of the PID and have an extension pid, e.g. 
base.device1.pid
+The files contains a list of key/value pairs. At least the following keys need 
to be present:
+service.bundleLocation
+service.pid
 
 ---
 
@@ -18,12 +23,15 @@ The config_admin bundle implements the configuration_admin 
service, the interfac
 
 1. Test the configuration of a service_factory
 2. Think about the option to allow remote update of the managed_services
+3. Support configuration of multiple managed services with the same PID. At 
the moment, only one service is bound to a configuration object.
+   To support this the getConfiguration2 function needs to be called with a 
location NULL according to the spec.
 
 ---
 
 ## Usage
 
 1. Bundle that needs configuration data
-   This bundle has to register next to its normal service a managed service 
that has an update method.  Use config_admin_tst/example_test as an example (it 
is better than example_test2)
+   This bundle has to register next to its normal service a managed service 
that has an update method. This managed service needs to be registered with a 
properties object that contains the key/value pair service.pid=<PID NAME>.
+ Use config_admin_tst/example_test as an example (it is better than 
example_test2)
 2. Bundle/application that wants to update the configuration data of the system
    This bundle needs to retrieve the running config_admin service. With this 
service it can retrieve all configuration objects for all known Persistent 
Identifiers (PIDs). For each PID, get all properites that need to be updated. 
See config_admin_test for an example.

http://git-wip-us.apache.org/repos/asf/celix/blob/4705f772/config_admin/service/private/src/configuration_impl.c
----------------------------------------------------------------------
diff --git a/config_admin/service/private/src/configuration_impl.c 
b/config_admin/service/private/src/configuration_impl.c
index f39dfa0..eed51ff 100644
--- a/config_admin/service/private/src/configuration_impl.c
+++ b/config_admin/service/private/src/configuration_impl.c
@@ -455,7 +455,8 @@ celix_status_t configuration_bind(configuration_impl_pt 
configuration, bundle_pt
 }
 
 celix_status_t configuration_unbind(configuration_impl_pt configuration, 
bundle_pt bundle){
-       return CELIX_SUCCESS;
+       configuration->boundBundle = NULL;
+    return CELIX_SUCCESS;
 }
 
 celix_status_t configuration_getBundleLocation2(configuration_impl_pt 
configuration, bool checkPermission, char **location){
@@ -635,9 +636,9 @@ celix_status_t 
configuration_setAutoProperties(configuration_impl_pt configurati
        configuration_lock(configuration);
 
        // (2) set service.pid
-    if (properties_get(*properties, (char*)OSGI_FRAMEWORK_SERVICE_PID) != 
NULL) {
+//    if (properties_get(*properties, (char*)OSGI_FRAMEWORK_SERVICE_PID) != 
NULL) {
         properties_set(*properties, (char*)OSGI_FRAMEWORK_SERVICE_PID, 
configuration->pid);
-    }
+//    }
 
        // (3) set factory.pid
        if ( configuration->factoryPid != NULL ){

http://git-wip-us.apache.org/repos/asf/celix/blob/4705f772/config_admin/service/private/src/configuration_store.c
----------------------------------------------------------------------
diff --git a/config_admin/service/private/src/configuration_store.c 
b/config_admin/service/private/src/configuration_store.c
index d4bb831..37b091e 100644
--- a/config_admin/service/private/src/configuration_store.c
+++ b/config_admin/service/private/src/configuration_store.c
@@ -261,7 +261,7 @@ celix_status_t 
configurationStore_writeConfigurationFile(int file, properties_pt
         char* key = hashMapEntry_getKey(entry);
         char* val = hashMapEntry_getValue(entry);
 
-        snprintf(buffer, 256, "%s=%s", key, val);
+        snprintf(buffer, 256, "%s=%s\n", key, val);
 
         int buffLength = strlen((const char *) buffer);
 

http://git-wip-us.apache.org/repos/asf/celix/blob/4705f772/config_admin/service/private/src/managed_service_tracker.c
----------------------------------------------------------------------
diff --git a/config_admin/service/private/src/managed_service_tracker.c 
b/config_admin/service/private/src/managed_service_tracker.c
index e723f29..1ce5ac1 100644
--- a/config_admin/service/private/src/managed_service_tracker.c
+++ b/config_admin/service/private/src/managed_service_tracker.c
@@ -399,6 +399,15 @@ celix_status_t 
managedServiceTracker_add(managed_service_tracker_pt tracker, ser
 }
 
 celix_status_t managedServiceTracker_remove(managed_service_tracker_pt 
tracker, service_reference_pt reference, char * pid){
+    configuration_pt configuration = NULL;
+    bundle_pt bundle = NULL;
+
+    configurationStore_findConfiguration(tracker->configurationStore, pid, 
&configuration);
+    if (configuration != NULL) {
+        if (serviceReference_getBundle(reference, &bundle) == CELIX_SUCCESS) {
+                       configuration_unbind(configuration->handle, bundle);
+               }       
+       }
        return managedServiceTracker_untrackManagedService(tracker, pid, 
reference);
 }
 

Reply via email to