http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/config_admin/service/private/src/activator.c ---------------------------------------------------------------------- diff --git a/bundles/config_admin/service/private/src/activator.c b/bundles/config_admin/service/private/src/activator.c new file mode 100644 index 0000000..2f94efa --- /dev/null +++ b/bundles/config_admin/service/private/src/activator.c @@ -0,0 +1,136 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ +/* + * activator.c + * + * \date Aug 12, 2013 + * \author <a href="mailto:d...@celix.apache.org">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + + +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> + +/* celix.framework.public */ +#include "bundle_activator.h" +#include "bundle_context.h" +#include "celix_errno.h" +#include "service_factory.h" +#include "service_registration.h" +/* celix.config_admin.public */ +#include "configuration_admin.h" +/* celix.config_admin.private */ +#include "configuration_admin_factory.h" + + +struct config_admin_bundle { + bundle_context_pt context; + service_registration_pt configAdminFactoryReg; + service_factory_pt configAdminFactory; + configuration_admin_factory_pt configAdminFactoryInstance; +}; + +typedef struct config_admin_bundle *config_admin_bundle_t; + + +/* -------------------- Implements BundleActivator ---------------------------- */ + +celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) { + + celix_status_t status = CELIX_SUCCESS; + + config_admin_bundle_t bi = calloc(1, sizeof(struct config_admin_bundle)); + + if (bi == NULL) { + + status = CELIX_ENOMEM; + + } else { + + (*userData) = bi; + bi->context = context; + bi->configAdminFactoryReg = NULL; + bi->configAdminFactoryInstance = NULL; + + status = CELIX_SUCCESS; + + } + return status; +} + +celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) { + + celix_status_t status; + + config_admin_bundle_t bi = (config_admin_bundle_t) userData; + + + status = configurationAdminFactory_create(bi->context, &bi->configAdminFactory, &bi->configAdminFactoryInstance); + if (status != CELIX_SUCCESS){ + return status; + } + + status = bundleContext_registerServiceFactory(bi->context, (char *) CONFIGURATION_ADMIN_SERVICE_NAME, bi->configAdminFactory, NULL, &bi->configAdminFactoryReg); + if (status != CELIX_SUCCESS){ + return status; + } + printf("[ SUCCESS ]: Activator - ConfigAdminFactory Registered \n"); + + status = configurationAdminFactory_start(bi->configAdminFactoryInstance); + if (status != CELIX_SUCCESS){ + return status; + } + + return CELIX_SUCCESS; + +} + +celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) { + + celix_status_t status = CELIX_SUCCESS; + + config_admin_bundle_t bi = (config_admin_bundle_t) userData; + configurationAdminFactory_stop(bi->configAdminFactoryInstance); + serviceRegistration_unregister(bi->configAdminFactoryReg); + configurationAdminFactory_destroy(context, bi->configAdminFactoryInstance); + + bi->configAdminFactoryReg = NULL; + free(bi->configAdminFactory); + + + return status; +} + +celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) { + + config_admin_bundle_t bi = (config_admin_bundle_t) userData; + + free(bi); + + return CELIX_SUCCESS; +} + + + + + + +
http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/config_admin/service/private/src/configuration_admin_factory.c ---------------------------------------------------------------------- diff --git a/bundles/config_admin/service/private/src/configuration_admin_factory.c b/bundles/config_admin/service/private/src/configuration_admin_factory.c new file mode 100644 index 0000000..f8871d9 --- /dev/null +++ b/bundles/config_admin/service/private/src/configuration_admin_factory.c @@ -0,0 +1,211 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ +/* + * configuration_admin_factory.c + * + * \date Aug 12, 2013 + * \author <a href="mailto:d...@celix.apache.org">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#include <celixbool.h> +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> + +/* celix.config_admin.ConfigAdminFactory */ +#include "configuration_admin_factory.h" + +/* celix.framework.Patch*/ +#include "framework_patch.h" +/* celix.config_admin.public*/ +#include "configuration_admin.h" +/* celix.config_admin.private*/ +#include "configuration_admin_impl.h" +#include "managed_service_tracker.h" +#include "configuration_store.h" + + +struct configuration_admin_factory{ + bundle_context_pt context; + +// configuration_permission_t configurationPermission; +// event_dispatcher_t eventDispatcher; +// plugin_manager_t pluginManager; + managed_service_tracker_pt managedServiceTrackerHandle; + service_tracker_pt managedServiceTracker; +// managed_service_factory_ptracker_t managedServiceFactoryTracker; + configuration_store_pt configurationStore; + +}; + + +celix_status_t configurationAdminFactory_getService(void *factory, bundle_pt bundle, service_registration_pt registration, void **service); +celix_status_t configurationAdminFactory_ungetService(void *factory, bundle_pt bundle, service_registration_pt registration, void **service); + + +/* ========== CONSTRUCTOR =========== */ + +/* ---------- public ---------- */ + +celix_status_t configurationAdminFactory_create( bundle_context_pt context, service_factory_pt *factory, configuration_admin_factory_pt *instance){ + + celix_status_t status; + + configuration_admin_factory_pt this = calloc(1, sizeof(*this)); + configuration_store_pt configurationStore; + managed_service_tracker_pt managedServiceTrackerHandle; + service_tracker_pt managedServiceTracker; + + // (1) SERVICE FACTORY + *factory = calloc(1, sizeof(**factory)); + if (!*factory) { + return CELIX_ENOMEM; + } + // (2) FACTORY DATA + if (!this){ + printf("[ ERROR ]: ConfigAdminFactory - Not initialized \n"); + return CELIX_ENOMEM; + } + // (2.1) CONFIGURATION STORE + status = configurationStore_create(context, this, &configurationStore); + if (status != CELIX_SUCCESS){ + return status; + } + // (2.2) SERVICE TRACKER + status = managedServiceTracker_create(context, this, configurationStore, &managedServiceTrackerHandle, &managedServiceTracker); + if (status != CELIX_SUCCESS){ + return status; + } + // (3) INITIALIZATION + this->context = context; + + this->managedServiceTrackerHandle = managedServiceTrackerHandle; + this->managedServiceTracker = managedServiceTracker; + this->configurationStore = configurationStore; + + (*factory)->handle = this; + (*factory)->getService = configurationAdminFactory_getService; + (*factory)->ungetService = configurationAdminFactory_ungetService; + + *instance = this; + return CELIX_SUCCESS; + +} + +celix_status_t configurationAdminFactory_destroy( bundle_context_pt context, configuration_admin_factory_pt instance){ + managedServiceTracker_destroy(context, instance->managedServiceTrackerHandle, instance->managedServiceTracker); + configurationStore_destroy(instance->configurationStore); + free(instance); + return CELIX_SUCCESS; +} +/* ========== IMPLEMENTS SERVICE FACTORY ========== */ + +/* ---------- public ---------- */ + +celix_status_t configurationAdminFactory_getService(void *handle, bundle_pt bundle, service_registration_pt registration, void **service){ + + celix_status_t status; + + configuration_admin_factory_pt configAdminFactory = (configuration_admin_factory_pt)handle; + configuration_admin_service_pt confAdminService; + + // TODO + // (1) reference = registration.getServiceReference + // (2) eventDispatcher.setServiceReference(reference); + + // (3) return new ConfigurationAdminImpl(this, configurationStore, bundle); + status = configurationAdmin_create(configAdminFactory, configAdminFactory->configurationStore, bundle, &confAdminService); + if (status != CELIX_SUCCESS){ + return status; + } + + /* DEBUG CODE * + char* location; + bundle_getBundleLocation(bundle, &location); + printf("[ SUCCESS ]: ConfigAdminFactory - get configAdminService (bundle=%s) \n ",location); + * END DEBUG CODE */ + + (*service) = confAdminService; + + return CELIX_SUCCESS; + +} + +celix_status_t configurationAdminFactory_ungetService(void *factory, bundle_pt bundle, service_registration_pt registration, void **service) { + + configuration_admin_service_pt confAdminService = (*service); + + configurationAdmin_destroy(&confAdminService); + + return CELIX_SUCCESS; +} + + +/* ========== IMPLEMENTATION ========== */ + +/* ---------- public ---------- */ + +celix_status_t configurationAdminFactory_start(configuration_admin_factory_pt factory){ + + celix_status_t status; + printf("%s\n", __func__); + status = serviceTracker_open(factory->managedServiceTracker); + if( status!=CELIX_SUCCESS ){ + printf("[ ERROR ]: ConfigAdminFactory - ManagedServiceTracker not opened \n"); + return status; + } + + return CELIX_SUCCESS; +} + +celix_status_t configurationAdminFactory_stop(configuration_admin_factory_pt factory){ + celix_status_t status = serviceTracker_close(factory->managedServiceTracker); + return status;; +} + +celix_status_t configurationAdminFactory_checkConfigurationPermission(configuration_admin_factory_pt factory){ + return CELIX_SUCCESS; +} + +celix_status_t configurationAdminFactory_dispatchEvent(configuration_admin_factory_pt factory, int type, char *factoryPid, char *pid){ + return CELIX_SUCCESS; +} + +celix_status_t configurationAdminFactory_notifyConfigurationUpdated(configuration_admin_factory_pt factory, configuration_pt configuration, bool isFactory){ + + if (isFactory == true){ + + return CELIX_SUCCESS; + + }else{ + + return managedServiceTracker_notifyUpdated(factory->managedServiceTrackerHandle,configuration); + + } + +} + +celix_status_t configurationAdminFactory_notifyConfigurationDeleted(configuration_admin_factory_pt factory, configuration_pt configuration, bool isFactory){ + return CELIX_SUCCESS; +} + +celix_status_t configurationAdminFactory_modifyConfiguration(configuration_admin_factory_pt factory, service_reference_pt reference, properties_pt properties){ + return CELIX_SUCCESS; +} http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/config_admin/service/private/src/configuration_admin_impl.c ---------------------------------------------------------------------- diff --git a/bundles/config_admin/service/private/src/configuration_admin_impl.c b/bundles/config_admin/service/private/src/configuration_admin_impl.c new file mode 100644 index 0000000..6d01cb0 --- /dev/null +++ b/bundles/config_admin/service/private/src/configuration_admin_impl.c @@ -0,0 +1,208 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ +/* + * configuration_admin_impl.c + * + * \date Aug 12, 2013 + * \author <a href="mailto:d...@celix.apache.org">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +/* celix.config_admin.ConfigAdmin */ +#include "configuration_admin_impl.h" + +/* celix.framework.public */ +#include "utils.h" +/* celix.framework_patch*/ +#include "framework_patch.h" +/* celix.config_admin.private*/ +#include "configuration_impl.h" + + +static celix_status_t configurationAdmin_checkPid(char *pid); + + +/* ========== CONSTRUCTOR ========== */ + +celix_status_t configurationAdmin_create(configuration_admin_factory_pt factory, configuration_store_pt store, bundle_pt bundle, + configuration_admin_service_pt *service){ + + *service = calloc(1, sizeof(**service)); + + + if(!*service){ + printf("[ ERROR ]: ConfigAdmin - Not initialized(ENOMEM) \n"); + return CELIX_ENOMEM; + } + + configuration_admin_pt this = calloc(1, sizeof(*this)); + if (!this){ + printf("[ ERROR ]: ConfigAdmin - Not initialized \n"); + return CELIX_ENOMEM; + } + + this->bundle = bundle; + + this->configurationAdminFactory = factory; + this->configurationStore = store; + + (*service)->configAdmin = this; + (*service)->createFactoryConfiguration = configurationAdmin_createFactoryConfiguration; + (*service)->createFactoryConfiguration2 = configurationAdmin_createFactoryConfiguration2; + (*service)->getConfiguration = configurationAdmin_getConfiguration; + (*service)->getConfiguration2 = configurationAdmin_getConfiguration2; + (*service)->listConfigurations = configurationAdmin_listConfigurations; + + return CELIX_SUCCESS; + +} + +celix_status_t configurationAdmin_destroy(configuration_admin_service_pt *service) { + free((*service)->configAdmin); + free(*service); + + return CELIX_SUCCESS; +} +/* ========== IMPLEMENTATION ========== */ + + +/* ---------- public ---------- */ + +celix_status_t configurationAdmin_createFactoryConfiguration(configuration_admin_pt configAdmin, char *factoryPid, configuration_pt *configuration){ + return CELIX_SUCCESS; +} + +celix_status_t configurationAdmin_createFactoryConfiguration2(configuration_admin_pt configAdmin, char *factoryPid, char *location, configuration_pt *configuration){ + return CELIX_SUCCESS; +} + +celix_status_t configurationAdmin_getConfiguration(configuration_admin_pt configAdmin, char *pid, configuration_pt *configuration){ + configuration_pt config; + + const char* configAdminBundleLocation; + const char* configBundleLocation; + + + // (1) configurationAdmin.checkPid + if ( configurationAdmin_checkPid(pid) != CELIX_SUCCESS ){ + *configuration = NULL; + return CELIX_ILLEGAL_ARGUMENT; + } + + // (2) bundle.getLocation + if ( bundle_getBundleLocation(configAdmin->bundle,&configAdminBundleLocation) != CELIX_SUCCESS ){ + *configuration = NULL; + return CELIX_ILLEGAL_ARGUMENT; + } + + // (3) delegates to configurationStore.getConfiguration + if ( configurationStore_getConfiguration(configAdmin->configurationStore, pid, (char*)configAdminBundleLocation, &config) != CELIX_SUCCESS ){ + *configuration = NULL; + return CELIX_ILLEGAL_ARGUMENT; + } + + + /* ---------- pseudo code ---------- */ + /* + + (4) is the configuration already bound? / configBundleLocation != NULL ? + YES - are the Configuration and the ConfigAdmin bound to the same bundle? + NO - check permission + + (5) config.bind(bundle) + if the Configuration is not bound, then we bind it up with the ConfigAdmin bundle + in case of be bound, the function does not bind it up with ConfigAdmin bundle + + */ + + + // (4) config.getBundleLocation != NULL ? + if ( configuration_getBundleLocation2(config->handle,false,(char**)&configBundleLocation) == CELIX_SUCCESS ){ + + if ( strcmp(configAdminBundleLocation,configBundleLocation) != 0 ){ + + if ( configurationAdminFactory_checkConfigurationPermission(configAdmin->configurationAdminFactory) != CELIX_SUCCESS ){ + printf("[ ERROR ]: ConfigAdmin - Config. Permission \n"); + *configuration = NULL; + return CELIX_ILLEGAL_STATE; //TODO checkConfigurationPermission not yet implemented, everything is allowed + } + } + } + + // (5) config.bind(bundle) + bool dummy; + if ( configuration_bind(config->handle, configAdmin->bundle, &dummy) != CELIX_SUCCESS){ + *configuration = NULL; + printf("[ ERROR]: ConfigAdmin - bind Config."); + return CELIX_ILLEGAL_STATE; + } + + *configuration = config; + return CELIX_SUCCESS; + +} + +celix_status_t configurationAdmin_getConfiguration2(configuration_admin_pt configAdmin, char *pid, char *location, configuration_pt *configuration){ + +// celix_status_t status; +// +// status = configurationAdmin_checkPid(pid); +// if (status != CELIX_SUCCESS){ +// *configuration = NULL; +// return status; +// } +// +// status = configurationAdminFactory_checkConfigurationPermission(configAdmin->configurationAdminFactory); +// if (status != CELIX_SUCCESS){ +// *configuration = NULL; +// return status; +// } +// +// configuration_pt config; +// status = configurationStore_getConfiguration(configAdmin->configurationStore, pid, location, &config); +// if (status != CELIX_SUCCESS){ +// *configuration = NULL; +// return status; +// } +// +// printf("SUCCESS get Configuration"); +// *configuration = config; + return CELIX_SUCCESS; +} + +celix_status_t configurationAdmin_listConfigurations(configuration_admin_pt configAdmin, char *filter, array_list_pt *configurations){ + return CELIX_SUCCESS; +} + +/* ---------- private ---------- */ + +celix_status_t configurationAdmin_checkPid(char *pid){ + + if (pid == NULL){ + printf("[ ERROR ]: PID cannot be null"); + return CELIX_ILLEGAL_ARGUMENT; + } else { + return CELIX_SUCCESS; + } +} http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/config_admin/service/private/src/configuration_impl.c ---------------------------------------------------------------------- diff --git a/bundles/config_admin/service/private/src/configuration_impl.c b/bundles/config_admin/service/private/src/configuration_impl.c new file mode 100644 index 0000000..ed3c8c6 --- /dev/null +++ b/bundles/config_admin/service/private/src/configuration_impl.c @@ -0,0 +1,683 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ +/* + * configuration_impl.c + * + * \date Aug 12, 2013 + * \author <a href="mailto:d...@celix.apache.org">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +/*celix.config_admin.Configuration */ +//#include "configuration.h" +#include "configuration_impl.h" +#include "celix_threads.h" + + +/* celix.framework */ +#include "bundle.h" +#include "constants.h" +#include "utils.h" +/* celix.framework_patch*/ +#include "framework_patch.h" +/* celix.config_admin.public*/ +#include "configuration_event.h" +#include "configuration_admin.h" +/* celix.config_admin.private*/ +#include "configuration_admin_factory.h" +#include "configuration_store.h" + +struct configuration_impl { + + configuration_admin_factory_pt configurationAdminFactory; + configuration_store_pt configurationStore; + + configuration_pt configuration_interface; + char *bundleLocation; + char *factoryPid; + char *pid; + properties_pt dictionary; + + bool deleted; // Not sure if it's needed + bundle_pt boundBundle; + + celix_thread_mutex_t mutex; +}; + + + +// External interface functions +// see configuration.h +celix_status_t configuration_delete(void* configuration); +celix_status_t configuration_equals(void* thisConfiguration, void* otherConfiguration, bool *equals); +celix_status_t configuration_getBundleLocation(void *configuration, char **bundleLocation); +celix_status_t configuration_getFactoryPid(void *handle, char **factoryPid); +celix_status_t configuration_hashCode(void *handle, int *hashCode); +celix_status_t configuration_setBundleLocation(void *handle, char *bundleLocation); +celix_status_t configuration_update(void *handle, properties_pt properties); + + +// Configuration admin internal functions +// see configuration_impl.h +//static celix_status_t configuration_getBundleLocation2(configuration_impl_pt configuration, bool checkPermission, char **location); + + +// static functions + +// org.eclipse.equinox.internal.cm +static celix_status_t configuration_getFactoryPid2(configuration_impl_pt configuration, bool checkDeleted, char **factoryPid); +static celix_status_t configuration_getPid2(configuration_impl_pt configuration, bool checkDeleted, char **pid); +static celix_status_t configuration_updateDictionary(configuration_impl_pt configuration, properties_pt properties); + +// org.apache.felix.cm.impl +static celix_status_t configuration_setBundleLocationProperty(configuration_impl_pt configuration, properties_pt *properties); +static celix_status_t configuration_setAutoProperties(configuration_impl_pt configuration, properties_pt *properties, bool withBundleLocation); + + +static celix_status_t configuration_checkDeleted(configuration_impl_pt configuration); + +/* ========== CONSTRUCTOR ========== */ + +/* ---------- public ---------- */ + +celix_status_t configuration_create( configuration_admin_factory_pt factory, configuration_store_pt store, + char *factoryPid, char *pid, char *bundleLocation, + configuration_pt *configuration){ + + struct configuration *config; + struct configuration_impl *conf_impl; + celix_thread_mutexattr_t mutex_attr; + + config = calloc(1, sizeof(struct configuration)); + if (config == NULL) return CELIX_ENOMEM; + conf_impl = calloc(1, sizeof(struct configuration_impl)); + if (conf_impl == NULL) { + free (config); + return CELIX_ENOMEM; + } + + config->configuration_delete = configuration_delete; + config->configuration_equals = configuration_equals; + config->configuration_getBundleLocation = configuration_getBundleLocation; + config->configuration_getFactoryPid = configuration_getFactoryPid; + config->configuration_getPid = configuration_getPid; + config->configuration_getProperties = configuration_getProperties; + config->configuration_hashCode = configuration_hashCode; + config->configuration_setBundleLocation = configuration_setBundleLocation; + config->configuration_update = configuration_update; +/* + config = calloc(1,sizeof(struct configuration)); + if(!config){ + printf("[ ERROR ]: Configuration{PID=%s} - Not created (ENOMEM) \n",pid); + return CELIX_ENOMEM; + } +*/ + conf_impl->configurationAdminFactory = factory; + conf_impl->configurationStore = store; + + if (factoryPid != NULL) + conf_impl->factoryPid = strdup(factoryPid); + else + conf_impl->factoryPid = NULL; + if (pid != NULL) + conf_impl->pid = strdup(pid); + else + conf_impl->pid = NULL; + if (bundleLocation != NULL) + conf_impl->bundleLocation = strdup(bundleLocation); + else + conf_impl->bundleLocation = NULL; + conf_impl->dictionary = NULL; + + conf_impl->deleted = false; + conf_impl->boundBundle = NULL; + + celixThreadMutexAttr_create(&mutex_attr); + celixThreadMutexAttr_settype(&mutex_attr, CELIX_THREAD_MUTEX_RECURSIVE); // why recursive? + if( celixThreadMutex_create(&conf_impl->mutex, &mutex_attr) != CELIX_SUCCESS ){ + printf("[ ERROR ]: Configuration{PID=%s} - Not created (MUTEX) \n",pid); + return CELIX_ILLEGAL_ARGUMENT; + } + + conf_impl->configuration_interface = config; + config->handle = conf_impl; + *configuration = config; + return CELIX_SUCCESS; +} + +celix_status_t configuration_create2(configuration_admin_factory_pt factory, configuration_store_pt store, + properties_pt dictionary, + configuration_pt *configuration){ + + configuration_pt config; + configuration_impl_pt conf_impl; + + celix_thread_mutexattr_t mutex_attr; + const char *value; + + config = calloc(1, sizeof(struct configuration)); + if (config == NULL) return CELIX_ENOMEM; + conf_impl = calloc(1, sizeof(struct configuration_impl)); + if (conf_impl == NULL) { + free (config); + return CELIX_ENOMEM; + } + + config->configuration_delete = configuration_delete; + config->configuration_equals = configuration_equals; + config->configuration_getBundleLocation = configuration_getBundleLocation; + config->configuration_getFactoryPid = configuration_getFactoryPid; + config->configuration_getPid = configuration_getPid; + config->configuration_getProperties = configuration_getProperties; + config->configuration_hashCode = configuration_hashCode; + config->configuration_setBundleLocation = configuration_setBundleLocation; + config->configuration_update = configuration_update; + + conf_impl->configurationAdminFactory = factory; + conf_impl->configurationStore = store; + + value = properties_get(dictionary,(char *)SERVICE_FACTORYPID); + if (value != NULL) + conf_impl->factoryPid = strdup(value); + else + conf_impl->factoryPid = NULL; + value = properties_get(dictionary, (char *)OSGI_FRAMEWORK_SERVICE_PID); + if (value != NULL) + conf_impl->pid = strdup(value); + else + conf_impl->pid = NULL; + value = properties_get(dictionary, (char *)SERVICE_BUNDLELOCATION); + if (value != NULL) + conf_impl->bundleLocation = strdup(value); + else + conf_impl->bundleLocation = NULL; + conf_impl->dictionary = NULL; + + conf_impl->deleted = false; + conf_impl->boundBundle = NULL; + + celixThreadMutexAttr_create(&mutex_attr); + celixThreadMutexAttr_settype(&mutex_attr, CELIX_THREAD_MUTEX_RECURSIVE); // why recursive? + if( celixThreadMutex_create(&conf_impl->mutex, &mutex_attr) != CELIX_SUCCESS ){ + printf("[ ERROR ]: Configuration{PID=%s} - Not created (MUTEX) \n", conf_impl->pid); + return CELIX_ILLEGAL_ARGUMENT; + } + celixThreadMutexAttr_destroy(&mutex_attr); + configuration_updateDictionary(conf_impl, dictionary); + + conf_impl->configuration_interface = config; + config->handle = conf_impl; + *configuration = config; + return CELIX_SUCCESS; + +} + + +/* ========== IMPLEMENTS CONFIGURATION ========== */ + +/* ---------- public ---------- */ +// specifications + +celix_status_t configuration_delete(void *handle){ + configuration_impl_pt conf = (configuration_impl_pt)handle; + + printf("TODO: Implement configuration_delete\n"); + celixThreadMutex_destroy(&conf->mutex); + if (conf->factoryPid != NULL) + free(conf->factoryPid); + if (conf->pid != NULL) + free(conf->pid); + if (conf->bundleLocation != NULL) + free(conf->bundleLocation); + free(conf->configuration_interface); + free(conf); + return CELIX_SUCCESS; +} + +celix_status_t configuration_equals(void* thisConfiguration, void *otherConfiguration, bool *equals){ + return CELIX_SUCCESS; +} + +celix_status_t configuration_getBundleLocation(void *handle, char **bundleLocation){ + return configuration_getBundleLocation2( handle, true, bundleLocation); +} + +celix_status_t configuration_getFactoryPid(void *handle, char **factoryPid){ + return configuration_getFactoryPid2(handle, true, factoryPid); +} + +celix_status_t configuration_getPid(void *handle, char **pid){ + return configuration_getPid2(handle, true, pid); +} + +celix_status_t configuration_getProperties(void *handle, properties_pt *properties){ + + configuration_impl_pt conf = (configuration_impl_pt) handle; + + properties_pt copy = conf->dictionary; + + // (1) configuration.lock + configuration_lock(conf); + + // (2) configuration.checkDeleted + if ( configuration_checkDeleted(conf) != CELIX_SUCCESS ){ + configuration_unlock(conf); + return CELIX_ILLEGAL_STATE; + } + // (3) Have the Configuration properties ? + if ( conf->dictionary == NULL ){ + *properties = NULL; + configuration_unlock(conf); + return CELIX_SUCCESS; + } + + // (4) configuration.setAutoProperties + if ( configuration_setAutoProperties(conf, ©, false) != CELIX_SUCCESS ){ + configuration_unlock(conf); + return CELIX_ILLEGAL_ARGUMENT; + } + + // (5) return + *properties = copy; + configuration_unlock(conf); + return CELIX_SUCCESS; +} + +celix_status_t configuration_hashCode(void *handle, int *hashCode){ + return CELIX_SUCCESS; +} + +celix_status_t configuration_setBundleLocation(void *handle, char *bundleLocation){ + + configuration_impl_pt conf = (configuration_impl_pt)handle; + configuration_lock(conf); + + if ( configuration_checkDeleted(conf) != CELIX_SUCCESS ){ + configuration_unlock(conf); + return CELIX_ILLEGAL_STATE; + } + + // TODO configurationAdminFactory.checkConfigurationPermission + + conf->bundleLocation = bundleLocation; + conf->boundBundle = NULL; // always reset the boundBundle when setBundleLocation is called + + configuration_unlock(conf); + + return CELIX_SUCCESS; +} + +celix_status_t configuration_update(void *handle, properties_pt properties){ + + configuration_impl_pt conf = (configuration_impl_pt)handle; + + + celix_status_t status; + + // (1) + configuration_lock(conf); + + // (2) + if ( configuration_checkDeleted(conf) != CELIX_SUCCESS ){ + configuration_unlock(conf); + return CELIX_ILLEGAL_STATE; + } + // (3) + configuration_updateDictionary(conf, properties); + + // (4) + status = configurationStore_saveConfiguration(conf->configurationStore, conf->pid, conf->configuration_interface); + if (status != CELIX_SUCCESS){ + configuration_unlock(conf); + return status; + } + + // (5) + bool isFactory; + if (conf->factoryPid == NULL){ + isFactory = false; + } else{ + isFactory = true; + } + + status = configurationAdminFactory_notifyConfigurationUpdated(conf->configurationAdminFactory, conf->configuration_interface, isFactory); + if (status != CELIX_SUCCESS){ + configuration_unlock(conf); + return status; + } + + // (6) + status = configurationAdminFactory_dispatchEvent(conf->configurationAdminFactory, CONFIGURATION_EVENT_CM_UPDATED, conf->factoryPid, conf->pid); + if (status != CELIX_SUCCESS){ + configuration_unlock(conf); + return status; + } + + // (7) + configuration_unlock(conf); + return CELIX_SUCCESS; +} + +/* ---------- protected ---------- */ +// org.eclipse.equinox.cm.impl + +celix_status_t configuration_lock(configuration_impl_pt configuration){ +// printf("[ DEBUG ]: Configuration{PID=%s} - LOCK \n",configuration->pid); + celixThreadMutex_lock(&configuration->mutex); + return CELIX_SUCCESS; +} + +celix_status_t configuration_unlock(configuration_impl_pt configuration){ +// printf("[ DEBUG ]: Configuration{PID=%s} - UNLOCK \n",configuration->pid); + celixThreadMutex_unlock(&configuration->mutex); + return CELIX_SUCCESS; +} + +celix_status_t configuration_checkLocked(configuration_impl_pt configuration){ + // Not used + return CELIX_SUCCESS; +} + +celix_status_t configuration_bind(configuration_impl_pt configuration, bundle_pt bundle, bool *isBind){ + +// printf("[ DEBUG ]: Configuration{PID=%s} - bind(START) \n",configuration->pid); + + char *bundleLocation; + + configuration_lock(configuration); + + /* ----------- BINDING -------------- */ + + // (1): it's the configuration already bound? + if ( configuration->boundBundle == NULL ){// (1): No + + // (2): it's the configuration located? + if ( configuration->bundleLocation != NULL ){//(2): Yes + + if ( bundle_getBundleLocation(bundle, (const char**)&bundleLocation) != CELIX_SUCCESS){ + configuration_unlock(configuration); + return CELIX_ILLEGAL_ARGUMENT; + } + + // (3): bundle and configuration have the same location? + if ( strcmp(configuration->bundleLocation, bundleLocation) == 0 ){ // (3): Yes + // bind up configuration with bundle + configuration->boundBundle = bundle; +// printf("[ DEBUG ]: Configuration{PID=%s} - bind (bound with Bundle{%s}) \n",configuration->pid,bundleLocation); + } + // (3): No + + }else{// (2): No + // bind up configuration with bundle + configuration->boundBundle = bundle; +// printf("[ DEBUG ]: Configuration{PID=%s}) - bind (not located and now bound with Bundle) \n",configuration->pid); + } + + }// (1): Yes + + /* ------------ RETURN -------------- */ + + bool bind; + if(configuration->boundBundle == bundle){ + bind = true; + }else{ + bind = false; + } + + /* ------------- END ----------------- */ + configuration_unlock(configuration); + + *isBind = bind; +// printf("[ DEBUG ]: Configuration{PID=%s} - bind(END) \n",configuration->pid); + return CELIX_SUCCESS; + +} + +celix_status_t configuration_unbind(configuration_impl_pt configuration, bundle_pt bundle){ + configuration->boundBundle = NULL; + return CELIX_SUCCESS; +} + +celix_status_t configuration_getBundleLocation2(configuration_impl_pt configuration, bool checkPermission, char** location){ + + celix_status_t status; + + // (1) + configuration_lock(configuration); + + // (2) + if( configuration_checkDeleted(configuration) != CELIX_SUCCESS ){ + configuration_unlock(configuration); + return CELIX_ILLEGAL_STATE; + } + // (3) + if ( checkPermission ){ + + if ( configurationAdminFactory_checkConfigurationPermission(configuration->configurationAdminFactory) != CELIX_SUCCESS ){ + return CELIX_ILLEGAL_STATE; // TODO configurationAdmin, not yet implemented + } + } + + // (4) + if ( configuration->bundleLocation ){ + *location = configuration->bundleLocation; + configuration_unlock(configuration); + return CELIX_SUCCESS; + } + + // (5) + if ( configuration->boundBundle != NULL ){ + status = bundle_getBundleLocation(configuration->boundBundle,(const char**)location); + configuration_unlock(configuration); + return status; + } + + // (6) + *location = NULL; + configuration_unlock(configuration); + return CELIX_SUCCESS; +} + +static celix_status_t configuration_getFactoryPid2(configuration_impl_pt configuration, bool checkDeleted, char **factoryPid){ + return CELIX_SUCCESS; +} + +static celix_status_t configuration_getPid2(configuration_impl_pt configuration, bool checkDeleted, char **pid){ + + configuration_lock(configuration); + + if ( checkDeleted ){ + if ( configuration_checkDeleted(configuration) != CELIX_SUCCESS ){ + configuration_unlock(configuration); + return CELIX_ILLEGAL_STATE; + } + } + + *pid = configuration->pid; + + configuration_unlock(configuration); + + return CELIX_SUCCESS; +} + +// org.eclipse.equinox.internal.cm modified to fit with org.apache.felix.cm.impl +// change due to ConfigurationStore implementation +celix_status_t configuration_getAllProperties(configuration_impl_pt configuration, properties_pt *properties){ + + celix_status_t status; + + properties_pt copy = NULL; + + // (1) configuration.lock + configuration_lock(configuration); + + // (2) configuration.deleted ? + if( configuration->deleted ){ + *properties = NULL; + configuration_unlock(configuration); + return CELIX_SUCCESS; + } + + // (3) configuration.getProps + if( configuration_getProperties(configuration, ©) != CELIX_SUCCESS){ + configuration_unlock(configuration); + return CELIX_ILLEGAL_ARGUMENT; + } + + // (4) configuration.setProperties + if ( copy == NULL ){ //set all the automatic properties + + copy = properties_create(); + status = configuration_setAutoProperties(configuration, ©, true); + + }else{ // copy != NULL - only set service.bundleLocation + + status = configuration_setBundleLocationProperty(configuration, ©); + + } + + // (5) return + if (status == CELIX_SUCCESS){ + *properties = copy; + }else{ + *properties = NULL; + } + + configuration_unlock(configuration); + return status; + +} + +celix_status_t configuration_isDeleted(configuration_impl_pt configuration, bool *isDeleted){ + return CELIX_SUCCESS; +} + +/* ---------- private ---------- */ + +celix_status_t configuration_checkDeleted(configuration_impl_pt configuration){ + + if ( configuration->deleted ){ + printf("[CELIX_ILLEGAL_STATE ]: configuration(pid=%s) deleted \n", configuration->pid); + return CELIX_ILLEGAL_STATE; + } + + return CELIX_SUCCESS; +} + +// configuration->dictionary must not contain keys reserved to ConfigAdmin (i.e. "service.pid") +celix_status_t configuration_updateDictionary(configuration_impl_pt configuration, properties_pt properties){ + + properties_pt newDictionary = NULL; + + if ( configuration->dictionary != NULL && configuration->dictionary != properties ){ + properties_destroy(configuration->dictionary); //free + } + + newDictionary = properties; // properties == NULL | properties != NULL + + if ( newDictionary != NULL ){ + + hashMap_remove(newDictionary, (void *) OSGI_FRAMEWORK_SERVICE_PID); + hashMap_remove(newDictionary, (void *) SERVICE_FACTORYPID); + hashMap_remove(newDictionary, (void *) SERVICE_BUNDLELOCATION); + } + + configuration->dictionary = newDictionary; + return CELIX_SUCCESS; + +} + +/* ========== IMPLEMENTATION ========== */ + +/* ---------- protected ---------- */ +#if 0 +celix_status_t configuration_getPool(configuration_impl_pt configuration, apr_pool_t **pool){ + + printf("[ DEBUG ]: Configuration{PID=%s} - get Pool \n",configuration->pid); + + configuration_lock(configuration); + + *pool = configuration->pool; + + configuration_unlock(configuration); + + return CELIX_SUCCESS; +} +#endif +/* ---------- private ---------- */ +// org.apache.felix.cm.impl + + +// properties_pt as input and output +celix_status_t configuration_setAutoProperties(configuration_impl_pt configuration, properties_pt *properties, bool withBundleLocation){ + + //(1) configuration.lock + configuration_lock(configuration); + + // (2) set service.pid +// 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 ){ + properties_set(*properties, (char*)SERVICE_FACTORYPID, configuration->factoryPid); + } + + // (4) set service.bundleLocation + if ( withBundleLocation ){ + + if ( configuration_setBundleLocationProperty(configuration, properties) != CELIX_SUCCESS ){ + configuration_unlock(configuration); + return CELIX_ILLEGAL_ARGUMENT; + } + + } + + // (5) return + configuration_unlock(configuration); + return CELIX_SUCCESS; + +} + +celix_status_t configuration_setBundleLocationProperty(configuration_impl_pt configuration, properties_pt *properties){ + + char *bundleLocation; + + configuration_lock(configuration); + + if( configuration_getBundleLocation(configuration, &bundleLocation) != CELIX_SUCCESS ){ + configuration_unlock(configuration); + return CELIX_ILLEGAL_ARGUMENT; + } + + if ( bundleLocation != NULL ) { + properties_set(*properties, (char*)SERVICE_BUNDLELOCATION, bundleLocation); + } + + configuration_unlock(configuration); + + return CELIX_SUCCESS; + +} http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/config_admin/service/private/src/configuration_store.c ---------------------------------------------------------------------- diff --git a/bundles/config_admin/service/private/src/configuration_store.c b/bundles/config_admin/service/private/src/configuration_store.c new file mode 100644 index 0000000..37b091e --- /dev/null +++ b/bundles/config_admin/service/private/src/configuration_store.c @@ -0,0 +1,417 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ +/* + * configuration_store.c + * + * \date Aug 12, 2013 + * \author <a href="mailto:d...@celix.apache.org">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <dirent.h> +#include <unistd.h> +#include <limits.h> + +/* celix.config_admin.ConfigurationStore */ +#include "configuration_store.h" + +/* celix.utils */ +#include "hash_map.h" +/* celix.framework */ +#include "properties.h" +#include "utils.h" +/* celix.config_admin.private*/ +#include "configuration_admin_factory.h" +#include "configuration.h" +#include "configuration_impl.h" + +#define STORE_DIR "store" +#define PID_EXT ".pid" +#define MAX_CONFIG_PROPERTY_LEN 128 + + +struct configuration_store { + + bundle_context_pt context; + + celix_thread_mutex_t mutex; + + configuration_admin_factory_pt configurationAdminFactory; + + hash_map_pt configurations; +// int createdPidCount; + +}; + +static celix_status_t configurationStore_createCache(configuration_store_pt store); +static celix_status_t configurationStore_getConfigurationFile(char *pid, char* storePath, int *file); +static celix_status_t configurationStore_writeConfigurationFile(int fd, properties_pt properties); +static celix_status_t configurationStore_readCache(configuration_store_pt store); +static celix_status_t configurationStore_readConfigurationFile(const char *name, int size, properties_pt *dictionary); +static celix_status_t configurationStore_parseDataConfigurationFile(char *data, properties_pt *dictionary); + +/* ========== CONSTRUCTOR ========== */ + +celix_status_t configurationStore_create(bundle_context_pt context, configuration_admin_factory_pt factory, configuration_store_pt *store) { + + *store = calloc(1, sizeof(**store)); + + if (!*store) { + printf("[ ERROR ]: ConfigStore - Not initialized (ENOMEM) \n"); + return CELIX_ENOMEM; + } + + (*store)->context = context; + + (*store)->configurationAdminFactory = factory; + + (*store)->configurations = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL); +// (*store)->createdPidCount = 0; + + if (configurationStore_createCache((*store)) != CELIX_SUCCESS) { + printf("[ ERROR ]: ConfigStore - Not initialized (CACHE) \n"); + return CELIX_ILLEGAL_ARGUMENT; + } + + celix_status_t mutexStatus = celixThreadMutex_create(&(*store)->mutex, NULL); + if (mutexStatus != CELIX_SUCCESS) { + printf("[ ERROR ]: ConfigStore - Not initialized (MUTEX) \n"); + return CELIX_ILLEGAL_ARGUMENT; + } + + configurationStore_readCache((*store)); + + return CELIX_SUCCESS; +} + +celix_status_t configurationStore_destroy(configuration_store_pt store) { + celixThreadMutex_destroy(&store->mutex); + hashMap_destroy(store->configurations, false, true); + free(store); + + return CELIX_SUCCESS; +} + +/* ========== IMPLEMENTATION ========== */ + +/* ---------- public ---------- */ +// org.eclipse.equinox.internal.cm +celix_status_t configurationStore_lock(configuration_store_pt store) { + celixThreadMutex_lock(&store->mutex); + return CELIX_SUCCESS; +} + +celix_status_t configurationStore_unlock(configuration_store_pt store) { + celixThreadMutex_unlock(&store->mutex); + return CELIX_SUCCESS; +} + +celix_status_t configurationStore_saveConfiguration(configuration_store_pt store, char *pid, configuration_pt configuration) { + + celix_status_t status; + + //(1) config.checkLocked + + //(2) configurationStore.getFile + int configFile; + status = configurationStore_getConfigurationFile(pid, (char *) STORE_DIR, &configFile); + if (status != CELIX_SUCCESS) { + return status; + } + + //(4) configProperties = config.getAllProperties + + properties_pt configProperties = NULL; + status = configuration_getAllProperties(configuration->handle, &configProperties); + if (status != CELIX_SUCCESS) { + printf("[ ERROR ]: ConfigStore - config{PID=%s}.getAllProperties \n", pid); + return status; + } + + + //(5) configStore.writeFile(file,properties) + status = configurationStore_writeConfigurationFile(configFile, configProperties); + + if (status != CELIX_SUCCESS) { + return status; + } + + return CELIX_SUCCESS; +} + +celix_status_t configurationStore_removeConfiguration(configuration_store_pt store, char *pid) { + return CELIX_SUCCESS; +} + +celix_status_t configurationStore_getConfiguration(configuration_store_pt store, char *pid, char *location, configuration_pt *configuration) { + + celix_status_t status; + + configuration_pt config; + config = hashMap_get(store->configurations, pid); + + if (config == NULL) { + + status = configuration_create(store->configurationAdminFactory, store, NULL, pid, location, &config); + if (status != CELIX_SUCCESS) { + printf("[ ERROR ]: ConfigStore - getConfig(PID=%s) (unable to create) \n", pid); + return status; + } + + hashMap_put(store->configurations, pid, config); + } + + *configuration = config; + return CELIX_SUCCESS; +} + +celix_status_t configurationStore_createFactoryConfiguration(configuration_store_pt store, char *factoryPid, char *location, configuration_pt *configuration) { + return CELIX_SUCCESS; +} + +celix_status_t configurationStore_findConfiguration(configuration_store_pt store, char *pid, configuration_pt *configuration) { + + *configuration = hashMap_get(store->configurations, pid); + return CELIX_SUCCESS; + +} + +celix_status_t configurationStore_getFactoryConfigurations(configuration_store_pt store, char *factoryPid, configuration_pt *configuration) { + return CELIX_SUCCESS; +} + +celix_status_t configurationStore_listConfigurations(configuration_store_pt store, filter_pt filter, array_list_pt *configurations) { + return CELIX_SUCCESS; +} + +celix_status_t configurationStore_unbindConfigurations(configuration_store_pt store, bundle_pt bundle) { + return CELIX_SUCCESS; +} + +/* ---------- private ---------- */ + +celix_status_t configurationStore_createCache(configuration_store_pt store) { + + int result = mkdir((const char*) STORE_DIR, 0777); + + if ((result == 0) || ((result == -1) && (errno == EEXIST))) { + return CELIX_SUCCESS; + } + + printf("[ ERROR ]: ConfigStore - Create Cache \n"); + return CELIX_FILE_IO_EXCEPTION; + +} + +celix_status_t configurationStore_getConfigurationFile(char *pid, char* storePath, int *file) { + + // (1) The full path to the file + char fname[PATH_MAX]; + strcpy(fname, storePath); + strcat(fname, "/"); + strcat(fname, (const char *) pid); + strcat(fname, (const char *) PID_EXT); + + // (2) configuration.getPool + // (3) file.open + if ((*file = open((const char*) fname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) < 0) { + printf("[ ERROR ]: ConfigStore - getFile(IO_EXCEPTION) \n"); + return CELIX_FILE_IO_EXCEPTION; + } + return CELIX_SUCCESS; +} + +celix_status_t configurationStore_writeConfigurationFile(int file, properties_pt properties) { + + if (properties == NULL || hashMap_size(properties) <= 0) { + return CELIX_SUCCESS; + } + // size >0 + + char buffer[256]; + + hash_map_iterator_pt iterator = hashMapIterator_create(properties); + while (hashMapIterator_hasNext(iterator)) { + + hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator); + + char* key = hashMapEntry_getKey(entry); + char* val = hashMapEntry_getValue(entry); + + snprintf(buffer, 256, "%s=%s\n", key, val); + + int buffLength = strlen((const char *) buffer); + + if (write(file, (const void *) buffer, buffLength) != buffLength) { + printf("[ ERROR ]: ConfigStore - writing in Cache incomplete \n"); + return CELIX_FILE_IO_EXCEPTION; + } + } + hashMapIterator_destroy(iterator); + return CELIX_SUCCESS; + +} + +celix_status_t configurationStore_readCache(configuration_store_pt store) { + + celix_status_t status; + + DIR *cache; // directory handle + + properties_pt properties = NULL; + configuration_pt configuration = NULL; + char *pid; + + // (1) cache.open + cache = opendir((const char*) STORE_DIR); + if (cache == NULL) { + printf("[ ERROR ]: ConfigStore - Read Cache \n"); + return CELIX_FILE_IO_EXCEPTION; + } + + // (2) directory.read + struct dirent *dp; + int res; + struct stat st; + union { + struct dirent d; + char b[offsetof (struct dirent, d_name) + NAME_MAX + 1]; + } u; + res = readdir_r(cache, (struct dirent*) &u, &dp); + while ((res == 0) && (dp != NULL)) { + + if ((strcmp((dp->d_name), ".") != 0) && (strcmp((dp->d_name), "..") != 0) && (strpbrk(dp->d_name, "~") == NULL)) { + char storeRoot[512]; + snprintf(storeRoot, sizeof(storeRoot), "%s/%s", STORE_DIR, dp->d_name); + // (2.1) file.readData + if (stat(storeRoot, &st) == 0) { + status = configurationStore_readConfigurationFile(dp->d_name, st.st_size, &properties); + if (status != CELIX_SUCCESS) { + closedir(cache); + return status; + } + } + else + perror("stat"); + // (2.2) new configuration + status = configuration_create2(store->configurationAdminFactory, store, properties, &configuration); + if (status != CELIX_SUCCESS) { + closedir(cache); + return status; + } + + // (2.3) configurations.put + configuration_getPid(configuration->handle, &pid); + hashMap_put(store->configurations, pid, configuration); + } + res = readdir_r(cache, (struct dirent*) &u, &dp); + } + + closedir(cache); + + return CELIX_SUCCESS; +} + +celix_status_t configurationStore_readConfigurationFile(const char *name, int size, properties_pt *dictionary) { + + char fname[256]; // file name + char *buffer; // file buffer + int fd; + celix_status_t status = CELIX_SUCCESS; + + properties_pt properties = NULL; + + // (1) The full path to the file + snprintf(fname, 256, "%s/%s", STORE_DIR, name); + + // (2) pool.new + + // (3) file.open + fd = open((const char*) fname, O_RDONLY); + if (fd < 0) { + printf("[ ERROR ]: ConfigStore - open File{%s} for reading (IO_EXCEPTION) \n", name); + return CELIX_FILE_IO_EXCEPTION; + } + + // (4) buffer.new + buffer = calloc(1, size+1); + if (!buffer) { + close(fd); + return CELIX_ENOMEM; + } + + // (5) file.read + if (read(fd, (void *) buffer, size) != size) { + printf("[ ERROR ]: ConfigStore - reading File{%s} \n", name); + status = CELIX_FILE_IO_EXCEPTION; + } + + status = CELIX_DO_IF(status, configurationStore_parseDataConfigurationFile(buffer, &properties)); + + // (6) file.close & buffer.destroy + free(buffer); + close(fd); + // (7) return + *dictionary = properties; + return status; + +} + +celix_status_t configurationStore_parseDataConfigurationFile(char *data, properties_pt *dictionary) { + + properties_pt properties = properties_create(); + + + char *token; + char *key; + char *value; + char *saveptr; + + bool isKey = true; + token = strtok_r(data, "=", &saveptr); + + while (token != NULL) { + + if (isKey) { + key = strdup(token); + isKey = false; + + } else { // isValue + value = strdup(token); + properties_set(properties, key, value); + isKey = true; + } + + token = strtok_r(NULL, "=\n", &saveptr); + } + + if (hashMap_isEmpty(properties)) { + return CELIX_ILLEGAL_ARGUMENT; + } + + *dictionary = properties; + return CELIX_SUCCESS; +} http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/config_admin/service/private/src/managed_service_impl.c ---------------------------------------------------------------------- diff --git a/bundles/config_admin/service/private/src/managed_service_impl.c b/bundles/config_admin/service/private/src/managed_service_impl.c new file mode 100644 index 0000000..3909979 --- /dev/null +++ b/bundles/config_admin/service/private/src/managed_service_impl.c @@ -0,0 +1,55 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ +/* + * managed_service_impl.c + * + * \date Aug 12, 2013 + * \author <a href="mailto:d...@celix.apache.org">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + + +#include <stdlib.h> +#include <stdio.h> + +/* celix.config_admin.ManagedService */ +#include "managed_service.h" + +/* APR */ + + +/* ------------------------ Constructor -------------------------------------*/ + +celix_status_t managedService_create(bundle_context_pt context, managed_service_service_pt *service){ + + managed_service_service_pt managedServiceService = calloc(1, sizeof(*managedServiceService)); + if(!managedServiceService){ + printf("[ ERROR ]: ManagedService Service not initialized \n"); + return CELIX_ENOMEM; + } + + *service = managedServiceService; + return CELIX_SUCCESS; + +} + +celix_status_t managedService_destroy(managed_service_service_pt service) { + free(service); + return CELIX_SUCCESS; +} http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/config_admin/service/private/src/managed_service_tracker.c ---------------------------------------------------------------------- diff --git a/bundles/config_admin/service/private/src/managed_service_tracker.c b/bundles/config_admin/service/private/src/managed_service_tracker.c new file mode 100644 index 0000000..a42d565 --- /dev/null +++ b/bundles/config_admin/service/private/src/managed_service_tracker.c @@ -0,0 +1,598 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ +/* + * managed_service_tracker.c + * + * \date Aug 12, 2013 + * \author <a href="mailto:d...@celix.apache.org">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +/* celix.config_admin.ManagedServiceTracker */ +#include "managed_service_tracker.h" +#include "service_tracker_customizer.h" + +/* celix.utils */ +#include "hash_map.h" +/* celix.framework */ +#include "constants.h" +#include "properties.h" +#include "utils.h" +#include "service_reference.h" +#include "service_registration.h" +/* celix.framework.Patch*/ +#include "framework_patch.h" +/* celix.config_admin.public */ +#include "managed_service.h" +/* celix.config_admin.private */ +#include "configuration_impl.h" +#include "updated_thread_pool.h" + +struct managed_service_tracker { + + bundle_context_pt context; + + configuration_admin_factory_pt configurationAdminfactory; + configuration_store_pt configurationStore; + updated_thread_pool_pt updatedThreadPool; // according to org.equinox is our "SerializableTaskQueue" + + hash_map_pt managedServices; + hash_map_pt managedServicesReferences; + celix_thread_mutex_t managedServicesReferencesMutex; +}; + +static celix_status_t managedServiceTracker_createHandle(bundle_context_pt context, configuration_admin_factory_pt factory, configuration_store_pt store, managed_service_tracker_pt *tracker); +static celix_status_t managedServiceTracker_createCustomized(bundle_context_pt context, managed_service_tracker_pt trackerHandle, service_tracker_pt *tracker); + +static celix_status_t managedServiceTracker_add(managed_service_tracker_pt tracker, service_reference_pt reference, char * pid, managed_service_service_pt service); +static celix_status_t managedServiceTracker_remove(managed_service_tracker_pt tracker, service_reference_pt reference, char * pid); +static celix_status_t managedServiceTracker_trackManagedService(managed_service_tracker_pt tracker, char *pid, service_reference_pt reference, managed_service_service_pt service); +static celix_status_t managedServiceTracker_untrackManagedService(managed_service_tracker_pt tracker, char *pid, service_reference_pt reference); +static celix_status_t managedServiceTracker_getManagedService(managed_service_tracker_pt tracker, char *pid, managed_service_service_pt *service); +static celix_status_t managedServiceTracker_getManagedServiceReference(managed_service_tracker_pt tracker, char *pid, service_reference_pt *reference); +//static celix_status_t managedServiceTracker_getPidForManagedService(managed_service_service_pt *service, char **pid); +celix_status_t managedServiceTracker_asynchUpdated(managed_service_tracker_pt trackerHandle, managed_service_service_pt service, properties_pt properties); + +static celix_status_t managedServiceTracker_getBundleContext(managed_service_tracker_pt trackerHandle, bundle_context_pt *context); + +static celix_status_t managedServiceTracker_lockManagedServicesReferences(managed_service_tracker_pt handle); +static celix_status_t managedServiceTracker_unlockManagedServicesReferences(managed_service_tracker_pt handle); + +/* ========== CONSTRUCTOR ========== */ + +/* ---------- public ---------- */ + +celix_status_t managedServiceTracker_create(bundle_context_pt context, configuration_admin_factory_pt factory, configuration_store_pt store, managed_service_tracker_pt *trackerHandle, service_tracker_pt *tracker) { + + celix_status_t status; + + managed_service_tracker_pt managedServiceTrackerHandle; + service_tracker_pt managedServiceTrackerCustomized; + + status = managedServiceTracker_createHandle(context, factory, store, &managedServiceTrackerHandle); + if (status != CELIX_SUCCESS) { + *trackerHandle = NULL; + *tracker = NULL; + return status; + } + + status = managedServiceTracker_createCustomized(context, managedServiceTrackerHandle, &managedServiceTrackerCustomized); + if (status != CELIX_SUCCESS) { + *trackerHandle = NULL; + *tracker = NULL; + return status; + } + *trackerHandle = managedServiceTrackerHandle; + *tracker = managedServiceTrackerCustomized; + + printf("[ SUCCESS ]: Tracker - Initialized \n"); + return CELIX_SUCCESS; + +} + +/* ---------- private ---------- */ + +celix_status_t managedServiceTracker_createHandle(bundle_context_pt context, configuration_admin_factory_pt factory, configuration_store_pt store, managed_service_tracker_pt *tracker) { + + celix_status_t status; + + updated_thread_pool_pt updatedThreadPool = NULL; + managed_service_tracker_pt this = calloc(1, sizeof(*this)); + + if (!this) { + printf("[ ERROR ]: TrackerInstance - Not initialized (ENOMEM) \n"); + *tracker = NULL; + return CELIX_ENOMEM; + } + + status = updatedThreadPool_create(context, MAX_THREADS, &updatedThreadPool); + if (status != CELIX_SUCCESS) { + return status; + } + + this->context = context; + + this->configurationAdminfactory = factory; + this->configurationStore = store; + this->updatedThreadPool = updatedThreadPool; + + this->managedServices = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL); + this->managedServicesReferences = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL); + + celix_status_t mutexStatus = celixThreadMutex_create(&this->managedServicesReferencesMutex, NULL); + if (mutexStatus != CELIX_SUCCESS) { + printf("[ ERROR ]: TrackerInstance - Not initialized (MUTEX) \n"); + // TODO destroy threadpool? + return CELIX_ILLEGAL_ARGUMENT; + } + + *tracker = this; + return CELIX_SUCCESS; + +} + +celix_status_t managedServiceTracker_createCustomized(bundle_context_pt context, managed_service_tracker_pt trackerHandle, service_tracker_pt *tracker) { + celix_status_t status; + + service_tracker_customizer_pt customizer = NULL; + service_tracker_pt managedServiceTracker = NULL; + + status = serviceTrackerCustomizer_create(trackerHandle, managedServiceTracker_addingService, managedServiceTracker_addedService, managedServiceTracker_modifiedService, managedServiceTracker_removedService, &customizer); + + if (status != CELIX_SUCCESS) { + printf("[ ERROR ]: TrackerCustomized - Not initialized(ENOMEM) \n"); + *tracker = NULL; + return CELIX_ENOMEM; + } + + serviceTracker_create(context, (char *) MANAGED_SERVICE_SERVICE_NAME, customizer, &managedServiceTracker); + + if (status != CELIX_SUCCESS) { + printf("[ ERROR ]: TrackerCustomized - Not created \n"); + *tracker = NULL; + return status; + } + + *tracker = managedServiceTracker; + return CELIX_SUCCESS; +} + +celix_status_t managedServiceTracker_destroy(bundle_context_pt context, managed_service_tracker_pt mgServTr, service_tracker_pt tracker) { + updatedThreadPool_destroy(mgServTr->updatedThreadPool); + celixThreadMutex_destroy(&mgServTr->managedServicesReferencesMutex); + serviceTracker_destroy(tracker); + + hashMap_destroy(mgServTr->managedServices, true, true); + hashMap_destroy(mgServTr->managedServicesReferences, true, true); + + free(mgServTr); + + return CELIX_SUCCESS; +} + + + +/* ========== IMPLEMENTS CUSTOMIZED TRACKER ========== */ + +/* ---------- public ---------- */ + +celix_status_t managedServiceTracker_addingService(void * handle, service_reference_pt reference, void **service) { + + + celix_status_t status; + + const char* pid = NULL; + + bundle_context_pt context = NULL; + + managed_service_tracker_pt managedServiceTracker_i = handle; //instance + managed_service_service_pt managedService_s = NULL; //service + + // (1) reference.getPid + + status = serviceReference_getProperty(reference, OSGI_FRAMEWORK_SERVICE_PID, &pid); + if (status != CELIX_SUCCESS || pid == NULL) { + *service = NULL; + printf(" [ ERROR ]: Tracker - PID is NULL \n"); + return CELIX_ILLEGAL_ARGUMENT; + } + + // (2) context.getManagedServiceService + + // (2.1) trackerInstance.getBundleContext + + if (managedServiceTracker_getBundleContext(managedServiceTracker_i, &context) != CELIX_SUCCESS) { + *service = NULL; + printf(" [ ERROR ]: Tracker - NULL bundleContext \n"); + return CELIX_ILLEGAL_ARGUMENT; + } + + // (2.2) context.getManagedServiceService + + if (bundleContext_getService(context, reference, (void*) &managedService_s) != CELIX_SUCCESS) { + printf("[ ERROR ]: Tracker - AddingService ( BundleContext - getService{PID=%s} ) \n", pid); + *service = NULL; + return CELIX_ILLEGAL_ARGUMENT; + } + if (managedService_s == NULL) { + printf("[ WARNING ]: Tracker - AddingService (none Service{PID=%s}) \n", pid); + *service = NULL; + return CELIX_ILLEGAL_ARGUMENT; + } + + /* DEBUG CODE * + + service_registration_pt registration = NULL; + serviceReference_getServiceRegistration(reference, ®istration); + char *serviceName = NULL; + serviceRegistration_getServiceName(registration, &serviceName); + + printf("[ DEBUG ]: Tracker - AddingService ( SUCCESS BundleCtxt - getService{Name=%s,PID=%s} ) \n", serviceName, pid); + + * ENF OF DEBUG CODE */ + + // (3) trackerInstance.AddManagedServiceToLocalList + configurationStore_lock(managedServiceTracker_i->configurationStore); + + status = managedServiceTracker_add(managedServiceTracker_i, reference, (char*)pid, managedService_s); + if (status != CELIX_SUCCESS) { + bundleContext_ungetService(context, reference, NULL); + } + configurationStore_unlock(managedServiceTracker_i->configurationStore); + + if (status != CELIX_SUCCESS) { + *service = NULL; + } else { + *service = &managedService_s; + } + + return status; + +} + +celix_status_t managedServiceTracker_addedService(void * handle, service_reference_pt reference, void * service) { + return CELIX_SUCCESS; +} + +celix_status_t managedServiceTracker_modifiedService(void * handle, service_reference_pt reference, void * service) { + return CELIX_SUCCESS; +} + +celix_status_t managedServiceTracker_removedService(void * handle, service_reference_pt reference, void * service) { + celix_status_t status = CELIX_SUCCESS; + const char* pid; + managed_service_tracker_pt managedServiceTracker_i = handle; //instance + bundle_context_pt context; + + + status = serviceReference_getProperty(reference, OSGI_FRAMEWORK_SERVICE_PID, &pid); + if (status != CELIX_SUCCESS || pid == NULL){ + return CELIX_ILLEGAL_ARGUMENT; + } + if ( managedServiceTracker_getBundleContext(managedServiceTracker_i, &context) != CELIX_SUCCESS ){ + return CELIX_ILLEGAL_ARGUMENT; + } + status = managedServiceTracker_remove(managedServiceTracker_i, reference, (char*)pid); + + return status; + +} + +/* ---------- private ---------- */ +// org.eclipse.equinox.internal.cm.ManagedServiceTracker +celix_status_t managedServiceTracker_add(managed_service_tracker_pt tracker, service_reference_pt reference, char *pid, managed_service_service_pt service) { + + celix_status_t status; + + bundle_pt bundle = NULL; + const char* bundleLocation; + + configuration_pt configuration = NULL; + properties_pt properties = NULL; + + configurationStore_findConfiguration(tracker->configurationStore, pid, &configuration); + + if (configuration == NULL) { + + if (managedServiceTracker_trackManagedService(tracker, pid, reference, service) == CELIX_SUCCESS) { + + // TODO : this is new code, it hasn't been tested yet + + if (serviceReference_getBundle(reference, &bundle) != CELIX_SUCCESS) { + return CELIX_ILLEGAL_ARGUMENT; + } + + if (bundle_getBundleLocation(bundle, &bundleLocation) != CELIX_SUCCESS) { + return CELIX_ILLEGAL_ARGUMENT; + } + + // (1) creates a new Configuration for the ManagedService + if (configurationStore_getConfiguration(tracker->configurationStore, pid, (char*)bundleLocation, &configuration) != CELIX_SUCCESS || configuration == NULL) { + return CELIX_ILLEGAL_ARGUMENT; + } + + // (2) bind the Configuration with the ManagedService + bool dummy; + if ((configuration_bind(configuration->handle, bundle, &dummy) != CELIX_SUCCESS)) { + return CELIX_ILLEGAL_ARGUMENT; + } + + // (3) the new Configuration is persisted and visible for other ConfigAdmin instances + if (configurationStore_saveConfiguration(tracker->configurationStore, pid, configuration) != CELIX_SUCCESS) { + return CELIX_ILLEGAL_STATE; + } + + // End of new code + + // TODO: It must be considered in case of fail if untrack the ManagedService + + return managedServiceTracker_asynchUpdated(tracker, service, NULL); + + } else { + return CELIX_ILLEGAL_ARGUMENT; // the service was already tracked + } + + } else { + + configuration_lock(configuration->handle); + + if (managedServiceTracker_trackManagedService(tracker, pid, reference, service) == CELIX_SUCCESS) { + + if (serviceReference_getBundle(reference, &bundle) != CELIX_SUCCESS) { + configuration_unlock(configuration->handle); + printf("[ERROR ]: Tracker - Add (Service{PID=%s} Reference - getBundle NULL)", pid); + return CELIX_ILLEGAL_ARGUMENT; + } + + // TODO configuration.isDeleted ? - with only using one calling bundle OK + + bool isBind; + if ((configuration_bind(configuration->handle, bundle, &isBind) == CELIX_SUCCESS) && (isBind == true)) { // config.bind(bundle) + + if (configuration_getProperties(configuration->handle, &properties) != CELIX_SUCCESS) { + configuration_unlock(configuration->handle); + return CELIX_ILLEGAL_ARGUMENT; + } + + if (configurationAdminFactory_modifyConfiguration(tracker->configurationAdminfactory, reference, properties) != CELIX_SUCCESS) { + configuration_unlock(configuration->handle); + return CELIX_ILLEGAL_ARGUMENT; + } + + status = managedServiceTracker_asynchUpdated(tracker, service, properties); + + configuration_unlock(configuration->handle); + + return status; + + } else { + configuration_unlock(configuration->handle); + return CELIX_ILLEGAL_STATE; + } + + } else { + configuration_unlock(configuration->handle); + return CELIX_ILLEGAL_ARGUMENT; // the service was already tracked + } + } +} + +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); +} + +celix_status_t managedServiceTracker_trackManagedService(managed_service_tracker_pt tracker, char *pid, service_reference_pt reference, managed_service_service_pt service) { + + managedServiceTracker_lockManagedServicesReferences(tracker); + + if (hashMap_containsKey(tracker->managedServicesReferences, pid)) { + printf("[ WARNING ]: Tracker - Track ( Service{PID=%s} already registered ) ", pid); + managedServiceTracker_unlockManagedServicesReferences(tracker); + return CELIX_ILLEGAL_ARGUMENT; + } + + hashMap_put(tracker->managedServicesReferences, pid, reference); + hashMap_put(tracker->managedServices, pid, service); + + managedServiceTracker_unlockManagedServicesReferences(tracker); + + return CELIX_SUCCESS; +} + +celix_status_t managedServiceTracker_untrackManagedService(managed_service_tracker_pt tracker, char *pid, service_reference_pt reference){ + managedServiceTracker_lockManagedServicesReferences(tracker); + + if ( hashMap_containsKey(tracker->managedServicesReferences, pid) ){ + hashMap_remove(tracker->managedServicesReferences, pid); + hashMap_remove(tracker->managedServices, pid); + } + managedServiceTracker_unlockManagedServicesReferences(tracker); + return CELIX_SUCCESS; + +} + +celix_status_t managedServiceTracker_getManagedService(managed_service_tracker_pt tracker, char *pid, managed_service_service_pt *service) { + + celix_status_t status; + managed_service_service_pt serv = NULL; + + managedServiceTracker_lockManagedServicesReferences(tracker); + + serv = hashMap_get(tracker->managedServices, pid); + if (serv == NULL) { + status = CELIX_ILLEGAL_ARGUMENT; + } else { + status = CELIX_SUCCESS; + } + + managedServiceTracker_unlockManagedServicesReferences(tracker); + + *service = serv; + return status; +} + +celix_status_t managedServiceTracker_getManagedServiceReference(managed_service_tracker_pt tracker, char *pid, service_reference_pt *reference) { + + celix_status_t status; + service_reference_pt ref = NULL; + + managedServiceTracker_lockManagedServicesReferences(tracker); + + ref = hashMap_get(tracker->managedServicesReferences, pid); + if (ref == NULL) { + status = CELIX_ILLEGAL_ARGUMENT; + } else { + status = CELIX_SUCCESS; + } + + managedServiceTracker_unlockManagedServicesReferences(tracker); + + *reference = ref; + return status; +} + +/* TODO + celix_status_t managedServiceTracker_getPidForManagedService(managed_service_service_pt *service, char **pid){ + return CELIX_SUCCESS; + } + */ + +celix_status_t managedServiceTracker_asynchUpdated(managed_service_tracker_pt trackerHandle, managed_service_service_pt service, properties_pt properties) { + + return updatedThreadPool_push(trackerHandle->updatedThreadPool, service, properties); + +} + +/* ========== IMPLEMENTENTATION ========== */ + +/* ---------- public ---------- */ + +celix_status_t managedServiceTracker_notifyDeleted(managed_service_tracker_pt tracker, configuration_pt configuration) { + return CELIX_SUCCESS; +} + +celix_status_t managedServiceTracker_notifyUpdated(managed_service_tracker_pt tracker, configuration_pt configuration) { + + + char *pid; + + service_reference_pt reference = NULL; + bundle_pt bundle = NULL; + properties_pt properties = NULL; + + managed_service_service_pt service = NULL; + + // (1) config.checkLocked + if (configuration_checkLocked(configuration->handle) != CELIX_SUCCESS) { //TODO not yet implemented + return CELIX_ILLEGAL_ARGUMENT; + } + + // (2) config.getPid + if (configuration_getPid(configuration->handle, &pid) != CELIX_SUCCESS) { + return CELIX_ILLEGAL_ARGUMENT; + } + + // (3) reference = getManagedServiceReference(pid) + if (managedServiceTracker_getManagedServiceReference(tracker, pid, &reference) != CELIX_SUCCESS || reference == NULL) { + printf("[ ERROR ]: Tracker - Notify (NULL Reference Service{PID=%s}) \n", pid); + return CELIX_ILLEGAL_ARGUMENT; // Eclipse ignores, but according to Specs, callback is delayed + } + + // (4.1) reference.getBundle + if (serviceReference_getBundle(reference, &bundle) != CELIX_SUCCESS || bundle == NULL) { + printf("[ ERROR ]: Tracker - Notify (NULL Bundle Service{PID=%s}) \n", pid); + return CELIX_ILLEGAL_ARGUMENT; + } + + // (4.2) config.bind(reference.getBundle) + bool isBind; + if (configuration_bind(configuration->handle, bundle, &isBind) != CELIX_SUCCESS || isBind == false) { + printf("[ ERROR ]: Tracker - Notify (Service{PID=%s} Permission Error) \n", pid); + return CELIX_ILLEGAL_STATE; + } + + // (5) if (reference != null && config.bind(reference.getBundle())) + + // (5.1) properties = config.getProperties + if (configuration_getProperties(configuration->handle, &properties) != CELIX_SUCCESS) { + printf("[ ERROR ]: Tracker - Notify (Service{PID=%s} Wrong Properties) \n", pid); + return CELIX_ILLEGAL_ARGUMENT; + } + + // (5.2) modifyConfiguration + if (configurationAdminFactory_modifyConfiguration(tracker->configurationAdminfactory, reference, properties) != CELIX_SUCCESS) { + return CELIX_ILLEGAL_ARGUMENT; //TODO no yet implemented modifyConfiguration + } + + // (5.3) service = getManagedService(pid) + if (managedServiceTracker_getManagedService(tracker, pid, &service) != CELIX_SUCCESS) { + printf("[ ERROR ]: Tracker - Notify (NULL Service{PID=%s}) \n", pid); + return CELIX_ILLEGAL_ARGUMENT; + } + + // (5.4) asynchUpdate(service,properties) + if ((properties == NULL) || (properties != NULL && hashMap_size(properties) == 0)) { + return managedServiceTracker_asynchUpdated(tracker, service, NULL); + } else { + return managedServiceTracker_asynchUpdated(tracker, service, properties); + } + return CELIX_ILLEGAL_ARGUMENT; +} + +/* ---------- private ---------- */ + +celix_status_t managedServiceTracker_getBundleContext(managed_service_tracker_pt trackerHandle, bundle_context_pt *context) { + + if (trackerHandle->context != NULL) { + *context = trackerHandle->context; + } else { + printf("[ ERROR ]: Tracker - getBundleContext (NULL context) \n"); + *context = NULL; + return CELIX_ILLEGAL_ARGUMENT; + } + return CELIX_SUCCESS; +} + +celix_status_t managedServiceTracker_lockManagedServicesReferences(managed_service_tracker_pt handle) { + + celixThreadMutex_lock(&handle->managedServicesReferencesMutex); + return CELIX_SUCCESS; + +} + +celix_status_t managedServiceTracker_unlockManagedServicesReferences(managed_service_tracker_pt handle) { + + celixThreadMutex_unlock(&handle->managedServicesReferencesMutex); + return CELIX_SUCCESS; + +} http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/config_admin/service/private/src/updated_thread_pool.c ---------------------------------------------------------------------- diff --git a/bundles/config_admin/service/private/src/updated_thread_pool.c b/bundles/config_admin/service/private/src/updated_thread_pool.c new file mode 100644 index 0000000..86220db --- /dev/null +++ b/bundles/config_admin/service/private/src/updated_thread_pool.c @@ -0,0 +1,146 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ +/* + * updated_thread_pool.c + * + * \date Aug 12, 2013 + * \author <a href="mailto:d...@celix.apache.org">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + + +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +/* celix.config_admin.UpdatedThreadPool */ +#include "thpool.h" +#include "updated_thread_pool.h" + + + +struct updated_thread_pool{ + + bundle_context_pt context; + + int maxTreads; + + // apr_thread_mutex_t *mutex; + threadpool threadPool; //protected by mutex + +}; + +typedef struct data_callback *data_callback_t; + +struct data_callback{ + + managed_service_service_pt managedServiceService; + properties_pt properties; + +}; + + +static void *updateThreadPool_updatedCallback(void *data); +static celix_status_t updatedThreadPool_wrapDataCallback(managed_service_service_pt service, properties_pt properties, data_callback_t *data); + + +/* ========== CONSTRUCTOR ========== */ + +/* ---------- public ---------- */ + +celix_status_t updatedThreadPool_create(bundle_context_pt context, int maxThreads, updated_thread_pool_pt *updatedThreadPool){ + + *updatedThreadPool = calloc(1, sizeof(**updatedThreadPool)); + if (!*updatedThreadPool){ + printf("[ ERROR ]: UpdatedThreadPool - Not initialized (ENOMEM) \n"); + return CELIX_ENOMEM; + } + + (*updatedThreadPool)->threadPool=thpool_init(maxThreads); +// if ( apr_thread_pool_create(&(*updatedThreadPool)->threadPool, INIT_THREADS, maxTreads, pool) != APR_SUCCESS ){ + if ((*updatedThreadPool)->threadPool == NULL) { + printf("[ ERROR ]: UpdatedThreadPool - Instance not created \n"); + return CELIX_ENOMEM; + } + + (*updatedThreadPool)->context = context; + + printf("[ SUCCESS ]: UpdatedThreadPool - initialized \n"); + return CELIX_SUCCESS; + +} + +celix_status_t updatedThreadPool_destroy(updated_thread_pool_pt pool) { + thpool_destroy(pool->threadPool); + free(pool); + return CELIX_SUCCESS; +} +/* ========== IMPLEMENTATION ========== */ + +/* ---------- public ---------- */ + +celix_status_t updatedThreadPool_push(updated_thread_pool_pt updatedThreadPool, managed_service_service_pt service, properties_pt properties){ + + data_callback_t data = NULL; + + if ( updatedThreadPool_wrapDataCallback(service, properties, &data) != CELIX_SUCCESS ){ + return CELIX_ILLEGAL_ARGUMENT; + } + + if (thpool_add_work(updatedThreadPool->threadPool, updateThreadPool_updatedCallback, data) != 0) { + printf("[ ERROR ]: UpdatedThreadPool - add_work \n "); + return CELIX_ILLEGAL_STATE; + } + + return CELIX_SUCCESS; +} + +/* ---------- private ---------- */ + +void *updateThreadPool_updatedCallback(void *data) { + + data_callback_t params = data; + + managed_service_service_pt managedServiceService = params->managedServiceService; + properties_pt properties = params->properties; + + (*managedServiceService->updated)(managedServiceService->managedService, properties); + + free(data); + + return NULL; + +} + +celix_status_t updatedThreadPool_wrapDataCallback(managed_service_service_pt service, properties_pt properties, data_callback_t *data){ + + *data = calloc(1, sizeof(**data)); + + if (!*data){ + printf("[ ERROR ]: UpdatedThreadPool - WrapDataCallback (Data not initialized) \n"); + return CELIX_ENOMEM; + } + + (*data)->managedServiceService = service; + (*data)->properties = properties; + + return CELIX_SUCCESS; +} + http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/config_admin/service/public/include/configuration.h ---------------------------------------------------------------------- diff --git a/bundles/config_admin/service/public/include/configuration.h b/bundles/config_admin/service/public/include/configuration.h new file mode 100644 index 0000000..74bf5b1 --- /dev/null +++ b/bundles/config_admin/service/public/include/configuration.h @@ -0,0 +1,80 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ +/* + * configuration.h + * + * \date Aug 12, 2013 + * \author <a href="mailto:d...@celix.apache.org">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + + +#ifndef CONFIGURATION_H_ +#define CONFIGURATION_H_ + + +#include <stdbool.h> +/* celix.framework */ +#include "celix_errno.h" +#include "properties.h" + + +// Note: the term interface is used because configuration is not a service, it is not +// registered in the service registry but it is owned by the config_admin +struct configuration +{ + void *handle; // pointer to configuration datastore + /* METHODS */ + celix_status_t (*configuration_delete)(void *handle); + + celix_status_t (*configuration_equals)(void *thisConfiguration, void *otherConfiguration, bool *equals); + + celix_status_t (*configuration_getBundleLocation)(void *handle, char **bundleLocation); + celix_status_t (*configuration_getFactoryPid)(void *handle, char **factoryPid); + celix_status_t (*configuration_getPid)(void *handle, char **pid); + celix_status_t (*configuration_getProperties)(void *handle, properties_pt *properties); + + celix_status_t (*configuration_hashCode)(void *handle, int *hashCode); + + celix_status_t (*configuration_setBundleLocation)(void *handle, char *bundleLocation); + + celix_status_t (*configuration_update)(void *handle, properties_pt properties); + +}; + +typedef struct configuration *configuration_pt; + +/* METHODS +celix_status_t configuration_delete(configuration_pt configuration); + +celix_status_t configuration_equals(configuration_pt thisConfiguration, configuration_pt otherConfiguration, bool *equals); + +celix_status_t configuration_getBundleLocation(configuration_pt configuration, char **bundleLocation); +celix_status_t configuration_getFactoryPid(configuration_pt configuration, char **factoryPid); +celix_status_t configuration_getPid(configuration_pt configuration, char **pid); +celix_status_t configuration_getProperties(configuration_pt configuration, properties_pt *properties); + +celix_status_t configuration_hashCode(configuration_pt configuration, int *hashCode); + +celix_status_t configuration_setBundleLocation(configuration_pt configuration, char *bundleLocation); + +celix_status_t configuration_update(configuration_pt configuration, properties_pt properties); +*/ + +#endif /* CONFIGURATION_H_ */