You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by ab...@apache.org on 2011/11/07 19:06:26 UTC

svn commit: r1198847 [1/2] - in /incubator/celix/trunk: cmake/ framework/ framework/private/include/ framework/private/src/ framework/public/include/ launcher/ log_writer/ remote_services/ remote_services/calc_shell/MANIFEST/ remote_services/discovery/...

Author: abroekhuis
Date: Mon Nov  7 18:06:25 2011
New Revision: 1198847

URL: http://svn.apache.org/viewvc?rev=1198847&view=rev
Log:
Remote Services

Updated remote services implementation

Added:
    incubator/celix/trunk/framework/private/include/listener_hook_info_impl.h
    incubator/celix/trunk/framework/public/include/listener_hook_service.h
Modified:
    incubator/celix/trunk/cmake/Includes.cmake
    incubator/celix/trunk/framework/CMakeLists.txt
    incubator/celix/trunk/framework/private/include/bundle.h
    incubator/celix/trunk/framework/private/include/bundle_context.h
    incubator/celix/trunk/framework/private/include/filter.h
    incubator/celix/trunk/framework/private/include/framework.h
    incubator/celix/trunk/framework/private/include/headers.h
    incubator/celix/trunk/framework/private/include/module.h
    incubator/celix/trunk/framework/private/include/service_registry.h
    incubator/celix/trunk/framework/private/src/bundle.c
    incubator/celix/trunk/framework/private/src/bundle_archive.c
    incubator/celix/trunk/framework/private/src/bundle_context.c
    incubator/celix/trunk/framework/private/src/filter.c
    incubator/celix/trunk/framework/private/src/framework.c
    incubator/celix/trunk/framework/private/src/module.c
    incubator/celix/trunk/framework/private/src/resolver.c
    incubator/celix/trunk/framework/private/src/service_registry.c
    incubator/celix/trunk/launcher/launcher.c
    incubator/celix/trunk/log_writer/log_writer.c
    incubator/celix/trunk/remote_services/CMakeLists.txt
    incubator/celix/trunk/remote_services/calc_shell/MANIFEST/MANIFEST.MF
    incubator/celix/trunk/remote_services/discovery/private/include/discovery.h
    incubator/celix/trunk/remote_services/discovery/private/src/discovery.c
    incubator/celix/trunk/remote_services/discovery/private/src/discovery_activator.c
    incubator/celix/trunk/remote_services/example_proxy/private/src/example_proxy_impl.c
    incubator/celix/trunk/remote_services/remote_service_admin/private/include/export_registration_impl.h
    incubator/celix/trunk/remote_services/remote_service_admin/private/include/import_registration_impl.h
    incubator/celix/trunk/remote_services/remote_service_admin/private/include/remote_service_admin_impl.h
    incubator/celix/trunk/remote_services/remote_service_admin/private/src/export_registration_impl.c
    incubator/celix/trunk/remote_services/remote_service_admin/private/src/import_registration_impl.c
    incubator/celix/trunk/remote_services/remote_service_admin/private/src/remote_service_admin_impl.c
    incubator/celix/trunk/remote_services/remote_service_admin/public/include/remote_constants.h
    incubator/celix/trunk/remote_services/remote_service_admin/public/include/remote_service_admin.h
    incubator/celix/trunk/remote_services/topology_manager/private/include/topology_manager.h
    incubator/celix/trunk/remote_services/topology_manager/private/src/activator.c
    incubator/celix/trunk/remote_services/topology_manager/private/src/topology_manager.c
    incubator/celix/trunk/shell/inspect_command.c
    incubator/celix/trunk/shell/ps_command.c

Modified: incubator/celix/trunk/cmake/Includes.cmake
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/cmake/Includes.cmake?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/cmake/Includes.cmake (original)
+++ incubator/celix/trunk/cmake/Includes.cmake Mon Nov  7 18:06:25 2011
@@ -23,6 +23,7 @@ ELSE(APR_FOUND)
 ENDIF(APR_FOUND)
 
 include_directories(${APR_INCLUDE_DIR})
+include_directories(${APRUTIL_INCLUDE_DIR})
 include_directories("framework/private/include")
 include_directories("framework/public/include")
 

Modified: incubator/celix/trunk/framework/CMakeLists.txt
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/CMakeLists.txt?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/framework/CMakeLists.txt (original)
+++ incubator/celix/trunk/framework/CMakeLists.txt Mon Nov  7 18:06:25 2011
@@ -40,7 +40,7 @@ include_directories("private/include")
 include_directories("public/include")
 include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
 add_library(framework SHARED ${SRC})
-target_link_libraries(framework utils ${ZLIB_LIBRARY} ${APR_LIBRARY} ${CURL_LIBRARY})
+target_link_libraries(framework utils ${ZLIB_LIBRARY} ${APR_LIBRARY} ${APRUTIL_LIBRARY} ${CURL_LIBRARY})
 
 install(TARGETS framework DESTINATION lib COMPONENT framework)
 FILE(GLOB files "private/include/*.h")

Modified: incubator/celix/trunk/framework/private/include/bundle.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/include/bundle.h?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/include/bundle.h (original)
+++ incubator/celix/trunk/framework/private/include/bundle.h Mon Nov  7 18:06:25 2011
@@ -37,7 +37,7 @@ celix_status_t bundle_destroy(BUNDLE bun
 
 celix_status_t bundle_isSystemBundle(BUNDLE bundle, bool *systemBundle);
 BUNDLE_ARCHIVE bundle_getArchive(BUNDLE bundle);
-MODULE bundle_getCurrentModule(BUNDLE bundle);
+celix_status_t bundle_getCurrentModule(BUNDLE bundle, MODULE *module);
 ARRAY_LIST bundle_getModules(BUNDLE bundle);
 void * bundle_getHandle(BUNDLE bundle);
 void bundle_setHandle(BUNDLE bundle, void * handle);

Modified: incubator/celix/trunk/framework/private/include/bundle_context.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/include/bundle_context.h?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/include/bundle_context.h (original)
+++ incubator/celix/trunk/framework/private/include/bundle_context.h Mon Nov  7 18:06:25 2011
@@ -55,5 +55,6 @@ celix_status_t bundleContext_getBundleBy
 celix_status_t bundleContext_addServiceListener(BUNDLE_CONTEXT context, SERVICE_LISTENER listener, char * filter);
 celix_status_t bundleContext_removeServiceListener(BUNDLE_CONTEXT context, SERVICE_LISTENER listener);
 
+celix_status_t bundleContext_getProperty(BUNDLE_CONTEXT context, const char *name, char **value);
 
 #endif /* BUNDLE_CONTEXT_H_ */

Modified: incubator/celix/trunk/framework/private/include/filter.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/include/filter.h?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/include/filter.h (original)
+++ incubator/celix/trunk/framework/private/include/filter.h Mon Nov  7 18:06:25 2011
@@ -33,4 +33,6 @@ void filter_destroy(FILTER filter);
 
 int filter_match(FILTER filter, PROPERTIES properties);
 
+celix_status_t filter_getString(FILTER filter, char **filterStr);
+
 #endif /* FILTER_H_ */

Modified: incubator/celix/trunk/framework/private/include/framework.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/include/framework.h?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/include/framework.h (original)
+++ incubator/celix/trunk/framework/private/include/framework.h Mon Nov  7 18:06:25 2011
@@ -34,13 +34,15 @@
 #include "celix_errno.h"
 #include "service_factory.h"
 
-celix_status_t framework_create(FRAMEWORK *framework, apr_pool_t *memoryPool);
+celix_status_t framework_create(FRAMEWORK *framework, apr_pool_t *memoryPool, PROPERTIES config);
 celix_status_t framework_destroy(FRAMEWORK framework);
 
 celix_status_t fw_init(FRAMEWORK framework);
 celix_status_t framework_start(FRAMEWORK framework);
 void framework_stop(FRAMEWORK framework);
 
+celix_status_t fw_getProperty(FRAMEWORK framework, const char *name, char **value);
+
 celix_status_t fw_installBundle(FRAMEWORK framework, BUNDLE * bundle, char * location);
 celix_status_t fw_uninstallBundle(FRAMEWORK framework, BUNDLE bundle);
 

Modified: incubator/celix/trunk/framework/private/include/headers.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/include/headers.h?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/include/headers.h (original)
+++ incubator/celix/trunk/framework/private/include/headers.h Mon Nov  7 18:06:25 2011
@@ -81,6 +81,8 @@ struct framework {
 	bool shutdown;
 
 	apr_pool_t *mp;
+
+	PROPERTIES configurationMap;
 };
 
 typedef struct framework * FRAMEWORK;
@@ -139,17 +141,6 @@ struct serviceEvent {
 
 typedef struct serviceEvent * SERVICE_EVENT;
 
-struct serviceRegistry {
-    FRAMEWORK framework;
-	HASH_MAP serviceRegistrations;
-	HASH_MAP inUseMap;
-	void (*serviceChanged)(FRAMEWORK, SERVICE_EVENT, PROPERTIES);
-	long currentServiceId;
-
-
-	pthread_mutex_t mutex;
-};
-
 typedef struct serviceRegistry * SERVICE_REGISTRY;
 
 struct serviceRegistration {

Added: incubator/celix/trunk/framework/private/include/listener_hook_info_impl.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/include/listener_hook_info_impl.h?rev=1198847&view=auto
==============================================================================
--- incubator/celix/trunk/framework/private/include/listener_hook_info_impl.h (added)
+++ incubator/celix/trunk/framework/private/include/listener_hook_info_impl.h Mon Nov  7 18:06:25 2011
@@ -0,0 +1,13 @@
+/*
+ * listener_hook_info_impl.h
+ *
+ *  Created on: Oct 28, 2011
+ *      Author: alexander
+ */
+
+#ifndef LISTENER_HOOK_INFO_IMPL_H_
+#define LISTENER_HOOK_INFO_IMPL_H_
+
+celix_status_t listenerHookInfo_create(apr_pool_t *pool);
+
+#endif /* LISTENER_HOOK_INFO_IMPL_H_ */

Modified: incubator/celix/trunk/framework/private/include/module.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/include/module.h?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/include/module.h (original)
+++ incubator/celix/trunk/framework/private/include/module.h Mon Nov  7 18:06:25 2011
@@ -41,7 +41,7 @@ int module_equals(void * module, void * 
 WIRE module_getWire(MODULE module, char * serviceName);
 
 VERSION module_getVersion(MODULE module);
-char * module_getSymbolicName(MODULE module);
+celix_status_t module_getSymbolicName(MODULE module, char **symbolicName);
 char * module_getId(MODULE module);
 LINKED_LIST module_getWires(MODULE module);
 void module_setWires(MODULE module, LINKED_LIST wires);

Modified: incubator/celix/trunk/framework/private/include/service_registry.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/include/service_registry.h?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/include/service_registry.h (original)
+++ incubator/celix/trunk/framework/private/include/service_registry.h Mon Nov  7 18:06:25 2011
@@ -47,4 +47,6 @@ void serviceRegistry_ungetServices(SERVI
 ARRAY_LIST serviceRegistry_getUsingBundles(SERVICE_REGISTRY registry, SERVICE_REFERENCE reference);
 SERVICE_REGISTRATION serviceRegistry_findRegistration(SERVICE_REGISTRY registry, SERVICE_REFERENCE reference);
 
+celix_status_t serviceRegistry_getListenerHooks(SERVICE_REGISTRY registry, ARRAY_LIST *hooks);
+
 #endif /* SERVICE_REGISTRY_H_ */

Modified: incubator/celix/trunk/framework/private/src/bundle.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/src/bundle.c?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/src/bundle.c (original)
+++ incubator/celix/trunk/framework/private/src/bundle.c Mon Nov  7 18:06:25 2011
@@ -130,8 +130,16 @@ BUNDLE_ARCHIVE bundle_getArchive(BUNDLE 
 	return bundle->archive;
 }
 
-MODULE bundle_getCurrentModule(BUNDLE bundle) {
-	return arrayList_get(bundle->modules, arrayList_size(bundle->modules) - 1);
+celix_status_t bundle_getCurrentModule(BUNDLE bundle, MODULE *module) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (bundle == NULL || *module != NULL) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	} else {
+		*module = arrayList_get(bundle->modules, arrayList_size(bundle->modules) - 1);
+	}
+
+	return status;
 }
 
 ARRAY_LIST bundle_getModules(BUNDLE bundle) {
@@ -205,28 +213,34 @@ celix_status_t bundle_createModule(BUNDL
 
 			if (*module != NULL) {
 				VERSION bundleVersion = module_getVersion(*module);
-				char * symName = module_getSymbolicName(*module);
-
-				ARRAY_LIST bundles = framework_getBundles(bundle->framework);
-				int i;
-				for (i = 0; i < arrayList_size(bundles); i++) {
-					BUNDLE check = (BUNDLE) arrayList_get(bundles, i);
-
-					long id;
-					if (bundleArchive_getId(check->archive, &id) == CELIX_SUCCESS) {
-						if (id != bundleId) {
-							char * sym = module_getSymbolicName(bundle_getCurrentModule(check));
-							VERSION version = module_getVersion(bundle_getCurrentModule(check));
-							if ((symName != NULL) && (sym != NULL) && !strcmp(symName, sym) &&
-									!version_compareTo(bundleVersion, version)) {
-								printf("Bundle symbolic name and version are not unique: %s:%s\n", sym, version_toString(version));
-								status = CELIX_BUNDLE_EXCEPTION;
-								break;
+				char * symName = NULL;
+				status = module_getSymbolicName(*module, &symName);
+				if (status == CELIX_SUCCESS) {
+					ARRAY_LIST bundles = framework_getBundles(bundle->framework);
+					int i;
+					for (i = 0; i < arrayList_size(bundles); i++) {
+						BUNDLE check = (BUNDLE) arrayList_get(bundles, i);
+
+						long id;
+						if (bundleArchive_getId(check->archive, &id) == CELIX_SUCCESS) {
+							if (id != bundleId) {
+								MODULE mod = NULL;
+								char * sym = NULL;
+								status = bundle_getCurrentModule(check, &mod);
+								status = module_getSymbolicName(mod, &sym);
+
+								VERSION version = module_getVersion(mod);
+								if ((symName != NULL) && (sym != NULL) && !strcmp(symName, sym) &&
+										!version_compareTo(bundleVersion, version)) {
+									printf("Bundle symbolic name and version are not unique: %s:%s\n", sym, version_toString(version));
+									status = CELIX_BUNDLE_EXCEPTION;
+									break;
+								}
 							}
 						}
 					}
+					arrayList_destroy(bundles);
 				}
-				arrayList_destroy(bundles);
 			}
         }
 	}

Modified: incubator/celix/trunk/framework/private/src/bundle_archive.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/src/bundle_archive.c?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/src/bundle_archive.c (original)
+++ incubator/celix/trunk/framework/private/src/bundle_archive.c Mon Nov  7 18:06:25 2011
@@ -685,11 +685,17 @@ celix_status_t bundleArchive_deleteTree(
 				}
 			}
 		}
+		if (apr_status != APR_SUCCESS && apr_status != APR_ENOENT) {
+			status = CELIX_FILE_IO_EXCEPTION;
+		}
+		apr_status = apr_dir_close(dir);
 		if (apr_status != APR_SUCCESS) {
 			status = CELIX_FILE_IO_EXCEPTION;
 		}
 		if (status == CELIX_SUCCESS) {
-			apr_file_remove(directory, mp);
+			if (apr_dir_remove(directory, mp) != APR_SUCCESS) {
+				status = CELIX_FILE_IO_EXCEPTION;
+			}
 		}
 	}
 

Modified: incubator/celix/trunk/framework/private/src/bundle_context.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/src/bundle_context.c?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/src/bundle_context.c (original)
+++ incubator/celix/trunk/framework/private/src/bundle_context.c Mon Nov  7 18:06:25 2011
@@ -269,3 +269,15 @@ celix_status_t bundleContext_removeServi
 
     return status;
 }
+
+celix_status_t bundleContext_getProperty(BUNDLE_CONTEXT context, const char *name, char **value) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (context == NULL || name == NULL || *value != NULL) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	} else {
+		fw_getProperty(context->framework, name, value);
+	}
+
+	return status;
+}

Modified: incubator/celix/trunk/framework/private/src/filter.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/src/filter.c?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/src/filter.c (original)
+++ incubator/celix/trunk/framework/private/src/filter.c Mon Nov  7 18:06:25 2011
@@ -48,6 +48,7 @@ struct filter {
 	char * attribute;
 	int operands;
 	void * value;
+	char *filterStr;
 };
 
 void filter_skipWhiteSpace(char * filterString, int * pos);
@@ -79,6 +80,7 @@ FILTER filter_create(char * filterString
 		printf("Error: Extraneous trailing characters\n");
 		return NULL;
 	}
+	filter->filterStr = filterString;
 	return filter;
 }
 
@@ -529,3 +531,9 @@ int filter_compareString(OPERAND operand
 	return 0;
 }
 
+celix_status_t filter_getString(FILTER filter, char **filterStr) {
+	if (filter != NULL) {
+		*filterStr = filter->filterStr;
+	}
+	return CELIX_SUCCESS;
+}

Modified: incubator/celix/trunk/framework/private/src/framework.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/src/framework.c?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/src/framework.c (original)
+++ incubator/celix/trunk/framework/private/src/framework.c Mon Nov  7 18:06:25 2011
@@ -52,6 +52,7 @@
 #include "bundle_context.h"
 #include "linked_list_iterator.h"
 #include "service_reference.h"
+#include "listener_hook_service.h"
 
 struct activator {
 	void * userData;
@@ -100,7 +101,7 @@ struct fw_serviceListener {
 typedef struct fw_serviceListener * FW_SERVICE_LISTENER;
 
 
-celix_status_t framework_create(FRAMEWORK *framework, apr_pool_t *memoryPool) {
+celix_status_t framework_create(FRAMEWORK *framework, apr_pool_t *memoryPool, PROPERTIES config) {
     celix_status_t status = CELIX_SUCCESS;
 
 	*framework = (FRAMEWORK) apr_palloc(memoryPool, sizeof(**framework));
@@ -155,6 +156,7 @@ celix_status_t framework_create(FRAMEWOR
                                     (*framework)->installRequestMap = hashMap_create(string_hash, string_hash, string_equals, string_equals);
                                     (*framework)->serviceListeners = NULL;
                                     (*framework)->shutdownGate = NULL;
+                                    (*framework)->configurationMap = config;
                                 }
                             }
                         }
@@ -177,7 +179,9 @@ celix_status_t framework_destroy(FRAMEWO
 		char * location = hashMapEntry_getKey(entry);
 
 		// for each installed bundle, clean up memory
-		LINKED_LIST wires = module_getWires(bundle_getCurrentModule(bundle));
+		MODULE mod = NULL;
+		bundle_getCurrentModule(bundle, &mod);
+		LINKED_LIST wires = module_getWires(mod);
 		if (wires != NULL) {
 			LINKED_LIST_ITERATOR iter = linkedListIterator_create(wires, 0);
 			while (linkedListIterator_hasNext(iter)) {
@@ -237,7 +241,13 @@ celix_status_t fw_init(FRAMEWORK framewo
 	status = bundleArchive_getLocation(bundle_getArchive(framework->bundle), &location);
 	hashMap_put(framework->installedBundleMap, location, framework->bundle);
 
-	HASH_MAP wires = resolver_resolve(bundle_getCurrentModule(framework->bundle));
+	MODULE module = NULL;
+
+	status = bundle_getCurrentModule(framework->bundle, &module);
+	if (status != CELIX_SUCCESS) {
+		return status;
+	}
+	HASH_MAP wires = resolver_resolve(module);
 	if (wires == NULL) {
 		printf("Unresolved constraints in System Bundle\n");
 		framework_releaseBundleLock(framework, framework->bundle);
@@ -362,6 +372,23 @@ void framework_stop(FRAMEWORK framework)
 	fw_stopBundle(framework, framework->bundle, true);
 }
 
+celix_status_t fw_getProperty(FRAMEWORK framework, const char *name, char **value) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (framework == NULL || name == NULL || *value != NULL) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	} else {
+		if (framework->configurationMap != NULL) {
+			*value = properties_get(framework->configurationMap, (char *) name);
+		}
+		if (*value == NULL) {
+			*value = getenv(name);
+		}
+	}
+
+	return status;
+}
+
 celix_status_t fw_installBundle(FRAMEWORK framework, BUNDLE * bundle, char * location) {
 	return fw_installBundle2(framework, bundle, -1, location, NULL);
 }
@@ -472,6 +499,7 @@ celix_status_t fw_startBundle(FRAMEWORK 
 
 	bundle_getState(bundle, &state);
 
+	MODULE module = NULL;
 	switch (state) {
 		case BUNDLE_UNINSTALLED:
 			printf("Cannot start bundle since it is uninstalled.");
@@ -490,8 +518,9 @@ celix_status_t fw_startBundle(FRAMEWORK 
 			framework_releaseBundleLock(framework, bundle);
 			return CELIX_SUCCESS;
 		case BUNDLE_INSTALLED:
-			if (!module_isResolved(bundle_getCurrentModule(bundle))) {
-                wires = resolver_resolve(bundle_getCurrentModule(bundle));
+			bundle_getCurrentModule(bundle, &module);
+			if (!module_isResolved(module)) {
+                wires = resolver_resolve(module);
                 if (wires == NULL) {
                     framework_releaseBundleLock(framework, bundle);
                     return CELIX_BUNDLE_EXCEPTION;
@@ -691,7 +720,9 @@ celix_status_t fw_stopBundle(FRAMEWORK f
 			activator->destroy(activator->userData, context);
 		}
 
-		if (strcmp(module_getId(bundle_getCurrentModule(bundle)), "0") != 0) {
+		MODULE module = NULL;
+		bundle_getCurrentModule(bundle, &module);
+		if (strcmp(module_getId(module), "0") != 0) {
 			activator->start = NULL;
 			activator->stop = NULL;
 			activator->userData = NULL;
@@ -963,6 +994,30 @@ celix_status_t fw_registerService(FRAMEW
 	*registration = serviceRegistry_registerService(framework->registry, bundle, serviceName, svcObj, properties);
 	framework_releaseBundleLock(framework, bundle);
 
+	// If this is a listener hook, invoke the callback with all current listeners
+	if (strcmp(serviceName, listener_hook_service_name) == 0) {
+		ARRAY_LIST infos = arrayList_create();
+		int i;
+		for (i = 0; i > arrayList_size(framework->serviceListeners); i++) {
+			FW_SERVICE_LISTENER listener = arrayList_get(framework->serviceListeners, i);
+			apr_pool_t *pool;
+			BUNDLE_CONTEXT context;
+			bundle_getContext(bundle, &context);
+			bundleContext_getMemoryPool(context, &pool);
+			listener_hook_info_t info = apr_palloc(pool, sizeof(*info));
+			info->context = listener->bundle->context;
+			info->removed = false;
+			filter_getString(listener->filter, &info->filter);
+
+			arrayList_add(infos, info);
+		}
+
+		SERVICE_REFERENCE ref = (*registration)->reference;
+		listener_hook_service_t hook = fw_getService(framework, framework->bundle, ref);
+		hook->added(hook->handle, infos);
+		serviceRegistry_ungetService(framework->registry, framework->bundle, ref);
+	}
+
 	return CELIX_SUCCESS;
 }
 
@@ -1028,22 +1083,60 @@ bool framework_ungetService(FRAMEWORK fr
 }
 
 void fw_addServiceListener(FRAMEWORK framework, BUNDLE bundle, SERVICE_LISTENER listener, char * sfilter) {
+	apr_pool_t *pool;
+	apr_pool_t *bpool;
+	BUNDLE_CONTEXT context;
+	bundle_getContext(bundle, &context);
+	bundleContext_getMemoryPool(context, &bpool);
+	apr_pool_create(&pool, bpool);
+
 	FW_SERVICE_LISTENER fwListener = (FW_SERVICE_LISTENER) malloc(sizeof(*fwListener));
 	fwListener->bundle = bundle;
 	if (sfilter != NULL) {
 		FILTER filter = filter_create(sfilter);
 		fwListener->filter = filter;
+	} else {
+		fwListener->filter = NULL;
 	}
 	fwListener->listener = listener;
 	arrayList_add(framework->serviceListeners, fwListener);
+
+	ARRAY_LIST listenerHooks = NULL;
+	serviceRegistry_getListenerHooks(framework->registry, &listenerHooks);
+
+	listener_hook_info_t info = apr_palloc(pool, sizeof(*info));
+	info->context = bundle->context;
+	info->removed = false;
+	info->filter = sfilter == NULL ? NULL : strdup(sfilter);
+
+	int i;
+	for (i = 0; i < arrayList_size(listenerHooks); i++) {
+		SERVICE_REFERENCE ref = arrayList_get(listenerHooks, i);
+		listener_hook_service_t hook = fw_getService(framework, framework->bundle, ref);
+		ARRAY_LIST infos = arrayList_create();
+		arrayList_add(infos, info);
+		hook->added(hook->handle, infos);
+		serviceRegistry_ungetService(framework->registry, framework->bundle, ref);
+	}
 }
 
 void fw_removeServiceListener(FRAMEWORK framework, BUNDLE bundle, SERVICE_LISTENER listener) {
+	listener_hook_info_t info = NULL;
 	unsigned int i;
 	FW_SERVICE_LISTENER element;
 	for (i = 0; i < arrayList_size(framework->serviceListeners); i++) {
 		element = (FW_SERVICE_LISTENER) arrayList_get(framework->serviceListeners, i);
 		if (element->listener == listener && element->bundle == bundle) {
+			apr_pool_t *pool;
+			BUNDLE_CONTEXT context;
+			bundle_getContext(bundle, &context);
+			bundleContext_getMemoryPool(context, &pool);
+			info = apr_palloc(pool, sizeof(*info));
+			info->context = element->bundle->context;
+			// TODO Filter toString;
+			filter_getString(element->filter, &info->filter);
+			info->removed = true;
+
 			arrayList_remove(framework->serviceListeners, i);
 			i--;
 			element->bundle = NULL;
@@ -1055,6 +1148,21 @@ void fw_removeServiceListener(FRAMEWORK 
 			break;
 		}
 	}
+
+	if (info != NULL) {
+		ARRAY_LIST listenerHooks = NULL;
+		serviceRegistry_getListenerHooks(framework->registry, &listenerHooks);
+
+		int i;
+		for (i = 0; i < arrayList_size(listenerHooks); i++) {
+			SERVICE_REFERENCE ref = arrayList_get(listenerHooks, i);
+			listener_hook_service_t hook = fw_getService(framework, framework->bundle, ref);
+			ARRAY_LIST infos = arrayList_create();
+			arrayList_add(infos, info);
+			hook->removed(hook->handle, infos);
+			serviceRegistry_ungetService(framework->registry, framework->bundle, ref);
+		}
+	}
 }
 
 void fw_serviceChanged(FRAMEWORK framework, SERVICE_EVENT event, PROPERTIES oldprops) {
@@ -1397,14 +1505,12 @@ celix_status_t framework_waitForStop(FRA
 			celix_log("Error waiting for shutdown gate.");
 			return CELIX_FRAMEWORK_EXCEPTION;
 		}
-		printf("Interrupted %d\n", framework->shutdown);
 	}
-	printf("waited for stop\n");
 	if (apr_thread_mutex_unlock(framework->mutex) != 0) {
 		celix_log("Error unlocking the framework.");
 		return CELIX_FRAMEWORK_EXCEPTION;
 	}
-	printf("waited for stop finish\n");
+	printf("FRAMEWORK: Successful shutdown\n");
 	return CELIX_SUCCESS;
 }
 
@@ -1420,7 +1526,6 @@ static void *APR_THREAD_FUNC framework_s
 		if (state == BUNDLE_ACTIVE || state == BUNDLE_STARTING) {
 			char *location;
 			bundleArchive_getLocation(bundle_getArchive(bundle), &location);
-		    printf("stop bundle: %s\n", location);
 			fw_stopBundle(fw, bundle, 0);
 		}
 	}

Modified: incubator/celix/trunk/framework/private/src/module.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/src/module.c?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/src/module.c (original)
+++ incubator/celix/trunk/framework/private/src/module.c Mon Nov  7 18:06:25 2011
@@ -155,8 +155,16 @@ VERSION module_getVersion(MODULE module)
 	return module->version;
 }
 
-char * module_getSymbolicName(MODULE module) {
-	return module->symbolicName;
+celix_status_t module_getSymbolicName(MODULE module, char **symbolicName) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (module == NULL || *symbolicName != NULL) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	} else {
+		*symbolicName = module->symbolicName;
+	}
+
+	return status;
 }
 
 char * module_getId(MODULE module) {

Modified: incubator/celix/trunk/framework/private/src/resolver.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/src/resolver.c?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/src/resolver.c (original)
+++ incubator/celix/trunk/framework/private/src/resolver.c Mon Nov  7 18:06:25 2011
@@ -168,7 +168,10 @@ int resolver_populateCandidatesMap(HASH_
                                     resolver_removeInvalidCandidate(targetModule, candidatesMap, invalid);
                                     apr_pool_destroy(invalid_pool);
                                     apr_pool_destroy(candidates_pool);
-                                    printf("Unable to resolve: %s, %s\n", module_getSymbolicName(targetModule), requirement_getTargetName(req));
+                                    char *name = NULL;
+                                    module_getSymbolicName(targetModule, &name);
+
+                                    printf("Unable to resolve: %s, %s\n", name, requirement_getTargetName(req));
                                 }
                             }
                             return -1;

Modified: incubator/celix/trunk/framework/private/src/service_registry.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/src/service_registry.c?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/src/service_registry.c (original)
+++ incubator/celix/trunk/framework/private/src/service_registry.c Mon Nov  7 18:06:25 2011
@@ -29,6 +29,20 @@
 #include "service_registration.h"
 #include "module.h"
 #include "bundle.h"
+#include "listener_hook_service.h"
+#include "constants.h"
+
+struct serviceRegistry {
+    FRAMEWORK framework;
+	HASH_MAP serviceRegistrations;
+	HASH_MAP inUseMap;
+	void (*serviceChanged)(FRAMEWORK, SERVICE_EVENT, PROPERTIES);
+	long currentServiceId;
+
+	ARRAY_LIST listenerHooks;
+
+	pthread_mutex_t mutex;
+};
 
 struct usageCount {
 	unsigned int count;
@@ -39,6 +53,8 @@ struct usageCount {
 typedef struct usageCount * USAGE_COUNT;
 
 celix_status_t serviceRegistry_registerServiceInternal(SERVICE_REGISTRY registry, BUNDLE bundle, char * serviceName, void * serviceObject, PROPERTIES dictionary, bool isFactory, SERVICE_REGISTRATION *registration);
+celix_status_t serviceRegistry_addHooks(SERVICE_REGISTRY registry, char *serviceName, void *serviceObject, SERVICE_REFERENCE reference);
+celix_status_t serviceRegistry_removeHook(SERVICE_REGISTRY registry, SERVICE_REFERENCE reference);
 
 USAGE_COUNT serviceRegistry_getUsageCount(SERVICE_REGISTRY registry, BUNDLE bundle, SERVICE_REFERENCE reference) {
 	ARRAY_LIST usages = hashMap_get(registry->inUseMap, bundle);
@@ -61,7 +77,8 @@ USAGE_COUNT serviceRegistry_addUsageCoun
 
 	if (usages == NULL) {
 		usages = arrayList_create();
-		MODULE mod = bundle_getCurrentModule(bundle);
+		MODULE mod = NULL;
+		bundle_getCurrentModule(bundle, &mod);
 	}
 	arrayList_add(usages, usage);
 	hashMap_put(registry->inUseMap, bundle, usages);
@@ -99,6 +116,8 @@ SERVICE_REGISTRY serviceRegistry_create(
         registry->serviceRegistrations = hashMap_create(NULL, NULL, NULL, NULL);
         registry->framework = framework;
 
+        registry->listenerHooks = arrayList_create();
+
         pthread_mutexattr_t mutexattr;
         pthread_mutexattr_init(&mutexattr);
         pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
@@ -153,6 +172,8 @@ celix_status_t serviceRegistry_registerS
 	    *registration = serviceRegistration_create(registry, bundle, serviceName, ++registry->currentServiceId, serviceObject, dictionary);
 	}
 
+	serviceRegistry_addHooks(registry, serviceName, serviceObject, (*registration)->reference);
+
 	ARRAY_LIST regs = (ARRAY_LIST) hashMap_get(registry->serviceRegistrations, bundle);
 	if (regs == NULL) {
 		regs = arrayList_create();
@@ -177,6 +198,8 @@ celix_status_t serviceRegistry_registerS
 void serviceRegistry_unregisterService(SERVICE_REGISTRY registry, BUNDLE bundle, SERVICE_REGISTRATION registration) {
 	pthread_mutex_lock(&registry->mutex);
 
+	serviceRegistry_removeHook(registry, registration->reference);
+
 	ARRAY_LIST regs = (ARRAY_LIST) hashMap_get(registry->serviceRegistrations, bundle);
 	if (regs != NULL) {
 		arrayList_removeElement(regs, registration);
@@ -382,3 +405,36 @@ ARRAY_LIST serviceRegistry_getUsingBundl
 	hashMapIterator_destroy(iter);
 	return bundles;
 }
+
+celix_status_t serviceRegistry_addHooks(SERVICE_REGISTRY registry, char *serviceName, void *serviceObject, SERVICE_REFERENCE reference) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (strcmp(listener_hook_service_name, serviceName) == 0) {
+		arrayList_add(registry->listenerHooks, reference);
+	}
+
+	return status;
+}
+
+celix_status_t serviceRegistry_removeHook(SERVICE_REGISTRY registry, SERVICE_REFERENCE reference) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	char *serviceName = properties_get(reference->registration->properties, (char *) OBJECTCLASS);
+	if (strcmp(listener_hook_service_name, serviceName) == 0) {
+		arrayList_removeElement(registry->listenerHooks, reference);
+	}
+
+	return status;
+}
+
+celix_status_t serviceRegistry_getListenerHooks(SERVICE_REGISTRY registry, ARRAY_LIST *hooks) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (registry == NULL || *hooks != NULL) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	} else {
+		*hooks = arrayList_clone(registry->listenerHooks);
+	}
+
+	return status;
+}

Added: incubator/celix/trunk/framework/public/include/listener_hook_service.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/public/include/listener_hook_service.h?rev=1198847&view=auto
==============================================================================
--- incubator/celix/trunk/framework/public/include/listener_hook_service.h (added)
+++ incubator/celix/trunk/framework/public/include/listener_hook_service.h Mon Nov  7 18:06:25 2011
@@ -0,0 +1,33 @@
+/*
+ * listener_hook_service.h
+ *
+ *  Created on: Oct 28, 2011
+ *      Author: alexander
+ */
+
+#ifndef LISTENER_HOOK_SERVICE_H_
+#define LISTENER_HOOK_SERVICE_H_
+
+#include "headers.h"
+
+#define listener_hook_service_name "listener_hook_service"
+
+typedef struct listener_hook *listener_hook_t;
+
+struct listener_hook_info {
+	BUNDLE_CONTEXT context;
+	char *filter;
+	bool removed;
+};
+
+typedef struct listener_hook_info *listener_hook_info_t;
+
+struct listener_hook_service {
+	void *handle;
+	celix_status_t (*added)(void *hook, ARRAY_LIST listeners);
+	celix_status_t (*removed)(void *hook, ARRAY_LIST listeners);
+};
+
+typedef struct listener_hook_service *listener_hook_service_t;
+
+#endif /* LISTENER_HOOK_SERVICE_H_ */

Modified: incubator/celix/trunk/launcher/launcher.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/launcher/launcher.c?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/launcher/launcher.c (original)
+++ incubator/celix/trunk/launcher/launcher.c Mon Nov  7 18:06:25 2011
@@ -54,7 +54,7 @@ int main(void) {
     PROPERTIES config = properties_load("config.properties");
     char * autoStart = properties_get(config, "cosgi.auto.start.1");
     framework = NULL;
-    framework_create(&framework, memoryPool);
+    framework_create(&framework, memoryPool, config);
     fw_init(framework);
 
     // Start the system bundle

Modified: incubator/celix/trunk/log_writer/log_writer.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/log_writer/log_writer.c?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/log_writer/log_writer.c (original)
+++ incubator/celix/trunk/log_writer/log_writer.c Mon Nov  7 18:06:25 2011
@@ -69,9 +69,17 @@ void service_destroy(void * userData) {
 }
 
 celix_status_t logListener_logged(log_listener_t listener, log_entry_t entry) {
-    MODULE module = bundle_getCurrentModule(entry->bundle);
-    char *sName = module_getSymbolicName(module);
-    printf("LogWriter: %s from %s\n", entry->message, sName);
+	celix_status_t status = CELIX_SUCCESS;
+    MODULE module = NULL;
+    char *sName = NULL;
 
-    return CELIX_SUCCESS;
+    status = bundle_getCurrentModule(entry->bundle, &module);
+    if (status == CELIX_SUCCESS) {
+		status = module_getSymbolicName(module, &sName);
+		if (status == CELIX_SUCCESS) {
+			printf("LogWriter: %s from %s\n", entry->message, sName);
+		}
+    }
+
+    return status;
 }

Modified: incubator/celix/trunk/remote_services/CMakeLists.txt
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/CMakeLists.txt?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/remote_services/CMakeLists.txt (original)
+++ incubator/celix/trunk/remote_services/CMakeLists.txt Mon Nov  7 18:06:25 2011
@@ -25,5 +25,5 @@ add_subdirectory(example_endpoint)
 add_subdirectory(example_proxy)
 add_subdirectory(calc_shell)
 
-deploy("remote-services" BUNDLES topology_manager remote_service_admin example example_endpoint discovery shell shell_tui log_service log_writer)
-deploy("remote-services-client" BUNDLES topology_manager remote_service_admin discovery example_proxy shell shell_tui log_service log_writer calc_shell)
+deploy("remote-services" BUNDLES discovery topology_manager remote_service_admin example shell shell_tui log_service log_writer)
+deploy("remote-services-client" BUNDLES discovery topology_manager remote_service_admin shell shell_tui log_service log_writer calc_shell)

Modified: incubator/celix/trunk/remote_services/calc_shell/MANIFEST/MANIFEST.MF
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/calc_shell/MANIFEST/MANIFEST.MF?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/remote_services/calc_shell/MANIFEST/MANIFEST.MF (original)
+++ incubator/celix/trunk/remote_services/calc_shell/MANIFEST/MANIFEST.MF Mon Nov  7 18:06:25 2011
@@ -2,4 +2,4 @@ Bundle-SymbolicName: calc_shell
 Bundle-Version: 1.0.0
 library: calc_shell
 Export-Service: commandService
-Import-Service: commandService, example
+Import-Service: commandService

Modified: incubator/celix/trunk/remote_services/discovery/private/include/discovery.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/discovery/private/include/discovery.h?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/remote_services/discovery/private/include/discovery.h (original)
+++ incubator/celix/trunk/remote_services/discovery/private/include/discovery.h Mon Nov  7 18:06:25 2011
@@ -13,6 +13,7 @@
 typedef struct discovery *discovery_t;
 
 celix_status_t discovery_create(apr_pool_t *pool, BUNDLE_CONTEXT context, discovery_t *discovery);
+celix_status_t discovery_stop(discovery_t discovery);
 
 celix_status_t discovery_endpointAdded(void *handle, endpoint_description_t endpoint, char *machtedFilter);
 celix_status_t discovery_endpointRemoved(void *handle, endpoint_description_t endpoint, char *machtedFilter);

Modified: incubator/celix/trunk/remote_services/discovery/private/src/discovery.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/discovery/private/src/discovery.c?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/remote_services/discovery/private/src/discovery.c (original)
+++ incubator/celix/trunk/remote_services/discovery/private/src/discovery.c Mon Nov  7 18:06:25 2011
@@ -13,6 +13,9 @@
 #include "headers.h"
 #include "bundle_context.h"
 #include "array_list.h"
+#include "utils.h"
+#include "celix_errno.h"
+#include "filter.h"
 
 #include "discovery.h"
 
@@ -21,18 +24,37 @@ struct discovery {
 	apr_pool_t *pool;
 
 	HASH_MAP listenerReferences;
-	ARRAY_LIST endpoints;
 
 	bool running;
 	apr_thread_t *slpPoll;
+
+	HASH_MAP slpServices;
+
+	char *rsaPort;
+
+	ARRAY_LIST handled;
+	ARRAY_LIST registered;
 };
 
+struct slp_service {
+	char *serviceUrl;
+	char *attributes;
+};
+
+typedef struct slp_service *slp_service_t;
+
 celix_status_t discovery_informListener(discovery_t discovery, endpoint_listener_t listener, endpoint_description_t endpoint);
+celix_status_t discovery_informListenerOfRemoval(discovery_t discovery, endpoint_listener_t listener, endpoint_description_t endpoint);
 
 celix_status_t discovery_addService(discovery_t discovery, endpoint_description_t endpoint);
+celix_status_t discovery_removeService(discovery_t discovery, endpoint_description_t endpoint);
 
 static void *APR_THREAD_FUNC discovery_pollSLP(apr_thread_t *thd, void *data);
 SLPBoolean discovery_pollSLPCallback(SLPHandle hslp, const char* srvurl, unsigned short lifetime, SLPError errcode, void* cookie);
+SLPBoolean discovery_attributesCallback(SLPHandle hslp, const char *attributes, SLPError error, void *cookie);
+
+celix_status_t discovery_deregisterEndpoint(discovery_t discovery, const char *serviceUrl);
+void discovery_deregistrationReport(SLPHandle hslp, SLPError errcode, void* cookie);
 
 celix_status_t discovery_create(apr_pool_t *pool, BUNDLE_CONTEXT context, discovery_t *discovery) {
 	celix_status_t status = CELIX_SUCCESS;
@@ -44,14 +66,11 @@ celix_status_t discovery_create(apr_pool
 		(*discovery)->context = context;
 		(*discovery)->pool = pool;
 		(*discovery)->listenerReferences = hashMap_create(NULL, NULL, NULL, NULL);
-		(*discovery)->endpoints = arrayList_create();
+		(*discovery)->slpServices = hashMap_create(string_hash, NULL, string_equals, NULL);
 		(*discovery)->running = true;
-
-		endpoint_description_t endpoint = apr_palloc(pool, sizeof(*endpoint));
-		endpoint->id = apr_pstrdup(pool, "http://localhost:8080/services/example/");
-		endpoint->serviceId = 42;
-		endpoint->service = "example";
-		discovery_addService(*discovery, endpoint);
+		(*discovery)->rsaPort = getenv("RSA_PORT");
+		(*discovery)->handled = arrayList_create();
+		(*discovery)->registered = arrayList_create();
 
 		apr_thread_create(&(*discovery)->slpPoll, NULL, discovery_pollSLP, *discovery, (*discovery)->pool);
 	}
@@ -59,11 +78,51 @@ celix_status_t discovery_create(apr_pool
 	return status;
 }
 
-celix_status_t discovery_addService(discovery_t discovery, endpoint_description_t endpoint) {
+celix_status_t discovery_deregisterEndpoint(discovery_t discovery, const char *serviceUrl) {
 	celix_status_t status = CELIX_SUCCESS;
-	printf("DISCOVERY: Service added\n");
+	printf("DISCOVERY: Remove endpoint: %s\n", serviceUrl);
 
-	arrayList_add(discovery->endpoints, endpoint);
+	SLPError err;
+	SLPError callbackerr;
+	SLPHandle slp;
+
+	err = SLPOpen("en", SLP_FALSE, &slp);
+	if (err != SLP_OK) {
+		status = CELIX_BUNDLE_EXCEPTION;
+	} else {
+		err = SLPDereg(slp, serviceUrl, discovery_deregistrationReport, &callbackerr);
+		if ((err != SLP_OK) || (callbackerr != SLP_OK)) {
+			printf("DISCOVERY: Error deregistering service (%s) with slp %i\n", serviceUrl, err);
+			status = CELIX_BUNDLE_EXCEPTION;
+		}
+		SLPClose(slp);
+	}
+
+	return status;
+}
+
+celix_status_t discovery_stop(discovery_t discovery) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	apr_status_t tstat;
+	discovery->running = false;
+	apr_status_t stat = apr_thread_join(&tstat, discovery->slpPoll);
+	if (stat != APR_SUCCESS && tstat != APR_SUCCESS) {
+		status = CELIX_BUNDLE_EXCEPTION;
+	}
+
+	int i;
+	for (i = 0; i < arrayList_size(discovery->registered); i++) {
+		char *url = arrayList_get(discovery->registered, i);
+		discovery_deregisterEndpoint(discovery, url);
+	}
+
+	return status;
+}
+
+celix_status_t discovery_removeService(discovery_t discovery, endpoint_description_t endpoint) {
+	celix_status_t status = CELIX_SUCCESS;
+	printf("DISCOVERY: Remove service (%s)\n", endpoint->service);
 
 	// Inform listeners of new endpoint
 	HASH_MAP_ITERATOR iter = hashMapIterator_create(discovery->listenerReferences);
@@ -72,7 +131,29 @@ celix_status_t discovery_addService(disc
 		SERVICE_REFERENCE reference = hashMapEntry_getKey(entry);
 		endpoint_listener_t listener = NULL;
 		bundleContext_getService(discovery->context, reference, (void**)&listener);
-		discovery_informListener(discovery, listener, endpoint);
+		discovery_informListenerOfRemoval(discovery, listener, endpoint);
+	}
+
+	return status;
+}
+
+celix_status_t discovery_addService(discovery_t discovery, endpoint_description_t endpoint) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	// Inform listeners of new endpoint
+	HASH_MAP_ITERATOR iter = hashMapIterator_create(discovery->listenerReferences);
+	while (hashMapIterator_hasNext(iter)) {
+		HASH_MAP_ENTRY entry = hashMapIterator_nextEntry(iter);
+		SERVICE_REFERENCE reference = hashMapEntry_getKey(entry);
+		endpoint_listener_t listener = NULL;
+
+		char *scope = properties_get(reference->registration->properties, (char *) ENDPOINT_LISTENER_SCOPE);
+		FILTER filter = filter_create(scope);
+		if (filter_match(filter, endpoint->properties)) {
+			printf("DISCOVERY: Add service (%s)\n", endpoint->service);
+			bundleContext_getService(discovery->context, reference, (void**)&listener);
+			discovery_informListener(discovery, listener, endpoint);
+		}
 	}
 
 	return status;
@@ -84,49 +165,109 @@ celix_status_t discovery_informListener(
 	return status;
 }
 
-void MySLPRegReport(SLPHandle hslp, SLPError errcode, void* cookie)
-  {
-      /* return the error code in the cookie */
-
-      *(SLPError*)cookie = errcode;
-
-      printf("Error\n");
-
-      /* You could do something else here like print out    */
-      /* the errcode, etc.  Remember, as a general rule,    */
-      /* do not try to do too much in a callback because    */
-      /* it is being executed by the same thread that is    */
-      /* reading slp packets from the wire.                 */
-  }
+celix_status_t discovery_informListenerOfRemoval(discovery_t discovery, endpoint_listener_t listener, endpoint_description_t endpoint) {
+	celix_status_t status = CELIX_SUCCESS;
+	listener->endpointRemoved(listener->handle, endpoint, NULL);
+	return status;
+}
+
+celix_status_t discovery_constructServiceUrl(discovery_t discovery, endpoint_description_t endpoint, char **serviceUrl) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (*serviceUrl != NULL || discovery == NULL || endpoint == NULL) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	} else {
+		char host[APRMAXHOSTLEN + 1];
+		apr_sockaddr_t *sa;
+		char *ip;
+
+		apr_status_t stat = apr_gethostname(host, APRMAXHOSTLEN + 1, discovery->pool);
+		if (stat != APR_SUCCESS) {
+			status = CELIX_BUNDLE_EXCEPTION;
+		} else {
+			stat = apr_sockaddr_info_get(&sa, host, APR_INET, 0, 0, discovery->pool);
+			if (stat != APR_SUCCESS) {
+				status = CELIX_BUNDLE_EXCEPTION;
+			} else {
+				stat = apr_sockaddr_ip_get(&ip, sa);
+				if (stat != APR_SUCCESS) {
+					status = CELIX_BUNDLE_EXCEPTION;
+				} else {
+					*serviceUrl = apr_pstrcat(discovery->pool, "service:osgi.remote:http://", ip, ":", discovery->rsaPort, "/services/", endpoint->service, NULL);
+				}
+			}
+		}
+	}
+
+	return status;
+}
+
+void discovery_registrationReport(SLPHandle hslp, SLPError errcode, void* cookie) {
+	*(SLPError*)cookie = errcode;
+}
 
 celix_status_t discovery_endpointAdded(void *handle, endpoint_description_t endpoint, char *machtedFilter) {
 	celix_status_t status = CELIX_SUCCESS;
-	printf("DISCOVERY: Endpoint added\n");
+	printf("DISCOVERY: Endpoint for %s, with filter \"%s\" added\n", endpoint->service, machtedFilter);
 	discovery_t discovery = handle;
 	SLPError err;
 	SLPError callbackerr;
 	SLPHandle slp;
+	char *serviceUrl = NULL;
 
-	//publish endpoint in slp
-
-	SLPOpen("en", SLP_FALSE, &slp);
-
-	err = SLPReg(slp, "service:osgi.remote://host:8081",
-			SLP_LIFETIME_MAXIMUM, 0, "", SLP_TRUE, MySLPRegReport, &callbackerr);
-
-	if ((err != SLP_OK) || (callbackerr != SLP_OK)) {
-		printf("Error registering service with slp %i\n", err);
-		return err;
+	err = SLPOpen("en", SLP_FALSE, &slp);
+	if (err != SLP_OK) {
+		status = CELIX_ILLEGAL_STATE;
+	} else {
+		status = discovery_constructServiceUrl(discovery, endpoint, &serviceUrl);
+		if (status == CELIX_SUCCESS) {
+			char *attributes = "";
+			HASH_MAP_ITERATOR iter = hashMapIterator_create(endpoint->properties);
+			while (hashMapIterator_hasNext(iter)) {
+				HASH_MAP_ENTRY entry = hashMapIterator_nextEntry(iter);
+				char *key = hashMapEntry_getKey(entry);
+				char *value = hashMapEntry_getValue(entry);
+				if (strlen(attributes) != 0) {
+					attributes = apr_pstrcat(discovery->pool, attributes, ",", NULL);
+				}
+				attributes = apr_pstrcat(discovery->pool, attributes, "(", key, "=", value, ")", NULL);
+			}
+			err = SLPReg(slp, serviceUrl, SLP_LIFETIME_MAXIMUM, 0, attributes, SLP_TRUE, discovery_registrationReport, &callbackerr);
+			if ((err != SLP_OK) || (callbackerr != SLP_OK)) {
+				status = CELIX_ILLEGAL_STATE;
+				printf("DISCOVERY: Error registering service (%s) with slp %i\n", serviceUrl, err);
+			}
+			arrayList_add(discovery->registered, serviceUrl);
+		}
+		SLPClose(slp);
 	}
 
 	return status;
 }
 
+void discovery_deregistrationReport(SLPHandle hslp, SLPError errcode, void* cookie) {
+	*(SLPError*)cookie = errcode;
+}
+
 celix_status_t discovery_endpointRemoved(void *handle, endpoint_description_t endpoint, char *machtedFilter) {
 	celix_status_t status = CELIX_SUCCESS;
-	printf("DISCOVERY: Endpoint removed\n");
+	printf("DISCOVERY: Endpoint for %s, with filter \"%s\" removed\n", endpoint->service, machtedFilter);
+
+	discovery_t discovery = handle;
+	SLPError err;
+	SLPError callbackerr;
+	SLPHandle slp;
+	char *serviceUrl = NULL;
 
-	//unpublish endpoint
+	err = SLPOpen("en", SLP_FALSE, &slp);
+	if (err != SLP_OK) {
+		status = CELIX_ILLEGAL_STATE;
+	} else {
+		status = discovery_constructServiceUrl(discovery, endpoint, &serviceUrl);
+		if (status == CELIX_SUCCESS) {
+			status = discovery_deregisterEndpoint(discovery, serviceUrl);
+		}
+	}
 
 	return status;
 }
@@ -179,11 +320,12 @@ celix_status_t discovery_updateEndpointL
 		arrayList_add(scopes, scope);
 	}
 
-	int size = arrayList_size(discovery->endpoints);
-	int iter = 0;
-	for (iter = 0; iter < size; iter++) {
-		endpoint_description_t endpoint = arrayList_get(discovery->endpoints, iter);
-		discovery_informListener(discovery, service, endpoint);
+	HASH_MAP_ITERATOR iter = hashMapIterator_create(discovery->slpServices);
+	while (hashMapIterator_hasNext(iter)) {
+		HASH_MAP_ENTRY entry = hashMapIterator_nextEntry(iter);
+		char *key = hashMapEntry_getKey(entry);
+		endpoint_description_t value = hashMapEntry_getValue(entry);
+		discovery_informListener(discovery, service, value);
 	}
 
 	return status;
@@ -201,27 +343,106 @@ celix_status_t discovery_endpointListene
 
 static void *APR_THREAD_FUNC discovery_pollSLP(apr_thread_t *thd, void *data) {
 	discovery_t discovery = data;
-	SLPError err;
-	SLPError callbackerr;
 	SLPHandle slp;
+	SLPError err;
 
-	SLPOpen("en", SLP_FALSE, &slp);
+	err = SLPOpen("en", SLP_FALSE, &slp);
 
 	while (discovery->running) {
-		err = SLPFindSrvs(slp, "osgi.remote", 0, 0, discovery_pollSLPCallback, &callbackerr);
-		sleep(5);
+		SLPError err = SLP_TRUE;
+		SLPError callbackerr;
+		arrayList_clear(discovery->handled);
+		while (err == SLP_TRUE) {
+			err = SLPFindSrvs(slp, "osgi.remote", 0, 0, discovery_pollSLPCallback, data);
+		}
+
+		HASH_MAP_ITERATOR iter = hashMapIterator_create(discovery->slpServices);
+		while (hashMapIterator_hasNext(iter)) {
+			HASH_MAP_ENTRY entry = hashMapIterator_nextEntry(iter);
+			char *key = hashMapEntry_getKey(entry);
+			endpoint_description_t value = hashMapEntry_getValue(entry);
+
+			bool inUse = false;
+			int i;
+			for (i = 0; i < arrayList_size(discovery->handled); i++) {
+				char *url = arrayList_get(discovery->handled, i);
+				if (strcmp(url, key) == 0) {
+					inUse = true;
+					break;
+				}
+			}
+
+			if (!inUse) {
+				discovery_removeService(discovery, value);
+
+				hashMapIterator_remove(iter);
+			}
+		}
+
+		sleep(1);
 	}
+	SLPClose(slp);
+	apr_thread_exit(thd, APR_SUCCESS);
 
 	return NULL;
 }
 
-SLPBoolean discovery_pollSLPCallback(SLPHandle hslp, const char* srvurl, unsigned short lifetime, SLPError errcode, void* cookie) {
-	if (errcode == SLP_OK || errcode == SLP_LAST_CALL) {
-		printf("Service URL     = %s\n", srvurl);
-		printf("Service Timeout = %i\n", lifetime);
-		*(SLPError*) cookie = SLP_OK;
+SLPBoolean discovery_pollSLPCallback(SLPHandle hslp, const char* srvurl, unsigned short lifetime, SLPError errcode, void *cookie) {
+	discovery_t discovery = cookie;
+	if (errcode == SLP_OK) {
+
+		arrayList_add(discovery->handled, (void *) srvurl);
+		if (!hashMap_containsKey(discovery->slpServices, (void *) srvurl)) {
+			// service:osgi.remote:http://10.0.0.21:8080/services/example
+			if (strncmp(srvurl, "service:osgi.remote:", 20) == 0) {
+				const char *url = srvurl+20;
+				const char *srv = strrchr(url, '/')+1;
+
+				SLPHandle handle = NULL;
+				SLPError err = SLPOpen("en", SLP_FALSE, &handle);
+				err = SLP_TRUE;
+				slp_service_t slpService = apr_palloc(discovery->pool, sizeof(*slpService));
+				while (err == SLP_TRUE) {
+					err = SLPFindAttrs(handle, srvurl, "", "", discovery_attributesCallback, slpService);
+				}
+
+				PROPERTIES props = properties_create();
+				char *track;
+				char *token = apr_strtok(slpService->attributes, ",", &track);
+				while (token != NULL) {
+					char *track2;
+					char *token2 = apr_strtok(token, "=", &track2);
+					char *token3 = apr_strtok(NULL, "=", &track2);
+					char *key = apr_pstrdup(discovery->pool, token2+1);
+					char *value = apr_pstrndup(discovery->pool, token3, strlen(token3) - 1);
+					properties_set(props, key, value);
+					token = apr_strtok(NULL, ",", &track);
+				}
+
+				endpoint_description_t endpoint = apr_palloc(discovery->pool, sizeof(*endpoint));
+				endpoint->id = apr_pstrdup(discovery->pool, url);
+				endpoint->serviceId = 42;
+				endpoint->service = apr_pstrdup(discovery->pool, srv);
+				endpoint->properties = props;
+				discovery_addService(discovery, endpoint);
+
+				hashMap_put(discovery->slpServices, apr_pstrdup(discovery->pool, srvurl), endpoint);
+			}
+		}
+	} else if (errcode == SLP_LAST_CALL) {
+		return SLP_FALSE;
 	} else {
-		*(SLPError*) cookie = errcode;
+	}
+
+	return SLP_TRUE;
+}
+
+SLPBoolean discovery_attributesCallback(SLPHandle hslp, const char *attributes, SLPError error, void *cookie) {
+	slp_service_t slpService = cookie;
+	if (error == SLP_OK) {
+		slpService->attributes = strdup(attributes);
+	} else if (error == SLP_LAST_CALL) {
+		return SLP_FALSE;
 	}
 
 	return SLP_TRUE;

Modified: incubator/celix/trunk/remote_services/discovery/private/src/discovery_activator.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/discovery/private/src/discovery_activator.c?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/remote_services/discovery/private/src/discovery_activator.c (original)
+++ incubator/celix/trunk/remote_services/discovery/private/src/discovery_activator.c Mon Nov  7 18:06:25 2011
@@ -9,6 +9,7 @@
 #include <stdlib.h>
 
 #include <apr_strings.h>
+#include <apr_uuid.h>
 
 #include "headers.h"
 #include "bundle_activator.h"
@@ -30,7 +31,8 @@ struct activator {
 	SERVICE_REGISTRATION endpointListenerService;
 };
 
-celix_status_t bundleActivator_createEPLTracker(struct activator *activator, SERVICE_TRACKER *tracker);
+celix_status_t discoveryActivator_createEPLTracker(struct activator *activator, SERVICE_TRACKER *tracker);
+celix_status_t discoveryActivator_getUUID(struct activator *activator, char **uuidStr);
 
 celix_status_t bundleActivator_create(BUNDLE_CONTEXT context, void **userData) {
 	celix_status_t status = CELIX_SUCCESS;
@@ -49,7 +51,7 @@ celix_status_t bundleActivator_create(BU
 
 		discovery_create(pool, context, &activator->discovery);
 
-		bundleActivator_createEPLTracker(activator, &activator->endpointListenerTracker);
+		discoveryActivator_createEPLTracker(activator, &activator->endpointListenerTracker);
 
 		*userData = activator;
 	}
@@ -57,7 +59,7 @@ celix_status_t bundleActivator_create(BU
 	return status;
 }
 
-celix_status_t bundleActivator_createEPLTracker(struct activator *activator, SERVICE_TRACKER *tracker) {
+celix_status_t discoveryActivator_createEPLTracker(struct activator *activator, SERVICE_TRACKER *tracker) {
 	celix_status_t status = CELIX_SUCCESS;
 
 	SERVICE_TRACKER_CUSTOMIZER custumizer = (SERVICE_TRACKER_CUSTOMIZER) apr_palloc(activator->pool, sizeof(*custumizer));
@@ -91,7 +93,9 @@ celix_status_t bundleActivator_start(voi
 
 	PROPERTIES props = properties_create();
 	properties_set(props, "DISCOVERY", "true");
-	char *scope = apr_pstrcat(activator->pool, "(&(", OBJECTCLASS, "=*)(", ENDPOINT_FRAMEWORK_UUID, "=42", "))", NULL);
+	char *uuid = NULL;
+	discoveryActivator_getUUID(activator, &uuid);
+	char *scope = apr_pstrcat(activator->pool, "(&(", OBJECTCLASS, "=*)(", ENDPOINT_FRAMEWORK_UUID, "=", uuid, "))", NULL);
 	properties_set(props, (char *) ENDPOINT_LISTENER_SCOPE, scope);
 	bundleContext_registerService(context, (char *) endpoint_listener_service, endpointListener, props, &activator->endpointListenerService);
 
@@ -102,6 +106,7 @@ celix_status_t bundleActivator_stop(void
 	celix_status_t status = CELIX_SUCCESS;
 	struct activator *activator = userData;
 
+	discovery_stop(activator->discovery);
 	serviceTracker_close(activator->endpointListenerTracker);
 	serviceRegistration_unregister(activator->endpointListenerService);
 
@@ -112,3 +117,20 @@ celix_status_t bundleActivator_destroy(v
 	celix_status_t status = CELIX_SUCCESS;
 	return status;
 }
+
+celix_status_t discoveryActivator_getUUID(struct activator *activator, char **uuidStr) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	status = bundleContext_getProperty(activator->context, ENDPOINT_FRAMEWORK_UUID, uuidStr);
+	if (status == CELIX_SUCCESS) {
+		if (*uuidStr == NULL) {
+			apr_uuid_t uuid;
+			apr_uuid_get(&uuid);
+			*uuidStr = apr_palloc(activator->pool, APR_UUID_FORMATTED_LENGTH + 1);
+			apr_uuid_format(*uuidStr, &uuid);
+			setenv(ENDPOINT_FRAMEWORK_UUID, *uuidStr, 1);
+		}
+	}
+
+	return status;
+}

Modified: incubator/celix/trunk/remote_services/example_proxy/private/src/example_proxy_impl.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/example_proxy/private/src/example_proxy_impl.c?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/remote_services/example_proxy/private/src/example_proxy_impl.c (original)
+++ incubator/celix/trunk/remote_services/example_proxy/private/src/example_proxy_impl.c Mon Nov  7 18:06:25 2011
@@ -47,7 +47,7 @@ celix_status_t exampleProxy_add(example_
 
 	if (example->endpoint != NULL) {
 		printf("PROXY: URL: %s\n", example->endpoint->id);
-		char *url = apr_pstrcat(example->pool, example->endpoint->id, "add", NULL);
+		char *url = apr_pstrcat(example->pool, example->endpoint->id, "/add", NULL);
 
 		json_t *root;
 		root = json_pack("{s:f, s:f}", "a", a, "b", b);
@@ -78,7 +78,7 @@ celix_status_t exampleProxy_sub(example_
 	celix_status_t status = CELIX_SUCCESS;
 	if (example->endpoint != NULL) {
 		printf("PROXY: URL: %s\n", example->endpoint->id);
-		char *url = apr_pstrcat(example->pool, example->endpoint->id, "sub", NULL);
+		char *url = apr_pstrcat(example->pool, example->endpoint->id, "/sub", NULL);
 
 		json_t *root;
 		root = json_pack("{s:f, s:f}", "a", a, "b", b);
@@ -109,7 +109,7 @@ celix_status_t exampleProxy_sqrt(example
 	celix_status_t status = CELIX_SUCCESS;
 	if (example->endpoint != NULL) {
 		printf("PROXY: URL: %s\n", example->endpoint->id);
-		char *url = apr_pstrcat(example->pool, example->endpoint->id, "sqrt", NULL);
+		char *url = apr_pstrcat(example->pool, example->endpoint->id, "/sqrt", NULL);
 
 		json_t *root;
 		root = json_pack("{s:f}", "a", a);

Modified: incubator/celix/trunk/remote_services/remote_service_admin/private/include/export_registration_impl.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/remote_service_admin/private/include/export_registration_impl.h?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/remote_services/remote_service_admin/private/include/export_registration_impl.h (original)
+++ incubator/celix/trunk/remote_services/remote_service_admin/private/include/export_registration_impl.h Mon Nov  7 18:06:25 2011
@@ -25,11 +25,13 @@ struct export_registration {
 	remote_endpoint_service_t endpoint;
 
 	export_reference_t exportReference;
+	BUNDLE bundle;
 
 	bool closed;
 };
 
 celix_status_t exportRegistration_create(apr_pool_t *pool, SERVICE_REFERENCE reference, endpoint_description_t endpoint, remote_service_admin_t rsa, BUNDLE_CONTEXT context, export_registration_t *registration);
+celix_status_t exportRegistration_open(export_registration_t registration);
 celix_status_t exportRegistration_close(export_registration_t registration);
 celix_status_t exportRegistration_getException(export_registration_t registration);
 celix_status_t exportRegistration_getExportReference(export_registration_t registration, export_reference_t *reference);

Modified: incubator/celix/trunk/remote_services/remote_service_admin/private/include/import_registration_impl.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/remote_service_admin/private/include/import_registration_impl.h?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/remote_services/remote_service_admin/private/include/import_registration_impl.h (original)
+++ incubator/celix/trunk/remote_services/remote_service_admin/private/include/import_registration_impl.h Mon Nov  7 18:06:25 2011
@@ -20,15 +20,19 @@ struct import_registration {
 
 	SERVICE_TRACKER proxyTracker;
 
+	SERVICE_REFERENCE reference;
 	remote_proxy_service_t proxy;
+	import_reference_t importReference;
+	BUNDLE bundle;
 
 	bool closed;
 };
 
 celix_status_t importRegistration_create(apr_pool_t *pool, endpoint_description_t endpoint, remote_service_admin_t rsa, BUNDLE_CONTEXT context, import_registration_t *registration);
+celix_status_t importRegistration_open(import_registration_t registration);
 celix_status_t importRegistration_close(import_registration_t registration);
 celix_status_t importRegistration_getException(import_registration_t registration);
-celix_status_t importRegistration_getImportReference(import_registration_t registration);
+celix_status_t importRegistration_getImportReference(import_registration_t registration, import_reference_t *reference);
 
 celix_status_t importRegistration_setEndpointDescription(import_registration_t registration, endpoint_description_t endpointDescription);
 celix_status_t importRegistration_startTracking(import_registration_t registration);

Modified: incubator/celix/trunk/remote_services/remote_service_admin/private/include/remote_service_admin_impl.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/remote_service_admin/private/include/remote_service_admin_impl.h?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/remote_services/remote_service_admin/private/include/remote_service_admin_impl.h (original)
+++ incubator/celix/trunk/remote_services/remote_service_admin/private/include/remote_service_admin_impl.h Mon Nov  7 18:06:25 2011
@@ -11,13 +11,16 @@
 #include "remote_service_admin.h"
 #include "mongoose.h"
 
+#define BUNDLE_STORE "rs_bundles"
+
 struct export_reference {
 	endpoint_description_t endpoint;
 	SERVICE_REFERENCE reference;
 };
 
 struct import_reference {
-
+	endpoint_description_t endpoint;
+	SERVICE_REFERENCE reference;
 };
 
 struct remote_service_admin {

Modified: incubator/celix/trunk/remote_services/remote_service_admin/private/src/export_registration_impl.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/remote_service_admin/private/src/export_registration_impl.c?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/remote_services/remote_service_admin/private/src/export_registration_impl.c (original)
+++ incubator/celix/trunk/remote_services/remote_service_admin/private/src/export_registration_impl.c Mon Nov  7 18:06:25 2011
@@ -6,6 +6,8 @@
  */
 #include <stdlib.h>
 
+#include <apr_strings.h>
+
 #include "headers.h"
 #include "celix_errno.h"
 
@@ -14,6 +16,7 @@
 #include "remote_endpoint.h"
 #include "service_tracker.h"
 #include "bundle_context.h"
+#include "bundle.h"
 
 celix_status_t exportRegistration_endpointAdding(void * handle, SERVICE_REFERENCE reference, void **service);
 celix_status_t exportRegistration_endpointAdded(void * handle, SERVICE_REFERENCE reference, void *service);
@@ -41,6 +44,7 @@ celix_status_t exportRegistration_create
 		(*registration)->endpoint = NULL;
 		(*registration)->endpointTracker = NULL;
 		(*registration)->exportReference = NULL;
+		(*registration)->bundle = NULL;
 	}
 
 	return status;
@@ -143,9 +147,28 @@ celix_status_t exportRegistration_endpoi
 	return status;
 }
 
+celix_status_t exportRegistration_open(export_registration_t registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	char *name = apr_pstrcat(registration->pool, BUNDLE_STORE, "/", registration->endpointDescription->service, "_endpoint.zip", NULL);
+	status = bundleContext_installBundle(registration->context, name, &registration->bundle);
+	if (status == CELIX_SUCCESS) {
+		status = bundle_start(registration->bundle, 0);
+		if (status == CELIX_SUCCESS) {
+		}
+	}
+
+	return status;
+}
+
 celix_status_t exportRegistration_close(export_registration_t registration) {
 	celix_status_t status = CELIX_SUCCESS;
 
+	exportRegistration_stopTracking(registration);
+
+	bundle_stop(registration->bundle, 0);
+	bundle_uninstall(registration->bundle);
+
 	return status;
 }
 

Modified: incubator/celix/trunk/remote_services/remote_service_admin/private/src/import_registration_impl.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/remote_service_admin/private/src/import_registration_impl.c?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/remote_services/remote_service_admin/private/src/import_registration_impl.c (original)
+++ incubator/celix/trunk/remote_services/remote_service_admin/private/src/import_registration_impl.c Mon Nov  7 18:06:25 2011
@@ -7,6 +7,8 @@
 
 #include <stdlib.h>
 
+#include <apr_strings.h>
+
 #include "headers.h"
 #include "celix_errno.h"
 
@@ -15,6 +17,7 @@
 #include "remote_proxy.h"
 #include "service_tracker.h"
 #include "bundle_context.h"
+#include "bundle.h"
 
 celix_status_t importRegistration_proxyAdding(void * handle, SERVICE_REFERENCE reference, void **service);
 celix_status_t importRegistration_proxyAdded(void * handle, SERVICE_REFERENCE reference, void *service);
@@ -25,18 +28,23 @@ celix_status_t importRegistration_create
 
 celix_status_t importRegistration_create(apr_pool_t *pool, endpoint_description_t endpoint, remote_service_admin_t rsa, BUNDLE_CONTEXT context, import_registration_t *registration) {
 	celix_status_t status = CELIX_SUCCESS;
+	apr_pool_t *mypool = NULL;
+	apr_pool_create(&mypool, pool);
 
-	*registration = apr_palloc(pool, sizeof(**registration));
+	*registration = apr_palloc(mypool, sizeof(**registration));
 	if (!*registration) {
 		status = CELIX_ENOMEM;
 	} else {
-		(*registration)->pool = pool;
+		(*registration)->pool = mypool;
 		(*registration)->context = context;
 		(*registration)->closed = false;
 		(*registration)->endpointDescription = endpoint;
 		(*registration)->rsa = rsa;
 		(*registration)->proxy = NULL;
+		(*registration)->reference = NULL;
 		(*registration)->proxyTracker = NULL;
+		(*registration)->bundle = NULL;
+		(*registration)->importReference = NULL;
 	}
 
 	return status;
@@ -97,6 +105,7 @@ celix_status_t importRegistration_proxyA
 
 	remote_proxy_service_t proxy = service;
 	if (registration->proxy == NULL) {
+		registration->reference = reference;
 		registration->proxy = proxy;
 		if (registration->endpointDescription != NULL) {
 			proxy->setEndpointDescription(proxy->proxy, registration->endpointDescription);
@@ -125,6 +134,7 @@ celix_status_t importRegistration_proxyR
 
 	remote_proxy_service_t proxy = service;
 	if (registration->proxy != NULL) {
+		registration->reference = NULL;
 		registration->proxy = NULL;
 		proxy->setEndpointDescription(proxy->proxy, NULL);
 	}
@@ -132,8 +142,30 @@ celix_status_t importRegistration_proxyR
 	return status;
 }
 
+celix_status_t importRegistration_open(import_registration_t registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	char *name = apr_pstrcat(registration->pool, BUNDLE_STORE, "/", registration->endpointDescription->service, "_proxy.zip", NULL);
+	status = bundleContext_installBundle(registration->context, name, &registration->bundle);
+	if (status == CELIX_SUCCESS) {
+		status = bundle_start(registration->bundle, 0);
+		if (status == CELIX_SUCCESS) {
+		}
+	}
+
+	return status;
+}
+
 celix_status_t importRegistration_close(import_registration_t registration) {
 	celix_status_t status = CELIX_SUCCESS;
+
+	importRegistration_stopTracking(registration);
+
+	if (registration->bundle != NULL) {
+		bundle_stop(registration->bundle, 0);
+		bundle_uninstall(registration->bundle);
+	}
+
 	return status;
 }
 
@@ -142,8 +174,21 @@ celix_status_t importRegistration_getExc
 	return status;
 }
 
-celix_status_t importRegistration_getImportReference(import_registration_t registration) {
+celix_status_t importRegistration_getImportReference(import_registration_t registration, import_reference_t *reference) {
 	celix_status_t status = CELIX_SUCCESS;
+
+	if (registration->importReference == NULL) {
+		registration->importReference = apr_palloc(registration->pool, sizeof(*registration->importReference));
+		if (registration->importReference == NULL) {
+			status = CELIX_ENOMEM;
+		} else {
+			registration->importReference->endpoint = registration->endpointDescription;
+			registration->importReference->reference = registration->reference;
+		}
+	}
+
+	*reference = registration->importReference;
+
 	return status;
 }
 

Modified: incubator/celix/trunk/remote_services/remote_service_admin/private/src/remote_service_admin_impl.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/remote_service_admin/private/src/remote_service_admin_impl.c?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/remote_services/remote_service_admin/private/src/remote_service_admin_impl.c (original)
+++ incubator/celix/trunk/remote_services/remote_service_admin/private/src/remote_service_admin_impl.c Mon Nov  7 18:06:25 2011
@@ -7,6 +7,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <apr_uuid.h>
 #include <apr_strings.h>
 
 #include "headers.h"
@@ -27,7 +28,8 @@ static const char *ajax_reply_start =
 
 void *remoteServiceAdmin_callback(enum mg_event event, struct mg_connection *conn, const struct mg_request_info *request_info);
 celix_status_t remoteServiceAdmin_installEndpoint(remote_service_admin_t admin, export_registration_t registration, SERVICE_REFERENCE reference, char *interface);
-celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_t admin, PROPERTIES serviceProperties, PROPERTIES endpointProperties, endpoint_description_t *description);
+celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_t admin, PROPERTIES serviceProperties, PROPERTIES endpointProperties, char *interface, endpoint_description_t *description);
+celix_status_t remoteServiceAdmin_getUUID(remote_service_admin_t rsa, char **uuidStr);
 
 celix_status_t remoteServiceAdmin_create(apr_pool_t *pool, BUNDLE_CONTEXT context, remote_service_admin_t *admin) {
 	celix_status_t status = CELIX_SUCCESS;
@@ -45,7 +47,6 @@ celix_status_t remoteServiceAdmin_create
 		const char *port = getenv("RSA_PORT");
 		const char *options[] = {"listening_ports", port, NULL};
 		(*admin)->ctx = mg_start(remoteServiceAdmin_callback, (*admin), options);
-		printf("Mongoose started on: %s\n", mg_get_option((*admin)->ctx, "listening_ports"));
 	}
 
 	return status;
@@ -140,8 +141,9 @@ celix_status_t remoteServiceAdmin_export
 	char *provided = properties_get(reference->registration->properties, (char *) OBJECTCLASS);
 
 	if (exports == NULL || provided == NULL) {
-		printf("RSA Export Service - No Services to export.\n");
+		printf("RSA: No Services to export.\n");
 	} else {
+		printf("RSA: Export services (%s)\n", exports);
 		ARRAY_LIST interfaces = arrayList_create();
 		if (strcmp(string_trim(exports), "*") == 0) {
 			char *token;
@@ -177,48 +179,62 @@ celix_status_t remoteServiceAdmin_export
 				arrayList_add(*registrations, registration);
 
 				remoteServiceAdmin_installEndpoint(admin, registration, reference, interface);
+				exportRegistration_open(registration);
 				exportRegistration_startTracking(registration);
 			}
 			hashMap_put(admin->exportedServices, reference, *registrations);
 		}
 	}
 
-
-	printf("RSA export service\n");
 	return status;
 }
 
 celix_status_t remoteServiceAdmin_installEndpoint(remote_service_admin_t admin, export_registration_t registration, SERVICE_REFERENCE reference, char *interface) {
 	celix_status_t status = CELIX_SUCCESS;
-	BUNDLE bundle = NULL;
 	PROPERTIES endpointProperties = properties_create();
 
-	// Find correct bundle
-//	bundleContext_installBundle(admin->context, "path/to/bundle.zip", &bundle);
-//	bundle_start(bundle, 0);
+	HASH_MAP_ITERATOR iter = hashMapIterator_create(reference->registration->properties);
+	while (hashMapIterator_hasNext(iter)) {
+		HASH_MAP_ENTRY entry = hashMapIterator_nextEntry(iter);
+		char *key = (char *) hashMapEntry_getKey(entry);
+		char *value = (char *) hashMapEntry_getValue(entry);
 
+		properties_set(endpointProperties, key, value);
+	}
+	char *serviceId = (char *) hashMap_remove(endpointProperties, (void *) SERVICE_ID);
+	properties_set(endpointProperties, (char *) OBJECTCLASS, interface);
+	properties_set(endpointProperties, (char *) ENDPOINT_SERVICE_ID, serviceId);
+	char *uuid = NULL;
+	remoteServiceAdmin_getUUID(admin, &uuid);
+	properties_set(endpointProperties, (char *) ENDPOINT_FRAMEWORK_UUID, uuid);
 	char *service = "/services/example";
 	properties_set(endpointProperties, (char *) SERVICE_LOCATION, apr_pstrdup(admin->pool, service));
 
 	endpoint_description_t endpointDescription = NULL;
-	remoteServiceAdmin_createEndpointDescription(admin, reference->registration->properties, endpointProperties, &endpointDescription);
+	remoteServiceAdmin_createEndpointDescription(admin, reference->registration->properties, endpointProperties, interface, &endpointDescription);
 	exportRegistration_setEndpointDescription(registration, endpointDescription);
 
 	return status;
 }
 
-celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_t admin, PROPERTIES serviceProperties, PROPERTIES endpointProperties, endpoint_description_t *description) {
+celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_t admin, PROPERTIES serviceProperties,
+		PROPERTIES endpointProperties, char *interface, endpoint_description_t *description) {
 	celix_status_t status = CELIX_SUCCESS;
 
-//	*description = apr_palloc(admin->pool, sizeof(*description));
-	*description = malloc(sizeof(*description));
+	*description = apr_palloc(admin->pool, sizeof(*description));
+//	*description = malloc(sizeof(*description));
 	if (!*description) {
 		status = CELIX_ENOMEM;
 	} else {
-		(*description)->properties = endpointProperties;
-		(*description)->serviceId = apr_atoi64(properties_get(serviceProperties, (char *) SERVICE_ID));
-		(*description)->id = properties_get(endpointProperties, (char *) SERVICE_LOCATION);
-		(*description)->service = strdup(properties_get(serviceProperties, (char *) OBJECTCLASS));
+		char *uuid = NULL;
+		status = bundleContext_getProperty(admin->context, ENDPOINT_FRAMEWORK_UUID, &uuid);
+		if (status == CELIX_SUCCESS) {
+			(*description)->properties = endpointProperties;
+			(*description)->frameworkUUID = uuid;
+			(*description)->serviceId = apr_atoi64(properties_get(serviceProperties, (char *) SERVICE_ID));
+			(*description)->id = properties_get(endpointProperties, (char *) SERVICE_LOCATION);
+			(*description)->service = interface;
+		}
 	}
 
 	return status;
@@ -247,6 +263,7 @@ celix_status_t remoteServiceAdmin_import
 	}
 	arrayList_add(importedRegs, *registration);
 
+	importRegistration_open(*registration);
 	importRegistration_startTracking(*registration);
 
 	return status;
@@ -275,3 +292,20 @@ celix_status_t importReference_getImport
 	celix_status_t status = CELIX_SUCCESS;
 	return status;
 }
+
+celix_status_t remoteServiceAdmin_getUUID(remote_service_admin_t rsa, char **uuidStr) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	status = bundleContext_getProperty(rsa->context, ENDPOINT_FRAMEWORK_UUID, uuidStr);
+	if (status == CELIX_SUCCESS) {
+		if (*uuidStr == NULL) {
+			apr_uuid_t uuid;
+			apr_uuid_get(&uuid);
+			*uuidStr = apr_palloc(rsa->pool, APR_UUID_FORMATTED_LENGTH + 1);
+			apr_uuid_format(*uuidStr, &uuid);
+			setenv(ENDPOINT_FRAMEWORK_UUID, *uuidStr, 1);
+		}
+	}
+
+	return status;
+}

Modified: incubator/celix/trunk/remote_services/remote_service_admin/public/include/remote_constants.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/remote_service_admin/public/include/remote_constants.h?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/remote_services/remote_service_admin/public/include/remote_constants.h (original)
+++ incubator/celix/trunk/remote_services/remote_service_admin/public/include/remote_constants.h Mon Nov  7 18:06:25 2011
@@ -10,6 +10,7 @@
 
 static const char * const SERVICE_EXPORTED_INTERFACES = "service.exported.interfaces";
 static const char * const ENDPOINT_FRAMEWORK_UUID = "endpoint.framework.uuid";
+static const char * const ENDPOINT_SERVICE_ID = "endpoint.service.id";
 
 static const char * const SERVICE_LOCATION = "service.location";
 

Modified: incubator/celix/trunk/remote_services/remote_service_admin/public/include/remote_service_admin.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/remote_service_admin/public/include/remote_service_admin.h?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/remote_services/remote_service_admin/public/include/remote_service_admin.h (original)
+++ incubator/celix/trunk/remote_services/remote_service_admin/public/include/remote_service_admin.h Mon Nov  7 18:06:25 2011
@@ -38,7 +38,7 @@ struct remote_service_admin_service {
 
 	celix_status_t (*importRegistration_close)(import_registration_t registration);
 	celix_status_t (*importRegistration_getException)(import_registration_t registration);
-	celix_status_t (*importRegistration_getImportReference)(import_registration_t registration);
+	celix_status_t (*importRegistration_getImportReference)(import_registration_t registration, import_reference_t *reference);
 
 };
 

Modified: incubator/celix/trunk/remote_services/topology_manager/private/include/topology_manager.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/topology_manager/private/include/topology_manager.h?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/remote_services/topology_manager/private/include/topology_manager.h (original)
+++ incubator/celix/trunk/remote_services/topology_manager/private/include/topology_manager.h Mon Nov  7 18:06:25 2011
@@ -28,4 +28,7 @@ celix_status_t topologyManager_importSer
 celix_status_t topologyManager_exportService(topology_manager_t manager, SERVICE_REFERENCE reference);
 celix_status_t topologyManager_removeService(topology_manager_t manager, SERVICE_REFERENCE reference);
 
+celix_status_t topologyManager_listenerAdded(void *handle, ARRAY_LIST listeners);
+celix_status_t topologyManager_listenerRemoved(void *handle, ARRAY_LIST listeners);
+
 #endif /* TOPOLOGY_MANAGER_H_ */

Modified: incubator/celix/trunk/remote_services/topology_manager/private/src/activator.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/remote_services/topology_manager/private/src/activator.c?rev=1198847&r1=1198846&r2=1198847&view=diff
==============================================================================
--- incubator/celix/trunk/remote_services/topology_manager/private/src/activator.c (original)
+++ incubator/celix/trunk/remote_services/topology_manager/private/src/activator.c Mon Nov  7 18:06:25 2011
@@ -8,6 +8,10 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <apr_strings.h>
+#include <apr_uuid.h>
+
+#include "constants.h"
 #include "headers.h"
 #include "bundle_activator.h"
 #include "service_tracker.h"
@@ -15,6 +19,8 @@
 
 #include "topology_manager.h"
 #include "endpoint_listener.h"
+#include "remote_constants.h"
+#include "listener_hook_service.h"
 
 struct activator {
 	apr_pool_t *pool;
@@ -26,10 +32,12 @@ struct activator {
 	SERVICE_LISTENER serviceListener;
 
 	SERVICE_REGISTRATION endpointListenerService;
+	SERVICE_REGISTRATION hook;
 };
 
 celix_status_t bundleActivator_createRSATracker(struct activator *activator, SERVICE_TRACKER *tracker);
 celix_status_t bundleActivator_createServiceListener(struct activator *activator, SERVICE_LISTENER *listener);
+celix_status_t topologyManagerActivator_getUUID(struct activator *activator, char **uuidStr);
 
 celix_status_t bundleActivator_create(BUNDLE_CONTEXT context, void **userData) {
 	celix_status_t status = CELIX_SUCCESS;
@@ -100,7 +108,21 @@ celix_status_t bundleActivator_start(voi
 	endpointListener->handle = activator->manager;
 	endpointListener->endpointAdded = topologyManager_endpointAdded;
 	endpointListener->endpointRemoved = topologyManager_endpointRemoved;
-	bundleContext_registerService(context, (char *) endpoint_listener_service, endpointListener, NULL, &activator->endpointListenerService);
+
+	PROPERTIES props = properties_create();
+	char *uuid = NULL;
+	topologyManagerActivator_getUUID(activator, &uuid);
+	char *scope = apr_pstrcat(pool, "(&(", OBJECTCLASS, "=*)(!(", ENDPOINT_FRAMEWORK_UUID, "=", uuid, ")))", NULL);
+	properties_set(props, (char *) ENDPOINT_LISTENER_SCOPE, scope);
+
+	bundleContext_registerService(context, (char *) endpoint_listener_service, endpointListener, props, &activator->endpointListenerService);
+
+	listener_hook_service_t hook = apr_palloc(pool, sizeof(*hook));
+	hook->handle = activator->manager;
+	hook->added = topologyManager_listenerAdded;
+	hook->removed = topologyManager_listenerRemoved;
+
+	bundleContext_registerService(context, (char *) listener_hook_service_name, hook, NULL, &activator->hook);
 
 	bundleContext_addServiceListener(context, activator->serviceListener, NULL);
 	serviceTracker_open(activator->remoteServiceAdminTracker);
@@ -112,9 +134,10 @@ celix_status_t bundleActivator_stop(void
 	celix_status_t status = CELIX_SUCCESS;
 	struct activator *activator = userData;
 
-	serviceRegistration_unregister(activator->endpointListenerService);
 	serviceTracker_close(activator->remoteServiceAdminTracker);
 	bundleContext_removeServiceListener(context, activator->serviceListener);
+	serviceRegistration_unregister(activator->hook);
+	serviceRegistration_unregister(activator->endpointListenerService);
 
 	return status;
 }
@@ -123,3 +146,22 @@ celix_status_t bundleActivator_destroy(v
 	celix_status_t status = CELIX_SUCCESS;
 	return status;
 }
+
+celix_status_t topologyManagerActivator_getUUID(struct activator *activator, char **uuidStr) {
+	celix_status_t status = CELIX_SUCCESS;
+	apr_pool_t *pool = NULL;
+	apr_pool_create(&pool, activator->pool);
+
+	status = bundleContext_getProperty(activator->context, ENDPOINT_FRAMEWORK_UUID, uuidStr);
+	if (status == CELIX_SUCCESS) {
+		if (*uuidStr == NULL) {
+			apr_uuid_t uuid;
+			apr_uuid_get(&uuid);
+			*uuidStr = apr_palloc(pool, APR_UUID_FORMATTED_LENGTH + 1);
+			apr_uuid_format(*uuidStr, &uuid);
+			setenv(ENDPOINT_FRAMEWORK_UUID, *uuidStr, 1);
+		}
+	}
+
+	return status;
+}