You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2018/01/24 18:30:31 UTC

[1/8] celix git commit: CELIX-417: Refactors cmake usage of pubsub and rsa. Started with installing exported targets

Repository: celix
Updated Branches:
  refs/heads/feature/CELIX-417-cmake-refactor ac0d0d771 -> 81804e001


http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/rsa_spi/include/remote_endpoint.h
----------------------------------------------------------------------
diff --git a/remote_services/rsa_spi/include/remote_endpoint.h b/remote_services/rsa_spi/include/remote_endpoint.h
new file mode 100644
index 0000000..ab80abb
--- /dev/null
+++ b/remote_services/rsa_spi/include/remote_endpoint.h
@@ -0,0 +1,44 @@
+/**
+ *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.
+ */
+/*
+ * remote_endpoint.h
+ *
+ *  \date       Oct 7, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_ENDPOINT_H_
+#define REMOTE_ENDPOINT_H_
+
+#define OSGI_RSA_REMOTE_ENDPOINT "remote_endpoint"
+
+typedef struct remote_endpoint remote_endpoint_t;
+typedef remote_endpoint_t* remote_endpoint_pt;
+
+struct remote_endpoint_service {
+	remote_endpoint_pt endpoint;
+	celix_status_t (*setService)(remote_endpoint_pt endpoint, void *service);
+	celix_status_t (*handleRequest)(remote_endpoint_pt endpoint, char *data, char **reply);
+};
+
+typedef struct remote_endpoint_service *remote_endpoint_service_pt;
+
+
+#endif /* REMOTE_ENDPOINT_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/rsa_spi/include/remote_endpoint_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/rsa_spi/include/remote_endpoint_impl.h b/remote_services/rsa_spi/include/remote_endpoint_impl.h
new file mode 100644
index 0000000..3782d62
--- /dev/null
+++ b/remote_services/rsa_spi/include/remote_endpoint_impl.h
@@ -0,0 +1,38 @@
+/**
+ *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.
+ */
+/*
+ * remote_endpoint_impl.h
+ *
+ *  \date       Oct 11, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_ENDPOINT_IMPL_H_
+#define REMOTE_ENDPOINT_IMPL_H_
+
+#include "remote_endpoint.h"
+#include "celix_threads.h"
+
+struct remote_endpoint {
+	celix_thread_mutex_t serviceLock;
+	void *service;
+};
+
+#endif /* REMOTE_ENDPOINT_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/rsa_spi/include/remote_proxy.h
----------------------------------------------------------------------
diff --git a/remote_services/rsa_spi/include/remote_proxy.h b/remote_services/rsa_spi/include/remote_proxy.h
new file mode 100644
index 0000000..4c3f5c3
--- /dev/null
+++ b/remote_services/rsa_spi/include/remote_proxy.h
@@ -0,0 +1,76 @@
+/**
+ *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.
+ */
+/*
+ * remote_proxy.h
+ *
+ *  \date       Oct 13, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_PROXY_H_
+#define REMOTE_PROXY_H_
+
+#include "endpoint_listener.h"
+#include "remote_service_admin.h"
+
+#define OSGI_RSA_REMOTE_PROXY_FACTORY 	"remote_proxy_factory"
+#define OSGI_RSA_REMOTE_PROXY_TIMEOUT   "remote_proxy_timeout"
+
+typedef celix_status_t (*sendToHandle)(remote_service_admin_pt remote_service_admin_ptr, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus);
+typedef celix_status_t (*createProxyService)(void *handle, endpoint_description_pt endpointDescription, remote_service_admin_pt rsa, sendToHandle sendToCallback, properties_pt properties, void **service);
+typedef celix_status_t (*destroyProxyService)(void *handle, void *service);
+
+typedef struct remote_proxy_factory *remote_proxy_factory_pt;
+typedef struct remote_proxy_factory_service *remote_proxy_factory_service_pt;
+
+struct remote_proxy_factory {
+	bundle_context_pt context_ptr;
+	char *service;
+
+	remote_proxy_factory_service_pt remote_proxy_factory_service_ptr;
+	properties_pt properties;
+	service_registration_pt registration;
+
+	hash_map_pt proxy_instances;
+
+	void *handle;
+
+	createProxyService create_proxy_service_ptr;
+	destroyProxyService destroy_proxy_service_ptr;
+};
+
+struct remote_proxy_factory_service {
+	remote_proxy_factory_pt factory;
+	celix_status_t (*registerProxyService)(remote_proxy_factory_pt proxyFactoryService, endpoint_description_pt endpoint, remote_service_admin_pt remote_service_admin_ptr, sendToHandle callback);
+	celix_status_t (*unregisterProxyService)(remote_proxy_factory_pt proxyFactoryService, endpoint_description_pt endpoint);
+};
+
+celix_status_t remoteProxyFactory_create(bundle_context_pt context, char *service, void *handle,
+		createProxyService create, destroyProxyService destroy,
+		remote_proxy_factory_pt *remote_proxy_factory_ptr);
+celix_status_t remoteProxyFactory_destroy(remote_proxy_factory_pt *remote_proxy_factory_ptr);
+
+celix_status_t remoteProxyFactory_register(remote_proxy_factory_pt remote_proxy_factory_ptr);
+celix_status_t remoteProxyFactory_unregister(remote_proxy_factory_pt remote_proxy_factory_ptr);
+
+
+
+
+#endif /* REMOTE_PROXY_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/rsa_spi/include/remote_service_admin.h
----------------------------------------------------------------------
diff --git a/remote_services/rsa_spi/include/remote_service_admin.h b/remote_services/rsa_spi/include/remote_service_admin.h
new file mode 100644
index 0000000..cc7fd98
--- /dev/null
+++ b/remote_services/rsa_spi/include/remote_service_admin.h
@@ -0,0 +1,73 @@
+/**
+ *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.
+ */
+/*
+ * remote_service_admin.h
+ *
+ *  \date       Sep 30, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_SERVICE_ADMIN_H_
+#define REMOTE_SERVICE_ADMIN_H_
+
+#include "endpoint_listener.h"
+#include "service_reference.h"
+#include "export_registration.h"
+#include "import_registration.h"
+
+#define OSGI_RSA_REMOTE_SERVICE_ADMIN "remote_service_admin"
+
+typedef struct import_registration_factory import_registration_factory_t;
+typedef import_registration_factory_t* import_registration_factory_pt;
+
+typedef struct remote_service_admin remote_service_admin_t;
+typedef remote_service_admin_t* remote_service_admin_pt;
+
+struct remote_service_admin_service {
+	remote_service_admin_pt admin;
+	celix_status_t (*exportService)(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations);
+	celix_status_t (*removeExportedService)(remote_service_admin_pt admin, export_registration_pt registration);
+	celix_status_t (*getExportedServices)(remote_service_admin_pt admin, array_list_pt *services);
+	celix_status_t (*getImportedEndpoints)(remote_service_admin_pt admin, array_list_pt *services);
+	celix_status_t (*importService)(remote_service_admin_pt admin, endpoint_description_pt endpoint, import_registration_pt *registration);
+
+	celix_status_t (*exportReference_getExportedEndpoint)(export_reference_pt reference, endpoint_description_pt *endpoint);
+	celix_status_t (*exportReference_getExportedService)(export_reference_pt reference, service_reference_pt *service);
+
+	celix_status_t (*exportRegistration_close)(remote_service_admin_pt admin, export_registration_pt registration);
+	celix_status_t (*exportRegistration_getException)(export_registration_pt registration);
+	celix_status_t (*exportRegistration_getExportReference)(export_registration_pt registration, export_reference_pt *reference);
+	celix_status_t (*exportRegistration_freeExportReference)(export_reference_pt *reference);
+	celix_status_t (*exportRegistration_getEndpointDescription)(export_registration_pt registration, endpoint_description_pt endpointDescription);
+
+	celix_status_t (*importReference_getImportedEndpoint)(import_reference_pt reference);
+	celix_status_t (*importReference_getImportedService)(import_reference_pt reference);
+
+	celix_status_t (*importRegistration_close)(remote_service_admin_pt admin, import_registration_pt registration);
+	celix_status_t (*importRegistration_getException)(import_registration_pt registration);
+	celix_status_t (*importRegistration_getImportReference)(import_registration_pt registration, import_reference_pt *reference);
+
+};
+
+typedef struct remote_service_admin_service remote_service_admin_service_t;
+typedef remote_service_admin_service_t* remote_service_admin_service_pt;
+
+
+#endif /* REMOTE_SERVICE_ADMIN_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/topology_manager/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/CMakeLists.txt b/remote_services/topology_manager/CMakeLists.txt
index 568054e..6050229 100644
--- a/remote_services/topology_manager/CMakeLists.txt
+++ b/remote_services/topology_manager/CMakeLists.txt
@@ -28,7 +28,7 @@ if (RSA_TOPOLOGY_MANAGER)
     )
     target_include_directories(rsa_topology_manager PRIVATE src)
     target_include_directories(rsa_topology_manager PUBLIC include)
-    target_link_libraries(rsa_topology_manager PRIVATE Celix::log_helper Celix::rsa_api)
+    target_link_libraries(rsa_topology_manager PRIVATE Celix::log_helper Celix::rsa_spi)
 
     install_bundle(rsa_topology_manager)
 

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt b/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
index eaf0a26..dc5dea5 100644
--- a/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
+++ b/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
@@ -32,4 +32,4 @@ bundle_files(topology_manager_test_bundle
     DESTINATION .
 )
 
-target_link_libraries(topology_manager_test_bundle PRIVATE ${CPPUTEST_LIBRARY} Celix::rsa_api calculator_api)
+target_link_libraries(topology_manager_test_bundle PRIVATE ${CPPUTEST_LIBRARY} Celix::rsa_spi calculator_api)

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/utils/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt
index e0c187f..1826902 100644
--- a/utils/CMakeLists.txt
+++ b/utils/CMakeLists.txt
@@ -19,7 +19,8 @@ set(MEMSTREAM_SOURCES )
 set(MEMSTREAM_INCLUDES )
 if (APPLE OR ANDROID)
     set(MEMSTREAM_SOURCES src/memstream/open_memstream.c  src/memstream/fmemopen.c)
-    set(MEMSTREAM_INCLUDE_DIR include/memstream)
+    set(MEMSTREAM_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR}/include/memstream)
+    install(DIRECTORY include/memstream/ DESTINATION include/celix/memstream COMPONENT framework)
 endif()
 
 add_library(utils SHARED
@@ -41,7 +42,11 @@ if (ANDROID)
     target_compile_definitions(utils PRIVATE -DUSE_FILE32API)
 endif ()
 
-target_include_directories(utils PUBLIC include ${MEMSTREAM_INCLUDE_DIR})
+target_include_directories(utils PUBLIC
+        $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
+        $<BUILD_INTERFACE:${MEMSTREAM_INCLUDE_DIR}>
+        $<INSTALL_INTERFACE:include/celix>
+)
 target_include_directories(utils PRIVATE src)
 set_target_properties(utils PROPERTIES "SOVERSION" 2)
 
@@ -51,7 +56,9 @@ ELSEIF(ANDROID)
     target_link_libraries(utils PRIVATE m)
 ENDIF()
 
-install(TARGETS utils DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT framework)
+install(TARGETS utils EXPORT celix DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT framework)
+install(DIRECTORY include/ DESTINATION include/celix COMPONENT framework
+        PATTERN memstream* EXCLUDE)
 
 #Alias setup to match external usage
 add_library(Celix::utils ALIAS utils)


[5/8] celix git commit: CELIX-417: Refactors cmake usage of pubsub and rsa. Started with installing exported targets

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_zmq/src/topic_subscription.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/src/topic_subscription.c b/pubsub/pubsub_admin_zmq/src/topic_subscription.c
new file mode 100644
index 0000000..0e7a794
--- /dev/null
+++ b/pubsub/pubsub_admin_zmq/src/topic_subscription.c
@@ -0,0 +1,732 @@
+/**
+ *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.
+ */
+/*
+ * topic_subscription.c
+ *
+ *  \date       Oct 2, 2015
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include "topic_subscription.h"
+#include <czmq.h>
+/* The following undefs prevent the collision between:
+ * - sys/syslog.h (which is included within czmq)
+ * - celix/dfi/dfi_log_util.h
+ */
+#undef LOG_DEBUG
+#undef LOG_WARNING
+#undef LOG_INFO
+#undef LOG_WARNING
+
+#include <string.h>
+#include <stdlib.h>
+#include <signal.h>
+
+#include "utils.h"
+#include "celix_errno.h"
+#include "constants.h"
+#include "version.h"
+
+#include "subscriber.h"
+#include "publisher.h"
+#include "pubsub_utils.h"
+
+#ifdef BUILD_WITH_ZMQ_SECURITY
+#include "zmq_crypto.h"
+
+#define MAX_CERT_PATH_LENGTH 512
+#endif
+
+#define POLL_TIMEOUT  	250
+#define ZMQ_POLL_TIMEOUT_MS_ENV 	"ZMQ_POLL_TIMEOUT_MS"
+
+struct topic_subscription{
+
+	zsock_t* zmq_socket;
+	zcert_t * zmq_cert;
+	zcert_t * zmq_pub_cert;
+	pthread_mutex_t socket_lock;
+	service_tracker_pt tracker;
+	array_list_pt sub_ep_list;
+	celix_thread_t recv_thread;
+	bool running;
+	celix_thread_mutex_t ts_lock;
+	bundle_context_pt context;
+
+	pubsub_serializer_service_t *serializer;
+
+	hash_map_pt servicesMap; // key = service, value = msg types map
+
+	celix_thread_mutex_t pendingConnections_lock;
+	array_list_pt pendingConnections;
+
+	array_list_pt pendingDisconnections;
+	celix_thread_mutex_t pendingDisconnections_lock;
+
+	unsigned int nrSubscribers;
+};
+
+typedef struct complete_zmq_msg{
+	zframe_t* header;
+	zframe_t* payload;
+}* complete_zmq_msg_pt;
+
+typedef struct mp_handle{
+	hash_map_pt svc_msg_db;
+	hash_map_pt rcv_msg_map;
+}* mp_handle_pt;
+
+typedef struct msg_map_entry{
+	bool retain;
+	void* msgInst;
+}* msg_map_entry_pt;
+
+static celix_status_t topicsub_subscriberTracked(void * handle, service_reference_pt reference, void * service);
+static celix_status_t topicsub_subscriberUntracked(void * handle, service_reference_pt reference, void * service);
+static void* zmq_recv_thread_func(void* arg);
+static bool checkVersion(version_pt msgVersion,pubsub_msg_header_pt hdr);
+static void sigusr1_sighandler(int signo);
+static int pubsub_localMsgTypeIdForMsgType(void* handle, const char* msgType, unsigned int* msgTypeId);
+static int pubsub_getMultipart(void *handle, unsigned int msgTypeId, bool retain, void **part);
+static mp_handle_pt create_mp_handle(hash_map_pt svc_msg_db,array_list_pt rcv_msg_list);
+static void destroy_mp_handle(mp_handle_pt mp_handle);
+static void connectPendingPublishers(topic_subscription_pt sub);
+static void disconnectPendingPublishers(topic_subscription_pt sub);
+
+celix_status_t pubsub_topicSubscriptionCreate(bundle_context_pt bundle_context, char* scope, char* topic, pubsub_serializer_service_t *best_serializer, topic_subscription_pt* out){
+	celix_status_t status = CELIX_SUCCESS;
+
+#ifdef BUILD_WITH_ZMQ_SECURITY
+	char* keys_bundle_dir = pubsub_getKeysBundleDir(bundle_context);
+	if (keys_bundle_dir == NULL){
+		return CELIX_SERVICE_EXCEPTION;
+	}
+
+	const char* keys_file_path = NULL;
+	const char* keys_file_name = NULL;
+	bundleContext_getProperty(bundle_context, PROPERTY_KEYS_FILE_PATH, &keys_file_path);
+	bundleContext_getProperty(bundle_context, PROPERTY_KEYS_FILE_NAME, &keys_file_name);
+
+	char sub_cert_path[MAX_CERT_PATH_LENGTH];
+	char pub_cert_path[MAX_CERT_PATH_LENGTH];
+
+	//certificate path ".cache/bundle{id}/version0.0/./META-INF/keys/subscriber/private/sub_{topic}.key.enc"
+	snprintf(sub_cert_path, MAX_CERT_PATH_LENGTH, "%s/META-INF/keys/subscriber/private/sub_%s.key.enc", keys_bundle_dir, topic);
+	snprintf(pub_cert_path, MAX_CERT_PATH_LENGTH, "%s/META-INF/keys/publisher/public/pub_%s.pub", keys_bundle_dir, topic);
+	free(keys_bundle_dir);
+
+	printf("PSA_ZMQ_PSA_ZMQ_TS: Loading subscriber key '%s'\n", sub_cert_path);
+	printf("PSA_ZMQ_PSA_ZMQ_TS: Loading publisher key '%s'\n", pub_cert_path);
+
+	zcert_t* sub_cert = get_zcert_from_encoded_file((char *) keys_file_path, (char *) keys_file_name, sub_cert_path);
+	if (sub_cert == NULL){
+		printf("PSA_ZMQ_PSA_ZMQ_TS: Cannot load key '%s'\n", sub_cert_path);
+		return CELIX_SERVICE_EXCEPTION;
+	}
+
+	zcert_t* pub_cert = zcert_load(pub_cert_path);
+	if (pub_cert == NULL){
+		zcert_destroy(&sub_cert);
+		printf("PSA_ZMQ_PSA_ZMQ_TS: Cannot load key '%s'\n", pub_cert_path);
+		return CELIX_SERVICE_EXCEPTION;
+	}
+
+	const char* pub_key = zcert_public_txt(pub_cert);
+#endif
+
+	zsock_t* zmq_s = zsock_new (ZMQ_SUB);
+	if(zmq_s==NULL){
+#ifdef BUILD_WITH_ZMQ_SECURITY
+		zcert_destroy(&sub_cert);
+		zcert_destroy(&pub_cert);
+#endif
+
+		return CELIX_SERVICE_EXCEPTION;
+	}
+
+#ifdef BUILD_WITH_ZMQ_SECURITY
+	zcert_apply (sub_cert, zmq_s);
+	zsock_set_curve_serverkey (zmq_s, pub_key); //apply key of publisher to socket of subscriber
+#endif
+
+	if(strcmp(topic,PUBSUB_ANY_SUB_TOPIC)==0){
+		zsock_set_subscribe (zmq_s, "");
+	}
+	else{
+		zsock_set_subscribe (zmq_s, topic);
+	}
+
+	topic_subscription_pt ts = (topic_subscription_pt) calloc(1,sizeof(*ts));
+	ts->context = bundle_context;
+	ts->zmq_socket = zmq_s;
+	ts->running = false;
+	ts->nrSubscribers = 0;
+	ts->serializer = best_serializer;
+
+#ifdef BUILD_WITH_ZMQ_SECURITY
+	ts->zmq_cert = sub_cert;
+	ts->zmq_pub_cert = pub_cert;
+#endif
+
+	celixThreadMutex_create(&ts->socket_lock, NULL);
+	celixThreadMutex_create(&ts->ts_lock,NULL);
+	arrayList_create(&ts->sub_ep_list);
+	ts->servicesMap = hashMap_create(NULL, NULL, NULL, NULL);
+
+	arrayList_create(&ts->pendingConnections);
+	arrayList_create(&ts->pendingDisconnections);
+	celixThreadMutex_create(&ts->pendingConnections_lock, NULL);
+	celixThreadMutex_create(&ts->pendingDisconnections_lock, NULL);
+
+	char filter[128];
+	memset(filter,0,128);
+	if(strncmp(PUBSUB_SUBSCRIBER_SCOPE_DEFAULT,scope,strlen(PUBSUB_SUBSCRIBER_SCOPE_DEFAULT)) == 0) {
+		// default scope, means that subscriber has not defined a scope property
+		snprintf(filter, 128, "(&(%s=%s)(%s=%s))",
+				(char*) OSGI_FRAMEWORK_OBJECTCLASS, PUBSUB_SUBSCRIBER_SERVICE_NAME,
+				PUBSUB_SUBSCRIBER_TOPIC,topic);
+
+	} else {
+		snprintf(filter, 128, "(&(%s=%s)(%s=%s)(%s=%s))",
+				(char*) OSGI_FRAMEWORK_OBJECTCLASS, PUBSUB_SUBSCRIBER_SERVICE_NAME,
+				PUBSUB_SUBSCRIBER_TOPIC,topic,
+				PUBSUB_SUBSCRIBER_SCOPE,scope);
+	}
+	service_tracker_customizer_pt customizer = NULL;
+	status += serviceTrackerCustomizer_create(ts,NULL,topicsub_subscriberTracked,NULL,topicsub_subscriberUntracked,&customizer);
+	status += serviceTracker_createWithFilter(bundle_context, filter, customizer, &ts->tracker);
+
+	struct sigaction actions;
+	memset(&actions, 0, sizeof(actions));
+	sigemptyset(&actions.sa_mask);
+	actions.sa_flags = 0;
+	actions.sa_handler = sigusr1_sighandler;
+
+	sigaction(SIGUSR1,&actions,NULL);
+
+	*out=ts;
+
+	return status;
+}
+
+celix_status_t pubsub_topicSubscriptionDestroy(topic_subscription_pt ts){
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&ts->ts_lock);
+
+	ts->running = false;
+	serviceTracker_destroy(ts->tracker);
+	arrayList_clear(ts->sub_ep_list);
+	arrayList_destroy(ts->sub_ep_list);
+	/* TODO: Destroy all the serializer maps? */
+	hashMap_destroy(ts->servicesMap,false,false);
+
+	celixThreadMutex_lock(&ts->pendingConnections_lock);
+	arrayList_destroy(ts->pendingConnections);
+	celixThreadMutex_unlock(&ts->pendingConnections_lock);
+	celixThreadMutex_destroy(&ts->pendingConnections_lock);
+
+	celixThreadMutex_lock(&ts->pendingDisconnections_lock);
+	arrayList_destroy(ts->pendingDisconnections);
+	celixThreadMutex_unlock(&ts->pendingDisconnections_lock);
+	celixThreadMutex_destroy(&ts->pendingDisconnections_lock);
+
+	celixThreadMutex_unlock(&ts->ts_lock);
+
+	celixThreadMutex_lock(&ts->socket_lock);
+	zsock_destroy(&(ts->zmq_socket));
+#ifdef BUILD_WITH_ZMQ_SECURITY
+	zcert_destroy(&(ts->zmq_cert));
+	zcert_destroy(&(ts->zmq_pub_cert));
+#endif
+	celixThreadMutex_unlock(&ts->socket_lock);
+	celixThreadMutex_destroy(&ts->socket_lock);
+
+	celixThreadMutex_destroy(&ts->ts_lock);
+
+	free(ts);
+
+	return status;
+}
+
+celix_status_t pubsub_topicSubscriptionStart(topic_subscription_pt ts){
+	celix_status_t status = CELIX_SUCCESS;
+
+	status = serviceTracker_open(ts->tracker);
+
+	ts->running = true;
+
+	if(status==CELIX_SUCCESS){
+		status=celixThread_create(&ts->recv_thread,NULL,zmq_recv_thread_func,ts);
+	}
+
+	return status;
+}
+
+celix_status_t pubsub_topicSubscriptionStop(topic_subscription_pt ts){
+	celix_status_t status = CELIX_SUCCESS;
+
+	ts->running = false;
+
+	pthread_kill(ts->recv_thread.thread,SIGUSR1);
+
+	celixThread_join(ts->recv_thread,NULL);
+
+	status = serviceTracker_close(ts->tracker);
+
+	return status;
+}
+
+celix_status_t pubsub_topicSubscriptionConnectPublisher(topic_subscription_pt ts, char* pubURL){
+	celix_status_t status = CELIX_SUCCESS;
+	celixThreadMutex_lock(&ts->socket_lock);
+	if(!zsock_is(ts->zmq_socket) || zsock_connect(ts->zmq_socket,"%s",pubURL) != 0){
+		status = CELIX_SERVICE_EXCEPTION;
+	}
+	celixThreadMutex_unlock(&ts->socket_lock);
+
+	return status;
+}
+
+celix_status_t pubsub_topicSubscriptionAddConnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL) {
+	celix_status_t status = CELIX_SUCCESS;
+	char *url = strdup(pubURL);
+	celixThreadMutex_lock(&ts->pendingConnections_lock);
+	arrayList_add(ts->pendingConnections, url);
+	celixThreadMutex_unlock(&ts->pendingConnections_lock);
+	return status;
+}
+
+celix_status_t pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL) {
+	celix_status_t status = CELIX_SUCCESS;
+	char *url = strdup(pubURL);
+	celixThreadMutex_lock(&ts->pendingDisconnections_lock);
+	arrayList_add(ts->pendingDisconnections, url);
+	celixThreadMutex_unlock(&ts->pendingDisconnections_lock);
+	return status;
+}
+
+celix_status_t pubsub_topicSubscriptionDisconnectPublisher(topic_subscription_pt ts, char* pubURL){
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&ts->socket_lock);
+	if(!zsock_is(ts->zmq_socket) || zsock_disconnect(ts->zmq_socket,"%s",pubURL) != 0){
+		status = CELIX_SERVICE_EXCEPTION;
+	}
+	celixThreadMutex_unlock(&ts->socket_lock);
+
+	return status;
+}
+
+celix_status_t pubsub_topicSubscriptionAddSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP){
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&ts->ts_lock);
+	arrayList_add(ts->sub_ep_list,subEP);
+	celixThreadMutex_unlock(&ts->ts_lock);
+
+	return status;
+
+}
+
+celix_status_t pubsub_topicIncreaseNrSubscribers(topic_subscription_pt ts) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&ts->ts_lock);
+	ts->nrSubscribers++;
+	celixThreadMutex_unlock(&ts->ts_lock);
+
+	return status;
+}
+
+celix_status_t pubsub_topicSubscriptionRemoveSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP){
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&ts->ts_lock);
+	arrayList_removeElement(ts->sub_ep_list,subEP);
+	celixThreadMutex_unlock(&ts->ts_lock);
+
+	return status;
+}
+
+celix_status_t pubsub_topicDecreaseNrSubscribers(topic_subscription_pt ts) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&ts->ts_lock);
+	ts->nrSubscribers--;
+	celixThreadMutex_unlock(&ts->ts_lock);
+
+	return status;
+}
+
+unsigned int pubsub_topicGetNrSubscribers(topic_subscription_pt ts) {
+	return ts->nrSubscribers;
+}
+
+array_list_pt pubsub_topicSubscriptionGetSubscribersList(topic_subscription_pt sub){
+	return sub->sub_ep_list;
+}
+
+static celix_status_t topicsub_subscriberTracked(void * handle, service_reference_pt reference, void * service){
+	celix_status_t status = CELIX_SUCCESS;
+	topic_subscription_pt ts = handle;
+
+	celixThreadMutex_lock(&ts->ts_lock);
+	if (!hashMap_containsKey(ts->servicesMap, service)) {
+		bundle_pt bundle = NULL;
+		hash_map_pt msgTypes = NULL;
+
+		serviceReference_getBundle(reference, &bundle);
+
+		if(ts->serializer != NULL && bundle!=NULL){
+			ts->serializer->createSerializerMap(ts->serializer->handle,bundle,&msgTypes);
+			if(msgTypes != NULL){
+				hashMap_put(ts->servicesMap, service, msgTypes);
+				printf("PSA_ZMQ_TS: New subscriber registered.\n");
+			}
+		}
+		else{
+			printf("PSA_ZMQ_TS: Cannot register new subscriber.\n");
+			status = CELIX_SERVICE_EXCEPTION;
+		}
+	}
+	celixThreadMutex_unlock(&ts->ts_lock);
+
+	return status;
+}
+
+static celix_status_t topicsub_subscriberUntracked(void * handle, service_reference_pt reference, void * service){
+	celix_status_t status = CELIX_SUCCESS;
+	topic_subscription_pt ts = handle;
+
+	celixThreadMutex_lock(&ts->ts_lock);
+	if (hashMap_containsKey(ts->servicesMap, service)) {
+		hash_map_pt msgTypes = hashMap_remove(ts->servicesMap, service);
+		if(msgTypes!=NULL && ts->serializer!=NULL){
+			ts->serializer->destroySerializerMap(ts->serializer->handle,msgTypes);
+			printf("PSA_ZMQ_TS: Subscriber unregistered.\n");
+		}
+		else{
+			printf("PSA_ZMQ_TS: Cannot unregister subscriber.\n");
+			status = CELIX_SERVICE_EXCEPTION;
+		}
+	}
+	celixThreadMutex_unlock(&ts->ts_lock);
+
+	return status;
+}
+
+
+static void process_msg(topic_subscription_pt sub,array_list_pt msg_list){
+
+	pubsub_msg_header_pt first_msg_hdr = (pubsub_msg_header_pt)zframe_data(((complete_zmq_msg_pt)arrayList_get(msg_list,0))->header);
+
+	hash_map_iterator_pt iter = hashMapIterator_create(sub->servicesMap);
+	while (hashMapIterator_hasNext(iter)) {
+		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+		pubsub_subscriber_pt subsvc = hashMapEntry_getKey(entry);
+		hash_map_pt msgTypes = hashMapEntry_getValue(entry);
+
+		pubsub_msg_serializer_t *msgSer = hashMap_get(msgTypes,(void*)(uintptr_t )first_msg_hdr->type);
+		if (msgSer == NULL) {
+			printf("PSA_ZMQ_TS: Primary message %d not supported. NOT sending any part of the whole message.\n",first_msg_hdr->type);
+		}
+		else{
+			void *msgInst = NULL;
+			bool validVersion = checkVersion(msgSer->msgVersion,first_msg_hdr);
+
+			if(validVersion){
+
+				celix_status_t status = msgSer->deserialize(msgSer, (const void *) zframe_data(((complete_zmq_msg_pt)arrayList_get(msg_list,0))->payload), 0, &msgInst);
+
+				if (status == CELIX_SUCCESS) {
+					bool release = true;
+					mp_handle_pt mp_handle = create_mp_handle(msgTypes,msg_list);
+					pubsub_multipart_callbacks_t mp_callbacks;
+					mp_callbacks.handle = mp_handle;
+					mp_callbacks.localMsgTypeIdForMsgType = pubsub_localMsgTypeIdForMsgType;
+					mp_callbacks.getMultipart = pubsub_getMultipart;
+					subsvc->receive(subsvc->handle, msgSer->msgName, first_msg_hdr->type, msgInst, &mp_callbacks, &release);
+
+					if(release){
+						msgSer->freeMsg(msgSer,msgInst); // pubsubSerializer_freeMsg(msgType, msgInst);
+					}
+					if(mp_handle!=NULL){
+						destroy_mp_handle(mp_handle);
+					}
+				}
+				else{
+					printf("PSA_ZMQ_TS: Cannot deserialize msgType %s.\n",msgSer->msgName);
+				}
+
+			}
+			else{
+				int major=0,minor=0;
+				version_getMajor(msgSer->msgVersion,&major);
+				version_getMinor(msgSer->msgVersion,&minor);
+				printf("PSA_ZMQ_TS: Version mismatch for primary message '%s' (have %d.%d, received %u.%u). NOT sending any part of the whole message.\n",
+						msgSer->msgName,major,minor,first_msg_hdr->major,first_msg_hdr->minor);
+			}
+
+		}
+	}
+	hashMapIterator_destroy(iter);
+
+	int i = 0;
+	for(;i<arrayList_size(msg_list);i++){
+		complete_zmq_msg_pt c_msg = arrayList_get(msg_list,i);
+		zframe_destroy(&(c_msg->header));
+		zframe_destroy(&(c_msg->payload));
+		free(c_msg);
+	}
+
+	arrayList_destroy(msg_list);
+
+}
+
+static void* zmq_recv_thread_func(void * arg) {
+	topic_subscription_pt sub = (topic_subscription_pt) arg;
+
+	while (sub->running) {
+
+		celixThreadMutex_lock(&sub->socket_lock);
+
+		zframe_t* headerMsg = zframe_recv(sub->zmq_socket);
+		if (headerMsg == NULL) {
+			if (errno == EINTR) {
+				//It means we got a signal and we have to exit...
+				printf("PSA_ZMQ_TS: header_recv thread for topic got a signal and will exit.\n");
+			} else {
+				perror("PSA_ZMQ_TS: header_recv thread");
+			}
+		}
+		else {
+
+			pubsub_msg_header_pt hdr = (pubsub_msg_header_pt) zframe_data(headerMsg);
+
+			if (zframe_more(headerMsg)) {
+
+				zframe_t* payloadMsg = zframe_recv(sub->zmq_socket);
+				if (payloadMsg == NULL) {
+					if (errno == EINTR) {
+						//It means we got a signal and we have to exit...
+						printf("PSA_ZMQ_TS: payload_recv thread for topic got a signal and will exit.\n");
+					} else {
+						perror("PSA_ZMQ_TS: payload_recv");
+					}
+					zframe_destroy(&headerMsg);
+				} else {
+
+					//Let's fetch all the messages from the socket
+					array_list_pt msg_list = NULL;
+					arrayList_create(&msg_list);
+					complete_zmq_msg_pt firstMsg = calloc(1, sizeof(struct complete_zmq_msg));
+					firstMsg->header = headerMsg;
+					firstMsg->payload = payloadMsg;
+					arrayList_add(msg_list, firstMsg);
+
+					bool more = zframe_more(payloadMsg);
+					while (more) {
+
+						zframe_t* h_msg = zframe_recv(sub->zmq_socket);
+						if (h_msg == NULL) {
+							if (errno == EINTR) {
+								//It means we got a signal and we have to exit...
+								printf("PSA_ZMQ_TS: h_recv thread for topic got a signal and will exit.\n");
+							} else {
+								perror("PSA_ZMQ_TS: h_recv");
+							}
+							break;
+						}
+
+						zframe_t* p_msg = zframe_recv(sub->zmq_socket);
+						if (p_msg == NULL) {
+							if (errno == EINTR) {
+								//It means we got a signal and we have to exit...
+								printf("PSA_ZMQ_TS: p_recv thread for topic got a signal and will exit.\n");
+							} else {
+								perror("PSA_ZMQ_TS: p_recv");
+							}
+							zframe_destroy(&h_msg);
+							break;
+						}
+
+						complete_zmq_msg_pt c_msg = calloc(1, sizeof(struct complete_zmq_msg));
+						c_msg->header = h_msg;
+						c_msg->payload = p_msg;
+						arrayList_add(msg_list, c_msg);
+
+						if (!zframe_more(p_msg)) {
+							more = false;
+						}
+					}
+
+					celixThreadMutex_lock(&sub->ts_lock);
+					process_msg(sub, msg_list);
+					celixThreadMutex_unlock(&sub->ts_lock);
+
+				}
+
+			} //zframe_more(headerMsg)
+			else {
+				free(headerMsg);
+				printf("PSA_ZMQ_TS: received message %u for topic %s without payload!\n", hdr->type, hdr->topic);
+			}
+
+		} // headerMsg != NULL
+		celixThreadMutex_unlock(&sub->socket_lock);
+		connectPendingPublishers(sub);
+		disconnectPendingPublishers(sub);
+	} // while
+
+	return NULL;
+}
+
+static void connectPendingPublishers(topic_subscription_pt sub) {
+	celixThreadMutex_lock(&sub->pendingConnections_lock);
+	while(!arrayList_isEmpty(sub->pendingConnections)) {
+		char * pubEP = arrayList_remove(sub->pendingConnections, 0);
+		pubsub_topicSubscriptionConnectPublisher(sub, pubEP);
+		free(pubEP);
+	}
+	celixThreadMutex_unlock(&sub->pendingConnections_lock);
+}
+
+static void disconnectPendingPublishers(topic_subscription_pt sub) {
+	celixThreadMutex_lock(&sub->pendingDisconnections_lock);
+	while(!arrayList_isEmpty(sub->pendingDisconnections)) {
+		char * pubEP = arrayList_remove(sub->pendingDisconnections, 0);
+		pubsub_topicSubscriptionDisconnectPublisher(sub, pubEP);
+		free(pubEP);
+	}
+	celixThreadMutex_unlock(&sub->pendingDisconnections_lock);
+}
+
+static void sigusr1_sighandler(int signo){
+	printf("PSA_ZMQ_TS: Topic subscription being shut down...\n");
+	return;
+}
+
+static bool checkVersion(version_pt msgVersion,pubsub_msg_header_pt hdr){
+	bool check=false;
+	int major=0,minor=0;
+
+	if(msgVersion!=NULL){
+		version_getMajor(msgVersion,&major);
+		version_getMinor(msgVersion,&minor);
+		if(hdr->major==((unsigned char)major)){ /* Different major means incompatible */
+			check = (hdr->minor>=((unsigned char)minor)); /* Compatible only if the provider has a minor equals or greater (means compatible update) */
+		}
+	}
+
+	return check;
+}
+
+static int pubsub_localMsgTypeIdForMsgType(void* handle, const char* msgType, unsigned int* msgTypeId){
+	*msgTypeId = utils_stringHash(msgType);
+	return 0;
+}
+
+static int pubsub_getMultipart(void *handle, unsigned int msgTypeId, bool retain, void **part){
+
+	if(handle==NULL){
+		*part = NULL;
+		return -1;
+	}
+
+	mp_handle_pt mp_handle = (mp_handle_pt)handle;
+	msg_map_entry_pt entry = hashMap_get(mp_handle->rcv_msg_map, (void*)(uintptr_t) msgTypeId);
+	if(entry!=NULL){
+		entry->retain = retain;
+		*part = entry->msgInst;
+	}
+	else{
+		printf("TP: getMultipart cannot find msg '%u'\n",msgTypeId);
+		*part=NULL;
+		return -2;
+	}
+
+	return 0;
+
+}
+
+static mp_handle_pt create_mp_handle(hash_map_pt svc_msg_db,array_list_pt rcv_msg_list){
+
+	if(arrayList_size(rcv_msg_list)==1){ //Means it's not a multipart message
+		return NULL;
+	}
+
+	mp_handle_pt mp_handle = calloc(1,sizeof(struct mp_handle));
+	mp_handle->svc_msg_db = svc_msg_db;
+	mp_handle->rcv_msg_map = hashMap_create(NULL, NULL, NULL, NULL);
+
+	int i=1; //We skip the first message, it will be handle differently
+	for(;i<arrayList_size(rcv_msg_list);i++){
+		complete_zmq_msg_pt c_msg = (complete_zmq_msg_pt)arrayList_get(rcv_msg_list,i);
+		pubsub_msg_header_pt header = (pubsub_msg_header_pt)zframe_data(c_msg->header);
+
+		pubsub_msg_serializer_t* msgSer = hashMap_get(svc_msg_db, (void*)(uintptr_t)(header->type));
+
+		if (msgSer!= NULL) {
+			void *msgInst = NULL;
+
+			bool validVersion = checkVersion(msgSer->msgVersion,header);
+
+			if(validVersion){
+				celix_status_t status = msgSer->deserialize(msgSer, (const void*)zframe_data(c_msg->payload), 0, &msgInst);
+
+				if(status == CELIX_SUCCESS){
+					msg_map_entry_pt entry = calloc(1,sizeof(struct msg_map_entry));
+					entry->msgInst = msgInst;
+					hashMap_put(mp_handle->rcv_msg_map, (void*)(uintptr_t)header->type,entry);
+				}
+			}
+		}
+	}
+
+	return mp_handle;
+
+}
+
+static void destroy_mp_handle(mp_handle_pt mp_handle){
+
+	hash_map_iterator_pt iter = hashMapIterator_create(mp_handle->rcv_msg_map);
+	while(hashMapIterator_hasNext(iter)){
+		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+		unsigned int msgId = (unsigned int)(uintptr_t)hashMapEntry_getKey(entry);
+		msg_map_entry_pt msgEntry = hashMapEntry_getValue(entry);
+		pubsub_msg_serializer_t* msgSer = hashMap_get(mp_handle->svc_msg_db, (void*)(uintptr_t)msgId);
+
+		if(msgSer!=NULL){
+			if(!msgEntry->retain){
+				msgSer->freeMsg(msgSer->handle,msgEntry->msgInst);
+			}
+		}
+		else{
+			printf("PSA_ZMQ_TS: ERROR: Cannot find messageSerializer for msg %u, so cannot destroy it!\n",msgId);
+		}
+
+		free(msgEntry);
+	}
+	hashMapIterator_destroy(iter);
+
+	hashMap_destroy(mp_handle->rcv_msg_map,false,false);
+	free(mp_handle);
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_zmq/src/topic_subscription.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/src/topic_subscription.h b/pubsub/pubsub_admin_zmq/src/topic_subscription.h
new file mode 100644
index 0000000..7267103
--- /dev/null
+++ b/pubsub/pubsub_admin_zmq/src/topic_subscription.h
@@ -0,0 +1,60 @@
+/**
+ *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.
+ */
+/*
+ * topic_subscription.h
+ *
+ *  \date       Sep 22, 2015
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef TOPIC_SUBSCRIPTION_H_
+#define TOPIC_SUBSCRIPTION_H_
+
+#include "celix_threads.h"
+#include "array_list.h"
+#include "celixbool.h"
+#include "service_tracker.h"
+
+#include "pubsub_endpoint.h"
+#include "pubsub_common.h"
+#include "pubsub_serializer.h"
+
+typedef struct topic_subscription* topic_subscription_pt;
+
+celix_status_t pubsub_topicSubscriptionCreate(bundle_context_pt bundle_context,char* scope, char* topic, pubsub_serializer_service_t *best_serializer, topic_subscription_pt* out);
+celix_status_t pubsub_topicSubscriptionDestroy(topic_subscription_pt ts);
+celix_status_t pubsub_topicSubscriptionStart(topic_subscription_pt ts);
+celix_status_t pubsub_topicSubscriptionStop(topic_subscription_pt ts);
+
+celix_status_t pubsub_topicSubscriptionAddConnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL);
+celix_status_t pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL);
+
+celix_status_t pubsub_topicSubscriptionConnectPublisher(topic_subscription_pt ts, char* pubURL);
+celix_status_t pubsub_topicSubscriptionDisconnectPublisher(topic_subscription_pt ts, char* pubURL);
+
+celix_status_t pubsub_topicSubscriptionAddSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP);
+celix_status_t pubsub_topicSubscriptionRemoveSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP);
+
+array_list_pt pubsub_topicSubscriptionGetSubscribersList(topic_subscription_pt sub);
+celix_status_t pubsub_topicIncreaseNrSubscribers(topic_subscription_pt subscription);
+celix_status_t pubsub_topicDecreaseNrSubscribers(topic_subscription_pt subscription);
+unsigned int pubsub_topicGetNrSubscribers(topic_subscription_pt subscription);
+
+#endif /*TOPIC_SUBSCRIPTION_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_zmq/src/zmq_crypto.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/src/zmq_crypto.c b/pubsub/pubsub_admin_zmq/src/zmq_crypto.c
new file mode 100644
index 0000000..fe444bd
--- /dev/null
+++ b/pubsub/pubsub_admin_zmq/src/zmq_crypto.c
@@ -0,0 +1,281 @@
+/**
+ *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.
+ */
+/*
+ * zmq_crypto.c
+ *
+ *  \date       Dec 2, 2016
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include "zmq_crypto.h"
+
+#include <zmq.h>
+#include <openssl/conf.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+
+#include <string.h>
+
+#define MAX_FILE_PATH_LENGTH 512
+#define ZMQ_KEY_LENGTH 40
+#define AES_KEY_LENGTH 32
+#define AES_IV_LENGTH 16
+
+#define KEY_TO_GET "aes_key"
+#define IV_TO_GET "aes_iv"
+
+static char* read_file_content(char* filePath, char* fileName);
+static void parse_key_lines(char *keysBuffer, char **key, char **iv);
+static void parse_key_line(char *line, char **key, char **iv);
+static void extract_keys_from_buffer(unsigned char *input, int inputlen, char **publicKey, char **secretKey);
+
+/**
+ * Return a valid zcert_t from an encoded file
+ * Caller is responsible for freeing by calling zcert_destroy(zcert** cert);
+ */
+zcert_t* get_zcert_from_encoded_file(char* keysFilePath, char* keysFileName, char* file_path)
+{
+
+	if (keysFilePath == NULL){
+		keysFilePath = DEFAULT_KEYS_FILE_PATH;
+	}
+
+	if (keysFileName == NULL){
+		keysFileName = DEFAULT_KEYS_FILE_NAME;
+	}
+
+	char* keys_data = read_file_content(keysFilePath, keysFileName);
+	if (keys_data == NULL){
+		return NULL;
+	}
+
+	char *key = NULL;
+	char *iv = NULL;
+	parse_key_lines(keys_data, &key, &iv);
+	free(keys_data);
+
+	if (key == NULL || iv == NULL){
+		free(key);
+		free(iv);
+
+		printf("CRYPTO: Loading AES key and/or AES iv failed!\n");
+		return NULL;
+	}
+
+	//At this point, we know an aes key and iv are stored and loaded
+
+	// generate sha256 hashes
+	unsigned char key_digest[EVP_MAX_MD_SIZE];
+	unsigned char iv_digest[EVP_MAX_MD_SIZE];
+	generate_sha256_hash((char*) key, key_digest);
+	generate_sha256_hash((char*) iv, iv_digest);
+
+	zchunk_t* encoded_secret = zchunk_slurp (file_path, 0);
+	if (encoded_secret == NULL){
+		free(key);
+		free(iv);
+
+		return NULL;
+	}
+
+	int encoded_secret_size = (int) zchunk_size (encoded_secret);
+	char* encoded_secret_data = zchunk_strdup(encoded_secret);
+	zchunk_destroy (&encoded_secret);
+
+	// Decryption of data
+	int decryptedtext_len;
+	unsigned char decryptedtext[encoded_secret_size];
+	decryptedtext_len = decrypt((unsigned char *) encoded_secret_data, encoded_secret_size, key_digest, iv_digest, decryptedtext);
+	decryptedtext[decryptedtext_len] = '\0';
+
+	EVP_cleanup();
+
+	free(encoded_secret_data);
+	free(key);
+	free(iv);
+
+	// The public and private keys are retrieved
+	char* public_text = NULL;
+	char* secret_text = NULL;
+
+	extract_keys_from_buffer(decryptedtext, decryptedtext_len, &public_text, &secret_text);
+
+	byte public_key [32] = { 0 };
+	byte secret_key [32] = { 0 };
+
+	zmq_z85_decode (public_key, public_text);
+	zmq_z85_decode (secret_key, secret_text);
+
+	zcert_t* cert_loaded = zcert_new_from(public_key, secret_key);
+
+	free(public_text);
+	free(secret_text);
+
+	return cert_loaded;
+}
+
+int generate_sha256_hash(char* text, unsigned char* digest)
+{
+	unsigned int digest_len;
+
+	EVP_MD_CTX * mdctx = EVP_MD_CTX_new();
+	EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL);
+	EVP_DigestUpdate(mdctx, text, strlen(text));
+	EVP_DigestFinal_ex(mdctx, digest, &digest_len);
+	EVP_MD_CTX_free(mdctx);
+
+	return digest_len;
+}
+
+int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext)
+{
+	int len;
+	int plaintext_len;
+
+	EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
+
+	EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
+	EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len);
+	plaintext_len = len;
+	EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
+	plaintext_len += len;
+
+	EVP_CIPHER_CTX_free(ctx);
+
+	return plaintext_len;
+}
+
+/**
+ * Caller is responsible for freeing the returned value
+ */
+static char* read_file_content(char* filePath, char* fileName){
+
+	char fileNameWithPath[MAX_FILE_PATH_LENGTH];
+	snprintf(fileNameWithPath, MAX_FILE_PATH_LENGTH, "%s/%s", filePath, fileName);
+	int rc = 0;
+
+	if (!zsys_file_exists(fileNameWithPath)){
+		printf("CRYPTO: Keys file '%s' doesn't exist!\n", fileNameWithPath);
+		return NULL;
+	}
+
+	zfile_t* keys_file = zfile_new (filePath, fileName);
+	rc = zfile_input (keys_file);
+	if (rc != 0){
+		zfile_destroy(&keys_file);
+		printf("CRYPTO: Keys file '%s' not readable!\n", fileNameWithPath);
+		return NULL;
+	}
+
+	ssize_t keys_file_size = zsys_file_size (fileNameWithPath);
+	zchunk_t* keys_chunk = zfile_read (keys_file, keys_file_size, 0);
+	if (keys_chunk == NULL){
+		zfile_close(keys_file);
+		zfile_destroy(&keys_file);
+		printf("CRYPTO: Can't read file '%s'!\n", fileNameWithPath);
+		return NULL;
+	}
+
+	char* keys_data = zchunk_strdup(keys_chunk);
+	zchunk_destroy(&keys_chunk);
+	zfile_close(keys_file);
+	zfile_destroy (&keys_file);
+
+	return keys_data;
+}
+
+static void parse_key_lines(char *keysBuffer, char **key, char **iv){
+	char *line = NULL, *saveLinePointer = NULL;
+
+	bool firstTime = true;
+	do {
+		if (firstTime){
+			line = strtok_r(keysBuffer, "\n", &saveLinePointer);
+			firstTime = false;
+		}else {
+			line = strtok_r(NULL, "\n", &saveLinePointer);
+		}
+
+		if (line == NULL){
+			break;
+		}
+
+		parse_key_line(line, key, iv);
+
+	} while((*key == NULL || *iv == NULL) && line != NULL);
+
+}
+
+static void parse_key_line(char *line, char **key, char **iv){
+	char *detectedKey = NULL, *detectedValue= NULL;
+
+	char* sep_at = strchr(line, ':');
+	if (sep_at == NULL){
+		return;
+	}
+
+	*sep_at = '\0'; // overwrite first separator, creating two strings.
+	detectedKey = line;
+	detectedValue = sep_at + 1;
+
+	if (detectedKey == NULL || detectedValue == NULL){
+		return;
+	}
+	if (detectedKey[0] == '\0' || detectedValue[0] == '\0'){
+		return;
+	}
+
+	if (*key == NULL && strcmp(detectedKey, KEY_TO_GET) == 0){
+		*key = strndup(detectedValue, AES_KEY_LENGTH);
+	} else if (*iv == NULL && strcmp(detectedKey, IV_TO_GET) == 0){
+		*iv = strndup(detectedValue, AES_IV_LENGTH);
+	}
+}
+
+static void extract_keys_from_buffer(unsigned char *input, int inputlen, char **publicKey, char **secretKey) {
+	// Load decrypted text buffer
+	zchunk_t* secret_decrypted = zchunk_new(input, inputlen);
+	if (secret_decrypted == NULL){
+		printf("CRYPTO: Failed to create zchunk\n");
+		return;
+	}
+
+	zconfig_t* secret_config = zconfig_chunk_load (secret_decrypted);
+	zchunk_destroy (&secret_decrypted);
+	if (secret_config == NULL){
+		printf("CRYPTO: Failed to create zconfig\n");
+		return;
+	}
+
+	// Extract public and secret key from text buffer
+	char* public_text = zconfig_get (secret_config, "/curve/public-key", NULL);
+	char* secret_text = zconfig_get (secret_config, "/curve/secret-key", NULL);
+
+	if (public_text == NULL || secret_text == NULL){
+		zconfig_destroy(&secret_config);
+		printf("CRYPTO: Loading public / secret key from text-buffer failed!\n");
+		return;
+	}
+
+	*publicKey = strndup(public_text, ZMQ_KEY_LENGTH + 1);
+	*secretKey = strndup(secret_text, ZMQ_KEY_LENGTH + 1);
+
+	zconfig_destroy(&secret_config);
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_zmq/src/zmq_crypto.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/src/zmq_crypto.h b/pubsub/pubsub_admin_zmq/src/zmq_crypto.h
new file mode 100644
index 0000000..f1a990f
--- /dev/null
+++ b/pubsub/pubsub_admin_zmq/src/zmq_crypto.h
@@ -0,0 +1,41 @@
+/**
+ *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.
+ */
+/*
+ * zmq_crypto.h
+ *
+ *  \date       Dec 2, 2016
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef ZMQ_CRYPTO_H_
+#define ZMQ_CRYPTO_H_
+
+#include <czmq.h>
+
+#define PROPERTY_KEYS_FILE_PATH "keys.file.path"
+#define PROPERTY_KEYS_FILE_NAME "keys.file.name"
+#define DEFAULT_KEYS_FILE_PATH "/etc/"
+#define DEFAULT_KEYS_FILE_NAME "pubsub.keys"
+
+zcert_t* get_zcert_from_encoded_file(char* keysFilePath, char* keysFileName, char* file_path);
+int generate_sha256_hash(char* text, unsigned char* digest);
+int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext);
+
+#endif

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_api/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_api/CMakeLists.txt b/pubsub/pubsub_api/CMakeLists.txt
new file mode 100644
index 0000000..5ceb291
--- /dev/null
+++ b/pubsub/pubsub_api/CMakeLists.txt
@@ -0,0 +1,32 @@
+# 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.
+
+#api target
+add_library(pubsub_api INTERFACE)
+
+target_include_directories(framework INTERFACE
+    $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
+    $<INSTALL_INTERFACE:include/celix/pubsub>
+)
+
+#install api
+install(TARGETS pubsub_api EXPORT celix DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT pubsub)
+install(DIRECTORY include/ DESTINATION include/celix/pubsub COMPONENT pubsub)
+
+#Setup target aliases to match external usage
+add_library(Celix::pubsub_api ALIAS pubsub_api)
+

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_api/include/pubsub/publisher.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_api/include/pubsub/publisher.h b/pubsub/pubsub_api/include/pubsub/publisher.h
new file mode 100644
index 0000000..3eec149
--- /dev/null
+++ b/pubsub/pubsub_api/include/pubsub/publisher.h
@@ -0,0 +1,88 @@
+/**
+ *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.
+ */
+/*
+ * publisher.h
+ *
+ *  \date       Jan 7, 2016
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef __PUBSUB_PUBLISHER_H_
+#define __PUBSUB_PUBLISHER_H_
+
+#include <stdlib.h>
+
+#define PUBSUB_PUBLISHER_SERVICE_NAME           "pubsub.publisher"
+#define PUBSUB_PUBLISHER_SERVICE_VERSION	      "2.0.0"
+ 
+//properties
+#define PUBSUB_PUBLISHER_TOPIC                  "pubsub.topic"
+#define PUBSUB_PUBLISHER_SCOPE                  "pubsub.scope"
+#define PUBSUB_PUBLISHER_STRATEGY               "pubsub.strategy"
+#define PUBSUB_PUBLISHER_CONFIG                 "pubsub.config"
+ 
+#define PUBSUB_PUBLISHER_SCOPE_DEFAULT			"default"
+//flags
+#define PUBSUB_PUBLISHER_FIRST_MSG  01
+#define PUBSUB_PUBLISHER_PART_MSG   02
+#define PUBSUB_PUBLISHER_LAST_MSG   04
+
+struct pubsub_release_callback_struct {
+    void *handle;
+    void (*release)(char *buf, void *handle);
+};
+typedef struct pubsub_release_callback_struct pubsub_release_callback_t;
+typedef struct pubsub_release_callback_struct* pubsub_release_callback_pt;
+ 
+ 
+struct pubsub_publisher {
+    void *handle;
+ 
+    /**
+     * Every msg is identifiable by msg type string. Because masg type string are performance wise not preferable (string compares),
+     * a "local" (int / platform dependent) unique id will be generated runtime
+     * with use of a distributed key/value store or communication between  participation parties.
+     * this is called the local message type id. This local message type id can be requested with the localMsgIdForMsgType method.
+     * When return is successful the msgTypeId is always greater than 0. (Note this can be used to specify/detect uninitialized msg type ids in the consumer code).
+     *
+     * Returns 0 on success.
+     */
+    int (*localMsgTypeIdForMsgType)(void *handle, const char *msgType, unsigned int *msgTypeId);
+  
+    /**
+     * send is a async function, but the msg can be safely deleted after send returns.
+     * Returns 0 on success.
+     */
+    int (*send)(void *handle, unsigned int msgTypeId, const void *msg);
+ 
+  
+    /**
+     * sendMultipart is a async function, but the msg can be safely deleted after send returns.
+     * The first (primary) message of a multipart message must have the flag PUBLISHER_PRIMARY_MSG
+     * The last message of a multipart message must have the flag PUBLISHER_LAST_MSG
+     * Returns 0 on success.
+     */
+    int (*sendMultipart)(void *handle, unsigned int msgTypeId, const void *msg, int flags);
+ 
+};
+typedef struct pubsub_publisher pubsub_publisher_t;
+typedef struct pubsub_publisher* pubsub_publisher_pt;
+
+#endif // __PUBSUB_PUBLISHER_H_

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_api/include/pubsub/subscriber.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_api/include/pubsub/subscriber.h b/pubsub/pubsub_api/include/pubsub/subscriber.h
new file mode 100644
index 0000000..5d87b8a
--- /dev/null
+++ b/pubsub/pubsub_api/include/pubsub/subscriber.h
@@ -0,0 +1,75 @@
+/**
+ *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.
+ */
+/*
+ * subscriber.h
+ *
+ *  \date       Jan 7, 2016
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef __PUBSUB_SUBSCRIBER_H_
+#define __PUBSUB_SUBSCRIBER_H_
+
+#include <stdbool.h>
+
+#define PUBSUB_SUBSCRIBER_SERVICE_NAME          "pubsub.subscriber"
+#define PUBSUB_SUBSCRIBER_SERVICE_VERSION       "2.0.0"
+ 
+//properties
+#define PUBSUB_SUBSCRIBER_TOPIC                "pubsub.topic"
+#define PUBSUB_SUBSCRIBER_SCOPE                "pubsub.scope"
+#define PUBSUB_SUBSCRIBER_STRATEGY             "pubsub.strategy"
+#define PUBSUB_SUBSCRIBER_CONFIG               "pubsub.config"
+
+#define PUBSUB_SUBSCRIBER_SCOPE_DEFAULT        "default"
+ 
+struct pubsub_multipart_callbacks_struct {
+    void *handle;
+    int (*localMsgTypeIdForMsgType)(void *handle, const char *msgType, unsigned int *msgId);
+    int (*getMultipart)(void *handle, unsigned int msgTypeId, bool retain, void **part);
+};
+typedef struct pubsub_multipart_callbacks_struct pubsub_multipart_callbacks_t;
+typedef struct pubsub_multipart_callbacks_struct* pubsub_multipart_callbacks_pt;
+ 
+struct pubsub_subscriber_struct {
+    void *handle;
+     
+    /**
+     * When a new message for a topic is available the receive will be called.
+     * 
+     * msgType contains fully qualified name of the type and msgTypeId is a local id which presents the type for performance reasons.
+     * Release can be used to instruct the pubsubadmin to release (free) the message when receive function returns. Set it to false to take
+     * over ownership of the msg (e.g. take the responsibility to free it).
+     *
+     * The callbacks argument is only valid inside the receive function, use the getMultipart callback, with retain=true, to keep multipart messages in memory.
+     * results of the localMsgTypeIdForMsgType callback are valid during the complete lifecycle of the component, not just a single receive call.
+     *
+     * Return 0 implies a successful handling. If return is not 0, the msg will always be released by the pubsubadmin.
+     *
+     * this method can be  NULL.
+     */
+    int (*receive)(void *handle, const char *msgType, unsigned int msgTypeId, void *msg, pubsub_multipart_callbacks_t *callbacks, bool *release);
+
+};
+typedef struct pubsub_subscriber_struct pubsub_subscriber_t;
+typedef struct pubsub_subscriber_struct* pubsub_subscriber_pt;
+
+
+#endif //  __PUBSUB_SUBSCRIBER_H_

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_common/public/include/publisher_endpoint_announce.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_common/public/include/publisher_endpoint_announce.h b/pubsub/pubsub_common/public/include/publisher_endpoint_announce.h
deleted file mode 100644
index bd39fc0..0000000
--- a/pubsub/pubsub_common/public/include/publisher_endpoint_announce.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- *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.
- */
-
-#ifndef PUBLISHER_ENDPOINT_ANNOUNCE_H_
-#define PUBLISHER_ENDPOINT_ANNOUNCE_H_
-
-#include "pubsub_endpoint.h"
-
-struct publisher_endpoint_announce {
-	void *handle;
-	celix_status_t (*announcePublisher)(void *handle, pubsub_endpoint_pt pubEP);
-	celix_status_t (*removePublisher)(void *handle, pubsub_endpoint_pt pubEP);
-	celix_status_t (*interestedInTopic)(void* handle, const char *scope, const char *topic);
-	celix_status_t (*uninterestedInTopic)(void* handle, const char *scope, const char *topic);
-};
-
-typedef struct publisher_endpoint_announce *publisher_endpoint_announce_pt;
-
-
-#endif /* PUBLISHER_ENDPOINT_ANNOUNCE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_common/public/include/pubsub_admin.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_common/public/include/pubsub_admin.h b/pubsub/pubsub_common/public/include/pubsub_admin.h
deleted file mode 100644
index f24d825..0000000
--- a/pubsub/pubsub_common/public/include/pubsub_admin.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- *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.
- */
-/*
- * pubsub_admin.h
- *
- *  \date       Sep 30, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef PUBSUB_ADMIN_H_
-#define PUBSUB_ADMIN_H_
-
-#include "service_reference.h"
-
-#include "pubsub_common.h"
-#include "pubsub_endpoint.h"
-
-#define PSA_IP 	"PSA_IP"
-#define PSA_ITF	"PSA_INTERFACE"
-#define PSA_MULTICAST_IP_PREFIX "PSA_MC_PREFIX"
-
-#define PUBSUB_ADMIN_TYPE_KEY	"pubsub_admin.type"
-
-typedef struct pubsub_admin *pubsub_admin_pt;
-
-struct pubsub_admin_service {
-	pubsub_admin_pt admin;
-
-	celix_status_t (*addSubscription)(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
-	celix_status_t (*removeSubscription)(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
-
-	celix_status_t (*addPublication)(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
-	celix_status_t (*removePublication)(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
-
-	celix_status_t (*closeAllPublications)(pubsub_admin_pt admin,char* scope, char* topic);
-	celix_status_t (*closeAllSubscriptions)(pubsub_admin_pt admin,char* scope, char* topic);
-
-	/* Match principle:
-	 * - A full matching pubsub_admin gives 200 points
-	 * - A full matching serializer gives 100 points
-	 * - If QoS = sample
-	 * 		- fallback pubsub_admin order of selection is: udp_mc, zmq. Points allocation is 100,75.
-	 * 		- fallback serializers order of selection is: json, void. Points allocation is 30,20.
-	 * - If QoS = control
-	 * 		- fallback pubsub_admin order of selection is: zmq,udp_mc. Points allocation is 100,75.
-	 * 		- fallback serializers order of selection is: json, void. Points allocation is 30,20.
-	 * - If nothing is specified, QoS = sample is assumed, so the same score applies, just divided by two.
-	 *
-	 */
-	celix_status_t (*matchEndpoint)(pubsub_admin_pt admin, pubsub_endpoint_pt endpoint, double* score);
-};
-
-typedef struct pubsub_admin_service *pubsub_admin_service_pt;
-
-#endif /* PUBSUB_ADMIN_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_common/public/include/pubsub_admin_match.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_common/public/include/pubsub_admin_match.h b/pubsub/pubsub_common/public/include/pubsub_admin_match.h
deleted file mode 100644
index e95ca7d..0000000
--- a/pubsub/pubsub_common/public/include/pubsub_admin_match.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- *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.
- */
-
-
-#ifndef PUBSUB_ADMIN_MATCH_H_
-#define PUBSUB_ADMIN_MATCH_H_
-
-#include "celix_errno.h"
-#include "properties.h"
-#include "array_list.h"
-
-#include "pubsub_serializer.h"
-
-#define QOS_ATTRIBUTE_KEY	"attribute.qos"
-#define QOS_TYPE_SAMPLE		"sample"	/* A.k.a. unreliable connection */
-#define QOS_TYPE_CONTROL	"control"	/* A.k.a. reliable connection */
-
-#define PUBSUB_ADMIN_FULL_MATCH_SCORE	200.0F
-#define SERIALIZER_FULL_MATCH_SCORE		100.0F
-
-celix_status_t pubsub_admin_match(properties_pt endpoint_props, const char *pubsub_admin_type, array_list_pt serializerList, double *score);
-celix_status_t pubsub_admin_get_best_serializer(properties_pt endpoint_props, array_list_pt serializerList, pubsub_serializer_service_t **serSvc);
-
-#endif /* PUBSUB_ADMIN_MATCH_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_common/public/include/pubsub_common.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_common/public/include/pubsub_common.h b/pubsub/pubsub_common/public/include/pubsub_common.h
deleted file mode 100644
index 5dfd8fd..0000000
--- a/pubsub/pubsub_common/public/include/pubsub_common.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- *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.
- */
-/*
- * pubsub_common.h
- *
- *  \date       Sep 17, 2015
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef PUBSUB_COMMON_H_
-#define PUBSUB_COMMON_H_
-
-#define PUBSUB_SERIALIZER_SERVICE 		"pubsub_serializer"
-#define PUBSUB_ADMIN_SERVICE 			"pubsub_admin"
-#define PUBSUB_DISCOVERY_SERVICE		"pubsub_discovery"
-#define PUBSUB_TM_ANNOUNCE_PUBLISHER_SERVICE    "pubsub_tm_announce_publisher"
-
-#define PUBSUB_ANY_SUB_TOPIC		        "any"
-
-#define	PUBSUB_BUNDLE_ID			"bundle.id"
-
-#define MAX_SCOPE_LEN                           1024
-#define MAX_TOPIC_LEN				1024
-
-struct pubsub_msg_header{
-	char topic[MAX_TOPIC_LEN];
-	unsigned int type;
-	unsigned char major;
-	unsigned char minor;
-};
-
-typedef struct pubsub_msg_header* pubsub_msg_header_pt;
-
-
-#endif /* PUBSUB_COMMON_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_common/public/include/pubsub_endpoint.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_common/public/include/pubsub_endpoint.h b/pubsub/pubsub_common/public/include/pubsub_endpoint.h
deleted file mode 100644
index 8a979eb..0000000
--- a/pubsub/pubsub_common/public/include/pubsub_endpoint.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- *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.
- */
-/*
- * pubsub_endpoint.h
- *
- *  \date       Sep 21, 2015
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef PUBSUB_ENDPOINT_H_
-#define PUBSUB_ENDPOINT_H_
-
-#include "service_reference.h"
-#include "listener_hook_service.h"
-#include "properties.h"
-
-#include "publisher.h"
-#include "subscriber.h"
-
-struct pubsub_endpoint {
-    char *frameworkUUID;
-    char *scope;
-    char *topic;
-    long serviceID;
-    char* endpoint;
-    bool is_secure;
-    properties_pt topic_props;
-};
-
-typedef struct pubsub_endpoint *pubsub_endpoint_pt;
-
-celix_status_t pubsubEndpoint_create(const char* fwUUID, const char* scope, const char* topic, long serviceId,const char* endpoint,properties_pt topic_props,pubsub_endpoint_pt* psEp);
-celix_status_t pubsubEndpoint_createFromServiceReference(service_reference_pt reference,pubsub_endpoint_pt* psEp, bool isPublisher);
-celix_status_t pubsubEndpoint_createFromListenerHookInfo(listener_hook_info_pt info,pubsub_endpoint_pt* psEp, bool isPublisher);
-celix_status_t pubsubEndpoint_clone(pubsub_endpoint_pt in, pubsub_endpoint_pt *out);
-celix_status_t pubsubEndpoint_destroy(pubsub_endpoint_pt psEp);
-bool pubsubEndpoint_equals(pubsub_endpoint_pt psEp1,pubsub_endpoint_pt psEp2);
-
-char *createScopeTopicKey(const char* scope, const char* topic);
-
-#endif /* PUBSUB_ENDPOINT_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_common/public/include/pubsub_serializer.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_common/public/include/pubsub_serializer.h b/pubsub/pubsub_common/public/include/pubsub_serializer.h
deleted file mode 100644
index 4489fa4..0000000
--- a/pubsub/pubsub_common/public/include/pubsub_serializer.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- *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.
- */
-/*
- * pubsub_serializer.h
- *
- *  \date       Mar 24, 2017
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef PUBSUB_SERIALIZER_SERVICE_H_
-#define PUBSUB_SERIALIZER_SERVICE_H_
-
-#include "service_reference.h"
-#include "hash_map.h"
-
-#include "pubsub_common.h"
-
-#define PUBSUB_SERIALIZER_TYPE_KEY	"pubsub_serializer.type"
-
-/**
- * There should be a pubsub_serializer_t
- * per msg type (msg id) per bundle
- *
- * The pubsub_serializer_service can create
- * a serializer_map per bundle. Potentially using
- * the extender pattern.
- */
-
-typedef struct pubsub_msg_serializer {
-	void* handle;
-	unsigned int msgId;
-	const char* msgName;
-	version_pt msgVersion;
-
-	celix_status_t (*serialize)(void* handle, const void* input, void** out, size_t* outLen);
-	celix_status_t (*deserialize)(void* handle, const void* input, size_t inputLen, void** out); //note inputLen can be 0 if predefined size is not needed
-	void (*freeMsg)(void* handle, void* msg);
-
-} pubsub_msg_serializer_t;
-
-typedef struct pubsub_serializer_service {
-	void* handle;
-
-	celix_status_t (*createSerializerMap)(void* handle, bundle_pt bundle, hash_map_pt* serializerMap);
-	celix_status_t (*destroySerializerMap)(void* handle, hash_map_pt serializerMap);
-
-} pubsub_serializer_service_t;
-
-#endif /* PUBSUB_SERIALIZER_SERVICE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_common/public/include/pubsub_topic_info.descriptor
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_common/public/include/pubsub_topic_info.descriptor b/pubsub/pubsub_common/public/include/pubsub_topic_info.descriptor
deleted file mode 100644
index c01a2fd..0000000
--- a/pubsub/pubsub_common/public/include/pubsub_topic_info.descriptor
+++ /dev/null
@@ -1,10 +0,0 @@
-:header
-type=interface
-name=pubsub_topic_info
-version=1.0.0
-:annotations
-:types
-:methods
-getParticipantsNumber(t)i=getParticipantsNumber(#am=handle;Pt#am=pre;*i)N
-getSubscribersNumber(t)i=getSubscribersNumber(#am=handle;Pt#am=pre;*i)N
-getPublishersNumber(t)i=getPublishersNumber(#am=handle;Pt#am=pre;*i)N

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_common/public/include/pubsub_utils.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_common/public/include/pubsub_utils.h b/pubsub/pubsub_common/public/include/pubsub_utils.h
deleted file mode 100644
index aff5c72..0000000
--- a/pubsub/pubsub_common/public/include/pubsub_utils.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- *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.
- */
-/*
- * pubsub_utils.h
- *
- *  \date       Sep 24, 2015
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef PUBSUB_UTILS_H_
-#define PUBSUB_UTILS_H_
-
-#include "bundle_context.h"
-#include "array_list.h"
-
-char* pubsub_getScopeFromFilter(char* bundle_filter);
-char* pubsub_getTopicFromFilter(char* bundle_filter);
-char* pubsub_getKeysBundleDir(bundle_context_pt ctx);
-array_list_pt pubsub_getTopicsFromString(char* string);
-
-
-#endif /* PUBSUB_UTILS_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_common/public/src/pubsub_admin_match.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_common/public/src/pubsub_admin_match.c b/pubsub/pubsub_common/public/src/pubsub_admin_match.c
deleted file mode 100644
index 2a695c1..0000000
--- a/pubsub/pubsub_common/public/src/pubsub_admin_match.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/**
- *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.
- */
-
-
-#include <string.h>
-#include "service_reference.h"
-
-#include "pubsub_admin.h"
-
-#include "pubsub_admin_match.h"
-
-#define KNOWN_PUBSUB_ADMIN_NUM	2
-#define KNOWN_SERIALIZER_NUM	2
-
-static char* qos_sample_pubsub_admin_prio_list[KNOWN_PUBSUB_ADMIN_NUM] = {"udp_mc","zmq"};
-static char* qos_sample_serializer_prio_list[KNOWN_SERIALIZER_NUM] = {"json","void"};
-
-static char* qos_control_pubsub_admin_prio_list[KNOWN_PUBSUB_ADMIN_NUM] = {"zmq","udp_mc"};
-static char* qos_control_serializer_prio_list[KNOWN_SERIALIZER_NUM] = {"json","void"};
-
-static double qos_pubsub_admin_score[KNOWN_PUBSUB_ADMIN_NUM] = {100.0F,75.0F};
-static double qos_serializer_score[KNOWN_SERIALIZER_NUM] = {30.0F,20.0F};
-
-static void get_serializer_type(service_reference_pt svcRef, char **serializerType);
-static void manage_service_from_reference(service_reference_pt svcRef, void **svc, bool getService);
-
-celix_status_t pubsub_admin_match(properties_pt endpoint_props, const char *pubsub_admin_type, array_list_pt serializerList, double *score){
-
-	celix_status_t status = CELIX_SUCCESS;
-	double final_score = 0;
-	int i = 0, j = 0;
-
-	const char *requested_admin_type 		= NULL;
-	const char *requested_serializer_type 	= NULL;
-	const char *requested_qos_type			= NULL;
-
-	if(endpoint_props!=NULL){
-		requested_admin_type 		= properties_get(endpoint_props,PUBSUB_ADMIN_TYPE_KEY);
-		requested_serializer_type 	= properties_get(endpoint_props,PUBSUB_SERIALIZER_TYPE_KEY);
-		requested_qos_type			= properties_get(endpoint_props,QOS_ATTRIBUTE_KEY);
-	}
-
-	/* Analyze the pubsub_admin */
-	if(requested_admin_type != NULL){ /* We got precise specification on the pubsub_admin we want */
-		if(strncmp(requested_admin_type,pubsub_admin_type,strlen(pubsub_admin_type))==0){ //Full match
-			final_score += PUBSUB_ADMIN_FULL_MATCH_SCORE;
-		}
-	}
-	else if(requested_qos_type != NULL){ /* We got QoS specification that will determine the selected PSA */
-		if(strncmp(requested_qos_type,QOS_TYPE_SAMPLE,strlen(QOS_TYPE_SAMPLE))==0){
-			for(i=0;i<KNOWN_PUBSUB_ADMIN_NUM;i++){
-				if(strncmp(qos_sample_pubsub_admin_prio_list[i],pubsub_admin_type,strlen(pubsub_admin_type))==0){
-					final_score += qos_pubsub_admin_score[i];
-					break;
-				}
-			}
-		}
-		else if(strncmp(requested_qos_type,QOS_TYPE_CONTROL,strlen(QOS_TYPE_CONTROL))==0){
-			for(i=0;i<KNOWN_PUBSUB_ADMIN_NUM;i++){
-				if(strncmp(qos_control_pubsub_admin_prio_list[i],pubsub_admin_type,strlen(pubsub_admin_type))==0){
-					final_score += qos_pubsub_admin_score[i];
-					break;
-				}
-			}
-		}
-		else{
-			printf("Unknown QoS type '%s'\n",requested_qos_type);
-			status = CELIX_ILLEGAL_ARGUMENT;
-		}
-	}
-	else{ /* We got no specification: fallback to Qos=Sample, but count half the score */
-		for(i=0;i<KNOWN_PUBSUB_ADMIN_NUM;i++){
-			if(strncmp(qos_sample_pubsub_admin_prio_list[i],pubsub_admin_type,strlen(pubsub_admin_type))==0){
-				final_score += (qos_pubsub_admin_score[i]/2);
-				break;
-			}
-		}
-	}
-
-	char *serializer_type = NULL;
-	/* Analyze the serializers */
-	if(requested_serializer_type != NULL){ /* We got precise specification on the serializer we want */
-		for(i=0;i<arrayList_size(serializerList);i++){
-			service_reference_pt svcRef = (service_reference_pt)arrayList_get(serializerList,i);
-			get_serializer_type(svcRef, &serializer_type);
-			if(serializer_type != NULL){
-				if(strncmp(requested_serializer_type,serializer_type,strlen(serializer_type))==0){
-					final_score += SERIALIZER_FULL_MATCH_SCORE;
-					break;
-				}
-			}
-		}
-	}
-	else if(requested_qos_type != NULL){ /* We got QoS specification that will determine the selected serializer */
-		if(strncmp(requested_qos_type,QOS_TYPE_SAMPLE,strlen(QOS_TYPE_SAMPLE))==0){
-			bool ser_found = false;
-			for(i=0;i<KNOWN_SERIALIZER_NUM && !ser_found;i++){
-				for(j=0;j<arrayList_size(serializerList) && !ser_found;j++){
-					service_reference_pt svcRef = (service_reference_pt)arrayList_get(serializerList,j);
-					get_serializer_type(svcRef, &serializer_type);
-					if(serializer_type != NULL){
-						if(strncmp(qos_sample_serializer_prio_list[i],serializer_type,strlen(serializer_type))==0){
-							ser_found = true;
-						}
-					}
-				}
-				if(ser_found){
-					final_score += qos_serializer_score[i];
-				}
-			}
-		}
-		else if(strncmp(requested_qos_type,QOS_TYPE_CONTROL,strlen(QOS_TYPE_CONTROL))==0){
-			bool ser_found = false;
-			for(i=0;i<KNOWN_SERIALIZER_NUM && !ser_found;i++){
-				for(j=0;j<arrayList_size(serializerList) && !ser_found;j++){
-					service_reference_pt svcRef = (service_reference_pt)arrayList_get(serializerList,j);
-					get_serializer_type(svcRef, &serializer_type);
-					if(serializer_type != NULL){
-						if(strncmp(qos_control_serializer_prio_list[i],serializer_type,strlen(serializer_type))==0){
-							ser_found = true;
-						}
-					}
-				}
-				if(ser_found){
-					final_score += qos_serializer_score[i];
-				}
-			}
-		}
-		else{
-			printf("Unknown QoS type '%s'\n",requested_qos_type);
-			status = CELIX_ILLEGAL_ARGUMENT;
-		}
-	}
-	else{ /* We got no specification: fallback to Qos=Sample, but count half the score */
-		bool ser_found = false;
-		for(i=0;i<KNOWN_SERIALIZER_NUM && !ser_found;i++){
-			for(j=0;j<arrayList_size(serializerList) && !ser_found;j++){
-				service_reference_pt svcRef = (service_reference_pt)arrayList_get(serializerList,j);
-				get_serializer_type(svcRef, &serializer_type);
-				if(serializer_type != NULL){
-					if(strncmp(qos_sample_serializer_prio_list[i],serializer_type,strlen(serializer_type))==0){
-						ser_found = true;
-					}
-				}
-			}
-			if(ser_found){
-				final_score += (qos_serializer_score[i]/2);
-			}
-		}
-	}
-
-	*score = final_score;
-
-	printf("Score for pair <%s,%s> = %f\n",pubsub_admin_type,serializer_type,final_score);
-
-	return status;
-}
-
-celix_status_t pubsub_admin_get_best_serializer(properties_pt endpoint_props, array_list_pt serializerList, pubsub_serializer_service_t **serSvc){
-	celix_status_t status = CELIX_SUCCESS;
-
-	int i = 0, j = 0;
-
-	const char *requested_serializer_type = NULL;
-	const char *requested_qos_type = NULL;
-
-	if (endpoint_props != NULL){
-		requested_serializer_type = properties_get(endpoint_props,PUBSUB_SERIALIZER_TYPE_KEY);
-		requested_qos_type = properties_get(endpoint_props,QOS_ATTRIBUTE_KEY);
-	}
-
-	service_reference_pt svcRef = NULL;
-	void *svc = NULL;
-
-	/* Analyze the serializers */
-	if(requested_serializer_type != NULL){ /* We got precise specification on the serializer we want */
-		for(i=0;i<arrayList_size(serializerList);i++){
-			svcRef = (service_reference_pt)arrayList_get(serializerList,i);
-			char *serializer_type = NULL;
-			get_serializer_type(svcRef, &serializer_type);
-			if(serializer_type != NULL){
-				if(strncmp(requested_serializer_type,serializer_type,strlen(serializer_type))==0){
-					manage_service_from_reference(svcRef, &svc,true);
-					if(svc==NULL){
-						printf("Cannot get pubsub_serializer_service from serviceReference %p\n",svcRef);
-						status = CELIX_SERVICE_EXCEPTION;
-					}
-					*serSvc = svc;
-					break;
-				}
-			}
-		}
-	}
-	else if(requested_qos_type != NULL){ /* We got QoS specification that will determine the selected serializer */
-		if(strncmp(requested_qos_type,QOS_TYPE_SAMPLE,strlen(QOS_TYPE_SAMPLE))==0){
-			bool ser_found = false;
-			for(i=0;i<KNOWN_SERIALIZER_NUM && !ser_found;i++){
-				for(j=0;j<arrayList_size(serializerList) && !ser_found;j++){
-					svcRef = (service_reference_pt)arrayList_get(serializerList,j);
-					char *serializer_type = NULL;
-					get_serializer_type(svcRef, &serializer_type);
-					if(serializer_type != NULL){
-						if(strncmp(qos_sample_serializer_prio_list[i],serializer_type,strlen(serializer_type))==0){
-							manage_service_from_reference(svcRef, &svc,true);
-							if(svc==NULL){
-								printf("Cannot get pubsub_serializer_service from serviceReference %p\n",svcRef);
-								status = CELIX_SERVICE_EXCEPTION;
-							}
-							else{
-								*serSvc = svc;
-								ser_found = true;
-								printf("Selected %s serializer as best for QoS=%s\n",qos_sample_serializer_prio_list[i],QOS_TYPE_SAMPLE);
-							}
-						}
-					}
-				}
-			}
-		}
-		else if(strncmp(requested_qos_type,QOS_TYPE_CONTROL,strlen(QOS_TYPE_CONTROL))==0){
-			bool ser_found = false;
-			for(i=0;i<KNOWN_SERIALIZER_NUM && !ser_found;i++){
-				for(j=0;j<arrayList_size(serializerList) && !ser_found;j++){
-					svcRef = (service_reference_pt)arrayList_get(serializerList,j);
-					char *serializer_type = NULL;
-					get_serializer_type(svcRef, &serializer_type);
-					if(serializer_type != NULL){
-						if(strncmp(qos_control_serializer_prio_list[i],serializer_type,strlen(serializer_type))==0){
-							manage_service_from_reference(svcRef, &svc,true);
-							if(svc==NULL){
-								printf("Cannot get pubsub_serializer_service from serviceReference %p\n",svcRef);
-								status = CELIX_SERVICE_EXCEPTION;
-							}
-							else{
-								*serSvc = svc;
-								ser_found = true;
-								printf("Selected %s serializer as best for QoS=%s\n",qos_control_serializer_prio_list[i],QOS_TYPE_CONTROL);
-							}
-						}
-					}
-				}
-			}
-		}
-		else{
-			printf("Unknown QoS type '%s'\n",requested_qos_type);
-			status = CELIX_ILLEGAL_ARGUMENT;
-		}
-	}
-	else{ /* We got no specification: fallback to Qos=Sample, but count half the score */
-		bool ser_found = false;
-		for(i=0;i<KNOWN_SERIALIZER_NUM && !ser_found;i++){
-			for(j=0;j<arrayList_size(serializerList) && !ser_found;j++){
-				svcRef = (service_reference_pt)arrayList_get(serializerList,j);
-				char *serializer_type = NULL;
-				get_serializer_type(svcRef, &serializer_type);
-				if(serializer_type != NULL){
-					if(strncmp(qos_sample_serializer_prio_list[i],serializer_type,strlen(serializer_type))==0){
-						manage_service_from_reference(svcRef, &svc,true);
-						if(svc==NULL){
-							printf("Cannot get pubsub_serializer_service from serviceReference %p\n",svcRef);
-							status = CELIX_SERVICE_EXCEPTION;
-						}
-						else{
-							*serSvc = svc;
-							ser_found = true;
-							printf("Selected %s serializer as best without any specification\n",qos_sample_serializer_prio_list[i]);
-						}
-					}
-				}
-			}
-		}
-	}
-
-	if(svc!=NULL && svcRef!=NULL){
-		manage_service_from_reference(svcRef, svc, false);
-	}
-
-	return status;
-}
-
-static void get_serializer_type(service_reference_pt svcRef, char **serializerType){
-
-	const char *serType = NULL;
-	serviceReference_getProperty(svcRef, PUBSUB_SERIALIZER_TYPE_KEY,&serType);
-	if(serType != NULL){
-		*serializerType = (char*)serType;
-	}
-	else{
-		printf("Serializer serviceReference %p has no pubsub_serializer.type property specified\n",svcRef);
-		*serializerType = NULL;
-	}
-}
-
-static void manage_service_from_reference(service_reference_pt svcRef, void **svc, bool getService){
-	bundle_context_pt context = NULL;
-	bundle_pt bundle = NULL;
-	serviceReference_getBundle(svcRef, &bundle);
-	bundle_getContext(bundle, &context);
-	if(getService){
-		bundleContext_getService(context, svcRef, svc);
-	}
-	else{
-		bundleContext_ungetService(context, svcRef, NULL);
-	}
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_common/public/src/pubsub_endpoint.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_common/public/src/pubsub_endpoint.c b/pubsub/pubsub_common/public/src/pubsub_endpoint.c
deleted file mode 100644
index c3fd293..0000000
--- a/pubsub/pubsub_common/public/src/pubsub_endpoint.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/**
- *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.
- */
-/*
- * endpoint_description.c
- *
- *  \date       25 Jul 2014
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-
-#include <string.h>
-#include <stdlib.h>
-
-#include "celix_errno.h"
-#include "celix_log.h"
-
-#include "pubsub_common.h"
-#include "pubsub_endpoint.h"
-#include "constants.h"
-
-#include "pubsub_utils.h"
-
-
-static void pubsubEndpoint_setFields(pubsub_endpoint_pt psEp, const char* fwUUID, const char* scope, const char* topic, long serviceId,const char* endpoint,properties_pt topic_props, bool cloneProps);
-static properties_pt pubsubEndpoint_getTopicProperties(bundle_pt bundle, const char *topic, bool isPublisher);
-
-static void pubsubEndpoint_setFields(pubsub_endpoint_pt psEp, const char* fwUUID, const char* scope, const char* topic, long serviceId,const char* endpoint,properties_pt topic_props, bool cloneProps){
-
-	if (fwUUID != NULL) {
-		psEp->frameworkUUID = strdup(fwUUID);
-	}
-
-	if (scope != NULL) {
-		psEp->scope = strdup(scope);
-	}
-
-	if (topic != NULL) {
-		psEp->topic = strdup(topic);
-	}
-
-	psEp->serviceID = serviceId;
-
-	if(endpoint != NULL) {
-		psEp->endpoint = strdup(endpoint);
-	}
-
-	if(topic_props != NULL){
-		if(cloneProps){
-			properties_copy(topic_props, &(psEp->topic_props));
-		}
-		else{
-			psEp->topic_props = topic_props;
-		}
-	}
-}
-
-static properties_pt pubsubEndpoint_getTopicProperties(bundle_pt bundle, const char *topic, bool isPublisher){
-
-	properties_pt topic_props = NULL;
-
-	bool isSystemBundle = false;
-	bundle_isSystemBundle(bundle, &isSystemBundle);
-	long bundleId = -1;
-	bundle_isSystemBundle(bundle, &isSystemBundle);
-	bundle_getBundleId(bundle,&bundleId);
-
-	if(isSystemBundle == false) {
-
-		char *bundleRoot = NULL;
-		char* topicPropertiesPath = NULL;
-		bundle_getEntry(bundle, ".", &bundleRoot);
-
-		if(bundleRoot != NULL){
-
-			asprintf(&topicPropertiesPath, "%s/META-INF/topics/%s/%s.properties", bundleRoot, isPublisher?"pub":"sub", topic);
-			topic_props = properties_load(topicPropertiesPath);
-			if(topic_props==NULL){
-				printf("PSEP: Could not load properties for %s on topic %s, bundleId=%ld\n", isPublisher?"publication":"subscription", topic,bundleId);
-			}
-
-			free(topicPropertiesPath);
-			free(bundleRoot);
-		}
-	}
-
-	return topic_props;
-}
-
-celix_status_t pubsubEndpoint_create(const char* fwUUID, const char* scope, const char* topic, long serviceId,const char* endpoint,properties_pt topic_props,pubsub_endpoint_pt* psEp){
-	celix_status_t status = CELIX_SUCCESS;
-
-	*psEp = calloc(1, sizeof(**psEp));
-
-	pubsubEndpoint_setFields(*psEp, fwUUID, scope, topic, serviceId, endpoint, topic_props, true);
-
-	return status;
-
-}
-
-celix_status_t pubsubEndpoint_clone(pubsub_endpoint_pt in, pubsub_endpoint_pt *out){
-	celix_status_t status = CELIX_SUCCESS;
-
-	*out = calloc(1,sizeof(**out));
-
-	pubsubEndpoint_setFields(*out, in->frameworkUUID, in->scope, in->topic, in->serviceID, in->endpoint, in->topic_props, true);
-
-	return status;
-
-}
-
-celix_status_t pubsubEndpoint_createFromServiceReference(service_reference_pt reference, pubsub_endpoint_pt* psEp, bool isPublisher){
-	celix_status_t status = CELIX_SUCCESS;
-
-	pubsub_endpoint_pt ep = calloc(1,sizeof(*ep));
-
-	bundle_pt bundle = NULL;
-	bundle_context_pt ctxt = NULL;
-	const char* fwUUID = NULL;
-	serviceReference_getBundle(reference,&bundle);
-	bundle_getContext(bundle,&ctxt);
-	bundleContext_getProperty(ctxt,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
-
-	const char* scope = NULL;
-	serviceReference_getProperty(reference, PUBSUB_SUBSCRIBER_SCOPE,&scope);
-
-	const char* topic = NULL;
-	serviceReference_getProperty(reference, PUBSUB_SUBSCRIBER_TOPIC,&topic);
-
-	const char* serviceId = NULL;
-	serviceReference_getProperty(reference,(char*)OSGI_FRAMEWORK_SERVICE_ID,&serviceId);
-
-	/* TODO: is topic_props==NULL a fatal error such that EP cannot be created? */
-	properties_pt topic_props = pubsubEndpoint_getTopicProperties(bundle, topic, isPublisher);
-
-	pubsubEndpoint_setFields(ep, fwUUID, scope!=NULL?scope:PUBSUB_SUBSCRIBER_SCOPE_DEFAULT, topic, strtol(serviceId,NULL,10), NULL, topic_props, false);
-
-	if (!ep->frameworkUUID || !ep->serviceID || !ep->scope || !ep->topic) {
-		fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "PUBSUB_ENDPOINT: incomplete description!.");
-		status = CELIX_BUNDLE_EXCEPTION;
-		pubsubEndpoint_destroy(ep);
-		*psEp = NULL;
-	}
-	else{
-		*psEp = ep;
-	}
-
-	return status;
-
-}
-
-celix_status_t pubsubEndpoint_createFromListenerHookInfo(listener_hook_info_pt info,pubsub_endpoint_pt* psEp, bool isPublisher){
-	celix_status_t status = CELIX_SUCCESS;
-
-	const char* fwUUID=NULL;
-	bundleContext_getProperty(info->context,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
-
-	if(fwUUID==NULL){
-		return CELIX_BUNDLE_EXCEPTION;
-	}
-
-	char* topic = pubsub_getTopicFromFilter(info->filter);
-	if(topic==NULL){
-		return CELIX_BUNDLE_EXCEPTION;
-	}
-
-	*psEp = calloc(1, sizeof(**psEp));
-
-	char* scope = pubsub_getScopeFromFilter(info->filter);
-	if(scope == NULL) {
-		scope = strdup(PUBSUB_PUBLISHER_SCOPE_DEFAULT);
-	}
-
-	bundle_pt bundle = NULL;
-	long bundleId = -1;
-	bundleContext_getBundle(info->context,&bundle);
-
-	bundle_getBundleId(bundle,&bundleId);
-
-	properties_pt topic_props = pubsubEndpoint_getTopicProperties(bundle, topic, isPublisher);
-
-	/* TODO: is topic_props==NULL a fatal error such that EP cannot be created? */
-	pubsubEndpoint_setFields(*psEp, fwUUID, scope!=NULL?scope:PUBSUB_SUBSCRIBER_SCOPE_DEFAULT, topic, bundleId, NULL, topic_props, false);
-
-	free(topic);
-	free(scope);
-
-
-	return status;
-}
-
-celix_status_t pubsubEndpoint_destroy(pubsub_endpoint_pt psEp){
-
-	if(psEp->frameworkUUID!=NULL){
-		free(psEp->frameworkUUID);
-		psEp->frameworkUUID = NULL;
-	}
-
-	if(psEp->scope!=NULL){
-		free(psEp->scope);
-		psEp->scope = NULL;
-	}
-
-	if(psEp->topic!=NULL){
-		free(psEp->topic);
-		psEp->topic = NULL;
-	}
-
-	if(psEp->endpoint!=NULL){
-		free(psEp->endpoint);
-		psEp->endpoint = NULL;
-	}
-
-	if(psEp->topic_props != NULL){
-		properties_destroy(psEp->topic_props);
-	}
-
-	free(psEp);
-
-	return CELIX_SUCCESS;
-
-}
-
-bool pubsubEndpoint_equals(pubsub_endpoint_pt psEp1,pubsub_endpoint_pt psEp2){
-
-	return ((strcmp(psEp1->frameworkUUID,psEp2->frameworkUUID)==0) &&
-			(strcmp(psEp1->scope,psEp2->scope)==0) &&
-			(strcmp(psEp1->topic,psEp2->topic)==0) &&
-			(psEp1->serviceID == psEp2->serviceID) /*&&
-			((psEp1->endpoint==NULL && psEp2->endpoint==NULL)||(strcmp(psEp1->endpoint,psEp2->endpoint)==0))*/
-	);
-}
-
-char *createScopeTopicKey(const char* scope, const char* topic) {
-	char *result = NULL;
-	asprintf(&result, "%s:%s", scope, topic);
-
-	return result;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_common/public/src/pubsub_utils.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_common/public/src/pubsub_utils.c b/pubsub/pubsub_common/public/src/pubsub_utils.c
deleted file mode 100644
index abc5ae6..0000000
--- a/pubsub/pubsub_common/public/src/pubsub_utils.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/**
- *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.
- */
-/*
- * pubsub_utils.c
- *
- *  \date       Sep 24, 2015
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#include <string.h>
-#include <stdlib.h>
-
-#include "constants.h"
-
-#include "pubsub_common.h"
-#include "publisher.h"
-#include "pubsub_utils.h"
-
-#include "array_list.h"
-#include "bundle.h"
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#define MAX_KEYBUNDLE_LENGTH 256
-
-char* pubsub_getScopeFromFilter(char* bundle_filter){
-
-	char* scope = NULL;
-
-	char* filter = strdup(bundle_filter);
-
-	char* oc = strstr(filter,OSGI_FRAMEWORK_OBJECTCLASS);
-	if(oc!=NULL){
-		oc+=strlen(OSGI_FRAMEWORK_OBJECTCLASS)+1;
-		if(strncmp(oc,PUBSUB_PUBLISHER_SERVICE_NAME,strlen(PUBSUB_PUBLISHER_SERVICE_NAME))==0){
-
-			char* scopes = strstr(filter,PUBSUB_PUBLISHER_SCOPE);
-			if(scopes!=NULL){
-
-				scopes+=strlen(PUBSUB_PUBLISHER_SCOPE)+1;
-				char* bottom=strchr(scopes,')');
-				*bottom='\0';
-
-				scope=strdup(scopes);
-			} else {
-			    scope=strdup(PUBSUB_PUBLISHER_SCOPE_DEFAULT);
-			}
-		}
-	}
-
-	free(filter);
-
-	return scope;
-}
-
-char* pubsub_getTopicFromFilter(char* bundle_filter){
-
-	char* topic = NULL;
-
-	char* filter = strdup(bundle_filter);
-
-	char* oc = strstr(filter,OSGI_FRAMEWORK_OBJECTCLASS);
-	if(oc!=NULL){
-		oc+=strlen(OSGI_FRAMEWORK_OBJECTCLASS)+1;
-		if(strncmp(oc,PUBSUB_PUBLISHER_SERVICE_NAME,strlen(PUBSUB_PUBLISHER_SERVICE_NAME))==0){
-
-			char* topics = strstr(filter,PUBSUB_PUBLISHER_TOPIC);
-			if(topics!=NULL){
-
-				topics+=strlen(PUBSUB_PUBLISHER_TOPIC)+1;
-				char* bottom=strchr(topics,')');
-				*bottom='\0';
-
-				topic=strdup(topics);
-
-			}
-		}
-	}
-
-	free(filter);
-
-	return topic;
-
-}
-
-array_list_pt pubsub_getTopicsFromString(char* string){
-
-	array_list_pt topic_list = NULL;
-	arrayList_create(&topic_list);
-
-	char* topics = strdup(string);
-
-	char* topic = strtok(topics,",;|# ");
-	arrayList_add(topic_list,strdup(topic));
-
-	while( (topic = strtok(NULL,",;|# ")) !=NULL){
-		arrayList_add(topic_list,strdup(topic));
-	}
-
-	free(topics);
-
-	return topic_list;
-
-}
-
-/**
- * Loop through all bundles and look for the bundle with the keys inside.
- * If no key bundle found, return NULL
- *
- * Caller is responsible for freeing the object
- */
-char* pubsub_getKeysBundleDir(bundle_context_pt ctx)
-{
-	array_list_pt bundles = NULL;
-	bundleContext_getBundles(ctx, &bundles);
-	int nrOfBundles = arrayList_size(bundles);
-	long bundle_id = -1;
-	char* result = NULL;
-
-	for (int i = 0; i < nrOfBundles; i++){
-		bundle_pt b = arrayList_get(bundles, i);
-
-		/* Skip bundle 0 (framework bundle) since it has no path nor revisions */
-		bundle_getBundleId(b, &bundle_id);
-		if(bundle_id==0){
-			continue;
-		}
-
-		char* dir = NULL;
-		bundle_getEntry(b, ".", &dir);
-
-		char cert_dir[MAX_KEYBUNDLE_LENGTH];
-		snprintf(cert_dir, MAX_KEYBUNDLE_LENGTH, "%s/META-INF/keys", dir);
-
-		struct stat s;
-		int err = stat(cert_dir, &s);
-		if (err != -1){
-			if (S_ISDIR(s.st_mode)){
-				result = dir;
-				break;
-			}
-		}
-
-		free(dir);
-	}
-
-	arrayList_destroy(bundles);
-
-	return result;
-}
-


[6/8] celix git commit: CELIX-417: Refactors cmake usage of pubsub and rsa. Started with installing exported targets

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_zmq/private/src/zmq_crypto.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/private/src/zmq_crypto.c b/pubsub/pubsub_admin_zmq/private/src/zmq_crypto.c
deleted file mode 100644
index fe444bd..0000000
--- a/pubsub/pubsub_admin_zmq/private/src/zmq_crypto.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/**
- *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.
- */
-/*
- * zmq_crypto.c
- *
- *  \date       Dec 2, 2016
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#include "zmq_crypto.h"
-
-#include <zmq.h>
-#include <openssl/conf.h>
-#include <openssl/evp.h>
-#include <openssl/err.h>
-
-#include <string.h>
-
-#define MAX_FILE_PATH_LENGTH 512
-#define ZMQ_KEY_LENGTH 40
-#define AES_KEY_LENGTH 32
-#define AES_IV_LENGTH 16
-
-#define KEY_TO_GET "aes_key"
-#define IV_TO_GET "aes_iv"
-
-static char* read_file_content(char* filePath, char* fileName);
-static void parse_key_lines(char *keysBuffer, char **key, char **iv);
-static void parse_key_line(char *line, char **key, char **iv);
-static void extract_keys_from_buffer(unsigned char *input, int inputlen, char **publicKey, char **secretKey);
-
-/**
- * Return a valid zcert_t from an encoded file
- * Caller is responsible for freeing by calling zcert_destroy(zcert** cert);
- */
-zcert_t* get_zcert_from_encoded_file(char* keysFilePath, char* keysFileName, char* file_path)
-{
-
-	if (keysFilePath == NULL){
-		keysFilePath = DEFAULT_KEYS_FILE_PATH;
-	}
-
-	if (keysFileName == NULL){
-		keysFileName = DEFAULT_KEYS_FILE_NAME;
-	}
-
-	char* keys_data = read_file_content(keysFilePath, keysFileName);
-	if (keys_data == NULL){
-		return NULL;
-	}
-
-	char *key = NULL;
-	char *iv = NULL;
-	parse_key_lines(keys_data, &key, &iv);
-	free(keys_data);
-
-	if (key == NULL || iv == NULL){
-		free(key);
-		free(iv);
-
-		printf("CRYPTO: Loading AES key and/or AES iv failed!\n");
-		return NULL;
-	}
-
-	//At this point, we know an aes key and iv are stored and loaded
-
-	// generate sha256 hashes
-	unsigned char key_digest[EVP_MAX_MD_SIZE];
-	unsigned char iv_digest[EVP_MAX_MD_SIZE];
-	generate_sha256_hash((char*) key, key_digest);
-	generate_sha256_hash((char*) iv, iv_digest);
-
-	zchunk_t* encoded_secret = zchunk_slurp (file_path, 0);
-	if (encoded_secret == NULL){
-		free(key);
-		free(iv);
-
-		return NULL;
-	}
-
-	int encoded_secret_size = (int) zchunk_size (encoded_secret);
-	char* encoded_secret_data = zchunk_strdup(encoded_secret);
-	zchunk_destroy (&encoded_secret);
-
-	// Decryption of data
-	int decryptedtext_len;
-	unsigned char decryptedtext[encoded_secret_size];
-	decryptedtext_len = decrypt((unsigned char *) encoded_secret_data, encoded_secret_size, key_digest, iv_digest, decryptedtext);
-	decryptedtext[decryptedtext_len] = '\0';
-
-	EVP_cleanup();
-
-	free(encoded_secret_data);
-	free(key);
-	free(iv);
-
-	// The public and private keys are retrieved
-	char* public_text = NULL;
-	char* secret_text = NULL;
-
-	extract_keys_from_buffer(decryptedtext, decryptedtext_len, &public_text, &secret_text);
-
-	byte public_key [32] = { 0 };
-	byte secret_key [32] = { 0 };
-
-	zmq_z85_decode (public_key, public_text);
-	zmq_z85_decode (secret_key, secret_text);
-
-	zcert_t* cert_loaded = zcert_new_from(public_key, secret_key);
-
-	free(public_text);
-	free(secret_text);
-
-	return cert_loaded;
-}
-
-int generate_sha256_hash(char* text, unsigned char* digest)
-{
-	unsigned int digest_len;
-
-	EVP_MD_CTX * mdctx = EVP_MD_CTX_new();
-	EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL);
-	EVP_DigestUpdate(mdctx, text, strlen(text));
-	EVP_DigestFinal_ex(mdctx, digest, &digest_len);
-	EVP_MD_CTX_free(mdctx);
-
-	return digest_len;
-}
-
-int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext)
-{
-	int len;
-	int plaintext_len;
-
-	EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
-
-	EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
-	EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len);
-	plaintext_len = len;
-	EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
-	plaintext_len += len;
-
-	EVP_CIPHER_CTX_free(ctx);
-
-	return plaintext_len;
-}
-
-/**
- * Caller is responsible for freeing the returned value
- */
-static char* read_file_content(char* filePath, char* fileName){
-
-	char fileNameWithPath[MAX_FILE_PATH_LENGTH];
-	snprintf(fileNameWithPath, MAX_FILE_PATH_LENGTH, "%s/%s", filePath, fileName);
-	int rc = 0;
-
-	if (!zsys_file_exists(fileNameWithPath)){
-		printf("CRYPTO: Keys file '%s' doesn't exist!\n", fileNameWithPath);
-		return NULL;
-	}
-
-	zfile_t* keys_file = zfile_new (filePath, fileName);
-	rc = zfile_input (keys_file);
-	if (rc != 0){
-		zfile_destroy(&keys_file);
-		printf("CRYPTO: Keys file '%s' not readable!\n", fileNameWithPath);
-		return NULL;
-	}
-
-	ssize_t keys_file_size = zsys_file_size (fileNameWithPath);
-	zchunk_t* keys_chunk = zfile_read (keys_file, keys_file_size, 0);
-	if (keys_chunk == NULL){
-		zfile_close(keys_file);
-		zfile_destroy(&keys_file);
-		printf("CRYPTO: Can't read file '%s'!\n", fileNameWithPath);
-		return NULL;
-	}
-
-	char* keys_data = zchunk_strdup(keys_chunk);
-	zchunk_destroy(&keys_chunk);
-	zfile_close(keys_file);
-	zfile_destroy (&keys_file);
-
-	return keys_data;
-}
-
-static void parse_key_lines(char *keysBuffer, char **key, char **iv){
-	char *line = NULL, *saveLinePointer = NULL;
-
-	bool firstTime = true;
-	do {
-		if (firstTime){
-			line = strtok_r(keysBuffer, "\n", &saveLinePointer);
-			firstTime = false;
-		}else {
-			line = strtok_r(NULL, "\n", &saveLinePointer);
-		}
-
-		if (line == NULL){
-			break;
-		}
-
-		parse_key_line(line, key, iv);
-
-	} while((*key == NULL || *iv == NULL) && line != NULL);
-
-}
-
-static void parse_key_line(char *line, char **key, char **iv){
-	char *detectedKey = NULL, *detectedValue= NULL;
-
-	char* sep_at = strchr(line, ':');
-	if (sep_at == NULL){
-		return;
-	}
-
-	*sep_at = '\0'; // overwrite first separator, creating two strings.
-	detectedKey = line;
-	detectedValue = sep_at + 1;
-
-	if (detectedKey == NULL || detectedValue == NULL){
-		return;
-	}
-	if (detectedKey[0] == '\0' || detectedValue[0] == '\0'){
-		return;
-	}
-
-	if (*key == NULL && strcmp(detectedKey, KEY_TO_GET) == 0){
-		*key = strndup(detectedValue, AES_KEY_LENGTH);
-	} else if (*iv == NULL && strcmp(detectedKey, IV_TO_GET) == 0){
-		*iv = strndup(detectedValue, AES_IV_LENGTH);
-	}
-}
-
-static void extract_keys_from_buffer(unsigned char *input, int inputlen, char **publicKey, char **secretKey) {
-	// Load decrypted text buffer
-	zchunk_t* secret_decrypted = zchunk_new(input, inputlen);
-	if (secret_decrypted == NULL){
-		printf("CRYPTO: Failed to create zchunk\n");
-		return;
-	}
-
-	zconfig_t* secret_config = zconfig_chunk_load (secret_decrypted);
-	zchunk_destroy (&secret_decrypted);
-	if (secret_config == NULL){
-		printf("CRYPTO: Failed to create zconfig\n");
-		return;
-	}
-
-	// Extract public and secret key from text buffer
-	char* public_text = zconfig_get (secret_config, "/curve/public-key", NULL);
-	char* secret_text = zconfig_get (secret_config, "/curve/secret-key", NULL);
-
-	if (public_text == NULL || secret_text == NULL){
-		zconfig_destroy(&secret_config);
-		printf("CRYPTO: Loading public / secret key from text-buffer failed!\n");
-		return;
-	}
-
-	*publicKey = strndup(public_text, ZMQ_KEY_LENGTH + 1);
-	*secretKey = strndup(secret_text, ZMQ_KEY_LENGTH + 1);
-
-	zconfig_destroy(&secret_config);
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_zmq/src/psa_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/src/psa_activator.c b/pubsub/pubsub_admin_zmq/src/psa_activator.c
new file mode 100644
index 0000000..fd07310
--- /dev/null
+++ b/pubsub/pubsub_admin_zmq/src/psa_activator.c
@@ -0,0 +1,142 @@
+/**
+ *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.
+ */
+/*
+ * psa_activator.c
+ *
+ *  \date       Sep 30, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+
+#include "bundle_activator.h"
+#include "service_registration.h"
+#include "service_tracker.h"
+
+#include "pubsub_admin_impl.h"
+
+
+struct activator {
+	pubsub_admin_pt admin;
+	pubsub_admin_service_pt adminService;
+	service_registration_pt registration;
+	service_tracker_pt serializerTracker;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator;
+
+	activator = calloc(1, sizeof(*activator));
+	if (!activator) {
+		status = CELIX_ENOMEM;
+	}
+	else{
+		*userData = activator;
+
+		status = pubsubAdmin_create(context, &(activator->admin));
+
+		if(status == CELIX_SUCCESS){
+			service_tracker_customizer_pt customizer = NULL;
+			status = serviceTrackerCustomizer_create(activator->admin,
+					NULL,
+					pubsubAdmin_serializerAdded,
+					NULL,
+					pubsubAdmin_serializerRemoved,
+					&customizer);
+			if(status == CELIX_SUCCESS){
+				status = serviceTracker_create(context, PUBSUB_SERIALIZER_SERVICE, customizer, &(activator->serializerTracker));
+				if(status != CELIX_SUCCESS){
+					serviceTrackerCustomizer_destroy(customizer);
+					pubsubAdmin_destroy(activator->admin);
+				}
+			}
+			else{
+				pubsubAdmin_destroy(activator->admin);
+			}
+		}
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+	pubsub_admin_service_pt pubsubAdminSvc = calloc(1, sizeof(*pubsubAdminSvc));
+
+	if (!pubsubAdminSvc) {
+		status = CELIX_ENOMEM;
+	}
+	else{
+		pubsubAdminSvc->admin = activator->admin;
+
+		pubsubAdminSvc->addPublication = pubsubAdmin_addPublication;
+		pubsubAdminSvc->removePublication = pubsubAdmin_removePublication;
+
+		pubsubAdminSvc->addSubscription = pubsubAdmin_addSubscription;
+		pubsubAdminSvc->removeSubscription = pubsubAdmin_removeSubscription;
+
+		pubsubAdminSvc->closeAllPublications = pubsubAdmin_closeAllPublications;
+		pubsubAdminSvc->closeAllSubscriptions = pubsubAdmin_closeAllSubscriptions;
+
+		pubsubAdminSvc->matchEndpoint = pubsubAdmin_matchEndpoint;
+
+		activator->adminService = pubsubAdminSvc;
+
+		status = bundleContext_registerService(context, PUBSUB_ADMIN_SERVICE, pubsubAdminSvc, NULL, &activator->registration);
+
+		status += serviceTracker_open(activator->serializerTracker);
+
+	}
+
+
+	return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	status += serviceTracker_close(activator->serializerTracker);
+	status += serviceRegistration_unregister(activator->registration);
+
+	activator->registration = NULL;
+
+	free(activator->adminService);
+	activator->adminService = NULL;
+
+	return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	serviceTracker_destroy(activator->serializerTracker);
+	pubsubAdmin_destroy(activator->admin);
+	activator->admin = NULL;
+
+	free(activator);
+
+	return status;
+}
+
+

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_zmq/src/pubsub_admin_impl.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/src/pubsub_admin_impl.c b/pubsub/pubsub_admin_zmq/src/pubsub_admin_impl.c
new file mode 100644
index 0000000..29ead0c
--- /dev/null
+++ b/pubsub/pubsub_admin_zmq/src/pubsub_admin_impl.c
@@ -0,0 +1,1040 @@
+/**
+ *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.
+ */
+/*
+ * pubsub_admin_impl.c
+ *
+ *  \date       Sep 30, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include "pubsub_admin_impl.h"
+#include <zmq.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+#ifndef ANDROID
+#include <ifaddrs.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "constants.h"
+#include "utils.h"
+#include "hash_map.h"
+#include "array_list.h"
+#include "bundle_context.h"
+#include "bundle.h"
+#include "service_reference.h"
+#include "service_registration.h"
+#include "log_helper.h"
+#include "log_service.h"
+#include "celix_threads.h"
+#include "service_factory.h"
+
+#include "topic_subscription.h"
+#include "topic_publication.h"
+#include "pubsub_endpoint.h"
+#include "pubsub_utils.h"
+#include "subscriber.h"
+
+#define MAX_KEY_FOLDER_PATH_LENGTH 512
+
+static const char *DEFAULT_IP = "127.0.0.1";
+
+static celix_status_t pubsubAdmin_getIpAdress(const char* interface, char** ip);
+static celix_status_t pubsubAdmin_addSubscriptionToPendingList(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
+static celix_status_t pubsubAdmin_addAnySubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
+
+static celix_status_t pubsubAdmin_getBestSerializer(pubsub_admin_pt admin,pubsub_endpoint_pt ep, pubsub_serializer_service_t **serSvc);
+static void connectTopicPubSubToSerializer(pubsub_admin_pt admin,pubsub_serializer_service_t *serializer,void *topicPubSub,bool isPublication);
+static void disconnectTopicPubSubFromSerializer(pubsub_admin_pt admin,void *topicPubSub,bool isPublication);
+
+celix_status_t pubsubAdmin_create(bundle_context_pt context, pubsub_admin_pt *admin) {
+	celix_status_t status = CELIX_SUCCESS;
+
+#ifdef BUILD_WITH_ZMQ_SECURITY
+	if (!zsys_has_curve()){
+		printf("PSA_ZMQ: zeromq curve unsupported\n");
+		return CELIX_SERVICE_EXCEPTION;
+	}
+#endif
+
+	*admin = calloc(1, sizeof(**admin));
+
+	if (!*admin) {
+		status = CELIX_ENOMEM;
+	}
+	else{
+
+		const char *ip = NULL;
+		char *detectedIp = NULL;
+		(*admin)->bundle_context= context;
+		(*admin)->localPublications = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+		(*admin)->subscriptions = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+		(*admin)->pendingSubscriptions = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+		(*admin)->externalPublications = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+		(*admin)->topicSubscriptionsPerSerializer = hashMap_create(NULL, NULL, NULL, NULL);
+		(*admin)->topicPublicationsPerSerializer  = hashMap_create(NULL, NULL, NULL, NULL);
+		arrayList_create(&((*admin)->noSerializerSubscriptions));
+		arrayList_create(&((*admin)->noSerializerPublications));
+		arrayList_create(&((*admin)->serializerList));
+
+		celixThreadMutex_create(&(*admin)->localPublicationsLock, NULL);
+		celixThreadMutex_create(&(*admin)->subscriptionsLock, NULL);
+		celixThreadMutex_create(&(*admin)->externalPublicationsLock, NULL);
+		celixThreadMutex_create(&(*admin)->serializerListLock, NULL);
+		celixThreadMutex_create(&(*admin)->usedSerializersLock, NULL);
+
+		celixThreadMutexAttr_create(&(*admin)->noSerializerPendingsAttr);
+		celixThreadMutexAttr_settype(&(*admin)->noSerializerPendingsAttr, CELIX_THREAD_MUTEX_RECURSIVE);
+		celixThreadMutex_create(&(*admin)->noSerializerPendingsLock, &(*admin)->noSerializerPendingsAttr);
+
+		celixThreadMutexAttr_create(&(*admin)->pendingSubscriptionsAttr);
+		celixThreadMutexAttr_settype(&(*admin)->pendingSubscriptionsAttr, CELIX_THREAD_MUTEX_RECURSIVE);
+		celixThreadMutex_create(&(*admin)->pendingSubscriptionsLock, &(*admin)->pendingSubscriptionsAttr);
+
+		if (logHelper_create(context, &(*admin)->loghelper) == CELIX_SUCCESS) {
+			logHelper_start((*admin)->loghelper);
+		}
+
+		bundleContext_getProperty(context,PSA_IP , &ip);
+
+#ifndef ANDROID
+		if (ip == NULL) {
+			const char *interface = NULL;
+
+			bundleContext_getProperty(context, PSA_ITF, &interface);
+			if (pubsubAdmin_getIpAdress(interface, &detectedIp) != CELIX_SUCCESS) {
+				logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "PSA_ZMQ: Could not retrieve IP adress for interface %s", interface);
+			}
+
+			ip = detectedIp;
+		}
+#endif
+
+		if (ip != NULL) {
+			logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "PSA_ZMQ: Using %s for service annunciation", ip);
+			(*admin)->ipAddress = strdup(ip);
+		}
+		else {
+			logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "PSA_ZMQ: No IP address for service annunciation set. Using %s", DEFAULT_IP);
+			(*admin)->ipAddress = strdup(DEFAULT_IP);
+		}
+
+		if (detectedIp != NULL) {
+			free(detectedIp);
+		}
+
+		const char* basePortStr = NULL;
+		const char* maxPortStr = NULL;
+		char* endptrBase = NULL;
+		char* endptrMax = NULL;
+		bundleContext_getPropertyWithDefault(context, PSA_ZMQ_BASE_PORT, "PSA_ZMQ_DEFAULT_BASE_PORT", &basePortStr);
+		bundleContext_getPropertyWithDefault(context, PSA_ZMQ_MAX_PORT, "PSA_ZMQ_DEFAULT_MAX_PORT", &maxPortStr);
+		(*admin)->basePort = strtol(basePortStr, &endptrBase, 10);
+		(*admin)->maxPort = strtol(maxPortStr, &endptrMax, 10);
+		if (*endptrBase != '\0') {
+			(*admin)->basePort = PSA_ZMQ_DEFAULT_BASE_PORT;
+		}
+		if (*endptrMax != '\0') {
+			(*admin)->maxPort = PSA_ZMQ_DEFAULT_MAX_PORT;
+		}
+
+		printf("PSA Using base port %u to max port %u\n", (*admin)->basePort, (*admin)->maxPort);
+
+		// Disable Signal Handling by CZMQ
+		setenv("ZSYS_SIGHANDLER", "false", true);
+
+		const char *nrZmqThreads = NULL;
+		bundleContext_getProperty(context, "PSA_NR_ZMQ_THREADS", &nrZmqThreads);
+
+		if(nrZmqThreads != NULL) {
+			char *endPtr = NULL;
+			unsigned int nrThreads = strtoul(nrZmqThreads, &endPtr, 10);
+			if(endPtr != nrZmqThreads && nrThreads > 0 && nrThreads < 50) {
+				zsys_set_io_threads(nrThreads);
+				logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "PSA_ZMQ: Using %d threads for ZMQ", nrThreads);
+				printf("PSA_ZMQ: Using %d threads for ZMQ\n", nrThreads);
+			}
+		}
+
+#ifdef BUILD_WITH_ZMQ_SECURITY
+		// Setup authenticator
+		zactor_t* auth = zactor_new (zauth, NULL);
+		zstr_sendx(auth, "VERBOSE", NULL);
+
+		// Load all public keys of subscribers into the application
+		// This step is done for authenticating subscribers
+		char curve_folder_path[MAX_KEY_FOLDER_PATH_LENGTH];
+		char* keys_bundle_dir = pubsub_getKeysBundleDir(context);
+		snprintf(curve_folder_path, MAX_KEY_FOLDER_PATH_LENGTH, "%s/META-INF/keys/subscriber/public", keys_bundle_dir);
+		zstr_sendx (auth, "CURVE", curve_folder_path, NULL);
+		free(keys_bundle_dir);
+
+		(*admin)->zmq_auth = auth;
+#endif
+
+	}
+
+	return status;
+}
+
+
+celix_status_t pubsubAdmin_destroy(pubsub_admin_pt admin)
+{
+	celix_status_t status = CELIX_SUCCESS;
+
+	free(admin->ipAddress);
+
+	celixThreadMutex_lock(&admin->pendingSubscriptionsLock);
+	hash_map_iterator_pt iter = hashMapIterator_create(admin->pendingSubscriptions);
+	while(hashMapIterator_hasNext(iter)){
+		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+		free((char*)hashMapEntry_getKey(entry));
+		arrayList_destroy((array_list_pt)hashMapEntry_getValue(entry));
+	}
+	hashMapIterator_destroy(iter);
+	hashMap_destroy(admin->pendingSubscriptions,false,false);
+	celixThreadMutex_unlock(&admin->pendingSubscriptionsLock);
+
+	celixThreadMutex_lock(&admin->subscriptionsLock);
+	hashMap_destroy(admin->subscriptions,false,false);
+	celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+	celixThreadMutex_lock(&admin->localPublicationsLock);
+	hashMap_destroy(admin->localPublications,true,false);
+	celixThreadMutex_unlock(&admin->localPublicationsLock);
+
+	celixThreadMutex_lock(&admin->externalPublicationsLock);
+	iter = hashMapIterator_create(admin->externalPublications);
+	while(hashMapIterator_hasNext(iter)){
+		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+		free((char*)hashMapEntry_getKey(entry));
+		arrayList_destroy((array_list_pt)hashMapEntry_getValue(entry));
+	}
+	hashMapIterator_destroy(iter);
+	hashMap_destroy(admin->externalPublications,false,false);
+	celixThreadMutex_unlock(&admin->externalPublicationsLock);
+
+	celixThreadMutex_lock(&admin->serializerListLock);
+	arrayList_destroy(admin->serializerList);
+	celixThreadMutex_unlock(&admin->serializerListLock);
+
+	celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+	arrayList_destroy(admin->noSerializerSubscriptions);
+	arrayList_destroy(admin->noSerializerPublications);
+	celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+
+
+	celixThreadMutex_lock(&admin->usedSerializersLock);
+
+	iter = hashMapIterator_create(admin->topicSubscriptionsPerSerializer);
+	while(hashMapIterator_hasNext(iter)){
+		arrayList_destroy((array_list_pt)hashMapIterator_nextValue(iter));
+	}
+	hashMapIterator_destroy(iter);
+	hashMap_destroy(admin->topicSubscriptionsPerSerializer,false,false);
+
+	iter = hashMapIterator_create(admin->topicPublicationsPerSerializer);
+	while(hashMapIterator_hasNext(iter)){
+		arrayList_destroy((array_list_pt)hashMapIterator_nextValue(iter));
+	}
+	hashMapIterator_destroy(iter);
+	hashMap_destroy(admin->topicPublicationsPerSerializer,false,false);
+
+	celixThreadMutex_unlock(&admin->usedSerializersLock);
+
+	celixThreadMutex_destroy(&admin->usedSerializersLock);
+	celixThreadMutex_destroy(&admin->serializerListLock);
+	celixThreadMutex_destroy(&admin->pendingSubscriptionsLock);
+
+	celixThreadMutexAttr_destroy(&admin->noSerializerPendingsAttr);
+	celixThreadMutex_destroy(&admin->noSerializerPendingsLock);
+
+	celixThreadMutexAttr_destroy(&admin->pendingSubscriptionsAttr);
+	celixThreadMutex_destroy(&admin->subscriptionsLock);
+
+	celixThreadMutex_destroy(&admin->localPublicationsLock);
+	celixThreadMutex_destroy(&admin->externalPublicationsLock);
+
+	logHelper_stop(admin->loghelper);
+
+	logHelper_destroy(&admin->loghelper);
+
+#ifdef BUILD_WITH_ZMQ_SECURITY
+	if (admin->zmq_auth != NULL){
+		zactor_destroy(&(admin->zmq_auth));
+	}
+#endif
+
+	free(admin);
+
+	return status;
+}
+
+static celix_status_t pubsubAdmin_addAnySubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&admin->subscriptionsLock);
+
+	topic_subscription_pt any_sub = hashMap_get(admin->subscriptions,PUBSUB_ANY_SUB_TOPIC);
+
+	if(any_sub==NULL){
+
+		int i;
+		pubsub_serializer_service_t *best_serializer = NULL;
+		if( (status=pubsubAdmin_getBestSerializer(admin, subEP, &best_serializer)) == CELIX_SUCCESS){
+			status = pubsub_topicSubscriptionCreate(admin->bundle_context, PUBSUB_SUBSCRIBER_SCOPE_DEFAULT, PUBSUB_ANY_SUB_TOPIC, best_serializer, &any_sub);
+		}
+		else{
+			printf("PSA_ZMQ: Cannot find a serializer for subscribing topic %s. Adding it to pending list.\n",subEP->topic);
+			celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+			arrayList_add(admin->noSerializerSubscriptions,subEP);
+			celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+		}
+
+		if (status == CELIX_SUCCESS){
+
+			/* Connect all internal publishers */
+			celixThreadMutex_lock(&admin->localPublicationsLock);
+			hash_map_iterator_pt lp_iter =hashMapIterator_create(admin->localPublications);
+			while(hashMapIterator_hasNext(lp_iter)){
+				service_factory_pt factory = (service_factory_pt)hashMapIterator_nextValue(lp_iter);
+				topic_publication_pt topic_pubs = (topic_publication_pt)factory->handle;
+				array_list_pt topic_publishers = pubsub_topicPublicationGetPublisherList(topic_pubs);
+
+				if(topic_publishers!=NULL){
+					for(i=0;i<arrayList_size(topic_publishers);i++){
+						pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(topic_publishers,i);
+						if(pubEP->endpoint !=NULL){
+							status += pubsub_topicSubscriptionConnectPublisher(any_sub,pubEP->endpoint);
+						}
+					}
+					arrayList_destroy(topic_publishers);
+				}
+			}
+			hashMapIterator_destroy(lp_iter);
+			celixThreadMutex_unlock(&admin->localPublicationsLock);
+
+			/* Connect also all external publishers */
+			celixThreadMutex_lock(&admin->externalPublicationsLock);
+			hash_map_iterator_pt extp_iter =hashMapIterator_create(admin->externalPublications);
+			while(hashMapIterator_hasNext(extp_iter)){
+				array_list_pt ext_pub_list = (array_list_pt)hashMapIterator_nextValue(extp_iter);
+				if(ext_pub_list!=NULL){
+					for(i=0;i<arrayList_size(ext_pub_list);i++){
+						pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
+						if(pubEP->endpoint !=NULL){
+							status += pubsub_topicSubscriptionConnectPublisher(any_sub,pubEP->endpoint);
+						}
+					}
+				}
+			}
+			hashMapIterator_destroy(extp_iter);
+			celixThreadMutex_unlock(&admin->externalPublicationsLock);
+
+
+			pubsub_topicSubscriptionAddSubscriber(any_sub,subEP);
+
+			status += pubsub_topicSubscriptionStart(any_sub);
+
+		}
+
+		if (status == CELIX_SUCCESS){
+			hashMap_put(admin->subscriptions,strdup(PUBSUB_ANY_SUB_TOPIC),any_sub);
+			connectTopicPubSubToSerializer(admin, best_serializer, any_sub, false);
+		}
+
+	}
+
+	celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+	return status;
+}
+
+celix_status_t pubsubAdmin_addSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
+	celix_status_t status = CELIX_SUCCESS;
+
+	printf("PSA_ZMQ: Received subscription [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n",subEP->frameworkUUID,subEP->serviceID,subEP->scope, subEP->topic);
+
+	if(strcmp(subEP->topic,PUBSUB_ANY_SUB_TOPIC)==0){
+		return pubsubAdmin_addAnySubscription(admin,subEP);
+	}
+
+	/* Check if we already know some publisher about this topic, otherwise let's put the subscription in the pending hashmap */
+	celixThreadMutex_lock(&admin->pendingSubscriptionsLock);
+	celixThreadMutex_lock(&admin->subscriptionsLock);
+	celixThreadMutex_lock(&admin->localPublicationsLock);
+	celixThreadMutex_lock(&admin->externalPublicationsLock);
+
+	char* scope_topic = createScopeTopicKey(subEP->scope, subEP->topic);
+
+	service_factory_pt factory = (service_factory_pt)hashMap_get(admin->localPublications,scope_topic);
+	array_list_pt ext_pub_list = (array_list_pt)hashMap_get(admin->externalPublications,scope_topic);
+
+	if(factory==NULL && ext_pub_list==NULL){ //No (local or external) publishers yet for this topic
+		pubsubAdmin_addSubscriptionToPendingList(admin,subEP);
+	}
+	else{
+		int i;
+		topic_subscription_pt subscription = hashMap_get(admin->subscriptions, scope_topic);
+
+		if(subscription == NULL) {
+			pubsub_serializer_service_t *best_serializer = NULL;
+			if( (status=pubsubAdmin_getBestSerializer(admin, subEP, &best_serializer)) == CELIX_SUCCESS){
+				status += pubsub_topicSubscriptionCreate(admin->bundle_context,subEP->scope, subEP->topic, best_serializer, &subscription);
+			}
+			else{
+				printf("PSA_ZMQ: Cannot find a serializer for subscribing topic %s. Adding it to pending list.\n",subEP->topic);
+				celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+				arrayList_add(admin->noSerializerSubscriptions,subEP);
+				celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+			}
+
+			if (status==CELIX_SUCCESS){
+
+				/* Try to connect internal publishers */
+				if(factory!=NULL){
+					topic_publication_pt topic_pubs = (topic_publication_pt)factory->handle;
+					array_list_pt topic_publishers = pubsub_topicPublicationGetPublisherList(topic_pubs);
+
+					if(topic_publishers!=NULL){
+						for(i=0;i<arrayList_size(topic_publishers);i++){
+							pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(topic_publishers,i);
+							if(pubEP->endpoint !=NULL){
+								status += pubsub_topicSubscriptionConnectPublisher(subscription,pubEP->endpoint);
+							}
+						}
+						arrayList_destroy(topic_publishers);
+					}
+
+				}
+
+				/* Look also for external publishers */
+				if(ext_pub_list!=NULL){
+					for(i=0;i<arrayList_size(ext_pub_list);i++){
+						pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
+						if(pubEP->endpoint !=NULL){
+							status += pubsub_topicSubscriptionConnectPublisher(subscription,pubEP->endpoint);
+						}
+					}
+				}
+
+				pubsub_topicSubscriptionAddSubscriber(subscription,subEP);
+
+				status += pubsub_topicSubscriptionStart(subscription);
+
+			}
+
+			if(status==CELIX_SUCCESS){
+
+				hashMap_put(admin->subscriptions,strdup(scope_topic),subscription);
+
+				connectTopicPubSubToSerializer(admin, best_serializer, subscription, false);
+			}
+		}
+
+		if (status == CELIX_SUCCESS){
+			pubsub_topicIncreaseNrSubscribers(subscription);
+		}
+	}
+
+	free(scope_topic);
+	celixThreadMutex_unlock(&admin->externalPublicationsLock);
+	celixThreadMutex_unlock(&admin->localPublicationsLock);
+	celixThreadMutex_unlock(&admin->subscriptionsLock);
+	celixThreadMutex_unlock(&admin->pendingSubscriptionsLock);
+
+	return status;
+
+}
+
+celix_status_t pubsubAdmin_removeSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
+	celix_status_t status = CELIX_SUCCESS;
+
+	printf("PSA_ZMQ: Removing subscription [FWUUID=%s bundleID=%ld topic=%s]\n",subEP->frameworkUUID,subEP->serviceID,subEP->topic);
+
+	char* scope_topic = createScopeTopicKey(subEP->scope, subEP->topic);
+
+	celixThreadMutex_lock(&admin->subscriptionsLock);
+	topic_subscription_pt sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,scope_topic);
+	if(sub!=NULL){
+		pubsub_topicDecreaseNrSubscribers(sub);
+		if(pubsub_topicGetNrSubscribers(sub) == 0) {
+			status = pubsub_topicSubscriptionRemoveSubscriber(sub,subEP);
+		}
+	}
+	celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+	if(sub==NULL){
+		/* Maybe the endpoint was pending */
+		celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+		if(!arrayList_removeElement(admin->noSerializerSubscriptions, subEP)){
+			status = CELIX_ILLEGAL_STATE;
+		}
+		celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+	}
+
+	free(scope_topic);
+
+
+
+	return status;
+
+}
+
+celix_status_t pubsubAdmin_addPublication(pubsub_admin_pt admin, pubsub_endpoint_pt pubEP) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	printf("PSA_ZMQ: Received publication [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n", pubEP->frameworkUUID, pubEP->serviceID, pubEP->scope, pubEP->topic);
+
+	const char* fwUUID = NULL;
+
+	bundleContext_getProperty(admin->bundle_context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &fwUUID);
+	if (fwUUID == NULL) {
+		printf("PSA_ZMQ: Cannot retrieve fwUUID.\n");
+		return CELIX_INVALID_BUNDLE_CONTEXT;
+	}
+
+	char *scope_topic = createScopeTopicKey(pubEP->scope, pubEP->topic);
+
+	if ((strcmp(pubEP->frameworkUUID, fwUUID) == 0) && (pubEP->endpoint == NULL)) {
+
+		celixThreadMutex_lock(&admin->localPublicationsLock);
+
+		service_factory_pt factory = (service_factory_pt) hashMap_get(admin->localPublications, scope_topic);
+
+		if (factory == NULL) {
+			topic_publication_pt pub = NULL;
+			pubsub_serializer_service_t *best_serializer = NULL;
+			if( (status=pubsubAdmin_getBestSerializer(admin, pubEP, &best_serializer)) == CELIX_SUCCESS){
+				status = pubsub_topicPublicationCreate(admin->bundle_context, pubEP, best_serializer, admin->ipAddress, admin->basePort, admin->maxPort, &pub);
+			}
+			else{
+				printf("PSA_ZMQ: Cannot find a serializer for publishing topic %s. Adding it to pending list.\n", pubEP->topic);
+				celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+				arrayList_add(admin->noSerializerPublications,pubEP);
+				celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+			}
+
+			if (status == CELIX_SUCCESS) {
+				status = pubsub_topicPublicationStart(admin->bundle_context, pub, &factory);
+				if (status == CELIX_SUCCESS && factory != NULL) {
+					hashMap_put(admin->localPublications, strdup(scope_topic), factory);
+					connectTopicPubSubToSerializer(admin, best_serializer, pub, true);
+				}
+			} else {
+				printf("PSA_ZMQ: Cannot create a topicPublication for scope=%s, topic=%s (bundle %ld).\n", pubEP->scope, pubEP->topic, pubEP->serviceID);
+			}
+		} else {
+			//just add the new EP to the list
+			topic_publication_pt pub = (topic_publication_pt) factory->handle;
+			pubsub_topicPublicationAddPublisherEP(pub, pubEP);
+		}
+
+		celixThreadMutex_unlock(&admin->localPublicationsLock);
+	}
+	else{
+
+		celixThreadMutex_lock(&admin->externalPublicationsLock);
+		array_list_pt ext_pub_list = (array_list_pt) hashMap_get(admin->externalPublications, scope_topic);
+		if (ext_pub_list == NULL) {
+			arrayList_create(&ext_pub_list);
+			hashMap_put(admin->externalPublications, strdup(scope_topic), ext_pub_list);
+		}
+
+		arrayList_add(ext_pub_list, pubEP);
+
+		celixThreadMutex_unlock(&admin->externalPublicationsLock);
+	}
+
+	/* Re-evaluate the pending subscriptions */
+	celixThreadMutex_lock(&admin->pendingSubscriptionsLock);
+
+	hash_map_entry_pt pendingSub = hashMap_getEntry(admin->pendingSubscriptions, scope_topic);
+	if (pendingSub != NULL) { //There were pending subscription for the just published topic. Let's connect them.
+		char* topic = (char*) hashMapEntry_getKey(pendingSub);
+		array_list_pt pendingSubList = (array_list_pt) hashMapEntry_getValue(pendingSub);
+		int i;
+		for (i = 0; i < arrayList_size(pendingSubList); i++) {
+			pubsub_endpoint_pt subEP = (pubsub_endpoint_pt) arrayList_get(pendingSubList, i);
+			pubsubAdmin_addSubscription(admin, subEP);
+		}
+		hashMap_remove(admin->pendingSubscriptions, scope_topic);
+		arrayList_clear(pendingSubList);
+		arrayList_destroy(pendingSubList);
+		free(topic);
+	}
+
+	celixThreadMutex_unlock(&admin->pendingSubscriptionsLock);
+
+	/* Connect the new publisher to the subscription for his topic, if there is any */
+	celixThreadMutex_lock(&admin->subscriptionsLock);
+
+	topic_subscription_pt sub = (topic_subscription_pt) hashMap_get(admin->subscriptions, scope_topic);
+	if (sub != NULL && pubEP->endpoint != NULL) {
+		pubsub_topicSubscriptionAddConnectPublisherToPendingList(sub, pubEP->endpoint);
+	}
+
+	/* And check also for ANY subscription */
+	topic_subscription_pt any_sub = (topic_subscription_pt) hashMap_get(admin->subscriptions, PUBSUB_ANY_SUB_TOPIC);
+	if (any_sub != NULL && pubEP->endpoint != NULL) {
+		pubsub_topicSubscriptionAddConnectPublisherToPendingList(any_sub, pubEP->endpoint);
+	}
+
+	free(scope_topic);
+
+	celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+	return status;
+
+}
+
+celix_status_t pubsubAdmin_removePublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP){
+	celix_status_t status = CELIX_SUCCESS;
+	int count = 0;
+
+	printf("PSA_ZMQ: Removing publication [FWUUID=%s bundleID=%ld topic=%s]\n",pubEP->frameworkUUID,pubEP->serviceID,pubEP->topic);
+
+	const char* fwUUID = NULL;
+
+	bundleContext_getProperty(admin->bundle_context,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
+	if(fwUUID==NULL){
+		printf("PSA_ZMQ: Cannot retrieve fwUUID.\n");
+		return CELIX_INVALID_BUNDLE_CONTEXT;
+	}
+	char *scope_topic = createScopeTopicKey(pubEP->scope, pubEP->topic);
+
+	if(strcmp(pubEP->frameworkUUID,fwUUID)==0){
+
+		celixThreadMutex_lock(&admin->localPublicationsLock);
+		service_factory_pt factory = (service_factory_pt)hashMap_get(admin->localPublications,scope_topic);
+		if(factory!=NULL){
+			topic_publication_pt pub = (topic_publication_pt)factory->handle;
+			pubsub_topicPublicationRemovePublisherEP(pub,pubEP);
+		}
+		celixThreadMutex_unlock(&admin->localPublicationsLock);
+
+		if(factory==NULL){
+			/* Maybe the endpoint was pending */
+			celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+			if(!arrayList_removeElement(admin->noSerializerPublications, pubEP)){
+				status = CELIX_ILLEGAL_STATE;
+			}
+			celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+		}
+	}
+	else{
+
+		celixThreadMutex_lock(&admin->externalPublicationsLock);
+		array_list_pt ext_pub_list = (array_list_pt)hashMap_get(admin->externalPublications,scope_topic);
+		if(ext_pub_list!=NULL){
+			int i;
+			bool found = false;
+			for(i=0;!found && i<arrayList_size(ext_pub_list);i++){
+				pubsub_endpoint_pt p  = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
+				found = pubsubEndpoint_equals(pubEP,p);
+				if (found){
+					arrayList_remove(ext_pub_list,i);
+				}
+			}
+			// Check if there are more publishers on the same endpoint (happens when 1 celix-instance with multiple bundles publish in same topic)
+			for(i=0; i<arrayList_size(ext_pub_list);i++) {
+				pubsub_endpoint_pt p  = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
+				if (strcmp(pubEP->endpoint,p->endpoint) == 0) {
+					count++;
+				}
+			}
+
+			if(arrayList_size(ext_pub_list)==0){
+				hash_map_entry_pt entry = hashMap_getEntry(admin->externalPublications,scope_topic);
+				char* topic = (char*)hashMapEntry_getKey(entry);
+				array_list_pt list = (array_list_pt)hashMapEntry_getValue(entry);
+				hashMap_remove(admin->externalPublications,topic);
+				arrayList_destroy(list);
+				free(topic);
+			}
+		}
+
+		celixThreadMutex_unlock(&admin->externalPublicationsLock);
+	}
+
+	/* Check if this publisher was connected to one of our subscribers*/
+	celixThreadMutex_lock(&admin->subscriptionsLock);
+
+	topic_subscription_pt sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,scope_topic);
+	if(sub!=NULL && pubEP->endpoint!=NULL && count == 0){
+		pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(sub,pubEP->endpoint);
+	}
+
+	/* And check also for ANY subscription */
+	topic_subscription_pt any_sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,PUBSUB_ANY_SUB_TOPIC);
+	if(any_sub!=NULL && pubEP->endpoint!=NULL && count == 0){
+		pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(any_sub,pubEP->endpoint);
+	}
+
+	free(scope_topic);
+	celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+	return status;
+
+}
+
+celix_status_t pubsubAdmin_closeAllPublications(pubsub_admin_pt admin, char *scope, char* topic){
+	celix_status_t status = CELIX_SUCCESS;
+
+	printf("PSA_ZMQ: Closing all publications\n");
+
+	celixThreadMutex_lock(&admin->localPublicationsLock);
+	char *scope_topic = createScopeTopicKey(scope, topic);
+	hash_map_entry_pt pubsvc_entry = (hash_map_entry_pt)hashMap_getEntry(admin->localPublications,scope_topic);
+	if(pubsvc_entry!=NULL){
+		char* key = (char*)hashMapEntry_getKey(pubsvc_entry);
+		service_factory_pt factory= (service_factory_pt)hashMapEntry_getValue(pubsvc_entry);
+		topic_publication_pt pub = (topic_publication_pt)factory->handle;
+		status += pubsub_topicPublicationStop(pub);
+		disconnectTopicPubSubFromSerializer(admin, pub, true);
+		status += pubsub_topicPublicationDestroy(pub);
+		hashMap_remove(admin->localPublications,scope_topic);
+		free(key);
+		free(factory);
+	}
+	free(scope_topic);
+	celixThreadMutex_unlock(&admin->localPublicationsLock);
+
+	return status;
+
+}
+
+celix_status_t pubsubAdmin_closeAllSubscriptions(pubsub_admin_pt admin,char* scope,char* topic){
+	celix_status_t status = CELIX_SUCCESS;
+
+	printf("PSA_ZMQ: Closing all subscriptions\n");
+
+	celixThreadMutex_lock(&admin->subscriptionsLock);
+	char *scope_topic = createScopeTopicKey(scope, topic);
+	hash_map_entry_pt sub_entry = (hash_map_entry_pt)hashMap_getEntry(admin->subscriptions,scope_topic);
+	if(sub_entry!=NULL){
+		char* topic = (char*)hashMapEntry_getKey(sub_entry);
+
+		topic_subscription_pt ts = (topic_subscription_pt)hashMapEntry_getValue(sub_entry);
+		status += pubsub_topicSubscriptionStop(ts);
+		disconnectTopicPubSubFromSerializer(admin, ts, false);
+		status += pubsub_topicSubscriptionDestroy(ts);
+		hashMap_remove(admin->subscriptions,scope_topic);
+		free(topic);
+
+	}
+	free(scope_topic);
+	celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+	return status;
+
+}
+
+
+#ifndef ANDROID
+static celix_status_t pubsubAdmin_getIpAdress(const char* interface, char** ip) {
+	celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+
+	struct ifaddrs *ifaddr, *ifa;
+	char host[NI_MAXHOST];
+
+	if (getifaddrs(&ifaddr) != -1)
+	{
+		for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next)
+		{
+			if (ifa->ifa_addr == NULL)
+				continue;
+
+			if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) {
+				if (interface == NULL) {
+					*ip = strdup(host);
+					status = CELIX_SUCCESS;
+				}
+				else if (strcmp(ifa->ifa_name, interface) == 0) {
+					*ip = strdup(host);
+					status = CELIX_SUCCESS;
+				}
+			}
+		}
+
+		freeifaddrs(ifaddr);
+	}
+
+	return status;
+}
+#endif
+
+static celix_status_t pubsubAdmin_addSubscriptionToPendingList(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
+	celix_status_t status = CELIX_SUCCESS;
+	char* scope_topic = createScopeTopicKey(subEP->scope, subEP->topic);
+	array_list_pt pendingListPerTopic = hashMap_get(admin->pendingSubscriptions,scope_topic);
+	if(pendingListPerTopic==NULL){
+		arrayList_create(&pendingListPerTopic);
+		hashMap_put(admin->pendingSubscriptions,strdup(scope_topic),pendingListPerTopic);
+	}
+	arrayList_add(pendingListPerTopic,subEP);
+	free(scope_topic);
+	return status;
+}
+
+celix_status_t pubsubAdmin_serializerAdded(void * handle, service_reference_pt reference, void * service){
+	/* Assumption: serializers are all available at startup.
+	 * If a new (possibly better) serializer is installed and started, already created topic_publications/subscriptions will not be destroyed and recreated */
+
+	celix_status_t status = CELIX_SUCCESS;
+	int i=0;
+
+	const char *serType = NULL;
+	serviceReference_getProperty(reference, PUBSUB_SERIALIZER_TYPE_KEY,&serType);
+	if(serType == NULL){
+		printf("Serializer serviceReference %p has no pubsub_serializer.type property specified\n",reference);
+		return CELIX_SERVICE_EXCEPTION;
+	}
+
+	pubsub_admin_pt admin = (pubsub_admin_pt)handle;
+	celixThreadMutex_lock(&admin->serializerListLock);
+	arrayList_add(admin->serializerList, reference);
+	celixThreadMutex_unlock(&admin->serializerListLock);
+
+	/* Now let's re-evaluate the pending */
+	celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+
+	for(i=0;i<arrayList_size(admin->noSerializerSubscriptions);i++){
+		pubsub_endpoint_pt ep = (pubsub_endpoint_pt)arrayList_get(admin->noSerializerSubscriptions,i);
+		pubsub_serializer_service_t *best_serializer = NULL;
+		pubsubAdmin_getBestSerializer(admin, ep, &best_serializer);
+		if(best_serializer != NULL){ /* Finally we have a valid serializer! */
+			pubsubAdmin_addSubscription(admin, ep);
+		}
+	}
+
+	for(i=0;i<arrayList_size(admin->noSerializerPublications);i++){
+		pubsub_endpoint_pt ep = (pubsub_endpoint_pt)arrayList_get(admin->noSerializerPublications,i);
+		pubsub_serializer_service_t *best_serializer = NULL;
+		pubsubAdmin_getBestSerializer(admin, ep, &best_serializer);
+		if(best_serializer != NULL){ /* Finally we have a valid serializer! */
+			pubsubAdmin_addPublication(admin, ep);
+		}
+	}
+
+	celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+
+	printf("PSA_ZMQ: %s serializer added\n",serType);
+
+	return status;
+}
+
+celix_status_t pubsubAdmin_serializerRemoved(void * handle, service_reference_pt reference, void * service){
+
+	pubsub_admin_pt admin = (pubsub_admin_pt)handle;
+	int i=0, j=0;
+	const char *serType = NULL;
+
+	serviceReference_getProperty(reference, PUBSUB_SERIALIZER_TYPE_KEY,&serType);
+	if(serType == NULL){
+		printf("Serializer serviceReference %p has no pubsub_serializer.type property specified\n",reference);
+		return CELIX_SERVICE_EXCEPTION;
+	}
+
+	celixThreadMutex_lock(&admin->serializerListLock);
+	/* Remove the serializer from the list */
+	arrayList_removeElement(admin->serializerList, reference);
+	celixThreadMutex_unlock(&admin->serializerListLock);
+
+
+	celixThreadMutex_lock(&admin->usedSerializersLock);
+	array_list_pt topicPubList = (array_list_pt)hashMap_remove(admin->topicPublicationsPerSerializer, service);
+	array_list_pt topicSubList = (array_list_pt)hashMap_remove(admin->topicSubscriptionsPerSerializer, service);
+	celixThreadMutex_unlock(&admin->usedSerializersLock);
+
+	/* Now destroy the topicPublications, but first put back the pubsub_endpoints back to the noSerializer pending list */
+	if(topicPubList!=NULL){
+		for(i=0;i<arrayList_size(topicPubList);i++){
+			topic_publication_pt topicPub = (topic_publication_pt)arrayList_get(topicPubList,i);
+			/* Stop the topic publication */
+			pubsub_topicPublicationStop(topicPub);
+			/* Get the endpoints that are going to be orphan */
+			array_list_pt pubList = pubsub_topicPublicationGetPublisherList(topicPub);
+			for(j=0;j<arrayList_size(pubList);j++){
+				pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pubList,j);
+				/* Remove the publication */
+				pubsubAdmin_removePublication(admin, pubEP);
+				/* Reset the endpoint field, so that will be recreated from scratch when a new serializer will be found */
+				if(pubEP->endpoint!=NULL){
+					free(pubEP->endpoint);
+					pubEP->endpoint = NULL;
+				}
+				/* Add the orphan endpoint to the noSerializer pending list */
+				celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+				arrayList_add(admin->noSerializerPublications,pubEP);
+				celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+			}
+			arrayList_destroy(pubList);
+
+			/* Cleanup also the localPublications hashmap*/
+			celixThreadMutex_lock(&admin->localPublicationsLock);
+			hash_map_iterator_pt iter = hashMapIterator_create(admin->localPublications);
+			char *key = NULL;
+			service_factory_pt factory = NULL;
+			while(hashMapIterator_hasNext(iter)){
+				hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+				factory = (service_factory_pt)hashMapEntry_getValue(entry);
+				topic_publication_pt pub = (topic_publication_pt)factory->handle;
+				if(pub==topicPub){
+					key = (char*)hashMapEntry_getKey(entry);
+					break;
+				}
+			}
+			hashMapIterator_destroy(iter);
+			if(key!=NULL){
+				hashMap_remove(admin->localPublications, key);
+				free(factory);
+				free(key);
+			}
+			celixThreadMutex_unlock(&admin->localPublicationsLock);
+
+			/* Finally destroy the topicPublication */
+			pubsub_topicPublicationDestroy(topicPub);
+		}
+		arrayList_destroy(topicPubList);
+	}
+
+	/* Now destroy the topicSubscriptions, but first put back the pubsub_endpoints back to the noSerializer pending list */
+	if(topicSubList!=NULL){
+		for(i=0;i<arrayList_size(topicSubList);i++){
+			topic_subscription_pt topicSub = (topic_subscription_pt)arrayList_get(topicSubList,i);
+			/* Stop the topic subscription */
+			pubsub_topicSubscriptionStop(topicSub);
+			/* Get the endpoints that are going to be orphan */
+			array_list_pt subList = pubsub_topicSubscriptionGetSubscribersList(topicSub);
+			for(j=0;j<arrayList_size(subList);j++){
+				pubsub_endpoint_pt subEP = (pubsub_endpoint_pt)arrayList_get(subList,j);
+				/* Remove the subscription */
+				pubsubAdmin_removeSubscription(admin, subEP);
+				/* Reset the endpoint field, so that will be recreated from scratch when a new serializer will be found */
+				if(subEP->endpoint!=NULL){
+					free(subEP->endpoint);
+					subEP->endpoint = NULL;
+				}
+				/* Add the orphan endpoint to the noSerializer pending list */
+				celixThreadMutex_lock(&admin->noSerializerPendingsLock);
+				arrayList_add(admin->noSerializerSubscriptions,subEP);
+				celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
+			}
+
+			/* Cleanup also the subscriptions hashmap*/
+			celixThreadMutex_lock(&admin->subscriptionsLock);
+			hash_map_iterator_pt iter = hashMapIterator_create(admin->subscriptions);
+			char *key = NULL;
+			while(hashMapIterator_hasNext(iter)){
+				hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+				topic_subscription_pt sub = (topic_subscription_pt)hashMapEntry_getValue(entry);
+				if(sub==topicSub){
+					key = (char*)hashMapEntry_getKey(entry);
+					break;
+				}
+			}
+			hashMapIterator_destroy(iter);
+			if(key!=NULL){
+				hashMap_remove(admin->subscriptions, key);
+				free(key);
+			}
+			celixThreadMutex_unlock(&admin->subscriptionsLock);
+
+			/* Finally destroy the topicSubscription */
+			pubsub_topicSubscriptionDestroy(topicSub);
+		}
+		arrayList_destroy(topicSubList);
+	}
+
+
+
+	printf("PSA_ZMQ: %s serializer removed\n",serType);
+
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t pubsubAdmin_matchEndpoint(pubsub_admin_pt admin, pubsub_endpoint_pt endpoint, double* score){
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&admin->serializerListLock);
+	status = pubsub_admin_match(endpoint->topic_props,PUBSUB_ADMIN_TYPE,admin->serializerList,score);
+	celixThreadMutex_unlock(&admin->serializerListLock);
+
+	return status;
+}
+
+/* This one recall the same logic as in the match function */
+static celix_status_t pubsubAdmin_getBestSerializer(pubsub_admin_pt admin,pubsub_endpoint_pt ep, pubsub_serializer_service_t **serSvc){
+
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&admin->serializerListLock);
+	status = pubsub_admin_get_best_serializer(ep->topic_props, admin->serializerList, serSvc);
+	celixThreadMutex_unlock(&admin->serializerListLock);
+
+	return status;
+
+}
+
+static void connectTopicPubSubToSerializer(pubsub_admin_pt admin,pubsub_serializer_service_t *serializer,void *topicPubSub,bool isPublication){
+
+	celixThreadMutex_lock(&admin->usedSerializersLock);
+
+	hash_map_pt map = isPublication?admin->topicPublicationsPerSerializer:admin->topicSubscriptionsPerSerializer;
+	array_list_pt list = (array_list_pt)hashMap_get(map,serializer);
+	if(list==NULL){
+		arrayList_create(&list);
+		hashMap_put(map,serializer,list);
+	}
+	arrayList_add(list,topicPubSub);
+
+	celixThreadMutex_unlock(&admin->usedSerializersLock);
+
+}
+
+static void disconnectTopicPubSubFromSerializer(pubsub_admin_pt admin,void *topicPubSub,bool isPublication){
+
+	celixThreadMutex_lock(&admin->usedSerializersLock);
+
+	hash_map_pt map = isPublication?admin->topicPublicationsPerSerializer:admin->topicSubscriptionsPerSerializer;
+	hash_map_iterator_pt iter = hashMapIterator_create(map);
+	while(hashMapIterator_hasNext(iter)){
+		array_list_pt list = (array_list_pt)hashMapIterator_nextValue(iter);
+		if(arrayList_removeElement(list, topicPubSub)){ //Found it!
+			break;
+		}
+	}
+	hashMapIterator_destroy(iter);
+
+	celixThreadMutex_unlock(&admin->usedSerializersLock);
+
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_zmq/src/pubsub_admin_impl.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/src/pubsub_admin_impl.h b/pubsub/pubsub_admin_zmq/src/pubsub_admin_impl.h
new file mode 100644
index 0000000..03e8556
--- /dev/null
+++ b/pubsub/pubsub_admin_zmq/src/pubsub_admin_impl.h
@@ -0,0 +1,109 @@
+/**
+ *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.
+ */
+/*
+ * pubsub_admin_impl.h
+ *
+ *  \date       Dec 5, 2013
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef PUBSUB_ADMIN_ZMQ_IMPL_H_
+#define PUBSUB_ADMIN_ZMQ_IMPL_H_
+
+#include <czmq.h>
+/* The following undefs prevent the collision between:
+ * - sys/syslog.h (which is included within czmq)
+ * - celix/dfi/dfi_log_util.h
+ */
+#undef LOG_DEBUG
+#undef LOG_WARNING
+#undef LOG_INFO
+#undef LOG_WARNING
+
+#include "pubsub_admin.h"
+#include "pubsub_admin_match.h"
+#include "log_helper.h"
+
+#define PSA_ZMQ_BASE_PORT "PSA_ZMQ_BASE_PORT"
+#define PSA_ZMQ_MAX_PORT "PSA_ZMQ_MAX_PORT"
+
+#define PSA_ZMQ_DEFAULT_BASE_PORT 5501
+#define PSA_ZMQ_DEFAULT_MAX_PORT 6000
+
+#define PUBSUB_ADMIN_TYPE	"zmq"
+
+struct pubsub_admin {
+
+	bundle_context_pt bundle_context;
+	log_helper_pt loghelper;
+
+	/* List of the available serializers */
+	celix_thread_mutex_t serializerListLock; // List<serializers>
+	array_list_pt serializerList;
+
+	celix_thread_mutex_t localPublicationsLock;
+	hash_map_pt localPublications;//<topic(string),service_factory_pt>
+
+	celix_thread_mutex_t externalPublicationsLock;
+	hash_map_pt externalPublications;//<topic(string),List<pubsub_ep>>
+
+	celix_thread_mutex_t subscriptionsLock;
+	hash_map_pt subscriptions; //<topic(string),topic_subscription>
+
+	celix_thread_mutex_t pendingSubscriptionsLock;
+	celix_thread_mutexattr_t pendingSubscriptionsAttr;
+	hash_map_pt pendingSubscriptions; //<topic(string),List<pubsub_ep>>
+
+	/* Those are used to keep track of valid subscriptions/publications that still have no valid serializer */
+	celix_thread_mutex_t noSerializerPendingsLock;
+	celix_thread_mutexattr_t noSerializerPendingsAttr;
+	array_list_pt noSerializerSubscriptions; // List<pubsub_ep>
+	array_list_pt noSerializerPublications; // List<pubsub_ep>
+
+	celix_thread_mutex_t usedSerializersLock;
+	hash_map_pt topicSubscriptionsPerSerializer; // <serializer,List<topicSubscription>>
+	hash_map_pt topicPublicationsPerSerializer; // <serializer,List<topicPublications>>
+
+	char* ipAddress;
+
+	zactor_t* zmq_auth;
+
+    unsigned int basePort;
+    unsigned int maxPort;
+};
+
+celix_status_t pubsubAdmin_create(bundle_context_pt context, pubsub_admin_pt *admin);
+celix_status_t pubsubAdmin_destroy(pubsub_admin_pt admin);
+
+celix_status_t pubsubAdmin_addSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
+celix_status_t pubsubAdmin_removeSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
+
+celix_status_t pubsubAdmin_addPublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP);
+celix_status_t pubsubAdmin_removePublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP);
+
+celix_status_t pubsubAdmin_closeAllPublications(pubsub_admin_pt admin,char* scope, char* topic);
+celix_status_t pubsubAdmin_closeAllSubscriptions(pubsub_admin_pt admin,char* scope,char* topic);
+
+celix_status_t pubsubAdmin_serializerAdded(void * handle, service_reference_pt reference, void * service);
+celix_status_t pubsubAdmin_serializerRemoved(void * handle, service_reference_pt reference, void * service);
+
+celix_status_t pubsubAdmin_matchEndpoint(pubsub_admin_pt admin, pubsub_endpoint_pt endpoint, double* score);
+
+#endif /* PUBSUB_ADMIN_ZMQ_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_zmq/src/topic_publication.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/src/topic_publication.c b/pubsub/pubsub_admin_zmq/src/topic_publication.c
new file mode 100644
index 0000000..e405866
--- /dev/null
+++ b/pubsub/pubsub_admin_zmq/src/topic_publication.c
@@ -0,0 +1,630 @@
+/**
+ *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.
+ */
+
+#include <czmq.h>
+/* The following undefs prevent the collision between:
+ * - sys/syslog.h (which is included within czmq)
+ * - celix/dfi/dfi_log_util.h
+ */
+#undef LOG_DEBUG
+#undef LOG_WARNING
+#undef LOG_INFO
+#undef LOG_WARNING
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "array_list.h"
+#include "celixbool.h"
+#include "service_registration.h"
+#include "utils.h"
+#include "service_factory.h"
+#include "version.h"
+
+#include "pubsub_common.h"
+#include "pubsub_utils.h"
+#include "publisher.h"
+
+#include "topic_publication.h"
+
+#include "pubsub_serializer.h"
+
+#ifdef BUILD_WITH_ZMQ_SECURITY
+	#include "zmq_crypto.h"
+
+	#define MAX_CERT_PATH_LENGTH 512
+#endif
+
+#define EP_ADDRESS_LEN		32
+#define ZMQ_BIND_MAX_RETRY	5
+
+#define FIRST_SEND_DELAY	2
+
+struct topic_publication {
+	zsock_t* zmq_socket;
+	celix_thread_mutex_t socket_lock; //Protects zmq_socket access
+	zcert_t * zmq_cert;
+	char* endpoint;
+	service_registration_pt svcFactoryReg;
+	array_list_pt pub_ep_list; //List<pubsub_endpoint>
+	hash_map_pt boundServices; //<bundle_pt,bound_service>
+	pubsub_serializer_service_t *serializer;
+	celix_thread_mutex_t tp_lock;
+};
+
+typedef struct publish_bundle_bound_service {
+	topic_publication_pt parent;
+	pubsub_publisher_t service;
+	bundle_pt bundle;
+	char *topic;
+	hash_map_pt msgTypes;
+	unsigned short getCount;
+	celix_thread_mutex_t mp_lock; //Protects publish_bundle_bound_service data structure
+	bool mp_send_in_progress;
+	array_list_pt mp_parts;
+}* publish_bundle_bound_service_pt;
+
+/* Note: correct locking order is
+ * 1. tp_lock
+ * 2. mp_lock
+ * 3. socket_lock
+ *
+ * tp_lock and socket_lock are independent.
+ */
+
+typedef struct pubsub_msg{
+	pubsub_msg_header_pt header;
+	char* payload;
+	int payloadSize;
+}* pubsub_msg_pt;
+
+static unsigned int rand_range(unsigned int min, unsigned int max);
+
+static celix_status_t pubsub_topicPublicationGetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service);
+static celix_status_t pubsub_topicPublicationUngetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service);
+
+static publish_bundle_bound_service_pt pubsub_createPublishBundleBoundService(topic_publication_pt tp,bundle_pt bundle);
+static void pubsub_destroyPublishBundleBoundService(publish_bundle_bound_service_pt boundSvc);
+
+static int pubsub_topicPublicationSend(void* handle,unsigned int msgTypeId, const void *msg);
+static int pubsub_topicPublicationSendMultipart(void *handle, unsigned int msgTypeId, const void *inMsg, int flags);
+static int pubsub_localMsgTypeIdForUUID(void* handle, const char* msgType, unsigned int* msgTypeId);
+
+static void delay_first_send_for_late_joiners(void);
+
+celix_status_t pubsub_topicPublicationCreate(bundle_context_pt bundle_context, pubsub_endpoint_pt pubEP, pubsub_serializer_service_t *best_serializer, char* bindIP, unsigned int basePort, unsigned int maxPort, topic_publication_pt *out){
+	celix_status_t status = CELIX_SUCCESS;
+
+#ifdef BUILD_WITH_ZMQ_SECURITY
+	char* secure_topics = NULL;
+	bundleContext_getProperty(bundle_context, "SECURE_TOPICS", (const char **) &secure_topics);
+
+	if (secure_topics){
+		array_list_pt secure_topics_list = pubsub_getTopicsFromString(secure_topics);
+
+		int i;
+		int secure_topics_size = arrayList_size(secure_topics_list);
+		for (i = 0; i < secure_topics_size; i++){
+			char* top = arrayList_get(secure_topics_list, i);
+			if (strcmp(pubEP->topic, top) == 0){
+				printf("PSA_ZMQ_TP: Secure topic: '%s'\n", top);
+				pubEP->is_secure = true;
+			}
+			free(top);
+			top = NULL;
+		}
+
+		arrayList_destroy(secure_topics_list);
+	}
+
+	zcert_t* pub_cert = NULL;
+	if (pubEP->is_secure){
+		char* keys_bundle_dir = pubsub_getKeysBundleDir(bundle_context);
+		if (keys_bundle_dir == NULL){
+			return CELIX_SERVICE_EXCEPTION;
+		}
+
+		const char* keys_file_path = NULL;
+		const char* keys_file_name = NULL;
+		bundleContext_getProperty(bundle_context, PROPERTY_KEYS_FILE_PATH, &keys_file_path);
+		bundleContext_getProperty(bundle_context, PROPERTY_KEYS_FILE_NAME, &keys_file_name);
+
+		char cert_path[MAX_CERT_PATH_LENGTH];
+
+		//certificate path ".cache/bundle{id}/version0.0/./META-INF/keys/publisher/private/pub_{topic}.key"
+		snprintf(cert_path, MAX_CERT_PATH_LENGTH, "%s/META-INF/keys/publisher/private/pub_%s.key.enc", keys_bundle_dir, pubEP->topic);
+		free(keys_bundle_dir);
+		printf("PSA_ZMQ_TP: Loading key '%s'\n", cert_path);
+
+		pub_cert = get_zcert_from_encoded_file((char *) keys_file_path, (char *) keys_file_name, cert_path);
+		if (pub_cert == NULL){
+			printf("PSA_ZMQ_TP: Cannot load key '%s'\n", cert_path);
+			printf("PSA_ZMQ_TP: Topic '%s' NOT SECURED !\n", pubEP->topic);
+			pubEP->is_secure = false;
+		}
+	}
+#endif
+
+	zsock_t* socket = zsock_new (ZMQ_PUB);
+	if(socket==NULL){
+		#ifdef BUILD_WITH_ZMQ_SECURITY
+			if (pubEP->is_secure){
+				zcert_destroy(&pub_cert);
+			}
+		#endif
+
+        perror("Error for zmq_socket");
+		return CELIX_SERVICE_EXCEPTION;
+	}
+#ifdef BUILD_WITH_ZMQ_SECURITY
+	if (pubEP->is_secure){
+		zcert_apply (pub_cert, socket); // apply certificate to socket
+		zsock_set_curve_server (socket, true); // setup the publisher's socket to use the curve functions
+	}
+#endif
+
+	int rv = -1, retry=0;
+	char* ep = malloc(EP_ADDRESS_LEN);
+    char bindAddress[EP_ADDRESS_LEN];
+
+	while(rv==-1 && retry<ZMQ_BIND_MAX_RETRY){
+		/* Randomized part due to same bundle publishing on different topics */
+		unsigned int port = rand_range(basePort,maxPort);
+		memset(ep,0,EP_ADDRESS_LEN);
+        memset(bindAddress, 0, EP_ADDRESS_LEN);
+
+		snprintf(ep,EP_ADDRESS_LEN,"tcp://%s:%u",bindIP,port);
+        snprintf(bindAddress, EP_ADDRESS_LEN, "tcp://0.0.0.0:%u", port); //NOTE using a different bind addres than endpoint address
+		rv = zsock_bind (socket, "%s", bindAddress);
+        if (rv == -1) {
+            perror("Error for zmq_bind");
+        }
+		retry++;
+	}
+
+	if(rv == -1){
+		free(ep);
+		return CELIX_SERVICE_EXCEPTION;
+	}
+
+	/* ZMQ stuffs are all fine at this point. Let's create and initialize the structure */
+
+	topic_publication_pt pub = calloc(1,sizeof(*pub));
+
+	arrayList_create(&(pub->pub_ep_list));
+	pub->boundServices = hashMap_create(NULL,NULL,NULL,NULL);
+	celixThreadMutex_create(&(pub->tp_lock),NULL);
+
+	pub->endpoint = ep;
+	pub->zmq_socket = socket;
+	pub->serializer = best_serializer;
+
+	celixThreadMutex_create(&(pub->socket_lock),NULL);
+
+#ifdef BUILD_WITH_ZMQ_SECURITY
+	if (pubEP->is_secure){
+		pub->zmq_cert = pub_cert;
+	}
+#endif
+
+	pubsub_topicPublicationAddPublisherEP(pub,pubEP);
+
+	*out = pub;
+
+	return status;
+}
+
+celix_status_t pubsub_topicPublicationDestroy(topic_publication_pt pub){
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&(pub->tp_lock));
+
+	free(pub->endpoint);
+	arrayList_destroy(pub->pub_ep_list);
+
+	hash_map_iterator_pt iter = hashMapIterator_create(pub->boundServices);
+	while(hashMapIterator_hasNext(iter)){
+		publish_bundle_bound_service_pt bound = hashMapIterator_nextValue(iter);
+		pubsub_destroyPublishBundleBoundService(bound);
+	}
+	hashMapIterator_destroy(iter);
+	hashMap_destroy(pub->boundServices,false,false);
+
+	pub->svcFactoryReg = NULL;
+	pub->serializer = NULL;
+#ifdef BUILD_WITH_ZMQ_SECURITY
+	zcert_destroy(&(pub->zmq_cert));
+#endif
+
+	celixThreadMutex_unlock(&(pub->tp_lock));
+
+	celixThreadMutex_destroy(&(pub->tp_lock));
+
+	celixThreadMutex_lock(&(pub->socket_lock));
+	zsock_destroy(&(pub->zmq_socket));
+	celixThreadMutex_unlock(&(pub->socket_lock));
+
+	celixThreadMutex_destroy(&(pub->socket_lock));
+
+	free(pub);
+
+	return status;
+}
+
+celix_status_t pubsub_topicPublicationStart(bundle_context_pt bundle_context,topic_publication_pt pub,service_factory_pt* svcFactory){
+	celix_status_t status = CELIX_SUCCESS;
+
+	/* Let's register the new service */
+
+	pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pub->pub_ep_list,0);
+
+	if(pubEP!=NULL){
+		service_factory_pt factory = calloc(1, sizeof(*factory));
+		factory->handle = pub;
+		factory->getService = pubsub_topicPublicationGetService;
+		factory->ungetService = pubsub_topicPublicationUngetService;
+
+		properties_pt props = properties_create();
+		properties_set(props,PUBSUB_PUBLISHER_TOPIC,pubEP->topic);
+		properties_set(props,PUBSUB_PUBLISHER_SCOPE,pubEP->scope);
+		properties_set(props,"service.version", PUBSUB_PUBLISHER_SERVICE_VERSION);
+
+		status = bundleContext_registerServiceFactory(bundle_context,PUBSUB_PUBLISHER_SERVICE_NAME,factory,props,&(pub->svcFactoryReg));
+
+		if(status != CELIX_SUCCESS){
+			properties_destroy(props);
+			printf("PSA_ZMQ_PSA_ZMQ_TP: Cannot register ServiceFactory for topic %s (bundle %ld).\n",pubEP->topic,pubEP->serviceID);
+		}
+		else{
+			*svcFactory = factory;
+		}
+	}
+	else{
+		printf("PSA_ZMQ_PSA_ZMQ_TP: Cannot find pubsub_endpoint after adding it...Should never happen!\n");
+		status = CELIX_SERVICE_EXCEPTION;
+	}
+
+	return status;
+}
+
+celix_status_t pubsub_topicPublicationStop(topic_publication_pt pub){
+	return serviceRegistration_unregister(pub->svcFactoryReg);
+}
+
+celix_status_t pubsub_topicPublicationAddPublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep){
+
+	celixThreadMutex_lock(&(pub->tp_lock));
+	ep->endpoint = strdup(pub->endpoint);
+	arrayList_add(pub->pub_ep_list,ep);
+	celixThreadMutex_unlock(&(pub->tp_lock));
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t pubsub_topicPublicationRemovePublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep){
+
+	celixThreadMutex_lock(&(pub->tp_lock));
+	for (int i = 0; i < arrayList_size(pub->pub_ep_list); i++) {
+	        pubsub_endpoint_pt e = arrayList_get(pub->pub_ep_list, i);
+	        if(pubsubEndpoint_equals(ep, e)) {
+	            arrayList_removeElement(pub->pub_ep_list,ep);
+	            break;
+	        }
+	}
+	celixThreadMutex_unlock(&(pub->tp_lock));
+
+	return CELIX_SUCCESS;
+}
+
+array_list_pt pubsub_topicPublicationGetPublisherList(topic_publication_pt pub){
+	array_list_pt list = NULL;
+	celixThreadMutex_lock(&(pub->tp_lock));
+	list = arrayList_clone(pub->pub_ep_list);
+	celixThreadMutex_unlock(&(pub->tp_lock));
+	return list;
+}
+
+
+static celix_status_t pubsub_topicPublicationGetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service) {
+	celix_status_t  status = CELIX_SUCCESS;
+
+	topic_publication_pt publish = (topic_publication_pt)handle;
+
+	celixThreadMutex_lock(&(publish->tp_lock));
+
+	publish_bundle_bound_service_pt bound = (publish_bundle_bound_service_pt)hashMap_get(publish->boundServices,bundle);
+	if(bound==NULL){
+		bound = pubsub_createPublishBundleBoundService(publish,bundle);
+		if(bound!=NULL){
+			hashMap_put(publish->boundServices,bundle,bound);
+		}
+	}
+	else{
+		bound->getCount++;
+	}
+
+	*service = &bound->service;
+
+	celixThreadMutex_unlock(&(publish->tp_lock));
+
+	return status;
+}
+
+static celix_status_t pubsub_topicPublicationUngetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service)  {
+
+	topic_publication_pt publish = (topic_publication_pt)handle;
+
+	celixThreadMutex_lock(&(publish->tp_lock));
+
+	publish_bundle_bound_service_pt bound = (publish_bundle_bound_service_pt)hashMap_get(publish->boundServices,bundle);
+	if(bound!=NULL){
+
+		bound->getCount--;
+		if(bound->getCount==0){
+			pubsub_destroyPublishBundleBoundService(bound);
+			hashMap_remove(publish->boundServices,bundle);
+		}
+
+	}
+	else{
+		long bundleId = -1;
+		bundle_getBundleId(bundle,&bundleId);
+		printf("PSA_ZMQ_TP: Unexpected ungetService call for bundle %ld.\n", bundleId);
+	}
+
+	/* service should be never used for unget, so let's set the pointer to NULL */
+	*service = NULL;
+
+	celixThreadMutex_unlock(&(publish->tp_lock));
+
+	return CELIX_SUCCESS;
+}
+
+static bool send_pubsub_msg(zsock_t* zmq_socket, pubsub_msg_pt msg, bool last){
+
+	bool ret = true;
+
+	zframe_t* headerMsg = zframe_new(msg->header, sizeof(struct pubsub_msg_header));
+	if (headerMsg == NULL) ret=false;
+	zframe_t* payloadMsg = zframe_new(msg->payload, msg->payloadSize);
+	if (payloadMsg == NULL) ret=false;
+
+	delay_first_send_for_late_joiners();
+
+	if( zframe_send(&headerMsg,zmq_socket, ZFRAME_MORE) == -1) ret=false;
+
+	if(!last){
+		if( zframe_send(&payloadMsg,zmq_socket, ZFRAME_MORE) == -1) ret=false;
+	}
+	else{
+		if( zframe_send(&payloadMsg,zmq_socket, 0) == -1) ret=false;
+	}
+
+	if (!ret){
+		zframe_destroy(&headerMsg);
+		zframe_destroy(&payloadMsg);
+	}
+
+	free(msg->header);
+	free(msg->payload);
+	free(msg);
+
+	return ret;
+
+}
+
+static bool send_pubsub_mp_msg(zsock_t* zmq_socket, array_list_pt mp_msg_parts){
+
+	bool ret = true;
+
+	unsigned int i = 0;
+	unsigned int mp_num = arrayList_size(mp_msg_parts);
+	for(;i<mp_num;i++){
+		ret = ret && send_pubsub_msg(zmq_socket, (pubsub_msg_pt)arrayList_get(mp_msg_parts,i), (i==mp_num-1));
+	}
+	arrayList_clear(mp_msg_parts);
+
+	return ret;
+
+}
+
+static int pubsub_topicPublicationSend(void* handle, unsigned int msgTypeId, const void *msg) {
+
+	return pubsub_topicPublicationSendMultipart(handle,msgTypeId,msg, PUBSUB_PUBLISHER_FIRST_MSG | PUBSUB_PUBLISHER_LAST_MSG);
+
+}
+
+static int pubsub_topicPublicationSendMultipart(void *handle, unsigned int msgTypeId, const void *inMsg, int flags){
+
+	int status = 0;
+
+	publish_bundle_bound_service_pt bound = (publish_bundle_bound_service_pt) handle;
+
+	celixThreadMutex_lock(&(bound->parent->tp_lock));
+	celixThreadMutex_lock(&(bound->mp_lock));
+	if( (flags & PUBSUB_PUBLISHER_FIRST_MSG) && !(flags & PUBSUB_PUBLISHER_LAST_MSG) && bound->mp_send_in_progress){ //means a real mp_msg
+		printf("PSA_ZMQ_TP: Multipart send already in progress. Cannot process a new one.\n");
+		celixThreadMutex_unlock(&(bound->mp_lock));
+		celixThreadMutex_unlock(&(bound->parent->tp_lock));
+		return -3;
+	}
+
+	pubsub_msg_serializer_t* msgSer = (pubsub_msg_serializer_t*)hashMap_get(bound->msgTypes, (void*)(uintptr_t)msgTypeId);
+
+	if (msgSer!= NULL) {
+		int major=0, minor=0;
+
+		pubsub_msg_header_pt msg_hdr = calloc(1,sizeof(struct pubsub_msg_header));
+		strncpy(msg_hdr->topic,bound->topic,MAX_TOPIC_LEN-1);
+		msg_hdr->type = msgTypeId;
+
+		if (msgSer->msgVersion != NULL){
+			version_getMajor(msgSer->msgVersion, &major);
+			version_getMinor(msgSer->msgVersion, &minor);
+			msg_hdr->major = major;
+			msg_hdr->minor = minor;
+		}
+
+		void *serializedOutput = NULL;
+		size_t serializedOutputLen = 0;
+		msgSer->serialize(msgSer,inMsg,&serializedOutput, &serializedOutputLen);
+
+		pubsub_msg_pt msg = calloc(1,sizeof(struct pubsub_msg));
+		msg->header = msg_hdr;
+		msg->payload = (char*)serializedOutput;
+		msg->payloadSize = serializedOutputLen;
+		bool snd = true;
+
+		switch(flags){
+		case PUBSUB_PUBLISHER_FIRST_MSG:
+			bound->mp_send_in_progress = true;
+			arrayList_add(bound->mp_parts,msg);
+			break;
+		case PUBSUB_PUBLISHER_PART_MSG:
+			if(!bound->mp_send_in_progress){
+				printf("PSA_ZMQ_TP: ERROR: received msg part without the first part.\n");
+				status = -4;
+			}
+			else{
+				arrayList_add(bound->mp_parts,msg);
+			}
+			break;
+		case PUBSUB_PUBLISHER_LAST_MSG:
+			if(!bound->mp_send_in_progress){
+				printf("PSA_ZMQ_TP: ERROR: received end msg without the first part.\n");
+				status = -4;
+			}
+			else{
+				arrayList_add(bound->mp_parts,msg);
+				snd = send_pubsub_mp_msg(bound->parent->zmq_socket,bound->mp_parts);
+				bound->mp_send_in_progress = false;
+			}
+			break;
+		case PUBSUB_PUBLISHER_FIRST_MSG | PUBSUB_PUBLISHER_LAST_MSG:	//Normal send case
+			snd = send_pubsub_msg(bound->parent->zmq_socket,msg,true);
+			break;
+		default:
+			printf("PSA_ZMQ_TP: ERROR: Invalid MP flags combination\n");
+			status = -4;
+			break;
+		}
+
+		if(status==-4){
+			free(msg);
+		}
+
+		if(!snd){
+			printf("PSA_ZMQ_TP: Failed to send %s message %u.\n",flags == (PUBSUB_PUBLISHER_FIRST_MSG | PUBSUB_PUBLISHER_LAST_MSG) ? "single" : "multipart", msgTypeId);
+		}
+
+	} else {
+        printf("PSA_ZMQ_TP: No msg serializer available for msg type id %d\n", msgTypeId);
+		status=-1;
+	}
+
+	celixThreadMutex_unlock(&(bound->mp_lock));
+	celixThreadMutex_unlock(&(bound->parent->tp_lock));
+
+	return status;
+
+}
+
+static int pubsub_localMsgTypeIdForUUID(void* handle, const char* msgType, unsigned int* msgTypeId){
+	*msgTypeId = utils_stringHash(msgType);
+	return 0;
+}
+
+
+static unsigned int rand_range(unsigned int min, unsigned int max){
+
+	double scaled = (double)(((double)random())/((double)RAND_MAX));
+	return (max-min+1)*scaled + min;
+
+}
+
+static publish_bundle_bound_service_pt pubsub_createPublishBundleBoundService(topic_publication_pt tp,bundle_pt bundle){
+
+	//PRECOND lock on tp->lock
+
+	publish_bundle_bound_service_pt bound = calloc(1, sizeof(*bound));
+
+	if (bound != NULL) {
+
+		bound->parent = tp;
+		bound->bundle = bundle;
+		bound->getCount = 1;
+		bound->mp_send_in_progress = false;
+		celixThreadMutex_create(&bound->mp_lock,NULL);
+
+		if(tp->serializer != NULL){
+			tp->serializer->createSerializerMap(tp->serializer->handle,bundle,&bound->msgTypes);
+		}
+
+		arrayList_create(&bound->mp_parts);
+
+		pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(bound->parent->pub_ep_list,0);
+		bound->topic=strdup(pubEP->topic);
+
+		bound->service.handle = bound;
+		bound->service.localMsgTypeIdForMsgType = pubsub_localMsgTypeIdForUUID;
+		bound->service.send = pubsub_topicPublicationSend;
+		bound->service.sendMultipart = pubsub_topicPublicationSendMultipart;
+
+	}
+
+	return bound;
+}
+
+static void pubsub_destroyPublishBundleBoundService(publish_bundle_bound_service_pt boundSvc){
+
+	//PRECOND lock on tp->lock
+
+	celixThreadMutex_lock(&boundSvc->mp_lock);
+
+
+	if(boundSvc->parent->serializer != NULL && boundSvc->msgTypes != NULL){
+		boundSvc->parent->serializer->destroySerializerMap(boundSvc->parent->serializer->handle, boundSvc->msgTypes);
+	}
+
+	if(boundSvc->mp_parts!=NULL){
+		arrayList_destroy(boundSvc->mp_parts);
+	}
+
+	if(boundSvc->topic!=NULL){
+		free(boundSvc->topic);
+	}
+
+	celixThreadMutex_unlock(&boundSvc->mp_lock);
+	celixThreadMutex_destroy(&boundSvc->mp_lock);
+
+	free(boundSvc);
+
+}
+
+static void delay_first_send_for_late_joiners(){
+
+	static bool firstSend = true;
+
+	if(firstSend){
+		printf("PSA_ZMQ_TP: Delaying first send for late joiners...\n");
+		sleep(FIRST_SEND_DELAY);
+		firstSend = false;
+	}
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_zmq/src/topic_publication.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/src/topic_publication.h b/pubsub/pubsub_admin_zmq/src/topic_publication.h
new file mode 100644
index 0000000..3457263
--- /dev/null
+++ b/pubsub/pubsub_admin_zmq/src/topic_publication.h
@@ -0,0 +1,49 @@
+/**
+ *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.
+ */
+/*
+ * topic_publication.h
+ *
+ *  \date       Sep 24, 2015
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef TOPIC_PUBLICATION_H_
+#define TOPIC_PUBLICATION_H_
+
+#include "publisher.h"
+#include "pubsub_endpoint.h"
+#include "pubsub_common.h"
+
+#include "pubsub_serializer.h"
+
+typedef struct topic_publication *topic_publication_pt;
+
+celix_status_t pubsub_topicPublicationCreate(bundle_context_pt bundle_context,pubsub_endpoint_pt pubEP, pubsub_serializer_service_t *best_serializer, char* bindIP, unsigned int basePort, unsigned int maxPort, topic_publication_pt *out);
+celix_status_t pubsub_topicPublicationDestroy(topic_publication_pt pub);
+
+celix_status_t pubsub_topicPublicationAddPublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep);
+celix_status_t pubsub_topicPublicationRemovePublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep);
+
+celix_status_t pubsub_topicPublicationStart(bundle_context_pt bundle_context,topic_publication_pt pub,service_factory_pt* svcFactory);
+celix_status_t pubsub_topicPublicationStop(topic_publication_pt pub);
+
+array_list_pt pubsub_topicPublicationGetPublisherList(topic_publication_pt pub);
+
+#endif /* TOPIC_PUBLICATION_H_ */


[3/8] celix git commit: CELIX-417: Refactors cmake usage of pubsub and rsa. Started with installing exported targets

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_topology_manager/src/pstm_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_topology_manager/src/pstm_activator.c b/pubsub/pubsub_topology_manager/src/pstm_activator.c
new file mode 100644
index 0000000..eb874fe
--- /dev/null
+++ b/pubsub/pubsub_topology_manager/src/pstm_activator.c
@@ -0,0 +1,244 @@
+/**
+ *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.
+ */
+/*
+ * pstm_activator.c
+ *
+ *  \date       Sep 29, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "constants.h"
+#include "bundle_activator.h"
+#include "service_tracker.h"
+#include "service_registration.h"
+
+#include "listener_hook_service.h"
+#include "log_service.h"
+#include "log_helper.h"
+
+
+#include "pubsub_topology_manager.h"
+#include "publisher_endpoint_announce.h"
+
+struct activator {
+	bundle_context_pt context;
+
+	pubsub_topology_manager_pt manager;
+
+	service_tracker_pt pubsubDiscoveryTracker;
+	service_tracker_pt pubsubAdminTracker;
+	service_tracker_pt pubsubSubscribersTracker;
+
+	listener_hook_service_pt hookService;
+	service_registration_pt hook;
+
+	publisher_endpoint_announce_pt publisherEPDiscover;
+	service_registration_pt publisherEPDiscoverService;
+
+	log_helper_pt loghelper;
+};
+
+
+static celix_status_t bundleActivator_createPSDTracker(struct activator *activator, service_tracker_pt *tracker);
+static celix_status_t bundleActivator_createPSATracker(struct activator *activator, service_tracker_pt *tracker);
+static celix_status_t bundleActivator_createPSSubTracker(struct activator *activator, service_tracker_pt *tracker);
+
+
+static celix_status_t bundleActivator_createPSDTracker(struct activator *activator, service_tracker_pt *tracker) {
+	celix_status_t status;
+
+	service_tracker_customizer_pt customizer = NULL;
+
+	status = serviceTrackerCustomizer_create(activator->manager,
+			NULL,
+			pubsub_topologyManager_pubsubDiscoveryAdded,
+			pubsub_topologyManager_pubsubDiscoveryModified,
+			pubsub_topologyManager_pubsubDiscoveryRemoved,
+			&customizer);
+
+	if (status == CELIX_SUCCESS) {
+		status = serviceTracker_create(activator->context, (char *) PUBSUB_DISCOVERY_SERVICE, customizer, tracker);
+	}
+
+	return status;
+}
+
+static celix_status_t bundleActivator_createPSATracker(struct activator *activator, service_tracker_pt *tracker) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	service_tracker_customizer_pt customizer = NULL;
+
+	status = serviceTrackerCustomizer_create(activator->manager,
+			NULL,
+			pubsub_topologyManager_psaAdded,
+			pubsub_topologyManager_psaModified,
+			pubsub_topologyManager_psaRemoved,
+			&customizer);
+
+	if (status == CELIX_SUCCESS) {
+		status = serviceTracker_create(activator->context, PUBSUB_ADMIN_SERVICE, customizer, tracker);
+	}
+
+	return status;
+}
+
+static celix_status_t bundleActivator_createPSSubTracker(struct activator *activator, service_tracker_pt *tracker) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	service_tracker_customizer_pt customizer = NULL;
+
+	status = serviceTrackerCustomizer_create(activator->manager,
+			NULL,
+			pubsub_topologyManager_subscriberAdded,
+			pubsub_topologyManager_subscriberModified,
+			pubsub_topologyManager_subscriberRemoved,
+			&customizer);
+
+	if (status == CELIX_SUCCESS) {
+		status = serviceTracker_create(activator->context, PUBSUB_SUBSCRIBER_SERVICE_NAME, customizer, tracker);
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = NULL;
+
+	activator = calloc(1,sizeof(struct activator));
+
+	if (!activator) {
+		return CELIX_ENOMEM;
+	}
+
+	activator->context = context;
+
+	logHelper_create(context, &activator->loghelper);
+	logHelper_start(activator->loghelper);
+
+	status = pubsub_topologyManager_create(context, activator->loghelper, &activator->manager);
+	if (status == CELIX_SUCCESS) {
+		status = bundleActivator_createPSDTracker(activator, &activator->pubsubDiscoveryTracker);
+		if (status == CELIX_SUCCESS) {
+			status = bundleActivator_createPSATracker(activator, &activator->pubsubAdminTracker);
+			if (status == CELIX_SUCCESS) {
+				status = bundleActivator_createPSSubTracker(activator, &activator->pubsubSubscribersTracker);
+				if (status == CELIX_SUCCESS) {
+					*userData = activator;
+				}
+			}
+		}
+	}
+
+	if(status != CELIX_SUCCESS){
+		bundleActivator_destroy(activator, context);
+	}
+
+	return status;
+}
+
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	publisher_endpoint_announce_pt pubEPDiscover = calloc(1, sizeof(*pubEPDiscover));
+	pubEPDiscover->handle = activator->manager;
+	pubEPDiscover->announcePublisher = pubsub_topologyManager_announcePublisher;
+	pubEPDiscover->removePublisher = pubsub_topologyManager_removePublisher;
+	activator->publisherEPDiscover = pubEPDiscover;
+
+	status += bundleContext_registerService(context, (char *) PUBSUB_TM_ANNOUNCE_PUBLISHER_SERVICE, pubEPDiscover, NULL, &activator->publisherEPDiscoverService);
+
+
+	listener_hook_service_pt hookService = calloc(1,sizeof(*hookService));
+	hookService->handle = activator->manager;
+	hookService->added = pubsub_topologyManager_publisherTrackerAdded;
+	hookService->removed = pubsub_topologyManager_publisherTrackerRemoved;
+	activator->hookService = hookService;
+
+	status += bundleContext_registerService(context, (char *) OSGI_FRAMEWORK_LISTENER_HOOK_SERVICE_NAME, hookService, NULL, &activator->hook);
+
+	/* NOTE: Enable those line in order to remotely expose the topic_info service
+	properties_pt props = properties_create();
+	properties_set(props, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, (char *) PUBSUB_TOPIC_INFO_SERVICE);
+	status += bundleContext_registerService(context, (char *) PUBSUB_TOPIC_INFO_SERVICE, activator->topicInfo, props, &activator->topicInfoService);
+	*/
+	status += serviceTracker_open(activator->pubsubAdminTracker);
+
+	status += serviceTracker_open(activator->pubsubDiscoveryTracker);
+
+	status += serviceTracker_open(activator->pubsubSubscribersTracker);
+
+
+	return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	serviceTracker_close(activator->pubsubSubscribersTracker);
+	serviceTracker_close(activator->pubsubDiscoveryTracker);
+	serviceTracker_close(activator->pubsubAdminTracker);
+
+	serviceRegistration_unregister(activator->publisherEPDiscoverService);
+	free(activator->publisherEPDiscover);
+
+	serviceRegistration_unregister(activator->hook);
+	free(activator->hookService);
+
+	return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	struct activator *activator = userData;
+	if (activator == NULL) {
+		status = CELIX_BUNDLE_EXCEPTION;
+	} else {
+
+		if(activator->pubsubSubscribersTracker!=NULL){
+			serviceTracker_destroy(activator->pubsubSubscribersTracker);
+		}
+		if(activator->pubsubDiscoveryTracker!=NULL){
+			serviceTracker_destroy(activator->pubsubDiscoveryTracker);
+		}
+		if(activator->pubsubAdminTracker!=NULL){
+			serviceTracker_destroy(activator->pubsubAdminTracker);
+		}
+
+		if(activator->manager!=NULL){
+			status = pubsub_topologyManager_destroy(activator->manager);
+		}
+
+		logHelper_stop(activator->loghelper);
+		logHelper_destroy(&activator->loghelper);
+
+		free(activator);
+	}
+
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_topology_manager/src/pubsub_topology_manager.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_topology_manager/src/pubsub_topology_manager.c b/pubsub/pubsub_topology_manager/src/pubsub_topology_manager.c
new file mode 100644
index 0000000..2ac75c9
--- /dev/null
+++ b/pubsub/pubsub_topology_manager/src/pubsub_topology_manager.c
@@ -0,0 +1,721 @@
+/**
+ *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.
+ */
+/*
+ * pubsub_topology_manager.c
+ *
+ *  \date       Sep 29, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "hash_map.h"
+#include "array_list.h"
+#include "bundle_context.h"
+#include "constants.h"
+#include "module.h"
+#include "bundle.h"
+#include "filter.h"
+#include "listener_hook_service.h"
+#include "utils.h"
+#include "service_reference.h"
+#include "service_registration.h"
+#include "log_service.h"
+#include "log_helper.h"
+
+#include "publisher_endpoint_announce.h"
+#include "pubsub_topology_manager.h"
+#include "pubsub_endpoint.h"
+#include "pubsub_admin.h"
+#include "pubsub_utils.h"
+
+
+celix_status_t pubsub_topologyManager_create(bundle_context_pt context, log_helper_pt logHelper, pubsub_topology_manager_pt *manager) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*manager = calloc(1, sizeof(**manager));
+	if (!*manager) {
+		return CELIX_ENOMEM;
+	}
+
+	(*manager)->context = context;
+
+	celix_thread_mutexattr_t psaAttr;
+	celixThreadMutexAttr_create(&psaAttr);
+	celixThreadMutexAttr_settype(&psaAttr, CELIX_THREAD_MUTEX_RECURSIVE);
+	status = celixThreadMutex_create(&(*manager)->psaListLock, &psaAttr);
+	celixThreadMutexAttr_destroy(&psaAttr);
+
+	status = celixThreadMutex_create(&(*manager)->publicationsLock, NULL);
+	status = celixThreadMutex_create(&(*manager)->subscriptionsLock, NULL);
+	status = celixThreadMutex_create(&(*manager)->discoveryListLock, NULL);
+
+	arrayList_create(&(*manager)->psaList);
+
+	(*manager)->discoveryList = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
+	(*manager)->publications = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+	(*manager)->subscriptions = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+
+	(*manager)->loghelper = logHelper;
+
+	return status;
+}
+
+celix_status_t pubsub_topologyManager_destroy(pubsub_topology_manager_pt manager) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	celixThreadMutex_lock(&manager->discoveryListLock);
+	hashMap_destroy(manager->discoveryList, false, false);
+	celixThreadMutex_unlock(&manager->discoveryListLock);
+	celixThreadMutex_destroy(&manager->discoveryListLock);
+
+	celixThreadMutex_lock(&manager->psaListLock);
+	arrayList_destroy(manager->psaList);
+	celixThreadMutex_unlock(&manager->psaListLock);
+	celixThreadMutex_destroy(&manager->psaListLock);
+
+	celixThreadMutex_lock(&manager->publicationsLock);
+	hash_map_iterator_pt pubit = hashMapIterator_create(manager->publications);
+	while(hashMapIterator_hasNext(pubit)){
+		array_list_pt l = (array_list_pt)hashMapIterator_nextValue(pubit);
+		int i;
+		for(i=0;i<arrayList_size(l);i++){
+			pubsubEndpoint_destroy((pubsub_endpoint_pt)arrayList_get(l,i));
+		}
+		arrayList_destroy(l);
+	}
+	hashMapIterator_destroy(pubit);
+	hashMap_destroy(manager->publications, true, false);
+	celixThreadMutex_unlock(&manager->publicationsLock);
+	celixThreadMutex_destroy(&manager->publicationsLock);
+
+	celixThreadMutex_lock(&manager->subscriptionsLock);
+	hash_map_iterator_pt subit = hashMapIterator_create(manager->subscriptions);
+	while(hashMapIterator_hasNext(subit)){
+		array_list_pt l = (array_list_pt)hashMapIterator_nextValue(subit);
+		int i;
+		for(i=0;i<arrayList_size(l);i++){
+			pubsubEndpoint_destroy((pubsub_endpoint_pt)arrayList_get(l,i));
+		}
+		arrayList_destroy(l);
+	}
+	hashMapIterator_destroy(subit);
+	hashMap_destroy(manager->subscriptions, true, false);
+	celixThreadMutex_unlock(&manager->subscriptionsLock);
+	celixThreadMutex_destroy(&manager->subscriptionsLock);
+
+	free(manager);
+
+	return status;
+}
+
+celix_status_t pubsub_topologyManager_psaAdded(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	pubsub_topology_manager_pt manager = handle;
+	int i;
+
+	pubsub_admin_service_pt psa = (pubsub_admin_service_pt) service;
+	logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "PSTM: Added PSA");
+
+	celixThreadMutex_lock(&manager->psaListLock);
+	arrayList_add(manager->psaList, psa);
+	celixThreadMutex_unlock(&manager->psaListLock);
+
+	// Add already detected subscriptions to new PSA
+	celixThreadMutex_lock(&manager->subscriptionsLock);
+	hash_map_iterator_pt subscriptionsIterator = hashMapIterator_create(manager->subscriptions);
+
+	while (hashMapIterator_hasNext(subscriptionsIterator)) {
+		array_list_pt sub_ep_list = hashMapIterator_nextValue(subscriptionsIterator);
+		for(i=0;i<arrayList_size(sub_ep_list);i++){
+			status += psa->addSubscription(psa->admin, (pubsub_endpoint_pt)arrayList_get(sub_ep_list,i));
+		}
+	}
+
+	hashMapIterator_destroy(subscriptionsIterator);
+
+	celixThreadMutex_unlock(&manager->subscriptionsLock);
+
+	// Add already detected publications to new PSA
+	status = celixThreadMutex_lock(&manager->publicationsLock);
+	hash_map_iterator_pt publicationsIterator = hashMapIterator_create(manager->publications);
+
+	while (hashMapIterator_hasNext(publicationsIterator)) {
+		array_list_pt pub_ep_list = hashMapIterator_nextValue(publicationsIterator);
+		for(i=0;i<arrayList_size(pub_ep_list);i++){
+			status += psa->addPublication(psa->admin, (pubsub_endpoint_pt)arrayList_get(pub_ep_list,i));
+		}
+	}
+
+	hashMapIterator_destroy(publicationsIterator);
+
+	celixThreadMutex_unlock(&manager->publicationsLock);
+
+	return status;
+}
+
+celix_status_t pubsub_topologyManager_psaModified(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	// Nop...
+
+	return status;
+}
+
+celix_status_t pubsub_topologyManager_psaRemoved(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	pubsub_topology_manager_pt manager = handle;
+
+	pubsub_admin_service_pt psa = (pubsub_admin_service_pt) service;
+
+	/* Deactivate all publications */
+	celixThreadMutex_lock(&manager->publicationsLock);
+
+	hash_map_iterator_pt pubit = hashMapIterator_create(manager->publications);
+	while(hashMapIterator_hasNext(pubit)){
+		hash_map_entry_pt pub_entry = hashMapIterator_nextEntry(pubit);
+		char* scope_topic_key = (char*)hashMapEntry_getKey(pub_entry);
+		// Extract scope/topic name from key
+		char scope[MAX_SCOPE_LEN];
+		char topic[MAX_TOPIC_LEN];
+		sscanf(scope_topic_key, "%[^:]:%s", scope, topic );
+		array_list_pt pubEP_list = (array_list_pt)hashMapEntry_getValue(pub_entry);
+
+		status = psa->closeAllPublications(psa->admin,scope,topic);
+
+		if(status==CELIX_SUCCESS){
+			celixThreadMutex_lock(&manager->discoveryListLock);
+			hash_map_iterator_pt iter = hashMapIterator_create(manager->discoveryList);
+			while(hashMapIterator_hasNext(iter)){
+				service_reference_pt disc_sr = (service_reference_pt)hashMapIterator_nextKey(iter);
+				publisher_endpoint_announce_pt disc = NULL;
+				bundleContext_getService(manager->context, disc_sr, (void**) &disc);
+				const char* fwUUID = NULL;
+				bundleContext_getProperty(manager->context,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
+				int i;
+				for(i=0;i<arrayList_size(pubEP_list);i++){
+					pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pubEP_list,i);
+					if(strcmp(pubEP->frameworkUUID,fwUUID)==0){
+						disc->removePublisher(disc->handle,pubEP);
+					}
+				}
+				bundleContext_ungetService(manager->context, disc_sr, NULL);
+			}
+			hashMapIterator_destroy(iter);
+			celixThreadMutex_unlock(&manager->discoveryListLock);
+		}
+	}
+	hashMapIterator_destroy(pubit);
+
+	celixThreadMutex_unlock(&manager->publicationsLock);
+
+	/* Deactivate all subscriptions */
+	celixThreadMutex_lock(&manager->subscriptionsLock);
+	hash_map_iterator_pt subit = hashMapIterator_create(manager->subscriptions);
+	while(hashMapIterator_hasNext(subit)){
+		// TODO do some error checking
+		char* scope_topic = (char*)hashMapIterator_nextKey(subit);
+		char scope[MAX_TOPIC_LEN];
+		char topic[MAX_TOPIC_LEN];
+		memset(scope, 0 , MAX_TOPIC_LEN*sizeof(char));
+		memset(topic, 0 , MAX_TOPIC_LEN*sizeof(char));
+		sscanf(scope_topic, "%[^:]:%s", scope, topic );
+		status += psa->closeAllSubscriptions(psa->admin,scope, topic);
+	}
+	hashMapIterator_destroy(subit);
+	celixThreadMutex_unlock(&manager->subscriptionsLock);
+
+	celixThreadMutex_lock(&manager->psaListLock);
+	arrayList_removeElement(manager->psaList, psa);
+	celixThreadMutex_unlock(&manager->psaListLock);
+
+	logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "PSTM: Removed PSA");
+
+	return status;
+}
+
+celix_status_t pubsub_topologyManager_subscriberAdded(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	pubsub_topology_manager_pt manager = handle;
+	//subscriber_service_pt subscriber = (subscriber_service_pt)service;
+
+	pubsub_endpoint_pt sub = NULL;
+	if(pubsubEndpoint_createFromServiceReference(reference,&sub,false) == CELIX_SUCCESS){
+		celixThreadMutex_lock(&manager->subscriptionsLock);
+		char *sub_key = createScopeTopicKey(sub->scope, sub->topic);
+
+		array_list_pt sub_list_by_topic = hashMap_get(manager->subscriptions,sub_key);
+		if(sub_list_by_topic==NULL){
+			arrayList_create(&sub_list_by_topic);
+			hashMap_put(manager->subscriptions,strdup(sub_key),sub_list_by_topic);
+		}
+		free(sub_key);
+		arrayList_add(sub_list_by_topic,sub);
+
+		celixThreadMutex_unlock(&manager->subscriptionsLock);
+
+		int j;
+		double score = 0;
+		double best_score = 0;
+		pubsub_admin_service_pt best_psa = NULL;
+		celixThreadMutex_lock(&manager->psaListLock);
+		for(j=0;j<arrayList_size(manager->psaList);j++){
+			pubsub_admin_service_pt psa = (pubsub_admin_service_pt)arrayList_get(manager->psaList,j);
+			psa->matchEndpoint(psa->admin,sub,&score);
+			if(score>best_score){ /* We have a new winner! */
+				best_score = score;
+				best_psa = psa;
+			}
+		}
+
+		if(best_psa != NULL && best_score>0){
+			best_psa->addSubscription(best_psa->admin,sub);
+		}
+
+		// Inform discoveries for interest in the topic
+		celixThreadMutex_lock(&manager->discoveryListLock);
+		hash_map_iterator_pt iter = hashMapIterator_create(manager->discoveryList);
+		while(hashMapIterator_hasNext(iter)){
+			service_reference_pt disc_sr = (service_reference_pt)hashMapIterator_nextKey(iter);
+			publisher_endpoint_announce_pt disc = NULL;
+			bundleContext_getService(manager->context, disc_sr, (void**) &disc);
+			disc->interestedInTopic(disc->handle, sub->scope, sub->topic);
+			bundleContext_ungetService(manager->context, disc_sr, NULL);
+		}
+		hashMapIterator_destroy(iter);
+		celixThreadMutex_unlock(&manager->discoveryListLock);
+
+		celixThreadMutex_unlock(&manager->psaListLock);
+	}
+	else{
+		status=CELIX_INVALID_BUNDLE_CONTEXT;
+	}
+
+	return status;
+}
+
+celix_status_t pubsub_topologyManager_subscriberModified(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	// Nop...
+
+	return status;
+}
+
+celix_status_t pubsub_topologyManager_subscriberRemoved(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+	pubsub_topology_manager_pt manager = handle;
+
+	pubsub_endpoint_pt subcmp = NULL;
+	if(pubsubEndpoint_createFromServiceReference(reference,&subcmp,false) == CELIX_SUCCESS){
+
+		int j,k;
+
+		// Inform discoveries that we not interested in the topic any more
+		celixThreadMutex_lock(&manager->discoveryListLock);
+		hash_map_iterator_pt iter = hashMapIterator_create(manager->discoveryList);
+		while(hashMapIterator_hasNext(iter)){
+			service_reference_pt disc_sr = (service_reference_pt)hashMapIterator_nextKey(iter);
+			publisher_endpoint_announce_pt disc = NULL;
+			bundleContext_getService(manager->context, disc_sr, (void**) &disc);
+			disc->uninterestedInTopic(disc->handle, subcmp->scope, subcmp->topic);
+			bundleContext_ungetService(manager->context, disc_sr, NULL);
+		}
+		hashMapIterator_destroy(iter);
+		celixThreadMutex_unlock(&manager->discoveryListLock);
+
+		celixThreadMutex_lock(&manager->subscriptionsLock);
+		celixThreadMutex_lock(&manager->psaListLock);
+
+		char *sub_key = createScopeTopicKey(subcmp->scope,subcmp->topic);
+		array_list_pt sub_list_by_topic = hashMap_get(manager->subscriptions,sub_key);
+		free(sub_key);
+		if(sub_list_by_topic!=NULL){
+			for(j=0;j<arrayList_size(sub_list_by_topic);j++){
+				pubsub_endpoint_pt sub = arrayList_get(sub_list_by_topic,j);
+				if(pubsubEndpoint_equals(sub,subcmp)){
+					for(k=0;k<arrayList_size(manager->psaList);k++){
+						/* No problem with invoking removal on all psa's, only the one that manage this topic will do something */
+						pubsub_admin_service_pt psa = (pubsub_admin_service_pt)arrayList_get(manager->psaList,k);
+						psa->removeSubscription(psa->admin,sub);
+					}
+
+				}
+				arrayList_remove(sub_list_by_topic,j);
+
+				/* If it was the last subscriber for this topic, tell PSA to close the ZMQ socket */
+				if(arrayList_size(sub_list_by_topic)==0){
+					for(k=0;k<arrayList_size(manager->psaList);k++){
+						pubsub_admin_service_pt psa = (pubsub_admin_service_pt)arrayList_get(manager->psaList,k);
+						psa->closeAllSubscriptions(psa->admin,sub->scope, sub->topic);
+					}
+				}
+
+				pubsubEndpoint_destroy(sub);
+
+			}
+		}
+
+		celixThreadMutex_unlock(&manager->psaListLock);
+		celixThreadMutex_unlock(&manager->subscriptionsLock);
+
+		pubsubEndpoint_destroy(subcmp);
+
+	}
+	else{
+		status=CELIX_INVALID_BUNDLE_CONTEXT;
+	}
+
+	return status;
+
+}
+
+celix_status_t pubsub_topologyManager_pubsubDiscoveryAdded(void* handle, service_reference_pt reference, void* service) {
+	celix_status_t status = CELIX_SUCCESS;
+	pubsub_topology_manager_pt manager = (pubsub_topology_manager_pt)handle;
+	publisher_endpoint_announce_pt disc = (publisher_endpoint_announce_pt)service;
+
+	const char* fwUUID = NULL;
+
+	bundleContext_getProperty(manager->context,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
+	if(fwUUID==NULL){
+		printf("PSD: ERRROR: Cannot retrieve fwUUID.\n");
+		return CELIX_INVALID_BUNDLE_CONTEXT;
+	}
+
+	celixThreadMutex_lock(&manager->publicationsLock);
+
+	celixThreadMutex_lock(&manager->discoveryListLock);
+	hashMap_put(manager->discoveryList, reference, NULL);
+	celixThreadMutex_unlock(&manager->discoveryListLock);
+
+	hash_map_iterator_pt iter = hashMapIterator_create(manager->publications);
+	while(hashMapIterator_hasNext(iter)){
+		array_list_pt pubEP_list = (array_list_pt)hashMapIterator_nextValue(iter);
+		for(int i = 0; i < arrayList_size(pubEP_list); i++) {
+			pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pubEP_list,i);
+			if( (strcmp(pubEP->frameworkUUID,fwUUID)==0) && (pubEP->endpoint!=NULL)){
+				status += disc->announcePublisher(disc->handle,pubEP);
+			}
+		}
+	}
+	hashMapIterator_destroy(iter);
+
+	celixThreadMutex_unlock(&manager->publicationsLock);
+
+	celixThreadMutex_lock(&manager->subscriptionsLock);
+	iter = hashMapIterator_create(manager->subscriptions);
+
+	while(hashMapIterator_hasNext(iter)) {
+		array_list_pt l = (array_list_pt)hashMapIterator_nextValue(iter);
+		int i;
+		for(i=0;i<arrayList_size(l);i++){
+			pubsub_endpoint_pt subEp = (pubsub_endpoint_pt)arrayList_get(l,i);
+
+			disc->interestedInTopic(disc->handle, subEp->scope, subEp->topic);
+		}
+	}
+	hashMapIterator_destroy(iter);
+	celixThreadMutex_unlock(&manager->subscriptionsLock);
+
+	return status;
+}
+
+celix_status_t pubsub_topologyManager_pubsubDiscoveryModified(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	status = pubsub_topologyManager_pubsubDiscoveryRemoved(handle, reference, service);
+	if (status == CELIX_SUCCESS) {
+		status = pubsub_topologyManager_pubsubDiscoveryAdded(handle, reference, service);
+	}
+
+	return status;
+}
+
+celix_status_t pubsub_topologyManager_pubsubDiscoveryRemoved(void * handle, service_reference_pt reference, void * service) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	pubsub_topology_manager_pt manager = handle;
+
+	celixThreadMutex_lock(&manager->discoveryListLock);
+
+
+	if (hashMap_remove(manager->discoveryList, reference)) {
+		logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "EndpointListener Removed");
+	}
+
+	celixThreadMutex_unlock(&manager->discoveryListLock);
+
+	return status;
+}
+
+
+celix_status_t pubsub_topologyManager_publisherTrackerAdded(void *handle, array_list_pt listeners) {
+
+	celix_status_t status = CELIX_SUCCESS;
+	pubsub_topology_manager_pt manager = handle;
+
+	int l_index;
+
+	for (l_index = 0; l_index < arrayList_size(listeners); l_index++) {
+
+		listener_hook_info_pt info = arrayList_get(listeners, l_index);
+
+		pubsub_endpoint_pt pub = NULL;
+		if(pubsubEndpoint_createFromListenerHookInfo(info, &pub, true) == CELIX_SUCCESS){
+
+			celixThreadMutex_lock(&manager->publicationsLock);
+			char *pub_key = createScopeTopicKey(pub->scope, pub->topic);
+			array_list_pt pub_list_by_topic = hashMap_get(manager->publications, pub_key);
+			if(pub_list_by_topic==NULL){
+				arrayList_create(&pub_list_by_topic);
+				hashMap_put(manager->publications,strdup(pub_key),pub_list_by_topic);
+			}
+			free(pub_key);
+			arrayList_add(pub_list_by_topic,pub);
+
+			celixThreadMutex_unlock(&manager->publicationsLock);
+
+			int j;
+			double score = 0;
+			double best_score = 0;
+			pubsub_admin_service_pt best_psa = NULL;
+			celixThreadMutex_lock(&manager->psaListLock);
+
+			for(j=0;j<arrayList_size(manager->psaList);j++){
+				pubsub_admin_service_pt psa = (pubsub_admin_service_pt)arrayList_get(manager->psaList,j);
+				psa->matchEndpoint(psa->admin,pub,&score);
+				if(score>best_score){ /* We have a new winner! */
+					best_score = score;
+					best_psa = psa;
+				}
+			}
+
+			if(best_psa != NULL && best_score>0){
+				status = best_psa->addPublication(best_psa->admin,pub);
+				if(status==CELIX_SUCCESS){
+					celixThreadMutex_lock(&manager->discoveryListLock);
+					hash_map_iterator_pt iter = hashMapIterator_create(manager->discoveryList);
+					while(hashMapIterator_hasNext(iter)){
+						service_reference_pt disc_sr = (service_reference_pt)hashMapIterator_nextKey(iter);
+						publisher_endpoint_announce_pt disc = NULL;
+						bundleContext_getService(manager->context, disc_sr, (void**) &disc);
+						disc->announcePublisher(disc->handle,pub);
+						bundleContext_ungetService(manager->context, disc_sr, NULL);
+					}
+					hashMapIterator_destroy(iter);
+					celixThreadMutex_unlock(&manager->discoveryListLock);
+				}
+			}
+
+			celixThreadMutex_unlock(&manager->psaListLock);
+
+		}
+
+	}
+
+	return status;
+
+}
+
+
+celix_status_t pubsub_topologyManager_publisherTrackerRemoved(void *handle, array_list_pt listeners) {
+	celix_status_t status = CELIX_SUCCESS;
+	pubsub_topology_manager_pt manager = handle;
+
+	int l_index;
+
+	for (l_index = 0; l_index < arrayList_size(listeners); l_index++) {
+
+		listener_hook_info_pt info = arrayList_get(listeners, l_index);
+
+		pubsub_endpoint_pt pubcmp = NULL;
+		if(pubsubEndpoint_createFromListenerHookInfo(info,&pubcmp,true) == CELIX_SUCCESS){
+
+
+			int j,k;
+			celixThreadMutex_lock(&manager->psaListLock);
+			celixThreadMutex_lock(&manager->publicationsLock);
+
+			char *pub_key = createScopeTopicKey(pubcmp->scope, pubcmp->topic);
+			array_list_pt pub_list_by_topic = hashMap_get(manager->publications,pub_key);
+			if(pub_list_by_topic!=NULL){
+				for(j=0;j<arrayList_size(pub_list_by_topic);j++){
+					pubsub_endpoint_pt pub = arrayList_get(pub_list_by_topic,j);
+					if(pubsubEndpoint_equals(pub,pubcmp)){
+						for(k=0;k<arrayList_size(manager->psaList);k++){
+							pubsub_admin_service_pt psa = (pubsub_admin_service_pt)arrayList_get(manager->psaList,k);
+							status = psa->removePublication(psa->admin,pub);
+							if(status==CELIX_SUCCESS){ /* We found the one that manages this endpoint */
+								celixThreadMutex_lock(&manager->discoveryListLock);
+								hash_map_iterator_pt iter = hashMapIterator_create(manager->discoveryList);
+								while(hashMapIterator_hasNext(iter)){
+									service_reference_pt disc_sr = (service_reference_pt)hashMapIterator_nextKey(iter);
+									publisher_endpoint_announce_pt disc = NULL;
+									bundleContext_getService(manager->context, disc_sr, (void**) &disc);
+									disc->removePublisher(disc->handle,pub);
+									bundleContext_ungetService(manager->context, disc_sr, NULL);
+								}
+								hashMapIterator_destroy(iter);
+								celixThreadMutex_unlock(&manager->discoveryListLock);
+							}
+							else if(status ==  CELIX_ILLEGAL_ARGUMENT){ /* Not a real error, just saying this psa does not handle this endpoint */
+								status = CELIX_SUCCESS;
+							}
+						}
+						//}
+						arrayList_remove(pub_list_by_topic,j);
+
+						/* If it was the last publisher for this topic, tell PSA to close the ZMQ socket and then inform the discovery */
+						if(arrayList_size(pub_list_by_topic)==0){
+							for(k=0;k<arrayList_size(manager->psaList);k++){
+								pubsub_admin_service_pt psa = (pubsub_admin_service_pt)arrayList_get(manager->psaList,k);
+								psa->closeAllPublications(psa->admin,pub->scope, pub->topic);
+							}
+						}
+
+						pubsubEndpoint_destroy(pub);
+					}
+
+				}
+			}
+
+			celixThreadMutex_unlock(&manager->publicationsLock);
+			celixThreadMutex_unlock(&manager->psaListLock);
+
+			free(pub_key);
+
+			pubsubEndpoint_destroy(pubcmp);
+
+		}
+
+	}
+
+	return status;
+}
+
+celix_status_t pubsub_topologyManager_announcePublisher(void *handle, pubsub_endpoint_pt pubEP){
+	celix_status_t status = CELIX_SUCCESS;
+	printf("PSTM: New publisher discovered for topic %s [fwUUID=%s, ep=%s]\n",pubEP->topic,pubEP->frameworkUUID,pubEP->endpoint);
+
+	pubsub_topology_manager_pt manager = handle;
+	celixThreadMutex_lock(&manager->psaListLock);
+	celixThreadMutex_lock(&manager->publicationsLock);
+
+	char *pub_key = createScopeTopicKey(pubEP->scope, pubEP->topic);
+
+	array_list_pt pub_list_by_topic = hashMap_get(manager->publications,pub_key);
+	if(pub_list_by_topic==NULL){
+		arrayList_create(&pub_list_by_topic);
+		hashMap_put(manager->publications,strdup(pub_key),pub_list_by_topic);
+	}
+	free(pub_key);
+
+	/* Shouldn't be any other duplicate, since it's filtered out by the discovery */
+	pubsub_endpoint_pt p = NULL;
+	pubsubEndpoint_clone(pubEP, &p);
+	arrayList_add(pub_list_by_topic,p);
+
+	int j;
+	double score = 0;
+	double best_score = 0;
+	pubsub_admin_service_pt best_psa = NULL;
+
+	for(j=0;j<arrayList_size(manager->psaList);j++){
+		pubsub_admin_service_pt psa = (pubsub_admin_service_pt)arrayList_get(manager->psaList,j);
+		psa->matchEndpoint(psa->admin,p,&score);
+		if(score>best_score){ /* We have a new winner! */
+			best_score = score;
+			best_psa = psa;
+		}
+	}
+
+	if(best_psa != NULL && best_score>0){
+		best_psa->addPublication(best_psa->admin,p);
+	}
+	else{
+		status = CELIX_ILLEGAL_STATE;
+	}
+
+	celixThreadMutex_unlock(&manager->publicationsLock);
+	celixThreadMutex_unlock(&manager->psaListLock);
+
+	return status;
+}
+
+celix_status_t pubsub_topologyManager_removePublisher(void *handle, pubsub_endpoint_pt pubEP){
+	celix_status_t status = CELIX_SUCCESS;
+	printf("PSTM: Publisher removed for topic %s [fwUUID=%s, ep=%s]\n",pubEP->topic,pubEP->frameworkUUID,pubEP->endpoint);
+
+	pubsub_topology_manager_pt manager = handle;
+	celixThreadMutex_lock(&manager->psaListLock);
+	celixThreadMutex_lock(&manager->publicationsLock);
+	int i;
+
+	char *pub_key = createScopeTopicKey(pubEP->scope, pubEP->topic);
+	array_list_pt pub_list_by_topic = hashMap_get(manager->publications,pub_key);
+	if(pub_list_by_topic==NULL){
+		printf("PSTM: ERROR: Cannot find topic for known endpoint [%s,%s,%s]. Something is inconsistent.\n",pub_key,pubEP->frameworkUUID,pubEP->endpoint);
+		status = CELIX_ILLEGAL_STATE;
+	}
+	else{
+
+		pubsub_endpoint_pt p = NULL;
+		bool found = false;
+
+		for(i=0;!found && i<arrayList_size(pub_list_by_topic);i++){
+			p = (pubsub_endpoint_pt)arrayList_get(pub_list_by_topic,i);
+			found = pubsubEndpoint_equals(p,pubEP);
+		}
+
+		if(found && p !=NULL){
+
+			for(i=0;i<arrayList_size(manager->psaList);i++){
+				pubsub_admin_service_pt psa = (pubsub_admin_service_pt)arrayList_get(manager->psaList,i);
+				/* No problem with invoking removal on all psa's, only the one that manage this topic will do something */
+				psa->removePublication(psa->admin,p);
+			}
+
+			arrayList_removeElement(pub_list_by_topic,p);
+
+			/* If it was the last publisher for this topic, tell PSA to close the ZMQ socket */
+			if(arrayList_size(pub_list_by_topic)==0){
+
+				for(i=0;i<arrayList_size(manager->psaList);i++){
+					pubsub_admin_service_pt psa = (pubsub_admin_service_pt)arrayList_get(manager->psaList,i);
+					psa->closeAllPublications(psa->admin,p->scope, p->topic);
+				}
+			}
+
+			pubsubEndpoint_destroy(p);
+		}
+
+
+	}
+	free(pub_key);
+	celixThreadMutex_unlock(&manager->publicationsLock);
+	celixThreadMutex_unlock(&manager->psaListLock);
+
+
+	return status;
+}
+

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_topology_manager/src/pubsub_topology_manager.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_topology_manager/src/pubsub_topology_manager.h b/pubsub/pubsub_topology_manager/src/pubsub_topology_manager.h
new file mode 100644
index 0000000..0074a75
--- /dev/null
+++ b/pubsub/pubsub_topology_manager/src/pubsub_topology_manager.h
@@ -0,0 +1,82 @@
+/**
+ *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.
+ */
+/*
+ * pubsub_topology_manager.h
+ *
+ *  \date       Sep 29, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef PUBSUB_TOPOLOGY_MANAGER_H_
+#define PUBSUB_TOPOLOGY_MANAGER_H_
+
+#include "service_reference.h"
+#include "bundle_context.h"
+#include "log_helper.h"
+
+#include "pubsub_common.h"
+#include "pubsub_endpoint.h"
+#include "pubsub/publisher.h"
+#include "pubsub/subscriber.h"
+
+
+struct pubsub_topology_manager {
+	bundle_context_pt context;
+
+	celix_thread_mutex_t psaListLock;
+	array_list_pt psaList;
+
+	celix_thread_mutex_t discoveryListLock;
+	hash_map_pt discoveryList; //<serviceReference,NULL>
+
+	celix_thread_mutex_t publicationsLock;
+	hash_map_pt publications; //<topic(string),list<pubsub_ep>>
+
+	celix_thread_mutex_t subscriptionsLock;
+	hash_map_pt subscriptions; //<topic(string),list<pubsub_ep>>
+
+	log_helper_pt loghelper;
+};
+
+typedef struct pubsub_topology_manager *pubsub_topology_manager_pt;
+
+celix_status_t pubsub_topologyManager_create(bundle_context_pt context, log_helper_pt logHelper, pubsub_topology_manager_pt *manager);
+celix_status_t pubsub_topologyManager_destroy(pubsub_topology_manager_pt manager);
+celix_status_t pubsub_topologyManager_closeImports(pubsub_topology_manager_pt manager);
+
+celix_status_t pubsub_topologyManager_psaAdded(void *handle, service_reference_pt reference, void *service);
+celix_status_t pubsub_topologyManager_psaModified(void *handle, service_reference_pt reference, void *service);
+celix_status_t pubsub_topologyManager_psaRemoved(void *handle, service_reference_pt reference, void *service);
+
+celix_status_t pubsub_topologyManager_pubsubDiscoveryAdded(void* handle, service_reference_pt reference, void* service);
+celix_status_t pubsub_topologyManager_pubsubDiscoveryModified(void * handle, service_reference_pt reference, void* service);
+celix_status_t pubsub_topologyManager_pubsubDiscoveryRemoved(void * handle, service_reference_pt reference, void* service);
+
+celix_status_t pubsub_topologyManager_subscriberAdded(void * handle, service_reference_pt reference, void * service);
+celix_status_t pubsub_topologyManager_subscriberModified(void * handle, service_reference_pt reference, void * service);
+celix_status_t pubsub_topologyManager_subscriberRemoved(void * handle, service_reference_pt reference, void * service);
+
+celix_status_t pubsub_topologyManager_publisherTrackerAdded(void *handle, array_list_pt listeners);
+celix_status_t pubsub_topologyManager_publisherTrackerRemoved(void *handle, array_list_pt listeners);
+
+celix_status_t pubsub_topologyManager_announcePublisher(void *handle, pubsub_endpoint_pt pubEP);
+celix_status_t pubsub_topologyManager_removePublisher(void *handle, pubsub_endpoint_pt pubEP);
+
+#endif /* PUBSUB_TOPOLOGY_MANAGER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/test/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/test/CMakeLists.txt b/pubsub/test/CMakeLists.txt
index 65e22e5..9fd324e 100644
--- a/pubsub/test/CMakeLists.txt
+++ b/pubsub/test/CMakeLists.txt
@@ -20,23 +20,21 @@ find_program(ETCD_CMD NAMES etcd)
 find_package(CppUTest REQUIRED)
 include_directories(${CPPUTEST_INCLUDE_DIR})
 
-include_directories(
-        ${CMAKE_SOURCE_DIR}/pubsub/api
-        test
-)
-
 add_bundle(pubsub_sut
     #"Vanilla" bundle which is under test
     SOURCES
         test/sut_activator.c
     VERSION 1.0.0
 )
-target_link_libraries(pubsub_sut PRIVATE Celix::framework)
+target_include_directories(pubsub_sut PRIVATE test)
+target_link_libraries(pubsub_sut PRIVATE Celix::pubsub_spi)
+
 bundle_files(pubsub_sut
     msg_descriptors/msg.descriptor
     msg_descriptors/sync.descriptor
     DESTINATION "META-INF/descriptors/messages"
 )
+
 add_deploy(pubsub_udpmc_sut
     NAME deploy_sut
     BUNDLES

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/CMakeLists.txt b/remote_services/CMakeLists.txt
index bb45908..ae27849 100644
--- a/remote_services/CMakeLists.txt
+++ b/remote_services/CMakeLists.txt
@@ -18,23 +18,24 @@
 celix_subproject(REMOTE_SERVICE_ADMIN "Option to enable building the Remote Service Admin Service bundles" OFF)
 if (REMOTE_SERVICE_ADMIN)
 
-    add_subdirectory(examples)
+    add_subdirectory(remote_services_api)
+    add_subdirectory(rsa_spi)
+    add_subdirectory(rsa_common)
+
+    add_subdirectory(civetweb)
 
     add_subdirectory(topology_manager)
 
-    add_subdirectory(civetweb)
     add_subdirectory(discovery_common)
     add_subdirectory(discovery_configured)
     add_subdirectory(discovery_etcd)
     add_subdirectory(discovery_shm)
 
     #TODO refactor shm rsa to use dfi
-    add_subdirectory(remote_service_admin_api)
-    add_subdirectory(remote_service_admin_common)
     #add_subdirectory(remote_service_admin_shm)
     add_subdirectory(remote_service_admin_dfi)
 
-
+    add_subdirectory(examples)
 endif (REMOTE_SERVICE_ADMIN)
 
 

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/discovery_common/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/CMakeLists.txt b/remote_services/discovery_common/CMakeLists.txt
index c3242a6..114f485 100644
--- a/remote_services/discovery_common/CMakeLists.txt
+++ b/remote_services/discovery_common/CMakeLists.txt
@@ -31,7 +31,7 @@ target_include_directories(rsa_discovery_common PUBLIC
 		$<TARGET_PROPERTY:Celix::framework,INTERFACE_INCLUDE_DIRECTORIES>
 		$<TARGET_PROPERTY:Celix::utils,INTERFACE_INCLUDE_DIRECTORIES>
 		$<TARGET_PROPERTY:Celix::log_helper,INTERFACE_INCLUDE_DIRECTORIES>
-		$<TARGET_PROPERTY:Celix::rsa_api,INTERFACE_INCLUDE_DIRECTORIES>
+		$<TARGET_PROPERTY:Celix::rsa_spi,INTERFACE_INCLUDE_DIRECTORIES>
 		$<TARGET_PROPERTY:civetweb,INCLUDE_DIRECTORIES>
 		${LIBXML2_INCLUDE_DIR})
 

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/examples/calculator_service/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/CMakeLists.txt b/remote_services/examples/calculator_service/CMakeLists.txt
index 5d97d16..167e705 100644
--- a/remote_services/examples/calculator_service/CMakeLists.txt
+++ b/remote_services/examples/calculator_service/CMakeLists.txt
@@ -23,7 +23,7 @@ add_bundle(calculator
     VERSION 0.0.1
 )
 target_include_directories(calculator PRIVATE src)
-target_link_libraries(calculator PRIVATE Celix::rsa_api calculator_api)
+target_link_libraries(calculator PRIVATE Celix::rsa_spi calculator_api)
 
 get_target_property(DESCR calculator_api INTERFACE_CALCULATOR_DESCRIPTOR)
 bundle_files(calculator ${DESCR} DESTINATION .)

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_service_admin_api/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/CMakeLists.txt b/remote_services/remote_service_admin_api/CMakeLists.txt
deleted file mode 100644
index f665576..0000000
--- a/remote_services/remote_service_admin_api/CMakeLists.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-# 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.
-
-add_library(rsa_api INTERFACE)
-target_include_directories(rsa_api INTERFACE include)
-
-install (FILES 
-        include/remote_endpoint_impl.h
-        include/remote_endpoint.h
-        include/remote_proxy.h
-        include/remote_service_admin.h
-        include/export_registration.h
-        include/import_registration.h
-        include/endpoint_description.h
-        include/endpoint_listener.h
-        include/remote_constants.h
-    DESTINATION 
-        include/celix/remote_service_admin 
-    COMPONENT 
-        remote_service_admin
-)
-install (FILES 
-        public/include/endpoint_listener.h
-    DESTINATION 
-        include/celix/endpoint_listener 
-    COMPONENT 
-        remote_service_admin
-)
-
-#Setup target aliases to match external usage
-add_library(Celix::rsa_api ALIAS rsa_api)

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_service_admin_api/README.md
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/README.md b/remote_services/remote_service_admin_api/README.md
deleted file mode 100644
index 2e3d268..0000000
--- a/remote_services/remote_service_admin_api/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# Remote Service Admin
-
-The Remote Service Admin (RSA) provides the mechanisms to import and export services when instructed to do so by the Topology Manager. 
-
-To delegate method calls to the actual service implementation, the RSA_SHM and the RSA_HTTP are using "endpoint/proxy" bundles, which has all the knowledge about the marshalling and unmarshalling of data for the service. The RSA_DFI implementation combines a [foreign function interface](https://en.wikipedia.org/wiki/Foreign_function_interface) technique together with manualy created descriptors.  
-
-Note that this folder contains code commonly used by the RSA implementations and therefore does not include any CMAKE configuration.
-
-## Properties
-    ENDPOINTS				 defines the relative directory where endpoints and proxys can be found (default: endpoints)
-    CELIX_FRAMEWORK_EXTENDER_PATH  Used in RSA_DFI only. Can be used to define a path to use as an extender path point for the framework bundle. For normal bundles the bundle cache is used. 

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_service_admin_api/include/endpoint_description.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/endpoint_description.h b/remote_services/remote_service_admin_api/include/endpoint_description.h
deleted file mode 100644
index de27d2e..0000000
--- a/remote_services/remote_service_admin_api/include/endpoint_description.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- *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.
- */
-/*
- * endpoint_description.h
- *
- *  \date       25 Jul 2014
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-
-#ifndef ENDPOINT_DESCRIPTION_H_
-#define ENDPOINT_DESCRIPTION_H_
-
-#include "properties.h"
-#include "array_list.h"
-
-struct endpoint_description {
-    char *frameworkUUID;
-    char *id;
-    // array_list_pt intents;
-    char *service;
-    // HASH_MAP packageVersions;
-    properties_pt properties;
-    unsigned long serviceId;
-};
-
-typedef struct endpoint_description endpoint_description_t;
-typedef endpoint_description_t* endpoint_description_pt;
-
-celix_status_t endpointDescription_create(properties_pt properties, endpoint_description_pt *endpointDescription);
-celix_status_t endpointDescription_destroy(endpoint_description_pt description);
-
-
-#endif /* ENDPOINT_DESCRIPTION_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_service_admin_api/include/endpoint_listener.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/endpoint_listener.h b/remote_services/remote_service_admin_api/include/endpoint_listener.h
deleted file mode 100644
index 2e6359f..0000000
--- a/remote_services/remote_service_admin_api/include/endpoint_listener.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- *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.
- */
-/*
- * endpoint_listener.h
- *
- *  \date       Sep 29, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef ENDPOINT_LISTENER_H_
-#define ENDPOINT_LISTENER_H_
-
-#include "array_list.h"
-#include "properties.h"
-
-#include "endpoint_description.h"
-
-static const char * const OSGI_ENDPOINT_LISTENER_SERVICE = "endpoint_listener";
-
-static const char * const OSGI_ENDPOINT_LISTENER_SCOPE = "endpoint.listener.scope";
-
-struct endpoint_listener {
-	void *handle;
-	celix_status_t (*endpointAdded)(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
-	celix_status_t (*endpointRemoved)(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
-};
-
-typedef struct endpoint_listener endpoint_listener_t;
-typedef endpoint_listener_t *endpoint_listener_pt;
-
-
-#endif /* ENDPOINT_LISTENER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_service_admin_api/include/export_registration.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/export_registration.h b/remote_services/remote_service_admin_api/include/export_registration.h
deleted file mode 100644
index dc3882b..0000000
--- a/remote_services/remote_service_admin_api/include/export_registration.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#ifndef CELIX_EXPORT_REGISTRATION_H
-#define CELIX_EXPORT_REGISTRATION_H
-
-#include "celix_errno.h"
-#include "endpoint_description.h"
-#include "service_reference.h"
-
-typedef struct export_registration *export_registration_pt;
-
-typedef struct export_reference *export_reference_pt;
-
-celix_status_t exportRegistration_close(export_registration_pt registration);
-celix_status_t exportRegistration_getException(export_registration_pt registration);
-celix_status_t exportRegistration_getExportReference(export_registration_pt registration, export_reference_pt *reference);
-
-celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint);
-celix_status_t exportReference_getExportedService(export_reference_pt reference, service_reference_pt *service);
-
-#endif //CELIX_EXPORT_REGISTRATION_H

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_service_admin_api/include/import_registration.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/import_registration.h b/remote_services/remote_service_admin_api/include/import_registration.h
deleted file mode 100644
index ef8193f..0000000
--- a/remote_services/remote_service_admin_api/include/import_registration.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed under Apache License v2. See LICENSE for more information.
- */
-#ifndef CELIX_IMPORT_REGISTRATION_H
-#define CELIX_IMPORT_REGISTRATION_H
-
-#include "celix_errno.h"
-#include "endpoint_description.h"
-#include "service_reference.h"
-
-typedef struct import_registration *import_registration_pt;
-
-typedef struct import_reference *import_reference_pt;
-
-celix_status_t importRegistration_close(import_registration_pt registration);
-celix_status_t importRegistration_getException(import_registration_pt registration);
-celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference);
-
-celix_status_t importReference_getImportedEndpoint(import_reference_pt reference);
-celix_status_t importReference_getImportedService(import_reference_pt reference);
-
-#endif //CELIX_IMPORT_REGISTRATION_H

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_service_admin_api/include/remote_constants.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/remote_constants.h b/remote_services/remote_service_admin_api/include/remote_constants.h
deleted file mode 100644
index 0736685..0000000
--- a/remote_services/remote_service_admin_api/include/remote_constants.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- *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.
- */
-/*
- * remote_constants.h
- *
- *  \date       Sep 30, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef REMOTE_CONSTANTS_H_
-#define REMOTE_CONSTANTS_H_
-
-static const char * const OSGI_RSA_SERVICE_EXPORTED_INTERFACES = "service.exported.interfaces";
-static const char * const OSGI_RSA_ENDPOINT_FRAMEWORK_UUID = "endpoint.framework.uuid";
-static const char * const OSGI_RSA_ENDPOINT_SERVICE_ID = "endpoint.service.id";
-static const char * const OSGI_RSA_ENDPOINT_ID = "endpoint.id";
-static const char * const OSGI_RSA_SERVICE_IMPORTED = "service.imported";
-static const char * const OSGI_RSA_SERVICE_IMPORTED_CONFIGS = "service.imported.configs";
-static const char * const OSGI_RSA_SERVICE_LOCATION = "service.location";
-
-#endif /* REMOTE_CONSTANTS_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_service_admin_api/include/remote_endpoint.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/remote_endpoint.h b/remote_services/remote_service_admin_api/include/remote_endpoint.h
deleted file mode 100644
index ab80abb..0000000
--- a/remote_services/remote_service_admin_api/include/remote_endpoint.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- *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.
- */
-/*
- * remote_endpoint.h
- *
- *  \date       Oct 7, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef REMOTE_ENDPOINT_H_
-#define REMOTE_ENDPOINT_H_
-
-#define OSGI_RSA_REMOTE_ENDPOINT "remote_endpoint"
-
-typedef struct remote_endpoint remote_endpoint_t;
-typedef remote_endpoint_t* remote_endpoint_pt;
-
-struct remote_endpoint_service {
-	remote_endpoint_pt endpoint;
-	celix_status_t (*setService)(remote_endpoint_pt endpoint, void *service);
-	celix_status_t (*handleRequest)(remote_endpoint_pt endpoint, char *data, char **reply);
-};
-
-typedef struct remote_endpoint_service *remote_endpoint_service_pt;
-
-
-#endif /* REMOTE_ENDPOINT_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_service_admin_api/include/remote_endpoint_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/remote_endpoint_impl.h b/remote_services/remote_service_admin_api/include/remote_endpoint_impl.h
deleted file mode 100644
index 3782d62..0000000
--- a/remote_services/remote_service_admin_api/include/remote_endpoint_impl.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- *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.
- */
-/*
- * remote_endpoint_impl.h
- *
- *  \date       Oct 11, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef REMOTE_ENDPOINT_IMPL_H_
-#define REMOTE_ENDPOINT_IMPL_H_
-
-#include "remote_endpoint.h"
-#include "celix_threads.h"
-
-struct remote_endpoint {
-	celix_thread_mutex_t serviceLock;
-	void *service;
-};
-
-#endif /* REMOTE_ENDPOINT_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_service_admin_api/include/remote_proxy.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/remote_proxy.h b/remote_services/remote_service_admin_api/include/remote_proxy.h
deleted file mode 100644
index 4c3f5c3..0000000
--- a/remote_services/remote_service_admin_api/include/remote_proxy.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- *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.
- */
-/*
- * remote_proxy.h
- *
- *  \date       Oct 13, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef REMOTE_PROXY_H_
-#define REMOTE_PROXY_H_
-
-#include "endpoint_listener.h"
-#include "remote_service_admin.h"
-
-#define OSGI_RSA_REMOTE_PROXY_FACTORY 	"remote_proxy_factory"
-#define OSGI_RSA_REMOTE_PROXY_TIMEOUT   "remote_proxy_timeout"
-
-typedef celix_status_t (*sendToHandle)(remote_service_admin_pt remote_service_admin_ptr, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus);
-typedef celix_status_t (*createProxyService)(void *handle, endpoint_description_pt endpointDescription, remote_service_admin_pt rsa, sendToHandle sendToCallback, properties_pt properties, void **service);
-typedef celix_status_t (*destroyProxyService)(void *handle, void *service);
-
-typedef struct remote_proxy_factory *remote_proxy_factory_pt;
-typedef struct remote_proxy_factory_service *remote_proxy_factory_service_pt;
-
-struct remote_proxy_factory {
-	bundle_context_pt context_ptr;
-	char *service;
-
-	remote_proxy_factory_service_pt remote_proxy_factory_service_ptr;
-	properties_pt properties;
-	service_registration_pt registration;
-
-	hash_map_pt proxy_instances;
-
-	void *handle;
-
-	createProxyService create_proxy_service_ptr;
-	destroyProxyService destroy_proxy_service_ptr;
-};
-
-struct remote_proxy_factory_service {
-	remote_proxy_factory_pt factory;
-	celix_status_t (*registerProxyService)(remote_proxy_factory_pt proxyFactoryService, endpoint_description_pt endpoint, remote_service_admin_pt remote_service_admin_ptr, sendToHandle callback);
-	celix_status_t (*unregisterProxyService)(remote_proxy_factory_pt proxyFactoryService, endpoint_description_pt endpoint);
-};
-
-celix_status_t remoteProxyFactory_create(bundle_context_pt context, char *service, void *handle,
-		createProxyService create, destroyProxyService destroy,
-		remote_proxy_factory_pt *remote_proxy_factory_ptr);
-celix_status_t remoteProxyFactory_destroy(remote_proxy_factory_pt *remote_proxy_factory_ptr);
-
-celix_status_t remoteProxyFactory_register(remote_proxy_factory_pt remote_proxy_factory_ptr);
-celix_status_t remoteProxyFactory_unregister(remote_proxy_factory_pt remote_proxy_factory_ptr);
-
-
-
-
-#endif /* REMOTE_PROXY_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_service_admin_api/include/remote_service_admin.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/include/remote_service_admin.h b/remote_services/remote_service_admin_api/include/remote_service_admin.h
deleted file mode 100644
index cc7fd98..0000000
--- a/remote_services/remote_service_admin_api/include/remote_service_admin.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- *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.
- */
-/*
- * remote_service_admin.h
- *
- *  \date       Sep 30, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef REMOTE_SERVICE_ADMIN_H_
-#define REMOTE_SERVICE_ADMIN_H_
-
-#include "endpoint_listener.h"
-#include "service_reference.h"
-#include "export_registration.h"
-#include "import_registration.h"
-
-#define OSGI_RSA_REMOTE_SERVICE_ADMIN "remote_service_admin"
-
-typedef struct import_registration_factory import_registration_factory_t;
-typedef import_registration_factory_t* import_registration_factory_pt;
-
-typedef struct remote_service_admin remote_service_admin_t;
-typedef remote_service_admin_t* remote_service_admin_pt;
-
-struct remote_service_admin_service {
-	remote_service_admin_pt admin;
-	celix_status_t (*exportService)(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations);
-	celix_status_t (*removeExportedService)(remote_service_admin_pt admin, export_registration_pt registration);
-	celix_status_t (*getExportedServices)(remote_service_admin_pt admin, array_list_pt *services);
-	celix_status_t (*getImportedEndpoints)(remote_service_admin_pt admin, array_list_pt *services);
-	celix_status_t (*importService)(remote_service_admin_pt admin, endpoint_description_pt endpoint, import_registration_pt *registration);
-
-	celix_status_t (*exportReference_getExportedEndpoint)(export_reference_pt reference, endpoint_description_pt *endpoint);
-	celix_status_t (*exportReference_getExportedService)(export_reference_pt reference, service_reference_pt *service);
-
-	celix_status_t (*exportRegistration_close)(remote_service_admin_pt admin, export_registration_pt registration);
-	celix_status_t (*exportRegistration_getException)(export_registration_pt registration);
-	celix_status_t (*exportRegistration_getExportReference)(export_registration_pt registration, export_reference_pt *reference);
-	celix_status_t (*exportRegistration_freeExportReference)(export_reference_pt *reference);
-	celix_status_t (*exportRegistration_getEndpointDescription)(export_registration_pt registration, endpoint_description_pt endpointDescription);
-
-	celix_status_t (*importReference_getImportedEndpoint)(import_reference_pt reference);
-	celix_status_t (*importReference_getImportedService)(import_reference_pt reference);
-
-	celix_status_t (*importRegistration_close)(remote_service_admin_pt admin, import_registration_pt registration);
-	celix_status_t (*importRegistration_getException)(import_registration_pt registration);
-	celix_status_t (*importRegistration_getImportReference)(import_registration_pt registration, import_reference_pt *reference);
-
-};
-
-typedef struct remote_service_admin_service remote_service_admin_service_t;
-typedef remote_service_admin_service_t* remote_service_admin_service_pt;
-
-
-#endif /* REMOTE_SERVICE_ADMIN_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_service_admin_common/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/CMakeLists.txt b/remote_services/remote_service_admin_common/CMakeLists.txt
deleted file mode 100644
index 018d868..0000000
--- a/remote_services/remote_service_admin_common/CMakeLists.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-# 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.
-
-add_library(rsa_common STATIC
-    src/endpoint_description.c
-    src/export_registration_impl.c
-    src/import_registration_impl.c
-)
-target_include_directories(rsa_common PRIVATE src)
-target_link_libraries(rsa_common PUBLIC Celix::framework Celix::rsa_api Celix::log_helper)
-
-#Setup target aliases to match external usage
-add_library(Celix::rsa_common ALIAS rsa_common)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_service_admin_common/src/endpoint_description.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/endpoint_description.c b/remote_services/remote_service_admin_common/src/endpoint_description.c
deleted file mode 100644
index 0d8b684..0000000
--- a/remote_services/remote_service_admin_common/src/endpoint_description.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- *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.
- */
-/*
- * endpoint_description.c
- *
- *  \date       25 Jul 2014
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-#include <stdlib.h>
-#include <string.h>
-
-#include "celix_errno.h"
-#include "celix_log.h"
-
-#include "endpoint_description.h"
-#include "remote_constants.h"
-#include "constants.h"
-
-static celix_status_t endpointDescription_verifyLongProperty(properties_pt properties, char *propertyName, unsigned long *longProperty);
-
-celix_status_t endpointDescription_create(properties_pt properties, endpoint_description_pt *endpointDescription) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	unsigned long serviceId = 0UL;
-	status = endpointDescription_verifyLongProperty(properties, (char *) OSGI_RSA_ENDPOINT_SERVICE_ID, &serviceId);
-	if (status != CELIX_SUCCESS) {
-		return status;
-	}
-
-	endpoint_description_pt ep = calloc(1,sizeof(*ep));
-
-    ep->properties = properties;
-    ep->frameworkUUID = (char*)properties_get(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
-    ep->id = (char*)properties_get(properties, OSGI_RSA_ENDPOINT_ID);
-    ep->service = strndup(properties_get(properties, OSGI_FRAMEWORK_OBJECTCLASS), 1024*10);
-    ep->serviceId = serviceId;
-
-    if (!(ep->frameworkUUID) || !(ep->id) || !(ep->service) ) {
-    	fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "ENDPOINT_DESCRIPTION: incomplete description!.");
-    	status = CELIX_BUNDLE_EXCEPTION;
-    }
-
-    if(status == CELIX_SUCCESS){
-	*endpointDescription = ep;
-    }
-    else{
-	*endpointDescription = NULL;
-	free(ep);
-    }
-
-    return status;
-}
-
-celix_status_t endpointDescription_destroy(endpoint_description_pt description) {
-    properties_destroy(description->properties);
-    free(description->service);
-    free(description);
-    return CELIX_SUCCESS;
-}
-
-static celix_status_t endpointDescription_verifyLongProperty(properties_pt properties, char *propertyName, unsigned long *longProperty) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    const char *value = properties_get(properties, propertyName);
-    if (value == NULL) {
-        *longProperty = 0UL;
-    } else {
-        *longProperty = strtoul(value,NULL,10);
-    }
-
-    return status;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_service_admin_common/src/export_registration_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/export_registration_impl.c b/remote_services/remote_service_admin_common/src/export_registration_impl.c
deleted file mode 100644
index 1c684e7..0000000
--- a/remote_services/remote_service_admin_common/src/export_registration_impl.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/**
- *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.
- */
-/*
- * export_registration_impl.c
- *
- *  \date       Oct 6, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-#include <stdlib.h>
-
-#include "constants.h"
-
-#include "celix_errno.h"
-
-#include "export_registration_impl.h"
-#include "remote_service_admin_impl.h"
-
-
-struct export_reference {
-	endpoint_description_pt endpoint;
-	service_reference_pt reference;
-};
-
-celix_status_t exportRegistration_endpointAdding(void * handle, service_reference_pt reference, void **service);
-celix_status_t exportRegistration_endpointAdded(void * handle, service_reference_pt reference, void *service);
-celix_status_t exportRegistration_endpointModified(void * handle, service_reference_pt reference, void *service);
-celix_status_t exportRegistration_endpointRemoved(void * handle, service_reference_pt reference, void *service);
-
-celix_status_t exportRegistration_createEndpointTracker(export_registration_pt registration, service_tracker_pt *tracker);
-
-celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, remote_service_admin_pt rsa, bundle_context_pt context, export_registration_pt *registration) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*registration = calloc(1, sizeof(**registration));
-	if (!*registration) {
-		status = CELIX_ENOMEM;
-	} else {
-		(*registration)->context = context;
-		(*registration)->closed = false;
-		(*registration)->endpointDescription = endpoint;
-		(*registration)->reference = reference;
-		(*registration)->rsa = rsa;
-		(*registration)->tracker = NULL;
-		(*registration)->endpoint = NULL;
-		(*registration)->endpointTracker = NULL;
-		(*registration)->exportReference = NULL;
-		(*registration)->bundle = NULL;
-		(*registration)->loghelper = helper;
-	}
-
-	return status;
-}
-
-celix_status_t exportRegistration_destroy(export_registration_pt *registration) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	remoteServiceAdmin_destroyEndpointDescription(&(*registration)->endpointDescription);
-	free(*registration);
-
-	return status;
-}
-
-celix_status_t exportRegistration_startTracking(export_registration_pt registration) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (registration->endpointTracker == NULL) {
-		status = exportRegistration_createEndpointTracker(registration, &registration->endpointTracker);
-		if (status == CELIX_SUCCESS) {
-			status = serviceTracker_open(registration->endpointTracker);
-		}
-	}
-
-	return status;
-}
-
-celix_status_t exportRegistration_stopTracking(export_registration_pt registration) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (registration->endpointTracker != NULL) {
-		status = serviceTracker_close(registration->endpointTracker);
-		if (status != CELIX_SUCCESS) {
-		    logHelper_log(registration->loghelper, OSGI_LOGSERVICE_ERROR, "EXPORT_REGISTRATION: Could not close endpoint tracker");
-		}
-		else {
-			status = serviceTracker_destroy(registration->endpointTracker);
-		}
-	}
-	if (registration->tracker != NULL) {
-		status = serviceTracker_close(registration->tracker);
-		if (status != CELIX_SUCCESS) {
-			logHelper_log(registration->loghelper, OSGI_LOGSERVICE_ERROR, "EXPORT_REGISTRATION: Could not close service tracker");
-		}
-		else {
-			status = serviceTracker_destroy(registration->tracker);
-		}
-	}
-
-	return status;
-}
-
-celix_status_t exportRegistration_createEndpointTracker(export_registration_pt registration, service_tracker_pt *tracker) {
-	celix_status_t status;
-
-	service_tracker_customizer_pt customizer = NULL;
-
-	status = serviceTrackerCustomizer_create(registration, exportRegistration_endpointAdding,
-			exportRegistration_endpointAdded, exportRegistration_endpointModified, exportRegistration_endpointRemoved, &customizer);
-
-	if (status == CELIX_SUCCESS) {
-		char filter[512];
-
-		snprintf(filter, 512, "(&(%s=%s)(remote.interface=%s))", (char*) OSGI_FRAMEWORK_OBJECTCLASS, (char*) OSGI_RSA_REMOTE_ENDPOINT, registration->endpointDescription->service);
-		status = serviceTracker_createWithFilter(registration->context, filter, customizer, tracker);
-	}
-
-	return status;
-}
-
-celix_status_t exportRegistration_endpointAdding(void * handle, service_reference_pt reference, void **service) {
-	celix_status_t status;
-	export_registration_pt registration = handle;
-
-	status = bundleContext_getService(registration->context, reference, service);
-
-	return status;
-}
-
-celix_status_t exportRegistration_endpointAdded(void * handle, service_reference_pt reference, void *endpoint_service) {
-	celix_status_t status = CELIX_SUCCESS;
-	export_registration_pt registration = handle;
-
-	remote_endpoint_service_pt endpoint = endpoint_service;
-	if (registration->endpoint == NULL) {
-		registration->endpoint = endpoint;
-		void *service = NULL;
-		status = bundleContext_getService(registration->context, registration->reference, &service);
-		if (status == CELIX_SUCCESS) {
-			endpoint->setService(endpoint->endpoint, service);
-		}
-	}
-
-	return status;
-}
-
-celix_status_t exportRegistration_endpointModified(void * handle, service_reference_pt reference, void *service) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	return status;
-}
-
-celix_status_t exportRegistration_endpointRemoved(void * handle, service_reference_pt reference, void *service) {
-	celix_status_t status = CELIX_SUCCESS;
-	export_registration_pt registration = handle;
-
-	remote_endpoint_service_pt endpoint = service;
-	if (registration->endpoint != NULL) {
-		endpoint->setService(endpoint->endpoint, NULL);
-	}
-
-	return status;
-}
-
-celix_status_t exportRegistration_open(export_registration_pt registration) {
-	celix_status_t status = CELIX_SUCCESS;
-	const char *bundleStore = NULL;
-
-	bundleContext_getProperty(registration->context, BUNDLE_STORE_PROPERTY_NAME, &bundleStore);
-
-	if (bundleStore == NULL) {
-		bundleStore = DEFAULT_BUNDLE_STORE;
-	}
-	char name[256];
-
-	snprintf(name, 256, "%s/%s_endpoint.zip", bundleStore, registration->endpointDescription->service);
-
-	status = bundleContext_installBundle(registration->context, name, &registration->bundle);
-	if (status == CELIX_SUCCESS) {
-		status = bundle_start(registration->bundle);
-		if (status == CELIX_SUCCESS) {
-		}
-	}
-
-	return status;
-}
-
-celix_status_t exportRegistration_close(export_registration_pt registration) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	exportRegistration_stopTracking(registration);
-
-	bundle_uninstall(registration->bundle);
-
-
-	return status;
-}
-
-celix_status_t exportRegistration_getException(export_registration_pt registration) {
-	celix_status_t status = CELIX_SUCCESS;
-	return status;
-}
-
-celix_status_t exportRegistration_getExportReference(export_registration_pt registration, export_reference_pt *reference) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	registration->exportReference = calloc(1, sizeof(*registration->exportReference));
-
-	if (registration->exportReference == NULL) {
-		status = CELIX_ENOMEM;
-	} else {
-		registration->exportReference->endpoint = registration->endpointDescription;
-		registration->exportReference->reference = registration->reference;
-	}
-	
-	*reference = registration->exportReference;
-
-	return status;
-}
-
-celix_status_t exportRegistration_setEndpointDescription(export_registration_pt registration, endpoint_description_pt endpointDescription) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	registration->endpointDescription = endpointDescription;
-
-	return status;
-}
-
-celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*endpoint = reference->endpoint;
-
-	return status;
-}
-
-celix_status_t exportReference_getExportedService(export_reference_pt reference, service_reference_pt *service) {
-	celix_status_t status = CELIX_SUCCESS;
-	*service = reference->reference;
-	return status;
-}
-

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_service_admin_common/src/export_registration_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/export_registration_impl.h b/remote_services/remote_service_admin_common/src/export_registration_impl.h
deleted file mode 100644
index bb276f9..0000000
--- a/remote_services/remote_service_admin_common/src/export_registration_impl.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- *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.
- */
-/*
- * export_registration_impl.h
- *
- *  \date       Oct 6, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef EXPORT_REGISTRATION_IMPL_H_
-#define EXPORT_REGISTRATION_IMPL_H_
-
-#include "remote_service_admin.h"
-#include "remote_endpoint.h"
-#include "service_tracker.h"
-#include "log_helper.h"
-
-struct export_registration {
-	bundle_context_pt context;
-	remote_service_admin_pt rsa;
-	endpoint_description_pt endpointDescription;
-	service_reference_pt reference;
-	log_helper_pt loghelper;
-
-	service_tracker_pt tracker;
-	service_tracker_pt endpointTracker;
-
-	remote_endpoint_service_pt endpoint;
-
-	export_reference_pt exportReference;
-	bundle_pt bundle;
-
-	bool closed;
-};
-
-celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, remote_service_admin_pt rsa, bundle_context_pt context, export_registration_pt *registration);
-celix_status_t exportRegistration_destroy(export_registration_pt *registration);
-celix_status_t exportRegistration_open(export_registration_pt registration);
-
-celix_status_t exportRegistration_setEndpointDescription(export_registration_pt registration, endpoint_description_pt endpointDescription);
-celix_status_t exportRegistration_startTracking(export_registration_pt registration);
-celix_status_t exportRegistration_stopTracking(export_registration_pt registration);
-
-#endif /* EXPORT_REGISTRATION_IMPL_H_ */


[4/8] celix git commit: CELIX-417: Refactors cmake usage of pubsub and rsa. Started with installing exported targets

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_discovery/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_discovery/CMakeLists.txt b/pubsub/pubsub_discovery/CMakeLists.txt
index 0e7d6c5..f92f81c 100644
--- a/pubsub/pubsub_discovery/CMakeLists.txt
+++ b/pubsub/pubsub_discovery/CMakeLists.txt
@@ -18,7 +18,7 @@
 find_package(CURL REQUIRED)
 find_package(Jansson REQUIRED)
 
-add_bundle(org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
+add_bundle(celix_pubsub_discovery_etcd
     BUNDLE_SYMBOLICNAME "apache_celix_pubsub_discovery_etcd"
     VERSION "1.0.0"
     SOURCES
@@ -27,16 +27,15 @@ add_bundle(org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
         src/etcd_common.c
         src/etcd_watcher.c
         src/etcd_writer.c
-		${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_endpoint.c
-		${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c
 )
 
-target_include_directories(org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery PRIVATE
+target_include_directories(celix_pubsub_discovery_etcd PRIVATE
     src
-    include
 	${CURL_INCLUDE_DIR}
 	${JANSSON_INCLUDE_DIR}
-        )
+)
+
+target_link_libraries(celix_pubsub_discovery_etcd PRIVATE Celix::pubsub_spi Celix::framework Celix::etcdlib_static ${CURL_LIBRARIES} ${JANSSON_LIBRARIES})
+install_bundle(celix_pubsub_discovery_etcd)
 
-target_link_libraries(org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery PRIVATE Celix::framework Celix::etcdlib_static ${CURL_LIBRARIES} ${JANSSON_LIBRARIES})
-install_bundle(org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery)
+add_library(Celix::pubsub_discovery_etcd ALIAS celix_pubsub_discovery_etcd)

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_serializer_json/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_serializer_json/CMakeLists.txt b/pubsub/pubsub_serializer_json/CMakeLists.txt
index b86f30e..1269cad 100644
--- a/pubsub/pubsub_serializer_json/CMakeLists.txt
+++ b/pubsub/pubsub_serializer_json/CMakeLists.txt
@@ -18,22 +18,23 @@
 find_package(Jansson REQUIRED)
 
 
-add_bundle(org.apache.celix.pubsub_serializer.PubSubSerializerJson
+add_bundle(celix_pubsub_serializer_json
     BUNDLE_SYMBOLICNAME "apache_celix_pubsub_serializer_json"
     VERSION "1.0.0"
     SOURCES
 		src/ps_activator.c
 		src/pubsub_serializer_impl.c
-    	${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c
 )
 
-target_include_directories(org.apache.celix.pubsub_serializer.PubSubSerializerJson PRIVATE
+target_include_directories(celix_pubsub_serializer_json PRIVATE
 	src
 	${JANSSON_INCLUDE_DIR}
 )
 
-set_target_properties(org.apache.celix.pubsub_serializer.PubSubSerializerJson PROPERTIES INSTALL_RPATH "$ORIGIN")
-target_link_libraries(org.apache.celix.pubsub_serializer.PubSubSerializerJson PRIVATE Celix::framework Celix::dfi ${JANSSON_LIBRARIES} Celix::log_helper)
+set_target_properties(celix_pubsub_serializer_json PROPERTIES INSTALL_RPATH "$ORIGIN")
+target_link_libraries(celix_pubsub_serializer_json PRIVATE Celix::pubsub_spi Celix::framework Celix::dfi ${JANSSON_LIBRARIES} Celix::log_helper)
 
-install_bundle(org.apache.celix.pubsub_serializer.PubSubSerializerJson)
+install_bundle(celix_pubsub_serializer_json)
+
+add_library(Celix::pubsub_serializer_json ALIAS celix_pubsub_serializer_json)
 

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_spi/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_spi/CMakeLists.txt b/pubsub/pubsub_spi/CMakeLists.txt
new file mode 100644
index 0000000..118dd3a
--- /dev/null
+++ b/pubsub/pubsub_spi/CMakeLists.txt
@@ -0,0 +1,35 @@
+# 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.
+
+add_library(celix_pubsub_spi STATIC
+		src/pubsub_admin_match.c
+        src/pubsub_endpoint.c
+        src/pubsub_utils.c
+)
+target_include_directories(celix_pubsub_spi PUBLIC
+		$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
+		$<INSTALL_INTERFACE:include/celix/pubsub_spi>
+)
+target_link_libraries(celix_pubsub_spi PUBLIC Celix::framework Celix::pubsub_api)
+
+set_target_properties(celix_pubsub_spi PROPERTIES TOPIC_INFO_DESCRIPTOR ${CMAKE_CURRENT_LIST_DIR}/include/pubsub_topic_info.descriptor)
+#TODO how to make this descriptor available for imported targets? $<INSTALL_INTERFACE:include/celix/pubsub_spi/pubsub_topic_info.descriptor>
+
+add_library(Celix::pubsub_spi ALIAS celix_pubsub_spi)
+
+install(TARGETS celix_pubsub_spi EXPORT celix DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT pubsub)
+install(DIRECTORY include/ DESTINATION include/celix/pubsub_spi COMPONENT pubsub)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_spi/include/publisher_endpoint_announce.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_spi/include/publisher_endpoint_announce.h b/pubsub/pubsub_spi/include/publisher_endpoint_announce.h
new file mode 100644
index 0000000..bd39fc0
--- /dev/null
+++ b/pubsub/pubsub_spi/include/publisher_endpoint_announce.h
@@ -0,0 +1,36 @@
+/**
+ *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.
+ */
+
+#ifndef PUBLISHER_ENDPOINT_ANNOUNCE_H_
+#define PUBLISHER_ENDPOINT_ANNOUNCE_H_
+
+#include "pubsub_endpoint.h"
+
+struct publisher_endpoint_announce {
+	void *handle;
+	celix_status_t (*announcePublisher)(void *handle, pubsub_endpoint_pt pubEP);
+	celix_status_t (*removePublisher)(void *handle, pubsub_endpoint_pt pubEP);
+	celix_status_t (*interestedInTopic)(void* handle, const char *scope, const char *topic);
+	celix_status_t (*uninterestedInTopic)(void* handle, const char *scope, const char *topic);
+};
+
+typedef struct publisher_endpoint_announce *publisher_endpoint_announce_pt;
+
+
+#endif /* PUBLISHER_ENDPOINT_ANNOUNCE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_spi/include/pubsub_admin.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_spi/include/pubsub_admin.h b/pubsub/pubsub_spi/include/pubsub_admin.h
new file mode 100644
index 0000000..f24d825
--- /dev/null
+++ b/pubsub/pubsub_spi/include/pubsub_admin.h
@@ -0,0 +1,72 @@
+/**
+ *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.
+ */
+/*
+ * pubsub_admin.h
+ *
+ *  \date       Sep 30, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef PUBSUB_ADMIN_H_
+#define PUBSUB_ADMIN_H_
+
+#include "service_reference.h"
+
+#include "pubsub_common.h"
+#include "pubsub_endpoint.h"
+
+#define PSA_IP 	"PSA_IP"
+#define PSA_ITF	"PSA_INTERFACE"
+#define PSA_MULTICAST_IP_PREFIX "PSA_MC_PREFIX"
+
+#define PUBSUB_ADMIN_TYPE_KEY	"pubsub_admin.type"
+
+typedef struct pubsub_admin *pubsub_admin_pt;
+
+struct pubsub_admin_service {
+	pubsub_admin_pt admin;
+
+	celix_status_t (*addSubscription)(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
+	celix_status_t (*removeSubscription)(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
+
+	celix_status_t (*addPublication)(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
+	celix_status_t (*removePublication)(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
+
+	celix_status_t (*closeAllPublications)(pubsub_admin_pt admin,char* scope, char* topic);
+	celix_status_t (*closeAllSubscriptions)(pubsub_admin_pt admin,char* scope, char* topic);
+
+	/* Match principle:
+	 * - A full matching pubsub_admin gives 200 points
+	 * - A full matching serializer gives 100 points
+	 * - If QoS = sample
+	 * 		- fallback pubsub_admin order of selection is: udp_mc, zmq. Points allocation is 100,75.
+	 * 		- fallback serializers order of selection is: json, void. Points allocation is 30,20.
+	 * - If QoS = control
+	 * 		- fallback pubsub_admin order of selection is: zmq,udp_mc. Points allocation is 100,75.
+	 * 		- fallback serializers order of selection is: json, void. Points allocation is 30,20.
+	 * - If nothing is specified, QoS = sample is assumed, so the same score applies, just divided by two.
+	 *
+	 */
+	celix_status_t (*matchEndpoint)(pubsub_admin_pt admin, pubsub_endpoint_pt endpoint, double* score);
+};
+
+typedef struct pubsub_admin_service *pubsub_admin_service_pt;
+
+#endif /* PUBSUB_ADMIN_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_spi/include/pubsub_admin_match.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_spi/include/pubsub_admin_match.h b/pubsub/pubsub_spi/include/pubsub_admin_match.h
new file mode 100644
index 0000000..e95ca7d
--- /dev/null
+++ b/pubsub/pubsub_spi/include/pubsub_admin_match.h
@@ -0,0 +1,40 @@
+/**
+ *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.
+ */
+
+
+#ifndef PUBSUB_ADMIN_MATCH_H_
+#define PUBSUB_ADMIN_MATCH_H_
+
+#include "celix_errno.h"
+#include "properties.h"
+#include "array_list.h"
+
+#include "pubsub_serializer.h"
+
+#define QOS_ATTRIBUTE_KEY	"attribute.qos"
+#define QOS_TYPE_SAMPLE		"sample"	/* A.k.a. unreliable connection */
+#define QOS_TYPE_CONTROL	"control"	/* A.k.a. reliable connection */
+
+#define PUBSUB_ADMIN_FULL_MATCH_SCORE	200.0F
+#define SERIALIZER_FULL_MATCH_SCORE		100.0F
+
+celix_status_t pubsub_admin_match(properties_pt endpoint_props, const char *pubsub_admin_type, array_list_pt serializerList, double *score);
+celix_status_t pubsub_admin_get_best_serializer(properties_pt endpoint_props, array_list_pt serializerList, pubsub_serializer_service_t **serSvc);
+
+#endif /* PUBSUB_ADMIN_MATCH_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_spi/include/pubsub_common.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_spi/include/pubsub_common.h b/pubsub/pubsub_spi/include/pubsub_common.h
new file mode 100644
index 0000000..5dfd8fd
--- /dev/null
+++ b/pubsub/pubsub_spi/include/pubsub_common.h
@@ -0,0 +1,52 @@
+/**
+ *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.
+ */
+/*
+ * pubsub_common.h
+ *
+ *  \date       Sep 17, 2015
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef PUBSUB_COMMON_H_
+#define PUBSUB_COMMON_H_
+
+#define PUBSUB_SERIALIZER_SERVICE 		"pubsub_serializer"
+#define PUBSUB_ADMIN_SERVICE 			"pubsub_admin"
+#define PUBSUB_DISCOVERY_SERVICE		"pubsub_discovery"
+#define PUBSUB_TM_ANNOUNCE_PUBLISHER_SERVICE    "pubsub_tm_announce_publisher"
+
+#define PUBSUB_ANY_SUB_TOPIC		        "any"
+
+#define	PUBSUB_BUNDLE_ID			"bundle.id"
+
+#define MAX_SCOPE_LEN                           1024
+#define MAX_TOPIC_LEN				1024
+
+struct pubsub_msg_header{
+	char topic[MAX_TOPIC_LEN];
+	unsigned int type;
+	unsigned char major;
+	unsigned char minor;
+};
+
+typedef struct pubsub_msg_header* pubsub_msg_header_pt;
+
+
+#endif /* PUBSUB_COMMON_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_spi/include/pubsub_endpoint.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_spi/include/pubsub_endpoint.h b/pubsub/pubsub_spi/include/pubsub_endpoint.h
new file mode 100644
index 0000000..4c39d2f
--- /dev/null
+++ b/pubsub/pubsub_spi/include/pubsub_endpoint.h
@@ -0,0 +1,58 @@
+/**
+ *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.
+ */
+/*
+ * pubsub_endpoint.h
+ *
+ *  \date       Sep 21, 2015
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef PUBSUB_ENDPOINT_H_
+#define PUBSUB_ENDPOINT_H_
+
+#include "service_reference.h"
+#include "listener_hook_service.h"
+#include "properties.h"
+
+#include "pubsub/publisher.h"
+#include "pubsub/subscriber.h"
+
+struct pubsub_endpoint {
+    char *frameworkUUID;
+    char *scope;
+    char *topic;
+    long serviceID;
+    char* endpoint;
+    bool is_secure;
+    properties_pt topic_props;
+};
+
+typedef struct pubsub_endpoint *pubsub_endpoint_pt;
+
+celix_status_t pubsubEndpoint_create(const char* fwUUID, const char* scope, const char* topic, long serviceId,const char* endpoint,properties_pt topic_props,pubsub_endpoint_pt* psEp);
+celix_status_t pubsubEndpoint_createFromServiceReference(service_reference_pt reference,pubsub_endpoint_pt* psEp, bool isPublisher);
+celix_status_t pubsubEndpoint_createFromListenerHookInfo(listener_hook_info_pt info,pubsub_endpoint_pt* psEp, bool isPublisher);
+celix_status_t pubsubEndpoint_clone(pubsub_endpoint_pt in, pubsub_endpoint_pt *out);
+celix_status_t pubsubEndpoint_destroy(pubsub_endpoint_pt psEp);
+bool pubsubEndpoint_equals(pubsub_endpoint_pt psEp1,pubsub_endpoint_pt psEp2);
+
+char *createScopeTopicKey(const char* scope, const char* topic);
+
+#endif /* PUBSUB_ENDPOINT_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_spi/include/pubsub_serializer.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_spi/include/pubsub_serializer.h b/pubsub/pubsub_spi/include/pubsub_serializer.h
new file mode 100644
index 0000000..4489fa4
--- /dev/null
+++ b/pubsub/pubsub_spi/include/pubsub_serializer.h
@@ -0,0 +1,66 @@
+/**
+ *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.
+ */
+/*
+ * pubsub_serializer.h
+ *
+ *  \date       Mar 24, 2017
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef PUBSUB_SERIALIZER_SERVICE_H_
+#define PUBSUB_SERIALIZER_SERVICE_H_
+
+#include "service_reference.h"
+#include "hash_map.h"
+
+#include "pubsub_common.h"
+
+#define PUBSUB_SERIALIZER_TYPE_KEY	"pubsub_serializer.type"
+
+/**
+ * There should be a pubsub_serializer_t
+ * per msg type (msg id) per bundle
+ *
+ * The pubsub_serializer_service can create
+ * a serializer_map per bundle. Potentially using
+ * the extender pattern.
+ */
+
+typedef struct pubsub_msg_serializer {
+	void* handle;
+	unsigned int msgId;
+	const char* msgName;
+	version_pt msgVersion;
+
+	celix_status_t (*serialize)(void* handle, const void* input, void** out, size_t* outLen);
+	celix_status_t (*deserialize)(void* handle, const void* input, size_t inputLen, void** out); //note inputLen can be 0 if predefined size is not needed
+	void (*freeMsg)(void* handle, void* msg);
+
+} pubsub_msg_serializer_t;
+
+typedef struct pubsub_serializer_service {
+	void* handle;
+
+	celix_status_t (*createSerializerMap)(void* handle, bundle_pt bundle, hash_map_pt* serializerMap);
+	celix_status_t (*destroySerializerMap)(void* handle, hash_map_pt serializerMap);
+
+} pubsub_serializer_service_t;
+
+#endif /* PUBSUB_SERIALIZER_SERVICE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_spi/include/pubsub_topic_info.descriptor
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_spi/include/pubsub_topic_info.descriptor b/pubsub/pubsub_spi/include/pubsub_topic_info.descriptor
new file mode 100644
index 0000000..c01a2fd
--- /dev/null
+++ b/pubsub/pubsub_spi/include/pubsub_topic_info.descriptor
@@ -0,0 +1,10 @@
+:header
+type=interface
+name=pubsub_topic_info
+version=1.0.0
+:annotations
+:types
+:methods
+getParticipantsNumber(t)i=getParticipantsNumber(#am=handle;Pt#am=pre;*i)N
+getSubscribersNumber(t)i=getSubscribersNumber(#am=handle;Pt#am=pre;*i)N
+getPublishersNumber(t)i=getPublishersNumber(#am=handle;Pt#am=pre;*i)N

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_spi/include/pubsub_utils.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_spi/include/pubsub_utils.h b/pubsub/pubsub_spi/include/pubsub_utils.h
new file mode 100644
index 0000000..aff5c72
--- /dev/null
+++ b/pubsub/pubsub_spi/include/pubsub_utils.h
@@ -0,0 +1,39 @@
+/**
+ *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.
+ */
+/*
+ * pubsub_utils.h
+ *
+ *  \date       Sep 24, 2015
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef PUBSUB_UTILS_H_
+#define PUBSUB_UTILS_H_
+
+#include "bundle_context.h"
+#include "array_list.h"
+
+char* pubsub_getScopeFromFilter(char* bundle_filter);
+char* pubsub_getTopicFromFilter(char* bundle_filter);
+char* pubsub_getKeysBundleDir(bundle_context_pt ctx);
+array_list_pt pubsub_getTopicsFromString(char* string);
+
+
+#endif /* PUBSUB_UTILS_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_spi/src/pubsub_admin_match.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_spi/src/pubsub_admin_match.c b/pubsub/pubsub_spi/src/pubsub_admin_match.c
new file mode 100644
index 0000000..2a695c1
--- /dev/null
+++ b/pubsub/pubsub_spi/src/pubsub_admin_match.c
@@ -0,0 +1,320 @@
+/**
+ *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.
+ */
+
+
+#include <string.h>
+#include "service_reference.h"
+
+#include "pubsub_admin.h"
+
+#include "pubsub_admin_match.h"
+
+#define KNOWN_PUBSUB_ADMIN_NUM	2
+#define KNOWN_SERIALIZER_NUM	2
+
+static char* qos_sample_pubsub_admin_prio_list[KNOWN_PUBSUB_ADMIN_NUM] = {"udp_mc","zmq"};
+static char* qos_sample_serializer_prio_list[KNOWN_SERIALIZER_NUM] = {"json","void"};
+
+static char* qos_control_pubsub_admin_prio_list[KNOWN_PUBSUB_ADMIN_NUM] = {"zmq","udp_mc"};
+static char* qos_control_serializer_prio_list[KNOWN_SERIALIZER_NUM] = {"json","void"};
+
+static double qos_pubsub_admin_score[KNOWN_PUBSUB_ADMIN_NUM] = {100.0F,75.0F};
+static double qos_serializer_score[KNOWN_SERIALIZER_NUM] = {30.0F,20.0F};
+
+static void get_serializer_type(service_reference_pt svcRef, char **serializerType);
+static void manage_service_from_reference(service_reference_pt svcRef, void **svc, bool getService);
+
+celix_status_t pubsub_admin_match(properties_pt endpoint_props, const char *pubsub_admin_type, array_list_pt serializerList, double *score){
+
+	celix_status_t status = CELIX_SUCCESS;
+	double final_score = 0;
+	int i = 0, j = 0;
+
+	const char *requested_admin_type 		= NULL;
+	const char *requested_serializer_type 	= NULL;
+	const char *requested_qos_type			= NULL;
+
+	if(endpoint_props!=NULL){
+		requested_admin_type 		= properties_get(endpoint_props,PUBSUB_ADMIN_TYPE_KEY);
+		requested_serializer_type 	= properties_get(endpoint_props,PUBSUB_SERIALIZER_TYPE_KEY);
+		requested_qos_type			= properties_get(endpoint_props,QOS_ATTRIBUTE_KEY);
+	}
+
+	/* Analyze the pubsub_admin */
+	if(requested_admin_type != NULL){ /* We got precise specification on the pubsub_admin we want */
+		if(strncmp(requested_admin_type,pubsub_admin_type,strlen(pubsub_admin_type))==0){ //Full match
+			final_score += PUBSUB_ADMIN_FULL_MATCH_SCORE;
+		}
+	}
+	else if(requested_qos_type != NULL){ /* We got QoS specification that will determine the selected PSA */
+		if(strncmp(requested_qos_type,QOS_TYPE_SAMPLE,strlen(QOS_TYPE_SAMPLE))==0){
+			for(i=0;i<KNOWN_PUBSUB_ADMIN_NUM;i++){
+				if(strncmp(qos_sample_pubsub_admin_prio_list[i],pubsub_admin_type,strlen(pubsub_admin_type))==0){
+					final_score += qos_pubsub_admin_score[i];
+					break;
+				}
+			}
+		}
+		else if(strncmp(requested_qos_type,QOS_TYPE_CONTROL,strlen(QOS_TYPE_CONTROL))==0){
+			for(i=0;i<KNOWN_PUBSUB_ADMIN_NUM;i++){
+				if(strncmp(qos_control_pubsub_admin_prio_list[i],pubsub_admin_type,strlen(pubsub_admin_type))==0){
+					final_score += qos_pubsub_admin_score[i];
+					break;
+				}
+			}
+		}
+		else{
+			printf("Unknown QoS type '%s'\n",requested_qos_type);
+			status = CELIX_ILLEGAL_ARGUMENT;
+		}
+	}
+	else{ /* We got no specification: fallback to Qos=Sample, but count half the score */
+		for(i=0;i<KNOWN_PUBSUB_ADMIN_NUM;i++){
+			if(strncmp(qos_sample_pubsub_admin_prio_list[i],pubsub_admin_type,strlen(pubsub_admin_type))==0){
+				final_score += (qos_pubsub_admin_score[i]/2);
+				break;
+			}
+		}
+	}
+
+	char *serializer_type = NULL;
+	/* Analyze the serializers */
+	if(requested_serializer_type != NULL){ /* We got precise specification on the serializer we want */
+		for(i=0;i<arrayList_size(serializerList);i++){
+			service_reference_pt svcRef = (service_reference_pt)arrayList_get(serializerList,i);
+			get_serializer_type(svcRef, &serializer_type);
+			if(serializer_type != NULL){
+				if(strncmp(requested_serializer_type,serializer_type,strlen(serializer_type))==0){
+					final_score += SERIALIZER_FULL_MATCH_SCORE;
+					break;
+				}
+			}
+		}
+	}
+	else if(requested_qos_type != NULL){ /* We got QoS specification that will determine the selected serializer */
+		if(strncmp(requested_qos_type,QOS_TYPE_SAMPLE,strlen(QOS_TYPE_SAMPLE))==0){
+			bool ser_found = false;
+			for(i=0;i<KNOWN_SERIALIZER_NUM && !ser_found;i++){
+				for(j=0;j<arrayList_size(serializerList) && !ser_found;j++){
+					service_reference_pt svcRef = (service_reference_pt)arrayList_get(serializerList,j);
+					get_serializer_type(svcRef, &serializer_type);
+					if(serializer_type != NULL){
+						if(strncmp(qos_sample_serializer_prio_list[i],serializer_type,strlen(serializer_type))==0){
+							ser_found = true;
+						}
+					}
+				}
+				if(ser_found){
+					final_score += qos_serializer_score[i];
+				}
+			}
+		}
+		else if(strncmp(requested_qos_type,QOS_TYPE_CONTROL,strlen(QOS_TYPE_CONTROL))==0){
+			bool ser_found = false;
+			for(i=0;i<KNOWN_SERIALIZER_NUM && !ser_found;i++){
+				for(j=0;j<arrayList_size(serializerList) && !ser_found;j++){
+					service_reference_pt svcRef = (service_reference_pt)arrayList_get(serializerList,j);
+					get_serializer_type(svcRef, &serializer_type);
+					if(serializer_type != NULL){
+						if(strncmp(qos_control_serializer_prio_list[i],serializer_type,strlen(serializer_type))==0){
+							ser_found = true;
+						}
+					}
+				}
+				if(ser_found){
+					final_score += qos_serializer_score[i];
+				}
+			}
+		}
+		else{
+			printf("Unknown QoS type '%s'\n",requested_qos_type);
+			status = CELIX_ILLEGAL_ARGUMENT;
+		}
+	}
+	else{ /* We got no specification: fallback to Qos=Sample, but count half the score */
+		bool ser_found = false;
+		for(i=0;i<KNOWN_SERIALIZER_NUM && !ser_found;i++){
+			for(j=0;j<arrayList_size(serializerList) && !ser_found;j++){
+				service_reference_pt svcRef = (service_reference_pt)arrayList_get(serializerList,j);
+				get_serializer_type(svcRef, &serializer_type);
+				if(serializer_type != NULL){
+					if(strncmp(qos_sample_serializer_prio_list[i],serializer_type,strlen(serializer_type))==0){
+						ser_found = true;
+					}
+				}
+			}
+			if(ser_found){
+				final_score += (qos_serializer_score[i]/2);
+			}
+		}
+	}
+
+	*score = final_score;
+
+	printf("Score for pair <%s,%s> = %f\n",pubsub_admin_type,serializer_type,final_score);
+
+	return status;
+}
+
+celix_status_t pubsub_admin_get_best_serializer(properties_pt endpoint_props, array_list_pt serializerList, pubsub_serializer_service_t **serSvc){
+	celix_status_t status = CELIX_SUCCESS;
+
+	int i = 0, j = 0;
+
+	const char *requested_serializer_type = NULL;
+	const char *requested_qos_type = NULL;
+
+	if (endpoint_props != NULL){
+		requested_serializer_type = properties_get(endpoint_props,PUBSUB_SERIALIZER_TYPE_KEY);
+		requested_qos_type = properties_get(endpoint_props,QOS_ATTRIBUTE_KEY);
+	}
+
+	service_reference_pt svcRef = NULL;
+	void *svc = NULL;
+
+	/* Analyze the serializers */
+	if(requested_serializer_type != NULL){ /* We got precise specification on the serializer we want */
+		for(i=0;i<arrayList_size(serializerList);i++){
+			svcRef = (service_reference_pt)arrayList_get(serializerList,i);
+			char *serializer_type = NULL;
+			get_serializer_type(svcRef, &serializer_type);
+			if(serializer_type != NULL){
+				if(strncmp(requested_serializer_type,serializer_type,strlen(serializer_type))==0){
+					manage_service_from_reference(svcRef, &svc,true);
+					if(svc==NULL){
+						printf("Cannot get pubsub_serializer_service from serviceReference %p\n",svcRef);
+						status = CELIX_SERVICE_EXCEPTION;
+					}
+					*serSvc = svc;
+					break;
+				}
+			}
+		}
+	}
+	else if(requested_qos_type != NULL){ /* We got QoS specification that will determine the selected serializer */
+		if(strncmp(requested_qos_type,QOS_TYPE_SAMPLE,strlen(QOS_TYPE_SAMPLE))==0){
+			bool ser_found = false;
+			for(i=0;i<KNOWN_SERIALIZER_NUM && !ser_found;i++){
+				for(j=0;j<arrayList_size(serializerList) && !ser_found;j++){
+					svcRef = (service_reference_pt)arrayList_get(serializerList,j);
+					char *serializer_type = NULL;
+					get_serializer_type(svcRef, &serializer_type);
+					if(serializer_type != NULL){
+						if(strncmp(qos_sample_serializer_prio_list[i],serializer_type,strlen(serializer_type))==0){
+							manage_service_from_reference(svcRef, &svc,true);
+							if(svc==NULL){
+								printf("Cannot get pubsub_serializer_service from serviceReference %p\n",svcRef);
+								status = CELIX_SERVICE_EXCEPTION;
+							}
+							else{
+								*serSvc = svc;
+								ser_found = true;
+								printf("Selected %s serializer as best for QoS=%s\n",qos_sample_serializer_prio_list[i],QOS_TYPE_SAMPLE);
+							}
+						}
+					}
+				}
+			}
+		}
+		else if(strncmp(requested_qos_type,QOS_TYPE_CONTROL,strlen(QOS_TYPE_CONTROL))==0){
+			bool ser_found = false;
+			for(i=0;i<KNOWN_SERIALIZER_NUM && !ser_found;i++){
+				for(j=0;j<arrayList_size(serializerList) && !ser_found;j++){
+					svcRef = (service_reference_pt)arrayList_get(serializerList,j);
+					char *serializer_type = NULL;
+					get_serializer_type(svcRef, &serializer_type);
+					if(serializer_type != NULL){
+						if(strncmp(qos_control_serializer_prio_list[i],serializer_type,strlen(serializer_type))==0){
+							manage_service_from_reference(svcRef, &svc,true);
+							if(svc==NULL){
+								printf("Cannot get pubsub_serializer_service from serviceReference %p\n",svcRef);
+								status = CELIX_SERVICE_EXCEPTION;
+							}
+							else{
+								*serSvc = svc;
+								ser_found = true;
+								printf("Selected %s serializer as best for QoS=%s\n",qos_control_serializer_prio_list[i],QOS_TYPE_CONTROL);
+							}
+						}
+					}
+				}
+			}
+		}
+		else{
+			printf("Unknown QoS type '%s'\n",requested_qos_type);
+			status = CELIX_ILLEGAL_ARGUMENT;
+		}
+	}
+	else{ /* We got no specification: fallback to Qos=Sample, but count half the score */
+		bool ser_found = false;
+		for(i=0;i<KNOWN_SERIALIZER_NUM && !ser_found;i++){
+			for(j=0;j<arrayList_size(serializerList) && !ser_found;j++){
+				svcRef = (service_reference_pt)arrayList_get(serializerList,j);
+				char *serializer_type = NULL;
+				get_serializer_type(svcRef, &serializer_type);
+				if(serializer_type != NULL){
+					if(strncmp(qos_sample_serializer_prio_list[i],serializer_type,strlen(serializer_type))==0){
+						manage_service_from_reference(svcRef, &svc,true);
+						if(svc==NULL){
+							printf("Cannot get pubsub_serializer_service from serviceReference %p\n",svcRef);
+							status = CELIX_SERVICE_EXCEPTION;
+						}
+						else{
+							*serSvc = svc;
+							ser_found = true;
+							printf("Selected %s serializer as best without any specification\n",qos_sample_serializer_prio_list[i]);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	if(svc!=NULL && svcRef!=NULL){
+		manage_service_from_reference(svcRef, svc, false);
+	}
+
+	return status;
+}
+
+static void get_serializer_type(service_reference_pt svcRef, char **serializerType){
+
+	const char *serType = NULL;
+	serviceReference_getProperty(svcRef, PUBSUB_SERIALIZER_TYPE_KEY,&serType);
+	if(serType != NULL){
+		*serializerType = (char*)serType;
+	}
+	else{
+		printf("Serializer serviceReference %p has no pubsub_serializer.type property specified\n",svcRef);
+		*serializerType = NULL;
+	}
+}
+
+static void manage_service_from_reference(service_reference_pt svcRef, void **svc, bool getService){
+	bundle_context_pt context = NULL;
+	bundle_pt bundle = NULL;
+	serviceReference_getBundle(svcRef, &bundle);
+	bundle_getContext(bundle, &context);
+	if(getService){
+		bundleContext_getService(context, svcRef, svc);
+	}
+	else{
+		bundleContext_ungetService(context, svcRef, NULL);
+	}
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_spi/src/pubsub_endpoint.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_spi/src/pubsub_endpoint.c b/pubsub/pubsub_spi/src/pubsub_endpoint.c
new file mode 100644
index 0000000..c3fd293
--- /dev/null
+++ b/pubsub/pubsub_spi/src/pubsub_endpoint.c
@@ -0,0 +1,254 @@
+/**
+ *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.
+ */
+/*
+ * endpoint_description.c
+ *
+ *  \date       25 Jul 2014
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "celix_errno.h"
+#include "celix_log.h"
+
+#include "pubsub_common.h"
+#include "pubsub_endpoint.h"
+#include "constants.h"
+
+#include "pubsub_utils.h"
+
+
+static void pubsubEndpoint_setFields(pubsub_endpoint_pt psEp, const char* fwUUID, const char* scope, const char* topic, long serviceId,const char* endpoint,properties_pt topic_props, bool cloneProps);
+static properties_pt pubsubEndpoint_getTopicProperties(bundle_pt bundle, const char *topic, bool isPublisher);
+
+static void pubsubEndpoint_setFields(pubsub_endpoint_pt psEp, const char* fwUUID, const char* scope, const char* topic, long serviceId,const char* endpoint,properties_pt topic_props, bool cloneProps){
+
+	if (fwUUID != NULL) {
+		psEp->frameworkUUID = strdup(fwUUID);
+	}
+
+	if (scope != NULL) {
+		psEp->scope = strdup(scope);
+	}
+
+	if (topic != NULL) {
+		psEp->topic = strdup(topic);
+	}
+
+	psEp->serviceID = serviceId;
+
+	if(endpoint != NULL) {
+		psEp->endpoint = strdup(endpoint);
+	}
+
+	if(topic_props != NULL){
+		if(cloneProps){
+			properties_copy(topic_props, &(psEp->topic_props));
+		}
+		else{
+			psEp->topic_props = topic_props;
+		}
+	}
+}
+
+static properties_pt pubsubEndpoint_getTopicProperties(bundle_pt bundle, const char *topic, bool isPublisher){
+
+	properties_pt topic_props = NULL;
+
+	bool isSystemBundle = false;
+	bundle_isSystemBundle(bundle, &isSystemBundle);
+	long bundleId = -1;
+	bundle_isSystemBundle(bundle, &isSystemBundle);
+	bundle_getBundleId(bundle,&bundleId);
+
+	if(isSystemBundle == false) {
+
+		char *bundleRoot = NULL;
+		char* topicPropertiesPath = NULL;
+		bundle_getEntry(bundle, ".", &bundleRoot);
+
+		if(bundleRoot != NULL){
+
+			asprintf(&topicPropertiesPath, "%s/META-INF/topics/%s/%s.properties", bundleRoot, isPublisher?"pub":"sub", topic);
+			topic_props = properties_load(topicPropertiesPath);
+			if(topic_props==NULL){
+				printf("PSEP: Could not load properties for %s on topic %s, bundleId=%ld\n", isPublisher?"publication":"subscription", topic,bundleId);
+			}
+
+			free(topicPropertiesPath);
+			free(bundleRoot);
+		}
+	}
+
+	return topic_props;
+}
+
+celix_status_t pubsubEndpoint_create(const char* fwUUID, const char* scope, const char* topic, long serviceId,const char* endpoint,properties_pt topic_props,pubsub_endpoint_pt* psEp){
+	celix_status_t status = CELIX_SUCCESS;
+
+	*psEp = calloc(1, sizeof(**psEp));
+
+	pubsubEndpoint_setFields(*psEp, fwUUID, scope, topic, serviceId, endpoint, topic_props, true);
+
+	return status;
+
+}
+
+celix_status_t pubsubEndpoint_clone(pubsub_endpoint_pt in, pubsub_endpoint_pt *out){
+	celix_status_t status = CELIX_SUCCESS;
+
+	*out = calloc(1,sizeof(**out));
+
+	pubsubEndpoint_setFields(*out, in->frameworkUUID, in->scope, in->topic, in->serviceID, in->endpoint, in->topic_props, true);
+
+	return status;
+
+}
+
+celix_status_t pubsubEndpoint_createFromServiceReference(service_reference_pt reference, pubsub_endpoint_pt* psEp, bool isPublisher){
+	celix_status_t status = CELIX_SUCCESS;
+
+	pubsub_endpoint_pt ep = calloc(1,sizeof(*ep));
+
+	bundle_pt bundle = NULL;
+	bundle_context_pt ctxt = NULL;
+	const char* fwUUID = NULL;
+	serviceReference_getBundle(reference,&bundle);
+	bundle_getContext(bundle,&ctxt);
+	bundleContext_getProperty(ctxt,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
+
+	const char* scope = NULL;
+	serviceReference_getProperty(reference, PUBSUB_SUBSCRIBER_SCOPE,&scope);
+
+	const char* topic = NULL;
+	serviceReference_getProperty(reference, PUBSUB_SUBSCRIBER_TOPIC,&topic);
+
+	const char* serviceId = NULL;
+	serviceReference_getProperty(reference,(char*)OSGI_FRAMEWORK_SERVICE_ID,&serviceId);
+
+	/* TODO: is topic_props==NULL a fatal error such that EP cannot be created? */
+	properties_pt topic_props = pubsubEndpoint_getTopicProperties(bundle, topic, isPublisher);
+
+	pubsubEndpoint_setFields(ep, fwUUID, scope!=NULL?scope:PUBSUB_SUBSCRIBER_SCOPE_DEFAULT, topic, strtol(serviceId,NULL,10), NULL, topic_props, false);
+
+	if (!ep->frameworkUUID || !ep->serviceID || !ep->scope || !ep->topic) {
+		fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "PUBSUB_ENDPOINT: incomplete description!.");
+		status = CELIX_BUNDLE_EXCEPTION;
+		pubsubEndpoint_destroy(ep);
+		*psEp = NULL;
+	}
+	else{
+		*psEp = ep;
+	}
+
+	return status;
+
+}
+
+celix_status_t pubsubEndpoint_createFromListenerHookInfo(listener_hook_info_pt info,pubsub_endpoint_pt* psEp, bool isPublisher){
+	celix_status_t status = CELIX_SUCCESS;
+
+	const char* fwUUID=NULL;
+	bundleContext_getProperty(info->context,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
+
+	if(fwUUID==NULL){
+		return CELIX_BUNDLE_EXCEPTION;
+	}
+
+	char* topic = pubsub_getTopicFromFilter(info->filter);
+	if(topic==NULL){
+		return CELIX_BUNDLE_EXCEPTION;
+	}
+
+	*psEp = calloc(1, sizeof(**psEp));
+
+	char* scope = pubsub_getScopeFromFilter(info->filter);
+	if(scope == NULL) {
+		scope = strdup(PUBSUB_PUBLISHER_SCOPE_DEFAULT);
+	}
+
+	bundle_pt bundle = NULL;
+	long bundleId = -1;
+	bundleContext_getBundle(info->context,&bundle);
+
+	bundle_getBundleId(bundle,&bundleId);
+
+	properties_pt topic_props = pubsubEndpoint_getTopicProperties(bundle, topic, isPublisher);
+
+	/* TODO: is topic_props==NULL a fatal error such that EP cannot be created? */
+	pubsubEndpoint_setFields(*psEp, fwUUID, scope!=NULL?scope:PUBSUB_SUBSCRIBER_SCOPE_DEFAULT, topic, bundleId, NULL, topic_props, false);
+
+	free(topic);
+	free(scope);
+
+
+	return status;
+}
+
+celix_status_t pubsubEndpoint_destroy(pubsub_endpoint_pt psEp){
+
+	if(psEp->frameworkUUID!=NULL){
+		free(psEp->frameworkUUID);
+		psEp->frameworkUUID = NULL;
+	}
+
+	if(psEp->scope!=NULL){
+		free(psEp->scope);
+		psEp->scope = NULL;
+	}
+
+	if(psEp->topic!=NULL){
+		free(psEp->topic);
+		psEp->topic = NULL;
+	}
+
+	if(psEp->endpoint!=NULL){
+		free(psEp->endpoint);
+		psEp->endpoint = NULL;
+	}
+
+	if(psEp->topic_props != NULL){
+		properties_destroy(psEp->topic_props);
+	}
+
+	free(psEp);
+
+	return CELIX_SUCCESS;
+
+}
+
+bool pubsubEndpoint_equals(pubsub_endpoint_pt psEp1,pubsub_endpoint_pt psEp2){
+
+	return ((strcmp(psEp1->frameworkUUID,psEp2->frameworkUUID)==0) &&
+			(strcmp(psEp1->scope,psEp2->scope)==0) &&
+			(strcmp(psEp1->topic,psEp2->topic)==0) &&
+			(psEp1->serviceID == psEp2->serviceID) /*&&
+			((psEp1->endpoint==NULL && psEp2->endpoint==NULL)||(strcmp(psEp1->endpoint,psEp2->endpoint)==0))*/
+	);
+}
+
+char *createScopeTopicKey(const char* scope, const char* topic) {
+	char *result = NULL;
+	asprintf(&result, "%s:%s", scope, topic);
+
+	return result;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_spi/src/pubsub_utils.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_spi/src/pubsub_utils.c b/pubsub/pubsub_spi/src/pubsub_utils.c
new file mode 100644
index 0000000..19b2271
--- /dev/null
+++ b/pubsub/pubsub_spi/src/pubsub_utils.c
@@ -0,0 +1,170 @@
+/**
+ *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.
+ */
+/*
+ * pubsub_utils.c
+ *
+ *  \date       Sep 24, 2015
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "constants.h"
+
+#include "pubsub_common.h"
+#include "pubsub/publisher.h"
+#include "pubsub_utils.h"
+
+#include "array_list.h"
+#include "bundle.h"
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define MAX_KEYBUNDLE_LENGTH 256
+
+char* pubsub_getScopeFromFilter(char* bundle_filter){
+
+	char* scope = NULL;
+
+	char* filter = strdup(bundle_filter);
+
+	char* oc = strstr(filter,OSGI_FRAMEWORK_OBJECTCLASS);
+	if(oc!=NULL){
+		oc+=strlen(OSGI_FRAMEWORK_OBJECTCLASS)+1;
+		if(strncmp(oc,PUBSUB_PUBLISHER_SERVICE_NAME,strlen(PUBSUB_PUBLISHER_SERVICE_NAME))==0){
+
+			char* scopes = strstr(filter,PUBSUB_PUBLISHER_SCOPE);
+			if(scopes!=NULL){
+
+				scopes+=strlen(PUBSUB_PUBLISHER_SCOPE)+1;
+				char* bottom=strchr(scopes,')');
+				*bottom='\0';
+
+				scope=strdup(scopes);
+			} else {
+			    scope=strdup(PUBSUB_PUBLISHER_SCOPE_DEFAULT);
+			}
+		}
+	}
+
+	free(filter);
+
+	return scope;
+}
+
+char* pubsub_getTopicFromFilter(char* bundle_filter){
+
+	char* topic = NULL;
+
+	char* filter = strdup(bundle_filter);
+
+	char* oc = strstr(filter,OSGI_FRAMEWORK_OBJECTCLASS);
+	if(oc!=NULL){
+		oc+=strlen(OSGI_FRAMEWORK_OBJECTCLASS)+1;
+		if(strncmp(oc,PUBSUB_PUBLISHER_SERVICE_NAME,strlen(PUBSUB_PUBLISHER_SERVICE_NAME))==0){
+
+			char* topics = strstr(filter,PUBSUB_PUBLISHER_TOPIC);
+			if(topics!=NULL){
+
+				topics+=strlen(PUBSUB_PUBLISHER_TOPIC)+1;
+				char* bottom=strchr(topics,')');
+				*bottom='\0';
+
+				topic=strdup(topics);
+
+			}
+		}
+	}
+
+	free(filter);
+
+	return topic;
+
+}
+
+array_list_pt pubsub_getTopicsFromString(char* string){
+
+	array_list_pt topic_list = NULL;
+	arrayList_create(&topic_list);
+
+	char* topics = strdup(string);
+
+	char* topic = strtok(topics,",;|# ");
+	arrayList_add(topic_list,strdup(topic));
+
+	while( (topic = strtok(NULL,",;|# ")) !=NULL){
+		arrayList_add(topic_list,strdup(topic));
+	}
+
+	free(topics);
+
+	return topic_list;
+
+}
+
+/**
+ * Loop through all bundles and look for the bundle with the keys inside.
+ * If no key bundle found, return NULL
+ *
+ * Caller is responsible for freeing the object
+ */
+char* pubsub_getKeysBundleDir(bundle_context_pt ctx)
+{
+	array_list_pt bundles = NULL;
+	bundleContext_getBundles(ctx, &bundles);
+	int nrOfBundles = arrayList_size(bundles);
+	long bundle_id = -1;
+	char* result = NULL;
+
+	for (int i = 0; i < nrOfBundles; i++){
+		bundle_pt b = arrayList_get(bundles, i);
+
+		/* Skip bundle 0 (framework bundle) since it has no path nor revisions */
+		bundle_getBundleId(b, &bundle_id);
+		if(bundle_id==0){
+			continue;
+		}
+
+		char* dir = NULL;
+		bundle_getEntry(b, ".", &dir);
+
+		char cert_dir[MAX_KEYBUNDLE_LENGTH];
+		snprintf(cert_dir, MAX_KEYBUNDLE_LENGTH, "%s/META-INF/keys", dir);
+
+		struct stat s;
+		int err = stat(cert_dir, &s);
+		if (err != -1){
+			if (S_ISDIR(s.st_mode)){
+				result = dir;
+				break;
+			}
+		}
+
+		free(dir);
+	}
+
+	arrayList_destroy(bundles);
+
+	return result;
+}
+

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_topology_manager/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_topology_manager/CMakeLists.txt b/pubsub/pubsub_topology_manager/CMakeLists.txt
index 784ca21..73b9ecb 100644
--- a/pubsub/pubsub_topology_manager/CMakeLists.txt
+++ b/pubsub/pubsub_topology_manager/CMakeLists.txt
@@ -15,22 +15,23 @@
 # specific language governing permissions and limitations
 # under the License.
 
-add_bundle(org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
+add_bundle(celix_pubsub_topology_manager
     BUNDLE_SYMBOLICNAME "apache_celix_pubsub_topology_manager"
     VERSION "1.0.0"
     SOURCES
-    	private/src/pstm_activator.c
-    	private/src/pubsub_topology_manager.c
-    	${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_endpoint.c
-    	${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c	
+    	src/pstm_activator.c
+    	src/pubsub_topology_manager.c
+    	src/pubsub_topology_manager.h
 )
+target_link_libraries(celix_pubsub_topology_manager PRIVATE Celix::framework Celix::log_helper Celix::pubsub_spi)
 
-bundle_files(org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
-   ${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include/pubsub_topic_info.descriptor
+get_target_property(DESC Celix::pubsub_spi TOPIC_INFO_DESCRIPTOR)
+bundle_files(celix_pubsub_topology_manager
+	${DESC}
     DESTINATION "META-INF/descriptors/services"
 )
-target_link_libraries(org.apache.celix.pubsub_topology_manager.PubSubTopologyManager PRIVATE Celix::framework Celix::log_helper)
 
+install_bundle(celix_pubsub_topology_manager)
 
-install_bundle(org.apache.celix.pubsub_topology_manager.PubSubTopologyManager)
+add_library(Celix::pubsub_topology_manager ALIAS celix_pubsub_topology_manager)
 

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_topology_manager/private/include/pubsub_topology_manager.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_topology_manager/private/include/pubsub_topology_manager.h b/pubsub/pubsub_topology_manager/private/include/pubsub_topology_manager.h
deleted file mode 100644
index 7614e0c..0000000
--- a/pubsub/pubsub_topology_manager/private/include/pubsub_topology_manager.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- *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.
- */
-/*
- * pubsub_topology_manager.h
- *
- *  \date       Sep 29, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef PUBSUB_TOPOLOGY_MANAGER_H_
-#define PUBSUB_TOPOLOGY_MANAGER_H_
-
-#include "endpoint_listener.h"
-#include "service_reference.h"
-#include "bundle_context.h"
-#include "log_helper.h"
-
-#include "pubsub_common.h"
-#include "pubsub_endpoint.h"
-#include "publisher.h"
-#include "subscriber.h"
-
-
-struct pubsub_topology_manager {
-	bundle_context_pt context;
-
-	celix_thread_mutex_t psaListLock;
-	array_list_pt psaList;
-
-	celix_thread_mutex_t discoveryListLock;
-	hash_map_pt discoveryList; //<serviceReference,NULL>
-
-	celix_thread_mutex_t publicationsLock;
-	hash_map_pt publications; //<topic(string),list<pubsub_ep>>
-
-	celix_thread_mutex_t subscriptionsLock;
-	hash_map_pt subscriptions; //<topic(string),list<pubsub_ep>>
-
-	log_helper_pt loghelper;
-};
-
-typedef struct pubsub_topology_manager *pubsub_topology_manager_pt;
-
-celix_status_t pubsub_topologyManager_create(bundle_context_pt context, log_helper_pt logHelper, pubsub_topology_manager_pt *manager);
-celix_status_t pubsub_topologyManager_destroy(pubsub_topology_manager_pt manager);
-celix_status_t pubsub_topologyManager_closeImports(pubsub_topology_manager_pt manager);
-
-celix_status_t pubsub_topologyManager_psaAdded(void *handle, service_reference_pt reference, void *service);
-celix_status_t pubsub_topologyManager_psaModified(void *handle, service_reference_pt reference, void *service);
-celix_status_t pubsub_topologyManager_psaRemoved(void *handle, service_reference_pt reference, void *service);
-
-celix_status_t pubsub_topologyManager_pubsubDiscoveryAdded(void* handle, service_reference_pt reference, void* service);
-celix_status_t pubsub_topologyManager_pubsubDiscoveryModified(void * handle, service_reference_pt reference, void* service);
-celix_status_t pubsub_topologyManager_pubsubDiscoveryRemoved(void * handle, service_reference_pt reference, void* service);
-
-celix_status_t pubsub_topologyManager_subscriberAdded(void * handle, service_reference_pt reference, void * service);
-celix_status_t pubsub_topologyManager_subscriberModified(void * handle, service_reference_pt reference, void * service);
-celix_status_t pubsub_topologyManager_subscriberRemoved(void * handle, service_reference_pt reference, void * service);
-
-celix_status_t pubsub_topologyManager_publisherTrackerAdded(void *handle, array_list_pt listeners);
-celix_status_t pubsub_topologyManager_publisherTrackerRemoved(void *handle, array_list_pt listeners);
-
-celix_status_t pubsub_topologyManager_announcePublisher(void *handle, pubsub_endpoint_pt pubEP);
-celix_status_t pubsub_topologyManager_removePublisher(void *handle, pubsub_endpoint_pt pubEP);
-
-#endif /* PUBSUB_TOPOLOGY_MANAGER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_topology_manager/private/src/pstm_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_topology_manager/private/src/pstm_activator.c b/pubsub/pubsub_topology_manager/private/src/pstm_activator.c
deleted file mode 100644
index 4d6dd27..0000000
--- a/pubsub/pubsub_topology_manager/private/src/pstm_activator.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/**
- *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.
- */
-/*
- * pstm_activator.c
- *
- *  \date       Sep 29, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "constants.h"
-#include "bundle_activator.h"
-#include "service_tracker.h"
-#include "service_registration.h"
-
-#include "endpoint_listener.h"
-#include "remote_constants.h"
-#include "listener_hook_service.h"
-#include "log_service.h"
-#include "log_helper.h"
-
-
-#include "pubsub_topology_manager.h"
-#include "publisher_endpoint_announce.h"
-
-struct activator {
-	bundle_context_pt context;
-
-	pubsub_topology_manager_pt manager;
-
-	service_tracker_pt pubsubDiscoveryTracker;
-	service_tracker_pt pubsubAdminTracker;
-	service_tracker_pt pubsubSubscribersTracker;
-
-	listener_hook_service_pt hookService;
-	service_registration_pt hook;
-
-	publisher_endpoint_announce_pt publisherEPDiscover;
-	service_registration_pt publisherEPDiscoverService;
-
-	log_helper_pt loghelper;
-};
-
-
-static celix_status_t bundleActivator_createPSDTracker(struct activator *activator, service_tracker_pt *tracker);
-static celix_status_t bundleActivator_createPSATracker(struct activator *activator, service_tracker_pt *tracker);
-static celix_status_t bundleActivator_createPSSubTracker(struct activator *activator, service_tracker_pt *tracker);
-
-
-static celix_status_t bundleActivator_createPSDTracker(struct activator *activator, service_tracker_pt *tracker) {
-	celix_status_t status;
-
-	service_tracker_customizer_pt customizer = NULL;
-
-	status = serviceTrackerCustomizer_create(activator->manager,
-			NULL,
-			pubsub_topologyManager_pubsubDiscoveryAdded,
-			pubsub_topologyManager_pubsubDiscoveryModified,
-			pubsub_topologyManager_pubsubDiscoveryRemoved,
-			&customizer);
-
-	if (status == CELIX_SUCCESS) {
-		status = serviceTracker_create(activator->context, (char *) PUBSUB_DISCOVERY_SERVICE, customizer, tracker);
-	}
-
-	return status;
-}
-
-static celix_status_t bundleActivator_createPSATracker(struct activator *activator, service_tracker_pt *tracker) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	service_tracker_customizer_pt customizer = NULL;
-
-	status = serviceTrackerCustomizer_create(activator->manager,
-			NULL,
-			pubsub_topologyManager_psaAdded,
-			pubsub_topologyManager_psaModified,
-			pubsub_topologyManager_psaRemoved,
-			&customizer);
-
-	if (status == CELIX_SUCCESS) {
-		status = serviceTracker_create(activator->context, PUBSUB_ADMIN_SERVICE, customizer, tracker);
-	}
-
-	return status;
-}
-
-static celix_status_t bundleActivator_createPSSubTracker(struct activator *activator, service_tracker_pt *tracker) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	service_tracker_customizer_pt customizer = NULL;
-
-	status = serviceTrackerCustomizer_create(activator->manager,
-			NULL,
-			pubsub_topologyManager_subscriberAdded,
-			pubsub_topologyManager_subscriberModified,
-			pubsub_topologyManager_subscriberRemoved,
-			&customizer);
-
-	if (status == CELIX_SUCCESS) {
-		status = serviceTracker_create(activator->context, PUBSUB_SUBSCRIBER_SERVICE_NAME, customizer, tracker);
-	}
-
-	return status;
-}
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = NULL;
-
-	activator = calloc(1,sizeof(struct activator));
-
-	if (!activator) {
-		return CELIX_ENOMEM;
-	}
-
-	activator->context = context;
-
-	logHelper_create(context, &activator->loghelper);
-	logHelper_start(activator->loghelper);
-
-	status = pubsub_topologyManager_create(context, activator->loghelper, &activator->manager);
-	if (status == CELIX_SUCCESS) {
-		status = bundleActivator_createPSDTracker(activator, &activator->pubsubDiscoveryTracker);
-		if (status == CELIX_SUCCESS) {
-			status = bundleActivator_createPSATracker(activator, &activator->pubsubAdminTracker);
-			if (status == CELIX_SUCCESS) {
-				status = bundleActivator_createPSSubTracker(activator, &activator->pubsubSubscribersTracker);
-				if (status == CELIX_SUCCESS) {
-					*userData = activator;
-				}
-			}
-		}
-	}
-
-	if(status != CELIX_SUCCESS){
-		bundleActivator_destroy(activator, context);
-	}
-
-	return status;
-}
-
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-
-	publisher_endpoint_announce_pt pubEPDiscover = calloc(1, sizeof(*pubEPDiscover));
-	pubEPDiscover->handle = activator->manager;
-	pubEPDiscover->announcePublisher = pubsub_topologyManager_announcePublisher;
-	pubEPDiscover->removePublisher = pubsub_topologyManager_removePublisher;
-	activator->publisherEPDiscover = pubEPDiscover;
-
-	status += bundleContext_registerService(context, (char *) PUBSUB_TM_ANNOUNCE_PUBLISHER_SERVICE, pubEPDiscover, NULL, &activator->publisherEPDiscoverService);
-
-
-	listener_hook_service_pt hookService = calloc(1,sizeof(*hookService));
-	hookService->handle = activator->manager;
-	hookService->added = pubsub_topologyManager_publisherTrackerAdded;
-	hookService->removed = pubsub_topologyManager_publisherTrackerRemoved;
-	activator->hookService = hookService;
-
-	status += bundleContext_registerService(context, (char *) OSGI_FRAMEWORK_LISTENER_HOOK_SERVICE_NAME, hookService, NULL, &activator->hook);
-
-	/* NOTE: Enable those line in order to remotely expose the topic_info service
-	properties_pt props = properties_create();
-	properties_set(props, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, (char *) PUBSUB_TOPIC_INFO_SERVICE);
-	status += bundleContext_registerService(context, (char *) PUBSUB_TOPIC_INFO_SERVICE, activator->topicInfo, props, &activator->topicInfoService);
-	*/
-	status += serviceTracker_open(activator->pubsubAdminTracker);
-
-	status += serviceTracker_open(activator->pubsubDiscoveryTracker);
-
-	status += serviceTracker_open(activator->pubsubSubscribersTracker);
-
-
-	return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-
-	serviceTracker_close(activator->pubsubSubscribersTracker);
-	serviceTracker_close(activator->pubsubDiscoveryTracker);
-	serviceTracker_close(activator->pubsubAdminTracker);
-
-	serviceRegistration_unregister(activator->publisherEPDiscoverService);
-	free(activator->publisherEPDiscover);
-
-	serviceRegistration_unregister(activator->hook);
-	free(activator->hookService);
-
-	return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	struct activator *activator = userData;
-	if (activator == NULL) {
-		status = CELIX_BUNDLE_EXCEPTION;
-	} else {
-
-		if(activator->pubsubSubscribersTracker!=NULL){
-			serviceTracker_destroy(activator->pubsubSubscribersTracker);
-		}
-		if(activator->pubsubDiscoveryTracker!=NULL){
-			serviceTracker_destroy(activator->pubsubDiscoveryTracker);
-		}
-		if(activator->pubsubAdminTracker!=NULL){
-			serviceTracker_destroy(activator->pubsubAdminTracker);
-		}
-
-		if(activator->manager!=NULL){
-			status = pubsub_topologyManager_destroy(activator->manager);
-		}
-
-		logHelper_stop(activator->loghelper);
-		logHelper_destroy(&activator->loghelper);
-
-		free(activator);
-	}
-
-	return status;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_topology_manager/private/src/pubsub_topology_manager.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_topology_manager/private/src/pubsub_topology_manager.c b/pubsub/pubsub_topology_manager/private/src/pubsub_topology_manager.c
deleted file mode 100644
index 987d864..0000000
--- a/pubsub/pubsub_topology_manager/private/src/pubsub_topology_manager.c
+++ /dev/null
@@ -1,723 +0,0 @@
-/**
- *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.
- */
-/*
- * pubsub_topology_manager.c
- *
- *  \date       Sep 29, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-
-#include "hash_map.h"
-#include "array_list.h"
-#include "bundle_context.h"
-#include "constants.h"
-#include "module.h"
-#include "bundle.h"
-#include "remote_service_admin.h"
-#include "remote_constants.h"
-#include "filter.h"
-#include "listener_hook_service.h"
-#include "utils.h"
-#include "service_reference.h"
-#include "service_registration.h"
-#include "log_service.h"
-#include "log_helper.h"
-
-#include "publisher_endpoint_announce.h"
-#include "pubsub_topology_manager.h"
-#include "pubsub_endpoint.h"
-#include "pubsub_admin.h"
-#include "pubsub_utils.h"
-
-
-celix_status_t pubsub_topologyManager_create(bundle_context_pt context, log_helper_pt logHelper, pubsub_topology_manager_pt *manager) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*manager = calloc(1, sizeof(**manager));
-	if (!*manager) {
-		return CELIX_ENOMEM;
-	}
-
-	(*manager)->context = context;
-
-	celix_thread_mutexattr_t psaAttr;
-	celixThreadMutexAttr_create(&psaAttr);
-	celixThreadMutexAttr_settype(&psaAttr, CELIX_THREAD_MUTEX_RECURSIVE);
-	status = celixThreadMutex_create(&(*manager)->psaListLock, &psaAttr);
-	celixThreadMutexAttr_destroy(&psaAttr);
-
-	status = celixThreadMutex_create(&(*manager)->publicationsLock, NULL);
-	status = celixThreadMutex_create(&(*manager)->subscriptionsLock, NULL);
-	status = celixThreadMutex_create(&(*manager)->discoveryListLock, NULL);
-
-	arrayList_create(&(*manager)->psaList);
-
-	(*manager)->discoveryList = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
-	(*manager)->publications = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-	(*manager)->subscriptions = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
-	(*manager)->loghelper = logHelper;
-
-	return status;
-}
-
-celix_status_t pubsub_topologyManager_destroy(pubsub_topology_manager_pt manager) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&manager->discoveryListLock);
-	hashMap_destroy(manager->discoveryList, false, false);
-	celixThreadMutex_unlock(&manager->discoveryListLock);
-	celixThreadMutex_destroy(&manager->discoveryListLock);
-
-	celixThreadMutex_lock(&manager->psaListLock);
-	arrayList_destroy(manager->psaList);
-	celixThreadMutex_unlock(&manager->psaListLock);
-	celixThreadMutex_destroy(&manager->psaListLock);
-
-	celixThreadMutex_lock(&manager->publicationsLock);
-	hash_map_iterator_pt pubit = hashMapIterator_create(manager->publications);
-	while(hashMapIterator_hasNext(pubit)){
-		array_list_pt l = (array_list_pt)hashMapIterator_nextValue(pubit);
-		int i;
-		for(i=0;i<arrayList_size(l);i++){
-			pubsubEndpoint_destroy((pubsub_endpoint_pt)arrayList_get(l,i));
-		}
-		arrayList_destroy(l);
-	}
-	hashMapIterator_destroy(pubit);
-	hashMap_destroy(manager->publications, true, false);
-	celixThreadMutex_unlock(&manager->publicationsLock);
-	celixThreadMutex_destroy(&manager->publicationsLock);
-
-	celixThreadMutex_lock(&manager->subscriptionsLock);
-	hash_map_iterator_pt subit = hashMapIterator_create(manager->subscriptions);
-	while(hashMapIterator_hasNext(subit)){
-		array_list_pt l = (array_list_pt)hashMapIterator_nextValue(subit);
-		int i;
-		for(i=0;i<arrayList_size(l);i++){
-			pubsubEndpoint_destroy((pubsub_endpoint_pt)arrayList_get(l,i));
-		}
-		arrayList_destroy(l);
-	}
-	hashMapIterator_destroy(subit);
-	hashMap_destroy(manager->subscriptions, true, false);
-	celixThreadMutex_unlock(&manager->subscriptionsLock);
-	celixThreadMutex_destroy(&manager->subscriptionsLock);
-
-	free(manager);
-
-	return status;
-}
-
-celix_status_t pubsub_topologyManager_psaAdded(void * handle, service_reference_pt reference, void * service) {
-	celix_status_t status = CELIX_SUCCESS;
-	pubsub_topology_manager_pt manager = handle;
-	int i;
-
-	pubsub_admin_service_pt psa = (pubsub_admin_service_pt) service;
-	logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "PSTM: Added PSA");
-
-	celixThreadMutex_lock(&manager->psaListLock);
-	arrayList_add(manager->psaList, psa);
-	celixThreadMutex_unlock(&manager->psaListLock);
-
-	// Add already detected subscriptions to new PSA
-	celixThreadMutex_lock(&manager->subscriptionsLock);
-	hash_map_iterator_pt subscriptionsIterator = hashMapIterator_create(manager->subscriptions);
-
-	while (hashMapIterator_hasNext(subscriptionsIterator)) {
-		array_list_pt sub_ep_list = hashMapIterator_nextValue(subscriptionsIterator);
-		for(i=0;i<arrayList_size(sub_ep_list);i++){
-			status += psa->addSubscription(psa->admin, (pubsub_endpoint_pt)arrayList_get(sub_ep_list,i));
-		}
-	}
-
-	hashMapIterator_destroy(subscriptionsIterator);
-
-	celixThreadMutex_unlock(&manager->subscriptionsLock);
-
-	// Add already detected publications to new PSA
-	status = celixThreadMutex_lock(&manager->publicationsLock);
-	hash_map_iterator_pt publicationsIterator = hashMapIterator_create(manager->publications);
-
-	while (hashMapIterator_hasNext(publicationsIterator)) {
-		array_list_pt pub_ep_list = hashMapIterator_nextValue(publicationsIterator);
-		for(i=0;i<arrayList_size(pub_ep_list);i++){
-			status += psa->addPublication(psa->admin, (pubsub_endpoint_pt)arrayList_get(pub_ep_list,i));
-		}
-	}
-
-	hashMapIterator_destroy(publicationsIterator);
-
-	celixThreadMutex_unlock(&manager->publicationsLock);
-
-	return status;
-}
-
-celix_status_t pubsub_topologyManager_psaModified(void * handle, service_reference_pt reference, void * service) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	// Nop...
-
-	return status;
-}
-
-celix_status_t pubsub_topologyManager_psaRemoved(void * handle, service_reference_pt reference, void * service) {
-	celix_status_t status = CELIX_SUCCESS;
-	pubsub_topology_manager_pt manager = handle;
-
-	pubsub_admin_service_pt psa = (pubsub_admin_service_pt) service;
-
-	/* Deactivate all publications */
-	celixThreadMutex_lock(&manager->publicationsLock);
-
-	hash_map_iterator_pt pubit = hashMapIterator_create(manager->publications);
-	while(hashMapIterator_hasNext(pubit)){
-		hash_map_entry_pt pub_entry = hashMapIterator_nextEntry(pubit);
-		char* scope_topic_key = (char*)hashMapEntry_getKey(pub_entry);
-		// Extract scope/topic name from key
-		char scope[MAX_SCOPE_LEN];
-		char topic[MAX_TOPIC_LEN];
-		sscanf(scope_topic_key, "%[^:]:%s", scope, topic );
-		array_list_pt pubEP_list = (array_list_pt)hashMapEntry_getValue(pub_entry);
-
-		status = psa->closeAllPublications(psa->admin,scope,topic);
-
-		if(status==CELIX_SUCCESS){
-			celixThreadMutex_lock(&manager->discoveryListLock);
-			hash_map_iterator_pt iter = hashMapIterator_create(manager->discoveryList);
-			while(hashMapIterator_hasNext(iter)){
-				service_reference_pt disc_sr = (service_reference_pt)hashMapIterator_nextKey(iter);
-				publisher_endpoint_announce_pt disc = NULL;
-				bundleContext_getService(manager->context, disc_sr, (void**) &disc);
-				const char* fwUUID = NULL;
-				bundleContext_getProperty(manager->context,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
-				int i;
-				for(i=0;i<arrayList_size(pubEP_list);i++){
-					pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pubEP_list,i);
-					if(strcmp(pubEP->frameworkUUID,fwUUID)==0){
-						disc->removePublisher(disc->handle,pubEP);
-					}
-				}
-				bundleContext_ungetService(manager->context, disc_sr, NULL);
-			}
-			hashMapIterator_destroy(iter);
-			celixThreadMutex_unlock(&manager->discoveryListLock);
-		}
-	}
-	hashMapIterator_destroy(pubit);
-
-	celixThreadMutex_unlock(&manager->publicationsLock);
-
-	/* Deactivate all subscriptions */
-	celixThreadMutex_lock(&manager->subscriptionsLock);
-	hash_map_iterator_pt subit = hashMapIterator_create(manager->subscriptions);
-	while(hashMapIterator_hasNext(subit)){
-		// TODO do some error checking
-		char* scope_topic = (char*)hashMapIterator_nextKey(subit);
-		char scope[MAX_TOPIC_LEN];
-		char topic[MAX_TOPIC_LEN];
-		memset(scope, 0 , MAX_TOPIC_LEN*sizeof(char));
-		memset(topic, 0 , MAX_TOPIC_LEN*sizeof(char));
-		sscanf(scope_topic, "%[^:]:%s", scope, topic );
-		status += psa->closeAllSubscriptions(psa->admin,scope, topic);
-	}
-	hashMapIterator_destroy(subit);
-	celixThreadMutex_unlock(&manager->subscriptionsLock);
-
-	celixThreadMutex_lock(&manager->psaListLock);
-	arrayList_removeElement(manager->psaList, psa);
-	celixThreadMutex_unlock(&manager->psaListLock);
-
-	logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "PSTM: Removed PSA");
-
-	return status;
-}
-
-celix_status_t pubsub_topologyManager_subscriberAdded(void * handle, service_reference_pt reference, void * service) {
-	celix_status_t status = CELIX_SUCCESS;
-	pubsub_topology_manager_pt manager = handle;
-	//subscriber_service_pt subscriber = (subscriber_service_pt)service;
-
-	pubsub_endpoint_pt sub = NULL;
-	if(pubsubEndpoint_createFromServiceReference(reference,&sub,false) == CELIX_SUCCESS){
-		celixThreadMutex_lock(&manager->subscriptionsLock);
-		char *sub_key = createScopeTopicKey(sub->scope, sub->topic);
-
-		array_list_pt sub_list_by_topic = hashMap_get(manager->subscriptions,sub_key);
-		if(sub_list_by_topic==NULL){
-			arrayList_create(&sub_list_by_topic);
-			hashMap_put(manager->subscriptions,strdup(sub_key),sub_list_by_topic);
-		}
-		free(sub_key);
-		arrayList_add(sub_list_by_topic,sub);
-
-		celixThreadMutex_unlock(&manager->subscriptionsLock);
-
-		int j;
-		double score = 0;
-		double best_score = 0;
-		pubsub_admin_service_pt best_psa = NULL;
-		celixThreadMutex_lock(&manager->psaListLock);
-		for(j=0;j<arrayList_size(manager->psaList);j++){
-			pubsub_admin_service_pt psa = (pubsub_admin_service_pt)arrayList_get(manager->psaList,j);
-			psa->matchEndpoint(psa->admin,sub,&score);
-			if(score>best_score){ /* We have a new winner! */
-				best_score = score;
-				best_psa = psa;
-			}
-		}
-
-		if(best_psa != NULL && best_score>0){
-			best_psa->addSubscription(best_psa->admin,sub);
-		}
-
-		// Inform discoveries for interest in the topic
-		celixThreadMutex_lock(&manager->discoveryListLock);
-		hash_map_iterator_pt iter = hashMapIterator_create(manager->discoveryList);
-		while(hashMapIterator_hasNext(iter)){
-			service_reference_pt disc_sr = (service_reference_pt)hashMapIterator_nextKey(iter);
-			publisher_endpoint_announce_pt disc = NULL;
-			bundleContext_getService(manager->context, disc_sr, (void**) &disc);
-			disc->interestedInTopic(disc->handle, sub->scope, sub->topic);
-			bundleContext_ungetService(manager->context, disc_sr, NULL);
-		}
-		hashMapIterator_destroy(iter);
-		celixThreadMutex_unlock(&manager->discoveryListLock);
-
-		celixThreadMutex_unlock(&manager->psaListLock);
-	}
-	else{
-		status=CELIX_INVALID_BUNDLE_CONTEXT;
-	}
-
-	return status;
-}
-
-celix_status_t pubsub_topologyManager_subscriberModified(void * handle, service_reference_pt reference, void * service) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	// Nop...
-
-	return status;
-}
-
-celix_status_t pubsub_topologyManager_subscriberRemoved(void * handle, service_reference_pt reference, void * service) {
-	celix_status_t status = CELIX_SUCCESS;
-	pubsub_topology_manager_pt manager = handle;
-
-	pubsub_endpoint_pt subcmp = NULL;
-	if(pubsubEndpoint_createFromServiceReference(reference,&subcmp,false) == CELIX_SUCCESS){
-
-		int j,k;
-
-		// Inform discoveries that we not interested in the topic any more
-		celixThreadMutex_lock(&manager->discoveryListLock);
-		hash_map_iterator_pt iter = hashMapIterator_create(manager->discoveryList);
-		while(hashMapIterator_hasNext(iter)){
-			service_reference_pt disc_sr = (service_reference_pt)hashMapIterator_nextKey(iter);
-			publisher_endpoint_announce_pt disc = NULL;
-			bundleContext_getService(manager->context, disc_sr, (void**) &disc);
-			disc->uninterestedInTopic(disc->handle, subcmp->scope, subcmp->topic);
-			bundleContext_ungetService(manager->context, disc_sr, NULL);
-		}
-		hashMapIterator_destroy(iter);
-		celixThreadMutex_unlock(&manager->discoveryListLock);
-
-		celixThreadMutex_lock(&manager->subscriptionsLock);
-		celixThreadMutex_lock(&manager->psaListLock);
-
-		char *sub_key = createScopeTopicKey(subcmp->scope,subcmp->topic);
-		array_list_pt sub_list_by_topic = hashMap_get(manager->subscriptions,sub_key);
-		free(sub_key);
-		if(sub_list_by_topic!=NULL){
-			for(j=0;j<arrayList_size(sub_list_by_topic);j++){
-				pubsub_endpoint_pt sub = arrayList_get(sub_list_by_topic,j);
-				if(pubsubEndpoint_equals(sub,subcmp)){
-					for(k=0;k<arrayList_size(manager->psaList);k++){
-						/* No problem with invoking removal on all psa's, only the one that manage this topic will do something */
-						pubsub_admin_service_pt psa = (pubsub_admin_service_pt)arrayList_get(manager->psaList,k);
-						psa->removeSubscription(psa->admin,sub);
-					}
-
-				}
-				arrayList_remove(sub_list_by_topic,j);
-
-				/* If it was the last subscriber for this topic, tell PSA to close the ZMQ socket */
-				if(arrayList_size(sub_list_by_topic)==0){
-					for(k=0;k<arrayList_size(manager->psaList);k++){
-						pubsub_admin_service_pt psa = (pubsub_admin_service_pt)arrayList_get(manager->psaList,k);
-						psa->closeAllSubscriptions(psa->admin,sub->scope, sub->topic);
-					}
-				}
-
-				pubsubEndpoint_destroy(sub);
-
-			}
-		}
-
-		celixThreadMutex_unlock(&manager->psaListLock);
-		celixThreadMutex_unlock(&manager->subscriptionsLock);
-
-		pubsubEndpoint_destroy(subcmp);
-
-	}
-	else{
-		status=CELIX_INVALID_BUNDLE_CONTEXT;
-	}
-
-	return status;
-
-}
-
-celix_status_t pubsub_topologyManager_pubsubDiscoveryAdded(void* handle, service_reference_pt reference, void* service) {
-	celix_status_t status = CELIX_SUCCESS;
-	pubsub_topology_manager_pt manager = (pubsub_topology_manager_pt)handle;
-	publisher_endpoint_announce_pt disc = (publisher_endpoint_announce_pt)service;
-
-	const char* fwUUID = NULL;
-
-	bundleContext_getProperty(manager->context,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
-	if(fwUUID==NULL){
-		printf("PSD: ERRROR: Cannot retrieve fwUUID.\n");
-		return CELIX_INVALID_BUNDLE_CONTEXT;
-	}
-
-	celixThreadMutex_lock(&manager->publicationsLock);
-
-	celixThreadMutex_lock(&manager->discoveryListLock);
-	hashMap_put(manager->discoveryList, reference, NULL);
-	celixThreadMutex_unlock(&manager->discoveryListLock);
-
-	hash_map_iterator_pt iter = hashMapIterator_create(manager->publications);
-	while(hashMapIterator_hasNext(iter)){
-		array_list_pt pubEP_list = (array_list_pt)hashMapIterator_nextValue(iter);
-		for(int i = 0; i < arrayList_size(pubEP_list); i++) {
-			pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pubEP_list,i);
-			if( (strcmp(pubEP->frameworkUUID,fwUUID)==0) && (pubEP->endpoint!=NULL)){
-				status += disc->announcePublisher(disc->handle,pubEP);
-			}
-		}
-	}
-	hashMapIterator_destroy(iter);
-
-	celixThreadMutex_unlock(&manager->publicationsLock);
-
-	celixThreadMutex_lock(&manager->subscriptionsLock);
-	iter = hashMapIterator_create(manager->subscriptions);
-
-	while(hashMapIterator_hasNext(iter)) {
-		array_list_pt l = (array_list_pt)hashMapIterator_nextValue(iter);
-		int i;
-		for(i=0;i<arrayList_size(l);i++){
-			pubsub_endpoint_pt subEp = (pubsub_endpoint_pt)arrayList_get(l,i);
-
-			disc->interestedInTopic(disc->handle, subEp->scope, subEp->topic);
-		}
-	}
-	hashMapIterator_destroy(iter);
-	celixThreadMutex_unlock(&manager->subscriptionsLock);
-
-	return status;
-}
-
-celix_status_t pubsub_topologyManager_pubsubDiscoveryModified(void * handle, service_reference_pt reference, void * service) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	status = pubsub_topologyManager_pubsubDiscoveryRemoved(handle, reference, service);
-	if (status == CELIX_SUCCESS) {
-		status = pubsub_topologyManager_pubsubDiscoveryAdded(handle, reference, service);
-	}
-
-	return status;
-}
-
-celix_status_t pubsub_topologyManager_pubsubDiscoveryRemoved(void * handle, service_reference_pt reference, void * service) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	pubsub_topology_manager_pt manager = handle;
-
-	celixThreadMutex_lock(&manager->discoveryListLock);
-
-
-	if (hashMap_remove(manager->discoveryList, reference)) {
-		logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "EndpointListener Removed");
-	}
-
-	celixThreadMutex_unlock(&manager->discoveryListLock);
-
-	return status;
-}
-
-
-celix_status_t pubsub_topologyManager_publisherTrackerAdded(void *handle, array_list_pt listeners) {
-
-	celix_status_t status = CELIX_SUCCESS;
-	pubsub_topology_manager_pt manager = handle;
-
-	int l_index;
-
-	for (l_index = 0; l_index < arrayList_size(listeners); l_index++) {
-
-		listener_hook_info_pt info = arrayList_get(listeners, l_index);
-
-		pubsub_endpoint_pt pub = NULL;
-		if(pubsubEndpoint_createFromListenerHookInfo(info, &pub, true) == CELIX_SUCCESS){
-
-			celixThreadMutex_lock(&manager->publicationsLock);
-			char *pub_key = createScopeTopicKey(pub->scope, pub->topic);
-			array_list_pt pub_list_by_topic = hashMap_get(manager->publications, pub_key);
-			if(pub_list_by_topic==NULL){
-				arrayList_create(&pub_list_by_topic);
-				hashMap_put(manager->publications,strdup(pub_key),pub_list_by_topic);
-			}
-			free(pub_key);
-			arrayList_add(pub_list_by_topic,pub);
-
-			celixThreadMutex_unlock(&manager->publicationsLock);
-
-			int j;
-			double score = 0;
-			double best_score = 0;
-			pubsub_admin_service_pt best_psa = NULL;
-			celixThreadMutex_lock(&manager->psaListLock);
-
-			for(j=0;j<arrayList_size(manager->psaList);j++){
-				pubsub_admin_service_pt psa = (pubsub_admin_service_pt)arrayList_get(manager->psaList,j);
-				psa->matchEndpoint(psa->admin,pub,&score);
-				if(score>best_score){ /* We have a new winner! */
-					best_score = score;
-					best_psa = psa;
-				}
-			}
-
-			if(best_psa != NULL && best_score>0){
-				status = best_psa->addPublication(best_psa->admin,pub);
-				if(status==CELIX_SUCCESS){
-					celixThreadMutex_lock(&manager->discoveryListLock);
-					hash_map_iterator_pt iter = hashMapIterator_create(manager->discoveryList);
-					while(hashMapIterator_hasNext(iter)){
-						service_reference_pt disc_sr = (service_reference_pt)hashMapIterator_nextKey(iter);
-						publisher_endpoint_announce_pt disc = NULL;
-						bundleContext_getService(manager->context, disc_sr, (void**) &disc);
-						disc->announcePublisher(disc->handle,pub);
-						bundleContext_ungetService(manager->context, disc_sr, NULL);
-					}
-					hashMapIterator_destroy(iter);
-					celixThreadMutex_unlock(&manager->discoveryListLock);
-				}
-			}
-
-			celixThreadMutex_unlock(&manager->psaListLock);
-
-		}
-
-	}
-
-	return status;
-
-}
-
-
-celix_status_t pubsub_topologyManager_publisherTrackerRemoved(void *handle, array_list_pt listeners) {
-	celix_status_t status = CELIX_SUCCESS;
-	pubsub_topology_manager_pt manager = handle;
-
-	int l_index;
-
-	for (l_index = 0; l_index < arrayList_size(listeners); l_index++) {
-
-		listener_hook_info_pt info = arrayList_get(listeners, l_index);
-
-		pubsub_endpoint_pt pubcmp = NULL;
-		if(pubsubEndpoint_createFromListenerHookInfo(info,&pubcmp,true) == CELIX_SUCCESS){
-
-
-			int j,k;
-			celixThreadMutex_lock(&manager->psaListLock);
-			celixThreadMutex_lock(&manager->publicationsLock);
-
-			char *pub_key = createScopeTopicKey(pubcmp->scope, pubcmp->topic);
-			array_list_pt pub_list_by_topic = hashMap_get(manager->publications,pub_key);
-			if(pub_list_by_topic!=NULL){
-				for(j=0;j<arrayList_size(pub_list_by_topic);j++){
-					pubsub_endpoint_pt pub = arrayList_get(pub_list_by_topic,j);
-					if(pubsubEndpoint_equals(pub,pubcmp)){
-						for(k=0;k<arrayList_size(manager->psaList);k++){
-							pubsub_admin_service_pt psa = (pubsub_admin_service_pt)arrayList_get(manager->psaList,k);
-							status = psa->removePublication(psa->admin,pub);
-							if(status==CELIX_SUCCESS){ /* We found the one that manages this endpoint */
-								celixThreadMutex_lock(&manager->discoveryListLock);
-								hash_map_iterator_pt iter = hashMapIterator_create(manager->discoveryList);
-								while(hashMapIterator_hasNext(iter)){
-									service_reference_pt disc_sr = (service_reference_pt)hashMapIterator_nextKey(iter);
-									publisher_endpoint_announce_pt disc = NULL;
-									bundleContext_getService(manager->context, disc_sr, (void**) &disc);
-									disc->removePublisher(disc->handle,pub);
-									bundleContext_ungetService(manager->context, disc_sr, NULL);
-								}
-								hashMapIterator_destroy(iter);
-								celixThreadMutex_unlock(&manager->discoveryListLock);
-							}
-							else if(status ==  CELIX_ILLEGAL_ARGUMENT){ /* Not a real error, just saying this psa does not handle this endpoint */
-								status = CELIX_SUCCESS;
-							}
-						}
-						//}
-						arrayList_remove(pub_list_by_topic,j);
-
-						/* If it was the last publisher for this topic, tell PSA to close the ZMQ socket and then inform the discovery */
-						if(arrayList_size(pub_list_by_topic)==0){
-							for(k=0;k<arrayList_size(manager->psaList);k++){
-								pubsub_admin_service_pt psa = (pubsub_admin_service_pt)arrayList_get(manager->psaList,k);
-								psa->closeAllPublications(psa->admin,pub->scope, pub->topic);
-							}
-						}
-
-						pubsubEndpoint_destroy(pub);
-					}
-
-				}
-			}
-
-			celixThreadMutex_unlock(&manager->publicationsLock);
-			celixThreadMutex_unlock(&manager->psaListLock);
-
-			free(pub_key);
-
-			pubsubEndpoint_destroy(pubcmp);
-
-		}
-
-	}
-
-	return status;
-}
-
-celix_status_t pubsub_topologyManager_announcePublisher(void *handle, pubsub_endpoint_pt pubEP){
-	celix_status_t status = CELIX_SUCCESS;
-	printf("PSTM: New publisher discovered for topic %s [fwUUID=%s, ep=%s]\n",pubEP->topic,pubEP->frameworkUUID,pubEP->endpoint);
-
-	pubsub_topology_manager_pt manager = handle;
-	celixThreadMutex_lock(&manager->psaListLock);
-	celixThreadMutex_lock(&manager->publicationsLock);
-
-	char *pub_key = createScopeTopicKey(pubEP->scope, pubEP->topic);
-
-	array_list_pt pub_list_by_topic = hashMap_get(manager->publications,pub_key);
-	if(pub_list_by_topic==NULL){
-		arrayList_create(&pub_list_by_topic);
-		hashMap_put(manager->publications,strdup(pub_key),pub_list_by_topic);
-	}
-	free(pub_key);
-
-	/* Shouldn't be any other duplicate, since it's filtered out by the discovery */
-	pubsub_endpoint_pt p = NULL;
-	pubsubEndpoint_clone(pubEP, &p);
-	arrayList_add(pub_list_by_topic,p);
-
-	int j;
-	double score = 0;
-	double best_score = 0;
-	pubsub_admin_service_pt best_psa = NULL;
-
-	for(j=0;j<arrayList_size(manager->psaList);j++){
-		pubsub_admin_service_pt psa = (pubsub_admin_service_pt)arrayList_get(manager->psaList,j);
-		psa->matchEndpoint(psa->admin,p,&score);
-		if(score>best_score){ /* We have a new winner! */
-			best_score = score;
-			best_psa = psa;
-		}
-	}
-
-	if(best_psa != NULL && best_score>0){
-		best_psa->addPublication(best_psa->admin,p);
-	}
-	else{
-		status = CELIX_ILLEGAL_STATE;
-	}
-
-	celixThreadMutex_unlock(&manager->publicationsLock);
-	celixThreadMutex_unlock(&manager->psaListLock);
-
-	return status;
-}
-
-celix_status_t pubsub_topologyManager_removePublisher(void *handle, pubsub_endpoint_pt pubEP){
-	celix_status_t status = CELIX_SUCCESS;
-	printf("PSTM: Publisher removed for topic %s [fwUUID=%s, ep=%s]\n",pubEP->topic,pubEP->frameworkUUID,pubEP->endpoint);
-
-	pubsub_topology_manager_pt manager = handle;
-	celixThreadMutex_lock(&manager->psaListLock);
-	celixThreadMutex_lock(&manager->publicationsLock);
-	int i;
-
-	char *pub_key = createScopeTopicKey(pubEP->scope, pubEP->topic);
-	array_list_pt pub_list_by_topic = hashMap_get(manager->publications,pub_key);
-	if(pub_list_by_topic==NULL){
-		printf("PSTM: ERROR: Cannot find topic for known endpoint [%s,%s,%s]. Something is inconsistent.\n",pub_key,pubEP->frameworkUUID,pubEP->endpoint);
-		status = CELIX_ILLEGAL_STATE;
-	}
-	else{
-
-		pubsub_endpoint_pt p = NULL;
-		bool found = false;
-
-		for(i=0;!found && i<arrayList_size(pub_list_by_topic);i++){
-			p = (pubsub_endpoint_pt)arrayList_get(pub_list_by_topic,i);
-			found = pubsubEndpoint_equals(p,pubEP);
-		}
-
-		if(found && p !=NULL){
-
-			for(i=0;i<arrayList_size(manager->psaList);i++){
-				pubsub_admin_service_pt psa = (pubsub_admin_service_pt)arrayList_get(manager->psaList,i);
-				/* No problem with invoking removal on all psa's, only the one that manage this topic will do something */
-				psa->removePublication(psa->admin,p);
-			}
-
-			arrayList_removeElement(pub_list_by_topic,p);
-
-			/* If it was the last publisher for this topic, tell PSA to close the ZMQ socket */
-			if(arrayList_size(pub_list_by_topic)==0){
-
-				for(i=0;i<arrayList_size(manager->psaList);i++){
-					pubsub_admin_service_pt psa = (pubsub_admin_service_pt)arrayList_get(manager->psaList,i);
-					psa->closeAllPublications(psa->admin,p->scope, p->topic);
-				}
-			}
-
-			pubsubEndpoint_destroy(p);
-		}
-
-
-	}
-	free(pub_key);
-	celixThreadMutex_unlock(&manager->publicationsLock);
-	celixThreadMutex_unlock(&manager->psaListLock);
-
-
-	return status;
-}
-


[8/8] celix git commit: CELIX-417: Refactors cmake usage of pubsub and rsa. Started with installing exported targets

Posted by pn...@apache.org.
CELIX-417: Refactors cmake usage of pubsub and rsa. Started with installing exported targets


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

Branch: refs/heads/feature/CELIX-417-cmake-refactor
Commit: 81804e001001de1cd7ffd86d671ef53b8e74a429
Parents: ac0d0d7
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Wed Jan 24 19:30:21 2018 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Wed Jan 24 19:30:21 2018 +0100

----------------------------------------------------------------------
 CMakeLists.txt                                  |    4 +
 framework/CMakeLists.txt                        |   18 +-
 log_service/CMakeLists.txt                      |   15 +-
 pubsub/CMakeLists.txt                           |   38 +-
 pubsub/api/pubsub/publisher.h                   |   88 --
 pubsub/api/pubsub/subscriber.h                  |   75 --
 pubsub/deploy/CMakeLists.txt                    |  229 ----
 pubsub/examples/CMakeLists.txt                  |  213 ++++
 .../examples/mp_pubsub/publisher/CMakeLists.txt |   11 +-
 .../private/include/mp_publisher_private.h      |    2 +-
 .../publisher/private/src/mp_pub_activator.c    |   48 +-
 .../publisher/private/src/mp_publisher.c        |    1 -
 .../mp_pubsub/subscriber/CMakeLists.txt         |   17 +-
 .../private/include/mp_subscriber_private.h     |    3 +-
 .../subscriber/private/src/mp_sub_activator.c   |   40 +-
 pubsub/examples/pubsub/publisher/CMakeLists.txt |   21 +-
 .../private/include/pubsub_publisher_private.h  |    2 +-
 .../publisher/private/src/ps_pub_activator.c    |   54 +-
 .../publisher/private/src/pubsub_publisher.c    |    1 -
 .../examples/pubsub/publisher2/CMakeLists.txt   |   23 +-
 .../examples/pubsub/subscriber/CMakeLists.txt   |   27 +-
 .../private/include/pubsub_subscriber_private.h |    3 +-
 .../subscriber/private/src/ps_sub_activator.c   |   38 +-
 pubsub/mock/CMakeLists.txt                      |   20 +-
 pubsub/pubsub_admin_udp_mc/CMakeLists.txt       |   15 +-
 .../pubsub_admin_udp_mc/src/pubsub_admin_impl.c |    2 +-
 .../pubsub_admin_udp_mc/src/topic_publication.c |    2 +-
 .../pubsub_admin_udp_mc/src/topic_publication.h |    2 +-
 .../src/topic_subscription.c                    |    4 +-
 pubsub/pubsub_admin_zmq/CMakeLists.txt          |   48 +-
 .../private/include/pubsub_admin_impl.h         |  109 --
 .../private/include/topic_publication.h         |   49 -
 .../private/include/topic_subscription.h        |   60 -
 .../private/include/zmq_crypto.h                |   41 -
 .../private/src/psa_activator.c                 |  142 ---
 .../private/src/pubsub_admin_impl.c             | 1040 ------------------
 .../private/src/topic_publication.c             |  630 -----------
 .../private/src/topic_subscription.c            |  732 ------------
 .../pubsub_admin_zmq/private/src/zmq_crypto.c   |  281 -----
 pubsub/pubsub_admin_zmq/src/psa_activator.c     |  142 +++
 pubsub/pubsub_admin_zmq/src/pubsub_admin_impl.c | 1040 ++++++++++++++++++
 pubsub/pubsub_admin_zmq/src/pubsub_admin_impl.h |  109 ++
 pubsub/pubsub_admin_zmq/src/topic_publication.c |  630 +++++++++++
 pubsub/pubsub_admin_zmq/src/topic_publication.h |   49 +
 .../pubsub_admin_zmq/src/topic_subscription.c   |  732 ++++++++++++
 .../pubsub_admin_zmq/src/topic_subscription.h   |   60 +
 pubsub/pubsub_admin_zmq/src/zmq_crypto.c        |  281 +++++
 pubsub/pubsub_admin_zmq/src/zmq_crypto.h        |   41 +
 pubsub/pubsub_api/CMakeLists.txt                |   32 +
 pubsub/pubsub_api/include/pubsub/publisher.h    |   88 ++
 pubsub/pubsub_api/include/pubsub/subscriber.h   |   75 ++
 .../include/publisher_endpoint_announce.h       |   36 -
 .../pubsub_common/public/include/pubsub_admin.h |   72 --
 .../public/include/pubsub_admin_match.h         |   40 -
 .../public/include/pubsub_common.h              |   52 -
 .../public/include/pubsub_endpoint.h            |   58 -
 .../public/include/pubsub_serializer.h          |   66 --
 .../public/include/pubsub_topic_info.descriptor |   10 -
 .../pubsub_common/public/include/pubsub_utils.h |   39 -
 .../public/src/pubsub_admin_match.c             |  320 ------
 .../pubsub_common/public/src/pubsub_endpoint.c  |  254 -----
 pubsub/pubsub_common/public/src/pubsub_utils.c  |  170 ---
 pubsub/pubsub_discovery/CMakeLists.txt          |   15 +-
 pubsub/pubsub_serializer_json/CMakeLists.txt    |   13 +-
 pubsub/pubsub_spi/CMakeLists.txt                |   35 +
 .../include/publisher_endpoint_announce.h       |   36 +
 pubsub/pubsub_spi/include/pubsub_admin.h        |   72 ++
 pubsub/pubsub_spi/include/pubsub_admin_match.h  |   40 +
 pubsub/pubsub_spi/include/pubsub_common.h       |   52 +
 pubsub/pubsub_spi/include/pubsub_endpoint.h     |   58 +
 pubsub/pubsub_spi/include/pubsub_serializer.h   |   66 ++
 .../include/pubsub_topic_info.descriptor        |   10 +
 pubsub/pubsub_spi/include/pubsub_utils.h        |   39 +
 pubsub/pubsub_spi/src/pubsub_admin_match.c      |  320 ++++++
 pubsub/pubsub_spi/src/pubsub_endpoint.c         |  254 +++++
 pubsub/pubsub_spi/src/pubsub_utils.c            |  170 +++
 pubsub/pubsub_topology_manager/CMakeLists.txt   |   19 +-
 .../private/include/pubsub_topology_manager.h   |   83 --
 .../private/src/pstm_activator.c                |  246 -----
 .../private/src/pubsub_topology_manager.c       |  723 ------------
 .../src/pstm_activator.c                        |  244 ++++
 .../src/pubsub_topology_manager.c               |  721 ++++++++++++
 .../src/pubsub_topology_manager.h               |   82 ++
 pubsub/test/CMakeLists.txt                      |   10 +-
 remote_services/CMakeLists.txt                  |   11 +-
 remote_services/discovery_common/CMakeLists.txt |    2 +-
 .../examples/calculator_service/CMakeLists.txt  |    2 +-
 .../remote_service_admin_api/CMakeLists.txt     |   45 -
 .../remote_service_admin_api/README.md          |   11 -
 .../include/endpoint_description.h              |   50 -
 .../include/endpoint_listener.h                 |   49 -
 .../include/export_registration.h               |   22 -
 .../include/import_registration.h               |   22 -
 .../include/remote_constants.h                  |   38 -
 .../include/remote_endpoint.h                   |   44 -
 .../include/remote_endpoint_impl.h              |   38 -
 .../include/remote_proxy.h                      |   76 --
 .../include/remote_service_admin.h              |   73 --
 .../remote_service_admin_common/CMakeLists.txt  |   27 -
 .../src/endpoint_description.c                  |   89 --
 .../src/export_registration_impl.c              |  257 -----
 .../src/export_registration_impl.h              |   61 -
 .../src/import_registration_impl.c              |  274 -----
 .../src/import_registration_impl.h              |   81 --
 .../src/remote_proxy_factory_impl.c             |  252 -----
 .../src/remote_service_admin_impl.h             |   49 -
 .../remote_services_api/CMakeLists.txt          |   28 +
 remote_services/remote_services_api/README.md   |   11 +
 .../include/remote_constants.h                  |   31 +
 remote_services/rsa_common/CMakeLists.txt       |   29 +
 .../rsa_common/src/endpoint_description.c       |   89 ++
 .../rsa_common/src/export_registration_impl.c   |  257 +++++
 .../rsa_common/src/export_registration_impl.h   |   61 +
 .../rsa_common/src/import_registration_impl.c   |  274 +++++
 .../rsa_common/src/import_registration_impl.h   |   81 ++
 .../rsa_common/src/remote_proxy_factory_impl.c  |  252 +++++
 .../rsa_common/src/remote_service_admin_impl.h  |   49 +
 remote_services/rsa_spi/CMakeLists.txt          |   29 +
 remote_services/rsa_spi/README.md               |   11 +
 .../rsa_spi/include/endpoint_description.h      |   50 +
 .../rsa_spi/include/endpoint_listener.h         |   49 +
 .../rsa_spi/include/export_registration.h       |   22 +
 .../rsa_spi/include/import_registration.h       |   22 +
 .../rsa_spi/include/remote_constants.h          |   38 +
 .../rsa_spi/include/remote_endpoint.h           |   44 +
 .../rsa_spi/include/remote_endpoint_impl.h      |   38 +
 remote_services/rsa_spi/include/remote_proxy.h  |   76 ++
 .../rsa_spi/include/remote_service_admin.h      |   73 ++
 remote_services/topology_manager/CMakeLists.txt |    2 +-
 .../tms_tst/bundle/CMakeLists.txt               |    2 +-
 utils/CMakeLists.txt                            |   13 +-
 131 files changed, 7540 insertions(+), 7516 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d05ec8a..aa26d8e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -95,5 +95,9 @@ add_subdirectory(pubsub)
 add_subdirectory(dependency_manager)
 add_subdirectory(dependency_manager_cxx)
 
+
+#export targets
+install(EXPORT celix NAMESPACE Celix:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/celix)
+
 #Example as last, because some example will check if underlining options are enabled
 add_subdirectory(examples)

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/framework/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt
index a92910c..1716a7d 100644
--- a/framework/CMakeLists.txt
+++ b/framework/CMakeLists.txt
@@ -36,7 +36,10 @@ set(SOURCES
 )
 add_library(framework SHARED ${SOURCES})
 set_target_properties(framework PROPERTIES OUTPUT_NAME "celix_framework")
-target_include_directories(framework PUBLIC include)
+target_include_directories(framework PUBLIC
+        $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
+        $<INSTALL_INTERFACE:include/celix>
+)
 target_include_directories(framework PRIVATE
         src
         ${ZLIB_INCLUDE_DIR}
@@ -45,7 +48,6 @@ target_include_directories(framework PRIVATE
 )
 target_compile_definitions(framework PRIVATE -DUSE_FILE32API)
 
-include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
 set_target_properties(framework PROPERTIES "SOVERSION" 2)
 
 if(NOT APPLE)
@@ -54,16 +56,16 @@ endif()
 target_link_libraries(framework PUBLIC Celix::utils)
 target_link_libraries(framework PRIVATE ${UUID} ${ZLIB_LIBRARY} ${CURL_LIBRARIES})
 
-install(TARGETS framework DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT framework)
+install(TARGETS framework EXPORT celix DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT framework)
+install(DIRECTORY include/ DESTINATION include/celix COMPONENT framework)
+install(DIRECTORY "${PROJECT_SOURCE_DIR}/cmake/" DESTINATION share/celix/cmake/modules COMPONENT framework
+    PATTERN "CMakeCelix-local.cmake" EXCLUDE
+)
+
 
 #Alias setup to match external usage
 add_library(Celix::framework ALIAS framework)
 
-install(DIRECTORY "${PROJECT_SOURCE_DIR}/cmake/" DESTINATION share/celix/cmake/modules
-        COMPONENT framework
-        PATTERN "CMakeCelix-local.cmake" EXCLUDE
-)
-
 
 if (ENABLE_TESTING)
     find_package(CppUTest REQUIRED)

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/log_service/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/log_service/CMakeLists.txt b/log_service/CMakeLists.txt
index b9af374..70afb0e 100644
--- a/log_service/CMakeLists.txt
+++ b/log_service/CMakeLists.txt
@@ -19,12 +19,21 @@ celix_subproject(LOG_SERVICE "Option to enable building the Log Service bundles"
 if (LOG_SERVICE)
 
 	add_library(log_service_api INTERFACE)
-	target_include_directories(log_service_api INTERFACE include)
+	target_include_directories(log_service_api INTERFACE
+			$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
+			$<INSTALL_INTERFACE:include/celix/log_service>
+	)
+	install(TARGETS log_service_api EXPORT celix)
+	install(DIRECTORY include/ DESTINATION include/celix/log_service)
 
 	add_library(log_helper STATIC src/log_helper.c)
-	target_include_directories(log_helper PUBLIC loghelper_include)
+	target_include_directories(log_helper PUBLIC
+			$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/loghelper_include>
+			$<INSTALL_INTERFACE:include/celix/log_helper>
+	)
 	target_link_libraries(log_helper PUBLIC Celix::framework log_service_api)
-	#TODO install log helper
+	install(TARGETS log_helper EXPORT celix DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT log_service)
+	install(DIRECTORY loghelper_include/ DESTINATION include/celix/log_helper COMPONENT log_service)
 
     add_bundle(log_service
     	SYMBOLIC_NAME "apache_celix_log_service"

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/CMakeLists.txt b/pubsub/CMakeLists.txt
index 9d18175..79f8168 100644
--- a/pubsub/CMakeLists.txt
+++ b/pubsub/CMakeLists.txt
@@ -23,52 +23,24 @@ if (PUBSUB)
 		message(WARNING "Celix will now contain a dependency with a LGPL License (ZeroMQ). For more information about this, consult the pubsub/README.md file.")
 		option(BUILD_ZMQ_SECURITY "Build with security for ZeroMQ." OFF)
     endif (BUILD_PUBSUB_PSA_ZMQ)
-	
+
+	add_subdirectory(pubsub_api)
+	add_subdirectory(pubsub_spi)
 	add_subdirectory(pubsub_topology_manager)
 	add_subdirectory(pubsub_discovery)
 	add_subdirectory(pubsub_serializer_json)
 	add_subdirectory(pubsub_admin_zmq)
 	add_subdirectory(pubsub_admin_udp_mc)
-	add_subdirectory(examples)
-	add_subdirectory(deploy)
 	add_subdirectory(keygen)
 	add_subdirectory(mock)
 
+	add_subdirectory(examples)
 
 	if (ENABLE_TESTING)
-        option(BUILD_PUBSUB_TESTS "Enable Tests for PUBSUB" OFF)
+		option(BUILD_PUBSUB_TESTS "Enable Tests for PUBSUB" OFF)
 	endif()
 	if (ENABLE_TESTING AND BUILD_PUBSUB_TESTS)
 		add_subdirectory(test)
 	endif()
 
-	#api target
-	add_library(pubsub_api INTERFACE)
-	target_include_directories(pubsub_api INTERFACE api)
-
-	#install api
-	install(FILES api/pubsub/publisher.h api/pubsub/subscriber.h DESTINATION include/celix/pubsub COMPONENT framework)
-   
-   #install public common files
-   install(FILES
-      pubsub_common/public/include/pubsub_serializer.h
-      pubsub_common/public/include/pubsub_utils.h
-      pubsub_common/public/include/pubsub_common.h
-      pubsub_common/public/include/pubsub_endpoint.h
-      pubsub_common/public/include/pubsub_admin_match.h
-      pubsub_common/public/include/publisher_endpoint_announce.h
-      pubsub_common/public/include/pubsub_admin.h
-      DESTINATION include/celix/pubsub
-      COMPONENT framework
-   )
-   install(FILES
-      pubsub_common/public/src/pubsub_admin_match.c
-      pubsub_common/public/src/pubsub_utils.c
-      pubsub_common/public/src/pubsub_endpoint.c
-      DESTINATION share/celix/pubsub 
-      COMPONENT framework
-   )
-
-	#Setup target aliases to match external usage
-	add_library(Celix::pubsub_api ALIAS pubsub_api)
 endif(PUBSUB)

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/api/pubsub/publisher.h
----------------------------------------------------------------------
diff --git a/pubsub/api/pubsub/publisher.h b/pubsub/api/pubsub/publisher.h
deleted file mode 100644
index 3eec149..0000000
--- a/pubsub/api/pubsub/publisher.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- *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.
- */
-/*
- * publisher.h
- *
- *  \date       Jan 7, 2016
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef __PUBSUB_PUBLISHER_H_
-#define __PUBSUB_PUBLISHER_H_
-
-#include <stdlib.h>
-
-#define PUBSUB_PUBLISHER_SERVICE_NAME           "pubsub.publisher"
-#define PUBSUB_PUBLISHER_SERVICE_VERSION	      "2.0.0"
- 
-//properties
-#define PUBSUB_PUBLISHER_TOPIC                  "pubsub.topic"
-#define PUBSUB_PUBLISHER_SCOPE                  "pubsub.scope"
-#define PUBSUB_PUBLISHER_STRATEGY               "pubsub.strategy"
-#define PUBSUB_PUBLISHER_CONFIG                 "pubsub.config"
- 
-#define PUBSUB_PUBLISHER_SCOPE_DEFAULT			"default"
-//flags
-#define PUBSUB_PUBLISHER_FIRST_MSG  01
-#define PUBSUB_PUBLISHER_PART_MSG   02
-#define PUBSUB_PUBLISHER_LAST_MSG   04
-
-struct pubsub_release_callback_struct {
-    void *handle;
-    void (*release)(char *buf, void *handle);
-};
-typedef struct pubsub_release_callback_struct pubsub_release_callback_t;
-typedef struct pubsub_release_callback_struct* pubsub_release_callback_pt;
- 
- 
-struct pubsub_publisher {
-    void *handle;
- 
-    /**
-     * Every msg is identifiable by msg type string. Because masg type string are performance wise not preferable (string compares),
-     * a "local" (int / platform dependent) unique id will be generated runtime
-     * with use of a distributed key/value store or communication between  participation parties.
-     * this is called the local message type id. This local message type id can be requested with the localMsgIdForMsgType method.
-     * When return is successful the msgTypeId is always greater than 0. (Note this can be used to specify/detect uninitialized msg type ids in the consumer code).
-     *
-     * Returns 0 on success.
-     */
-    int (*localMsgTypeIdForMsgType)(void *handle, const char *msgType, unsigned int *msgTypeId);
-  
-    /**
-     * send is a async function, but the msg can be safely deleted after send returns.
-     * Returns 0 on success.
-     */
-    int (*send)(void *handle, unsigned int msgTypeId, const void *msg);
- 
-  
-    /**
-     * sendMultipart is a async function, but the msg can be safely deleted after send returns.
-     * The first (primary) message of a multipart message must have the flag PUBLISHER_PRIMARY_MSG
-     * The last message of a multipart message must have the flag PUBLISHER_LAST_MSG
-     * Returns 0 on success.
-     */
-    int (*sendMultipart)(void *handle, unsigned int msgTypeId, const void *msg, int flags);
- 
-};
-typedef struct pubsub_publisher pubsub_publisher_t;
-typedef struct pubsub_publisher* pubsub_publisher_pt;
-
-#endif // __PUBSUB_PUBLISHER_H_

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/api/pubsub/subscriber.h
----------------------------------------------------------------------
diff --git a/pubsub/api/pubsub/subscriber.h b/pubsub/api/pubsub/subscriber.h
deleted file mode 100644
index 5d87b8a..0000000
--- a/pubsub/api/pubsub/subscriber.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- *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.
- */
-/*
- * subscriber.h
- *
- *  \date       Jan 7, 2016
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef __PUBSUB_SUBSCRIBER_H_
-#define __PUBSUB_SUBSCRIBER_H_
-
-#include <stdbool.h>
-
-#define PUBSUB_SUBSCRIBER_SERVICE_NAME          "pubsub.subscriber"
-#define PUBSUB_SUBSCRIBER_SERVICE_VERSION       "2.0.0"
- 
-//properties
-#define PUBSUB_SUBSCRIBER_TOPIC                "pubsub.topic"
-#define PUBSUB_SUBSCRIBER_SCOPE                "pubsub.scope"
-#define PUBSUB_SUBSCRIBER_STRATEGY             "pubsub.strategy"
-#define PUBSUB_SUBSCRIBER_CONFIG               "pubsub.config"
-
-#define PUBSUB_SUBSCRIBER_SCOPE_DEFAULT        "default"
- 
-struct pubsub_multipart_callbacks_struct {
-    void *handle;
-    int (*localMsgTypeIdForMsgType)(void *handle, const char *msgType, unsigned int *msgId);
-    int (*getMultipart)(void *handle, unsigned int msgTypeId, bool retain, void **part);
-};
-typedef struct pubsub_multipart_callbacks_struct pubsub_multipart_callbacks_t;
-typedef struct pubsub_multipart_callbacks_struct* pubsub_multipart_callbacks_pt;
- 
-struct pubsub_subscriber_struct {
-    void *handle;
-     
-    /**
-     * When a new message for a topic is available the receive will be called.
-     * 
-     * msgType contains fully qualified name of the type and msgTypeId is a local id which presents the type for performance reasons.
-     * Release can be used to instruct the pubsubadmin to release (free) the message when receive function returns. Set it to false to take
-     * over ownership of the msg (e.g. take the responsibility to free it).
-     *
-     * The callbacks argument is only valid inside the receive function, use the getMultipart callback, with retain=true, to keep multipart messages in memory.
-     * results of the localMsgTypeIdForMsgType callback are valid during the complete lifecycle of the component, not just a single receive call.
-     *
-     * Return 0 implies a successful handling. If return is not 0, the msg will always be released by the pubsubadmin.
-     *
-     * this method can be  NULL.
-     */
-    int (*receive)(void *handle, const char *msgType, unsigned int msgTypeId, void *msg, pubsub_multipart_callbacks_t *callbacks, bool *release);
-
-};
-typedef struct pubsub_subscriber_struct pubsub_subscriber_t;
-typedef struct pubsub_subscriber_struct* pubsub_subscriber_pt;
-
-
-#endif //  __PUBSUB_SUBSCRIBER_H_

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/deploy/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/deploy/CMakeLists.txt b/pubsub/deploy/CMakeLists.txt
deleted file mode 100644
index e76f91b..0000000
--- a/pubsub/deploy/CMakeLists.txt
+++ /dev/null
@@ -1,229 +0,0 @@
-# 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.
-
-find_program(ETCD_CMD NAMES etcd)
-find_program(XTERM_CMD NAMES xterm)
-
-# UDP Multicast
-add_deploy(pubsub_publisher_udp_mc
-	GROUP pubsub
-	BUNDLES
-		Celix::shell
-	   	Celix::shell_tui
-	   	org.apache.celix.pubsub_serializer.PubSubSerializerJson
-	   	org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
-	   	org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
-	   	org.apache.celix.pubsub_admin.PubSubAdminUdpMc
-	   	org.apache.celix.pubsub_publisher.PoiPublisher
-	   	org.apache.celix.pubsub_publisher.PoiPublisher2
-)
-
-add_deploy("pubsub_subscriber_udp_mc"
-	GROUP "pubsub"
-	BUNDLES
-		Celix::shell
-		Celix::shell_tui
-	   	org.apache.celix.pubsub_serializer.PubSubSerializerJson
-	  	org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
-	   	org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
-	   	org.apache.celix.pubsub_admin.PubSubAdminUdpMc
-	   	org.apache.celix.pubsub_subscriber.PoiSubscriber
-)
-
-add_deploy("pubsub_subscriber2_udp_mc"
-	GROUP "pubsub"
-	BUNDLES
-		Celix::shell
-		Celix::shell_tui
-	   	org.apache.celix.pubsub_serializer.PubSubSerializerJson
-	   	org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
-	   	org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
-	   	org.apache.celix.pubsub_admin.PubSubAdminUdpMc
-	   	org.apache.celix.pubsub_subscriber.PoiSubscriber
-)
-
-if (ETCD_CMD AND XTERM_CMD)
-	#Runtime starting a publish and subscriber for udp mc
-	add_runtime(pubsub_rt_upd_mc
-		NAME udp_mc
-		GROUP pubsub
-		DEPLOYMENTS
-			pubsub_publisher_udp_mc
-			pubsub_subscriber_udp_mc
-			pubsub_subscriber2_udp_mc
-		COMMANDS
-			etcd
-		USE_TERM
-	)
-endif ()
-
-if (BUILD_PUBSUB_PSA_ZMQ)
-
-	# Dynamic ZMQ / UDP admin
-	add_deploy("pubsub_publisher"
-	    GROUP "pubsub"
-	    BUNDLES
-			Celix::shell
-			Celix::shell_tui
-	      	org.apache.celix.pubsub_serializer.PubSubSerializerJson
-	       	org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
-	       	org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
-	       	org.apache.celix.pubsub_admin.PubSubAdminZmq
-	       	org.apache.celix.pubsub_admin.PubSubAdminUdpMc
-	       	org.apache.celix.pubsub_publisher.PoiPublisher
-	       	org.apache.celix.pubsub_publisher.PoiPublisher2
-	    PROPERTIES
-	       	poi1.psa=zmq
-	       	poi2.psa=udp
-	)
-
-	add_deploy("pubsub_subscriber"
-	    GROUP "pubsub"
-	    BUNDLES
-			Celix::shell
-			Celix::shell_tui
-	       	org.apache.celix.pubsub_serializer.PubSubSerializerJson
-	       	org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
-	       	org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
-	       	org.apache.celix.pubsub_admin.PubSubAdminZmq
-	       	org.apache.celix.pubsub_admin.PubSubAdminUdpMc
-	       	org.apache.celix.pubsub_subscriber.PoiSubscriber
-	    PROPERTIES
-	       	poi1.psa=zmq
-	       	poi2.psa=udp
-	)
-
-	# ZMQ
-	add_deploy("pubsub_zmq"
-	    GROUP "pubsub"
-	    BUNDLES
-			Celix::shell
-			Celix::shell_tui
-	       	org.apache.celix.pubsub_serializer.PubSubSerializerJson
-	       	org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
-	       	org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
-	       	org.apache.celix.pubsub_admin.PubSubAdminZmq
-	       	org.apache.celix.pubsub_publisher.PoiPublisher
-	       	org.apache.celix.pubsub_subscriber.PoiSubscriber
-	)
-
-	add_deploy("pubsub_publisher_zmq"
-	    GROUP "pubsub"
-	    BUNDLES
-			Celix::shell
-			Celix::shell_tui
-	       	org.apache.celix.pubsub_serializer.PubSubSerializerJson
-	       	org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
-	       	org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
-	       	org.apache.celix.pubsub_admin.PubSubAdminZmq
-	       	org.apache.celix.pubsub_publisher.PoiPublisher
-	       	org.apache.celix.pubsub_publisher.PoiPublisher2
-	   	PROPERTIES
-		    pubsub.scope=my_small_scope
-	)
-
-	add_deploy("pubsub_subscriber_zmq"
-	    GROUP "pubsub"
-	    BUNDLES
-			Celix::shell
-			Celix::shell_tui
-	       	org.apache.celix.pubsub_serializer.PubSubSerializerJson
-	       	org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
-	       	org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
-	       	org.apache.celix.pubsub_admin.PubSubAdminZmq
-	       	org.apache.celix.pubsub_subscriber.PoiSubscriber
-	)
-
-	add_deploy("pubsub_subscriber2_zmq"
-	    GROUP "pubsub"
-	    BUNDLES
-			Celix::shell
-			Celix::shell_tui
-	       	org.apache.celix.pubsub_serializer.PubSubSerializerJson
-	       	org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
-	       	org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
-	       	org.apache.celix.pubsub_admin.PubSubAdminZmq
-	       	org.apache.celix.pubsub_subscriber.PoiSubscriber
-
-	)
-
-	# ZMQ Multipart
-	add_deploy("pubsub_mp_subscriber_zmq"
-	    GROUP "pubsub"
-	    BUNDLES
-			Celix::shell
-			Celix::shell_tui
-	       	org.apache.celix.pubsub_serializer.PubSubSerializerJson
-	       	org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
-	       	org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
-	       	org.apache.celix.pubsub_admin.PubSubAdminZmq
-	       	org.apache.celix.pubsub_subscriber.MpSubscriber
-	)
-
-	add_deploy("pubsub_mp_publisher_zmq"
-	    GROUP "pubsub"
-	    BUNDLES
-			Celix::shell
-			Celix::shell_tui
-	   		org.apache.celix.pubsub_serializer.PubSubSerializerJson
-	   		org.apache.celix.pubsub_discovery.etcd.PubsubDiscovery
-	   		org.apache.celix.pubsub_topology_manager.PubSubTopologyManager
-	   		org.apache.celix.pubsub_admin.PubSubAdminZmq
-	   		org.apache.celix.pubsub_publisher.MpPublisher
-	)
-
-	if (ETCD_CMD AND XTERM_CMD)
-		#Runtime starting two bundles using both zmq and upd mc pubsub
-		add_runtime(pubsub_rt_zmq_udpmc_combi
-			NAME combi
-			GROUP pubsub
-			DEPLOYMENTS
-				pubsub_publisher_zmq
-				pubsub_subscriber_zmq
-				pubsub_subscriber_zmq
-			COMMANDS
-				etcd
-			USE_TERM
-		)
-
-		#Runtime starting a publish and 2 subscribers for zmq
-		add_runtime(pubsub_rt_zmq
-			NAME zmq
-			GROUP pubsub
-			DEPLOYMENTS
-				pubsub_publisher
-				pubsub_subscriber_zmq
-				pubsub_subscriber2_zmq
-			COMMANDS
-				etcd
-			USE_TERM
-		)
-
-		#Runtime starting a multipart (multiple message in one send) publish and subscriber for zmq
-		add_runtime(pubsub_rt_multipart_zmq
-			NAME zmq_multipart
-			GROUP pubsub
-			DEPLOYMENTS
-				pubsub_mp_subscriber_zmq
-				pubsub_mp_publisher_zmq
-			COMMANDS
-				etcd
-			USE_TERM
-		)
-	endif ()
-
-endif()

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/examples/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/examples/CMakeLists.txt b/pubsub/examples/CMakeLists.txt
index 22ca5ca..b79b101 100644
--- a/pubsub/examples/CMakeLists.txt
+++ b/pubsub/examples/CMakeLists.txt
@@ -17,3 +17,216 @@
 
 add_subdirectory(pubsub)
 add_subdirectory(mp_pubsub)
+
+find_program(ETCD_CMD NAMES etcd)
+find_program(XTERM_CMD NAMES xterm)
+
+# UDP Multicast
+add_deploy(pubsub_publisher_udp_mc
+        GROUP pubsub
+        BUNDLES
+        Celix::shell
+        Celix::shell_tui
+        Celix::pubsub_serializer_json
+        Celix::pubsub_discovery_etcd
+        Celix::pubsub_topology_manager
+        Celix::pubsub_admin_udp_multicast
+        celix_pubsub_poi_publisher
+        celix_pubsub_poi_publisher2
+        )
+
+add_deploy("pubsub_subscriber_udp_mc"
+        GROUP "pubsub"
+        BUNDLES
+        Celix::shell
+        Celix::shell_tui
+        Celix::pubsub_serializer_json
+        Celix::pubsub_discovery_etcd
+        Celix::pubsub_topology_manager
+        Celix::pubsub_admin_udp_multicast
+        celix_pubsub_poi_subscriber
+        )
+
+add_deploy("pubsub_subscriber2_udp_mc"
+        GROUP "pubsub"
+        BUNDLES
+        Celix::shell
+        Celix::shell_tui
+        Celix::pubsub_serializer_json
+        Celix::pubsub_discovery_etcd
+        Celix::pubsub_topology_manager
+        Celix::pubsub_admin_udp_multicast
+        celix_pubsub_poi_subscriber
+        )
+
+if (ETCD_CMD AND XTERM_CMD)
+    #Runtime starting a publish and subscriber for udp mc
+    add_runtime(pubsub_rt_upd_mc
+            NAME udp_mc
+            GROUP pubsub
+            DEPLOYMENTS
+            pubsub_publisher_udp_mc
+            pubsub_subscriber_udp_mc
+            pubsub_subscriber2_udp_mc
+            COMMANDS
+            etcd
+            USE_TERM
+            )
+endif ()
+
+if (BUILD_PUBSUB_PSA_ZMQ)
+
+    # Dynamic ZMQ / UDP admin
+    add_deploy("pubsub_publisher"
+            GROUP "pubsub"
+            BUNDLES
+            Celix::shell
+            Celix::shell_tui
+            Celix::pubsub_serializer_json
+            Celix::pubsub_discovery_etcd
+            Celix::pubsub_topology_manager
+            Celix::pubsub_admin_zmq
+            Celix::pubsub_admin_udp_multicast
+            celix_pubsub_poi_publisher
+            celix_pubsub_poi_publisher2
+            PROPERTIES
+            poi1.psa=zmq
+            poi2.psa=udp
+            )
+
+    add_deploy("pubsub_subscriber"
+            GROUP "pubsub"
+            BUNDLES
+            Celix::shell
+            Celix::shell_tui
+            Celix::pubsub_serializer_json
+            Celix::pubsub_discovery_etcd
+            Celix::pubsub_topology_manager
+            Celix::pubsub_admin_zmq
+            Celix::pubsub_admin_udp_multicast
+            celix_pubsub_poi_subscriber
+            PROPERTIES
+            poi1.psa=zmq
+            poi2.psa=udp
+            )
+
+    # ZMQ
+    add_deploy("pubsub_zmq"
+            GROUP "pubsub"
+            BUNDLES
+            Celix::shell
+            Celix::shell_tui
+            Celix::pubsub_serializer_json
+            Celix::pubsub_discovery_etcd
+            Celix::pubsub_topology_manager
+            org.apache.celix.pubsub_admin.PubSubAdminZmq
+            celix_pubsub_poi_publisher
+            celix_pubsub_poi_subscriber
+            )
+
+    add_deploy("pubsub_publisher_zmq"
+            GROUP "pubsub"
+            BUNDLES
+            Celix::shell
+            Celix::shell_tui
+            Celix::pubsub_serializer_json
+            Celix::pubsub_discovery_etcd
+            Celix::pubsub_topology_manager
+            Celix::pubsub_admin_zmq
+            celix_pubsub_poi_publisher
+            celix_pubsub_poi_publisher2
+            PROPERTIES
+            pubsub.scope=my_small_scope
+            )
+
+    add_deploy("pubsub_subscriber_zmq"
+            GROUP "pubsub"
+            BUNDLES
+            Celix::shell
+            Celix::shell_tui
+            Celix::pubsub_serializer_json
+            Celix::pubsub_discovery_etcd
+            Celix::pubsub_topology_manager
+            org.apache.celix.pubsub_admin.PubSubAdminZmq
+            celix_pubsub_poi_subscriber
+            )
+
+    add_deploy("pubsub_subscriber2_zmq"
+            GROUP "pubsub"
+            BUNDLES
+            Celix::shell
+            Celix::shell_tui
+            Celix::pubsub_serializer_json
+            Celix::pubsub_discovery_etcd
+            Celix::pubsub_topology_manager
+            Celix::pubsub_admin_zmq
+            celix_pubsub_poi_subscriber
+
+            )
+
+    # ZMQ Multipart
+    add_deploy("pubsub_mp_subscriber_zmq"
+            GROUP "pubsub"
+            BUNDLES
+            Celix::shell
+            Celix::shell_tui
+            Celix::pubsub_serializer_json
+            Celix::pubsub_discovery_etcd
+            Celix::pubsub_topology_manager
+            Celix::pubsub_admin_zmq
+            org.apache.celix.pubsub_subscriber.MpSubscriber
+            )
+
+    add_deploy("pubsub_mp_publisher_zmq"
+            GROUP "pubsub"
+            BUNDLES
+            Celix::shell
+            Celix::shell_tui
+            Celix::pubsub_serializer_json
+            Celix::pubsub_discovery_etcd
+            Celix::pubsub_topology_manager
+            Celix::pubsub_admin_zmq
+            org.apache.celix.pubsub_publisher.MpPublisher
+            )
+
+    if (ETCD_CMD AND XTERM_CMD)
+        #Runtime starting two bundles using both zmq and upd mc pubsub
+        add_runtime(pubsub_rt_zmq_udpmc_combi
+                NAME combi
+                GROUP pubsub
+                DEPLOYMENTS
+                pubsub_publisher_zmq
+                pubsub_subscriber_zmq
+                pubsub_subscriber_zmq
+                COMMANDS
+                etcd
+                USE_TERM
+                )
+
+        #Runtime starting a publish and 2 subscribers for zmq
+        add_runtime(pubsub_rt_zmq
+                NAME zmq
+                GROUP pubsub
+                DEPLOYMENTS
+                pubsub_publisher
+                pubsub_subscriber_zmq
+                pubsub_subscriber2_zmq
+                COMMANDS
+                etcd
+                USE_TERM
+                )
+
+        #Runtime starting a multipart (multiple message in one send) publish and subscriber for zmq
+        add_runtime(pubsub_rt_multipart_zmq
+                NAME zmq_multipart
+                GROUP pubsub
+                DEPLOYMENTS
+                pubsub_mp_subscriber_zmq
+                pubsub_mp_publisher_zmq
+                COMMANDS
+                etcd
+                USE_TERM
+                )
+    endif ()
+
+endif()

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt b/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt
index 1ef8645..e837d7f 100644
--- a/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt
+++ b/pubsub/examples/mp_pubsub/publisher/CMakeLists.txt
@@ -15,20 +15,15 @@
 # specific language governing permissions and limitations
 # under the License.
 
-include_directories("private/include")
-include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/api/pubsub")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/examples/mp_pubsub/common/include")
-
 add_bundle(org.apache.celix.pubsub_publisher.MpPublisher
     SYMBOLIC_NAME "apache_celix_pubsub_mp_publisher"
     VERSION "1.0.0"
     SOURCES 
     	private/src/mp_pub_activator.c
     	private/src/mp_publisher.c
-    	${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c
 )
+target_link_libraries(org.apache.celix.pubsub_publisher.MpPublisher PRIVATE Celix::framework Celix::pubsub_api)
+target_include_directories(org.apache.celix.pubsub_publisher.MpPublisher PRIVATE private/include)
 
 bundle_files(org.apache.celix.pubsub_publisher.MpPublisher
 	${PROJECT_SOURCE_DIR}/pubsub/examples/mp_pubsub/msg_descriptors/msg_ew.descriptor
@@ -46,5 +41,3 @@ bundle_files(org.apache.celix.pubsub_publisher.MpPublisher
 		${PROJECT_SOURCE_DIR}/pubsub/examples/keys/subscriber/public
     DESTINATION "META-INF/keys/subscriber"
 )
-
-target_link_libraries(org.apache.celix.pubsub_publisher.MpPublisher PRIVATE Celix::framework)

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/examples/mp_pubsub/publisher/private/include/mp_publisher_private.h
----------------------------------------------------------------------
diff --git a/pubsub/examples/mp_pubsub/publisher/private/include/mp_publisher_private.h b/pubsub/examples/mp_pubsub/publisher/private/include/mp_publisher_private.h
index a9c070f..9c227fd 100644
--- a/pubsub/examples/mp_pubsub/publisher/private/include/mp_publisher_private.h
+++ b/pubsub/examples/mp_pubsub/publisher/private/include/mp_publisher_private.h
@@ -29,7 +29,7 @@
 
 #include <celixbool.h>
 
-#include "publisher.h"
+#include "pubsub/publisher.h"
 
 struct pubsub_sender {
 	array_list_pt trackers;

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/examples/mp_pubsub/publisher/private/src/mp_pub_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/examples/mp_pubsub/publisher/private/src/mp_pub_activator.c b/pubsub/examples/mp_pubsub/publisher/private/src/mp_pub_activator.c
index 5c8b145..464d1ab 100644
--- a/pubsub/examples/mp_pubsub/publisher/private/src/mp_pub_activator.c
+++ b/pubsub/examples/mp_pubsub/publisher/private/src/mp_pub_activator.c
@@ -32,11 +32,13 @@
 #include "service_tracker.h"
 #include "constants.h"
 
-#include "pubsub_common.h"
-#include "pubsub_utils.h"
 #include "mp_publisher_private.h"
 
-#define PUB_TOPIC "multipart"
+static const char * PUB_TOPICS[] = {
+		"multipart",
+		NULL
+};
+
 
 struct publisherActivator {
 	pubsub_sender_pt client;
@@ -78,40 +80,28 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context)
 
 	int i;
 
-	array_list_pt topic_list = pubsub_getTopicsFromString(PUB_TOPIC);
-
-	if(topic_list !=NULL){
-
+	if(PUB_TOPICS != NULL) {
 		char filter[128];
+		for(i=0; PUB_TOPICS[i] != NULL; i++){
+			const char* topic = PUB_TOPICS[i];
 
-		for(i=0; i<arrayList_size(topic_list);i++){
-			char* topic = arrayList_get(topic_list,i);
-			if(strlen(topic)<MAX_TOPIC_LEN){
-
-				bundle_pt bundle = NULL;
-				long bundleId = 0;
-				bundleContext_getBundle(context,&bundle);
-				bundle_getBundleId(bundle,&bundleId);
+			bundle_pt bundle = NULL;
+			long bundleId = 0;
+			bundleContext_getBundle(context,&bundle);
+			bundle_getBundleId(bundle,&bundleId);
 
-				service_tracker_pt tracker = NULL;
-				memset(filter,0,128);
+			service_tracker_pt tracker = NULL;
+			memset(filter,0,128);
 
-				snprintf(filter, 128, "(&(%s=%s)(%s=%s))", (char*) OSGI_FRAMEWORK_OBJECTCLASS, PUBSUB_PUBLISHER_SERVICE_NAME, PUBSUB_PUBLISHER_TOPIC,topic);
+			snprintf(filter, 128, "(&(%s=%s)(%s=%s))", (char*) OSGI_FRAMEWORK_OBJECTCLASS, PUBSUB_PUBLISHER_SERVICE_NAME, PUBSUB_PUBLISHER_TOPIC,topic);
 
-				service_tracker_customizer_pt customizer = NULL;
+			service_tracker_customizer_pt customizer = NULL;
 
-				serviceTrackerCustomizer_create(act->client,NULL,publisher_publishSvcAdded,NULL,publisher_publishSvcRemoved,&customizer);
-				serviceTracker_createWithFilter(context, filter, customizer, &tracker);
+			serviceTrackerCustomizer_create(act->client,NULL,publisher_publishSvcAdded,NULL,publisher_publishSvcRemoved,&customizer);
+			serviceTracker_createWithFilter(context, filter, customizer, &tracker);
 
-				arrayList_add(act->trackerList,tracker);
-			}
-			else{
-				printf("Topic %s too long. Skipping publication.\n",topic);
-			}
-			free(topic);
+			arrayList_add(act->trackerList,tracker);
 		}
-		arrayList_destroy(topic_list);
-
 	}
 
 	publisher_start(act->client);

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/examples/mp_pubsub/publisher/private/src/mp_publisher.c
----------------------------------------------------------------------
diff --git a/pubsub/examples/mp_pubsub/publisher/private/src/mp_publisher.c b/pubsub/examples/mp_pubsub/publisher/private/src/mp_publisher.c
index fa53487..f47be29 100644
--- a/pubsub/examples/mp_pubsub/publisher/private/src/mp_publisher.c
+++ b/pubsub/examples/mp_pubsub/publisher/private/src/mp_publisher.c
@@ -32,7 +32,6 @@
 #include "service_tracker.h"
 #include "celix_threads.h"
 
-#include "pubsub_common.h"
 #include "ew.h"
 #include "ide.h"
 #include "kinematics.h"

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt b/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt
index e281ab1..858efb5 100644
--- a/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt
+++ b/pubsub/examples/mp_pubsub/subscriber/CMakeLists.txt
@@ -15,20 +15,15 @@
 # specific language governing permissions and limitations
 # under the License.
 
-include_directories("private/include")
-include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/api/pubsub")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/examples/mp_pubsub/common/include")
-
-add_bundle( org.apache.celix.pubsub_subscriber.MpSubscriber
+add_bundle(org.apache.celix.pubsub_subscriber.MpSubscriber
     SYMBOLIC_NAME "apache_celix_pubsub_mp_subscriber"
     VERSION "1.0.0"
     SOURCES 
 		private/src/mp_sub_activator.c
 		private/src/mp_subscriber.c
-		${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c
 )
+target_link_libraries(org.apache.celix.pubsub_subscriber.MpSubscriber PRIVATE Celix::framework Celix::pubsub_api)
+target_include_directories(org.apache.celix.pubsub_subscriber.MpSubscriber PRIVATE private/include)
 
 bundle_files( org.apache.celix.pubsub_subscriber.MpSubscriber
     ${PROJECT_SOURCE_DIR}/pubsub/examples/mp_pubsub/msg_descriptors/msg_ew.descriptor
@@ -43,8 +38,6 @@ bundle_files(org.apache.celix.pubsub_subscriber.MpSubscriber
 )
 
 bundle_files(org.apache.celix.pubsub_subscriber.MpSubscriber
-		${PROJECT_SOURCE_DIR}/pubsub/examples/keys/publisher/public
+	${PROJECT_SOURCE_DIR}/pubsub/examples/keys/publisher/public
     DESTINATION "META-INF/keys/publisher"
-)
-
-target_link_libraries(org.apache.celix.pubsub_subscriber.MpSubscriber PRIVATE Celix::framework)
+)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/examples/mp_pubsub/subscriber/private/include/mp_subscriber_private.h
----------------------------------------------------------------------
diff --git a/pubsub/examples/mp_pubsub/subscriber/private/include/mp_subscriber_private.h b/pubsub/examples/mp_pubsub/subscriber/private/include/mp_subscriber_private.h
index 1cc7270..2d582b3 100644
--- a/pubsub/examples/mp_pubsub/subscriber/private/include/mp_subscriber_private.h
+++ b/pubsub/examples/mp_pubsub/subscriber/private/include/mp_subscriber_private.h
@@ -32,8 +32,7 @@
 
 #include "celixbool.h"
 
-#include "pubsub_common.h"
-#include "subscriber.h"
+#include "pubsub/subscriber.h"
 
 struct pubsub_receiver {
 	char * name;

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/examples/mp_pubsub/subscriber/private/src/mp_sub_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/examples/mp_pubsub/subscriber/private/src/mp_sub_activator.c b/pubsub/examples/mp_pubsub/subscriber/private/src/mp_sub_activator.c
index ecd4245..df9cb0f 100644
--- a/pubsub/examples/mp_pubsub/subscriber/private/src/mp_sub_activator.c
+++ b/pubsub/examples/mp_pubsub/subscriber/private/src/mp_sub_activator.c
@@ -26,17 +26,20 @@
 
 #include <stdlib.h>
 
+#include "pubsub/subscriber.h"
 #include "bundle_activator.h"
 
-#include "pubsub_common.h"
-#include "pubsub_utils.h"
 #include "mp_subscriber_private.h"
 
-#define SUB_TOPIC "multipart"
+#define SUB_NAME "multipart"
+static const char * SUB_TOPICS[] = {
+		"multipart",
+		NULL
+};
 
 struct subscriberActivator {
 	array_list_pt registrationList; //List<service_registration_pt>
-	pubsub_subscriber_pt subsvc;
+	pubsub_subscriber_t* subsvc;
 };
 
 celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
@@ -51,33 +54,24 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context)
 
 
 	pubsub_subscriber_pt subsvc = calloc(1,sizeof(*subsvc));
-	pubsub_receiver_pt sub = subscriber_create(SUB_TOPIC);
+	pubsub_receiver_pt sub = subscriber_create(SUB_NAME);
 	subsvc->handle = sub;
 	subsvc->receive = pubsub_subscriber_recv;
 
 	act->subsvc = subsvc;
 
-	array_list_pt topic_list = pubsub_getTopicsFromString(SUB_TOPIC);
-
-	if(topic_list !=NULL){
+	if (SUB_TOPICS !=NULL) {
 
 		int i;
-		for(i=0; i<arrayList_size(topic_list);i++){
-			char* topic = arrayList_get(topic_list,i);
-			if(strlen(topic)<MAX_TOPIC_LEN){
-				properties_pt props = properties_create();
-				properties_set(props, PUBSUB_SUBSCRIBER_TOPIC,topic);
-				service_registration_pt reg = NULL;
-				bundleContext_registerService(context, PUBSUB_SUBSCRIBER_SERVICE_NAME, subsvc, props, &reg);
-				arrayList_add(act->registrationList,reg);
-			}
-			else{
-				printf("Topic %s too long. Skipping subscription.\n",topic);
-			}
-			free(topic);
+		for(i=0; SUB_TOPICS[i] != NULL; i++){
+			const char* topic = SUB_TOPICS[i];
+
+			properties_pt props = properties_create();
+			properties_set(props, PUBSUB_SUBSCRIBER_TOPIC,topic);
+			service_registration_pt reg = NULL;
+			bundleContext_registerService(context, PUBSUB_SUBSCRIBER_SERVICE_NAME, subsvc, props, &reg);
+			arrayList_add(act->registrationList,reg);
 		}
-		arrayList_destroy(topic_list);
-
 	}
 
 	subscriber_start((pubsub_receiver_pt)act->subsvc->handle);

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/examples/pubsub/publisher/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/examples/pubsub/publisher/CMakeLists.txt b/pubsub/examples/pubsub/publisher/CMakeLists.txt
index fcf50c7..43eabd8 100644
--- a/pubsub/examples/pubsub/publisher/CMakeLists.txt
+++ b/pubsub/examples/pubsub/publisher/CMakeLists.txt
@@ -15,40 +15,35 @@
 # specific language governing permissions and limitations
 # under the License.
 
-include_directories("private/include")
-include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/api/pubsub")
-
-add_bundle(org.apache.celix.pubsub_publisher.PoiPublisher
+add_bundle(celix_pubsub_poi_publisher
     SYMBOLIC_NAME "apache_celix_pubsub_poi_publisher"
     VERSION "1.0.0"
     SOURCES 
     	private/src/ps_pub_activator.c
     	private/src/pubsub_publisher.c
-    	${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c	
 )
 
-bundle_files(org.apache.celix.pubsub_publisher.PoiPublisher
+target_link_libraries(celix_pubsub_poi_publisher PRIVATE Celix::framework Celix::pubsub_api)
+target_include_directories(celix_pubsub_poi_publisher PRIVATE private/include)
+
+bundle_files(celix_pubsub_poi_publisher
 		${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor
 		${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor
     DESTINATION "META-INF/descriptors"
 )
 
-bundle_files(org.apache.celix.pubsub_publisher.PoiPublisher
+bundle_files(celix_pubsub_poi_publisher
 		${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/poi1.properties
 		${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/poi2.properties
     DESTINATION "META-INF/topics/pub"
 )
 
-bundle_files(org.apache.celix.pubsub_publisher.PoiPublisher
+bundle_files(celix_pubsub_poi_publisher
 		${PROJECT_SOURCE_DIR}/pubsub/examples/keys/publisher
     DESTINATION "META-INF/keys"
 )
 
-bundle_files(org.apache.celix.pubsub_publisher.PoiPublisher
+bundle_files(celix_pubsub_poi_publisher
 		${PROJECT_SOURCE_DIR}/pubsub/examples/keys/subscriber/public
     DESTINATION "META-INF/keys/subscriber"
 )
-
-target_link_libraries(org.apache.celix.pubsub_publisher.PoiPublisher PRIVATE Celix::framework)

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/examples/pubsub/publisher/private/include/pubsub_publisher_private.h
----------------------------------------------------------------------
diff --git a/pubsub/examples/pubsub/publisher/private/include/pubsub_publisher_private.h b/pubsub/examples/pubsub/publisher/private/include/pubsub_publisher_private.h
index 834dada..56ec678 100644
--- a/pubsub/examples/pubsub/publisher/private/include/pubsub_publisher_private.h
+++ b/pubsub/examples/pubsub/publisher/private/include/pubsub_publisher_private.h
@@ -29,7 +29,7 @@
 
 #include <celixbool.h>
 #include <pthread.h>
-#include "publisher.h"
+#include "pubsub/publisher.h"
 
 struct pubsub_sender {
 	array_list_pt trackers;

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/examples/pubsub/publisher/private/src/ps_pub_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/examples/pubsub/publisher/private/src/ps_pub_activator.c b/pubsub/examples/pubsub/publisher/private/src/ps_pub_activator.c
index e6c7a3b..a1f2dc8 100644
--- a/pubsub/examples/pubsub/publisher/private/src/ps_pub_activator.c
+++ b/pubsub/examples/pubsub/publisher/private/src/ps_pub_activator.c
@@ -32,12 +32,15 @@
 #include "service_tracker.h"
 #include "constants.h"
 
-#include "pubsub_common.h"
-#include "pubsub_utils.h"
-#include "publisher.h"
+#include "pubsub/publisher.h"
 #include "pubsub_publisher_private.h"
 
-#define PUB_TOPIC "poi1;poi2"
+static const char * PUB_TOPICS[] = {
+		"poi1",
+		"poi2",
+		NULL
+};
+
 
 struct publisherActivator {
 	pubsub_sender_pt client;
@@ -73,22 +76,19 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context)
 	struct publisherActivator * act = (struct publisherActivator *) userData;
 
 	int i;
-	array_list_pt topic_list = pubsub_getTopicsFromString(PUB_TOPIC);
-
-	if(topic_list !=NULL){
+	if(PUB_TOPICS !=NULL){
 
 		char filter[128];
-		for(i=0; i<arrayList_size(topic_list);i++){
-			char* topic = arrayList_get(topic_list,i);
-			if(strlen(topic)<MAX_TOPIC_LEN){
+		for(i=0; PUB_TOPICS[i] != NULL; i++){
+			const char* topic = PUB_TOPICS[i];
 
-				bundle_pt bundle = NULL;
-				long bundleId = 0;
-				bundleContext_getBundle(context,&bundle);
-				bundle_getBundleId(bundle,&bundleId);
+			bundle_pt bundle = NULL;
+			long bundleId = 0;
+			bundleContext_getBundle(context,&bundle);
+			bundle_getBundleId(bundle,&bundleId);
 
-				service_tracker_pt tracker = NULL;
-				memset(filter,0,128);
+			service_tracker_pt tracker = NULL;
+			memset(filter,0,128);
 #ifdef USE_SCOPE
 				char *scope;
 				asprintf(&scope, "my_scope_%d", i);
@@ -98,23 +98,15 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context)
 						PUBLISHER_SCOPE, scope);
 				free(scope);
 #else
-				snprintf(filter, 128, "(&(%s=%s)(%s=%s))",
-				          (char*) OSGI_FRAMEWORK_OBJECTCLASS, PUBSUB_PUBLISHER_SERVICE_NAME,
-				                  PUBSUB_PUBLISHER_TOPIC, topic);
+			snprintf(filter, 128, "(&(%s=%s)(%s=%s))", (char*) OSGI_FRAMEWORK_OBJECTCLASS, PUBSUB_PUBLISHER_SERVICE_NAME, PUBSUB_PUBLISHER_TOPIC, topic);
 #endif
-				service_tracker_customizer_pt customizer = NULL;
-				serviceTrackerCustomizer_create(act->client,NULL,publisher_publishSvcAdded,NULL,publisher_publishSvcRemoved,&customizer);
-				serviceTracker_createWithFilter(context, filter, customizer, &tracker);
-
-				arrayList_add(act->trackerList,tracker);
-			}
-			else{
-				printf("Topic %s too long. Skipping publication.\n",topic);
-			}
-			free(topic);
-		}
-		arrayList_destroy(topic_list);
+			service_tracker_customizer_pt customizer = NULL;
+			serviceTrackerCustomizer_create(act->client,NULL,publisher_publishSvcAdded,NULL,publisher_publishSvcRemoved,&customizer);
+			serviceTracker_createWithFilter(context, filter, customizer, &tracker);
+
+			arrayList_add(act->trackerList,tracker);
 
+		}
 	}
 
 	publisher_start(act->client);

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/examples/pubsub/publisher/private/src/pubsub_publisher.c
----------------------------------------------------------------------
diff --git a/pubsub/examples/pubsub/publisher/private/src/pubsub_publisher.c b/pubsub/examples/pubsub/publisher/private/src/pubsub_publisher.c
index 7e7602e..9a7aedc 100644
--- a/pubsub/examples/pubsub/publisher/private/src/pubsub_publisher.c
+++ b/pubsub/examples/pubsub/publisher/private/src/pubsub_publisher.c
@@ -32,7 +32,6 @@
 #include "service_tracker.h"
 #include "celix_threads.h"
 
-#include "pubsub_common.h"
 #include "poi.h"
 
 #include "pubsub_publisher_private.h"

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/examples/pubsub/publisher2/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/examples/pubsub/publisher2/CMakeLists.txt b/pubsub/examples/pubsub/publisher2/CMakeLists.txt
index 82ffb75..ba007c2 100644
--- a/pubsub/examples/pubsub/publisher2/CMakeLists.txt
+++ b/pubsub/examples/pubsub/publisher2/CMakeLists.txt
@@ -15,40 +15,37 @@
 # specific language governing permissions and limitations
 # under the License.
 
-include_directories("../publisher/private/include")
-include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/api/pubsub")
-
-add_bundle(org.apache.celix.pubsub_publisher.PoiPublisher2
+add_bundle(celix_pubsub_poi_publisher2
     SYMBOLIC_NAME "apache_celix_pubsub_poi_publisher2"
     VERSION "1.0.0"
     SOURCES 
     	../publisher/private/src/ps_pub_activator.c
     	../publisher/private/src/pubsub_publisher.c
-    	${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c
 )
+target_link_libraries(celix_pubsub_poi_publisher2 PRIVATE Celix::framework Celix::pubsub_api)
+target_include_directories(celix_pubsub_poi_publisher2 PRIVATE ../publisher/private/include)
+
 
-bundle_files(org.apache.celix.pubsub_publisher.PoiPublisher2
+bundle_files(celix_pubsub_poi_publisher2
 	${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor
 	${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor
     DESTINATION "META-INF/descriptors"
 )
 
-bundle_files(org.apache.celix.pubsub_publisher.PoiPublisher2
+bundle_files(celix_pubsub_poi_publisher2
 		${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/poi1.properties
 		${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/poi2.properties
     DESTINATION "META-INF/topics/pub"
 )
 
-bundle_files(org.apache.celix.pubsub_publisher.PoiPublisher2
+bundle_files(celix_pubsub_poi_publisher2
 		${PROJECT_SOURCE_DIR}/pubsub/examples/keys/publisher
     DESTINATION "META-INF/keys"
 )
 
-bundle_files(org.apache.celix.pubsub_publisher.PoiPublisher2
-		${PROJECT_SOURCE_DIR}/pubsub/examples/keys/subscriber/public
+bundle_files(celix_pubsub_poi_publisher2
+	${PROJECT_SOURCE_DIR}/pubsub/examples/keys/subscriber/public
     DESTINATION "META-INF/keys/subscriber"
 )
 
-target_link_libraries(org.apache.celix.pubsub_publisher.PoiPublisher2 PRIVATE Celix::framework)
+target_link_libraries(celix_pubsub_poi_publisher2 PRIVATE Celix::framework)

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/examples/pubsub/subscriber/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/examples/pubsub/subscriber/CMakeLists.txt b/pubsub/examples/pubsub/subscriber/CMakeLists.txt
index 28569b0..1ffd39a 100644
--- a/pubsub/examples/pubsub/subscriber/CMakeLists.txt
+++ b/pubsub/examples/pubsub/subscriber/CMakeLists.txt
@@ -15,41 +15,36 @@
 # specific language governing permissions and limitations
 # under the License.
 
-include_directories("private/include")
-include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/api/pubsub")
-include_directories("${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/common/include")
-
-add_bundle(org.apache.celix.pubsub_subscriber.PoiSubscriber
+add_bundle(celix_pubsub_poi_subscriber
     SYMBOLIC_NAME "apache_celix_pubsub_poi_subscriber" 
     VERSION "1.0.0"
     SOURCES 
     	private/src/ps_sub_activator.c
-    	private/src/pubsub_subscriber.c
-    	${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c
+		private/src/pubsub_subscriber.c
 )
 
-bundle_files(org.apache.celix.pubsub_subscriber.PoiSubscriber
+target_link_libraries(celix_pubsub_poi_subscriber PRIVATE Celix::framework Celix::pubsub_api)
+target_include_directories(celix_pubsub_poi_subscriber PRIVATE private/include)
+
+
+bundle_files(celix_pubsub_poi_subscriber
 	    ${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor
 	    ${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor
     DESTINATION "META-INF/descriptors"
 )
 
-bundle_files(org.apache.celix.pubsub_subscriber.PoiSubscriber
+bundle_files(celix_pubsub_poi_subscriber
 		${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/poi1.properties
 		${PROJECT_SOURCE_DIR}/pubsub/examples/pubsub/msg_descriptors/poi2.properties
     DESTINATION "META-INF/topics/sub"
 )
 
-bundle_files(org.apache.celix.pubsub_subscriber.PoiSubscriber
+bundle_files(celix_pubsub_poi_subscriber
 		${PROJECT_SOURCE_DIR}/pubsub/examples/keys/subscriber
     DESTINATION "META-INF/keys"
 )
 
-bundle_files(org.apache.celix.pubsub_subscriber.PoiSubscriber
+bundle_files(celix_pubsub_poi_subscriber
 		${PROJECT_SOURCE_DIR}/pubsub/examples/keys/publisher/public
     DESTINATION "META-INF/keys/publisher"
-)
-
-target_link_libraries(org.apache.celix.pubsub_subscriber.PoiSubscriber PRIVATE Celix::framework)
+)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/examples/pubsub/subscriber/private/include/pubsub_subscriber_private.h
----------------------------------------------------------------------
diff --git a/pubsub/examples/pubsub/subscriber/private/include/pubsub_subscriber_private.h b/pubsub/examples/pubsub/subscriber/private/include/pubsub_subscriber_private.h
index c6072df..00ca9b4 100644
--- a/pubsub/examples/pubsub/subscriber/private/include/pubsub_subscriber_private.h
+++ b/pubsub/examples/pubsub/subscriber/private/include/pubsub_subscriber_private.h
@@ -32,8 +32,7 @@
 
 #include "celixbool.h"
 
-#include "pubsub_common.h"
-#include "subscriber.h"
+#include "pubsub/subscriber.h"
 
 struct pubsub_receiver {
 	char * name;

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/examples/pubsub/subscriber/private/src/ps_sub_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/examples/pubsub/subscriber/private/src/ps_sub_activator.c b/pubsub/examples/pubsub/subscriber/private/src/ps_sub_activator.c
index efd34c9..4738abd 100644
--- a/pubsub/examples/pubsub/subscriber/private/src/ps_sub_activator.c
+++ b/pubsub/examples/pubsub/subscriber/private/src/ps_sub_activator.c
@@ -25,14 +25,18 @@
  */
 
 #include <stdlib.h>
+#include <pubsub/subscriber.h>
 
 #include "bundle_activator.h"
 
-#include "pubsub_common.h"
-#include "pubsub_utils.h"
 #include "pubsub_subscriber_private.h"
 
-#define SUB_TOPIC "poi1;poi2"
+#define SUB_NAME "poi1;poi2"
+static const char * SUB_TOPICS[] = {
+		"poi1",
+		"poi2",
+		NULL
+};
 
 struct subscriberActivator {
 	array_list_pt registrationList; //List<service_registration_pt>
@@ -51,39 +55,29 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context)
 
 
 	pubsub_subscriber_pt subsvc = calloc(1,sizeof(*subsvc));
-	pubsub_receiver_pt sub = subscriber_create(SUB_TOPIC);
+	pubsub_receiver_pt sub = subscriber_create(SUB_NAME);
 	subsvc->handle = sub;
 	subsvc->receive = pubsub_subscriber_recv;
 
 	act->subsvc = subsvc;
 
-	array_list_pt topic_list = pubsub_getTopicsFromString(SUB_TOPIC);
-
-	if(topic_list !=NULL){
+	if (SUB_TOPICS !=NULL){
 
 		int i;
-		for(i=0; i<arrayList_size(topic_list);i++){
-			char* topic = arrayList_get(topic_list,i);
-			if(strlen(topic)<MAX_TOPIC_LEN){
-				properties_pt props = properties_create();
-				properties_set(props, PUBSUB_SUBSCRIBER_TOPIC,topic);
+		for(i=0; SUB_TOPICS[i] != NULL ;i++){
+			const char* topic = SUB_TOPICS[i];
+			properties_pt props = properties_create();
+			properties_set(props, PUBSUB_SUBSCRIBER_TOPIC,topic);
 #ifdef USE_SCOPE
 				char *scope;
 				asprintf(&scope, "my_scope_%d", i);
 				properties_set(props,SUBSCRIBER_SCOPE,scope);
 				free(scope);
 #endif
-				service_registration_pt reg = NULL;
-				bundleContext_registerService(context, PUBSUB_SUBSCRIBER_SERVICE_NAME, subsvc, props, &reg);
-				arrayList_add(act->registrationList,reg);
-			}
-			else{
-				printf("Topic %s too long. Skipping subscription.\n",topic);
-			}
-			free(topic);
+			service_registration_pt reg = NULL;
+			bundleContext_registerService(context, PUBSUB_SUBSCRIBER_SERVICE_NAME, subsvc, props, &reg);
+			arrayList_add(act->registrationList,reg);
 		}
-		arrayList_destroy(topic_list);
-
 	}
 
 	subscriber_start((pubsub_receiver_pt)act->subsvc->handle);

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/mock/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/mock/CMakeLists.txt b/pubsub/mock/CMakeLists.txt
index 6313987..ccc3d20 100644
--- a/pubsub/mock/CMakeLists.txt
+++ b/pubsub/mock/CMakeLists.txt
@@ -18,28 +18,22 @@
 #only install if CppuTest is available
 find_package(CppUTest QUIET)
 if (CPPUTEST_FOUND)
-    include_directories(
-        ../api
-        api
+
+    add_library(celix_pubsub_mock STATIC
+            src/publisher_mock.cc
     )
-    include_directories(SYSTEM
+    target_include_directories(celix_pubsub_mock PUBLIC api)
+    target_link_libraries(celix_pubsub_mock PRIVATE Celix::pubsub_spi ${CPPUTEST_LIBRARY})
+    target_include_directories(celix_pubsub_mock PRIVATE SYSTEM
         ${CPPUTEST_INCLUDE_DIR}
     )
 
-    add_library(celix_pubsubmock STATIC
-        src/publisher_mock.cc
-            ../test/test/msg.h)
-    target_link_libraries(celix_pubsubmock ${CPPUTEST_LIBRARY})
-
-    install(TARGETS celix_pubsubmock DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT framework)
-    install(FILES api/pubsub/publisher_mock.h DESTINATION include/celix/pubsub COMPONENT framework)
-
     if (ENABLE_TESTING)
         add_executable(pubsubmock_test
             tst/pubsubmock_test.cc
             tst/run_tests.cc
         )
-        target_link_libraries(pubsubmock_test celix_pubsubmock ${CPPUTEST_LIBRARY} ${CPPUTEST_EXT_LIBRARY})
+        target_link_libraries(pubsubmock_test celix_pubsub_mock ${CPPUTEST_LIBRARY} ${CPPUTEST_EXT_LIBRARY} Celix::framework)
         add_test(NAME pubsubmock_test COMMAND pubsubmock_test)
     endif()
 endif()

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_udp_mc/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/CMakeLists.txt b/pubsub/pubsub_admin_udp_mc/CMakeLists.txt
index a57693f..87858e3 100644
--- a/pubsub/pubsub_admin_udp_mc/CMakeLists.txt
+++ b/pubsub/pubsub_admin_udp_mc/CMakeLists.txt
@@ -17,7 +17,7 @@
 
 find_package(Jansson REQUIRED)
 
-add_bundle(org.apache.celix.pubsub_admin.PubSubAdminUdpMc
+add_bundle(celix_pubsub_admin_udp_multicast
 	BUNDLE_SYMBOLICNAME "apache_celix_pubsub_admin_udp_multicast"
 	VERSION "1.0.0"
 	SOURCES
@@ -26,20 +26,19 @@ add_bundle(org.apache.celix.pubsub_admin.PubSubAdminUdpMc
         src/topic_subscription.c
         src/topic_publication.c
         src/large_udp.c
-		${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_endpoint.c
-		${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_admin_match.c
-		${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c
 )
 
 
-target_include_directories(org.apache.celix.pubsub_admin.PubSubAdminUdpMc PRIVATE
+target_include_directories(celix_pubsub_admin_udp_multicast PRIVATE
 		src
 		${JANSSON_INCLUDE_DIR}
 )
 
-set_target_properties(org.apache.celix.pubsub_admin.PubSubAdminUdpMc PROPERTIES INSTALL_RPATH "$ORIGIN")
-target_link_libraries(org.apache.celix.pubsub_admin.PubSubAdminUdpMc PRIVATE Celix::framework Celix::dfi Celix::log_helper)
+set_target_properties(celix_pubsub_admin_udp_multicast PROPERTIES INSTALL_RPATH "$ORIGIN")
+target_link_libraries(celix_pubsub_admin_udp_multicast PRIVATE Celix::pubsub_spi Celix::framework Celix::dfi Celix::log_helper)
 
-install_bundle(org.apache.celix.pubsub_admin.PubSubAdminUdpMc)
+install_bundle(celix_pubsub_admin_udp_multicast)
+
+add_library(Celix::pubsub_admin_udp_multicast ALIAS celix_pubsub_admin_udp_multicast)
 
 

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.c b/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.c
index 1fbdb08..674f817 100644
--- a/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.c
+++ b/pubsub/pubsub_admin_udp_mc/src/pubsub_admin_impl.c
@@ -59,7 +59,7 @@
 #include "topic_subscription.h"
 #include "topic_publication.h"
 #include "pubsub_endpoint.h"
-#include "subscriber.h"
+#include "pubsub/subscriber.h"
 #include "pubsub_admin_match.h"
 
 static const char *DEFAULT_MC_IP = "224.100.1.1";

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_udp_mc/src/topic_publication.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/topic_publication.c b/pubsub/pubsub_admin_udp_mc/src/topic_publication.c
index 44106df..15af108 100644
--- a/pubsub/pubsub_admin_udp_mc/src/topic_publication.c
+++ b/pubsub/pubsub_admin_udp_mc/src/topic_publication.c
@@ -36,7 +36,7 @@
 
 #include "topic_publication.h"
 #include "pubsub_common.h"
-#include "publisher.h"
+#include "pubsub/publisher.h"
 #include "large_udp.h"
 
 #include "pubsub_serializer.h"

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_udp_mc/src/topic_publication.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/topic_publication.h b/pubsub/pubsub_admin_udp_mc/src/topic_publication.h
index 4363d71..8f47deb 100644
--- a/pubsub/pubsub_admin_udp_mc/src/topic_publication.h
+++ b/pubsub/pubsub_admin_udp_mc/src/topic_publication.h
@@ -27,7 +27,7 @@
 #ifndef TOPIC_PUBLICATION_H_
 #define TOPIC_PUBLICATION_H_
 
-#include "publisher.h"
+#include "pubsub/publisher.h"
 #include "pubsub_endpoint.h"
 #include "pubsub_common.h"
 

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_udp_mc/src/topic_subscription.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_udp_mc/src/topic_subscription.c b/pubsub/pubsub_admin_udp_mc/src/topic_subscription.c
index d8e6f45..6d0768b 100644
--- a/pubsub/pubsub_admin_udp_mc/src/topic_subscription.c
+++ b/pubsub/pubsub_admin_udp_mc/src/topic_subscription.c
@@ -42,8 +42,8 @@
 
 #include "topic_subscription.h"
 #include "topic_publication.h"
-#include "subscriber.h"
-#include "publisher.h"
+#include "pubsub/subscriber.h"
+#include "pubsub/publisher.h"
 #include "large_udp.h"
 
 #include "pubsub_serializer.h"

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_zmq/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/CMakeLists.txt b/pubsub/pubsub_admin_zmq/CMakeLists.txt
index d71aedb..9d57756 100644
--- a/pubsub/pubsub_admin_zmq/CMakeLists.txt
+++ b/pubsub/pubsub_admin_zmq/CMakeLists.txt
@@ -21,17 +21,6 @@ if (BUILD_PUBSUB_PSA_ZMQ)
 	find_package(CZMQ REQUIRED)
 	find_package(Jansson REQUIRED)
 
-	include_directories("${ZMQ_INCLUDE_DIR}")
-	include_directories("${CZMQ_INCLUDE_DIR}")
-	include_directories("${JANSSON_INCLUDE_DIR}")
-	include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
-	include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
-	include_directories("${PROJECT_SOURCE_DIR}/dfi/public/include")
-	include_directories("${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/include")
-	include_directories("${PROJECT_SOURCE_DIR}/pubsub/api/pubsub")
-	include_directories("private/include")
-	include_directories("public/include")
-
 	if (BUILD_ZMQ_SECURITY)
 		add_definitions(-DBUILD_WITH_ZMQ_SECURITY=1)
 
@@ -41,24 +30,31 @@ if (BUILD_PUBSUB_PSA_ZMQ)
 		set (ZMQ_CRYPTO_C "private/src/zmq_crypto.c")
 	endif()
 
-	add_bundle(org.apache.celix.pubsub_admin.PubSubAdminZmq
-	    BUNDLE_SYMBOLICNAME "apache_celix_pubsub_admin_zmq"
-	    VERSION "1.0.0"
-	    SOURCES
-	    	private/src/psa_activator.c
-	    	private/src/pubsub_admin_impl.c
-	    	private/src/topic_subscription.c
-	    	private/src/topic_publication.c
-	    	${ZMQ_CRYPTO_C}
-	    	${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_endpoint.c
-	    	${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_utils.c
-    	   ${PROJECT_SOURCE_DIR}/pubsub/pubsub_common/public/src/pubsub_admin_match.c
+	add_bundle(celix_pubsub_admin_zmq
+			BUNDLE_SYMBOLICNAME "apache_celix_pubsub_admin_zmq"
+			VERSION "1.0.0"
+			SOURCES
+			src/psa_activator.c
+			src/pubsub_admin_impl.c
+			src/topic_subscription.c
+			src/topic_publication.c
+			${ZMQ_CRYPTO_C}
 	)
 
-	set_target_properties(org.apache.celix.pubsub_admin.PubSubAdminZmq PROPERTIES INSTALL_RPATH "$ORIGIN")
-	target_link_libraries(org.apache.celix.pubsub_admin.PubSubAdminZmq PRIVATE
+	set_target_properties(celix_pubsub_admin_zmq PROPERTIES INSTALL_RPATH "$ORIGIN")
+	target_link_libraries(celix_pubsub_admin_zmq PRIVATE
+			Celix::pubsub_spi
 			Celix::framework Celix::dfi Celix::log_helper
-			${ZMQ_LIBRARIES} ${CZMQ_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARY})
+			${ZMQ_LIBRARIES} ${CZMQ_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARY}
+	)
+	target_include_directories(celix_pubsub_admin_zmq PRIVATE
+		${ZMQ_INCLUDE_DIR}
+		${CZMQ_INCLUDE_DIR}
+		${JANSSON_INCLUDE_DIR}
+		src
+	)
+
 	install_bundle(org.apache.celix.pubsub_admin.PubSubAdminZmq)
 
+	add_library(Celix::pubsub_admin_zmq ALIAS celix_pubsub_admin_zmq)
 endif()

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_zmq/private/include/pubsub_admin_impl.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/private/include/pubsub_admin_impl.h b/pubsub/pubsub_admin_zmq/private/include/pubsub_admin_impl.h
deleted file mode 100644
index 03e8556..0000000
--- a/pubsub/pubsub_admin_zmq/private/include/pubsub_admin_impl.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- *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.
- */
-/*
- * pubsub_admin_impl.h
- *
- *  \date       Dec 5, 2013
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef PUBSUB_ADMIN_ZMQ_IMPL_H_
-#define PUBSUB_ADMIN_ZMQ_IMPL_H_
-
-#include <czmq.h>
-/* The following undefs prevent the collision between:
- * - sys/syslog.h (which is included within czmq)
- * - celix/dfi/dfi_log_util.h
- */
-#undef LOG_DEBUG
-#undef LOG_WARNING
-#undef LOG_INFO
-#undef LOG_WARNING
-
-#include "pubsub_admin.h"
-#include "pubsub_admin_match.h"
-#include "log_helper.h"
-
-#define PSA_ZMQ_BASE_PORT "PSA_ZMQ_BASE_PORT"
-#define PSA_ZMQ_MAX_PORT "PSA_ZMQ_MAX_PORT"
-
-#define PSA_ZMQ_DEFAULT_BASE_PORT 5501
-#define PSA_ZMQ_DEFAULT_MAX_PORT 6000
-
-#define PUBSUB_ADMIN_TYPE	"zmq"
-
-struct pubsub_admin {
-
-	bundle_context_pt bundle_context;
-	log_helper_pt loghelper;
-
-	/* List of the available serializers */
-	celix_thread_mutex_t serializerListLock; // List<serializers>
-	array_list_pt serializerList;
-
-	celix_thread_mutex_t localPublicationsLock;
-	hash_map_pt localPublications;//<topic(string),service_factory_pt>
-
-	celix_thread_mutex_t externalPublicationsLock;
-	hash_map_pt externalPublications;//<topic(string),List<pubsub_ep>>
-
-	celix_thread_mutex_t subscriptionsLock;
-	hash_map_pt subscriptions; //<topic(string),topic_subscription>
-
-	celix_thread_mutex_t pendingSubscriptionsLock;
-	celix_thread_mutexattr_t pendingSubscriptionsAttr;
-	hash_map_pt pendingSubscriptions; //<topic(string),List<pubsub_ep>>
-
-	/* Those are used to keep track of valid subscriptions/publications that still have no valid serializer */
-	celix_thread_mutex_t noSerializerPendingsLock;
-	celix_thread_mutexattr_t noSerializerPendingsAttr;
-	array_list_pt noSerializerSubscriptions; // List<pubsub_ep>
-	array_list_pt noSerializerPublications; // List<pubsub_ep>
-
-	celix_thread_mutex_t usedSerializersLock;
-	hash_map_pt topicSubscriptionsPerSerializer; // <serializer,List<topicSubscription>>
-	hash_map_pt topicPublicationsPerSerializer; // <serializer,List<topicPublications>>
-
-	char* ipAddress;
-
-	zactor_t* zmq_auth;
-
-    unsigned int basePort;
-    unsigned int maxPort;
-};
-
-celix_status_t pubsubAdmin_create(bundle_context_pt context, pubsub_admin_pt *admin);
-celix_status_t pubsubAdmin_destroy(pubsub_admin_pt admin);
-
-celix_status_t pubsubAdmin_addSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
-celix_status_t pubsubAdmin_removeSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
-
-celix_status_t pubsubAdmin_addPublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP);
-celix_status_t pubsubAdmin_removePublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP);
-
-celix_status_t pubsubAdmin_closeAllPublications(pubsub_admin_pt admin,char* scope, char* topic);
-celix_status_t pubsubAdmin_closeAllSubscriptions(pubsub_admin_pt admin,char* scope,char* topic);
-
-celix_status_t pubsubAdmin_serializerAdded(void * handle, service_reference_pt reference, void * service);
-celix_status_t pubsubAdmin_serializerRemoved(void * handle, service_reference_pt reference, void * service);
-
-celix_status_t pubsubAdmin_matchEndpoint(pubsub_admin_pt admin, pubsub_endpoint_pt endpoint, double* score);
-
-#endif /* PUBSUB_ADMIN_ZMQ_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_zmq/private/include/topic_publication.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/private/include/topic_publication.h b/pubsub/pubsub_admin_zmq/private/include/topic_publication.h
deleted file mode 100644
index 3457263..0000000
--- a/pubsub/pubsub_admin_zmq/private/include/topic_publication.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- *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.
- */
-/*
- * topic_publication.h
- *
- *  \date       Sep 24, 2015
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef TOPIC_PUBLICATION_H_
-#define TOPIC_PUBLICATION_H_
-
-#include "publisher.h"
-#include "pubsub_endpoint.h"
-#include "pubsub_common.h"
-
-#include "pubsub_serializer.h"
-
-typedef struct topic_publication *topic_publication_pt;
-
-celix_status_t pubsub_topicPublicationCreate(bundle_context_pt bundle_context,pubsub_endpoint_pt pubEP, pubsub_serializer_service_t *best_serializer, char* bindIP, unsigned int basePort, unsigned int maxPort, topic_publication_pt *out);
-celix_status_t pubsub_topicPublicationDestroy(topic_publication_pt pub);
-
-celix_status_t pubsub_topicPublicationAddPublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep);
-celix_status_t pubsub_topicPublicationRemovePublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep);
-
-celix_status_t pubsub_topicPublicationStart(bundle_context_pt bundle_context,topic_publication_pt pub,service_factory_pt* svcFactory);
-celix_status_t pubsub_topicPublicationStop(topic_publication_pt pub);
-
-array_list_pt pubsub_topicPublicationGetPublisherList(topic_publication_pt pub);
-
-#endif /* TOPIC_PUBLICATION_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_zmq/private/include/topic_subscription.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/private/include/topic_subscription.h b/pubsub/pubsub_admin_zmq/private/include/topic_subscription.h
deleted file mode 100644
index 7267103..0000000
--- a/pubsub/pubsub_admin_zmq/private/include/topic_subscription.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- *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.
- */
-/*
- * topic_subscription.h
- *
- *  \date       Sep 22, 2015
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef TOPIC_SUBSCRIPTION_H_
-#define TOPIC_SUBSCRIPTION_H_
-
-#include "celix_threads.h"
-#include "array_list.h"
-#include "celixbool.h"
-#include "service_tracker.h"
-
-#include "pubsub_endpoint.h"
-#include "pubsub_common.h"
-#include "pubsub_serializer.h"
-
-typedef struct topic_subscription* topic_subscription_pt;
-
-celix_status_t pubsub_topicSubscriptionCreate(bundle_context_pt bundle_context,char* scope, char* topic, pubsub_serializer_service_t *best_serializer, topic_subscription_pt* out);
-celix_status_t pubsub_topicSubscriptionDestroy(topic_subscription_pt ts);
-celix_status_t pubsub_topicSubscriptionStart(topic_subscription_pt ts);
-celix_status_t pubsub_topicSubscriptionStop(topic_subscription_pt ts);
-
-celix_status_t pubsub_topicSubscriptionAddConnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL);
-celix_status_t pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL);
-
-celix_status_t pubsub_topicSubscriptionConnectPublisher(topic_subscription_pt ts, char* pubURL);
-celix_status_t pubsub_topicSubscriptionDisconnectPublisher(topic_subscription_pt ts, char* pubURL);
-
-celix_status_t pubsub_topicSubscriptionAddSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP);
-celix_status_t pubsub_topicSubscriptionRemoveSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP);
-
-array_list_pt pubsub_topicSubscriptionGetSubscribersList(topic_subscription_pt sub);
-celix_status_t pubsub_topicIncreaseNrSubscribers(topic_subscription_pt subscription);
-celix_status_t pubsub_topicDecreaseNrSubscribers(topic_subscription_pt subscription);
-unsigned int pubsub_topicGetNrSubscribers(topic_subscription_pt subscription);
-
-#endif /*TOPIC_SUBSCRIPTION_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_zmq/private/include/zmq_crypto.h
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/private/include/zmq_crypto.h b/pubsub/pubsub_admin_zmq/private/include/zmq_crypto.h
deleted file mode 100644
index f1a990f..0000000
--- a/pubsub/pubsub_admin_zmq/private/include/zmq_crypto.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- *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.
- */
-/*
- * zmq_crypto.h
- *
- *  \date       Dec 2, 2016
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef ZMQ_CRYPTO_H_
-#define ZMQ_CRYPTO_H_
-
-#include <czmq.h>
-
-#define PROPERTY_KEYS_FILE_PATH "keys.file.path"
-#define PROPERTY_KEYS_FILE_NAME "keys.file.name"
-#define DEFAULT_KEYS_FILE_PATH "/etc/"
-#define DEFAULT_KEYS_FILE_NAME "pubsub.keys"
-
-zcert_t* get_zcert_from_encoded_file(char* keysFilePath, char* keysFileName, char* file_path);
-int generate_sha256_hash(char* text, unsigned char* digest);
-int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext);
-
-#endif


[7/8] celix git commit: CELIX-417: Refactors cmake usage of pubsub and rsa. Started with installing exported targets

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_zmq/private/src/psa_activator.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/private/src/psa_activator.c b/pubsub/pubsub_admin_zmq/private/src/psa_activator.c
deleted file mode 100644
index fd07310..0000000
--- a/pubsub/pubsub_admin_zmq/private/src/psa_activator.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/**
- *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.
- */
-/*
- * psa_activator.c
- *
- *  \date       Sep 30, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-
-#include "bundle_activator.h"
-#include "service_registration.h"
-#include "service_tracker.h"
-
-#include "pubsub_admin_impl.h"
-
-
-struct activator {
-	pubsub_admin_pt admin;
-	pubsub_admin_service_pt adminService;
-	service_registration_pt registration;
-	service_tracker_pt serializerTracker;
-};
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator;
-
-	activator = calloc(1, sizeof(*activator));
-	if (!activator) {
-		status = CELIX_ENOMEM;
-	}
-	else{
-		*userData = activator;
-
-		status = pubsubAdmin_create(context, &(activator->admin));
-
-		if(status == CELIX_SUCCESS){
-			service_tracker_customizer_pt customizer = NULL;
-			status = serviceTrackerCustomizer_create(activator->admin,
-					NULL,
-					pubsubAdmin_serializerAdded,
-					NULL,
-					pubsubAdmin_serializerRemoved,
-					&customizer);
-			if(status == CELIX_SUCCESS){
-				status = serviceTracker_create(context, PUBSUB_SERIALIZER_SERVICE, customizer, &(activator->serializerTracker));
-				if(status != CELIX_SUCCESS){
-					serviceTrackerCustomizer_destroy(customizer);
-					pubsubAdmin_destroy(activator->admin);
-				}
-			}
-			else{
-				pubsubAdmin_destroy(activator->admin);
-			}
-		}
-	}
-
-	return status;
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-	pubsub_admin_service_pt pubsubAdminSvc = calloc(1, sizeof(*pubsubAdminSvc));
-
-	if (!pubsubAdminSvc) {
-		status = CELIX_ENOMEM;
-	}
-	else{
-		pubsubAdminSvc->admin = activator->admin;
-
-		pubsubAdminSvc->addPublication = pubsubAdmin_addPublication;
-		pubsubAdminSvc->removePublication = pubsubAdmin_removePublication;
-
-		pubsubAdminSvc->addSubscription = pubsubAdmin_addSubscription;
-		pubsubAdminSvc->removeSubscription = pubsubAdmin_removeSubscription;
-
-		pubsubAdminSvc->closeAllPublications = pubsubAdmin_closeAllPublications;
-		pubsubAdminSvc->closeAllSubscriptions = pubsubAdmin_closeAllSubscriptions;
-
-		pubsubAdminSvc->matchEndpoint = pubsubAdmin_matchEndpoint;
-
-		activator->adminService = pubsubAdminSvc;
-
-		status = bundleContext_registerService(context, PUBSUB_ADMIN_SERVICE, pubsubAdminSvc, NULL, &activator->registration);
-
-		status += serviceTracker_open(activator->serializerTracker);
-
-	}
-
-
-	return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-
-	status += serviceTracker_close(activator->serializerTracker);
-	status += serviceRegistration_unregister(activator->registration);
-
-	activator->registration = NULL;
-
-	free(activator->adminService);
-	activator->adminService = NULL;
-
-	return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-
-	serviceTracker_destroy(activator->serializerTracker);
-	pubsubAdmin_destroy(activator->admin);
-	activator->admin = NULL;
-
-	free(activator);
-
-	return status;
-}
-
-

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_zmq/private/src/pubsub_admin_impl.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/private/src/pubsub_admin_impl.c b/pubsub/pubsub_admin_zmq/private/src/pubsub_admin_impl.c
deleted file mode 100644
index 29ead0c..0000000
--- a/pubsub/pubsub_admin_zmq/private/src/pubsub_admin_impl.c
+++ /dev/null
@@ -1,1040 +0,0 @@
-/**
- *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.
- */
-/*
- * pubsub_admin_impl.c
- *
- *  \date       Sep 30, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#include "pubsub_admin_impl.h"
-#include <zmq.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#include <netdb.h>
-
-#ifndef ANDROID
-#include <ifaddrs.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "constants.h"
-#include "utils.h"
-#include "hash_map.h"
-#include "array_list.h"
-#include "bundle_context.h"
-#include "bundle.h"
-#include "service_reference.h"
-#include "service_registration.h"
-#include "log_helper.h"
-#include "log_service.h"
-#include "celix_threads.h"
-#include "service_factory.h"
-
-#include "topic_subscription.h"
-#include "topic_publication.h"
-#include "pubsub_endpoint.h"
-#include "pubsub_utils.h"
-#include "subscriber.h"
-
-#define MAX_KEY_FOLDER_PATH_LENGTH 512
-
-static const char *DEFAULT_IP = "127.0.0.1";
-
-static celix_status_t pubsubAdmin_getIpAdress(const char* interface, char** ip);
-static celix_status_t pubsubAdmin_addSubscriptionToPendingList(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
-static celix_status_t pubsubAdmin_addAnySubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP);
-
-static celix_status_t pubsubAdmin_getBestSerializer(pubsub_admin_pt admin,pubsub_endpoint_pt ep, pubsub_serializer_service_t **serSvc);
-static void connectTopicPubSubToSerializer(pubsub_admin_pt admin,pubsub_serializer_service_t *serializer,void *topicPubSub,bool isPublication);
-static void disconnectTopicPubSubFromSerializer(pubsub_admin_pt admin,void *topicPubSub,bool isPublication);
-
-celix_status_t pubsubAdmin_create(bundle_context_pt context, pubsub_admin_pt *admin) {
-	celix_status_t status = CELIX_SUCCESS;
-
-#ifdef BUILD_WITH_ZMQ_SECURITY
-	if (!zsys_has_curve()){
-		printf("PSA_ZMQ: zeromq curve unsupported\n");
-		return CELIX_SERVICE_EXCEPTION;
-	}
-#endif
-
-	*admin = calloc(1, sizeof(**admin));
-
-	if (!*admin) {
-		status = CELIX_ENOMEM;
-	}
-	else{
-
-		const char *ip = NULL;
-		char *detectedIp = NULL;
-		(*admin)->bundle_context= context;
-		(*admin)->localPublications = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-		(*admin)->subscriptions = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-		(*admin)->pendingSubscriptions = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-		(*admin)->externalPublications = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-		(*admin)->topicSubscriptionsPerSerializer = hashMap_create(NULL, NULL, NULL, NULL);
-		(*admin)->topicPublicationsPerSerializer  = hashMap_create(NULL, NULL, NULL, NULL);
-		arrayList_create(&((*admin)->noSerializerSubscriptions));
-		arrayList_create(&((*admin)->noSerializerPublications));
-		arrayList_create(&((*admin)->serializerList));
-
-		celixThreadMutex_create(&(*admin)->localPublicationsLock, NULL);
-		celixThreadMutex_create(&(*admin)->subscriptionsLock, NULL);
-		celixThreadMutex_create(&(*admin)->externalPublicationsLock, NULL);
-		celixThreadMutex_create(&(*admin)->serializerListLock, NULL);
-		celixThreadMutex_create(&(*admin)->usedSerializersLock, NULL);
-
-		celixThreadMutexAttr_create(&(*admin)->noSerializerPendingsAttr);
-		celixThreadMutexAttr_settype(&(*admin)->noSerializerPendingsAttr, CELIX_THREAD_MUTEX_RECURSIVE);
-		celixThreadMutex_create(&(*admin)->noSerializerPendingsLock, &(*admin)->noSerializerPendingsAttr);
-
-		celixThreadMutexAttr_create(&(*admin)->pendingSubscriptionsAttr);
-		celixThreadMutexAttr_settype(&(*admin)->pendingSubscriptionsAttr, CELIX_THREAD_MUTEX_RECURSIVE);
-		celixThreadMutex_create(&(*admin)->pendingSubscriptionsLock, &(*admin)->pendingSubscriptionsAttr);
-
-		if (logHelper_create(context, &(*admin)->loghelper) == CELIX_SUCCESS) {
-			logHelper_start((*admin)->loghelper);
-		}
-
-		bundleContext_getProperty(context,PSA_IP , &ip);
-
-#ifndef ANDROID
-		if (ip == NULL) {
-			const char *interface = NULL;
-
-			bundleContext_getProperty(context, PSA_ITF, &interface);
-			if (pubsubAdmin_getIpAdress(interface, &detectedIp) != CELIX_SUCCESS) {
-				logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "PSA_ZMQ: Could not retrieve IP adress for interface %s", interface);
-			}
-
-			ip = detectedIp;
-		}
-#endif
-
-		if (ip != NULL) {
-			logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "PSA_ZMQ: Using %s for service annunciation", ip);
-			(*admin)->ipAddress = strdup(ip);
-		}
-		else {
-			logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "PSA_ZMQ: No IP address for service annunciation set. Using %s", DEFAULT_IP);
-			(*admin)->ipAddress = strdup(DEFAULT_IP);
-		}
-
-		if (detectedIp != NULL) {
-			free(detectedIp);
-		}
-
-		const char* basePortStr = NULL;
-		const char* maxPortStr = NULL;
-		char* endptrBase = NULL;
-		char* endptrMax = NULL;
-		bundleContext_getPropertyWithDefault(context, PSA_ZMQ_BASE_PORT, "PSA_ZMQ_DEFAULT_BASE_PORT", &basePortStr);
-		bundleContext_getPropertyWithDefault(context, PSA_ZMQ_MAX_PORT, "PSA_ZMQ_DEFAULT_MAX_PORT", &maxPortStr);
-		(*admin)->basePort = strtol(basePortStr, &endptrBase, 10);
-		(*admin)->maxPort = strtol(maxPortStr, &endptrMax, 10);
-		if (*endptrBase != '\0') {
-			(*admin)->basePort = PSA_ZMQ_DEFAULT_BASE_PORT;
-		}
-		if (*endptrMax != '\0') {
-			(*admin)->maxPort = PSA_ZMQ_DEFAULT_MAX_PORT;
-		}
-
-		printf("PSA Using base port %u to max port %u\n", (*admin)->basePort, (*admin)->maxPort);
-
-		// Disable Signal Handling by CZMQ
-		setenv("ZSYS_SIGHANDLER", "false", true);
-
-		const char *nrZmqThreads = NULL;
-		bundleContext_getProperty(context, "PSA_NR_ZMQ_THREADS", &nrZmqThreads);
-
-		if(nrZmqThreads != NULL) {
-			char *endPtr = NULL;
-			unsigned int nrThreads = strtoul(nrZmqThreads, &endPtr, 10);
-			if(endPtr != nrZmqThreads && nrThreads > 0 && nrThreads < 50) {
-				zsys_set_io_threads(nrThreads);
-				logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "PSA_ZMQ: Using %d threads for ZMQ", nrThreads);
-				printf("PSA_ZMQ: Using %d threads for ZMQ\n", nrThreads);
-			}
-		}
-
-#ifdef BUILD_WITH_ZMQ_SECURITY
-		// Setup authenticator
-		zactor_t* auth = zactor_new (zauth, NULL);
-		zstr_sendx(auth, "VERBOSE", NULL);
-
-		// Load all public keys of subscribers into the application
-		// This step is done for authenticating subscribers
-		char curve_folder_path[MAX_KEY_FOLDER_PATH_LENGTH];
-		char* keys_bundle_dir = pubsub_getKeysBundleDir(context);
-		snprintf(curve_folder_path, MAX_KEY_FOLDER_PATH_LENGTH, "%s/META-INF/keys/subscriber/public", keys_bundle_dir);
-		zstr_sendx (auth, "CURVE", curve_folder_path, NULL);
-		free(keys_bundle_dir);
-
-		(*admin)->zmq_auth = auth;
-#endif
-
-	}
-
-	return status;
-}
-
-
-celix_status_t pubsubAdmin_destroy(pubsub_admin_pt admin)
-{
-	celix_status_t status = CELIX_SUCCESS;
-
-	free(admin->ipAddress);
-
-	celixThreadMutex_lock(&admin->pendingSubscriptionsLock);
-	hash_map_iterator_pt iter = hashMapIterator_create(admin->pendingSubscriptions);
-	while(hashMapIterator_hasNext(iter)){
-		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-		free((char*)hashMapEntry_getKey(entry));
-		arrayList_destroy((array_list_pt)hashMapEntry_getValue(entry));
-	}
-	hashMapIterator_destroy(iter);
-	hashMap_destroy(admin->pendingSubscriptions,false,false);
-	celixThreadMutex_unlock(&admin->pendingSubscriptionsLock);
-
-	celixThreadMutex_lock(&admin->subscriptionsLock);
-	hashMap_destroy(admin->subscriptions,false,false);
-	celixThreadMutex_unlock(&admin->subscriptionsLock);
-
-	celixThreadMutex_lock(&admin->localPublicationsLock);
-	hashMap_destroy(admin->localPublications,true,false);
-	celixThreadMutex_unlock(&admin->localPublicationsLock);
-
-	celixThreadMutex_lock(&admin->externalPublicationsLock);
-	iter = hashMapIterator_create(admin->externalPublications);
-	while(hashMapIterator_hasNext(iter)){
-		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-		free((char*)hashMapEntry_getKey(entry));
-		arrayList_destroy((array_list_pt)hashMapEntry_getValue(entry));
-	}
-	hashMapIterator_destroy(iter);
-	hashMap_destroy(admin->externalPublications,false,false);
-	celixThreadMutex_unlock(&admin->externalPublicationsLock);
-
-	celixThreadMutex_lock(&admin->serializerListLock);
-	arrayList_destroy(admin->serializerList);
-	celixThreadMutex_unlock(&admin->serializerListLock);
-
-	celixThreadMutex_lock(&admin->noSerializerPendingsLock);
-	arrayList_destroy(admin->noSerializerSubscriptions);
-	arrayList_destroy(admin->noSerializerPublications);
-	celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-
-
-	celixThreadMutex_lock(&admin->usedSerializersLock);
-
-	iter = hashMapIterator_create(admin->topicSubscriptionsPerSerializer);
-	while(hashMapIterator_hasNext(iter)){
-		arrayList_destroy((array_list_pt)hashMapIterator_nextValue(iter));
-	}
-	hashMapIterator_destroy(iter);
-	hashMap_destroy(admin->topicSubscriptionsPerSerializer,false,false);
-
-	iter = hashMapIterator_create(admin->topicPublicationsPerSerializer);
-	while(hashMapIterator_hasNext(iter)){
-		arrayList_destroy((array_list_pt)hashMapIterator_nextValue(iter));
-	}
-	hashMapIterator_destroy(iter);
-	hashMap_destroy(admin->topicPublicationsPerSerializer,false,false);
-
-	celixThreadMutex_unlock(&admin->usedSerializersLock);
-
-	celixThreadMutex_destroy(&admin->usedSerializersLock);
-	celixThreadMutex_destroy(&admin->serializerListLock);
-	celixThreadMutex_destroy(&admin->pendingSubscriptionsLock);
-
-	celixThreadMutexAttr_destroy(&admin->noSerializerPendingsAttr);
-	celixThreadMutex_destroy(&admin->noSerializerPendingsLock);
-
-	celixThreadMutexAttr_destroy(&admin->pendingSubscriptionsAttr);
-	celixThreadMutex_destroy(&admin->subscriptionsLock);
-
-	celixThreadMutex_destroy(&admin->localPublicationsLock);
-	celixThreadMutex_destroy(&admin->externalPublicationsLock);
-
-	logHelper_stop(admin->loghelper);
-
-	logHelper_destroy(&admin->loghelper);
-
-#ifdef BUILD_WITH_ZMQ_SECURITY
-	if (admin->zmq_auth != NULL){
-		zactor_destroy(&(admin->zmq_auth));
-	}
-#endif
-
-	free(admin);
-
-	return status;
-}
-
-static celix_status_t pubsubAdmin_addAnySubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&admin->subscriptionsLock);
-
-	topic_subscription_pt any_sub = hashMap_get(admin->subscriptions,PUBSUB_ANY_SUB_TOPIC);
-
-	if(any_sub==NULL){
-
-		int i;
-		pubsub_serializer_service_t *best_serializer = NULL;
-		if( (status=pubsubAdmin_getBestSerializer(admin, subEP, &best_serializer)) == CELIX_SUCCESS){
-			status = pubsub_topicSubscriptionCreate(admin->bundle_context, PUBSUB_SUBSCRIBER_SCOPE_DEFAULT, PUBSUB_ANY_SUB_TOPIC, best_serializer, &any_sub);
-		}
-		else{
-			printf("PSA_ZMQ: Cannot find a serializer for subscribing topic %s. Adding it to pending list.\n",subEP->topic);
-			celixThreadMutex_lock(&admin->noSerializerPendingsLock);
-			arrayList_add(admin->noSerializerSubscriptions,subEP);
-			celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-		}
-
-		if (status == CELIX_SUCCESS){
-
-			/* Connect all internal publishers */
-			celixThreadMutex_lock(&admin->localPublicationsLock);
-			hash_map_iterator_pt lp_iter =hashMapIterator_create(admin->localPublications);
-			while(hashMapIterator_hasNext(lp_iter)){
-				service_factory_pt factory = (service_factory_pt)hashMapIterator_nextValue(lp_iter);
-				topic_publication_pt topic_pubs = (topic_publication_pt)factory->handle;
-				array_list_pt topic_publishers = pubsub_topicPublicationGetPublisherList(topic_pubs);
-
-				if(topic_publishers!=NULL){
-					for(i=0;i<arrayList_size(topic_publishers);i++){
-						pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(topic_publishers,i);
-						if(pubEP->endpoint !=NULL){
-							status += pubsub_topicSubscriptionConnectPublisher(any_sub,pubEP->endpoint);
-						}
-					}
-					arrayList_destroy(topic_publishers);
-				}
-			}
-			hashMapIterator_destroy(lp_iter);
-			celixThreadMutex_unlock(&admin->localPublicationsLock);
-
-			/* Connect also all external publishers */
-			celixThreadMutex_lock(&admin->externalPublicationsLock);
-			hash_map_iterator_pt extp_iter =hashMapIterator_create(admin->externalPublications);
-			while(hashMapIterator_hasNext(extp_iter)){
-				array_list_pt ext_pub_list = (array_list_pt)hashMapIterator_nextValue(extp_iter);
-				if(ext_pub_list!=NULL){
-					for(i=0;i<arrayList_size(ext_pub_list);i++){
-						pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
-						if(pubEP->endpoint !=NULL){
-							status += pubsub_topicSubscriptionConnectPublisher(any_sub,pubEP->endpoint);
-						}
-					}
-				}
-			}
-			hashMapIterator_destroy(extp_iter);
-			celixThreadMutex_unlock(&admin->externalPublicationsLock);
-
-
-			pubsub_topicSubscriptionAddSubscriber(any_sub,subEP);
-
-			status += pubsub_topicSubscriptionStart(any_sub);
-
-		}
-
-		if (status == CELIX_SUCCESS){
-			hashMap_put(admin->subscriptions,strdup(PUBSUB_ANY_SUB_TOPIC),any_sub);
-			connectTopicPubSubToSerializer(admin, best_serializer, any_sub, false);
-		}
-
-	}
-
-	celixThreadMutex_unlock(&admin->subscriptionsLock);
-
-	return status;
-}
-
-celix_status_t pubsubAdmin_addSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
-	celix_status_t status = CELIX_SUCCESS;
-
-	printf("PSA_ZMQ: Received subscription [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n",subEP->frameworkUUID,subEP->serviceID,subEP->scope, subEP->topic);
-
-	if(strcmp(subEP->topic,PUBSUB_ANY_SUB_TOPIC)==0){
-		return pubsubAdmin_addAnySubscription(admin,subEP);
-	}
-
-	/* Check if we already know some publisher about this topic, otherwise let's put the subscription in the pending hashmap */
-	celixThreadMutex_lock(&admin->pendingSubscriptionsLock);
-	celixThreadMutex_lock(&admin->subscriptionsLock);
-	celixThreadMutex_lock(&admin->localPublicationsLock);
-	celixThreadMutex_lock(&admin->externalPublicationsLock);
-
-	char* scope_topic = createScopeTopicKey(subEP->scope, subEP->topic);
-
-	service_factory_pt factory = (service_factory_pt)hashMap_get(admin->localPublications,scope_topic);
-	array_list_pt ext_pub_list = (array_list_pt)hashMap_get(admin->externalPublications,scope_topic);
-
-	if(factory==NULL && ext_pub_list==NULL){ //No (local or external) publishers yet for this topic
-		pubsubAdmin_addSubscriptionToPendingList(admin,subEP);
-	}
-	else{
-		int i;
-		topic_subscription_pt subscription = hashMap_get(admin->subscriptions, scope_topic);
-
-		if(subscription == NULL) {
-			pubsub_serializer_service_t *best_serializer = NULL;
-			if( (status=pubsubAdmin_getBestSerializer(admin, subEP, &best_serializer)) == CELIX_SUCCESS){
-				status += pubsub_topicSubscriptionCreate(admin->bundle_context,subEP->scope, subEP->topic, best_serializer, &subscription);
-			}
-			else{
-				printf("PSA_ZMQ: Cannot find a serializer for subscribing topic %s. Adding it to pending list.\n",subEP->topic);
-				celixThreadMutex_lock(&admin->noSerializerPendingsLock);
-				arrayList_add(admin->noSerializerSubscriptions,subEP);
-				celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-			}
-
-			if (status==CELIX_SUCCESS){
-
-				/* Try to connect internal publishers */
-				if(factory!=NULL){
-					topic_publication_pt topic_pubs = (topic_publication_pt)factory->handle;
-					array_list_pt topic_publishers = pubsub_topicPublicationGetPublisherList(topic_pubs);
-
-					if(topic_publishers!=NULL){
-						for(i=0;i<arrayList_size(topic_publishers);i++){
-							pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(topic_publishers,i);
-							if(pubEP->endpoint !=NULL){
-								status += pubsub_topicSubscriptionConnectPublisher(subscription,pubEP->endpoint);
-							}
-						}
-						arrayList_destroy(topic_publishers);
-					}
-
-				}
-
-				/* Look also for external publishers */
-				if(ext_pub_list!=NULL){
-					for(i=0;i<arrayList_size(ext_pub_list);i++){
-						pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
-						if(pubEP->endpoint !=NULL){
-							status += pubsub_topicSubscriptionConnectPublisher(subscription,pubEP->endpoint);
-						}
-					}
-				}
-
-				pubsub_topicSubscriptionAddSubscriber(subscription,subEP);
-
-				status += pubsub_topicSubscriptionStart(subscription);
-
-			}
-
-			if(status==CELIX_SUCCESS){
-
-				hashMap_put(admin->subscriptions,strdup(scope_topic),subscription);
-
-				connectTopicPubSubToSerializer(admin, best_serializer, subscription, false);
-			}
-		}
-
-		if (status == CELIX_SUCCESS){
-			pubsub_topicIncreaseNrSubscribers(subscription);
-		}
-	}
-
-	free(scope_topic);
-	celixThreadMutex_unlock(&admin->externalPublicationsLock);
-	celixThreadMutex_unlock(&admin->localPublicationsLock);
-	celixThreadMutex_unlock(&admin->subscriptionsLock);
-	celixThreadMutex_unlock(&admin->pendingSubscriptionsLock);
-
-	return status;
-
-}
-
-celix_status_t pubsubAdmin_removeSubscription(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
-	celix_status_t status = CELIX_SUCCESS;
-
-	printf("PSA_ZMQ: Removing subscription [FWUUID=%s bundleID=%ld topic=%s]\n",subEP->frameworkUUID,subEP->serviceID,subEP->topic);
-
-	char* scope_topic = createScopeTopicKey(subEP->scope, subEP->topic);
-
-	celixThreadMutex_lock(&admin->subscriptionsLock);
-	topic_subscription_pt sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,scope_topic);
-	if(sub!=NULL){
-		pubsub_topicDecreaseNrSubscribers(sub);
-		if(pubsub_topicGetNrSubscribers(sub) == 0) {
-			status = pubsub_topicSubscriptionRemoveSubscriber(sub,subEP);
-		}
-	}
-	celixThreadMutex_unlock(&admin->subscriptionsLock);
-
-	if(sub==NULL){
-		/* Maybe the endpoint was pending */
-		celixThreadMutex_lock(&admin->noSerializerPendingsLock);
-		if(!arrayList_removeElement(admin->noSerializerSubscriptions, subEP)){
-			status = CELIX_ILLEGAL_STATE;
-		}
-		celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-	}
-
-	free(scope_topic);
-
-
-
-	return status;
-
-}
-
-celix_status_t pubsubAdmin_addPublication(pubsub_admin_pt admin, pubsub_endpoint_pt pubEP) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	printf("PSA_ZMQ: Received publication [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n", pubEP->frameworkUUID, pubEP->serviceID, pubEP->scope, pubEP->topic);
-
-	const char* fwUUID = NULL;
-
-	bundleContext_getProperty(admin->bundle_context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &fwUUID);
-	if (fwUUID == NULL) {
-		printf("PSA_ZMQ: Cannot retrieve fwUUID.\n");
-		return CELIX_INVALID_BUNDLE_CONTEXT;
-	}
-
-	char *scope_topic = createScopeTopicKey(pubEP->scope, pubEP->topic);
-
-	if ((strcmp(pubEP->frameworkUUID, fwUUID) == 0) && (pubEP->endpoint == NULL)) {
-
-		celixThreadMutex_lock(&admin->localPublicationsLock);
-
-		service_factory_pt factory = (service_factory_pt) hashMap_get(admin->localPublications, scope_topic);
-
-		if (factory == NULL) {
-			topic_publication_pt pub = NULL;
-			pubsub_serializer_service_t *best_serializer = NULL;
-			if( (status=pubsubAdmin_getBestSerializer(admin, pubEP, &best_serializer)) == CELIX_SUCCESS){
-				status = pubsub_topicPublicationCreate(admin->bundle_context, pubEP, best_serializer, admin->ipAddress, admin->basePort, admin->maxPort, &pub);
-			}
-			else{
-				printf("PSA_ZMQ: Cannot find a serializer for publishing topic %s. Adding it to pending list.\n", pubEP->topic);
-				celixThreadMutex_lock(&admin->noSerializerPendingsLock);
-				arrayList_add(admin->noSerializerPublications,pubEP);
-				celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-			}
-
-			if (status == CELIX_SUCCESS) {
-				status = pubsub_topicPublicationStart(admin->bundle_context, pub, &factory);
-				if (status == CELIX_SUCCESS && factory != NULL) {
-					hashMap_put(admin->localPublications, strdup(scope_topic), factory);
-					connectTopicPubSubToSerializer(admin, best_serializer, pub, true);
-				}
-			} else {
-				printf("PSA_ZMQ: Cannot create a topicPublication for scope=%s, topic=%s (bundle %ld).\n", pubEP->scope, pubEP->topic, pubEP->serviceID);
-			}
-		} else {
-			//just add the new EP to the list
-			topic_publication_pt pub = (topic_publication_pt) factory->handle;
-			pubsub_topicPublicationAddPublisherEP(pub, pubEP);
-		}
-
-		celixThreadMutex_unlock(&admin->localPublicationsLock);
-	}
-	else{
-
-		celixThreadMutex_lock(&admin->externalPublicationsLock);
-		array_list_pt ext_pub_list = (array_list_pt) hashMap_get(admin->externalPublications, scope_topic);
-		if (ext_pub_list == NULL) {
-			arrayList_create(&ext_pub_list);
-			hashMap_put(admin->externalPublications, strdup(scope_topic), ext_pub_list);
-		}
-
-		arrayList_add(ext_pub_list, pubEP);
-
-		celixThreadMutex_unlock(&admin->externalPublicationsLock);
-	}
-
-	/* Re-evaluate the pending subscriptions */
-	celixThreadMutex_lock(&admin->pendingSubscriptionsLock);
-
-	hash_map_entry_pt pendingSub = hashMap_getEntry(admin->pendingSubscriptions, scope_topic);
-	if (pendingSub != NULL) { //There were pending subscription for the just published topic. Let's connect them.
-		char* topic = (char*) hashMapEntry_getKey(pendingSub);
-		array_list_pt pendingSubList = (array_list_pt) hashMapEntry_getValue(pendingSub);
-		int i;
-		for (i = 0; i < arrayList_size(pendingSubList); i++) {
-			pubsub_endpoint_pt subEP = (pubsub_endpoint_pt) arrayList_get(pendingSubList, i);
-			pubsubAdmin_addSubscription(admin, subEP);
-		}
-		hashMap_remove(admin->pendingSubscriptions, scope_topic);
-		arrayList_clear(pendingSubList);
-		arrayList_destroy(pendingSubList);
-		free(topic);
-	}
-
-	celixThreadMutex_unlock(&admin->pendingSubscriptionsLock);
-
-	/* Connect the new publisher to the subscription for his topic, if there is any */
-	celixThreadMutex_lock(&admin->subscriptionsLock);
-
-	topic_subscription_pt sub = (topic_subscription_pt) hashMap_get(admin->subscriptions, scope_topic);
-	if (sub != NULL && pubEP->endpoint != NULL) {
-		pubsub_topicSubscriptionAddConnectPublisherToPendingList(sub, pubEP->endpoint);
-	}
-
-	/* And check also for ANY subscription */
-	topic_subscription_pt any_sub = (topic_subscription_pt) hashMap_get(admin->subscriptions, PUBSUB_ANY_SUB_TOPIC);
-	if (any_sub != NULL && pubEP->endpoint != NULL) {
-		pubsub_topicSubscriptionAddConnectPublisherToPendingList(any_sub, pubEP->endpoint);
-	}
-
-	free(scope_topic);
-
-	celixThreadMutex_unlock(&admin->subscriptionsLock);
-
-	return status;
-
-}
-
-celix_status_t pubsubAdmin_removePublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP){
-	celix_status_t status = CELIX_SUCCESS;
-	int count = 0;
-
-	printf("PSA_ZMQ: Removing publication [FWUUID=%s bundleID=%ld topic=%s]\n",pubEP->frameworkUUID,pubEP->serviceID,pubEP->topic);
-
-	const char* fwUUID = NULL;
-
-	bundleContext_getProperty(admin->bundle_context,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID);
-	if(fwUUID==NULL){
-		printf("PSA_ZMQ: Cannot retrieve fwUUID.\n");
-		return CELIX_INVALID_BUNDLE_CONTEXT;
-	}
-	char *scope_topic = createScopeTopicKey(pubEP->scope, pubEP->topic);
-
-	if(strcmp(pubEP->frameworkUUID,fwUUID)==0){
-
-		celixThreadMutex_lock(&admin->localPublicationsLock);
-		service_factory_pt factory = (service_factory_pt)hashMap_get(admin->localPublications,scope_topic);
-		if(factory!=NULL){
-			topic_publication_pt pub = (topic_publication_pt)factory->handle;
-			pubsub_topicPublicationRemovePublisherEP(pub,pubEP);
-		}
-		celixThreadMutex_unlock(&admin->localPublicationsLock);
-
-		if(factory==NULL){
-			/* Maybe the endpoint was pending */
-			celixThreadMutex_lock(&admin->noSerializerPendingsLock);
-			if(!arrayList_removeElement(admin->noSerializerPublications, pubEP)){
-				status = CELIX_ILLEGAL_STATE;
-			}
-			celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-		}
-	}
-	else{
-
-		celixThreadMutex_lock(&admin->externalPublicationsLock);
-		array_list_pt ext_pub_list = (array_list_pt)hashMap_get(admin->externalPublications,scope_topic);
-		if(ext_pub_list!=NULL){
-			int i;
-			bool found = false;
-			for(i=0;!found && i<arrayList_size(ext_pub_list);i++){
-				pubsub_endpoint_pt p  = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
-				found = pubsubEndpoint_equals(pubEP,p);
-				if (found){
-					arrayList_remove(ext_pub_list,i);
-				}
-			}
-			// Check if there are more publishers on the same endpoint (happens when 1 celix-instance with multiple bundles publish in same topic)
-			for(i=0; i<arrayList_size(ext_pub_list);i++) {
-				pubsub_endpoint_pt p  = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i);
-				if (strcmp(pubEP->endpoint,p->endpoint) == 0) {
-					count++;
-				}
-			}
-
-			if(arrayList_size(ext_pub_list)==0){
-				hash_map_entry_pt entry = hashMap_getEntry(admin->externalPublications,scope_topic);
-				char* topic = (char*)hashMapEntry_getKey(entry);
-				array_list_pt list = (array_list_pt)hashMapEntry_getValue(entry);
-				hashMap_remove(admin->externalPublications,topic);
-				arrayList_destroy(list);
-				free(topic);
-			}
-		}
-
-		celixThreadMutex_unlock(&admin->externalPublicationsLock);
-	}
-
-	/* Check if this publisher was connected to one of our subscribers*/
-	celixThreadMutex_lock(&admin->subscriptionsLock);
-
-	topic_subscription_pt sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,scope_topic);
-	if(sub!=NULL && pubEP->endpoint!=NULL && count == 0){
-		pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(sub,pubEP->endpoint);
-	}
-
-	/* And check also for ANY subscription */
-	topic_subscription_pt any_sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,PUBSUB_ANY_SUB_TOPIC);
-	if(any_sub!=NULL && pubEP->endpoint!=NULL && count == 0){
-		pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(any_sub,pubEP->endpoint);
-	}
-
-	free(scope_topic);
-	celixThreadMutex_unlock(&admin->subscriptionsLock);
-
-	return status;
-
-}
-
-celix_status_t pubsubAdmin_closeAllPublications(pubsub_admin_pt admin, char *scope, char* topic){
-	celix_status_t status = CELIX_SUCCESS;
-
-	printf("PSA_ZMQ: Closing all publications\n");
-
-	celixThreadMutex_lock(&admin->localPublicationsLock);
-	char *scope_topic = createScopeTopicKey(scope, topic);
-	hash_map_entry_pt pubsvc_entry = (hash_map_entry_pt)hashMap_getEntry(admin->localPublications,scope_topic);
-	if(pubsvc_entry!=NULL){
-		char* key = (char*)hashMapEntry_getKey(pubsvc_entry);
-		service_factory_pt factory= (service_factory_pt)hashMapEntry_getValue(pubsvc_entry);
-		topic_publication_pt pub = (topic_publication_pt)factory->handle;
-		status += pubsub_topicPublicationStop(pub);
-		disconnectTopicPubSubFromSerializer(admin, pub, true);
-		status += pubsub_topicPublicationDestroy(pub);
-		hashMap_remove(admin->localPublications,scope_topic);
-		free(key);
-		free(factory);
-	}
-	free(scope_topic);
-	celixThreadMutex_unlock(&admin->localPublicationsLock);
-
-	return status;
-
-}
-
-celix_status_t pubsubAdmin_closeAllSubscriptions(pubsub_admin_pt admin,char* scope,char* topic){
-	celix_status_t status = CELIX_SUCCESS;
-
-	printf("PSA_ZMQ: Closing all subscriptions\n");
-
-	celixThreadMutex_lock(&admin->subscriptionsLock);
-	char *scope_topic = createScopeTopicKey(scope, topic);
-	hash_map_entry_pt sub_entry = (hash_map_entry_pt)hashMap_getEntry(admin->subscriptions,scope_topic);
-	if(sub_entry!=NULL){
-		char* topic = (char*)hashMapEntry_getKey(sub_entry);
-
-		topic_subscription_pt ts = (topic_subscription_pt)hashMapEntry_getValue(sub_entry);
-		status += pubsub_topicSubscriptionStop(ts);
-		disconnectTopicPubSubFromSerializer(admin, ts, false);
-		status += pubsub_topicSubscriptionDestroy(ts);
-		hashMap_remove(admin->subscriptions,scope_topic);
-		free(topic);
-
-	}
-	free(scope_topic);
-	celixThreadMutex_unlock(&admin->subscriptionsLock);
-
-	return status;
-
-}
-
-
-#ifndef ANDROID
-static celix_status_t pubsubAdmin_getIpAdress(const char* interface, char** ip) {
-	celix_status_t status = CELIX_BUNDLE_EXCEPTION;
-
-	struct ifaddrs *ifaddr, *ifa;
-	char host[NI_MAXHOST];
-
-	if (getifaddrs(&ifaddr) != -1)
-	{
-		for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next)
-		{
-			if (ifa->ifa_addr == NULL)
-				continue;
-
-			if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) {
-				if (interface == NULL) {
-					*ip = strdup(host);
-					status = CELIX_SUCCESS;
-				}
-				else if (strcmp(ifa->ifa_name, interface) == 0) {
-					*ip = strdup(host);
-					status = CELIX_SUCCESS;
-				}
-			}
-		}
-
-		freeifaddrs(ifaddr);
-	}
-
-	return status;
-}
-#endif
-
-static celix_status_t pubsubAdmin_addSubscriptionToPendingList(pubsub_admin_pt admin,pubsub_endpoint_pt subEP){
-	celix_status_t status = CELIX_SUCCESS;
-	char* scope_topic = createScopeTopicKey(subEP->scope, subEP->topic);
-	array_list_pt pendingListPerTopic = hashMap_get(admin->pendingSubscriptions,scope_topic);
-	if(pendingListPerTopic==NULL){
-		arrayList_create(&pendingListPerTopic);
-		hashMap_put(admin->pendingSubscriptions,strdup(scope_topic),pendingListPerTopic);
-	}
-	arrayList_add(pendingListPerTopic,subEP);
-	free(scope_topic);
-	return status;
-}
-
-celix_status_t pubsubAdmin_serializerAdded(void * handle, service_reference_pt reference, void * service){
-	/* Assumption: serializers are all available at startup.
-	 * If a new (possibly better) serializer is installed and started, already created topic_publications/subscriptions will not be destroyed and recreated */
-
-	celix_status_t status = CELIX_SUCCESS;
-	int i=0;
-
-	const char *serType = NULL;
-	serviceReference_getProperty(reference, PUBSUB_SERIALIZER_TYPE_KEY,&serType);
-	if(serType == NULL){
-		printf("Serializer serviceReference %p has no pubsub_serializer.type property specified\n",reference);
-		return CELIX_SERVICE_EXCEPTION;
-	}
-
-	pubsub_admin_pt admin = (pubsub_admin_pt)handle;
-	celixThreadMutex_lock(&admin->serializerListLock);
-	arrayList_add(admin->serializerList, reference);
-	celixThreadMutex_unlock(&admin->serializerListLock);
-
-	/* Now let's re-evaluate the pending */
-	celixThreadMutex_lock(&admin->noSerializerPendingsLock);
-
-	for(i=0;i<arrayList_size(admin->noSerializerSubscriptions);i++){
-		pubsub_endpoint_pt ep = (pubsub_endpoint_pt)arrayList_get(admin->noSerializerSubscriptions,i);
-		pubsub_serializer_service_t *best_serializer = NULL;
-		pubsubAdmin_getBestSerializer(admin, ep, &best_serializer);
-		if(best_serializer != NULL){ /* Finally we have a valid serializer! */
-			pubsubAdmin_addSubscription(admin, ep);
-		}
-	}
-
-	for(i=0;i<arrayList_size(admin->noSerializerPublications);i++){
-		pubsub_endpoint_pt ep = (pubsub_endpoint_pt)arrayList_get(admin->noSerializerPublications,i);
-		pubsub_serializer_service_t *best_serializer = NULL;
-		pubsubAdmin_getBestSerializer(admin, ep, &best_serializer);
-		if(best_serializer != NULL){ /* Finally we have a valid serializer! */
-			pubsubAdmin_addPublication(admin, ep);
-		}
-	}
-
-	celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-
-	printf("PSA_ZMQ: %s serializer added\n",serType);
-
-	return status;
-}
-
-celix_status_t pubsubAdmin_serializerRemoved(void * handle, service_reference_pt reference, void * service){
-
-	pubsub_admin_pt admin = (pubsub_admin_pt)handle;
-	int i=0, j=0;
-	const char *serType = NULL;
-
-	serviceReference_getProperty(reference, PUBSUB_SERIALIZER_TYPE_KEY,&serType);
-	if(serType == NULL){
-		printf("Serializer serviceReference %p has no pubsub_serializer.type property specified\n",reference);
-		return CELIX_SERVICE_EXCEPTION;
-	}
-
-	celixThreadMutex_lock(&admin->serializerListLock);
-	/* Remove the serializer from the list */
-	arrayList_removeElement(admin->serializerList, reference);
-	celixThreadMutex_unlock(&admin->serializerListLock);
-
-
-	celixThreadMutex_lock(&admin->usedSerializersLock);
-	array_list_pt topicPubList = (array_list_pt)hashMap_remove(admin->topicPublicationsPerSerializer, service);
-	array_list_pt topicSubList = (array_list_pt)hashMap_remove(admin->topicSubscriptionsPerSerializer, service);
-	celixThreadMutex_unlock(&admin->usedSerializersLock);
-
-	/* Now destroy the topicPublications, but first put back the pubsub_endpoints back to the noSerializer pending list */
-	if(topicPubList!=NULL){
-		for(i=0;i<arrayList_size(topicPubList);i++){
-			topic_publication_pt topicPub = (topic_publication_pt)arrayList_get(topicPubList,i);
-			/* Stop the topic publication */
-			pubsub_topicPublicationStop(topicPub);
-			/* Get the endpoints that are going to be orphan */
-			array_list_pt pubList = pubsub_topicPublicationGetPublisherList(topicPub);
-			for(j=0;j<arrayList_size(pubList);j++){
-				pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pubList,j);
-				/* Remove the publication */
-				pubsubAdmin_removePublication(admin, pubEP);
-				/* Reset the endpoint field, so that will be recreated from scratch when a new serializer will be found */
-				if(pubEP->endpoint!=NULL){
-					free(pubEP->endpoint);
-					pubEP->endpoint = NULL;
-				}
-				/* Add the orphan endpoint to the noSerializer pending list */
-				celixThreadMutex_lock(&admin->noSerializerPendingsLock);
-				arrayList_add(admin->noSerializerPublications,pubEP);
-				celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-			}
-			arrayList_destroy(pubList);
-
-			/* Cleanup also the localPublications hashmap*/
-			celixThreadMutex_lock(&admin->localPublicationsLock);
-			hash_map_iterator_pt iter = hashMapIterator_create(admin->localPublications);
-			char *key = NULL;
-			service_factory_pt factory = NULL;
-			while(hashMapIterator_hasNext(iter)){
-				hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-				factory = (service_factory_pt)hashMapEntry_getValue(entry);
-				topic_publication_pt pub = (topic_publication_pt)factory->handle;
-				if(pub==topicPub){
-					key = (char*)hashMapEntry_getKey(entry);
-					break;
-				}
-			}
-			hashMapIterator_destroy(iter);
-			if(key!=NULL){
-				hashMap_remove(admin->localPublications, key);
-				free(factory);
-				free(key);
-			}
-			celixThreadMutex_unlock(&admin->localPublicationsLock);
-
-			/* Finally destroy the topicPublication */
-			pubsub_topicPublicationDestroy(topicPub);
-		}
-		arrayList_destroy(topicPubList);
-	}
-
-	/* Now destroy the topicSubscriptions, but first put back the pubsub_endpoints back to the noSerializer pending list */
-	if(topicSubList!=NULL){
-		for(i=0;i<arrayList_size(topicSubList);i++){
-			topic_subscription_pt topicSub = (topic_subscription_pt)arrayList_get(topicSubList,i);
-			/* Stop the topic subscription */
-			pubsub_topicSubscriptionStop(topicSub);
-			/* Get the endpoints that are going to be orphan */
-			array_list_pt subList = pubsub_topicSubscriptionGetSubscribersList(topicSub);
-			for(j=0;j<arrayList_size(subList);j++){
-				pubsub_endpoint_pt subEP = (pubsub_endpoint_pt)arrayList_get(subList,j);
-				/* Remove the subscription */
-				pubsubAdmin_removeSubscription(admin, subEP);
-				/* Reset the endpoint field, so that will be recreated from scratch when a new serializer will be found */
-				if(subEP->endpoint!=NULL){
-					free(subEP->endpoint);
-					subEP->endpoint = NULL;
-				}
-				/* Add the orphan endpoint to the noSerializer pending list */
-				celixThreadMutex_lock(&admin->noSerializerPendingsLock);
-				arrayList_add(admin->noSerializerSubscriptions,subEP);
-				celixThreadMutex_unlock(&admin->noSerializerPendingsLock);
-			}
-
-			/* Cleanup also the subscriptions hashmap*/
-			celixThreadMutex_lock(&admin->subscriptionsLock);
-			hash_map_iterator_pt iter = hashMapIterator_create(admin->subscriptions);
-			char *key = NULL;
-			while(hashMapIterator_hasNext(iter)){
-				hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-				topic_subscription_pt sub = (topic_subscription_pt)hashMapEntry_getValue(entry);
-				if(sub==topicSub){
-					key = (char*)hashMapEntry_getKey(entry);
-					break;
-				}
-			}
-			hashMapIterator_destroy(iter);
-			if(key!=NULL){
-				hashMap_remove(admin->subscriptions, key);
-				free(key);
-			}
-			celixThreadMutex_unlock(&admin->subscriptionsLock);
-
-			/* Finally destroy the topicSubscription */
-			pubsub_topicSubscriptionDestroy(topicSub);
-		}
-		arrayList_destroy(topicSubList);
-	}
-
-
-
-	printf("PSA_ZMQ: %s serializer removed\n",serType);
-
-
-	return CELIX_SUCCESS;
-}
-
-celix_status_t pubsubAdmin_matchEndpoint(pubsub_admin_pt admin, pubsub_endpoint_pt endpoint, double* score){
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&admin->serializerListLock);
-	status = pubsub_admin_match(endpoint->topic_props,PUBSUB_ADMIN_TYPE,admin->serializerList,score);
-	celixThreadMutex_unlock(&admin->serializerListLock);
-
-	return status;
-}
-
-/* This one recall the same logic as in the match function */
-static celix_status_t pubsubAdmin_getBestSerializer(pubsub_admin_pt admin,pubsub_endpoint_pt ep, pubsub_serializer_service_t **serSvc){
-
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&admin->serializerListLock);
-	status = pubsub_admin_get_best_serializer(ep->topic_props, admin->serializerList, serSvc);
-	celixThreadMutex_unlock(&admin->serializerListLock);
-
-	return status;
-
-}
-
-static void connectTopicPubSubToSerializer(pubsub_admin_pt admin,pubsub_serializer_service_t *serializer,void *topicPubSub,bool isPublication){
-
-	celixThreadMutex_lock(&admin->usedSerializersLock);
-
-	hash_map_pt map = isPublication?admin->topicPublicationsPerSerializer:admin->topicSubscriptionsPerSerializer;
-	array_list_pt list = (array_list_pt)hashMap_get(map,serializer);
-	if(list==NULL){
-		arrayList_create(&list);
-		hashMap_put(map,serializer,list);
-	}
-	arrayList_add(list,topicPubSub);
-
-	celixThreadMutex_unlock(&admin->usedSerializersLock);
-
-}
-
-static void disconnectTopicPubSubFromSerializer(pubsub_admin_pt admin,void *topicPubSub,bool isPublication){
-
-	celixThreadMutex_lock(&admin->usedSerializersLock);
-
-	hash_map_pt map = isPublication?admin->topicPublicationsPerSerializer:admin->topicSubscriptionsPerSerializer;
-	hash_map_iterator_pt iter = hashMapIterator_create(map);
-	while(hashMapIterator_hasNext(iter)){
-		array_list_pt list = (array_list_pt)hashMapIterator_nextValue(iter);
-		if(arrayList_removeElement(list, topicPubSub)){ //Found it!
-			break;
-		}
-	}
-	hashMapIterator_destroy(iter);
-
-	celixThreadMutex_unlock(&admin->usedSerializersLock);
-
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_zmq/private/src/topic_publication.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/private/src/topic_publication.c b/pubsub/pubsub_admin_zmq/private/src/topic_publication.c
deleted file mode 100644
index e405866..0000000
--- a/pubsub/pubsub_admin_zmq/private/src/topic_publication.c
+++ /dev/null
@@ -1,630 +0,0 @@
-/**
- *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.
- */
-
-#include <czmq.h>
-/* The following undefs prevent the collision between:
- * - sys/syslog.h (which is included within czmq)
- * - celix/dfi/dfi_log_util.h
- */
-#undef LOG_DEBUG
-#undef LOG_WARNING
-#undef LOG_INFO
-#undef LOG_WARNING
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "array_list.h"
-#include "celixbool.h"
-#include "service_registration.h"
-#include "utils.h"
-#include "service_factory.h"
-#include "version.h"
-
-#include "pubsub_common.h"
-#include "pubsub_utils.h"
-#include "publisher.h"
-
-#include "topic_publication.h"
-
-#include "pubsub_serializer.h"
-
-#ifdef BUILD_WITH_ZMQ_SECURITY
-	#include "zmq_crypto.h"
-
-	#define MAX_CERT_PATH_LENGTH 512
-#endif
-
-#define EP_ADDRESS_LEN		32
-#define ZMQ_BIND_MAX_RETRY	5
-
-#define FIRST_SEND_DELAY	2
-
-struct topic_publication {
-	zsock_t* zmq_socket;
-	celix_thread_mutex_t socket_lock; //Protects zmq_socket access
-	zcert_t * zmq_cert;
-	char* endpoint;
-	service_registration_pt svcFactoryReg;
-	array_list_pt pub_ep_list; //List<pubsub_endpoint>
-	hash_map_pt boundServices; //<bundle_pt,bound_service>
-	pubsub_serializer_service_t *serializer;
-	celix_thread_mutex_t tp_lock;
-};
-
-typedef struct publish_bundle_bound_service {
-	topic_publication_pt parent;
-	pubsub_publisher_t service;
-	bundle_pt bundle;
-	char *topic;
-	hash_map_pt msgTypes;
-	unsigned short getCount;
-	celix_thread_mutex_t mp_lock; //Protects publish_bundle_bound_service data structure
-	bool mp_send_in_progress;
-	array_list_pt mp_parts;
-}* publish_bundle_bound_service_pt;
-
-/* Note: correct locking order is
- * 1. tp_lock
- * 2. mp_lock
- * 3. socket_lock
- *
- * tp_lock and socket_lock are independent.
- */
-
-typedef struct pubsub_msg{
-	pubsub_msg_header_pt header;
-	char* payload;
-	int payloadSize;
-}* pubsub_msg_pt;
-
-static unsigned int rand_range(unsigned int min, unsigned int max);
-
-static celix_status_t pubsub_topicPublicationGetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service);
-static celix_status_t pubsub_topicPublicationUngetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service);
-
-static publish_bundle_bound_service_pt pubsub_createPublishBundleBoundService(topic_publication_pt tp,bundle_pt bundle);
-static void pubsub_destroyPublishBundleBoundService(publish_bundle_bound_service_pt boundSvc);
-
-static int pubsub_topicPublicationSend(void* handle,unsigned int msgTypeId, const void *msg);
-static int pubsub_topicPublicationSendMultipart(void *handle, unsigned int msgTypeId, const void *inMsg, int flags);
-static int pubsub_localMsgTypeIdForUUID(void* handle, const char* msgType, unsigned int* msgTypeId);
-
-static void delay_first_send_for_late_joiners(void);
-
-celix_status_t pubsub_topicPublicationCreate(bundle_context_pt bundle_context, pubsub_endpoint_pt pubEP, pubsub_serializer_service_t *best_serializer, char* bindIP, unsigned int basePort, unsigned int maxPort, topic_publication_pt *out){
-	celix_status_t status = CELIX_SUCCESS;
-
-#ifdef BUILD_WITH_ZMQ_SECURITY
-	char* secure_topics = NULL;
-	bundleContext_getProperty(bundle_context, "SECURE_TOPICS", (const char **) &secure_topics);
-
-	if (secure_topics){
-		array_list_pt secure_topics_list = pubsub_getTopicsFromString(secure_topics);
-
-		int i;
-		int secure_topics_size = arrayList_size(secure_topics_list);
-		for (i = 0; i < secure_topics_size; i++){
-			char* top = arrayList_get(secure_topics_list, i);
-			if (strcmp(pubEP->topic, top) == 0){
-				printf("PSA_ZMQ_TP: Secure topic: '%s'\n", top);
-				pubEP->is_secure = true;
-			}
-			free(top);
-			top = NULL;
-		}
-
-		arrayList_destroy(secure_topics_list);
-	}
-
-	zcert_t* pub_cert = NULL;
-	if (pubEP->is_secure){
-		char* keys_bundle_dir = pubsub_getKeysBundleDir(bundle_context);
-		if (keys_bundle_dir == NULL){
-			return CELIX_SERVICE_EXCEPTION;
-		}
-
-		const char* keys_file_path = NULL;
-		const char* keys_file_name = NULL;
-		bundleContext_getProperty(bundle_context, PROPERTY_KEYS_FILE_PATH, &keys_file_path);
-		bundleContext_getProperty(bundle_context, PROPERTY_KEYS_FILE_NAME, &keys_file_name);
-
-		char cert_path[MAX_CERT_PATH_LENGTH];
-
-		//certificate path ".cache/bundle{id}/version0.0/./META-INF/keys/publisher/private/pub_{topic}.key"
-		snprintf(cert_path, MAX_CERT_PATH_LENGTH, "%s/META-INF/keys/publisher/private/pub_%s.key.enc", keys_bundle_dir, pubEP->topic);
-		free(keys_bundle_dir);
-		printf("PSA_ZMQ_TP: Loading key '%s'\n", cert_path);
-
-		pub_cert = get_zcert_from_encoded_file((char *) keys_file_path, (char *) keys_file_name, cert_path);
-		if (pub_cert == NULL){
-			printf("PSA_ZMQ_TP: Cannot load key '%s'\n", cert_path);
-			printf("PSA_ZMQ_TP: Topic '%s' NOT SECURED !\n", pubEP->topic);
-			pubEP->is_secure = false;
-		}
-	}
-#endif
-
-	zsock_t* socket = zsock_new (ZMQ_PUB);
-	if(socket==NULL){
-		#ifdef BUILD_WITH_ZMQ_SECURITY
-			if (pubEP->is_secure){
-				zcert_destroy(&pub_cert);
-			}
-		#endif
-
-        perror("Error for zmq_socket");
-		return CELIX_SERVICE_EXCEPTION;
-	}
-#ifdef BUILD_WITH_ZMQ_SECURITY
-	if (pubEP->is_secure){
-		zcert_apply (pub_cert, socket); // apply certificate to socket
-		zsock_set_curve_server (socket, true); // setup the publisher's socket to use the curve functions
-	}
-#endif
-
-	int rv = -1, retry=0;
-	char* ep = malloc(EP_ADDRESS_LEN);
-    char bindAddress[EP_ADDRESS_LEN];
-
-	while(rv==-1 && retry<ZMQ_BIND_MAX_RETRY){
-		/* Randomized part due to same bundle publishing on different topics */
-		unsigned int port = rand_range(basePort,maxPort);
-		memset(ep,0,EP_ADDRESS_LEN);
-        memset(bindAddress, 0, EP_ADDRESS_LEN);
-
-		snprintf(ep,EP_ADDRESS_LEN,"tcp://%s:%u",bindIP,port);
-        snprintf(bindAddress, EP_ADDRESS_LEN, "tcp://0.0.0.0:%u", port); //NOTE using a different bind addres than endpoint address
-		rv = zsock_bind (socket, "%s", bindAddress);
-        if (rv == -1) {
-            perror("Error for zmq_bind");
-        }
-		retry++;
-	}
-
-	if(rv == -1){
-		free(ep);
-		return CELIX_SERVICE_EXCEPTION;
-	}
-
-	/* ZMQ stuffs are all fine at this point. Let's create and initialize the structure */
-
-	topic_publication_pt pub = calloc(1,sizeof(*pub));
-
-	arrayList_create(&(pub->pub_ep_list));
-	pub->boundServices = hashMap_create(NULL,NULL,NULL,NULL);
-	celixThreadMutex_create(&(pub->tp_lock),NULL);
-
-	pub->endpoint = ep;
-	pub->zmq_socket = socket;
-	pub->serializer = best_serializer;
-
-	celixThreadMutex_create(&(pub->socket_lock),NULL);
-
-#ifdef BUILD_WITH_ZMQ_SECURITY
-	if (pubEP->is_secure){
-		pub->zmq_cert = pub_cert;
-	}
-#endif
-
-	pubsub_topicPublicationAddPublisherEP(pub,pubEP);
-
-	*out = pub;
-
-	return status;
-}
-
-celix_status_t pubsub_topicPublicationDestroy(topic_publication_pt pub){
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&(pub->tp_lock));
-
-	free(pub->endpoint);
-	arrayList_destroy(pub->pub_ep_list);
-
-	hash_map_iterator_pt iter = hashMapIterator_create(pub->boundServices);
-	while(hashMapIterator_hasNext(iter)){
-		publish_bundle_bound_service_pt bound = hashMapIterator_nextValue(iter);
-		pubsub_destroyPublishBundleBoundService(bound);
-	}
-	hashMapIterator_destroy(iter);
-	hashMap_destroy(pub->boundServices,false,false);
-
-	pub->svcFactoryReg = NULL;
-	pub->serializer = NULL;
-#ifdef BUILD_WITH_ZMQ_SECURITY
-	zcert_destroy(&(pub->zmq_cert));
-#endif
-
-	celixThreadMutex_unlock(&(pub->tp_lock));
-
-	celixThreadMutex_destroy(&(pub->tp_lock));
-
-	celixThreadMutex_lock(&(pub->socket_lock));
-	zsock_destroy(&(pub->zmq_socket));
-	celixThreadMutex_unlock(&(pub->socket_lock));
-
-	celixThreadMutex_destroy(&(pub->socket_lock));
-
-	free(pub);
-
-	return status;
-}
-
-celix_status_t pubsub_topicPublicationStart(bundle_context_pt bundle_context,topic_publication_pt pub,service_factory_pt* svcFactory){
-	celix_status_t status = CELIX_SUCCESS;
-
-	/* Let's register the new service */
-
-	pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(pub->pub_ep_list,0);
-
-	if(pubEP!=NULL){
-		service_factory_pt factory = calloc(1, sizeof(*factory));
-		factory->handle = pub;
-		factory->getService = pubsub_topicPublicationGetService;
-		factory->ungetService = pubsub_topicPublicationUngetService;
-
-		properties_pt props = properties_create();
-		properties_set(props,PUBSUB_PUBLISHER_TOPIC,pubEP->topic);
-		properties_set(props,PUBSUB_PUBLISHER_SCOPE,pubEP->scope);
-		properties_set(props,"service.version", PUBSUB_PUBLISHER_SERVICE_VERSION);
-
-		status = bundleContext_registerServiceFactory(bundle_context,PUBSUB_PUBLISHER_SERVICE_NAME,factory,props,&(pub->svcFactoryReg));
-
-		if(status != CELIX_SUCCESS){
-			properties_destroy(props);
-			printf("PSA_ZMQ_PSA_ZMQ_TP: Cannot register ServiceFactory for topic %s (bundle %ld).\n",pubEP->topic,pubEP->serviceID);
-		}
-		else{
-			*svcFactory = factory;
-		}
-	}
-	else{
-		printf("PSA_ZMQ_PSA_ZMQ_TP: Cannot find pubsub_endpoint after adding it...Should never happen!\n");
-		status = CELIX_SERVICE_EXCEPTION;
-	}
-
-	return status;
-}
-
-celix_status_t pubsub_topicPublicationStop(topic_publication_pt pub){
-	return serviceRegistration_unregister(pub->svcFactoryReg);
-}
-
-celix_status_t pubsub_topicPublicationAddPublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep){
-
-	celixThreadMutex_lock(&(pub->tp_lock));
-	ep->endpoint = strdup(pub->endpoint);
-	arrayList_add(pub->pub_ep_list,ep);
-	celixThreadMutex_unlock(&(pub->tp_lock));
-
-	return CELIX_SUCCESS;
-}
-
-celix_status_t pubsub_topicPublicationRemovePublisherEP(topic_publication_pt pub,pubsub_endpoint_pt ep){
-
-	celixThreadMutex_lock(&(pub->tp_lock));
-	for (int i = 0; i < arrayList_size(pub->pub_ep_list); i++) {
-	        pubsub_endpoint_pt e = arrayList_get(pub->pub_ep_list, i);
-	        if(pubsubEndpoint_equals(ep, e)) {
-	            arrayList_removeElement(pub->pub_ep_list,ep);
-	            break;
-	        }
-	}
-	celixThreadMutex_unlock(&(pub->tp_lock));
-
-	return CELIX_SUCCESS;
-}
-
-array_list_pt pubsub_topicPublicationGetPublisherList(topic_publication_pt pub){
-	array_list_pt list = NULL;
-	celixThreadMutex_lock(&(pub->tp_lock));
-	list = arrayList_clone(pub->pub_ep_list);
-	celixThreadMutex_unlock(&(pub->tp_lock));
-	return list;
-}
-
-
-static celix_status_t pubsub_topicPublicationGetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service) {
-	celix_status_t  status = CELIX_SUCCESS;
-
-	topic_publication_pt publish = (topic_publication_pt)handle;
-
-	celixThreadMutex_lock(&(publish->tp_lock));
-
-	publish_bundle_bound_service_pt bound = (publish_bundle_bound_service_pt)hashMap_get(publish->boundServices,bundle);
-	if(bound==NULL){
-		bound = pubsub_createPublishBundleBoundService(publish,bundle);
-		if(bound!=NULL){
-			hashMap_put(publish->boundServices,bundle,bound);
-		}
-	}
-	else{
-		bound->getCount++;
-	}
-
-	*service = &bound->service;
-
-	celixThreadMutex_unlock(&(publish->tp_lock));
-
-	return status;
-}
-
-static celix_status_t pubsub_topicPublicationUngetService(void* handle, bundle_pt bundle, service_registration_pt registration, void **service)  {
-
-	topic_publication_pt publish = (topic_publication_pt)handle;
-
-	celixThreadMutex_lock(&(publish->tp_lock));
-
-	publish_bundle_bound_service_pt bound = (publish_bundle_bound_service_pt)hashMap_get(publish->boundServices,bundle);
-	if(bound!=NULL){
-
-		bound->getCount--;
-		if(bound->getCount==0){
-			pubsub_destroyPublishBundleBoundService(bound);
-			hashMap_remove(publish->boundServices,bundle);
-		}
-
-	}
-	else{
-		long bundleId = -1;
-		bundle_getBundleId(bundle,&bundleId);
-		printf("PSA_ZMQ_TP: Unexpected ungetService call for bundle %ld.\n", bundleId);
-	}
-
-	/* service should be never used for unget, so let's set the pointer to NULL */
-	*service = NULL;
-
-	celixThreadMutex_unlock(&(publish->tp_lock));
-
-	return CELIX_SUCCESS;
-}
-
-static bool send_pubsub_msg(zsock_t* zmq_socket, pubsub_msg_pt msg, bool last){
-
-	bool ret = true;
-
-	zframe_t* headerMsg = zframe_new(msg->header, sizeof(struct pubsub_msg_header));
-	if (headerMsg == NULL) ret=false;
-	zframe_t* payloadMsg = zframe_new(msg->payload, msg->payloadSize);
-	if (payloadMsg == NULL) ret=false;
-
-	delay_first_send_for_late_joiners();
-
-	if( zframe_send(&headerMsg,zmq_socket, ZFRAME_MORE) == -1) ret=false;
-
-	if(!last){
-		if( zframe_send(&payloadMsg,zmq_socket, ZFRAME_MORE) == -1) ret=false;
-	}
-	else{
-		if( zframe_send(&payloadMsg,zmq_socket, 0) == -1) ret=false;
-	}
-
-	if (!ret){
-		zframe_destroy(&headerMsg);
-		zframe_destroy(&payloadMsg);
-	}
-
-	free(msg->header);
-	free(msg->payload);
-	free(msg);
-
-	return ret;
-
-}
-
-static bool send_pubsub_mp_msg(zsock_t* zmq_socket, array_list_pt mp_msg_parts){
-
-	bool ret = true;
-
-	unsigned int i = 0;
-	unsigned int mp_num = arrayList_size(mp_msg_parts);
-	for(;i<mp_num;i++){
-		ret = ret && send_pubsub_msg(zmq_socket, (pubsub_msg_pt)arrayList_get(mp_msg_parts,i), (i==mp_num-1));
-	}
-	arrayList_clear(mp_msg_parts);
-
-	return ret;
-
-}
-
-static int pubsub_topicPublicationSend(void* handle, unsigned int msgTypeId, const void *msg) {
-
-	return pubsub_topicPublicationSendMultipart(handle,msgTypeId,msg, PUBSUB_PUBLISHER_FIRST_MSG | PUBSUB_PUBLISHER_LAST_MSG);
-
-}
-
-static int pubsub_topicPublicationSendMultipart(void *handle, unsigned int msgTypeId, const void *inMsg, int flags){
-
-	int status = 0;
-
-	publish_bundle_bound_service_pt bound = (publish_bundle_bound_service_pt) handle;
-
-	celixThreadMutex_lock(&(bound->parent->tp_lock));
-	celixThreadMutex_lock(&(bound->mp_lock));
-	if( (flags & PUBSUB_PUBLISHER_FIRST_MSG) && !(flags & PUBSUB_PUBLISHER_LAST_MSG) && bound->mp_send_in_progress){ //means a real mp_msg
-		printf("PSA_ZMQ_TP: Multipart send already in progress. Cannot process a new one.\n");
-		celixThreadMutex_unlock(&(bound->mp_lock));
-		celixThreadMutex_unlock(&(bound->parent->tp_lock));
-		return -3;
-	}
-
-	pubsub_msg_serializer_t* msgSer = (pubsub_msg_serializer_t*)hashMap_get(bound->msgTypes, (void*)(uintptr_t)msgTypeId);
-
-	if (msgSer!= NULL) {
-		int major=0, minor=0;
-
-		pubsub_msg_header_pt msg_hdr = calloc(1,sizeof(struct pubsub_msg_header));
-		strncpy(msg_hdr->topic,bound->topic,MAX_TOPIC_LEN-1);
-		msg_hdr->type = msgTypeId;
-
-		if (msgSer->msgVersion != NULL){
-			version_getMajor(msgSer->msgVersion, &major);
-			version_getMinor(msgSer->msgVersion, &minor);
-			msg_hdr->major = major;
-			msg_hdr->minor = minor;
-		}
-
-		void *serializedOutput = NULL;
-		size_t serializedOutputLen = 0;
-		msgSer->serialize(msgSer,inMsg,&serializedOutput, &serializedOutputLen);
-
-		pubsub_msg_pt msg = calloc(1,sizeof(struct pubsub_msg));
-		msg->header = msg_hdr;
-		msg->payload = (char*)serializedOutput;
-		msg->payloadSize = serializedOutputLen;
-		bool snd = true;
-
-		switch(flags){
-		case PUBSUB_PUBLISHER_FIRST_MSG:
-			bound->mp_send_in_progress = true;
-			arrayList_add(bound->mp_parts,msg);
-			break;
-		case PUBSUB_PUBLISHER_PART_MSG:
-			if(!bound->mp_send_in_progress){
-				printf("PSA_ZMQ_TP: ERROR: received msg part without the first part.\n");
-				status = -4;
-			}
-			else{
-				arrayList_add(bound->mp_parts,msg);
-			}
-			break;
-		case PUBSUB_PUBLISHER_LAST_MSG:
-			if(!bound->mp_send_in_progress){
-				printf("PSA_ZMQ_TP: ERROR: received end msg without the first part.\n");
-				status = -4;
-			}
-			else{
-				arrayList_add(bound->mp_parts,msg);
-				snd = send_pubsub_mp_msg(bound->parent->zmq_socket,bound->mp_parts);
-				bound->mp_send_in_progress = false;
-			}
-			break;
-		case PUBSUB_PUBLISHER_FIRST_MSG | PUBSUB_PUBLISHER_LAST_MSG:	//Normal send case
-			snd = send_pubsub_msg(bound->parent->zmq_socket,msg,true);
-			break;
-		default:
-			printf("PSA_ZMQ_TP: ERROR: Invalid MP flags combination\n");
-			status = -4;
-			break;
-		}
-
-		if(status==-4){
-			free(msg);
-		}
-
-		if(!snd){
-			printf("PSA_ZMQ_TP: Failed to send %s message %u.\n",flags == (PUBSUB_PUBLISHER_FIRST_MSG | PUBSUB_PUBLISHER_LAST_MSG) ? "single" : "multipart", msgTypeId);
-		}
-
-	} else {
-        printf("PSA_ZMQ_TP: No msg serializer available for msg type id %d\n", msgTypeId);
-		status=-1;
-	}
-
-	celixThreadMutex_unlock(&(bound->mp_lock));
-	celixThreadMutex_unlock(&(bound->parent->tp_lock));
-
-	return status;
-
-}
-
-static int pubsub_localMsgTypeIdForUUID(void* handle, const char* msgType, unsigned int* msgTypeId){
-	*msgTypeId = utils_stringHash(msgType);
-	return 0;
-}
-
-
-static unsigned int rand_range(unsigned int min, unsigned int max){
-
-	double scaled = (double)(((double)random())/((double)RAND_MAX));
-	return (max-min+1)*scaled + min;
-
-}
-
-static publish_bundle_bound_service_pt pubsub_createPublishBundleBoundService(topic_publication_pt tp,bundle_pt bundle){
-
-	//PRECOND lock on tp->lock
-
-	publish_bundle_bound_service_pt bound = calloc(1, sizeof(*bound));
-
-	if (bound != NULL) {
-
-		bound->parent = tp;
-		bound->bundle = bundle;
-		bound->getCount = 1;
-		bound->mp_send_in_progress = false;
-		celixThreadMutex_create(&bound->mp_lock,NULL);
-
-		if(tp->serializer != NULL){
-			tp->serializer->createSerializerMap(tp->serializer->handle,bundle,&bound->msgTypes);
-		}
-
-		arrayList_create(&bound->mp_parts);
-
-		pubsub_endpoint_pt pubEP = (pubsub_endpoint_pt)arrayList_get(bound->parent->pub_ep_list,0);
-		bound->topic=strdup(pubEP->topic);
-
-		bound->service.handle = bound;
-		bound->service.localMsgTypeIdForMsgType = pubsub_localMsgTypeIdForUUID;
-		bound->service.send = pubsub_topicPublicationSend;
-		bound->service.sendMultipart = pubsub_topicPublicationSendMultipart;
-
-	}
-
-	return bound;
-}
-
-static void pubsub_destroyPublishBundleBoundService(publish_bundle_bound_service_pt boundSvc){
-
-	//PRECOND lock on tp->lock
-
-	celixThreadMutex_lock(&boundSvc->mp_lock);
-
-
-	if(boundSvc->parent->serializer != NULL && boundSvc->msgTypes != NULL){
-		boundSvc->parent->serializer->destroySerializerMap(boundSvc->parent->serializer->handle, boundSvc->msgTypes);
-	}
-
-	if(boundSvc->mp_parts!=NULL){
-		arrayList_destroy(boundSvc->mp_parts);
-	}
-
-	if(boundSvc->topic!=NULL){
-		free(boundSvc->topic);
-	}
-
-	celixThreadMutex_unlock(&boundSvc->mp_lock);
-	celixThreadMutex_destroy(&boundSvc->mp_lock);
-
-	free(boundSvc);
-
-}
-
-static void delay_first_send_for_late_joiners(){
-
-	static bool firstSend = true;
-
-	if(firstSend){
-		printf("PSA_ZMQ_TP: Delaying first send for late joiners...\n");
-		sleep(FIRST_SEND_DELAY);
-		firstSend = false;
-	}
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/pubsub/pubsub_admin_zmq/private/src/topic_subscription.c
----------------------------------------------------------------------
diff --git a/pubsub/pubsub_admin_zmq/private/src/topic_subscription.c b/pubsub/pubsub_admin_zmq/private/src/topic_subscription.c
deleted file mode 100644
index 0e7a794..0000000
--- a/pubsub/pubsub_admin_zmq/private/src/topic_subscription.c
+++ /dev/null
@@ -1,732 +0,0 @@
-/**
- *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.
- */
-/*
- * topic_subscription.c
- *
- *  \date       Oct 2, 2015
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#include "topic_subscription.h"
-#include <czmq.h>
-/* The following undefs prevent the collision between:
- * - sys/syslog.h (which is included within czmq)
- * - celix/dfi/dfi_log_util.h
- */
-#undef LOG_DEBUG
-#undef LOG_WARNING
-#undef LOG_INFO
-#undef LOG_WARNING
-
-#include <string.h>
-#include <stdlib.h>
-#include <signal.h>
-
-#include "utils.h"
-#include "celix_errno.h"
-#include "constants.h"
-#include "version.h"
-
-#include "subscriber.h"
-#include "publisher.h"
-#include "pubsub_utils.h"
-
-#ifdef BUILD_WITH_ZMQ_SECURITY
-#include "zmq_crypto.h"
-
-#define MAX_CERT_PATH_LENGTH 512
-#endif
-
-#define POLL_TIMEOUT  	250
-#define ZMQ_POLL_TIMEOUT_MS_ENV 	"ZMQ_POLL_TIMEOUT_MS"
-
-struct topic_subscription{
-
-	zsock_t* zmq_socket;
-	zcert_t * zmq_cert;
-	zcert_t * zmq_pub_cert;
-	pthread_mutex_t socket_lock;
-	service_tracker_pt tracker;
-	array_list_pt sub_ep_list;
-	celix_thread_t recv_thread;
-	bool running;
-	celix_thread_mutex_t ts_lock;
-	bundle_context_pt context;
-
-	pubsub_serializer_service_t *serializer;
-
-	hash_map_pt servicesMap; // key = service, value = msg types map
-
-	celix_thread_mutex_t pendingConnections_lock;
-	array_list_pt pendingConnections;
-
-	array_list_pt pendingDisconnections;
-	celix_thread_mutex_t pendingDisconnections_lock;
-
-	unsigned int nrSubscribers;
-};
-
-typedef struct complete_zmq_msg{
-	zframe_t* header;
-	zframe_t* payload;
-}* complete_zmq_msg_pt;
-
-typedef struct mp_handle{
-	hash_map_pt svc_msg_db;
-	hash_map_pt rcv_msg_map;
-}* mp_handle_pt;
-
-typedef struct msg_map_entry{
-	bool retain;
-	void* msgInst;
-}* msg_map_entry_pt;
-
-static celix_status_t topicsub_subscriberTracked(void * handle, service_reference_pt reference, void * service);
-static celix_status_t topicsub_subscriberUntracked(void * handle, service_reference_pt reference, void * service);
-static void* zmq_recv_thread_func(void* arg);
-static bool checkVersion(version_pt msgVersion,pubsub_msg_header_pt hdr);
-static void sigusr1_sighandler(int signo);
-static int pubsub_localMsgTypeIdForMsgType(void* handle, const char* msgType, unsigned int* msgTypeId);
-static int pubsub_getMultipart(void *handle, unsigned int msgTypeId, bool retain, void **part);
-static mp_handle_pt create_mp_handle(hash_map_pt svc_msg_db,array_list_pt rcv_msg_list);
-static void destroy_mp_handle(mp_handle_pt mp_handle);
-static void connectPendingPublishers(topic_subscription_pt sub);
-static void disconnectPendingPublishers(topic_subscription_pt sub);
-
-celix_status_t pubsub_topicSubscriptionCreate(bundle_context_pt bundle_context, char* scope, char* topic, pubsub_serializer_service_t *best_serializer, topic_subscription_pt* out){
-	celix_status_t status = CELIX_SUCCESS;
-
-#ifdef BUILD_WITH_ZMQ_SECURITY
-	char* keys_bundle_dir = pubsub_getKeysBundleDir(bundle_context);
-	if (keys_bundle_dir == NULL){
-		return CELIX_SERVICE_EXCEPTION;
-	}
-
-	const char* keys_file_path = NULL;
-	const char* keys_file_name = NULL;
-	bundleContext_getProperty(bundle_context, PROPERTY_KEYS_FILE_PATH, &keys_file_path);
-	bundleContext_getProperty(bundle_context, PROPERTY_KEYS_FILE_NAME, &keys_file_name);
-
-	char sub_cert_path[MAX_CERT_PATH_LENGTH];
-	char pub_cert_path[MAX_CERT_PATH_LENGTH];
-
-	//certificate path ".cache/bundle{id}/version0.0/./META-INF/keys/subscriber/private/sub_{topic}.key.enc"
-	snprintf(sub_cert_path, MAX_CERT_PATH_LENGTH, "%s/META-INF/keys/subscriber/private/sub_%s.key.enc", keys_bundle_dir, topic);
-	snprintf(pub_cert_path, MAX_CERT_PATH_LENGTH, "%s/META-INF/keys/publisher/public/pub_%s.pub", keys_bundle_dir, topic);
-	free(keys_bundle_dir);
-
-	printf("PSA_ZMQ_PSA_ZMQ_TS: Loading subscriber key '%s'\n", sub_cert_path);
-	printf("PSA_ZMQ_PSA_ZMQ_TS: Loading publisher key '%s'\n", pub_cert_path);
-
-	zcert_t* sub_cert = get_zcert_from_encoded_file((char *) keys_file_path, (char *) keys_file_name, sub_cert_path);
-	if (sub_cert == NULL){
-		printf("PSA_ZMQ_PSA_ZMQ_TS: Cannot load key '%s'\n", sub_cert_path);
-		return CELIX_SERVICE_EXCEPTION;
-	}
-
-	zcert_t* pub_cert = zcert_load(pub_cert_path);
-	if (pub_cert == NULL){
-		zcert_destroy(&sub_cert);
-		printf("PSA_ZMQ_PSA_ZMQ_TS: Cannot load key '%s'\n", pub_cert_path);
-		return CELIX_SERVICE_EXCEPTION;
-	}
-
-	const char* pub_key = zcert_public_txt(pub_cert);
-#endif
-
-	zsock_t* zmq_s = zsock_new (ZMQ_SUB);
-	if(zmq_s==NULL){
-#ifdef BUILD_WITH_ZMQ_SECURITY
-		zcert_destroy(&sub_cert);
-		zcert_destroy(&pub_cert);
-#endif
-
-		return CELIX_SERVICE_EXCEPTION;
-	}
-
-#ifdef BUILD_WITH_ZMQ_SECURITY
-	zcert_apply (sub_cert, zmq_s);
-	zsock_set_curve_serverkey (zmq_s, pub_key); //apply key of publisher to socket of subscriber
-#endif
-
-	if(strcmp(topic,PUBSUB_ANY_SUB_TOPIC)==0){
-		zsock_set_subscribe (zmq_s, "");
-	}
-	else{
-		zsock_set_subscribe (zmq_s, topic);
-	}
-
-	topic_subscription_pt ts = (topic_subscription_pt) calloc(1,sizeof(*ts));
-	ts->context = bundle_context;
-	ts->zmq_socket = zmq_s;
-	ts->running = false;
-	ts->nrSubscribers = 0;
-	ts->serializer = best_serializer;
-
-#ifdef BUILD_WITH_ZMQ_SECURITY
-	ts->zmq_cert = sub_cert;
-	ts->zmq_pub_cert = pub_cert;
-#endif
-
-	celixThreadMutex_create(&ts->socket_lock, NULL);
-	celixThreadMutex_create(&ts->ts_lock,NULL);
-	arrayList_create(&ts->sub_ep_list);
-	ts->servicesMap = hashMap_create(NULL, NULL, NULL, NULL);
-
-	arrayList_create(&ts->pendingConnections);
-	arrayList_create(&ts->pendingDisconnections);
-	celixThreadMutex_create(&ts->pendingConnections_lock, NULL);
-	celixThreadMutex_create(&ts->pendingDisconnections_lock, NULL);
-
-	char filter[128];
-	memset(filter,0,128);
-	if(strncmp(PUBSUB_SUBSCRIBER_SCOPE_DEFAULT,scope,strlen(PUBSUB_SUBSCRIBER_SCOPE_DEFAULT)) == 0) {
-		// default scope, means that subscriber has not defined a scope property
-		snprintf(filter, 128, "(&(%s=%s)(%s=%s))",
-				(char*) OSGI_FRAMEWORK_OBJECTCLASS, PUBSUB_SUBSCRIBER_SERVICE_NAME,
-				PUBSUB_SUBSCRIBER_TOPIC,topic);
-
-	} else {
-		snprintf(filter, 128, "(&(%s=%s)(%s=%s)(%s=%s))",
-				(char*) OSGI_FRAMEWORK_OBJECTCLASS, PUBSUB_SUBSCRIBER_SERVICE_NAME,
-				PUBSUB_SUBSCRIBER_TOPIC,topic,
-				PUBSUB_SUBSCRIBER_SCOPE,scope);
-	}
-	service_tracker_customizer_pt customizer = NULL;
-	status += serviceTrackerCustomizer_create(ts,NULL,topicsub_subscriberTracked,NULL,topicsub_subscriberUntracked,&customizer);
-	status += serviceTracker_createWithFilter(bundle_context, filter, customizer, &ts->tracker);
-
-	struct sigaction actions;
-	memset(&actions, 0, sizeof(actions));
-	sigemptyset(&actions.sa_mask);
-	actions.sa_flags = 0;
-	actions.sa_handler = sigusr1_sighandler;
-
-	sigaction(SIGUSR1,&actions,NULL);
-
-	*out=ts;
-
-	return status;
-}
-
-celix_status_t pubsub_topicSubscriptionDestroy(topic_subscription_pt ts){
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&ts->ts_lock);
-
-	ts->running = false;
-	serviceTracker_destroy(ts->tracker);
-	arrayList_clear(ts->sub_ep_list);
-	arrayList_destroy(ts->sub_ep_list);
-	/* TODO: Destroy all the serializer maps? */
-	hashMap_destroy(ts->servicesMap,false,false);
-
-	celixThreadMutex_lock(&ts->pendingConnections_lock);
-	arrayList_destroy(ts->pendingConnections);
-	celixThreadMutex_unlock(&ts->pendingConnections_lock);
-	celixThreadMutex_destroy(&ts->pendingConnections_lock);
-
-	celixThreadMutex_lock(&ts->pendingDisconnections_lock);
-	arrayList_destroy(ts->pendingDisconnections);
-	celixThreadMutex_unlock(&ts->pendingDisconnections_lock);
-	celixThreadMutex_destroy(&ts->pendingDisconnections_lock);
-
-	celixThreadMutex_unlock(&ts->ts_lock);
-
-	celixThreadMutex_lock(&ts->socket_lock);
-	zsock_destroy(&(ts->zmq_socket));
-#ifdef BUILD_WITH_ZMQ_SECURITY
-	zcert_destroy(&(ts->zmq_cert));
-	zcert_destroy(&(ts->zmq_pub_cert));
-#endif
-	celixThreadMutex_unlock(&ts->socket_lock);
-	celixThreadMutex_destroy(&ts->socket_lock);
-
-	celixThreadMutex_destroy(&ts->ts_lock);
-
-	free(ts);
-
-	return status;
-}
-
-celix_status_t pubsub_topicSubscriptionStart(topic_subscription_pt ts){
-	celix_status_t status = CELIX_SUCCESS;
-
-	status = serviceTracker_open(ts->tracker);
-
-	ts->running = true;
-
-	if(status==CELIX_SUCCESS){
-		status=celixThread_create(&ts->recv_thread,NULL,zmq_recv_thread_func,ts);
-	}
-
-	return status;
-}
-
-celix_status_t pubsub_topicSubscriptionStop(topic_subscription_pt ts){
-	celix_status_t status = CELIX_SUCCESS;
-
-	ts->running = false;
-
-	pthread_kill(ts->recv_thread.thread,SIGUSR1);
-
-	celixThread_join(ts->recv_thread,NULL);
-
-	status = serviceTracker_close(ts->tracker);
-
-	return status;
-}
-
-celix_status_t pubsub_topicSubscriptionConnectPublisher(topic_subscription_pt ts, char* pubURL){
-	celix_status_t status = CELIX_SUCCESS;
-	celixThreadMutex_lock(&ts->socket_lock);
-	if(!zsock_is(ts->zmq_socket) || zsock_connect(ts->zmq_socket,"%s",pubURL) != 0){
-		status = CELIX_SERVICE_EXCEPTION;
-	}
-	celixThreadMutex_unlock(&ts->socket_lock);
-
-	return status;
-}
-
-celix_status_t pubsub_topicSubscriptionAddConnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL) {
-	celix_status_t status = CELIX_SUCCESS;
-	char *url = strdup(pubURL);
-	celixThreadMutex_lock(&ts->pendingConnections_lock);
-	arrayList_add(ts->pendingConnections, url);
-	celixThreadMutex_unlock(&ts->pendingConnections_lock);
-	return status;
-}
-
-celix_status_t pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(topic_subscription_pt ts, char* pubURL) {
-	celix_status_t status = CELIX_SUCCESS;
-	char *url = strdup(pubURL);
-	celixThreadMutex_lock(&ts->pendingDisconnections_lock);
-	arrayList_add(ts->pendingDisconnections, url);
-	celixThreadMutex_unlock(&ts->pendingDisconnections_lock);
-	return status;
-}
-
-celix_status_t pubsub_topicSubscriptionDisconnectPublisher(topic_subscription_pt ts, char* pubURL){
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&ts->socket_lock);
-	if(!zsock_is(ts->zmq_socket) || zsock_disconnect(ts->zmq_socket,"%s",pubURL) != 0){
-		status = CELIX_SERVICE_EXCEPTION;
-	}
-	celixThreadMutex_unlock(&ts->socket_lock);
-
-	return status;
-}
-
-celix_status_t pubsub_topicSubscriptionAddSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP){
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&ts->ts_lock);
-	arrayList_add(ts->sub_ep_list,subEP);
-	celixThreadMutex_unlock(&ts->ts_lock);
-
-	return status;
-
-}
-
-celix_status_t pubsub_topicIncreaseNrSubscribers(topic_subscription_pt ts) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&ts->ts_lock);
-	ts->nrSubscribers++;
-	celixThreadMutex_unlock(&ts->ts_lock);
-
-	return status;
-}
-
-celix_status_t pubsub_topicSubscriptionRemoveSubscriber(topic_subscription_pt ts, pubsub_endpoint_pt subEP){
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&ts->ts_lock);
-	arrayList_removeElement(ts->sub_ep_list,subEP);
-	celixThreadMutex_unlock(&ts->ts_lock);
-
-	return status;
-}
-
-celix_status_t pubsub_topicDecreaseNrSubscribers(topic_subscription_pt ts) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	celixThreadMutex_lock(&ts->ts_lock);
-	ts->nrSubscribers--;
-	celixThreadMutex_unlock(&ts->ts_lock);
-
-	return status;
-}
-
-unsigned int pubsub_topicGetNrSubscribers(topic_subscription_pt ts) {
-	return ts->nrSubscribers;
-}
-
-array_list_pt pubsub_topicSubscriptionGetSubscribersList(topic_subscription_pt sub){
-	return sub->sub_ep_list;
-}
-
-static celix_status_t topicsub_subscriberTracked(void * handle, service_reference_pt reference, void * service){
-	celix_status_t status = CELIX_SUCCESS;
-	topic_subscription_pt ts = handle;
-
-	celixThreadMutex_lock(&ts->ts_lock);
-	if (!hashMap_containsKey(ts->servicesMap, service)) {
-		bundle_pt bundle = NULL;
-		hash_map_pt msgTypes = NULL;
-
-		serviceReference_getBundle(reference, &bundle);
-
-		if(ts->serializer != NULL && bundle!=NULL){
-			ts->serializer->createSerializerMap(ts->serializer->handle,bundle,&msgTypes);
-			if(msgTypes != NULL){
-				hashMap_put(ts->servicesMap, service, msgTypes);
-				printf("PSA_ZMQ_TS: New subscriber registered.\n");
-			}
-		}
-		else{
-			printf("PSA_ZMQ_TS: Cannot register new subscriber.\n");
-			status = CELIX_SERVICE_EXCEPTION;
-		}
-	}
-	celixThreadMutex_unlock(&ts->ts_lock);
-
-	return status;
-}
-
-static celix_status_t topicsub_subscriberUntracked(void * handle, service_reference_pt reference, void * service){
-	celix_status_t status = CELIX_SUCCESS;
-	topic_subscription_pt ts = handle;
-
-	celixThreadMutex_lock(&ts->ts_lock);
-	if (hashMap_containsKey(ts->servicesMap, service)) {
-		hash_map_pt msgTypes = hashMap_remove(ts->servicesMap, service);
-		if(msgTypes!=NULL && ts->serializer!=NULL){
-			ts->serializer->destroySerializerMap(ts->serializer->handle,msgTypes);
-			printf("PSA_ZMQ_TS: Subscriber unregistered.\n");
-		}
-		else{
-			printf("PSA_ZMQ_TS: Cannot unregister subscriber.\n");
-			status = CELIX_SERVICE_EXCEPTION;
-		}
-	}
-	celixThreadMutex_unlock(&ts->ts_lock);
-
-	return status;
-}
-
-
-static void process_msg(topic_subscription_pt sub,array_list_pt msg_list){
-
-	pubsub_msg_header_pt first_msg_hdr = (pubsub_msg_header_pt)zframe_data(((complete_zmq_msg_pt)arrayList_get(msg_list,0))->header);
-
-	hash_map_iterator_pt iter = hashMapIterator_create(sub->servicesMap);
-	while (hashMapIterator_hasNext(iter)) {
-		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-		pubsub_subscriber_pt subsvc = hashMapEntry_getKey(entry);
-		hash_map_pt msgTypes = hashMapEntry_getValue(entry);
-
-		pubsub_msg_serializer_t *msgSer = hashMap_get(msgTypes,(void*)(uintptr_t )first_msg_hdr->type);
-		if (msgSer == NULL) {
-			printf("PSA_ZMQ_TS: Primary message %d not supported. NOT sending any part of the whole message.\n",first_msg_hdr->type);
-		}
-		else{
-			void *msgInst = NULL;
-			bool validVersion = checkVersion(msgSer->msgVersion,first_msg_hdr);
-
-			if(validVersion){
-
-				celix_status_t status = msgSer->deserialize(msgSer, (const void *) zframe_data(((complete_zmq_msg_pt)arrayList_get(msg_list,0))->payload), 0, &msgInst);
-
-				if (status == CELIX_SUCCESS) {
-					bool release = true;
-					mp_handle_pt mp_handle = create_mp_handle(msgTypes,msg_list);
-					pubsub_multipart_callbacks_t mp_callbacks;
-					mp_callbacks.handle = mp_handle;
-					mp_callbacks.localMsgTypeIdForMsgType = pubsub_localMsgTypeIdForMsgType;
-					mp_callbacks.getMultipart = pubsub_getMultipart;
-					subsvc->receive(subsvc->handle, msgSer->msgName, first_msg_hdr->type, msgInst, &mp_callbacks, &release);
-
-					if(release){
-						msgSer->freeMsg(msgSer,msgInst); // pubsubSerializer_freeMsg(msgType, msgInst);
-					}
-					if(mp_handle!=NULL){
-						destroy_mp_handle(mp_handle);
-					}
-				}
-				else{
-					printf("PSA_ZMQ_TS: Cannot deserialize msgType %s.\n",msgSer->msgName);
-				}
-
-			}
-			else{
-				int major=0,minor=0;
-				version_getMajor(msgSer->msgVersion,&major);
-				version_getMinor(msgSer->msgVersion,&minor);
-				printf("PSA_ZMQ_TS: Version mismatch for primary message '%s' (have %d.%d, received %u.%u). NOT sending any part of the whole message.\n",
-						msgSer->msgName,major,minor,first_msg_hdr->major,first_msg_hdr->minor);
-			}
-
-		}
-	}
-	hashMapIterator_destroy(iter);
-
-	int i = 0;
-	for(;i<arrayList_size(msg_list);i++){
-		complete_zmq_msg_pt c_msg = arrayList_get(msg_list,i);
-		zframe_destroy(&(c_msg->header));
-		zframe_destroy(&(c_msg->payload));
-		free(c_msg);
-	}
-
-	arrayList_destroy(msg_list);
-
-}
-
-static void* zmq_recv_thread_func(void * arg) {
-	topic_subscription_pt sub = (topic_subscription_pt) arg;
-
-	while (sub->running) {
-
-		celixThreadMutex_lock(&sub->socket_lock);
-
-		zframe_t* headerMsg = zframe_recv(sub->zmq_socket);
-		if (headerMsg == NULL) {
-			if (errno == EINTR) {
-				//It means we got a signal and we have to exit...
-				printf("PSA_ZMQ_TS: header_recv thread for topic got a signal and will exit.\n");
-			} else {
-				perror("PSA_ZMQ_TS: header_recv thread");
-			}
-		}
-		else {
-
-			pubsub_msg_header_pt hdr = (pubsub_msg_header_pt) zframe_data(headerMsg);
-
-			if (zframe_more(headerMsg)) {
-
-				zframe_t* payloadMsg = zframe_recv(sub->zmq_socket);
-				if (payloadMsg == NULL) {
-					if (errno == EINTR) {
-						//It means we got a signal and we have to exit...
-						printf("PSA_ZMQ_TS: payload_recv thread for topic got a signal and will exit.\n");
-					} else {
-						perror("PSA_ZMQ_TS: payload_recv");
-					}
-					zframe_destroy(&headerMsg);
-				} else {
-
-					//Let's fetch all the messages from the socket
-					array_list_pt msg_list = NULL;
-					arrayList_create(&msg_list);
-					complete_zmq_msg_pt firstMsg = calloc(1, sizeof(struct complete_zmq_msg));
-					firstMsg->header = headerMsg;
-					firstMsg->payload = payloadMsg;
-					arrayList_add(msg_list, firstMsg);
-
-					bool more = zframe_more(payloadMsg);
-					while (more) {
-
-						zframe_t* h_msg = zframe_recv(sub->zmq_socket);
-						if (h_msg == NULL) {
-							if (errno == EINTR) {
-								//It means we got a signal and we have to exit...
-								printf("PSA_ZMQ_TS: h_recv thread for topic got a signal and will exit.\n");
-							} else {
-								perror("PSA_ZMQ_TS: h_recv");
-							}
-							break;
-						}
-
-						zframe_t* p_msg = zframe_recv(sub->zmq_socket);
-						if (p_msg == NULL) {
-							if (errno == EINTR) {
-								//It means we got a signal and we have to exit...
-								printf("PSA_ZMQ_TS: p_recv thread for topic got a signal and will exit.\n");
-							} else {
-								perror("PSA_ZMQ_TS: p_recv");
-							}
-							zframe_destroy(&h_msg);
-							break;
-						}
-
-						complete_zmq_msg_pt c_msg = calloc(1, sizeof(struct complete_zmq_msg));
-						c_msg->header = h_msg;
-						c_msg->payload = p_msg;
-						arrayList_add(msg_list, c_msg);
-
-						if (!zframe_more(p_msg)) {
-							more = false;
-						}
-					}
-
-					celixThreadMutex_lock(&sub->ts_lock);
-					process_msg(sub, msg_list);
-					celixThreadMutex_unlock(&sub->ts_lock);
-
-				}
-
-			} //zframe_more(headerMsg)
-			else {
-				free(headerMsg);
-				printf("PSA_ZMQ_TS: received message %u for topic %s without payload!\n", hdr->type, hdr->topic);
-			}
-
-		} // headerMsg != NULL
-		celixThreadMutex_unlock(&sub->socket_lock);
-		connectPendingPublishers(sub);
-		disconnectPendingPublishers(sub);
-	} // while
-
-	return NULL;
-}
-
-static void connectPendingPublishers(topic_subscription_pt sub) {
-	celixThreadMutex_lock(&sub->pendingConnections_lock);
-	while(!arrayList_isEmpty(sub->pendingConnections)) {
-		char * pubEP = arrayList_remove(sub->pendingConnections, 0);
-		pubsub_topicSubscriptionConnectPublisher(sub, pubEP);
-		free(pubEP);
-	}
-	celixThreadMutex_unlock(&sub->pendingConnections_lock);
-}
-
-static void disconnectPendingPublishers(topic_subscription_pt sub) {
-	celixThreadMutex_lock(&sub->pendingDisconnections_lock);
-	while(!arrayList_isEmpty(sub->pendingDisconnections)) {
-		char * pubEP = arrayList_remove(sub->pendingDisconnections, 0);
-		pubsub_topicSubscriptionDisconnectPublisher(sub, pubEP);
-		free(pubEP);
-	}
-	celixThreadMutex_unlock(&sub->pendingDisconnections_lock);
-}
-
-static void sigusr1_sighandler(int signo){
-	printf("PSA_ZMQ_TS: Topic subscription being shut down...\n");
-	return;
-}
-
-static bool checkVersion(version_pt msgVersion,pubsub_msg_header_pt hdr){
-	bool check=false;
-	int major=0,minor=0;
-
-	if(msgVersion!=NULL){
-		version_getMajor(msgVersion,&major);
-		version_getMinor(msgVersion,&minor);
-		if(hdr->major==((unsigned char)major)){ /* Different major means incompatible */
-			check = (hdr->minor>=((unsigned char)minor)); /* Compatible only if the provider has a minor equals or greater (means compatible update) */
-		}
-	}
-
-	return check;
-}
-
-static int pubsub_localMsgTypeIdForMsgType(void* handle, const char* msgType, unsigned int* msgTypeId){
-	*msgTypeId = utils_stringHash(msgType);
-	return 0;
-}
-
-static int pubsub_getMultipart(void *handle, unsigned int msgTypeId, bool retain, void **part){
-
-	if(handle==NULL){
-		*part = NULL;
-		return -1;
-	}
-
-	mp_handle_pt mp_handle = (mp_handle_pt)handle;
-	msg_map_entry_pt entry = hashMap_get(mp_handle->rcv_msg_map, (void*)(uintptr_t) msgTypeId);
-	if(entry!=NULL){
-		entry->retain = retain;
-		*part = entry->msgInst;
-	}
-	else{
-		printf("TP: getMultipart cannot find msg '%u'\n",msgTypeId);
-		*part=NULL;
-		return -2;
-	}
-
-	return 0;
-
-}
-
-static mp_handle_pt create_mp_handle(hash_map_pt svc_msg_db,array_list_pt rcv_msg_list){
-
-	if(arrayList_size(rcv_msg_list)==1){ //Means it's not a multipart message
-		return NULL;
-	}
-
-	mp_handle_pt mp_handle = calloc(1,sizeof(struct mp_handle));
-	mp_handle->svc_msg_db = svc_msg_db;
-	mp_handle->rcv_msg_map = hashMap_create(NULL, NULL, NULL, NULL);
-
-	int i=1; //We skip the first message, it will be handle differently
-	for(;i<arrayList_size(rcv_msg_list);i++){
-		complete_zmq_msg_pt c_msg = (complete_zmq_msg_pt)arrayList_get(rcv_msg_list,i);
-		pubsub_msg_header_pt header = (pubsub_msg_header_pt)zframe_data(c_msg->header);
-
-		pubsub_msg_serializer_t* msgSer = hashMap_get(svc_msg_db, (void*)(uintptr_t)(header->type));
-
-		if (msgSer!= NULL) {
-			void *msgInst = NULL;
-
-			bool validVersion = checkVersion(msgSer->msgVersion,header);
-
-			if(validVersion){
-				celix_status_t status = msgSer->deserialize(msgSer, (const void*)zframe_data(c_msg->payload), 0, &msgInst);
-
-				if(status == CELIX_SUCCESS){
-					msg_map_entry_pt entry = calloc(1,sizeof(struct msg_map_entry));
-					entry->msgInst = msgInst;
-					hashMap_put(mp_handle->rcv_msg_map, (void*)(uintptr_t)header->type,entry);
-				}
-			}
-		}
-	}
-
-	return mp_handle;
-
-}
-
-static void destroy_mp_handle(mp_handle_pt mp_handle){
-
-	hash_map_iterator_pt iter = hashMapIterator_create(mp_handle->rcv_msg_map);
-	while(hashMapIterator_hasNext(iter)){
-		hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-		unsigned int msgId = (unsigned int)(uintptr_t)hashMapEntry_getKey(entry);
-		msg_map_entry_pt msgEntry = hashMapEntry_getValue(entry);
-		pubsub_msg_serializer_t* msgSer = hashMap_get(mp_handle->svc_msg_db, (void*)(uintptr_t)msgId);
-
-		if(msgSer!=NULL){
-			if(!msgEntry->retain){
-				msgSer->freeMsg(msgSer->handle,msgEntry->msgInst);
-			}
-		}
-		else{
-			printf("PSA_ZMQ_TS: ERROR: Cannot find messageSerializer for msg %u, so cannot destroy it!\n",msgId);
-		}
-
-		free(msgEntry);
-	}
-	hashMapIterator_destroy(iter);
-
-	hashMap_destroy(mp_handle->rcv_msg_map,false,false);
-	free(mp_handle);
-}


[2/8] celix git commit: CELIX-417: Refactors cmake usage of pubsub and rsa. Started with installing exported targets

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_service_admin_common/src/import_registration_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/import_registration_impl.c b/remote_services/remote_service_admin_common/src/import_registration_impl.c
deleted file mode 100644
index 9a84327..0000000
--- a/remote_services/remote_service_admin_common/src/import_registration_impl.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/**
- *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.
- */
-/*
- * import_registration_impl.c
- *
- *  \date       Oct 14, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <constants.h>
-
-#include "celix_errno.h"
-
-#include "import_registration_impl.h"
-#include "remote_service_admin_impl.h"
-
-struct import_reference {
-	endpoint_description_pt endpoint;
-	service_reference_pt reference;
-};
-
-
-
-celix_status_t importRegistration_proxyFactoryAdding(void * handle, service_reference_pt reference, void **service);
-celix_status_t importRegistration_proxyFactoryAdded(void * handle, service_reference_pt reference, void *service);
-celix_status_t importRegistration_proxyFactoryModified(void * handle, service_reference_pt reference, void *service);
-celix_status_t importRegistration_proxyFactoryRemoved(void * handle, service_reference_pt reference, void *service);
-
-celix_status_t importRegistration_create(endpoint_description_pt endpoint, remote_service_admin_pt rsa, sendToHandle sendToCallback, bundle_context_pt context, import_registration_pt *registration) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*registration = calloc(1, sizeof(**registration));
-	if (!*registration) {
-		status = CELIX_ENOMEM;
-	} else {
-		(*registration)->context = context;
-		(*registration)->closed = false;
-		(*registration)->endpointDescription = endpoint;
-		(*registration)->rsa = rsa;
-		(*registration)->sendToCallback = sendToCallback;
-		(*registration)->reference = NULL;
-		(*registration)->importReference = NULL;
-	}
-
-	return status;
-}
-
-celix_status_t importRegistration_destroy(import_registration_pt registration)
-{
-	free(registration);
-
-	return CELIX_SUCCESS;
-}
-
-
-celix_status_t importRegistrationFactory_create(log_helper_pt helper, char* serviceName, bundle_context_pt context, import_registration_factory_pt *registration_factory) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*registration_factory = calloc(1, sizeof(**registration_factory));
-	if (!*registration_factory) {
-		status = CELIX_ENOMEM;
-	} else {
-		(*registration_factory)->serviceName = strdup(serviceName);
-		(*registration_factory)->context = context;
-		(*registration_factory)->bundle = NULL;
-		(*registration_factory)->loghelper = helper;
-
-		arrayList_create(&(*registration_factory)->registrations);
-	}
-
-	return status;
-}
-
-
-
-celix_status_t importRegistrationFactory_destroy(import_registration_factory_pt* registration_factory) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (*registration_factory != NULL)
-	{
-		free((*registration_factory)->serviceName);
-		arrayList_destroy((*registration_factory)->registrations);
-
-		serviceTracker_destroy((*registration_factory)->proxyFactoryTracker);
-		free(*registration_factory);
-
-		*registration_factory = NULL;
-	}
-
-
-	return status;
-}
-
-
-celix_status_t importRegistrationFactory_open(import_registration_factory_pt registration_factory)
-{
-	celix_status_t status;
-
-	const char *bundleStore = NULL;
-	bundleContext_getProperty(registration_factory->context, BUNDLE_STORE_PROPERTY_NAME, &bundleStore);
-
-	if (bundleStore == NULL) {
-		bundleStore = DEFAULT_BUNDLE_STORE;
-	}
-
-	char name[256];
-	snprintf(name, 256, "%s/%s_proxy.zip", bundleStore, registration_factory->serviceName);
-
-	status = bundleContext_installBundle(registration_factory->context, name, &registration_factory->bundle);
-
-	if (status == CELIX_SUCCESS) {
-		status = bundle_start(registration_factory->bundle);
-		if (status == CELIX_SUCCESS) {
-			logHelper_log(registration_factory->loghelper, OSGI_LOGSERVICE_INFO, "%s successfully started.", name);
-		}
-	}
-	else {
-		logHelper_log(registration_factory->loghelper, OSGI_LOGSERVICE_ERROR, "%s could not be installed.", name);
-	}
-
-	return status;
-}
-
-celix_status_t importRegistrationFactory_close(import_registration_factory_pt registration_factory)
-{
-	celix_status_t status = CELIX_SUCCESS;
-
-
-	if (registration_factory->proxyFactoryTracker != NULL) {
-		serviceTracker_close(registration_factory->proxyFactoryTracker);
-	}
-
-	if (registration_factory->bundle != NULL) {
-		bundle_uninstall(registration_factory->bundle);
-	}
-
-	return status;
-}
-
-
-celix_status_t importRegistration_createProxyFactoryTracker(import_registration_factory_pt registration_factory, service_tracker_pt *tracker) {
-	celix_status_t status;
-	service_tracker_customizer_pt customizer = NULL;
-
-	status = serviceTrackerCustomizer_create(registration_factory, importRegistration_proxyFactoryAdding, importRegistration_proxyFactoryAdded, importRegistration_proxyFactoryModified, importRegistration_proxyFactoryRemoved, &customizer);
-
-	if (status == CELIX_SUCCESS) {
-		char filter[512];
-
-		snprintf(filter, 512, "(&(%s=%s)(proxy.interface=%s))", (char*) OSGI_FRAMEWORK_OBJECTCLASS, (char*) OSGI_RSA_REMOTE_PROXY_FACTORY, registration_factory->serviceName);
-		status = serviceTracker_createWithFilter(registration_factory->context, filter, customizer, tracker);
-
-		if (status == CELIX_SUCCESS)
-		{
-			serviceTracker_open(*tracker);
-		}
-	}
-
-	return status;
-}
-
-celix_status_t importRegistration_proxyFactoryAdding(void * handle, service_reference_pt reference, void **service) {
-	celix_status_t status = CELIX_SUCCESS;
-	import_registration_factory_pt registration_factory = (import_registration_factory_pt) handle;
-
-	bundleContext_getService(registration_factory->context, reference, service);
-
-	return status;
-}
-
-celix_status_t importRegistration_proxyFactoryAdded(void * handle, service_reference_pt reference, void *service) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	import_registration_factory_pt registration_factory = (import_registration_factory_pt) handle;
-	registration_factory->trackedFactory = (remote_proxy_factory_service_pt) service;
-
-	return status;
-}
-
-celix_status_t importRegistration_proxyFactoryModified(void * handle, service_reference_pt reference, void *service) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	return status;
-}
-
-celix_status_t importRegistration_proxyFactoryRemoved(void * handle, service_reference_pt reference, void *service) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	import_registration_factory_pt registration_factory = (import_registration_factory_pt) handle;
-	registration_factory->trackedFactory = NULL;
-
-	return status;
-}
-
-
-
-celix_status_t importRegistrationFactory_install(log_helper_pt helper, char* serviceName, bundle_context_pt context, import_registration_factory_pt *registration_factory)
-{
-	celix_status_t status;
-
-	if ( (status = importRegistrationFactory_create(helper, serviceName, context, registration_factory)) == CELIX_SUCCESS) {
-		// starting the proxy tracker first allows us to pick up already available proxy factories
-		importRegistration_createProxyFactoryTracker(*registration_factory, &((*registration_factory)->proxyFactoryTracker));
-		logHelper_log((*registration_factory)->loghelper, OSGI_LOGSERVICE_INFO, "remoteServiceAdmin_importService: new registration_factory added for %s at %p", serviceName, (*registration_factory)->proxyFactoryTracker);
-
-		// check whether factory is available
-		if (((*registration_factory)->trackedFactory == NULL) && ((status = importRegistrationFactory_open(*registration_factory)) != CELIX_SUCCESS)) {
-			logHelper_log((*registration_factory)->loghelper, OSGI_LOGSERVICE_ERROR, "remoteServiceAdmin_importService: cannot open registration_factory for %s.", serviceName);
-
-			importRegistrationFactory_close(*registration_factory);
-			importRegistrationFactory_destroy(registration_factory);
-		}
-	}
-
-	return status;
-}
-
-
-
-
-celix_status_t importRegistration_getException(import_registration_pt registration) {
-	celix_status_t status = CELIX_SUCCESS;
-	return status;
-}
-
-
-celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (registration->importReference == NULL) {
-		registration->importReference = calloc(1, 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;
-}
-
-
-celix_status_t importReference_getImportedEndpoint(import_reference_pt reference) {
-	celix_status_t status = CELIX_SUCCESS;
-	return status;
-}
-
-celix_status_t importReference_getImportedService(import_reference_pt reference) {
-	celix_status_t status = CELIX_SUCCESS;
-	return status;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_service_admin_common/src/import_registration_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/import_registration_impl.h b/remote_services/remote_service_admin_common/src/import_registration_impl.h
deleted file mode 100644
index 7aa397f..0000000
--- a/remote_services/remote_service_admin_common/src/import_registration_impl.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- *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.
- */
-/*
- * import_registration_impl.h
- *
- *  \date       Oct 14, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef IMPORT_REGISTRATION_IMPL_H_
-#define IMPORT_REGISTRATION_IMPL_H_
-
-#include "remote_service_admin.h"
-#include "remote_proxy.h"
-#include "service_tracker.h"
-#include "log_helper.h"
-
-struct import_registration {
-	bundle_context_pt context;
-	endpoint_description_pt endpointDescription;
-
-	service_reference_pt reference;
-	import_reference_pt importReference;
-
-	remote_service_admin_pt rsa;
-	sendToHandle sendToCallback;
-
-	bool closed;
-};
-
-
-
-struct import_registration_factory
-{
-	char* serviceName;
-	log_helper_pt loghelper;
-	remote_proxy_factory_service_pt trackedFactory;
-	service_tracker_pt proxyFactoryTracker;
-	bundle_context_pt context;
-	array_list_pt registrations;
-	bundle_pt bundle;
-};
-
-
-celix_status_t importRegistration_create(endpoint_description_pt endpoint, remote_service_admin_pt rsa, sendToHandle callback, bundle_context_pt context, import_registration_pt *registration);
-celix_status_t importRegistration_destroy(import_registration_pt registration);
-
-celix_status_t importRegistration_setEndpointDescription(import_registration_pt registration, endpoint_description_pt endpointDescription);
-celix_status_t importRegistration_setHandler(import_registration_pt registration, void * handler);
-celix_status_t importRegistration_setCallback(import_registration_pt registration, sendToHandle callback);
-
-celix_status_t importRegistration_getException(import_registration_pt registration);
-celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference);
-
-celix_status_t importRegistration_createProxyFactoryTracker(import_registration_factory_pt registration_factory, service_tracker_pt *tracker);
-
-celix_status_t importRegistrationFactory_destroy(import_registration_factory_pt* registration_factory);
-//celix_status_t importRegistrationFactory_open(import_registration_factory_pt registration_factory);
-celix_status_t importRegistrationFactory_close(import_registration_factory_pt registration_factory);
-celix_status_t importRegistrationFactory_install(log_helper_pt helper, char* serviceName, bundle_context_pt context, import_registration_factory_pt *registration_factory);
-
-
-
-#endif /* IMPORT_REGISTRATION_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_service_admin_common/src/remote_proxy_factory_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/remote_proxy_factory_impl.c b/remote_services/remote_service_admin_common/src/remote_proxy_factory_impl.c
deleted file mode 100644
index 9f996d6..0000000
--- a/remote_services/remote_service_admin_common/src/remote_proxy_factory_impl.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/**
- * 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.
- */
-
-/*
- * remote_proxy_factory_impl.c
- *
- *  \date       22 Dec 2014
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "remote_proxy.h"
-
-typedef struct proxy_instance {
-	service_registration_pt registration_ptr;
-	void *service;
-	properties_pt properties;
-} *proxy_instance_pt;
-
-static celix_status_t remoteProxyFactory_registerProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription, remote_service_admin_pt rsa, sendToHandle sendToCallback);
-static celix_status_t remoteProxyFactory_unregisterProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription);
-
-celix_status_t remoteProxyFactory_create(bundle_context_pt context, char *service, void *handle,
-		createProxyService create, destroyProxyService destroy,
-		remote_proxy_factory_pt *remote_proxy_factory_ptr) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*remote_proxy_factory_ptr = calloc(1, sizeof(**remote_proxy_factory_ptr));
-	if (!*remote_proxy_factory_ptr) {
-		status = CELIX_ENOMEM;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		(*remote_proxy_factory_ptr)->context_ptr = context;
-		(*remote_proxy_factory_ptr)->service = strdup(service);
-
-		(*remote_proxy_factory_ptr)->remote_proxy_factory_service_ptr = NULL;
-		(*remote_proxy_factory_ptr)->properties = NULL;
-		(*remote_proxy_factory_ptr)->registration = NULL;
-
-		(*remote_proxy_factory_ptr)->proxy_instances = hashMap_create(NULL, NULL, NULL, NULL);
-
-		(*remote_proxy_factory_ptr)->handle = handle;
-
-		(*remote_proxy_factory_ptr)->create_proxy_service_ptr = create;
-		(*remote_proxy_factory_ptr)->destroy_proxy_service_ptr = destroy;
-	}
-
-	return status;
-}
-
-celix_status_t remoteProxyFactory_destroy(remote_proxy_factory_pt *remote_proxy_factory_ptr) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (!*remote_proxy_factory_ptr) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		if ((*remote_proxy_factory_ptr)->proxy_instances) {
-			hashMap_destroy((*remote_proxy_factory_ptr)->proxy_instances, false, false);
-			(*remote_proxy_factory_ptr)->proxy_instances = NULL;
-		}
-		if ((*remote_proxy_factory_ptr)->service) {
-			free((*remote_proxy_factory_ptr)->service);
-			(*remote_proxy_factory_ptr)->service = NULL;
-		}
-		free(*remote_proxy_factory_ptr);
-		*remote_proxy_factory_ptr = NULL;
-	}
-
-	return status;
-}
-
-celix_status_t remoteProxyFactory_register(remote_proxy_factory_pt remote_proxy_factory_ptr) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	remote_proxy_factory_ptr->remote_proxy_factory_service_ptr = calloc(1, sizeof(*remote_proxy_factory_ptr->remote_proxy_factory_service_ptr));
-	if (!remote_proxy_factory_ptr->remote_proxy_factory_service_ptr) {
-		status = CELIX_ENOMEM;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		remote_proxy_factory_ptr->remote_proxy_factory_service_ptr->factory = remote_proxy_factory_ptr;
-		remote_proxy_factory_ptr->remote_proxy_factory_service_ptr->registerProxyService = remoteProxyFactory_registerProxyService;
-		remote_proxy_factory_ptr->remote_proxy_factory_service_ptr->unregisterProxyService = remoteProxyFactory_unregisterProxyService;
-
-		remote_proxy_factory_ptr->properties = properties_create();
-		if (!remote_proxy_factory_ptr->properties) {
-			status = CELIX_BUNDLE_EXCEPTION;
-		} else {
-			properties_set(remote_proxy_factory_ptr->properties, "proxy.interface", remote_proxy_factory_ptr->service);
-		}
-	}
-
-	if (status == CELIX_SUCCESS) {
-		status = bundleContext_registerService(remote_proxy_factory_ptr->context_ptr, OSGI_RSA_REMOTE_PROXY_FACTORY,
-				remote_proxy_factory_ptr->remote_proxy_factory_service_ptr, remote_proxy_factory_ptr->properties, &remote_proxy_factory_ptr->registration);
-	}
-
-	return status;
-}
-
-celix_status_t remoteProxyFactory_unregister(remote_proxy_factory_pt remote_proxy_factory_ptr) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (!remote_proxy_factory_ptr) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	// #TODO Remove proxy registrations
-	if (status == CELIX_SUCCESS) {
-
-		hash_map_iterator_pt iter = hashMapIterator_create(remote_proxy_factory_ptr->proxy_instances);
-		while(hashMapIterator_hasNext(iter)){
-			proxy_instance_pt proxy_instance_ptr = (proxy_instance_pt)hashMapIterator_nextValue(iter);
-
-			if (proxy_instance_ptr->service) {
-				remote_proxy_factory_ptr->destroy_proxy_service_ptr(remote_proxy_factory_ptr->handle, proxy_instance_ptr->service);
-			}
-			free(proxy_instance_ptr);
-		}
-		hashMapIterator_destroy(iter);
-
-		if (remote_proxy_factory_ptr->registration) {
-			status = serviceRegistration_unregister(remote_proxy_factory_ptr->registration);
-			remote_proxy_factory_ptr->properties = NULL;
-		}
-		if (remote_proxy_factory_ptr->properties) {
-			properties_destroy(remote_proxy_factory_ptr->properties);
-		}
-		if (remote_proxy_factory_ptr->remote_proxy_factory_service_ptr) {
-			free(remote_proxy_factory_ptr->remote_proxy_factory_service_ptr);
-		}
-	}
-
-	return status;
-}
-
-
-static celix_status_t remoteProxyFactory_registerProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription, remote_service_admin_pt rsa, sendToHandle sendToCallback) {
-	celix_status_t status = CELIX_SUCCESS;
-	proxy_instance_pt proxy_instance_ptr = NULL;
-
-	if (!remote_proxy_factory_ptr || !remote_proxy_factory_ptr->create_proxy_service_ptr) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		proxy_instance_ptr = calloc(1, sizeof(*proxy_instance_ptr));
-		if (!proxy_instance_ptr) {
-			status = CELIX_ENOMEM;
-		}
-	}
-
-	if (status == CELIX_SUCCESS) {
-		proxy_instance_ptr->properties = properties_create();
-		if (!proxy_instance_ptr->properties) {
-			status = CELIX_ENOMEM;
-		}
-	}
-
-	if (status == CELIX_SUCCESS) {
-		status = remote_proxy_factory_ptr->create_proxy_service_ptr(remote_proxy_factory_ptr->handle, endpointDescription, rsa, sendToCallback, proxy_instance_ptr->properties, &proxy_instance_ptr->service);
-	}
-
-	if (status == CELIX_SUCCESS) {
-		properties_set(proxy_instance_ptr->properties, "proxy.interface", remote_proxy_factory_ptr->service);
-
-		hash_map_iterator_pt iter = hashMapIterator_create(endpointDescription->properties);
-		while (hashMapIterator_hasNext(iter)) {
-			hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-			char *key = hashMapEntry_getKey(entry);
-			char *value = hashMapEntry_getValue(entry);
-
-			properties_set(proxy_instance_ptr->properties, key, value);
-		}
-		hashMapIterator_destroy(iter);
-	}
-
-	if (status == CELIX_SUCCESS) {
-		status = bundleContext_registerService(remote_proxy_factory_ptr->context_ptr, remote_proxy_factory_ptr->service, proxy_instance_ptr->service, proxy_instance_ptr->properties, &proxy_instance_ptr->registration_ptr);
-	}
-
-	if (status == CELIX_SUCCESS) {
-		hashMap_put(remote_proxy_factory_ptr->proxy_instances, endpointDescription, proxy_instance_ptr);
-	}
-
-	if(status!=CELIX_SUCCESS){
-		if(proxy_instance_ptr != NULL){
-			if(proxy_instance_ptr->properties != NULL){
-				properties_destroy(proxy_instance_ptr->properties);
-			}
-			free(proxy_instance_ptr);
-		}
-	}
-
-	return status;
-}
-
-static celix_status_t remoteProxyFactory_unregisterProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription) {
-	celix_status_t status = CELIX_SUCCESS;
-	proxy_instance_pt proxy_instance_ptr = NULL;
-
-	if (!remote_proxy_factory_ptr || !endpointDescription || !remote_proxy_factory_ptr->proxy_instances || !remote_proxy_factory_ptr->handle) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		proxy_instance_ptr = hashMap_remove(remote_proxy_factory_ptr->proxy_instances, endpointDescription);
-		if (proxy_instance_ptr == NULL) {
-			status = CELIX_BUNDLE_EXCEPTION;
-		}
-	}
-
-	if (status == CELIX_SUCCESS) {
-		if (proxy_instance_ptr->registration_ptr) {
-			status = serviceRegistration_unregister(proxy_instance_ptr->registration_ptr);
-			proxy_instance_ptr->properties = NULL;
-		}
-		if (proxy_instance_ptr->service) {
-			status = remote_proxy_factory_ptr->destroy_proxy_service_ptr(remote_proxy_factory_ptr->handle, proxy_instance_ptr->service);
-		}
-		if (proxy_instance_ptr->properties) {
-			properties_destroy(proxy_instance_ptr->properties);
-		}
-        free(proxy_instance_ptr);
-	}
-
-	return status;
-}
-
-

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_service_admin_common/src/remote_service_admin_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/src/remote_service_admin_impl.h b/remote_services/remote_service_admin_common/src/remote_service_admin_impl.h
deleted file mode 100644
index e8a5e1f..0000000
--- a/remote_services/remote_service_admin_common/src/remote_service_admin_impl.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- *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.
- */
-/*
- * remote_service_admin_impl.h
- *
- *  \date       Dec 5, 2013
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
-#ifndef REMOTE_SERVICE_ADMIN_IMPL_H_
-#define REMOTE_SERVICE_ADMIN_IMPL_H_
-
-#include "remote_service_admin.h"
-
-#define BUNDLE_STORE_PROPERTY_NAME "ENDPOINTS"
-#define DEFAULT_BUNDLE_STORE "endpoints"
-
-celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin);
-celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin);
-
-celix_status_t remoteServiceAdmin_send(remote_service_admin_pt rsa, endpoint_description_pt endpointDescription, char *methodSignature, char **reply, int* replyStatus);
-
-celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations);
-celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_pt admin, export_registration_pt registration);
-celix_status_t remoteServiceAdmin_getExportedServices(remote_service_admin_pt admin, array_list_pt *services);
-celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt admin, array_list_pt *services);
-celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpoint, import_registration_pt *registration);
-celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration);
-
-celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description);
-
-#endif /* REMOTE_SERVICE_ADMIN_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_services_api/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_services_api/CMakeLists.txt b/remote_services/remote_services_api/CMakeLists.txt
new file mode 100644
index 0000000..67656d3
--- /dev/null
+++ b/remote_services/remote_services_api/CMakeLists.txt
@@ -0,0 +1,28 @@
+# 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.
+
+add_library(celix_remote_services_api INTERFACE)
+target_include_directories(celix_remote_services_api INTERFACE
+    $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
+    $<INSTALL_INTERFACE:include/celix/remote_services>
+)
+
+install(TARGETS celix_remote_services_api EXPORT celix DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT rsa)
+install(DIRECTORY include/ DESTINATION include/celix/remote_services COMPONENT rsa)
+
+#Setup target aliases to match external usage
+add_library(Celix::remote_services_api ALIAS celix_remote_services_api)

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_services_api/README.md
----------------------------------------------------------------------
diff --git a/remote_services/remote_services_api/README.md b/remote_services/remote_services_api/README.md
new file mode 100644
index 0000000..2e3d268
--- /dev/null
+++ b/remote_services/remote_services_api/README.md
@@ -0,0 +1,11 @@
+# Remote Service Admin
+
+The Remote Service Admin (RSA) provides the mechanisms to import and export services when instructed to do so by the Topology Manager. 
+
+To delegate method calls to the actual service implementation, the RSA_SHM and the RSA_HTTP are using "endpoint/proxy" bundles, which has all the knowledge about the marshalling and unmarshalling of data for the service. The RSA_DFI implementation combines a [foreign function interface](https://en.wikipedia.org/wiki/Foreign_function_interface) technique together with manualy created descriptors.  
+
+Note that this folder contains code commonly used by the RSA implementations and therefore does not include any CMAKE configuration.
+
+## Properties
+    ENDPOINTS				 defines the relative directory where endpoints and proxys can be found (default: endpoints)
+    CELIX_FRAMEWORK_EXTENDER_PATH  Used in RSA_DFI only. Can be used to define a path to use as an extender path point for the framework bundle. For normal bundles the bundle cache is used. 

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/remote_services_api/include/remote_constants.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_services_api/include/remote_constants.h b/remote_services/remote_services_api/include/remote_constants.h
new file mode 100644
index 0000000..277f837
--- /dev/null
+++ b/remote_services/remote_services_api/include/remote_constants.h
@@ -0,0 +1,31 @@
+/**
+ *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.
+ */
+
+#ifndef REMOTE_CONSTANTS_H_
+#define REMOTE_CONSTANTS_H_
+
+static const char * const OSGI_RSA_SERVICE_EXPORTED_INTERFACES = "service.exported.interfaces";
+static const char * const OSGI_RSA_ENDPOINT_FRAMEWORK_UUID = "endpoint.framework.uuid";
+static const char * const OSGI_RSA_ENDPOINT_SERVICE_ID = "endpoint.service.id";
+static const char * const OSGI_RSA_ENDPOINT_ID = "endpoint.id";
+static const char * const OSGI_RSA_SERVICE_IMPORTED = "service.imported";
+static const char * const OSGI_RSA_SERVICE_IMPORTED_CONFIGS = "service.imported.configs";
+static const char * const OSGI_RSA_SERVICE_LOCATION = "service.location";
+
+#endif /* REMOTE_CONSTANTS_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/rsa_common/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/rsa_common/CMakeLists.txt b/remote_services/rsa_common/CMakeLists.txt
new file mode 100644
index 0000000..27c2dba
--- /dev/null
+++ b/remote_services/rsa_common/CMakeLists.txt
@@ -0,0 +1,29 @@
+# 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.
+
+add_library(celix_rsa_common STATIC
+    src/endpoint_description.c
+    src/export_registration_impl.c
+    src/import_registration_impl.c
+)
+target_include_directories(celix_rsa_common PRIVATE src)
+target_link_libraries(celix_rsa_common PUBLIC Celix::framework Celix::rsa_spi Celix::log_helper)
+
+install(TARGETS celix_rsa_common EXPORT celix COMPONENT rsa DESTINATION ${CMAKE_INSTALL_LIBDIR})
+
+#Setup target aliases to match external usage
+add_library(Celix::rsa_common ALIAS celix_rsa_common)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/rsa_common/src/endpoint_description.c
----------------------------------------------------------------------
diff --git a/remote_services/rsa_common/src/endpoint_description.c b/remote_services/rsa_common/src/endpoint_description.c
new file mode 100644
index 0000000..0d8b684
--- /dev/null
+++ b/remote_services/rsa_common/src/endpoint_description.c
@@ -0,0 +1,89 @@
+/**
+ *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.
+ */
+/*
+ * endpoint_description.c
+ *
+ *  \date       25 Jul 2014
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <string.h>
+
+#include "celix_errno.h"
+#include "celix_log.h"
+
+#include "endpoint_description.h"
+#include "remote_constants.h"
+#include "constants.h"
+
+static celix_status_t endpointDescription_verifyLongProperty(properties_pt properties, char *propertyName, unsigned long *longProperty);
+
+celix_status_t endpointDescription_create(properties_pt properties, endpoint_description_pt *endpointDescription) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	unsigned long serviceId = 0UL;
+	status = endpointDescription_verifyLongProperty(properties, (char *) OSGI_RSA_ENDPOINT_SERVICE_ID, &serviceId);
+	if (status != CELIX_SUCCESS) {
+		return status;
+	}
+
+	endpoint_description_pt ep = calloc(1,sizeof(*ep));
+
+    ep->properties = properties;
+    ep->frameworkUUID = (char*)properties_get(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
+    ep->id = (char*)properties_get(properties, OSGI_RSA_ENDPOINT_ID);
+    ep->service = strndup(properties_get(properties, OSGI_FRAMEWORK_OBJECTCLASS), 1024*10);
+    ep->serviceId = serviceId;
+
+    if (!(ep->frameworkUUID) || !(ep->id) || !(ep->service) ) {
+    	fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "ENDPOINT_DESCRIPTION: incomplete description!.");
+    	status = CELIX_BUNDLE_EXCEPTION;
+    }
+
+    if(status == CELIX_SUCCESS){
+	*endpointDescription = ep;
+    }
+    else{
+	*endpointDescription = NULL;
+	free(ep);
+    }
+
+    return status;
+}
+
+celix_status_t endpointDescription_destroy(endpoint_description_pt description) {
+    properties_destroy(description->properties);
+    free(description->service);
+    free(description);
+    return CELIX_SUCCESS;
+}
+
+static celix_status_t endpointDescription_verifyLongProperty(properties_pt properties, char *propertyName, unsigned long *longProperty) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    const char *value = properties_get(properties, propertyName);
+    if (value == NULL) {
+        *longProperty = 0UL;
+    } else {
+        *longProperty = strtoul(value,NULL,10);
+    }
+
+    return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/rsa_common/src/export_registration_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/rsa_common/src/export_registration_impl.c b/remote_services/rsa_common/src/export_registration_impl.c
new file mode 100644
index 0000000..1c684e7
--- /dev/null
+++ b/remote_services/rsa_common/src/export_registration_impl.c
@@ -0,0 +1,257 @@
+/**
+ *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.
+ */
+/*
+ * export_registration_impl.c
+ *
+ *  \date       Oct 6, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+#include <stdlib.h>
+
+#include "constants.h"
+
+#include "celix_errno.h"
+
+#include "export_registration_impl.h"
+#include "remote_service_admin_impl.h"
+
+
+struct export_reference {
+	endpoint_description_pt endpoint;
+	service_reference_pt reference;
+};
+
+celix_status_t exportRegistration_endpointAdding(void * handle, service_reference_pt reference, void **service);
+celix_status_t exportRegistration_endpointAdded(void * handle, service_reference_pt reference, void *service);
+celix_status_t exportRegistration_endpointModified(void * handle, service_reference_pt reference, void *service);
+celix_status_t exportRegistration_endpointRemoved(void * handle, service_reference_pt reference, void *service);
+
+celix_status_t exportRegistration_createEndpointTracker(export_registration_pt registration, service_tracker_pt *tracker);
+
+celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, remote_service_admin_pt rsa, bundle_context_pt context, export_registration_pt *registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*registration = calloc(1, sizeof(**registration));
+	if (!*registration) {
+		status = CELIX_ENOMEM;
+	} else {
+		(*registration)->context = context;
+		(*registration)->closed = false;
+		(*registration)->endpointDescription = endpoint;
+		(*registration)->reference = reference;
+		(*registration)->rsa = rsa;
+		(*registration)->tracker = NULL;
+		(*registration)->endpoint = NULL;
+		(*registration)->endpointTracker = NULL;
+		(*registration)->exportReference = NULL;
+		(*registration)->bundle = NULL;
+		(*registration)->loghelper = helper;
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_destroy(export_registration_pt *registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	remoteServiceAdmin_destroyEndpointDescription(&(*registration)->endpointDescription);
+	free(*registration);
+
+	return status;
+}
+
+celix_status_t exportRegistration_startTracking(export_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (registration->endpointTracker == NULL) {
+		status = exportRegistration_createEndpointTracker(registration, &registration->endpointTracker);
+		if (status == CELIX_SUCCESS) {
+			status = serviceTracker_open(registration->endpointTracker);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_stopTracking(export_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (registration->endpointTracker != NULL) {
+		status = serviceTracker_close(registration->endpointTracker);
+		if (status != CELIX_SUCCESS) {
+		    logHelper_log(registration->loghelper, OSGI_LOGSERVICE_ERROR, "EXPORT_REGISTRATION: Could not close endpoint tracker");
+		}
+		else {
+			status = serviceTracker_destroy(registration->endpointTracker);
+		}
+	}
+	if (registration->tracker != NULL) {
+		status = serviceTracker_close(registration->tracker);
+		if (status != CELIX_SUCCESS) {
+			logHelper_log(registration->loghelper, OSGI_LOGSERVICE_ERROR, "EXPORT_REGISTRATION: Could not close service tracker");
+		}
+		else {
+			status = serviceTracker_destroy(registration->tracker);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_createEndpointTracker(export_registration_pt registration, service_tracker_pt *tracker) {
+	celix_status_t status;
+
+	service_tracker_customizer_pt customizer = NULL;
+
+	status = serviceTrackerCustomizer_create(registration, exportRegistration_endpointAdding,
+			exportRegistration_endpointAdded, exportRegistration_endpointModified, exportRegistration_endpointRemoved, &customizer);
+
+	if (status == CELIX_SUCCESS) {
+		char filter[512];
+
+		snprintf(filter, 512, "(&(%s=%s)(remote.interface=%s))", (char*) OSGI_FRAMEWORK_OBJECTCLASS, (char*) OSGI_RSA_REMOTE_ENDPOINT, registration->endpointDescription->service);
+		status = serviceTracker_createWithFilter(registration->context, filter, customizer, tracker);
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_endpointAdding(void * handle, service_reference_pt reference, void **service) {
+	celix_status_t status;
+	export_registration_pt registration = handle;
+
+	status = bundleContext_getService(registration->context, reference, service);
+
+	return status;
+}
+
+celix_status_t exportRegistration_endpointAdded(void * handle, service_reference_pt reference, void *endpoint_service) {
+	celix_status_t status = CELIX_SUCCESS;
+	export_registration_pt registration = handle;
+
+	remote_endpoint_service_pt endpoint = endpoint_service;
+	if (registration->endpoint == NULL) {
+		registration->endpoint = endpoint;
+		void *service = NULL;
+		status = bundleContext_getService(registration->context, registration->reference, &service);
+		if (status == CELIX_SUCCESS) {
+			endpoint->setService(endpoint->endpoint, service);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_endpointModified(void * handle, service_reference_pt reference, void *service) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	return status;
+}
+
+celix_status_t exportRegistration_endpointRemoved(void * handle, service_reference_pt reference, void *service) {
+	celix_status_t status = CELIX_SUCCESS;
+	export_registration_pt registration = handle;
+
+	remote_endpoint_service_pt endpoint = service;
+	if (registration->endpoint != NULL) {
+		endpoint->setService(endpoint->endpoint, NULL);
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_open(export_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+	const char *bundleStore = NULL;
+
+	bundleContext_getProperty(registration->context, BUNDLE_STORE_PROPERTY_NAME, &bundleStore);
+
+	if (bundleStore == NULL) {
+		bundleStore = DEFAULT_BUNDLE_STORE;
+	}
+	char name[256];
+
+	snprintf(name, 256, "%s/%s_endpoint.zip", bundleStore, registration->endpointDescription->service);
+
+	status = bundleContext_installBundle(registration->context, name, &registration->bundle);
+	if (status == CELIX_SUCCESS) {
+		status = bundle_start(registration->bundle);
+		if (status == CELIX_SUCCESS) {
+		}
+	}
+
+	return status;
+}
+
+celix_status_t exportRegistration_close(export_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	exportRegistration_stopTracking(registration);
+
+	bundle_uninstall(registration->bundle);
+
+
+	return status;
+}
+
+celix_status_t exportRegistration_getException(export_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+	return status;
+}
+
+celix_status_t exportRegistration_getExportReference(export_registration_pt registration, export_reference_pt *reference) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	registration->exportReference = calloc(1, sizeof(*registration->exportReference));
+
+	if (registration->exportReference == NULL) {
+		status = CELIX_ENOMEM;
+	} else {
+		registration->exportReference->endpoint = registration->endpointDescription;
+		registration->exportReference->reference = registration->reference;
+	}
+	
+	*reference = registration->exportReference;
+
+	return status;
+}
+
+celix_status_t exportRegistration_setEndpointDescription(export_registration_pt registration, endpoint_description_pt endpointDescription) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	registration->endpointDescription = endpointDescription;
+
+	return status;
+}
+
+celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*endpoint = reference->endpoint;
+
+	return status;
+}
+
+celix_status_t exportReference_getExportedService(export_reference_pt reference, service_reference_pt *service) {
+	celix_status_t status = CELIX_SUCCESS;
+	*service = reference->reference;
+	return status;
+}
+

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/rsa_common/src/export_registration_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/rsa_common/src/export_registration_impl.h b/remote_services/rsa_common/src/export_registration_impl.h
new file mode 100644
index 0000000..bb276f9
--- /dev/null
+++ b/remote_services/rsa_common/src/export_registration_impl.h
@@ -0,0 +1,61 @@
+/**
+ *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.
+ */
+/*
+ * export_registration_impl.h
+ *
+ *  \date       Oct 6, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef EXPORT_REGISTRATION_IMPL_H_
+#define EXPORT_REGISTRATION_IMPL_H_
+
+#include "remote_service_admin.h"
+#include "remote_endpoint.h"
+#include "service_tracker.h"
+#include "log_helper.h"
+
+struct export_registration {
+	bundle_context_pt context;
+	remote_service_admin_pt rsa;
+	endpoint_description_pt endpointDescription;
+	service_reference_pt reference;
+	log_helper_pt loghelper;
+
+	service_tracker_pt tracker;
+	service_tracker_pt endpointTracker;
+
+	remote_endpoint_service_pt endpoint;
+
+	export_reference_pt exportReference;
+	bundle_pt bundle;
+
+	bool closed;
+};
+
+celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, remote_service_admin_pt rsa, bundle_context_pt context, export_registration_pt *registration);
+celix_status_t exportRegistration_destroy(export_registration_pt *registration);
+celix_status_t exportRegistration_open(export_registration_pt registration);
+
+celix_status_t exportRegistration_setEndpointDescription(export_registration_pt registration, endpoint_description_pt endpointDescription);
+celix_status_t exportRegistration_startTracking(export_registration_pt registration);
+celix_status_t exportRegistration_stopTracking(export_registration_pt registration);
+
+#endif /* EXPORT_REGISTRATION_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/rsa_common/src/import_registration_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/rsa_common/src/import_registration_impl.c b/remote_services/rsa_common/src/import_registration_impl.c
new file mode 100644
index 0000000..9a84327
--- /dev/null
+++ b/remote_services/rsa_common/src/import_registration_impl.c
@@ -0,0 +1,274 @@
+/**
+ *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.
+ */
+/*
+ * import_registration_impl.c
+ *
+ *  \date       Oct 14, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <constants.h>
+
+#include "celix_errno.h"
+
+#include "import_registration_impl.h"
+#include "remote_service_admin_impl.h"
+
+struct import_reference {
+	endpoint_description_pt endpoint;
+	service_reference_pt reference;
+};
+
+
+
+celix_status_t importRegistration_proxyFactoryAdding(void * handle, service_reference_pt reference, void **service);
+celix_status_t importRegistration_proxyFactoryAdded(void * handle, service_reference_pt reference, void *service);
+celix_status_t importRegistration_proxyFactoryModified(void * handle, service_reference_pt reference, void *service);
+celix_status_t importRegistration_proxyFactoryRemoved(void * handle, service_reference_pt reference, void *service);
+
+celix_status_t importRegistration_create(endpoint_description_pt endpoint, remote_service_admin_pt rsa, sendToHandle sendToCallback, bundle_context_pt context, import_registration_pt *registration) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*registration = calloc(1, sizeof(**registration));
+	if (!*registration) {
+		status = CELIX_ENOMEM;
+	} else {
+		(*registration)->context = context;
+		(*registration)->closed = false;
+		(*registration)->endpointDescription = endpoint;
+		(*registration)->rsa = rsa;
+		(*registration)->sendToCallback = sendToCallback;
+		(*registration)->reference = NULL;
+		(*registration)->importReference = NULL;
+	}
+
+	return status;
+}
+
+celix_status_t importRegistration_destroy(import_registration_pt registration)
+{
+	free(registration);
+
+	return CELIX_SUCCESS;
+}
+
+
+celix_status_t importRegistrationFactory_create(log_helper_pt helper, char* serviceName, bundle_context_pt context, import_registration_factory_pt *registration_factory) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*registration_factory = calloc(1, sizeof(**registration_factory));
+	if (!*registration_factory) {
+		status = CELIX_ENOMEM;
+	} else {
+		(*registration_factory)->serviceName = strdup(serviceName);
+		(*registration_factory)->context = context;
+		(*registration_factory)->bundle = NULL;
+		(*registration_factory)->loghelper = helper;
+
+		arrayList_create(&(*registration_factory)->registrations);
+	}
+
+	return status;
+}
+
+
+
+celix_status_t importRegistrationFactory_destroy(import_registration_factory_pt* registration_factory) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (*registration_factory != NULL)
+	{
+		free((*registration_factory)->serviceName);
+		arrayList_destroy((*registration_factory)->registrations);
+
+		serviceTracker_destroy((*registration_factory)->proxyFactoryTracker);
+		free(*registration_factory);
+
+		*registration_factory = NULL;
+	}
+
+
+	return status;
+}
+
+
+celix_status_t importRegistrationFactory_open(import_registration_factory_pt registration_factory)
+{
+	celix_status_t status;
+
+	const char *bundleStore = NULL;
+	bundleContext_getProperty(registration_factory->context, BUNDLE_STORE_PROPERTY_NAME, &bundleStore);
+
+	if (bundleStore == NULL) {
+		bundleStore = DEFAULT_BUNDLE_STORE;
+	}
+
+	char name[256];
+	snprintf(name, 256, "%s/%s_proxy.zip", bundleStore, registration_factory->serviceName);
+
+	status = bundleContext_installBundle(registration_factory->context, name, &registration_factory->bundle);
+
+	if (status == CELIX_SUCCESS) {
+		status = bundle_start(registration_factory->bundle);
+		if (status == CELIX_SUCCESS) {
+			logHelper_log(registration_factory->loghelper, OSGI_LOGSERVICE_INFO, "%s successfully started.", name);
+		}
+	}
+	else {
+		logHelper_log(registration_factory->loghelper, OSGI_LOGSERVICE_ERROR, "%s could not be installed.", name);
+	}
+
+	return status;
+}
+
+celix_status_t importRegistrationFactory_close(import_registration_factory_pt registration_factory)
+{
+	celix_status_t status = CELIX_SUCCESS;
+
+
+	if (registration_factory->proxyFactoryTracker != NULL) {
+		serviceTracker_close(registration_factory->proxyFactoryTracker);
+	}
+
+	if (registration_factory->bundle != NULL) {
+		bundle_uninstall(registration_factory->bundle);
+	}
+
+	return status;
+}
+
+
+celix_status_t importRegistration_createProxyFactoryTracker(import_registration_factory_pt registration_factory, service_tracker_pt *tracker) {
+	celix_status_t status;
+	service_tracker_customizer_pt customizer = NULL;
+
+	status = serviceTrackerCustomizer_create(registration_factory, importRegistration_proxyFactoryAdding, importRegistration_proxyFactoryAdded, importRegistration_proxyFactoryModified, importRegistration_proxyFactoryRemoved, &customizer);
+
+	if (status == CELIX_SUCCESS) {
+		char filter[512];
+
+		snprintf(filter, 512, "(&(%s=%s)(proxy.interface=%s))", (char*) OSGI_FRAMEWORK_OBJECTCLASS, (char*) OSGI_RSA_REMOTE_PROXY_FACTORY, registration_factory->serviceName);
+		status = serviceTracker_createWithFilter(registration_factory->context, filter, customizer, tracker);
+
+		if (status == CELIX_SUCCESS)
+		{
+			serviceTracker_open(*tracker);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t importRegistration_proxyFactoryAdding(void * handle, service_reference_pt reference, void **service) {
+	celix_status_t status = CELIX_SUCCESS;
+	import_registration_factory_pt registration_factory = (import_registration_factory_pt) handle;
+
+	bundleContext_getService(registration_factory->context, reference, service);
+
+	return status;
+}
+
+celix_status_t importRegistration_proxyFactoryAdded(void * handle, service_reference_pt reference, void *service) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	import_registration_factory_pt registration_factory = (import_registration_factory_pt) handle;
+	registration_factory->trackedFactory = (remote_proxy_factory_service_pt) service;
+
+	return status;
+}
+
+celix_status_t importRegistration_proxyFactoryModified(void * handle, service_reference_pt reference, void *service) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	return status;
+}
+
+celix_status_t importRegistration_proxyFactoryRemoved(void * handle, service_reference_pt reference, void *service) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	import_registration_factory_pt registration_factory = (import_registration_factory_pt) handle;
+	registration_factory->trackedFactory = NULL;
+
+	return status;
+}
+
+
+
+celix_status_t importRegistrationFactory_install(log_helper_pt helper, char* serviceName, bundle_context_pt context, import_registration_factory_pt *registration_factory)
+{
+	celix_status_t status;
+
+	if ( (status = importRegistrationFactory_create(helper, serviceName, context, registration_factory)) == CELIX_SUCCESS) {
+		// starting the proxy tracker first allows us to pick up already available proxy factories
+		importRegistration_createProxyFactoryTracker(*registration_factory, &((*registration_factory)->proxyFactoryTracker));
+		logHelper_log((*registration_factory)->loghelper, OSGI_LOGSERVICE_INFO, "remoteServiceAdmin_importService: new registration_factory added for %s at %p", serviceName, (*registration_factory)->proxyFactoryTracker);
+
+		// check whether factory is available
+		if (((*registration_factory)->trackedFactory == NULL) && ((status = importRegistrationFactory_open(*registration_factory)) != CELIX_SUCCESS)) {
+			logHelper_log((*registration_factory)->loghelper, OSGI_LOGSERVICE_ERROR, "remoteServiceAdmin_importService: cannot open registration_factory for %s.", serviceName);
+
+			importRegistrationFactory_close(*registration_factory);
+			importRegistrationFactory_destroy(registration_factory);
+		}
+	}
+
+	return status;
+}
+
+
+
+
+celix_status_t importRegistration_getException(import_registration_pt registration) {
+	celix_status_t status = CELIX_SUCCESS;
+	return status;
+}
+
+
+celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (registration->importReference == NULL) {
+		registration->importReference = calloc(1, 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;
+}
+
+
+celix_status_t importReference_getImportedEndpoint(import_reference_pt reference) {
+	celix_status_t status = CELIX_SUCCESS;
+	return status;
+}
+
+celix_status_t importReference_getImportedService(import_reference_pt reference) {
+	celix_status_t status = CELIX_SUCCESS;
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/rsa_common/src/import_registration_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/rsa_common/src/import_registration_impl.h b/remote_services/rsa_common/src/import_registration_impl.h
new file mode 100644
index 0000000..7aa397f
--- /dev/null
+++ b/remote_services/rsa_common/src/import_registration_impl.h
@@ -0,0 +1,81 @@
+/**
+ *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.
+ */
+/*
+ * import_registration_impl.h
+ *
+ *  \date       Oct 14, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef IMPORT_REGISTRATION_IMPL_H_
+#define IMPORT_REGISTRATION_IMPL_H_
+
+#include "remote_service_admin.h"
+#include "remote_proxy.h"
+#include "service_tracker.h"
+#include "log_helper.h"
+
+struct import_registration {
+	bundle_context_pt context;
+	endpoint_description_pt endpointDescription;
+
+	service_reference_pt reference;
+	import_reference_pt importReference;
+
+	remote_service_admin_pt rsa;
+	sendToHandle sendToCallback;
+
+	bool closed;
+};
+
+
+
+struct import_registration_factory
+{
+	char* serviceName;
+	log_helper_pt loghelper;
+	remote_proxy_factory_service_pt trackedFactory;
+	service_tracker_pt proxyFactoryTracker;
+	bundle_context_pt context;
+	array_list_pt registrations;
+	bundle_pt bundle;
+};
+
+
+celix_status_t importRegistration_create(endpoint_description_pt endpoint, remote_service_admin_pt rsa, sendToHandle callback, bundle_context_pt context, import_registration_pt *registration);
+celix_status_t importRegistration_destroy(import_registration_pt registration);
+
+celix_status_t importRegistration_setEndpointDescription(import_registration_pt registration, endpoint_description_pt endpointDescription);
+celix_status_t importRegistration_setHandler(import_registration_pt registration, void * handler);
+celix_status_t importRegistration_setCallback(import_registration_pt registration, sendToHandle callback);
+
+celix_status_t importRegistration_getException(import_registration_pt registration);
+celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference);
+
+celix_status_t importRegistration_createProxyFactoryTracker(import_registration_factory_pt registration_factory, service_tracker_pt *tracker);
+
+celix_status_t importRegistrationFactory_destroy(import_registration_factory_pt* registration_factory);
+//celix_status_t importRegistrationFactory_open(import_registration_factory_pt registration_factory);
+celix_status_t importRegistrationFactory_close(import_registration_factory_pt registration_factory);
+celix_status_t importRegistrationFactory_install(log_helper_pt helper, char* serviceName, bundle_context_pt context, import_registration_factory_pt *registration_factory);
+
+
+
+#endif /* IMPORT_REGISTRATION_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/rsa_common/src/remote_proxy_factory_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/rsa_common/src/remote_proxy_factory_impl.c b/remote_services/rsa_common/src/remote_proxy_factory_impl.c
new file mode 100644
index 0000000..9f996d6
--- /dev/null
+++ b/remote_services/rsa_common/src/remote_proxy_factory_impl.c
@@ -0,0 +1,252 @@
+/**
+ * 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.
+ */
+
+/*
+ * remote_proxy_factory_impl.c
+ *
+ *  \date       22 Dec 2014
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "remote_proxy.h"
+
+typedef struct proxy_instance {
+	service_registration_pt registration_ptr;
+	void *service;
+	properties_pt properties;
+} *proxy_instance_pt;
+
+static celix_status_t remoteProxyFactory_registerProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription, remote_service_admin_pt rsa, sendToHandle sendToCallback);
+static celix_status_t remoteProxyFactory_unregisterProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription);
+
+celix_status_t remoteProxyFactory_create(bundle_context_pt context, char *service, void *handle,
+		createProxyService create, destroyProxyService destroy,
+		remote_proxy_factory_pt *remote_proxy_factory_ptr) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*remote_proxy_factory_ptr = calloc(1, sizeof(**remote_proxy_factory_ptr));
+	if (!*remote_proxy_factory_ptr) {
+		status = CELIX_ENOMEM;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		(*remote_proxy_factory_ptr)->context_ptr = context;
+		(*remote_proxy_factory_ptr)->service = strdup(service);
+
+		(*remote_proxy_factory_ptr)->remote_proxy_factory_service_ptr = NULL;
+		(*remote_proxy_factory_ptr)->properties = NULL;
+		(*remote_proxy_factory_ptr)->registration = NULL;
+
+		(*remote_proxy_factory_ptr)->proxy_instances = hashMap_create(NULL, NULL, NULL, NULL);
+
+		(*remote_proxy_factory_ptr)->handle = handle;
+
+		(*remote_proxy_factory_ptr)->create_proxy_service_ptr = create;
+		(*remote_proxy_factory_ptr)->destroy_proxy_service_ptr = destroy;
+	}
+
+	return status;
+}
+
+celix_status_t remoteProxyFactory_destroy(remote_proxy_factory_pt *remote_proxy_factory_ptr) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (!*remote_proxy_factory_ptr) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		if ((*remote_proxy_factory_ptr)->proxy_instances) {
+			hashMap_destroy((*remote_proxy_factory_ptr)->proxy_instances, false, false);
+			(*remote_proxy_factory_ptr)->proxy_instances = NULL;
+		}
+		if ((*remote_proxy_factory_ptr)->service) {
+			free((*remote_proxy_factory_ptr)->service);
+			(*remote_proxy_factory_ptr)->service = NULL;
+		}
+		free(*remote_proxy_factory_ptr);
+		*remote_proxy_factory_ptr = NULL;
+	}
+
+	return status;
+}
+
+celix_status_t remoteProxyFactory_register(remote_proxy_factory_pt remote_proxy_factory_ptr) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	remote_proxy_factory_ptr->remote_proxy_factory_service_ptr = calloc(1, sizeof(*remote_proxy_factory_ptr->remote_proxy_factory_service_ptr));
+	if (!remote_proxy_factory_ptr->remote_proxy_factory_service_ptr) {
+		status = CELIX_ENOMEM;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		remote_proxy_factory_ptr->remote_proxy_factory_service_ptr->factory = remote_proxy_factory_ptr;
+		remote_proxy_factory_ptr->remote_proxy_factory_service_ptr->registerProxyService = remoteProxyFactory_registerProxyService;
+		remote_proxy_factory_ptr->remote_proxy_factory_service_ptr->unregisterProxyService = remoteProxyFactory_unregisterProxyService;
+
+		remote_proxy_factory_ptr->properties = properties_create();
+		if (!remote_proxy_factory_ptr->properties) {
+			status = CELIX_BUNDLE_EXCEPTION;
+		} else {
+			properties_set(remote_proxy_factory_ptr->properties, "proxy.interface", remote_proxy_factory_ptr->service);
+		}
+	}
+
+	if (status == CELIX_SUCCESS) {
+		status = bundleContext_registerService(remote_proxy_factory_ptr->context_ptr, OSGI_RSA_REMOTE_PROXY_FACTORY,
+				remote_proxy_factory_ptr->remote_proxy_factory_service_ptr, remote_proxy_factory_ptr->properties, &remote_proxy_factory_ptr->registration);
+	}
+
+	return status;
+}
+
+celix_status_t remoteProxyFactory_unregister(remote_proxy_factory_pt remote_proxy_factory_ptr) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (!remote_proxy_factory_ptr) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	// #TODO Remove proxy registrations
+	if (status == CELIX_SUCCESS) {
+
+		hash_map_iterator_pt iter = hashMapIterator_create(remote_proxy_factory_ptr->proxy_instances);
+		while(hashMapIterator_hasNext(iter)){
+			proxy_instance_pt proxy_instance_ptr = (proxy_instance_pt)hashMapIterator_nextValue(iter);
+
+			if (proxy_instance_ptr->service) {
+				remote_proxy_factory_ptr->destroy_proxy_service_ptr(remote_proxy_factory_ptr->handle, proxy_instance_ptr->service);
+			}
+			free(proxy_instance_ptr);
+		}
+		hashMapIterator_destroy(iter);
+
+		if (remote_proxy_factory_ptr->registration) {
+			status = serviceRegistration_unregister(remote_proxy_factory_ptr->registration);
+			remote_proxy_factory_ptr->properties = NULL;
+		}
+		if (remote_proxy_factory_ptr->properties) {
+			properties_destroy(remote_proxy_factory_ptr->properties);
+		}
+		if (remote_proxy_factory_ptr->remote_proxy_factory_service_ptr) {
+			free(remote_proxy_factory_ptr->remote_proxy_factory_service_ptr);
+		}
+	}
+
+	return status;
+}
+
+
+static celix_status_t remoteProxyFactory_registerProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription, remote_service_admin_pt rsa, sendToHandle sendToCallback) {
+	celix_status_t status = CELIX_SUCCESS;
+	proxy_instance_pt proxy_instance_ptr = NULL;
+
+	if (!remote_proxy_factory_ptr || !remote_proxy_factory_ptr->create_proxy_service_ptr) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		proxy_instance_ptr = calloc(1, sizeof(*proxy_instance_ptr));
+		if (!proxy_instance_ptr) {
+			status = CELIX_ENOMEM;
+		}
+	}
+
+	if (status == CELIX_SUCCESS) {
+		proxy_instance_ptr->properties = properties_create();
+		if (!proxy_instance_ptr->properties) {
+			status = CELIX_ENOMEM;
+		}
+	}
+
+	if (status == CELIX_SUCCESS) {
+		status = remote_proxy_factory_ptr->create_proxy_service_ptr(remote_proxy_factory_ptr->handle, endpointDescription, rsa, sendToCallback, proxy_instance_ptr->properties, &proxy_instance_ptr->service);
+	}
+
+	if (status == CELIX_SUCCESS) {
+		properties_set(proxy_instance_ptr->properties, "proxy.interface", remote_proxy_factory_ptr->service);
+
+		hash_map_iterator_pt iter = hashMapIterator_create(endpointDescription->properties);
+		while (hashMapIterator_hasNext(iter)) {
+			hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+			char *key = hashMapEntry_getKey(entry);
+			char *value = hashMapEntry_getValue(entry);
+
+			properties_set(proxy_instance_ptr->properties, key, value);
+		}
+		hashMapIterator_destroy(iter);
+	}
+
+	if (status == CELIX_SUCCESS) {
+		status = bundleContext_registerService(remote_proxy_factory_ptr->context_ptr, remote_proxy_factory_ptr->service, proxy_instance_ptr->service, proxy_instance_ptr->properties, &proxy_instance_ptr->registration_ptr);
+	}
+
+	if (status == CELIX_SUCCESS) {
+		hashMap_put(remote_proxy_factory_ptr->proxy_instances, endpointDescription, proxy_instance_ptr);
+	}
+
+	if(status!=CELIX_SUCCESS){
+		if(proxy_instance_ptr != NULL){
+			if(proxy_instance_ptr->properties != NULL){
+				properties_destroy(proxy_instance_ptr->properties);
+			}
+			free(proxy_instance_ptr);
+		}
+	}
+
+	return status;
+}
+
+static celix_status_t remoteProxyFactory_unregisterProxyService(remote_proxy_factory_pt remote_proxy_factory_ptr, endpoint_description_pt endpointDescription) {
+	celix_status_t status = CELIX_SUCCESS;
+	proxy_instance_pt proxy_instance_ptr = NULL;
+
+	if (!remote_proxy_factory_ptr || !endpointDescription || !remote_proxy_factory_ptr->proxy_instances || !remote_proxy_factory_ptr->handle) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		proxy_instance_ptr = hashMap_remove(remote_proxy_factory_ptr->proxy_instances, endpointDescription);
+		if (proxy_instance_ptr == NULL) {
+			status = CELIX_BUNDLE_EXCEPTION;
+		}
+	}
+
+	if (status == CELIX_SUCCESS) {
+		if (proxy_instance_ptr->registration_ptr) {
+			status = serviceRegistration_unregister(proxy_instance_ptr->registration_ptr);
+			proxy_instance_ptr->properties = NULL;
+		}
+		if (proxy_instance_ptr->service) {
+			status = remote_proxy_factory_ptr->destroy_proxy_service_ptr(remote_proxy_factory_ptr->handle, proxy_instance_ptr->service);
+		}
+		if (proxy_instance_ptr->properties) {
+			properties_destroy(proxy_instance_ptr->properties);
+		}
+        free(proxy_instance_ptr);
+	}
+
+	return status;
+}
+
+

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/rsa_common/src/remote_service_admin_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/rsa_common/src/remote_service_admin_impl.h b/remote_services/rsa_common/src/remote_service_admin_impl.h
new file mode 100644
index 0000000..e8a5e1f
--- /dev/null
+++ b/remote_services/rsa_common/src/remote_service_admin_impl.h
@@ -0,0 +1,49 @@
+/**
+ *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.
+ */
+/*
+ * remote_service_admin_impl.h
+ *
+ *  \date       Dec 5, 2013
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_SERVICE_ADMIN_IMPL_H_
+#define REMOTE_SERVICE_ADMIN_IMPL_H_
+
+#include "remote_service_admin.h"
+
+#define BUNDLE_STORE_PROPERTY_NAME "ENDPOINTS"
+#define DEFAULT_BUNDLE_STORE "endpoints"
+
+celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin);
+celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin);
+
+celix_status_t remoteServiceAdmin_send(remote_service_admin_pt rsa, endpoint_description_pt endpointDescription, char *methodSignature, char **reply, int* replyStatus);
+
+celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations);
+celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_pt admin, export_registration_pt registration);
+celix_status_t remoteServiceAdmin_getExportedServices(remote_service_admin_pt admin, array_list_pt *services);
+celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt admin, array_list_pt *services);
+celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpoint, import_registration_pt *registration);
+celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration);
+
+celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description);
+
+#endif /* REMOTE_SERVICE_ADMIN_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/rsa_spi/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/rsa_spi/CMakeLists.txt b/remote_services/rsa_spi/CMakeLists.txt
new file mode 100644
index 0000000..ea4ec95
--- /dev/null
+++ b/remote_services/rsa_spi/CMakeLists.txt
@@ -0,0 +1,29 @@
+# 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.
+
+add_library(rsa_spi INTERFACE)
+target_include_directories(rsa_spi INTERFACE
+    $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
+    $<INSTALL_INTERFACE:include/celix/rsa>
+)
+target_link_libraries(rsa_spi INTERFACE Celix::remote_services_api)
+
+install(TARGETS rsa_spi EXPORT celix DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT rsa)
+install(DIRECTORY include/ DESTINATION include/celix/rsa COMPONENT rsa)
+
+#Setup target aliases to match external usage
+add_library(Celix::rsa_spi ALIAS rsa_spi)

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/rsa_spi/README.md
----------------------------------------------------------------------
diff --git a/remote_services/rsa_spi/README.md b/remote_services/rsa_spi/README.md
new file mode 100644
index 0000000..2e3d268
--- /dev/null
+++ b/remote_services/rsa_spi/README.md
@@ -0,0 +1,11 @@
+# Remote Service Admin
+
+The Remote Service Admin (RSA) provides the mechanisms to import and export services when instructed to do so by the Topology Manager. 
+
+To delegate method calls to the actual service implementation, the RSA_SHM and the RSA_HTTP are using "endpoint/proxy" bundles, which has all the knowledge about the marshalling and unmarshalling of data for the service. The RSA_DFI implementation combines a [foreign function interface](https://en.wikipedia.org/wiki/Foreign_function_interface) technique together with manualy created descriptors.  
+
+Note that this folder contains code commonly used by the RSA implementations and therefore does not include any CMAKE configuration.
+
+## Properties
+    ENDPOINTS				 defines the relative directory where endpoints and proxys can be found (default: endpoints)
+    CELIX_FRAMEWORK_EXTENDER_PATH  Used in RSA_DFI only. Can be used to define a path to use as an extender path point for the framework bundle. For normal bundles the bundle cache is used. 

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/rsa_spi/include/endpoint_description.h
----------------------------------------------------------------------
diff --git a/remote_services/rsa_spi/include/endpoint_description.h b/remote_services/rsa_spi/include/endpoint_description.h
new file mode 100644
index 0000000..de27d2e
--- /dev/null
+++ b/remote_services/rsa_spi/include/endpoint_description.h
@@ -0,0 +1,50 @@
+/**
+ *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.
+ */
+/*
+ * endpoint_description.h
+ *
+ *  \date       25 Jul 2014
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+#ifndef ENDPOINT_DESCRIPTION_H_
+#define ENDPOINT_DESCRIPTION_H_
+
+#include "properties.h"
+#include "array_list.h"
+
+struct endpoint_description {
+    char *frameworkUUID;
+    char *id;
+    // array_list_pt intents;
+    char *service;
+    // HASH_MAP packageVersions;
+    properties_pt properties;
+    unsigned long serviceId;
+};
+
+typedef struct endpoint_description endpoint_description_t;
+typedef endpoint_description_t* endpoint_description_pt;
+
+celix_status_t endpointDescription_create(properties_pt properties, endpoint_description_pt *endpointDescription);
+celix_status_t endpointDescription_destroy(endpoint_description_pt description);
+
+
+#endif /* ENDPOINT_DESCRIPTION_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/rsa_spi/include/endpoint_listener.h
----------------------------------------------------------------------
diff --git a/remote_services/rsa_spi/include/endpoint_listener.h b/remote_services/rsa_spi/include/endpoint_listener.h
new file mode 100644
index 0000000..2e6359f
--- /dev/null
+++ b/remote_services/rsa_spi/include/endpoint_listener.h
@@ -0,0 +1,49 @@
+/**
+ *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.
+ */
+/*
+ * endpoint_listener.h
+ *
+ *  \date       Sep 29, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef ENDPOINT_LISTENER_H_
+#define ENDPOINT_LISTENER_H_
+
+#include "array_list.h"
+#include "properties.h"
+
+#include "endpoint_description.h"
+
+static const char * const OSGI_ENDPOINT_LISTENER_SERVICE = "endpoint_listener";
+
+static const char * const OSGI_ENDPOINT_LISTENER_SCOPE = "endpoint.listener.scope";
+
+struct endpoint_listener {
+	void *handle;
+	celix_status_t (*endpointAdded)(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
+	celix_status_t (*endpointRemoved)(void *handle, endpoint_description_pt endpoint, char *machtedFilter);
+};
+
+typedef struct endpoint_listener endpoint_listener_t;
+typedef endpoint_listener_t *endpoint_listener_pt;
+
+
+#endif /* ENDPOINT_LISTENER_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/rsa_spi/include/export_registration.h
----------------------------------------------------------------------
diff --git a/remote_services/rsa_spi/include/export_registration.h b/remote_services/rsa_spi/include/export_registration.h
new file mode 100644
index 0000000..dc3882b
--- /dev/null
+++ b/remote_services/rsa_spi/include/export_registration.h
@@ -0,0 +1,22 @@
+/*
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#ifndef CELIX_EXPORT_REGISTRATION_H
+#define CELIX_EXPORT_REGISTRATION_H
+
+#include "celix_errno.h"
+#include "endpoint_description.h"
+#include "service_reference.h"
+
+typedef struct export_registration *export_registration_pt;
+
+typedef struct export_reference *export_reference_pt;
+
+celix_status_t exportRegistration_close(export_registration_pt registration);
+celix_status_t exportRegistration_getException(export_registration_pt registration);
+celix_status_t exportRegistration_getExportReference(export_registration_pt registration, export_reference_pt *reference);
+
+celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint);
+celix_status_t exportReference_getExportedService(export_reference_pt reference, service_reference_pt *service);
+
+#endif //CELIX_EXPORT_REGISTRATION_H

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/rsa_spi/include/import_registration.h
----------------------------------------------------------------------
diff --git a/remote_services/rsa_spi/include/import_registration.h b/remote_services/rsa_spi/include/import_registration.h
new file mode 100644
index 0000000..ef8193f
--- /dev/null
+++ b/remote_services/rsa_spi/include/import_registration.h
@@ -0,0 +1,22 @@
+/*
+ * Licensed under Apache License v2. See LICENSE for more information.
+ */
+#ifndef CELIX_IMPORT_REGISTRATION_H
+#define CELIX_IMPORT_REGISTRATION_H
+
+#include "celix_errno.h"
+#include "endpoint_description.h"
+#include "service_reference.h"
+
+typedef struct import_registration *import_registration_pt;
+
+typedef struct import_reference *import_reference_pt;
+
+celix_status_t importRegistration_close(import_registration_pt registration);
+celix_status_t importRegistration_getException(import_registration_pt registration);
+celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference);
+
+celix_status_t importReference_getImportedEndpoint(import_reference_pt reference);
+celix_status_t importReference_getImportedService(import_reference_pt reference);
+
+#endif //CELIX_IMPORT_REGISTRATION_H

http://git-wip-us.apache.org/repos/asf/celix/blob/81804e00/remote_services/rsa_spi/include/remote_constants.h
----------------------------------------------------------------------
diff --git a/remote_services/rsa_spi/include/remote_constants.h b/remote_services/rsa_spi/include/remote_constants.h
new file mode 100644
index 0000000..0736685
--- /dev/null
+++ b/remote_services/rsa_spi/include/remote_constants.h
@@ -0,0 +1,38 @@
+/**
+ *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.
+ */
+/*
+ * remote_constants.h
+ *
+ *  \date       Sep 30, 2011
+ *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright	Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_CONSTANTS_H_
+#define REMOTE_CONSTANTS_H_
+
+static const char * const OSGI_RSA_SERVICE_EXPORTED_INTERFACES = "service.exported.interfaces";
+static const char * const OSGI_RSA_ENDPOINT_FRAMEWORK_UUID = "endpoint.framework.uuid";
+static const char * const OSGI_RSA_ENDPOINT_SERVICE_ID = "endpoint.service.id";
+static const char * const OSGI_RSA_ENDPOINT_ID = "endpoint.id";
+static const char * const OSGI_RSA_SERVICE_IMPORTED = "service.imported";
+static const char * const OSGI_RSA_SERVICE_IMPORTED_CONFIGS = "service.imported.configs";
+static const char * const OSGI_RSA_SERVICE_LOCATION = "service.location";
+
+#endif /* REMOTE_CONSTANTS_H_ */