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 2021/10/07 18:47:03 UTC

[celix] branch feature/remove_psa_versions_v1 created (now f1efeac)

This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a change to branch feature/remove_psa_versions_v1
in repository https://gitbox.apache.org/repos/asf/celix.git.


      at f1efeac  Removes integration test for pubsub_admin _v1 versions

This branch includes the following new commits:

     new 99865c0  Removes pubsub admin _v1 versions
     new f1efeac  Removes integration test for pubsub_admin _v1 versions

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[celix] 01/02: Removes pubsub admin _v1 versions

Posted by pn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch feature/remove_psa_versions_v1
in repository https://gitbox.apache.org/repos/asf/celix.git

commit 99865c01c99f26b39f47f90c9fcbafb103bf5def
Author: Pepijn Noltes <pe...@gmail.com>
AuthorDate: Thu Oct 7 20:32:21 2021 +0200

    Removes pubsub admin _v1 versions
---
 bundles/pubsub/CMakeLists.txt                      |   14 +-
 bundles/pubsub/examples/CMakeLists.txt             |   24 +-
 .../pubsub_admin_tcp/{v2 => }/CMakeLists.txt       |    0
 .../pubsub_admin_tcp/{v2 => }/src/psa_activator.c  |    0
 .../{v2 => }/src/pubsub_psa_tcp_constants.h        |    0
 .../{v2 => }/src/pubsub_tcp_admin.c                |    0
 .../{v2 => }/src/pubsub_tcp_admin.h                |    0
 .../{v2 => }/src/pubsub_tcp_common.c               |    0
 .../{v2 => }/src/pubsub_tcp_common.h               |    0
 .../{v2 => }/src/pubsub_tcp_handler.c              |    0
 .../{v2 => }/src/pubsub_tcp_handler.h              |    0
 .../{v2 => }/src/pubsub_tcp_topic_receiver.c       |    0
 .../{v2 => }/src/pubsub_tcp_topic_receiver.h       |    0
 .../{v2 => }/src/pubsub_tcp_topic_sender.c         |    0
 .../{v2 => }/src/pubsub_tcp_topic_sender.h         |    0
 bundles/pubsub/pubsub_admin_tcp/v1/CMakeLists.txt  |   46 -
 .../pubsub/pubsub_admin_tcp/v1/src/psa_activator.c |  144 --
 .../v1/src/pubsub_psa_tcp_constants.h              |  140 --
 .../pubsub_admin_tcp/v1/src/pubsub_tcp_admin.c     |  785 -----------
 .../pubsub_admin_tcp/v1/src/pubsub_tcp_admin.h     |   80 --
 .../pubsub_admin_tcp/v1/src/pubsub_tcp_common.c    |   38 -
 .../pubsub_admin_tcp/v1/src/pubsub_tcp_common.h    |   33 -
 .../pubsub_admin_tcp/v1/src/pubsub_tcp_handler.c   | 1448 --------------------
 .../pubsub_admin_tcp/v1/src/pubsub_tcp_handler.h   |   92 --
 .../v1/src/pubsub_tcp_topic_receiver.c             |  804 -----------
 .../v1/src/pubsub_tcp_topic_receiver.h             |   57 -
 .../v1/src/pubsub_tcp_topic_sender.c               |  613 ---------
 .../v1/src/pubsub_tcp_topic_sender.h               |   60 -
 .../pubsub_admin_websocket/{v2 => }/CMakeLists.txt |    0
 .../{v2 => }/src/psa_activator.c                   |    0
 .../{v2 => }/src/pubsub_psa_websocket_constants.h  |    0
 .../{v2 => }/src/pubsub_websocket_admin.c          |    0
 .../{v2 => }/src/pubsub_websocket_admin.h          |    0
 .../{v2 => }/src/pubsub_websocket_common.c         |    0
 .../{v2 => }/src/pubsub_websocket_common.h         |    0
 .../{v2 => }/src/pubsub_websocket_topic_receiver.c |    0
 .../{v2 => }/src/pubsub_websocket_topic_receiver.h |    0
 .../{v2 => }/src/pubsub_websocket_topic_sender.c   |    0
 .../{v2 => }/src/pubsub_websocket_topic_sender.h   |    0
 .../pubsub_admin_websocket/v1/CMakeLists.txt       |   47 -
 .../pubsub_admin_websocket/v1/src/psa_activator.c  |  112 --
 .../v1/src/pubsub_psa_websocket_constants.h        |   54 -
 .../v1/src/pubsub_websocket_admin.c                |  605 --------
 .../v1/src/pubsub_websocket_admin.h                |   52 -
 .../v1/src/pubsub_websocket_common.c               |   68 -
 .../v1/src/pubsub_websocket_common.h               |   43 -
 .../v1/src/pubsub_websocket_topic_receiver.c       |  774 -----------
 .../v1/src/pubsub_websocket_topic_receiver.h       |   47 -
 .../v1/src/pubsub_websocket_topic_sender.c         |  381 -----
 .../v1/src/pubsub_websocket_topic_sender.h         |   43 -
 .../pubsub_admin_zmq/{v2 => }/CMakeLists.txt       |    0
 .../pubsub_admin_zmq/{v2 => }/src/psa_activator.c  |    0
 .../{v2 => }/src/pubsub_psa_zmq_constants.h        |    0
 .../{v2 => }/src/pubsub_zmq_admin.c                |    0
 .../{v2 => }/src/pubsub_zmq_admin.h                |    0
 .../{v2 => }/src/pubsub_zmq_topic_receiver.c       |    0
 .../{v2 => }/src/pubsub_zmq_topic_receiver.h       |    0
 .../{v2 => }/src/pubsub_zmq_topic_sender.c         |    0
 .../{v2 => }/src/pubsub_zmq_topic_sender.h         |    0
 .../pubsub_admin_zmq/{v2 => }/src/zmq_crypto.c     |    0
 .../pubsub_admin_zmq/{v2 => }/src/zmq_crypto.h     |    0
 bundles/pubsub/pubsub_admin_zmq/v1/CMakeLists.txt  |   61 -
 .../pubsub/pubsub_admin_zmq/v1/src/psa_activator.c |  141 --
 .../v1/src/pubsub_psa_zmq_constants.h              |  112 --
 .../pubsub_admin_zmq/v1/src/pubsub_zmq_admin.c     |  885 ------------
 .../pubsub_admin_zmq/v1/src/pubsub_zmq_admin.h     |   57 -
 .../v1/src/pubsub_zmq_topic_receiver.c             |  855 ------------
 .../v1/src/pubsub_zmq_topic_receiver.h             |   53 -
 .../v1/src/pubsub_zmq_topic_sender.c               |  748 ----------
 .../v1/src/pubsub_zmq_topic_sender.h               |   60 -
 .../pubsub/pubsub_admin_zmq/v1/src/zmq_crypto.c    |  278 ----
 .../pubsub/pubsub_admin_zmq/v1/src/zmq_crypto.h    |   41 -
 cmake/CelixConfig.cmake                            |    2 +-
 73 files changed, 17 insertions(+), 9880 deletions(-)

diff --git a/bundles/pubsub/CMakeLists.txt b/bundles/pubsub/CMakeLists.txt
index 39c04b2..39275c5 100644
--- a/bundles/pubsub/CMakeLists.txt
+++ b/bundles/pubsub/CMakeLists.txt
@@ -21,16 +21,12 @@ if (PUBSUB)
     option(BUILD_PUBSUB_PSA_ZMQ "Build ZeroMQ PubSub Admin (LGPL License)" ON)
     if (BUILD_PUBSUB_PSA_ZMQ)
         option(BUILD_ZMQ_SECURITY "Build with security for ZeroMQ." OFF)
-        add_subdirectory(pubsub_admin_zmq/v1)
-        add_subdirectory(pubsub_admin_zmq/v2)
-        add_library(Celix::celix_pubsub_admin_zmq ALIAS celix_pubsub_admin_zmq)
+        add_subdirectory(pubsub_admin_zmq)
     endif (BUILD_PUBSUB_PSA_ZMQ)
 
     option(BUILD_PUBSUB_PSA_TCP "Build TCP PubSub Admin" ON)
     if (BUILD_PUBSUB_PSA_TCP)
-        add_subdirectory(pubsub_admin_tcp/v1)
-        add_subdirectory(pubsub_admin_tcp/v2)
-        add_library(Celix::celix_pubsub_admin_tcp ALIAS celix_pubsub_admin_tcp)
+        add_subdirectory(pubsub_admin_tcp)
     endif (BUILD_PUBSUB_PSA_TCP)
 
     option(BUILD_PUBSUB_PSA_UDP_MC "Build UDP MC PubSub Admin" ON)
@@ -40,9 +36,7 @@ if (PUBSUB)
 
     option(BUILD_PUBSUB_PSA_WS "Build WebSocket PubSub Admin" ON)
     if (BUILD_PUBSUB_PSA_WS)
-        add_subdirectory(pubsub_admin_websocket/v1)
-        add_subdirectory(pubsub_admin_websocket/v2)
-        add_library(Celix::celix_pubsub_admin_websocket ALIAS celix_pubsub_admin_websocket)
+        add_subdirectory(pubsub_admin_websocket)
     endif (BUILD_PUBSUB_PSA_WS)
 
     add_subdirectory(pubsub_api)
@@ -58,7 +52,7 @@ if (PUBSUB)
     add_subdirectory(examples)
 
     if (ENABLE_TESTING)
-        add_subdirectory(integration)
+         add_subdirectory(integration)
     endif()
 
 endif(PUBSUB)
diff --git a/bundles/pubsub/examples/CMakeLists.txt b/bundles/pubsub/examples/CMakeLists.txt
index a34a28b..6b17310 100644
--- a/bundles/pubsub/examples/CMakeLists.txt
+++ b/bundles/pubsub/examples/CMakeLists.txt
@@ -108,7 +108,7 @@ if (BUILD_PUBSUB_PSA_TCP)
                 Celix::celix_pubsub_serializer_json
                 Celix::celix_pubsub_discovery_etcd
                 Celix::celix_pubsub_topology_manager
-                Celix::celix_pubsub_admin_tcp
+                Celix::celix_pubsub_admin_tcp_v2
                 Celix::celix_pubsub_protocol_wire_v2
                 celix_pubsub_poi_publisher
                 celix_pubsub_poi_publisher2
@@ -128,7 +128,7 @@ if (BUILD_PUBSUB_PSA_TCP)
                 Celix::celix_pubsub_serializer_json
                 Celix::celix_pubsub_discovery_etcd
                 Celix::celix_pubsub_topology_manager
-                Celix::celix_pubsub_admin_tcp
+                Celix::celix_pubsub_admin_tcp_v2
                 Celix::celix_pubsub_protocol_wire_v2
                 celix_pubsub_poi_subscriber
             PROPERTIES
@@ -147,7 +147,7 @@ if (BUILD_PUBSUB_PSA_TCP)
                 Celix::celix_pubsub_serializer_json
                 Celix::celix_pubsub_discovery_etcd
                 Celix::celix_pubsub_topology_manager
-                Celix::celix_pubsub_admin_tcp
+                Celix::celix_pubsub_admin_tcp_v2
                 Celix::celix_pubsub_protocol_wire_v2
                 celix_pubsub_poi_subscriber
             PROPERTIES
@@ -189,9 +189,9 @@ if (BUILD_PUBSUB_PSA_ZMQ)
                 Celix::celix_pubsub_serializer_json
                 Celix::celix_pubsub_discovery_etcd
                 Celix::celix_pubsub_topology_manager
-                Celix::celix_pubsub_admin_zmq
+                Celix::celix_pubsub_admin_zmq_v2
                 Celix::celix_pubsub_admin_udp_multicast
-                Celix::celix_pubsub_admin_tcp
+                Celix::celix_pubsub_admin_tcp_v2
                 Celix::celix_pubsub_protocol_wire_v1
                 celix_pubsub_poi_publisher
                 celix_pubsub_poi_publisher2
@@ -206,9 +206,9 @@ if (BUILD_PUBSUB_PSA_ZMQ)
                 Celix::celix_pubsub_serializer_json
                 Celix::celix_pubsub_discovery_etcd
                 Celix::celix_pubsub_topology_manager
-                Celix::celix_pubsub_admin_zmq
+                Celix::celix_pubsub_admin_zmq_v2
                 Celix::celix_pubsub_admin_udp_multicast
-                Celix::celix_pubsub_admin_tcp
+                Celix::celix_pubsub_admin_tcp_v2
                 Celix::celix_pubsub_protocol_wire_v1
                 celix_pubsub_poi_subscriber
         )
@@ -224,7 +224,7 @@ if (BUILD_PUBSUB_PSA_ZMQ)
             Celix::celix_pubsub_serializer_json
             Celix::celix_pubsub_discovery_etcd
             Celix::celix_pubsub_topology_manager
-            Celix::celix_pubsub_admin_zmq
+            Celix::celix_pubsub_admin_zmq_v2
             celix_pubsub_poi_publisher
             celix_pubsub_poi_subscriber
         PROPERTIES
@@ -241,7 +241,7 @@ if (BUILD_PUBSUB_PSA_ZMQ)
             Celix::celix_pubsub_protocol_wire_v1
             Celix::celix_pubsub_discovery_etcd
             Celix::celix_pubsub_topology_manager
-            Celix::celix_pubsub_admin_zmq
+            Celix::celix_pubsub_admin_zmq_v2
             celix_pubsub_poi_publisher
             celix_pubsub_poi_publisher2
             celix_pubsub_interceptors_example
@@ -262,7 +262,7 @@ if (BUILD_PUBSUB_PSA_ZMQ)
             Celix::celix_pubsub_protocol_wire_v1
             Celix::celix_pubsub_discovery_etcd
             Celix::celix_pubsub_topology_manager
-            Celix::celix_pubsub_admin_zmq
+            Celix::celix_pubsub_admin_zmq_v2
             celix_pubsub_poi_subscriber
             celix_pubsub_interceptors_example
         PROPERTIES
@@ -280,7 +280,7 @@ if (BUILD_PUBSUB_PSA_ZMQ)
             Celix::celix_pubsub_serializer_json
             Celix::celix_pubsub_discovery_etcd
             Celix::celix_pubsub_topology_manager
-            Celix::celix_pubsub_admin_zmq
+            Celix::celix_pubsub_admin_zmq_v2
             celix_pubsub_poi_subscriber
         PROPERTIES
             PSA_ZMQ_VERBOSE=true
@@ -417,7 +417,7 @@ if (BUILD_PUBSUB_PSA_WS)
             Celix::http_admin
             Celix::celix_pubsub_serializer_json
             Celix::celix_pubsub_topology_manager
-            Celix::celix_pubsub_admin_websocket
+            Celix::celix_pubsub_admin_websocket_v2
             celix_pubsub_websocket_example
         PROPERTIES
             PSA_TCP_VERBOSE=true
diff --git a/bundles/pubsub/pubsub_admin_tcp/v2/CMakeLists.txt b/bundles/pubsub/pubsub_admin_tcp/CMakeLists.txt
similarity index 100%
rename from bundles/pubsub/pubsub_admin_tcp/v2/CMakeLists.txt
rename to bundles/pubsub/pubsub_admin_tcp/CMakeLists.txt
diff --git a/bundles/pubsub/pubsub_admin_tcp/v2/src/psa_activator.c b/bundles/pubsub/pubsub_admin_tcp/src/psa_activator.c
similarity index 100%
rename from bundles/pubsub/pubsub_admin_tcp/v2/src/psa_activator.c
rename to bundles/pubsub/pubsub_admin_tcp/src/psa_activator.c
diff --git a/bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_psa_tcp_constants.h b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_psa_tcp_constants.h
similarity index 100%
rename from bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_psa_tcp_constants.h
rename to bundles/pubsub/pubsub_admin_tcp/src/pubsub_psa_tcp_constants.h
diff --git a/bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_admin.c b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_admin.c
similarity index 100%
rename from bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_admin.c
rename to bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_admin.c
diff --git a/bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_admin.h b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_admin.h
similarity index 100%
rename from bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_admin.h
rename to bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_admin.h
diff --git a/bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_common.c b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_common.c
similarity index 100%
rename from bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_common.c
rename to bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_common.c
diff --git a/bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_common.h b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_common.h
similarity index 100%
rename from bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_common.h
rename to bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_common.h
diff --git a/bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_handler.c b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_handler.c
similarity index 100%
rename from bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_handler.c
rename to bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_handler.c
diff --git a/bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_handler.h b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_handler.h
similarity index 100%
rename from bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_handler.h
rename to bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_handler.h
diff --git a/bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_topic_receiver.c b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_receiver.c
similarity index 100%
rename from bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_topic_receiver.c
rename to bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_receiver.c
diff --git a/bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_topic_receiver.h b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_receiver.h
similarity index 100%
rename from bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_topic_receiver.h
rename to bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_receiver.h
diff --git a/bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_topic_sender.c b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_sender.c
similarity index 100%
rename from bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_topic_sender.c
rename to bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_sender.c
diff --git a/bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_topic_sender.h b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_sender.h
similarity index 100%
rename from bundles/pubsub/pubsub_admin_tcp/v2/src/pubsub_tcp_topic_sender.h
rename to bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_sender.h
diff --git a/bundles/pubsub/pubsub_admin_tcp/v1/CMakeLists.txt b/bundles/pubsub/pubsub_admin_tcp/v1/CMakeLists.txt
deleted file mode 100644
index 9a181eb..0000000
--- a/bundles/pubsub/pubsub_admin_tcp/v1/CMakeLists.txt
+++ /dev/null
@@ -1,46 +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.
-
-message(STATUS "PubSub TCP Admin V1 is deprecated, and will eventually be replaced with PubSub TCP Admin v2")
-
-find_package(UUID REQUIRED)
-
-add_celix_bundle(celix_pubsub_admin_tcp
-    BUNDLE_SYMBOLICNAME "apache_celix_pubsub_admin_tcp"
-    VERSION "1.0.0"
-    GROUP "Celix/PubSub"
-    SOURCES
-        src/psa_activator.c
-        src/pubsub_tcp_admin.c
-        src/pubsub_tcp_topic_sender.c
-        src/pubsub_tcp_topic_receiver.c
-        src/pubsub_tcp_handler.c
-        src/pubsub_tcp_common.c
-)
-
-set_target_properties(celix_pubsub_admin_tcp PROPERTIES INSTALL_RPATH "$ORIGIN")
-target_link_libraries(celix_pubsub_admin_tcp PRIVATE Celix::pubsub_spi Celix::pubsub_utils)
-target_link_libraries(celix_pubsub_admin_tcp PRIVATE Celix::framework Celix::dfi Celix::log_helper)
-target_include_directories(celix_pubsub_admin_tcp PRIVATE src)
-# cmake find package UUID set the wrong include dir for OSX
-if (NOT APPLE)
-    target_link_libraries(celix_pubsub_admin_tcp PRIVATE UUID::lib)
-endif()
-
-install_celix_bundle(celix_pubsub_admin_tcp EXPORT celix COMPONENT pubsub)
-target_link_libraries(celix_pubsub_admin_tcp PRIVATE Celix::shell_api)
-add_library(Celix::celix_pubsub_admin_tcp ALIAS celix_pubsub_admin_tcp)
diff --git a/bundles/pubsub/pubsub_admin_tcp/v1/src/psa_activator.c b/bundles/pubsub/pubsub_admin_tcp/v1/src/psa_activator.c
deleted file mode 100644
index d93c478..0000000
--- a/bundles/pubsub/pubsub_admin_tcp/v1/src/psa_activator.c
+++ /dev/null
@@ -1,144 +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 <stdlib.h>
-
-#include "celix_api.h"
-#include "pubsub_serializer.h"
-#include "pubsub_protocol.h"
-#include "celix_log_helper.h"
-
-#include "pubsub_admin.h"
-#include "pubsub_admin_metrics.h"
-#include "pubsub_tcp_admin.h"
-#include "celix_shell_command.h"
-
-typedef struct psa_tcp_activator {
-    celix_log_helper_t *logHelper;
-
-    pubsub_tcp_admin_t *admin;
-
-    long serializersTrackerId;
-    long protocolsTrackerId;
-
-    pubsub_admin_service_t adminService;
-    long adminSvcId;
-
-    pubsub_admin_metrics_service_t adminMetricsService;
-    long adminMetricsSvcId;
-
-    celix_shell_command_t cmdSvc;
-    long cmdSvcId;
-} psa_tcp_activator_t;
-
-int psa_tcp_start(psa_tcp_activator_t *act, celix_bundle_context_t *ctx) {
-    act->adminSvcId = -1L;
-    act->cmdSvcId = -1L;
-    act->serializersTrackerId = -1L;
-    act->protocolsTrackerId = -1L;
-
-    act->logHelper = celix_logHelper_create(ctx, "celix_psa_admin_tcp");
-
-    act->admin = pubsub_tcpAdmin_create(ctx, act->logHelper);
-    celix_status_t status = act->admin != NULL ? CELIX_SUCCESS : CELIX_BUNDLE_EXCEPTION;
-
-    //track serializers
-    if (status == CELIX_SUCCESS) {
-        celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
-        opts.filter.serviceName = PUBSUB_SERIALIZER_SERVICE_NAME;
-        opts.filter.ignoreServiceLanguage = true;
-        opts.callbackHandle = act->admin;
-        opts.addWithProperties = pubsub_tcpAdmin_addSerializerSvc;
-        opts.removeWithProperties = pubsub_tcpAdmin_removeSerializerSvc;
-        act->serializersTrackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
-    }
-
-    //track protocols
-    if (status == CELIX_SUCCESS) {
-        celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
-        opts.filter.serviceName = PUBSUB_PROTOCOL_SERVICE_NAME;
-        opts.filter.ignoreServiceLanguage = true;
-        opts.callbackHandle = act->admin;
-        opts.addWithProperties = pubsub_tcpAdmin_addProtocolSvc;
-        opts.removeWithProperties = pubsub_tcpAdmin_removeProtocolSvc;
-        act->protocolsTrackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
-    }
-
-    //register pubsub admin service
-    if (status == CELIX_SUCCESS) {
-        pubsub_admin_service_t *psaSvc = &act->adminService;
-        psaSvc->handle = act->admin;
-        psaSvc->matchPublisher = pubsub_tcpAdmin_matchPublisher;
-        psaSvc->matchSubscriber = pubsub_tcpAdmin_matchSubscriber;
-        psaSvc->matchDiscoveredEndpoint = pubsub_tcpAdmin_matchDiscoveredEndpoint;
-        psaSvc->setupTopicSender = pubsub_tcpAdmin_setupTopicSender;
-        psaSvc->teardownTopicSender = pubsub_tcpAdmin_teardownTopicSender;
-        psaSvc->setupTopicReceiver = pubsub_tcpAdmin_setupTopicReceiver;
-        psaSvc->teardownTopicReceiver = pubsub_tcpAdmin_teardownTopicReceiver;
-        psaSvc->addDiscoveredEndpoint = pubsub_tcpAdmin_addDiscoveredEndpoint;
-        psaSvc->removeDiscoveredEndpoint = pubsub_tcpAdmin_removeDiscoveredEndpoint;
-
-        celix_properties_t *props = celix_properties_create();
-        celix_properties_set(props, PUBSUB_ADMIN_SERVICE_TYPE, PUBSUB_TCP_ADMIN_TYPE);
-
-        act->adminSvcId = celix_bundleContext_registerService(ctx, psaSvc, PUBSUB_ADMIN_SERVICE_NAME, props);
-    }
-
-    if (status == CELIX_SUCCESS) {
-        act->adminMetricsService.handle = act->admin;
-        act->adminMetricsService.metrics = pubsub_tcpAdmin_metrics;
-
-        celix_properties_t *props = celix_properties_create();
-        celix_properties_set(props, PUBSUB_ADMIN_SERVICE_TYPE, PUBSUB_TCP_ADMIN_TYPE);
-
-        act->adminMetricsSvcId =
-            celix_bundleContext_registerService(ctx,
-                                                &act->adminMetricsService,
-                                                PUBSUB_ADMIN_METRICS_SERVICE_NAME,
-                                                props);
-    }
-
-    //register shell command service
-    {
-        act->cmdSvc.handle = act->admin;
-        act->cmdSvc.executeCommand = pubsub_tcpAdmin_executeCommand;
-        celix_properties_t *props = celix_properties_create();
-        celix_properties_set(props, CELIX_SHELL_COMMAND_NAME, "celix::psa_tcp");
-        celix_properties_set(props, CELIX_SHELL_COMMAND_USAGE, "psa_tcp");
-        celix_properties_set(props, CELIX_SHELL_COMMAND_DESCRIPTION, "Print the information about the TopicSender and TopicReceivers for the TCP PSA");
-        act->cmdSvcId = celix_bundleContext_registerService(ctx, &act->cmdSvc, CELIX_SHELL_COMMAND_SERVICE_NAME, props);
-    }
-
-    return status;
-}
-
-int psa_tcp_stop(psa_tcp_activator_t *act, celix_bundle_context_t *ctx) {
-    celix_bundleContext_unregisterService(ctx, act->adminSvcId);
-    celix_bundleContext_unregisterService(ctx, act->cmdSvcId);
-    celix_bundleContext_unregisterService(ctx, act->adminMetricsSvcId);
-    celix_bundleContext_stopTracker(ctx, act->serializersTrackerId);
-    celix_bundleContext_stopTracker(ctx, act->protocolsTrackerId);
-    pubsub_tcpAdmin_destroy(act->admin);
-
-    celix_logHelper_destroy(act->logHelper);
-
-    return CELIX_SUCCESS;
-}
-
-CELIX_GEN_BUNDLE_ACTIVATOR(psa_tcp_activator_t, psa_tcp_start, psa_tcp_stop);
diff --git a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_psa_tcp_constants.h b/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_psa_tcp_constants.h
deleted file mode 100644
index d493eaa..0000000
--- a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_psa_tcp_constants.h
+++ /dev/null
@@ -1,140 +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_PSA_TCP_CONSTANTS_H_
-#define PUBSUB_PSA_TCP_CONSTANTS_H_
-
-#define PSA_TCP_BASE_PORT                       "PSA_TCP_BASE_PORT"
-#define PSA_TCP_MAX_PORT                        "PSA_TCP_MAX_PORT"
-
-#define PSA_TCP_MAX_MESSAGE_SIZE                "PSA_TCP_MAX_MESSAGE_SIZE"
-#define PSA_TCP_RECV_BUFFER_SIZE                "PSA_TCP_RECV_BUFFER_SIZE"
-#define PSA_TCP_TIMEOUT                         "PSA_TCP_TIMEOUT"
-#define PSA_TCP_SUBSCRIBER_CONNECTION_TIMEOUT   "PSA_TCP_SUBSCRIBER_CONNECTION_TIMEOUT"
-
-#define PSA_TCP_DEFAULT_BASE_PORT               5501
-#define PSA_TCP_DEFAULT_MAX_PORT                6000
-
-#define PSA_TCP_DEFAULT_MAX_MESSAGE_SIZE        UINT32_MAX
-#define PSA_TCP_DEFAULT_RECV_BUFFER_SIZE        65 * 1024
-#define PSA_TCP_DEFAULT_TIMEOUT                 2000 // 2 seconds
-#define PSA_TCP_SUBSCRIBER_CONNECTION_DEFAULT_TIMEOUT 250 // 250 ms
-
-#define PSA_TCP_DEFAULT_QOS_SAMPLE_SCORE        30
-#define PSA_TCP_DEFAULT_QOS_CONTROL_SCORE       70
-#define PSA_TCP_DEFAULT_SCORE                   30
-
-#define PSA_TCP_QOS_SAMPLE_SCORE_KEY            "PSA_TCP_QOS_SAMPLE_SCORE"
-#define PSA_TCP_QOS_CONTROL_SCORE_KEY           "PSA_TCP_QOS_CONTROL_SCORE"
-#define PSA_TCP_DEFAULT_SCORE_KEY               "PSA_TCP_DEFAULT_SCORE"
-
-#define PSA_TCP_METRICS_ENABLED                 "PSA_TCP_METRICS_ENABLED"
-#define PSA_TCP_DEFAULT_METRICS_ENABLED         false
-
-#define PUBSUB_TCP_VERBOSE_KEY                  "PSA_TCP_VERBOSE"
-#define PUBSUB_TCP_VERBOSE_DEFAULT              false
-
-#define PUBSUB_TCP_PUBLISHER_RETRY_CNT_KEY      "PUBSUB_TCP_PUBLISHER_RETRY_COUNT"
-#define PUBSUB_TCP_PUBLISHER_RETRY_CNT_DEFAULT  5
-
-#define PUBSUB_TCP_SUBSCRIBER_RETRY_CNT_KEY     "PUBSUB_TCP_SUBSCRIBER_RETRY_COUNT"
-#define PUBSUB_TCP_SUBSCRIBER_RETRY_CNT_DEFAULT 5
-
-
-//Time-out settings are only for BLOCKING connections
-#define PUBSUB_TCP_PUBLISHER_SNDTIMEO_KEY       "PUBSUB_TCP_PUBLISHER_SEND_TIMEOUT"
-#define PUBSUB_TCP_PUBLISHER_SNDTIMEO_DEFAULT   5.0
-#define PUBSUB_TCP_PUBLISHER_SNDTIMEO_ENDPOINT_DEFAULT   0.0
-
-#define PUBSUB_TCP_SUBSCRIBER_RCVTIMEO_KEY      "PUBSUB_TCP_SUBSCRIBER_RCV_TIMEOUT"
-#define PUBSUB_TCP_SUBSCRIBER_RCVTIMEO_DEFAULT  5.0
-
-#define PUBSUB_TCP_PSA_IP_KEY                   "PSA_IP"
-#define PUBSUB_TCP_ADMIN_TYPE                   "tcp"
-
-/**
- * The TCP url key for the topic sender endpoints
- */
-#define PUBSUB_TCP_URL_KEY                      "tcp.url"
-
-/**
- * Can be set in the topic properties to fix a static bind url
- */
-#define PUBSUB_TCP_STATIC_BIND_URL              "tcp.static.bind.url"
-
-/**
- * Name of environment variable with ip/url to bind to
- * e.g. PSA_TCP_STATIC_BIND_FOR_topic_scope="tcp://0.0.0.0:4444"
- */
-#define PUBSUB_TCP_STATIC_BIND_URL_FOR          "PSA_TCP_STATIC_BIND_URL_FOR_"
-
-/**
- * Can be set in the topic properties to fix a static url used for discovery
- */
-#define PUBSUB_TCP_STATIC_DISCOVER_URL          "tcp.static.bind.url"
-
-/**
- * If set true on the endpoint, the tcp TopicSender bind and/or discovery url is statically configured.
- */
-#define PUBSUB_TCP_STATIC_CONFIGURED            "tcp.static.configured"
-
-/**
- * The static url which a subscriber should try to connect to.
- * The urls are space separated.
- * Can be set in the topic properties.
- */
-#define PUBSUB_TCP_STATIC_CONNECT_URLS          "tcp.static.connect.urls"
-
-
-/**
- * Defines if the publisher / subscriber is a passive endpoint and shares
- * the connection with publisher / subscriber endpoint with the matching (passive) key
- * e.g. tcp.passive.configured="true" means that a publisher / subscriber is passive,
- * when a publisher / subscriber is found with a matching key (for example tcp.passive.key="localhost").
- * This creates full-duplex connection using a single socket.
- */
-#define PUBSUB_TCP_PASSIVE_CONFIGURED            "tcp.passive.configured"
-#define PUBSUB_TCP_PASSIVE_KEY                   "tcp.passive.key"
-
-/**
- * Name of environment variable to indicate that passive endpoint is configured
- * e.g. PSA_TCP_PASSIVE_CONFIGURED_topic_scope="true"
- */
-#define PUBSUB_TCP_PASSIVE_ENABLED               "PSA_TCP_PASSIVE_CONFIGURED_"
-/**
- * Name of environment variable to configure the passive key (see PUBSUB_TCP_PASSIVE_KEY )
- * e.g. PSA_TCP_PASSIVE_KEY__topic_scope="tcp://localhost:4444"
- */
-#define PUBSUB_TCP_PASSIVE_SELECTION_KEY         "PSA_TCP_PASSIVE_KEY_"
-
-/**
- * Name of environment variable with space-separated list of ips/urls to connect to
- * e.g. PSA_TCP_STATIC_CONNECT_FOR_topic_scope="tcp://127.0.0.1:4444 tcp://127.0.0.2:4444"
- */
-#define PUBSUB_TCP_STATIC_CONNECT_URLS_FOR       "PSA_TCP_STATIC_CONNECT_URL_FOR_"
-
-/**
- * Realtime thread prio and scheduling information. This is used to setup the thread prio/sched of the
- * internal TCP threads.
- * Can be set in the topic properties.
- */
-#define PUBSUB_TCP_THREAD_REALTIME_PRIO         "thread.realtime.prio"
-#define PUBSUB_TCP_THREAD_REALTIME_SCHED        "thread.realtime.sched"
-
-#endif /* PUBSUB_PSA_TCP_CONSTANTS_H_ */
diff --git a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_admin.c b/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_admin.c
deleted file mode 100644
index ba3bdb8..0000000
--- a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_admin.c
+++ /dev/null
@@ -1,785 +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 <memory.h>
-#include <pubsub_endpoint.h>
-#include <pubsub_serializer.h>
-#include <ip_utils.h>
-
-#include "pubsub_utils.h"
-#include "pubsub_tcp_admin.h"
-#include "pubsub_tcp_handler.h"
-#include "pubsub_psa_tcp_constants.h"
-#include "pubsub_tcp_topic_sender.h"
-#include "pubsub_tcp_topic_receiver.h"
-
-#define L_DEBUG(...) \
-    celix_logHelper_log(psa->log, CELIX_LOG_LEVEL_DEBUG, __VA_ARGS__)
-#define L_INFO(...) \
-    celix_logHelper_log(psa->log, CELIX_LOG_LEVEL_INFO, __VA_ARGS__)
-#define L_WARN(...) \
-    celix_logHelper_log(psa->log, CELIX_LOG_LEVEL_WARNING, __VA_ARGS__)
-#define L_ERROR(...) \
-    celix_logHelper_log(psa->log, CELIX_LOG_LEVEL_ERROR, __VA_ARGS__)
-
-struct pubsub_tcp_admin {
-    celix_bundle_context_t *ctx;
-    celix_log_helper_t *log;
-    const char *fwUUID;
-
-    char *ipAddress;
-
-    unsigned int basePort;
-
-    double qosSampleScore;
-    double qosControlScore;
-    double defaultScore;
-
-    bool verbose;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = svcId, value = psa_tcp_serializer_entry_t*
-    } serializers;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = svcId, value = psa_tcp_protocol_entry_t*
-    } protocols;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = scope:topic key, value = pubsub_tcp_topic_sender_t*
-    } topicSenders;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = scope:topic key, value = pubsub_tcp_topic_sender_t*
-    } topicReceivers;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = endpoint uuid, value = celix_properties_t* (endpoint)
-    } discoveredEndpoints;
-
-    pubsub_tcp_endPointStore_t endpointStore;
-};
-
-typedef struct psa_tcp_serializer_entry {
-    const char *serType;
-    long svcId;
-    pubsub_serializer_service_t *svc;
-} psa_tcp_serializer_entry_t;
-
-typedef struct psa_tcp_protocol_entry {
-    const char *protType;
-    long svcId;
-    pubsub_protocol_service_t *svc;
-} psa_tcp_protocol_entry_t;
-
-static celix_status_t
-pubsub_tcpAdmin_connectEndpointToReceiver(pubsub_tcp_admin_t *psa, pubsub_tcp_topic_receiver_t *receiver,
-                                          const celix_properties_t *endpoint);
-
-static celix_status_t
-pubsub_tcpAdmin_disconnectEndpointFromReceiver(pubsub_tcp_admin_t *psa, pubsub_tcp_topic_receiver_t *receiver,
-                                               const celix_properties_t *endpoint);
-
-static bool pubsub_tcpAdmin_endpointIsPublisher(const celix_properties_t *endpoint) {
-    const char *type = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TYPE, NULL);
-    return type != NULL && strncmp(PUBSUB_PUBLISHER_ENDPOINT_TYPE, type, strlen(PUBSUB_PUBLISHER_ENDPOINT_TYPE)) == 0;
-}
-
-pubsub_tcp_admin_t *pubsub_tcpAdmin_create(celix_bundle_context_t *ctx, celix_log_helper_t *logHelper) {
-    pubsub_tcp_admin_t *psa = calloc(1, sizeof(*psa));
-    psa->ctx = ctx;
-    psa->log = logHelper;
-    psa->verbose = celix_bundleContext_getPropertyAsBool(ctx, PUBSUB_TCP_VERBOSE_KEY, PUBSUB_TCP_VERBOSE_DEFAULT);
-    psa->fwUUID = celix_bundleContext_getProperty(ctx, OSGI_FRAMEWORK_FRAMEWORK_UUID, NULL);
-    long basePort = celix_bundleContext_getPropertyAsLong(ctx, PSA_TCP_BASE_PORT, PSA_TCP_DEFAULT_BASE_PORT);
-    psa->basePort = (unsigned int) basePort;
-    psa->defaultScore = celix_bundleContext_getPropertyAsDouble(ctx, PSA_TCP_DEFAULT_SCORE_KEY, PSA_TCP_DEFAULT_SCORE);
-    psa->qosSampleScore = celix_bundleContext_getPropertyAsDouble(ctx, PSA_TCP_QOS_SAMPLE_SCORE_KEY,
-                                                                  PSA_TCP_DEFAULT_QOS_SAMPLE_SCORE);
-    psa->qosControlScore = celix_bundleContext_getPropertyAsDouble(ctx, PSA_TCP_QOS_CONTROL_SCORE_KEY,
-                                                                   PSA_TCP_DEFAULT_QOS_CONTROL_SCORE);
-
-    celixThreadMutex_create(&psa->serializers.mutex, NULL);
-    psa->serializers.map = hashMap_create(NULL, NULL, NULL, NULL);
-
-    celixThreadMutex_create(&psa->protocols.mutex, NULL);
-    psa->protocols.map = hashMap_create(NULL, NULL, NULL, NULL);
-    celixThreadMutex_create(&psa->topicSenders.mutex, NULL);
-    psa->topicSenders.map = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
-    celixThreadMutex_create(&psa->topicReceivers.mutex, NULL);
-    psa->topicReceivers.map = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
-    celixThreadMutex_create(&psa->discoveredEndpoints.mutex, NULL);
-    psa->discoveredEndpoints.map = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
-    celixThreadMutex_create(&psa->endpointStore.mutex, NULL);
-    psa->endpointStore.map = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
-    return psa;
-}
-
-void pubsub_tcpAdmin_destroy(pubsub_tcp_admin_t *psa) {
-    if (psa == NULL) {
-        return;
-    }
-
-    celixThreadMutex_lock(&psa->endpointStore.mutex);
-    hash_map_iterator_t iter = hashMapIterator_construct(psa->endpointStore.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        pubsub_tcpHandler_t *tcpHandler = hashMapIterator_nextValue(&iter);
-        pubsub_tcpHandler_destroy(tcpHandler);
-    }
-    celixThreadMutex_unlock(&psa->endpointStore.mutex);
-
-    celixThreadMutex_lock(&psa->topicSenders.mutex);
-    iter = hashMapIterator_construct(psa->topicSenders.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        pubsub_tcp_topic_sender_t *sender = hashMapIterator_nextValue(&iter);
-        pubsub_tcpTopicSender_destroy(sender);
-    }
-    celixThreadMutex_unlock(&psa->topicSenders.mutex);
-
-    celixThreadMutex_lock(&psa->topicReceivers.mutex);
-    iter = hashMapIterator_construct(psa->topicReceivers.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        pubsub_tcp_topic_receiver_t *recv = hashMapIterator_nextValue(&iter);
-        pubsub_tcpTopicReceiver_destroy(recv);
-    }
-    celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-
-    celixThreadMutex_lock(&psa->discoveredEndpoints.mutex);
-    iter = hashMapIterator_construct(psa->discoveredEndpoints.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        celix_properties_t *ep = hashMapIterator_nextValue(&iter);
-        celix_properties_destroy(ep);
-    }
-    celixThreadMutex_unlock(&psa->discoveredEndpoints.mutex);
-
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    iter = hashMapIterator_construct(psa->serializers.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        psa_tcp_serializer_entry_t *entry = hashMapIterator_nextValue(&iter);
-        free(entry);
-    }
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-
-    celixThreadMutex_lock(&psa->protocols.mutex);
-    iter = hashMapIterator_construct(psa->protocols.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        psa_tcp_protocol_entry_t *entry = hashMapIterator_nextValue(&iter);
-        free(entry);
-    }
-    celixThreadMutex_unlock(&psa->protocols.mutex);
-    //note assuming al psa register services and service tracker are removed.
-    celixThreadMutex_destroy(&psa->endpointStore.mutex);
-    hashMap_destroy(psa->endpointStore.map, false, false);
-
-    celixThreadMutex_destroy(&psa->topicSenders.mutex);
-    hashMap_destroy(psa->topicSenders.map, true, false);
-
-    celixThreadMutex_destroy(&psa->topicReceivers.mutex);
-    hashMap_destroy(psa->topicReceivers.map, true, false);
-
-    celixThreadMutex_destroy(&psa->discoveredEndpoints.mutex);
-    hashMap_destroy(psa->discoveredEndpoints.map, false, false);
-
-    celixThreadMutex_destroy(&psa->serializers.mutex);
-    hashMap_destroy(psa->serializers.map, false, false);
-    celixThreadMutex_destroy(&psa->protocols.mutex);
-    hashMap_destroy(psa->protocols.map, false, false);
-
-    free(psa->ipAddress);
-
-    free(psa);
-}
-
-void pubsub_tcpAdmin_addSerializerSvc(void *handle, void *svc, const celix_properties_t *props) {
-    pubsub_tcp_admin_t *psa = handle;
-
-    const char *serType = celix_properties_get(props, PUBSUB_SERIALIZER_TYPE_KEY, NULL);
-    long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
-
-    if (serType == NULL) {
-        L_INFO("[PSA_TCP] Ignoring serializer service without %s property", PUBSUB_SERIALIZER_TYPE_KEY);
-        return;
-    }
-
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    psa_tcp_serializer_entry_t *entry = hashMap_get(psa->serializers.map, (void *) svcId);
-    if (entry == NULL) {
-        entry = calloc(1, sizeof(*entry));
-        entry->serType = serType;
-        entry->svcId = svcId;
-        entry->svc = svc;
-        hashMap_put(psa->serializers.map, (void *) svcId, entry);
-    }
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-}
-
-void pubsub_tcpAdmin_removeSerializerSvc(void *handle, void *svc, const celix_properties_t *props) {
-    pubsub_tcp_admin_t *psa = handle;
-    long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
-
-    //remove serializer
-    // 1) First find entry and
-    // 2) loop and destroy all topic sender using the serializer and
-    // 3) loop and destroy all topic receivers using the serializer
-    // Note that it is the responsibility of the topology manager to create new topic senders/receivers
-
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    psa_tcp_serializer_entry_t *entry = hashMap_remove(psa->serializers.map, (void *) svcId);
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-
-    if (entry != NULL) {
-        celixThreadMutex_lock(&psa->topicSenders.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(psa->topicSenders.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            hash_map_entry_t *senderEntry = hashMapIterator_nextEntry(&iter);
-            pubsub_tcp_topic_sender_t *sender = hashMapEntry_getValue(senderEntry);
-            if (sender != NULL && entry->svcId == pubsub_tcpTopicSender_serializerSvcId(sender)) {
-                char *key = hashMapEntry_getKey(senderEntry);
-                hashMapIterator_remove(&iter);
-                pubsub_tcpTopicSender_destroy(sender);
-                free(key);
-            }
-        }
-        celixThreadMutex_unlock(&psa->topicSenders.mutex);
-
-        celixThreadMutex_lock(&psa->topicReceivers.mutex);
-        iter = hashMapIterator_construct(psa->topicReceivers.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            hash_map_entry_t *senderEntry = hashMapIterator_nextEntry(&iter);
-            pubsub_tcp_topic_receiver_t *receiver = hashMapEntry_getValue(senderEntry);
-            if (receiver != NULL && entry->svcId == pubsub_tcpTopicReceiver_serializerSvcId(receiver)) {
-                char *key = hashMapEntry_getKey(senderEntry);
-                hashMapIterator_remove(&iter);
-                pubsub_tcpTopicReceiver_destroy(receiver);
-                free(key);
-            }
-        }
-        celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-
-        free(entry);
-    }
-}
-
-void pubsub_tcpAdmin_addProtocolSvc(void *handle, void *svc, const celix_properties_t *props) {
-    pubsub_tcp_admin_t *psa = handle;
-
-    const char *protType = celix_properties_get(props, PUBSUB_PROTOCOL_TYPE_KEY, NULL);
-    long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
-
-    if (protType == NULL) {
-        L_INFO("[PSA_ZMQ] Ignoring protocol service without %s property", PUBSUB_PROTOCOL_TYPE_KEY);
-        return;
-    }
-
-    celixThreadMutex_lock(&psa->protocols.mutex);
-    psa_tcp_protocol_entry_t *entry = hashMap_get(psa->protocols.map, (void *) svcId);
-    if (entry == NULL) {
-        entry = calloc(1, sizeof(*entry));
-        entry->protType = protType;
-        entry->svcId = svcId;
-        entry->svc = svc;
-        hashMap_put(psa->protocols.map, (void *) svcId, entry);
-    }
-    celixThreadMutex_unlock(&psa->protocols.mutex);
-}
-
-void pubsub_tcpAdmin_removeProtocolSvc(void *handle, void *svc, const celix_properties_t *props) {
-    pubsub_tcp_admin_t *psa = handle;
-    long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
-
-    //remove protocol
-    // 1) First find entry and
-    // 2) loop and destroy all topic sender using the protocol and
-    // 3) loop and destroy all topic receivers using the protocol
-    // Note that it is the responsibility of the topology manager to create new topic senders/receivers
-
-    celixThreadMutex_lock(&psa->protocols.mutex);
-    psa_tcp_protocol_entry_t *entry = hashMap_remove(psa->protocols.map, (void *) svcId);
-    celixThreadMutex_unlock(&psa->protocols.mutex);
-
-    if (entry != NULL) {
-        celixThreadMutex_lock(&psa->topicSenders.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(psa->topicSenders.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            hash_map_entry_t *senderEntry = hashMapIterator_nextEntry(&iter);
-            pubsub_tcp_topic_sender_t *sender = hashMapEntry_getValue(senderEntry);
-            if (sender != NULL && entry->svcId == pubsub_tcpTopicSender_protocolSvcId(sender)) {
-                char *key = hashMapEntry_getKey(senderEntry);
-                hashMapIterator_remove(&iter);
-                pubsub_tcpTopicSender_destroy(sender);
-                free(key);
-            }
-        }
-        celixThreadMutex_unlock(&psa->topicSenders.mutex);
-
-        celixThreadMutex_lock(&psa->topicReceivers.mutex);
-        iter = hashMapIterator_construct(psa->topicReceivers.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            hash_map_entry_t *senderEntry = hashMapIterator_nextEntry(&iter);
-            pubsub_tcp_topic_receiver_t *receiver = hashMapEntry_getValue(senderEntry);
-            if (receiver != NULL && entry->svcId == pubsub_tcpTopicReceiver_protocolSvcId(receiver)) {
-                char *key = hashMapEntry_getKey(senderEntry);
-                hashMapIterator_remove(&iter);
-                pubsub_tcpTopicReceiver_destroy(receiver);
-                free(key);
-            }
-        }
-        celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-
-        free(entry);
-    }
-}
-
-celix_status_t pubsub_tcpAdmin_matchPublisher(void *handle, long svcRequesterBndId, const celix_filter_t *svcFilter,
-                                              celix_properties_t **topicProperties, double *outScore,
-                                              long *outSerializerSvcId, long *outProtocolSvcId) {
-    pubsub_tcp_admin_t *psa = handle;
-    L_DEBUG("[PSA_TCP] pubsub_tcpAdmin_matchPublisher");
-    celix_status_t status = CELIX_SUCCESS;
-    double score = pubsubEndpoint_matchPublisher(psa->ctx, svcRequesterBndId, svcFilter->filterStr, PUBSUB_TCP_ADMIN_TYPE,
-                                               psa->qosSampleScore, psa->qosControlScore, psa->defaultScore, true,
-                                               topicProperties, outSerializerSvcId, outProtocolSvcId);
-    *outScore = score;
-
-    return status;
-}
-
-celix_status_t
-pubsub_tcpAdmin_matchSubscriber(void *handle, long svcProviderBndId, const celix_properties_t *svcProperties,
-                                celix_properties_t **topicProperties, double *outScore, long *outSerializerSvcId,
-                                long *outProtocolSvcId) {
-    pubsub_tcp_admin_t *psa = handle;
-    L_DEBUG("[PSA_TCP] pubsub_tcpAdmin_matchSubscriber");
-    celix_status_t status = CELIX_SUCCESS;
-    double score = pubsubEndpoint_matchSubscriber(psa->ctx, svcProviderBndId, svcProperties, PUBSUB_TCP_ADMIN_TYPE,
-                                                psa->qosSampleScore, psa->qosControlScore, psa->defaultScore, true,
-                                                topicProperties, outSerializerSvcId, outProtocolSvcId);
-    if (outScore != NULL) {
-        *outScore = score;
-    }
-    return status;
-}
-
-celix_status_t
-pubsub_tcpAdmin_matchDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint, bool *outMatch) {
-    pubsub_tcp_admin_t *psa = handle;
-    L_DEBUG("[PSA_TCP] pubsub_tcpAdmin_matchEndpoint");
-    celix_status_t status = CELIX_SUCCESS;
-    bool match = pubsubEndpoint_match(psa->ctx, psa->log, endpoint, PUBSUB_TCP_ADMIN_TYPE, true, NULL, NULL);
-    if (outMatch != NULL) {
-        *outMatch = match;
-    }
-    return status;
-}
-
-celix_status_t pubsub_tcpAdmin_setupTopicSender(void *handle, const char *scope, const char *topic,
-                                                const celix_properties_t *topicProperties, long serializerSvcId,
-                                                long protocolSvcId, celix_properties_t **outPublisherEndpoint) {
-    pubsub_tcp_admin_t *psa = handle;
-    celix_status_t status = CELIX_SUCCESS;
-
-    //1) Create TopicSender
-    //2) Store TopicSender
-    //3) Connect existing endpoints
-    //4) set outPublisherEndpoint
-
-    celix_properties_t *newEndpoint = NULL;
-    char *key = pubsubEndpoint_createScopeTopicKey(scope, topic);
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    celixThreadMutex_lock(&psa->protocols.mutex);
-    celixThreadMutex_lock(&psa->topicSenders.mutex);
-    pubsub_tcp_topic_sender_t *sender = hashMap_get(psa->topicSenders.map, key);
-    if (sender == NULL) {
-        psa_tcp_serializer_entry_t *serEntry = hashMap_get(psa->serializers.map, (void *) serializerSvcId);
-        psa_tcp_protocol_entry_t *protEntry = hashMap_get(psa->protocols.map, (void *) protocolSvcId);
-        if (serEntry != NULL && protEntry != NULL) {
-            sender = pubsub_tcpTopicSender_create(psa->ctx, psa->log, scope, topic, topicProperties,
-                                                  &psa->endpointStore, serializerSvcId, serEntry->svc, protocolSvcId,
-                                                  protEntry->svc);
-        }
-        if (sender != NULL) {
-            const char *psaType = PUBSUB_TCP_ADMIN_TYPE;
-            const char *serType = serEntry->serType;
-            const char *protType = protEntry->protType;
-            newEndpoint = pubsubEndpoint_create(psa->fwUUID, scope, topic, PUBSUB_PUBLISHER_ENDPOINT_TYPE, psaType, serType, protType, NULL);
-            celix_properties_set(newEndpoint, PUBSUB_TCP_URL_KEY, pubsub_tcpTopicSender_url(sender));
-
-            celix_properties_setBool(newEndpoint, PUBSUB_TCP_STATIC_CONFIGURED, pubsub_tcpTopicSender_isStatic(sender));
-            if (pubsub_tcpTopicSender_isPassive(sender)) {
-                celix_properties_set(newEndpoint, PUBSUB_ENDPOINT_VISIBILITY, PUBSUB_ENDPOINT_LOCAL_VISIBILITY);
-            } else {
-                celix_properties_set(newEndpoint, PUBSUB_ENDPOINT_VISIBILITY, PUBSUB_ENDPOINT_SYSTEM_VISIBILITY);
-            }
-            //if available also set container name
-            const char *cn = celix_bundleContext_getProperty(psa->ctx, "CELIX_CONTAINER_NAME", NULL);
-            if (cn != NULL)
-              celix_properties_set(newEndpoint, "container_name", cn);
-            hashMap_put(psa->topicSenders.map, key, sender);
-        } else {
-            L_ERROR("[PSA TCP] Error creating a TopicSender");
-            free(key);
-        }
-    } else {
-        free(key);
-        L_ERROR("[PSA_TCP] Cannot setup already existing TopicSender for scope/topic %s/%s!", scope, topic);
-    }
-    celixThreadMutex_unlock(&psa->topicSenders.mutex);
-    celixThreadMutex_unlock(&psa->protocols.mutex);
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-
-    if (newEndpoint != NULL && outPublisherEndpoint != NULL) {
-        *outPublisherEndpoint = newEndpoint;
-    }
-
-    return status;
-}
-
-celix_status_t pubsub_tcpAdmin_teardownTopicSender(void *handle, const char *scope, const char *topic) {
-    pubsub_tcp_admin_t *psa = handle;
-    celix_status_t status = CELIX_SUCCESS;
-
-    //1) Find and remove TopicSender from map
-    //2) destroy topic sender
-
-    char *key = pubsubEndpoint_createScopeTopicKey(scope, topic);
-    celixThreadMutex_lock(&psa->topicSenders.mutex);
-    hash_map_entry_t *entry = hashMap_getEntry(psa->topicSenders.map, key);
-    if (entry != NULL) {
-        char *mapKey = hashMapEntry_getKey(entry);
-        pubsub_tcp_topic_sender_t *sender = hashMap_remove(psa->topicSenders.map, key);
-        free(mapKey);
-        pubsub_tcpTopicSender_destroy(sender);
-    } else {
-        L_ERROR("[PSA TCP] Cannot teardown TopicSender with scope/topic %s/%s. Does not exists",
-                scope == NULL ? "(null)" : scope,
-                topic);
-    }
-    celixThreadMutex_unlock(&psa->topicSenders.mutex);
-    free(key);
-
-    return status;
-}
-
-celix_status_t pubsub_tcpAdmin_setupTopicReceiver(void *handle, const char *scope, const char *topic,
-                                                  const celix_properties_t *topicProperties, long serializerSvcId,
-                                                  long protocolSvcId, celix_properties_t **outSubscriberEndpoint) {
-    pubsub_tcp_admin_t *psa = handle;
-
-    celix_properties_t *newEndpoint = NULL;
-
-    char *key = pubsubEndpoint_createScopeTopicKey(scope, topic);
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    celixThreadMutex_lock(&psa->protocols.mutex);
-    celixThreadMutex_lock(&psa->topicReceivers.mutex);
-    pubsub_tcp_topic_receiver_t *receiver = hashMap_get(psa->topicReceivers.map, key);
-    if (receiver == NULL) {
-        psa_tcp_serializer_entry_t *serEntry = hashMap_get(psa->serializers.map, (void *) serializerSvcId);
-        psa_tcp_protocol_entry_t *protEntry = hashMap_get(psa->protocols.map, (void *) protocolSvcId);
-        if (serEntry != NULL && protEntry != NULL) {
-            receiver = pubsub_tcpTopicReceiver_create(psa->ctx, psa->log, scope, topic, topicProperties,
-                                                      &psa->endpointStore, serializerSvcId, serEntry->svc,
-                                                      protocolSvcId, protEntry->svc);
-        } else {
-            L_ERROR("[PSA_TCP] Cannot find serializer or protocol for TopicSender %s/%s", scope == NULL ? "(null)" : scope, topic);
-        }
-        if (receiver != NULL) {
-            const char *psaType = PUBSUB_TCP_ADMIN_TYPE;
-            const char *serType = serEntry->serType;
-            const char *protType = protEntry->protType;
-            newEndpoint = pubsubEndpoint_create(psa->fwUUID, scope, topic,
-                                                PUBSUB_SUBSCRIBER_ENDPOINT_TYPE, psaType, serType, protType, NULL);
-            //if available also set container name
-            const char *cn = celix_bundleContext_getProperty(psa->ctx, "CELIX_CONTAINER_NAME", NULL);
-            if (cn != NULL) {
-                celix_properties_set(newEndpoint, "container_name", cn);
-            }
-            hashMap_put(psa->topicReceivers.map, key, receiver);
-        } else {
-            L_ERROR("[PSA TCP] Error creating a TopicReceiver.");
-            free(key);
-        }
-    } else {
-        free(key);
-        L_ERROR("[PSA_TCP] Cannot setup already existing TopicReceiver for scope/topic %s/%s!",
-                scope == NULL ? "(null)" : scope,
-                topic);
-    }
-    celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-    celixThreadMutex_unlock(&psa->protocols.mutex);
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-
-    if (receiver != NULL && newEndpoint != NULL) {
-        celixThreadMutex_lock(&psa->discoveredEndpoints.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(psa->discoveredEndpoints.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            celix_properties_t *endpoint = hashMapIterator_nextValue(&iter);
-            if (pubsub_tcpAdmin_endpointIsPublisher(endpoint) && pubsubEndpoint_matchWithTopicAndScope(endpoint, topic, scope)) {
-                pubsub_tcpAdmin_connectEndpointToReceiver(psa, receiver, endpoint);
-            }
-        }
-        celixThreadMutex_unlock(&psa->discoveredEndpoints.mutex);
-    }
-
-    if (newEndpoint != NULL && outSubscriberEndpoint != NULL) {
-        *outSubscriberEndpoint = newEndpoint;
-    }
-
-    celix_status_t status = CELIX_SUCCESS;
-    return status;
-}
-
-celix_status_t pubsub_tcpAdmin_teardownTopicReceiver(void *handle, const char *scope, const char *topic) {
-    pubsub_tcp_admin_t *psa = handle;
-
-    char *key = pubsubEndpoint_createScopeTopicKey(scope, topic);
-    celixThreadMutex_lock(&psa->topicReceivers.mutex);
-    hash_map_entry_t *entry = hashMap_getEntry(psa->topicReceivers.map, key);
-    free(key);
-    if (entry != NULL) {
-        char *receiverKey = hashMapEntry_getKey(entry);
-        pubsub_tcp_topic_receiver_t *receiver = hashMapEntry_getValue(entry);
-        hashMap_remove(psa->topicReceivers.map, receiverKey);
-
-        free(receiverKey);
-        pubsub_tcpTopicReceiver_destroy(receiver);
-    }
-    celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-
-    celix_status_t status = CELIX_SUCCESS;
-    return status;
-}
-
-static celix_status_t
-pubsub_tcpAdmin_connectEndpointToReceiver(pubsub_tcp_admin_t *psa, pubsub_tcp_topic_receiver_t *receiver,
-                                          const celix_properties_t *endpoint) {
-    //note can be called with discoveredEndpoint.mutex lock
-    celix_status_t status = CELIX_SUCCESS;
-
-    const char *url = celix_properties_get(endpoint, PUBSUB_TCP_URL_KEY, NULL);
-
-    if (url == NULL) {
-        const char *admin = celix_properties_get(endpoint, PUBSUB_ENDPOINT_ADMIN_TYPE, NULL);
-        const char *type = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TYPE, NULL);
-        L_WARN("[PSA TCP] Error got endpoint without a tcp url (admin: %s, type: %s)", admin, type);
-        status = CELIX_BUNDLE_EXCEPTION;
-    } else {
-        pubsub_tcpTopicReceiver_connectTo(receiver, url);
-    }
-
-    return status;
-}
-
-celix_status_t pubsub_tcpAdmin_addDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint) {
-    pubsub_tcp_admin_t *psa = handle;
-
-    if (pubsub_tcpAdmin_endpointIsPublisher(endpoint)) {
-        celixThreadMutex_lock(&psa->topicReceivers.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(psa->topicReceivers.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            pubsub_tcp_topic_receiver_t *receiver = hashMapIterator_nextValue(&iter);
-            if (pubsubEndpoint_matchWithTopicAndScope(endpoint, pubsub_tcpTopicReceiver_topic(receiver), pubsub_tcpTopicReceiver_scope(receiver))) {
-                pubsub_tcpAdmin_connectEndpointToReceiver(psa, receiver, endpoint);
-            }
-        }
-        celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-    }
-
-    celixThreadMutex_lock(&psa->discoveredEndpoints.mutex);
-    celix_properties_t *cpy = celix_properties_copy(endpoint);
-    const char *uuid = celix_properties_get(cpy, PUBSUB_ENDPOINT_UUID, NULL);
-    hashMap_put(psa->discoveredEndpoints.map, (void *) uuid, cpy);
-    celixThreadMutex_unlock(&psa->discoveredEndpoints.mutex);
-
-    celix_status_t status = CELIX_SUCCESS;
-    return status;
-}
-
-static celix_status_t
-pubsub_tcpAdmin_disconnectEndpointFromReceiver(pubsub_tcp_admin_t *psa, pubsub_tcp_topic_receiver_t *receiver,
-                                               const celix_properties_t *endpoint) {
-    //note can be called with discoveredEndpoint.mutex lock
-    celix_status_t status = CELIX_SUCCESS;
-
-    const char *url = celix_properties_get(endpoint, PUBSUB_TCP_URL_KEY, NULL);
-
-    if (url == NULL) {
-        L_WARN("[PSA TCP] Error got endpoint without tcp url");
-        status = CELIX_BUNDLE_EXCEPTION;
-    } else {
-        pubsub_tcpTopicReceiver_disconnectFrom(receiver, url);
-    }
-
-    return status;
-}
-
-celix_status_t pubsub_tcpAdmin_removeDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint) {
-    pubsub_tcp_admin_t *psa = handle;
-
-    if (pubsub_tcpAdmin_endpointIsPublisher(endpoint)) {
-        celixThreadMutex_lock(&psa->topicReceivers.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(psa->topicReceivers.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            pubsub_tcp_topic_receiver_t *receiver = hashMapIterator_nextValue(&iter);
-            pubsub_tcpAdmin_disconnectEndpointFromReceiver(psa, receiver, endpoint);
-        }
-        celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-    }
-
-    celixThreadMutex_lock(&psa->discoveredEndpoints.mutex);
-    const char *uuid = celix_properties_get(endpoint, PUBSUB_ENDPOINT_UUID, NULL);
-    celix_properties_t *found = hashMap_remove(psa->discoveredEndpoints.map, (void *) uuid);
-    celixThreadMutex_unlock(&psa->discoveredEndpoints.mutex);
-
-    if (found != NULL) {
-        celix_properties_destroy(found);
-    }
-
-    celix_status_t status = CELIX_SUCCESS;
-    return status;
-}
-
-bool pubsub_tcpAdmin_executeCommand(void *handle, const char *commandLine __attribute__((unused)), FILE *out,
-                                    FILE *errStream __attribute__((unused))) {
-    pubsub_tcp_admin_t *psa = handle;
-    celix_status_t status = CELIX_SUCCESS;
-    char *line = celix_utils_strdup(commandLine);
-    char *token = line;
-    strtok_r(line, " ", &token); //first token is command name
-    strtok_r(NULL, " ", &token); //second token is sub command
-
-    if (celix_utils_stringEquals(token, "nr_of_receivers")) {
-        celixThreadMutex_lock(&psa->topicReceivers.mutex);
-        fprintf(out,"%i\n", hashMap_size(psa->topicReceivers.map));
-        celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-    }
-    if (celix_utils_stringEquals(token, "nr_of_senders")) {
-        celixThreadMutex_lock(&psa->topicSenders.mutex);
-        fprintf(out, "%i\n", hashMap_size(psa->topicSenders.map));
-        celixThreadMutex_unlock(&psa->topicSenders.mutex);
-    }
-
-    fprintf(out, "\n");
-    fprintf(out, "Topic Senders:\n");
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    celixThreadMutex_lock(&psa->protocols.mutex);
-    celixThreadMutex_lock(&psa->topicSenders.mutex);
-    hash_map_iterator_t iter = hashMapIterator_construct(psa->topicSenders.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        pubsub_tcp_topic_sender_t *sender = hashMapIterator_nextValue(&iter);
-        long serSvcId = pubsub_tcpTopicSender_serializerSvcId(sender);
-        psa_tcp_serializer_entry_t *serEntry = hashMap_get(psa->serializers.map, (void *) serSvcId);
-        long protSvcId = pubsub_tcpTopicSender_protocolSvcId(sender);
-        psa_tcp_protocol_entry_t *protEntry = hashMap_get(psa->protocols.map, (void *) protSvcId);
-        const char *serType = serEntry == NULL ? "!Error!" : serEntry->serType;
-        const char *protType = protEntry == NULL ? "!Error!" : protEntry->protType;
-        const char *scope = pubsub_tcpTopicSender_scope(sender);
-        const char *topic = pubsub_tcpTopicSender_topic(sender);
-        const char *url = pubsub_tcpTopicSender_url(sender);
-        const char *isPassive = pubsub_tcpTopicSender_isPassive(sender) ? " (passive)" : "";
-        const char *postUrl = pubsub_tcpTopicSender_isStatic(sender) ? " (static)" : "";
-        fprintf(out, "|- Topic Sender %s/%s\n", scope == NULL ? "(null)" : scope, topic);
-        fprintf(out, "   |- serializer type = %s\n", serType);
-        fprintf(out, "   |- protocol type = %s\n", protType);
-        fprintf(out, "   |- url            = %s%s%s\n", url, postUrl, isPassive);
-    }
-    celixThreadMutex_unlock(&psa->topicSenders.mutex);
-    celixThreadMutex_unlock(&psa->protocols.mutex);
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-
-    fprintf(out, "\n");
-    fprintf(out, "\nTopic Receivers:\n");
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    celixThreadMutex_lock(&psa->protocols.mutex);
-    celixThreadMutex_lock(&psa->topicReceivers.mutex);
-    iter = hashMapIterator_construct(psa->topicReceivers.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        pubsub_tcp_topic_receiver_t *receiver = hashMapIterator_nextValue(&iter);
-        long serSvcId = pubsub_tcpTopicReceiver_serializerSvcId(receiver);
-        psa_tcp_serializer_entry_t *serEntry = hashMap_get(psa->serializers.map, (void *) serSvcId);
-        long protSvcId = pubsub_tcpTopicReceiver_protocolSvcId(receiver);
-        psa_tcp_protocol_entry_t *protEntry = hashMap_get(psa->protocols.map, (void *) protSvcId);
-        const char *serType = serEntry == NULL ? "!Error!" : serEntry->serType;
-        const char *protType = protEntry == NULL ? "!Error!" : protEntry->protType;
-        const char *scope = pubsub_tcpTopicReceiver_scope(receiver);
-        const char *topic = pubsub_tcpTopicReceiver_topic(receiver);
-
-        celix_array_list_t *connected = celix_arrayList_create();
-        celix_array_list_t *unconnected = celix_arrayList_create();
-        pubsub_tcpTopicReceiver_listConnections(receiver, connected, unconnected);
-
-        fprintf(out, "|- Topic Receiver %s/%s\n", scope == NULL ? "(null)" : scope, topic);
-        fprintf(out, "   |- serializer type = %s\n", serType);
-        fprintf(out, "   |- protocol type = %s\n", protType);
-        for (int i = 0; i < celix_arrayList_size(connected); ++i) {
-            char *url = celix_arrayList_get(connected, i);
-            fprintf(out, "   |- connected url   = %s\n", url);
-            free(url);
-        }
-        for (int i = 0; i < celix_arrayList_size(unconnected); ++i) {
-            char *url = celix_arrayList_get(unconnected, i);
-            fprintf(out, "   |- unconnected url = %s\n", url);
-            free(url);
-        }
-        celix_arrayList_destroy(connected);
-        celix_arrayList_destroy(unconnected);
-    }
-    celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-    celixThreadMutex_unlock(&psa->protocols.mutex);
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-    fprintf(out, "\n");
-
-    return status;
-}
-
-pubsub_admin_metrics_t *pubsub_tcpAdmin_metrics(void *handle) {
-    pubsub_tcp_admin_t *psa = handle;
-    pubsub_admin_metrics_t *result = calloc(1, sizeof(*result));
-    snprintf(result->psaType, PUBSUB_AMDIN_METRICS_NAME_MAX, "%s", PUBSUB_TCP_ADMIN_TYPE);
-    result->senders = celix_arrayList_create();
-    result->receivers = celix_arrayList_create();
-
-    celixThreadMutex_lock(&psa->topicSenders.mutex);
-    hash_map_iterator_t iter = hashMapIterator_construct(psa->topicSenders.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        pubsub_tcp_topic_sender_t *sender = hashMapIterator_nextValue(&iter);
-        pubsub_admin_sender_metrics_t *metrics = pubsub_tcpTopicSender_metrics(sender);
-        celix_arrayList_add(result->senders, metrics);
-    }
-    celixThreadMutex_unlock(&psa->topicSenders.mutex);
-
-    celixThreadMutex_lock(&psa->topicReceivers.mutex);
-    iter = hashMapIterator_construct(psa->topicReceivers.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        pubsub_tcp_topic_receiver_t *receiver = hashMapIterator_nextValue(&iter);
-        pubsub_admin_receiver_metrics_t *metrics = pubsub_tcpTopicReceiver_metrics(receiver);
-        celix_arrayList_add(result->receivers, metrics);
-    }
-    celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-
-    return result;
-}
diff --git a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_admin.h b/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_admin.h
deleted file mode 100644
index b6286c8..0000000
--- a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_admin.h
+++ /dev/null
@@ -1,80 +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 CELIX_PUBSUB_TCP_ADMIN_H
-#define CELIX_PUBSUB_TCP_ADMIN_H
-
-#include <pubsub_admin_metrics.h>
-#include "celix_api.h"
-#include "celix_log_helper.h"
-#include "pubsub_psa_tcp_constants.h"
-
-typedef struct pubsub_tcp_admin pubsub_tcp_admin_t;
-
-pubsub_tcp_admin_t *pubsub_tcpAdmin_create(celix_bundle_context_t *ctx, celix_log_helper_t *logHelper);
-void pubsub_tcpAdmin_destroy(pubsub_tcp_admin_t *psa);
-
-celix_status_t pubsub_tcpAdmin_matchPublisher(void *handle,
-                                              long svcRequesterBndId,
-                                              const celix_filter_t *svcFilter,
-                                              celix_properties_t **topicProperties,
-                                              double *score,
-                                              long *serializerSvcId,
-                                              long *protocolSvcId);
-celix_status_t pubsub_tcpAdmin_matchSubscriber(void *handle,
-                                               long svcProviderBndId,
-                                               const celix_properties_t *svcProperties,
-                                               celix_properties_t **topicProperties,
-                                               double *score,
-                                               long *serializerSvcId,
-                                               long *protocolSvcId);
-celix_status_t pubsub_tcpAdmin_matchDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint, bool *match);
-
-celix_status_t pubsub_tcpAdmin_setupTopicSender(void *handle,
-                                                const char *scope,
-                                                const char *topic,
-                                                const celix_properties_t *topicProperties,
-                                                long serializerSvcId,
-                                                long protocolSvcId,
-                                                celix_properties_t **publisherEndpoint);
-celix_status_t pubsub_tcpAdmin_teardownTopicSender(void *handle, const char *scope, const char *topic);
-
-celix_status_t pubsub_tcpAdmin_setupTopicReceiver(void *handle,
-                                                  const char *scope,
-                                                  const char *topic,
-                                                  const celix_properties_t *topicProperties,
-                                                  long serializerSvcId,
-                                                  long protocolSvcId,
-                                                  celix_properties_t **subscriberEndpoint);
-celix_status_t pubsub_tcpAdmin_teardownTopicReceiver(void *handle, const char *scope, const char *topic);
-
-celix_status_t pubsub_tcpAdmin_addDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint);
-celix_status_t pubsub_tcpAdmin_removeDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint);
-
-void pubsub_tcpAdmin_addSerializerSvc(void *handle, void *svc, const celix_properties_t *props);
-void pubsub_tcpAdmin_removeSerializerSvc(void *handle, void *svc, const celix_properties_t *props);
-
-void pubsub_tcpAdmin_addProtocolSvc(void *handle, void *svc, const celix_properties_t *props);
-void pubsub_tcpAdmin_removeProtocolSvc(void *handle, void *svc, const celix_properties_t *props);
-bool pubsub_tcpAdmin_executeCommand(void *handle, const char *commandLine, FILE *outStream, FILE *errStream);
-
-pubsub_admin_metrics_t *pubsub_tcpAdmin_metrics(void *handle);
-
-#endif //CELIX_PUBSUB_TCP_ADMIN_H
-
diff --git a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_common.c b/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_common.c
deleted file mode 100644
index d8f05f7..0000000
--- a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_common.c
+++ /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.
- */
-#include <stdio.h>
-#include <string.h>
-#include "pubsub_tcp_common.h"
-
-
-bool psa_tcp_isPassive(const char* buffer) {
-    bool isPassive = false;
-    // Parse Properties
-    if (buffer != NULL) {
-        char buf[32];
-        snprintf(buf, 32, "%s", buffer);
-        char *trimmed = utils_stringTrim(buf);
-        if (strncasecmp("true", trimmed, strlen("true")) == 0) {
-            isPassive = true;
-        } else if (strncasecmp("false", trimmed, strlen("false")) == 0) {
-            isPassive = false;
-        }
-    }
-    return isPassive;
-}
diff --git a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_common.h b/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_common.h
deleted file mode 100644
index 9ea31db..0000000
--- a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_common.h
+++ /dev/null
@@ -1,33 +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 CELIX_PUBSUB_TCP_COMMON_H
-#define CELIX_PUBSUB_TCP_COMMON_H
-
-#include <utils.h>
-#include <hash_map.h>
-
-typedef struct pubsub_tcp_endPointStore {
-    celix_thread_mutex_t mutex;
-    hash_map_t *map;
-} pubsub_tcp_endPointStore_t;
-
-bool psa_tcp_isPassive(const char* buffer);
-
-#endif //CELIX_PUBSUB_TCP_COMMON_H
diff --git a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_handler.c b/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_handler.c
deleted file mode 100644
index 262940b..0000000
--- a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_handler.c
+++ /dev/null
@@ -1,1448 +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_tcp_handler.c
- *
- *  \date       July 18, 2019
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <array_list.h>
-#include <pthread.h>
-#if defined(__APPLE__)
-#include <sys/types.h>
-#include <sys/event.h>
-#include <sys/time.h>
-#else
-#include <sys/epoll.h>
-#endif
-#include <limits.h>
-#include <fcntl.h>
-#include <arpa/inet.h>
-#include <netinet/tcp.h>
-#include "hash_map.h"
-#include "utils.h"
-#include "pubsub_tcp_handler.h"
-
-#define MAX_EVENTS   64
-#define MAX_DEFAULT_BUFFER_SIZE 4u
-
-#if defined(__APPLE__)
-#ifndef MSG_NOSIGNAL
-#define MSG_NOSIGNAL (0)
-#endif
-#endif
-
-#define L_DEBUG(...) \
-    celix_logHelper_log(handle->logHelper, CELIX_LOG_LEVEL_DEBUG, __VA_ARGS__)
-#define L_INFO(...) \
-    celix_logHelper_log(handle->logHelper, CELIX_LOG_LEVEL_INFO, __VA_ARGS__)
-#define L_WARN(...) \
-    celix_logHelper_log(handle->logHelper, CELIX_LOG_LEVEL_WARNING, __VA_ARGS__)
-#define L_ERROR(...) \
-    celix_logHelper_log(handle->logHelper, CELIX_LOG_LEVEL_ERROR, __VA_ARGS__)
-
-//
-// Entry administration
-//
-typedef struct psa_tcp_connection_entry {
-    char *interface_url;
-    char *url;
-    int fd;
-    struct sockaddr_in addr;
-    socklen_t len;
-    bool connected;
-    bool headerError;
-    pubsub_protocol_message_t header;
-    size_t maxMsgSize;
-    size_t readHeaderSize;
-    size_t readHeaderBufferSize; // Size of headerBuffer
-    void *readHeaderBuffer;
-    size_t writeHeaderBufferSize; // Size of headerBuffer
-    void *writeHeaderBuffer;
-    size_t readFooterSize;
-    size_t readFooterBufferSize;
-    void *readFooterBuffer;
-    size_t writeFooterBufferSize;
-    void *writeFooterBuffer;
-    size_t bufferSize;
-    void *buffer;
-    size_t readMetaBufferSize;
-    void *readMetaBuffer;
-    size_t writeMetaBufferSize;
-    void *writeMetaBuffer;
-    unsigned int retryCount;
-    celix_thread_mutex_t writeMutex;
-    struct msghdr readMsg;
-} psa_tcp_connection_entry_t;
-
-//
-// Handle administration
-//
-struct pubsub_tcpHandler {
-    celix_thread_rwlock_t dbLock;
-    unsigned int timeout;
-    hash_map_t *connection_url_map;
-    hash_map_t *connection_fd_map;
-    hash_map_t *interface_url_map;
-    hash_map_t *interface_fd_map;
-    int efd;
-    pubsub_tcpHandler_receiverConnectMessage_callback_t receiverConnectMessageCallback;
-    pubsub_tcpHandler_receiverConnectMessage_callback_t receiverDisconnectMessageCallback;
-    void *receiverConnectPayload;
-    pubsub_tcpHandler_acceptConnectMessage_callback_t acceptConnectMessageCallback;
-    pubsub_tcpHandler_acceptConnectMessage_callback_t acceptDisconnectMessageCallback;
-    void *acceptConnectPayload;
-    pubsub_tcpHandler_processMessage_callback_t processMessageCallback;
-    void *processMessagePayload;
-    celix_log_helper_t *logHelper;
-    pubsub_protocol_service_t *protocol;
-    unsigned int bufferSize;
-    unsigned int maxMsgSize;
-    unsigned int maxSendRetryCount;
-    unsigned int maxRcvRetryCount;
-    double sendTimeout;
-    double rcvTimeout;
-    celix_thread_t thread;
-    bool running;
-    bool enableReceiveEvent;
-};
-
-static inline int pubsub_tcpHandler_closeConnectionEntry(pubsub_tcpHandler_t *handle, psa_tcp_connection_entry_t *entry, bool lock);
-static inline int pubsub_tcpHandler_closeInterfaceEntry(pubsub_tcpHandler_t *handle, psa_tcp_connection_entry_t *entry);
-static inline int pubsub_tcpHandler_makeNonBlocking(pubsub_tcpHandler_t *handle, int fd);
-static inline psa_tcp_connection_entry_t* pubsub_tcpHandler_createEntry(pubsub_tcpHandler_t *handle, int fd, char *url, char *interface_url, struct sockaddr_in *addr);
-static inline void pubsub_tcpHandler_freeEntry(psa_tcp_connection_entry_t *entry);
-static inline void pubsub_tcpHandler_releaseEntryBuffer(pubsub_tcpHandler_t *handle, int fd, unsigned int index);
-static inline long int pubsub_tcpHandler_getMsgSize(psa_tcp_connection_entry_t *entry);
-static inline void pubsub_tcpHandler_ensureReadBufferCapacity(pubsub_tcpHandler_t *handle, psa_tcp_connection_entry_t *entry);
-static inline bool pubsub_tcpHandler_readHeader(pubsub_tcpHandler_t *handle, int fd, psa_tcp_connection_entry_t *entry, long int* msgSize);
-static inline void pubsub_tcpHandler_decodePayload(pubsub_tcpHandler_t *handle, psa_tcp_connection_entry_t *entry);
-static inline long int pubsub_tcpHandler_readPayload(pubsub_tcpHandler_t *handle, int fd, psa_tcp_connection_entry_t *entry);
-static inline void pubsub_tcpHandler_connectionHandler(pubsub_tcpHandler_t *handle, int fd);
-static inline void pubsub_tcpHandler_handler(pubsub_tcpHandler_t *handle);
-static void *pubsub_tcpHandler_thread(void *data);
-
-
-
-//
-// Create a handle
-//
-pubsub_tcpHandler_t *pubsub_tcpHandler_create(pubsub_protocol_service_t *protocol, celix_log_helper_t *logHelper) {
-    pubsub_tcpHandler_t *handle = calloc(sizeof(*handle), 1);
-    if (handle != NULL) {
-#if defined(__APPLE__)
-        handle->efd = kqueue();
-#else
-        handle->efd = epoll_create1(0);
-#endif
-        handle->connection_url_map = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-        handle->connection_fd_map = hashMap_create(NULL, NULL, NULL, NULL);
-        handle->interface_url_map = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-        handle->interface_fd_map = hashMap_create(NULL, NULL, NULL, NULL);
-        handle->timeout = 2000; // default 2 sec
-        handle->logHelper = logHelper;
-        handle->protocol = protocol;
-        handle->bufferSize = MAX_DEFAULT_BUFFER_SIZE;
-        celixThreadRwlock_create(&handle->dbLock, 0);
-        handle->running = true;
-        celixThread_create(&handle->thread, NULL, pubsub_tcpHandler_thread, handle);
-        // signal(SIGPIPE, SIG_IGN);
-    }
-    return handle;
-}
-
-//
-// Destroys the handle
-//
-void pubsub_tcpHandler_destroy(pubsub_tcpHandler_t *handle) {
-    if (handle != NULL) {
-        celixThreadRwlock_readLock(&handle->dbLock);
-        bool running = handle->running;
-        celixThreadRwlock_unlock(&handle->dbLock);
-        if (running) {
-            celixThreadRwlock_writeLock(&handle->dbLock);
-            handle->running = false;
-            celixThreadRwlock_unlock(&handle->dbLock);
-            celixThread_join(handle->thread, NULL);
-        }
-        celixThreadRwlock_writeLock(&handle->dbLock);
-        hash_map_iterator_t interface_iter = hashMapIterator_construct(handle->interface_url_map);
-        while (hashMapIterator_hasNext(&interface_iter)) {
-            psa_tcp_connection_entry_t *entry = hashMapIterator_nextValue(&interface_iter);
-            if (entry != NULL) {
-                pubsub_tcpHandler_closeInterfaceEntry(handle, entry);
-            }
-        }
-
-        hash_map_iterator_t connection_iter = hashMapIterator_construct(handle->connection_url_map);
-        while (hashMapIterator_hasNext(&connection_iter)) {
-            psa_tcp_connection_entry_t *entry = hashMapIterator_nextValue(&connection_iter);
-            if (entry != NULL) {
-                pubsub_tcpHandler_closeConnectionEntry(handle, entry, true);
-            }
-        }
-        if (handle->efd >= 0) close(handle->efd);
-        hashMap_destroy(handle->connection_url_map, false, false);
-        hashMap_destroy(handle->connection_fd_map, false, false);
-        hashMap_destroy(handle->interface_url_map, false, false);
-        hashMap_destroy(handle->interface_fd_map, false, false);
-        celixThreadRwlock_unlock(&handle->dbLock);
-        celixThreadRwlock_destroy(&handle->dbLock);
-        free(handle);
-    }
-}
-
-//
-// Open the socket using an url
-//
-int pubsub_tcpHandler_open(pubsub_tcpHandler_t *handle, char *url) {
-    int rc = 0;
-    celixThreadRwlock_readLock(&handle->dbLock);
-    pubsub_utils_url_t *url_info = pubsub_utils_url_parse(url);
-    int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-    if (rc >= 0) {
-        int setting = 1;
-        if (rc == 0) {
-            rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &setting, sizeof(setting));
-            if (rc != 0) {
-                close(fd);
-                L_ERROR("[TCP Socket] Error setsockopt(SO_REUSEADDR): %s\n", strerror(errno));
-            }
-        }
-        if (rc == 0) {
-            rc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &setting, sizeof(setting));
-            if (rc != 0) {
-                close(fd);
-                L_ERROR("[TCP Socket] Error setsockopt(TCP_NODELAY): %s\n", strerror(errno));
-            }
-        } else {
-            L_ERROR("[TCP Socket] Error creating socket: %s\n", strerror(errno));
-        }
-        if (rc == 0 && handle->sendTimeout != 0.0) {
-            struct timeval tv;
-            tv.tv_sec = (long int) handle->sendTimeout;
-            tv.tv_usec = (long int) ((handle->sendTimeout - tv.tv_sec) * 1000000.0);
-            rc = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
-            if (rc != 0) {
-                L_ERROR("[TCP Socket] Error setsockopt (SO_SNDTIMEO) to set send timeout: %s", strerror(errno));
-            }
-        }
-        if (rc == 0 && handle->rcvTimeout != 0.0) {
-            struct timeval tv;
-            tv.tv_sec = (long int) handle->rcvTimeout;
-            tv.tv_usec = (long int) ((handle->rcvTimeout - tv.tv_sec) * 1000000.0);
-            rc = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
-            if (rc != 0) {
-                L_ERROR("[TCP Socket] Error setsockopt (SO_RCVTIMEO) to set send timeout: %s", strerror(errno));
-            }
-        }
-        struct sockaddr_in *addr = pubsub_utils_url_getInAddr(url_info->hostname, url_info->port_nr);
-        if (addr) {
-            rc = bind(fd, (struct sockaddr *) addr, sizeof(struct sockaddr));
-            if (rc != 0) {
-                close(fd);
-                L_ERROR("[TCP Socket] Error bind: %s\n", strerror(errno));
-            }
-            free(addr);
-        }
-    }
-    pubsub_utils_url_free(url_info);
-    celixThreadRwlock_unlock(&handle->dbLock);
-    return (!rc) ? fd : rc;
-}
-
-//
-// Closes the discriptor with it's connection/interfaces (receiver/sender)
-//
-int pubsub_tcpHandler_close(pubsub_tcpHandler_t *handle, int fd) {
-    int rc = 0;
-    if (handle != NULL) {
-        psa_tcp_connection_entry_t *entry = NULL;
-        celixThreadRwlock_writeLock(&handle->dbLock);
-        entry = hashMap_get(handle->interface_fd_map, (void *) (intptr_t) fd);
-        if (entry) {
-            entry = hashMap_remove(handle->interface_url_map, (void *) (intptr_t) entry->url);
-            rc = pubsub_tcpHandler_closeInterfaceEntry(handle, entry);
-            entry = NULL;
-        }
-        entry = hashMap_get(handle->connection_fd_map, (void *) (intptr_t) fd);
-        if (entry) {
-            entry = hashMap_remove(handle->connection_url_map, (void *) (intptr_t) entry->url);
-            rc = pubsub_tcpHandler_closeConnectionEntry(handle, entry, false);
-            entry = NULL;
-        }
-        celixThreadRwlock_unlock(&handle->dbLock);
-    }
-    return rc;
-}
-
-//
-// Create connection/interface entry
-//
-static inline psa_tcp_connection_entry_t *
-pubsub_tcpHandler_createEntry(pubsub_tcpHandler_t *handle, int fd, char *url, char *interface_url,
-                              struct sockaddr_in *addr) {
-    psa_tcp_connection_entry_t *entry = NULL;
-    if (fd >= 0) {
-        entry = calloc(sizeof(psa_tcp_connection_entry_t), 1);
-        entry->fd = fd;
-        celixThreadMutex_create(&entry->writeMutex, NULL);
-        if (url) {
-            entry->url = strndup(url, 1024 * 1024);
-        }
-        if (interface_url) {
-            entry->interface_url = strndup(interface_url, 1024 * 1024);
-        } else {
-            if (url) {
-                entry->interface_url = strndup(url, 1024 * 1024);
-            }
-        }
-        if (addr) {
-            entry->addr = *addr;
-        }
-        entry->len = sizeof(struct sockaddr_in);
-        size_t headerSize = 0;
-        size_t footerSize = 0;
-        handle->protocol->getHeaderSize(handle->protocol->handle, &headerSize);
-        handle->protocol->getFooterSize(handle->protocol->handle, &footerSize);
-        entry->readHeaderBufferSize = headerSize;
-        entry->writeHeaderBufferSize = headerSize;
-
-        entry->readFooterBufferSize = footerSize;
-        entry->writeFooterBufferSize = footerSize;
-        entry->bufferSize = MAX(handle->bufferSize, headerSize);
-        entry->connected = false;
-        unsigned minimalMsgSize = entry->writeHeaderBufferSize + entry->writeFooterBufferSize;
-        if ((minimalMsgSize > handle->maxMsgSize) && (handle->maxMsgSize)) {
-            L_ERROR("[TCP Socket] maxMsgSize (%d) < headerSize + FooterSize (%d): %s\n", handle->maxMsgSize, minimalMsgSize);
-        } else {
-            entry->maxMsgSize = (handle->maxMsgSize) ? handle->maxMsgSize : LONG_MAX;
-        }
-        entry->readHeaderBuffer = calloc(sizeof(char), headerSize);
-        entry->writeHeaderBuffer = calloc(sizeof(char), headerSize);
-        if (entry->readFooterBufferSize ) entry->readFooterBuffer = calloc(sizeof(char), entry->readFooterBufferSize );
-        if (entry->writeFooterBufferSize) entry->writeFooterBuffer = calloc(sizeof(char), entry->writeFooterBufferSize);
-        if (entry->bufferSize) entry->buffer = calloc(sizeof(char), entry->bufferSize);
-        memset(&entry->readMsg, 0x00, sizeof(struct msghdr));
-        entry->readMsg.msg_iov = calloc(sizeof(struct iovec), IOV_MAX);
-    }
-    return entry;
-}
-
-//
-// Free connection/interface entry
-//
-static inline void
-pubsub_tcpHandler_freeEntry(psa_tcp_connection_entry_t *entry) {
-    if (entry) {
-        free(entry->url);
-        free(entry->interface_url);
-        if (entry->fd >= 0) close(entry->fd);
-        free(entry->buffer);
-        free(entry->readHeaderBuffer);
-        free(entry->writeHeaderBuffer);
-        free(entry->readFooterBuffer);
-        free(entry->writeFooterBuffer);
-        free(entry->readMetaBuffer);
-        free(entry->writeMetaBuffer);
-        free(entry->readMsg.msg_iov);
-        celixThreadMutex_destroy(&entry->writeMutex);
-        free(entry);
-    }
-}
-
-//
-// Releases the Buffer
-//
-static inline void
-pubsub_tcpHandler_releaseEntryBuffer(pubsub_tcpHandler_t *handle, int fd, unsigned int index __attribute__((unused))) {
-    psa_tcp_connection_entry_t *entry = hashMap_get(handle->connection_fd_map, (void *) (intptr_t) fd);
-    if (entry != NULL) {
-        entry->buffer = NULL;
-        entry->bufferSize = 0;
-    }
-}
-
-//
-// Connect to url (receiver)
-//
-int pubsub_tcpHandler_connect(pubsub_tcpHandler_t *handle, char *url) {
-    int rc = 0;
-    psa_tcp_connection_entry_t *entry = hashMap_get(handle->connection_url_map, (void *) (intptr_t) url);
-    if (entry == NULL) {
-        pubsub_utils_url_t *url_info = pubsub_utils_url_parse(url);
-        int fd = pubsub_tcpHandler_open(handle, url_info->interface_url);
-        rc = fd;
-        // Connect to sender
-        struct sockaddr_in sin;
-        socklen_t len = sizeof(sin);
-        getsockname(fd, (struct sockaddr *) &sin, &len);
-        char *interface_url = pubsub_utils_url_get_url(&sin, NULL);
-        struct sockaddr_in *addr = pubsub_utils_url_getInAddr(url_info->hostname, url_info->port_nr);
-        if ((rc >= 0) && addr) {
-            rc = connect(fd, (struct sockaddr *) addr, sizeof(struct sockaddr));
-            if (rc < 0 && errno != EINPROGRESS) {
-                L_ERROR("[TCP Socket] Cannot connect to %s:%d: using %s err(%d): %s\n", url_info->hostname, url_info->port_nr, interface_url, errno, strerror(errno));
-                close(fd);
-            } else {
-                entry = pubsub_tcpHandler_createEntry(handle, fd, url, interface_url, &sin);
-            }
-            free(addr);
-        }
-        free(interface_url);
-        // Subscribe File Descriptor to epoll
-        if ((rc >= 0) && (entry)) {
-#if defined(__APPLE__)
-            struct kevent ev;
-            EV_SET (&ev, entry->fd, EVFILT_READ | EVFILT_WRITE, EV_ADD | EV_ENABLE, 0, 0, 0);
-            rc = kevent (handle->efd, &ev, 1, NULL, 0, NULL);
-#else
-            struct epoll_event event;
-            bzero(&event,  sizeof(struct epoll_event)); // zero the struct
-            event.events = EPOLLIN | EPOLLRDHUP | EPOLLERR;
-            event.data.fd = entry->fd;
-            rc = epoll_ctl(handle->efd, EPOLL_CTL_ADD, entry->fd, &event);
-#endif
-            if (rc < 0) {
-                pubsub_tcpHandler_freeEntry(entry);
-                L_ERROR("[TCP Socket] Cannot create poll event %s\n", strerror(errno));
-                entry = NULL;
-            }
-        }
-        if ((rc >= 0) && (entry)) {
-            celixThreadRwlock_writeLock(&handle->dbLock);
-            hashMap_put(handle->connection_url_map, entry->url, entry);
-            hashMap_put(handle->connection_fd_map, (void *) (intptr_t) entry->fd, entry);
-            celixThreadRwlock_unlock(&handle->dbLock);
-            pubsub_tcpHandler_connectionHandler(handle, fd);
-            L_INFO("[TCP Socket] Connect to %s using: %s\n", entry->url, entry->interface_url);
-        }
-        pubsub_utils_url_free(url_info);
-    }
-    return rc;
-}
-
-//
-// Disconnect from url
-//
-int pubsub_tcpHandler_disconnect(pubsub_tcpHandler_t *handle, char *url) {
-    int rc = 0;
-    if (handle != NULL) {
-        celixThreadRwlock_writeLock(&handle->dbLock);
-        psa_tcp_connection_entry_t *entry = NULL;
-        entry = hashMap_remove(handle->connection_url_map, url);
-        if (entry) {
-            pubsub_tcpHandler_closeConnectionEntry(handle, entry, false);
-        }
-        celixThreadRwlock_unlock(&handle->dbLock);
-    }
-    return rc;
-}
-
-// loses the connection entry (of receiver)
-//
-static inline int pubsub_tcpHandler_closeConnectionEntry(
-    pubsub_tcpHandler_t *handle, psa_tcp_connection_entry_t *entry, bool lock) {
-    int rc = 0;
-    if (handle != NULL && entry != NULL) {
-        fprintf(stdout, "[TCP Socket] Close connection to url: %s: \n", entry->url);
-        hashMap_remove(handle->connection_fd_map, (void *) (intptr_t) entry->fd);
-        if ((handle->efd >= 0)) {
-#if defined(__APPLE__)
-          struct kevent ev;
-          EV_SET (&ev, entry->fd, EVFILT_READ, EV_DELETE , 0, 0, 0);
-          rc = kevent (handle->efd, &ev, 1, NULL, 0, NULL);
-#else
-            struct epoll_event event;
-            bzero(&event, sizeof(struct epoll_event)); // zero the struct
-            rc = epoll_ctl(handle->efd, EPOLL_CTL_DEL, entry->fd, &event);
-#endif
-            if (rc < 0) {
-                L_ERROR("[PSA TCP] Error disconnecting %s\n", strerror(errno));
-            }
-        }
-        if (entry->fd >= 0) {
-            if (handle->receiverDisconnectMessageCallback)
-                handle->receiverDisconnectMessageCallback(handle->receiverConnectPayload, entry->url, lock);
-            if (handle->acceptConnectMessageCallback)
-                handle->acceptConnectMessageCallback(handle->acceptConnectPayload, entry->url);
-            pubsub_tcpHandler_freeEntry(entry);
-            entry = NULL;
-        }
-    }
-    return rc;
-}
-
-//
-// Closes the interface entry (of sender)
-//
-static inline int
-pubsub_tcpHandler_closeInterfaceEntry(pubsub_tcpHandler_t *handle,
-                                      psa_tcp_connection_entry_t *entry) {
-    int rc = 0;
-    if (handle != NULL && entry != NULL) {
-        L_INFO("[TCP Socket] Close interface url: %s: \n", entry->url);
-        hashMap_remove(handle->interface_fd_map, (void *) (intptr_t) entry->fd);
-        if ((handle->efd >= 0)) {
-#if defined(__APPLE__)
-            struct kevent ev;
-            EV_SET (&ev, entry->fd, EVFILT_READ, EV_DELETE , 0, 0, 0);
-            rc = kevent (handle->efd, &ev, 1, NULL, 0, NULL);
-#else
-            struct epoll_event event;
-            bzero(&event, sizeof(struct epoll_event)); // zero the struct
-            rc = epoll_ctl(handle->efd, EPOLL_CTL_DEL, entry->fd, &event);
-#endif
-            if (rc < 0) {
-                L_ERROR("[PSA TCP] Error disconnecting %s\n", strerror(errno));
-            }
-        }
-        if (entry->fd >= 0) {
-            pubsub_tcpHandler_freeEntry(entry);
-        }
-    }
-    return rc;
-}
-
-//
-// Make accept file descriptor non blocking
-//
-static inline int pubsub_tcpHandler_makeNonBlocking(pubsub_tcpHandler_t *handle, int fd) {
-    int rc = 0;
-    int flags = fcntl(fd, F_GETFL, 0);
-    if (flags == -1)
-        rc = flags;
-    else {
-        rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-        if (rc < 0) {
-            L_ERROR("[TCP Socket] Cannot set to NON_BLOCKING: %s\n", strerror(errno));
-        }
-    }
-    return rc;
-}
-
-//
-// setup listening to interface (sender) using an url
-//
-int pubsub_tcpHandler_listen(pubsub_tcpHandler_t *handle, char *url) {
-    int rc = 0;
-    celixThreadRwlock_readLock(&handle->dbLock);
-    psa_tcp_connection_entry_t *entry =
-        hashMap_get(handle->connection_url_map, (void *) (intptr_t) url);
-    celixThreadRwlock_unlock(&handle->dbLock);
-    if (entry == NULL) {
-        char protocol[] = "tcp";
-        int fd = pubsub_tcpHandler_open(handle, url);
-        rc = fd;
-        struct sockaddr_in *sin = pubsub_utils_url_from_fd(fd);
-        // Make handler fd entry
-        char *pUrl = pubsub_utils_url_get_url(sin, protocol);
-        entry = pubsub_tcpHandler_createEntry(handle, fd, pUrl, NULL, sin);
-        if (entry != NULL) {
-            entry->connected = true;
-            free(pUrl);
-            free(sin);
-            celixThreadRwlock_writeLock(&handle->dbLock);
-            if (rc >= 0) {
-                rc = listen(fd, SOMAXCONN);
-                if (rc != 0) {
-                    L_ERROR("[TCP Socket] Error listen: %s\n", strerror(errno));
-                    pubsub_tcpHandler_freeEntry(entry);
-                    entry = NULL;
-                }
-            }
-            if (rc >= 0) {
-                rc = pubsub_tcpHandler_makeNonBlocking(handle, fd);
-                if (rc < 0) {
-                    pubsub_tcpHandler_freeEntry(entry);
-                    entry = NULL;
-                }
-            }
-            if ((rc >= 0) && (handle->efd >= 0)) {
-#if defined(__APPLE__)
-                struct kevent ev;
-                EV_SET (&ev, fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
-                rc = kevent(handle->efd, &ev, 1, NULL, 0, NULL);
-#else
-                struct epoll_event event;
-                bzero(&event, sizeof(event)); // zero the struct
-                event.events = EPOLLIN | EPOLLRDHUP | EPOLLERR;
-                event.data.fd = fd;
-                rc = epoll_ctl(handle->efd, EPOLL_CTL_ADD, fd, &event);
-#endif
-                if (rc < 0) {
-                    L_ERROR("[TCP Socket] Cannot create poll: %s\n", strerror(errno));
-                    errno = 0;
-                    pubsub_tcpHandler_freeEntry(entry);
-                    entry = NULL;
-                }
-                if (entry) {
-                    L_INFO("[TCP Socket] Using %s for service annunciation", entry->url);
-                    hashMap_put(handle->interface_fd_map, (void *) (intptr_t) entry->fd, entry);
-                    hashMap_put(handle->interface_url_map, entry->url, entry);
-                }
-            }
-            celixThreadRwlock_unlock(&handle->dbLock);
-        } else {
-            L_ERROR("[TCP Socket] Error listen socket cannot bind to %s: %s\n", url ? url : "", strerror(errno));
-        }
-    }
-    return rc;
-}
-
-//
-// Setup default receive buffer size.
-// This size is used to allocated the initial read buffer, to avoid receive buffer reallocting.
-// The default receive buffer is allocated in the createEntry when the connection is establised
-//
-int pubsub_tcpHandler_setReceiveBufferSize(pubsub_tcpHandler_t *handle, unsigned int size) {
-    if (handle != NULL) {
-        celixThreadRwlock_writeLock(&handle->dbLock);
-        handle->bufferSize = size;
-        celixThreadRwlock_unlock(&handle->dbLock);
-    }
-    return 0;
-}
-
-//
-// Set Maximum message size
-//
-int pubsub_tcpHandler_setMaxMsgSize(pubsub_tcpHandler_t *handle, unsigned int size) {
-    if (handle != NULL) {
-        celixThreadRwlock_writeLock(&handle->dbLock);
-        handle->maxMsgSize = size;
-        celixThreadRwlock_unlock(&handle->dbLock);
-    }
-    return 0;
-}
-
-//
-// Setup thread timeout
-//
-void pubsub_tcpHandler_setTimeout(pubsub_tcpHandler_t *handle,
-                                  unsigned int timeout) {
-    if (handle != NULL) {
-        celixThreadRwlock_writeLock(&handle->dbLock);
-        handle->timeout = timeout;
-        celixThreadRwlock_unlock(&handle->dbLock);
-    }
-}
-
-//
-// Setup thread name
-//
-void pubsub_tcpHandler_setThreadName(pubsub_tcpHandler_t *handle,
-                                     const char *topic, const char *scope) {
-    if ((handle != NULL) && (topic)) {
-        char *thread_name = NULL;
-        if ((scope) && (topic))
-            asprintf(&thread_name, "TCP TS %s/%s", scope, topic);
-        else
-            asprintf(&thread_name, "TCP TS %s", topic);
-        celixThreadRwlock_writeLock(&handle->dbLock);
-        celixThread_setName(&handle->thread, thread_name);
-        celixThreadRwlock_unlock(&handle->dbLock);
-        free(thread_name);
-    }
-}
-
-//
-// Setup thread priorities
-//
-void pubsub_tcpHandler_setThreadPriority(pubsub_tcpHandler_t *handle, long prio,
-                                         const char *sched) {
-    if (handle == NULL)
-        return;
-    // NOTE. Function will abort when performing a sched_setscheduler without
-    // permission. As result permission has to be checked first.
-    // TODO update this to use cap_get_pid and cap-get_flag instead of check user
-    // is root (note adds dep to -lcap)
-    bool gotPermission = false;
-    if (getuid() == 0) {
-        gotPermission = true;
-    }
-    if (sched != NULL) {
-        int policy = SCHED_OTHER;
-        if (strncmp("SCHED_OTHER", sched, 16) == 0) {
-            policy = SCHED_OTHER;
-#if !defined(__APPLE__)
-        } else if (strncmp("SCHED_BATCH", sched, 16) == 0) {
-            policy = SCHED_BATCH;
-        } else if (strncmp("SCHED_IDLE", sched, 16) == 0) {
-            policy = SCHED_IDLE;
-#endif
-        } else if (strncmp("SCHED_FIFO", sched, 16) == 0) {
-            policy = SCHED_FIFO;
-        } else if (strncmp("SCHED_RR", sched, 16) == 0) {
-            policy = SCHED_RR;
-        }
-        if (gotPermission) {
-            celixThreadRwlock_writeLock(&handle->dbLock);
-            if (prio > 0 && prio < 100) {
-                struct sched_param sch;
-                bzero(&sch, sizeof(struct sched_param));
-                sch.sched_priority = (int)prio;
-                pthread_setschedparam(handle->thread.thread, policy, &sch);
-            } else {
-                L_INFO("Skipping configuration of thread prio to %i and thread "
-                       "scheduling to %s. No permission\n",
-                       (int) prio, sched);
-            }
-            celixThreadRwlock_unlock(&handle->dbLock);
-        }
-    }
-}
-
-void pubsub_tcpHandler_setSendRetryCnt(pubsub_tcpHandler_t *handle, unsigned int count) {
-    if (handle != NULL) {
-        celixThreadRwlock_writeLock(&handle->dbLock);
-        handle->maxSendRetryCount = count;
-        celixThreadRwlock_unlock(&handle->dbLock);
-    }
-}
-
-void pubsub_tcpHandler_setReceiveRetryCnt(pubsub_tcpHandler_t *handle, unsigned int count) {
-    if (handle != NULL) {
-        celixThreadRwlock_writeLock(&handle->dbLock);
-        handle->maxRcvRetryCount = count;
-        celixThreadRwlock_unlock(&handle->dbLock);
-    }
-}
-
-void pubsub_tcpHandler_setSendTimeOut(pubsub_tcpHandler_t *handle, double timeout) {
-    if (handle != NULL) {
-        celixThreadRwlock_writeLock(&handle->dbLock);
-        handle->sendTimeout = timeout;
-        celixThreadRwlock_unlock(&handle->dbLock);
-    }
-}
-
-void pubsub_tcpHandler_setReceiveTimeOut(pubsub_tcpHandler_t *handle, double timeout) {
-    if (handle != NULL) {
-        celixThreadRwlock_writeLock(&handle->dbLock);
-        handle->rcvTimeout = timeout;
-        celixThreadRwlock_unlock(&handle->dbLock);
-    }
-}
-
-void pubsub_tcpHandler_enableReceiveEvent(pubsub_tcpHandler_t *handle,bool enable) {
-    if (handle != NULL) {
-        celixThreadRwlock_writeLock(&handle->dbLock);
-        handle->enableReceiveEvent = enable;
-        celixThreadRwlock_unlock(&handle->dbLock);
-    }
-}
-
-static inline long int pubsub_tcpHandler_getMsgSize(psa_tcp_connection_entry_t *entry) {
-    // Note header message is already read
-    return (long int)entry->header.header.payloadPartSize + (long int)entry->header.header.metadataSize + (long int)entry->readFooterSize;
-}
-
-static inline 
-bool pubsub_tcpHandler_readHeader(pubsub_tcpHandler_t *handle, int fd, psa_tcp_connection_entry_t *entry, long int* msgSize) {
-    bool result = false;
-    size_t syncSize = 0;
-    size_t protocolHeaderBufferSize = 0;
-    // Get Sync Size
-    handle->protocol->getSyncHeaderSize(handle->protocol->handle, &syncSize);
-    // Get HeaderSize of the Protocol Header
-    handle->protocol->getHeaderSize(handle->protocol->handle, &entry->readHeaderSize);
-    // Get HeaderBufferSize of the Protocol Header, when headerBufferSize == 0, the protocol header is included in the payload (needed for endpoints)
-    handle->protocol->getHeaderBufferSize(handle->protocol->handle, &protocolHeaderBufferSize);
-
-    // Ensure capacity in header buffer
-    pubsub_tcpHandler_ensureReadBufferCapacity(handle, entry);
-
-    entry->readMsg.msg_iovlen = 0;
-    entry->readMsg.msg_iov[entry->readMsg.msg_iovlen].iov_base = entry->readHeaderBuffer;
-    entry->readMsg.msg_iov[entry->readMsg.msg_iovlen].iov_len  = entry->readHeaderBufferSize;
-    entry->readMsg.msg_iovlen++;
-
-    // Read the message
-    long int nbytes = 0;
-    // Use peek flag to find sync word or when header is part of the payload
-    unsigned int flag = (entry->headerError || (!protocolHeaderBufferSize)) ? MSG_PEEK : 0;
-    if (entry->readHeaderSize) nbytes = recvmsg(fd, &(entry->readMsg), MSG_NOSIGNAL | MSG_WAITALL | flag);
-    if (nbytes >= entry->readHeaderSize) {
-        if (handle->protocol->decodeHeader(handle->protocol->handle,
-                                           entry->readMsg.msg_iov[0].iov_base,
-                                           entry->readMsg.msg_iov[0].iov_len,
-                                           &entry->header) == CELIX_SUCCESS) {
-            // read header from queue, when recovered from headerError and when header is not part of the payload. (Because of MSG_PEEK)
-            if (entry->headerError && protocolHeaderBufferSize && entry->readHeaderSize) nbytes = recvmsg(fd, &(entry->readMsg), MSG_NOSIGNAL | MSG_WAITALL);
-            entry->headerError = false;
-            result = true;
-        } else {
-            // Did not receive correct header
-            // skip sync word and try to read next header
-            if (!entry->headerError) {
-                L_WARN("[TCP Socket] Failed to decode message header (fd: %d) (url: %s)", entry->fd, entry->url);
-            }
-            entry->headerError = true;
-            entry->readMsg.msg_iovlen = 0;
-            entry->readMsg.msg_iov[entry->readMsg.msg_iovlen].iov_len = syncSize;
-            entry->readMsg.msg_iovlen++;
-            // remove sync item from the queue
-            if (syncSize) nbytes = recvmsg(fd, &(entry->readMsg), MSG_NOSIGNAL | MSG_WAITALL);
-        }
-    }
-    if (msgSize) *msgSize = nbytes;
-    return result;
-}
-
-
-static inline void pubsub_tcpHandler_ensureReadBufferCapacity(pubsub_tcpHandler_t *handle, psa_tcp_connection_entry_t *entry) {
-    if (entry->readHeaderSize > entry->readHeaderBufferSize) {
-        free(entry->readHeaderBuffer);
-        entry->readHeaderBuffer = malloc((size_t) entry->readHeaderSize);
-        entry->readHeaderBufferSize = entry->readHeaderSize;
-    }
-
-    if (entry->header.header.payloadSize > entry->bufferSize) {
-        free(entry->buffer);
-        entry->buffer = malloc((size_t)entry->header.header.payloadSize);
-        entry->bufferSize = entry->header.header.payloadSize;
-    }
-
-    if (entry->header.header.metadataSize > entry->readMetaBufferSize) {
-        free(entry->readMetaBuffer);
-        entry->readMetaBuffer = malloc((size_t) entry->header.header.metadataSize);
-        entry->readMetaBufferSize = entry->header.header.metadataSize;
-    }
-
-    if (entry->readFooterSize > entry->readFooterBufferSize) {
-        free(entry->readFooterBuffer);
-        entry->readFooterBuffer = malloc( (size_t) entry->readFooterSize);
-        entry->readFooterBufferSize = entry->readFooterSize;
-    }
-}
-
-static inline
-void pubsub_tcpHandler_decodePayload(pubsub_tcpHandler_t *handle, psa_tcp_connection_entry_t *entry) {
-
-  if (entry->header.header.payloadSize > 0) {
-      handle->protocol->decodePayload(handle->protocol->handle, entry->buffer, entry->header.header.payloadSize, &entry->header);
-  }
-  if (entry->header.header.metadataSize > 0) {
-      handle->protocol->decodeMetadata(handle->protocol->handle, entry->readMetaBuffer,
-                                       entry->header.header.metadataSize, &entry->header);
-  }
-  if (handle->processMessageCallback && entry->header.payload.payload != NULL && entry->header.payload.length) {
-    struct timespec receiveTime;
-    clock_gettime(CLOCK_REALTIME, &receiveTime);
-    bool releaseEntryBuffer = false;
-    handle->processMessageCallback(handle->processMessagePayload, &entry->header, &releaseEntryBuffer, &receiveTime);
-    if (releaseEntryBuffer) pubsub_tcpHandler_releaseEntryBuffer(handle, entry->fd, 0);
-  }
-}
-
-static inline
-long int pubsub_tcpHandler_readPayload(pubsub_tcpHandler_t *handle, int fd, psa_tcp_connection_entry_t *entry) {
-    entry->readMsg.msg_iovlen = 0;
-    handle->protocol->getFooterSize(handle->protocol->handle, &entry->readFooterSize);
-
-    // from the header can be determined how large buffers should be. Even before receiving all data these buffers can be allocated
-    pubsub_tcpHandler_ensureReadBufferCapacity(handle, entry);
-
-    if (entry->header.header.payloadPartSize) {
-        char* buffer = entry->buffer;
-        entry->readMsg.msg_iov[entry->readMsg.msg_iovlen].iov_base = &buffer[entry->header.header.payloadOffset];
-        entry->readMsg.msg_iov[entry->readMsg.msg_iovlen].iov_len = entry->header.header.payloadPartSize;
-        entry->readMsg.msg_iovlen++;
-    }
-    if (entry->header.header.metadataSize) {
-        entry->readMsg.msg_iov[entry->readMsg.msg_iovlen].iov_base = entry->readMetaBuffer;
-        entry->readMsg.msg_iov[entry->readMsg.msg_iovlen].iov_len  = entry->header.header.metadataSize;
-        entry->readMsg.msg_iovlen++;
-    }
-
-    if (entry->readFooterSize) {
-        entry->readMsg.msg_iov[entry->readMsg.msg_iovlen].iov_base = entry->readFooterBuffer;
-        entry->readMsg.msg_iov[entry->readMsg.msg_iovlen].iov_len  = entry->readFooterSize;
-        entry->readMsg.msg_iovlen++;
-    }
-
-    long int nbytes = recvmsg(fd, &(entry->readMsg), MSG_NOSIGNAL | MSG_WAITALL);
-    if (nbytes >= pubsub_tcpHandler_getMsgSize(entry)) {
-        bool valid = true;
-        if (entry->readFooterSize) {
-            if (handle->protocol->decodeFooter(handle->protocol->handle, entry->readFooterBuffer, entry->readFooterBufferSize, &entry->header) != CELIX_SUCCESS) {
-                // Did not receive correct footer
-                L_ERROR("[TCP Socket] Failed to decode message footer seq %d (received corrupt message, transmit buffer full?) (fd: %d) (url: %s)", entry->header.header.seqNr, entry->fd, entry->url);
-                valid = false;
-            }
-        }
-        if (!entry->header.header.isLastSegment) {
-            // Not last Segment of message
-            valid = false;
-        }
-
-        if (valid) {
-            // Complete message is received
-            pubsub_tcpHandler_decodePayload(handle, entry);
-        }
-    }
-    return nbytes;
-}
-
-//
-// Reads data from the filedescriptor which has date (determined by epoll()) and stores it in the internal structure
-// If the message is completely reassembled true is returned and the index and size have valid values
-//
-int pubsub_tcpHandler_read(pubsub_tcpHandler_t *handle, int fd) {
-    celixThreadRwlock_readLock(&handle->dbLock);
-    psa_tcp_connection_entry_t *entry = hashMap_get(handle->interface_fd_map, (void *) (intptr_t) fd);
-    if (entry == NULL) {
-        entry = hashMap_get(handle->connection_fd_map, (void *) (intptr_t) fd);
-    }
-    // Find FD entry
-    if (entry == NULL) {
-        celixThreadRwlock_unlock(&handle->dbLock);
-        return -1;
-    }
-    // If it's not connected return from function
-    if (!entry->connected) {
-        celixThreadRwlock_unlock(&handle->dbLock);
-        return -1;
-    }
-    long int nbytes = 0;
-    // if not yet enough bytes are received the header can not be read
-    if (pubsub_tcpHandler_readHeader(handle, fd, entry, &nbytes)) {
-        nbytes = pubsub_tcpHandler_readPayload(handle, fd, entry);
-    }
-    if (nbytes > 0) {
-        entry->retryCount = 0;
-    } else if (nbytes < 0) {
-        if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
-            // Non blocking interrupt
-            entry->retryCount = 0;
-        } else if (entry->retryCount < handle->maxRcvRetryCount) {
-            entry->retryCount++;
-            L_WARN(
-                    "[TCP Socket] Failed to receive message (fd: %d), try again. error(%d): %s, Retry count %u of %u.",
-                    entry->fd, errno, strerror(errno), entry->retryCount, handle->maxSendRetryCount);
-        } else {
-            L_ERROR("[TCP Socket] Failed to receive message (fd: %d) after %u retries! Closing connection... Error: %s",
-                    entry->fd, handle->maxRcvRetryCount, strerror(errno));
-            nbytes = 0; //Return 0 as indicator to close the connection
-        }
-    }
-    celixThreadRwlock_unlock(&handle->dbLock);
-    return (int)nbytes;
-}
-
-int pubsub_tcpHandler_addMessageHandler(pubsub_tcpHandler_t *handle, void *payload,
-                                        pubsub_tcpHandler_processMessage_callback_t processMessageCallback) {
-    int result = 0;
-    celixThreadRwlock_writeLock(&handle->dbLock);
-    handle->processMessageCallback = processMessageCallback;
-    handle->processMessagePayload = payload;
-    celixThreadRwlock_unlock(&handle->dbLock);
-    return result;
-}
-
-int pubsub_tcpHandler_addReceiverConnectionCallback(pubsub_tcpHandler_t *handle, void *payload,
-                                                    pubsub_tcpHandler_receiverConnectMessage_callback_t connectMessageCallback,
-                                                    pubsub_tcpHandler_receiverConnectMessage_callback_t disconnectMessageCallback) {
-    int result = 0;
-    celixThreadRwlock_writeLock(&handle->dbLock);
-    handle->receiverConnectMessageCallback = connectMessageCallback;
-    handle->receiverDisconnectMessageCallback = disconnectMessageCallback;
-    handle->receiverConnectPayload = payload;
-    celixThreadRwlock_unlock(&handle->dbLock);
-    return result;
-}
-
-//
-// Write large data to TCP. .
-//
-int pubsub_tcpHandler_write(pubsub_tcpHandler_t *handle, pubsub_protocol_message_t *message, struct iovec *msgIoVec,
-                            size_t msg_iov_len, int flags) {
-    int result = 0;
-    if (handle == NULL) {
-        return -1;
-    }
-    int connFdCloseQueue[hashMap_size(handle->connection_fd_map)];
-    int nofConnToClose = 0;
-    if (handle) {
-        celixThreadRwlock_readLock(&handle->dbLock);
-        hash_map_iterator_t iter = hashMapIterator_construct(handle->connection_fd_map);
-        size_t max_msg_iov_len = IOV_MAX - 2; // header , footer, padding
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_tcp_connection_entry_t *entry = hashMapIterator_nextValue(&iter);
-            if (!entry->connected) {
-                continue;
-            }
-            // When maxMsgSize is zero then payloadSize is disabled
-            if (entry->maxMsgSize == 0) {
-                // if max msg size is set to zero nothing will be send
-                continue;
-            }
-            celixThreadMutex_lock(&entry->writeMutex);
-            void *payloadData = NULL;
-            size_t payloadSize = 0;
-            if (msg_iov_len == 1) {
-                handle->protocol->encodePayload(handle->protocol->handle, message, &payloadData, &payloadSize);
-            } else {
-                for (size_t i = 0; i < msg_iov_len; i++) {
-                    payloadSize += msgIoVec[i].iov_len;
-                }
-            }
-
-            // check if message is not too large
-            bool isMessageSegmentationSupported = false;
-            handle->protocol->isMessageSegmentationSupported(handle->protocol->handle, &isMessageSegmentationSupported);
-            if (!isMessageSegmentationSupported && (msg_iov_len > max_msg_iov_len || payloadSize > entry->maxMsgSize)) {
-                L_WARN("[TCP Socket] Failed to send message (fd: %d), Message segmentation is not supported\n", entry->fd);
-                celixThreadMutex_unlock(&entry->writeMutex);
-                continue;
-            }
-
-            message->header.convertEndianess = 0;
-            message->header.payloadSize = payloadSize;
-            message->header.payloadPartSize = payloadSize;
-            message->header.payloadOffset = 0;
-            message->header.isLastSegment = 1;
-
-            void *metadataData = NULL;
-            size_t metadataSize = 0;
-            if (message->metadata.metadata) {
-                metadataSize = entry->writeMetaBufferSize;
-                metadataData = entry->writeMetaBuffer;
-                // When maxMsgSize is smaller then meta data is disabled
-                if (metadataSize > entry->maxMsgSize) {
-                    metadataSize = 0;
-                }
-                handle->protocol->encodeMetadata(handle->protocol->handle, message, &metadataData, &metadataSize);
-            }
-
-            message->header.metadataSize = metadataSize;
-            size_t totalMsgSize = payloadSize + metadataSize;
-
-            size_t sendMsgSize = 0;
-            size_t msgPayloadOffset = 0;
-            size_t msgIovOffset     = 0;
-            bool allPayloadAdded = (payloadSize == 0);
-            long int nbytes = LONG_MAX;
-            while (sendMsgSize < totalMsgSize && nbytes > 0) {
-                struct msghdr msg;
-                struct iovec msg_iov[IOV_MAX];
-                memset(&msg, 0x00, sizeof(struct msghdr));
-                msg.msg_name = &entry->addr;
-                msg.msg_namelen = entry->len;
-                msg.msg_flags = flags;
-                msg.msg_iov = msg_iov;
-
-                size_t msgPartSize = 0;
-                message->header.payloadPartSize = 0;
-                message->header.payloadOffset = 0;
-                message->header.metadataSize = 0;
-                message->header.isLastSegment = 0;
-
-                size_t protocolHeaderBufferSize = 0;
-                // Get HeaderBufferSize of the Protocol Header, when headerBufferSize == 0, the protocol header is included in the payload (needed for endpoints)
-                handle->protocol->getHeaderBufferSize(handle->protocol->handle, &protocolHeaderBufferSize);
-                size_t footerSize = 0;
-                // Get size of the Protocol Footer
-                handle->protocol->getFooterSize(handle->protocol->handle, &footerSize);
-                size_t maxMsgSize = entry->maxMsgSize - protocolHeaderBufferSize - footerSize;
-
-                // reserve space for the header if required, header is added later when size of message is known (message can split in parts)
-                if (protocolHeaderBufferSize) {
-                    msg.msg_iovlen++;
-                }
-                // Write generic seralized payload in vector buffer
-                if (!allPayloadAdded) {
-                    if (payloadSize && payloadData && maxMsgSize) {
-                        char *buffer = payloadData;
-                        msg.msg_iov[msg.msg_iovlen].iov_base = &buffer[msgPayloadOffset];
-                        msg.msg_iov[msg.msg_iovlen].iov_len = MIN((payloadSize - msgPayloadOffset), maxMsgSize);
-                        msgPartSize += msg.msg_iov[msg.msg_iovlen].iov_len;
-                        msg.msg_iovlen++;
-
-                    } else {
-                        // copy serialized vector into vector buffer
-                        size_t i;
-                        for (i = msgIovOffset; i < MIN(msg_iov_len, msgIovOffset + max_msg_iov_len); i++) {
-                            if ((msgPartSize + msgIoVec[i].iov_len) > maxMsgSize) {
-                                break;
-                            }
-                            msg.msg_iov[msg.msg_iovlen].iov_base = msgIoVec[i].iov_base;
-                            msg.msg_iov[msg.msg_iovlen].iov_len = msgIoVec[i].iov_len;
-                            msgPartSize += msg.msg_iov[msg.msg_iovlen].iov_len;
-                            msg.msg_iovlen++;
-                        }
-                        // if no entry could be added
-                        if (i == msgIovOffset) {
-                            // TODO element can be split in parts?
-                            L_ERROR("[TCP Socket] vector io element is larger than max msg size");
-                            break;
-                        }
-                        msgIovOffset = i;
-                    }
-                    message->header.payloadPartSize = msgPartSize;
-                    message->header.payloadOffset   = msgPayloadOffset;
-                    msgPayloadOffset += message->header.payloadPartSize;
-                    sendMsgSize = msgPayloadOffset;
-                    allPayloadAdded= msgPayloadOffset >= payloadSize;
-                }
-
-                // Write optional metadata in vector buffer
-                if (allPayloadAdded &&
-                    (metadataSize != 0 && metadataData) &&
-                    (msgPartSize < maxMsgSize) &&
-                    (msg.msg_iovlen-1 < max_msg_iov_len)) {  // header is already included
-                    msg.msg_iov[msg.msg_iovlen].iov_base = metadataData;
-                    msg.msg_iov[msg.msg_iovlen].iov_len = metadataSize;
-                    msg.msg_iovlen++;
-                    msgPartSize += metadataSize;
-                    message->header.metadataSize = metadataSize;
-                    sendMsgSize += metadataSize;
-                }
-                if (sendMsgSize >= totalMsgSize) {
-                    message->header.isLastSegment = 0x1;
-                }
-
-                void *headerData = NULL;
-                size_t headerSize = 0;
-                // Get HeaderSize of the Protocol Header
-                handle->protocol->getHeaderSize(handle->protocol->handle, &headerSize);
-
-                // check if header is not part of the payload (=> headerBufferSize = 0)
-                if (protocolHeaderBufferSize) {
-                    headerData = entry->writeHeaderBuffer;
-                    // Encode the header, with payload size and metadata size
-                    handle->protocol->encodeHeader(handle->protocol->handle, message, &headerData, &headerSize);
-                    entry->writeHeaderBufferSize = MAX(headerSize, entry->writeHeaderBufferSize);
-                    if (headerData && entry->writeHeaderBuffer != headerData) {
-                        entry->writeHeaderBuffer = headerData;
-                    }
-                    if (headerSize && headerData) {
-                        // Write header in 1st vector buffer item
-                        msg.msg_iov[0].iov_base = headerData;
-                        msg.msg_iov[0].iov_len = headerSize;
-                        msgPartSize += msg.msg_iov[0].iov_len;
-                    } else {
-                        L_ERROR("[TCP Socket] No header buffer is generated");
-                        break;
-                    }
-                }
-
-                void *footerData = NULL;
-                // Write optional footerData in vector buffer
-                if (footerSize) {
-                    footerData = entry->writeFooterBuffer;
-                    handle->protocol->encodeFooter(handle->protocol->handle, message, &footerData, &footerSize);
-                    if (footerData && entry->writeFooterBuffer != footerData) {
-                        entry->writeFooterBuffer = footerData;
-                        entry->writeFooterBufferSize = footerSize;
-                    }
-                    if (footerData) {
-                        msg.msg_iov[msg.msg_iovlen].iov_base = footerData;
-                        msg.msg_iov[msg.msg_iovlen].iov_len  = footerSize;
-                        msg.msg_iovlen++;
-                        msgPartSize += footerSize;
-                    }
-                }
-                nbytes = sendmsg(entry->fd, &msg, flags | MSG_NOSIGNAL);
-
-                //  When a specific socket keeps reporting errors can indicate a subscriber
-                //  which is not active anymore, the connection will remain until the retry
-                //  counter exceeds the maximum retry count.
-                //  Btw, also, SIGSTOP issued by a debugging tool can result in EINTR error.
-                if (nbytes == -1) {
-                    if (entry->retryCount < handle->maxSendRetryCount) {
-                        entry->retryCount++;
-                        L_ERROR(
-                            "[TCP Socket] Failed to send message (fd: %d), try again. Retry count %u of %u, error(%d): %s.",
-                            entry->fd, entry->retryCount, handle->maxSendRetryCount, errno, strerror(errno));
-                    } else {
-                        L_ERROR(
-                            "[TCP Socket] Failed to send message (fd: %d) after %u retries! Closing connection... Error: %s", entry->fd, handle->maxSendRetryCount, strerror(errno));
-                        connFdCloseQueue[nofConnToClose++] = entry->fd;
-                    }
-                    result = -1; //At least one connection failed sending
-                } else if (msgPartSize) {
-                    entry->retryCount = 0;
-                    if (nbytes != msgPartSize) {
-                        L_ERROR("[TCP Socket] seq: %d MsgSize not correct: %d != %d (%s)\n", message->header.seqNr, msgPartSize, nbytes, strerror(errno));
-                    }
-                }
-                // Note: serialized Payload is deleted by serializer
-                if (payloadData && (payloadData != message->payload.payload)) {
-                    free(payloadData);
-                }
-            }
-            celixThreadMutex_unlock(&entry->writeMutex);
-        }
-        celixThreadRwlock_unlock(&handle->dbLock);
-    }
-    //Force close all connections that are queued in a list, done outside of locking handle->dbLock to prevent deadlock
-    for (int i = 0; i < nofConnToClose; i++) {
-        pubsub_tcpHandler_close(handle, connFdCloseQueue[i]);
-    }
-    return result;
-}
-
-//
-// get interface URL
-//
-char *pubsub_tcpHandler_get_interface_url(pubsub_tcpHandler_t *handle) {
-    hash_map_iterator_t iter =
-        hashMapIterator_construct(handle->interface_url_map);
-    char *url = NULL;
-    while (hashMapIterator_hasNext(&iter)) {
-        psa_tcp_connection_entry_t *entry =
-            hashMapIterator_nextValue(&iter);
-        if (entry && entry->url) {
-            if (!url) {
-                url = celix_utils_strdup(entry->url);
-            } else {
-                char *tmp = url;
-                asprintf(&url, "%s %s", tmp, entry->url);
-                free(tmp);
-            }
-        }
-    }
-    return url;
-}
-//
-// get interface URL
-//
-char *pubsub_tcpHandler_get_connection_url(pubsub_tcpHandler_t *handle) {
-    celixThreadRwlock_writeLock(&handle->dbLock);
-    hash_map_iterator_t iter =
-            hashMapIterator_construct(handle->connection_url_map);
-    char *url = NULL;
-    while (hashMapIterator_hasNext(&iter)) {
-        psa_tcp_connection_entry_t *entry =
-                hashMapIterator_nextValue(&iter);
-        if (entry && entry->url) {
-            if (!url) {
-                pubsub_utils_url_t *url_info = pubsub_utils_url_parse(entry->url);
-                url = celix_utils_strdup(url_info->interface_url ? url_info->interface_url : entry->url);
-                pubsub_utils_url_free(url_info);
-            } else {
-                char *tmp = url;
-                pubsub_utils_url_t *url_info = pubsub_utils_url_parse(entry->url);
-                asprintf(&url, "%s %s", tmp, url_info->interface_url ? url_info->interface_url : entry->url);
-                pubsub_utils_url_free(url_info);
-                free(tmp);
-            }
-        }
-    }
-    celixThreadRwlock_unlock(&handle->dbLock);
-    return url;
-}
-
-//
-// Handle non-blocking accept (sender)
-//
-static inline
-int pubsub_tcpHandler_acceptHandler(pubsub_tcpHandler_t *handle, psa_tcp_connection_entry_t *pendingConnectionEntry) {
-    celixThreadRwlock_writeLock(&handle->dbLock);
-    // new connection available
-    struct sockaddr_in their_addr;
-    socklen_t len = sizeof(struct sockaddr_in);
-    int fd = accept(pendingConnectionEntry->fd, (struct sockaddr*)&their_addr, &len);
-    int rc = fd;
-    if (rc == -1) {
-        L_ERROR("[TCP Socket] accept failed: %s\n", strerror(errno));
-    }
-    if (rc >= 0) {
-        // handle new connection:
-        struct sockaddr_in sin;
-        getsockname(pendingConnectionEntry->fd, (struct sockaddr *) &sin, &len);
-        char *interface_url = pubsub_utils_url_get_url(&sin, NULL);
-        char *url = pubsub_utils_url_get_url(&their_addr, NULL);
-        psa_tcp_connection_entry_t *entry = pubsub_tcpHandler_createEntry(handle, fd, url, interface_url, &their_addr);
-#if defined(__APPLE__)
-        struct kevent ev;
-        EV_SET (&ev, entry->fd, EVFILT_READ, EV_ADD | EV_ENABLE , 0, 0, 0);
-        rc = kevent (handle->efd, &ev, 1, NULL, 0, NULL);
-#else
-        struct epoll_event event;
-        bzero(&event, sizeof(event)); // zero the struct
-        event.events = EPOLLRDHUP | EPOLLERR;
-        if (handle->enableReceiveEvent) event.events |= EPOLLIN;
-        event.data.fd = entry->fd;
-        // Register Read to epoll
-        rc = epoll_ctl(handle->efd, EPOLL_CTL_ADD, entry->fd, &event);
-#endif
-        if (rc < 0) {
-            pubsub_tcpHandler_freeEntry(entry);
-            free(entry);
-            L_ERROR("[TCP Socket] Cannot create epoll\n");
-        } else {
-            // Call Accept Connection callback
-            if (handle->acceptConnectMessageCallback)
-                handle->acceptConnectMessageCallback(handle->acceptConnectPayload, url);
-            hashMap_put(handle->connection_fd_map, (void *) (intptr_t) entry->fd, entry);
-            hashMap_put(handle->connection_url_map, entry->url, entry);
-            L_INFO("[TCP Socket] New connection to url: %s: \n", url);
-        }
-        free(url);
-        free(interface_url);
-    }
-    celixThreadRwlock_unlock(&handle->dbLock);
-    return fd;
-}
-
-//
-// Handle sockets connection (sender)
-//
-static inline
-void pubsub_tcpHandler_connectionHandler(pubsub_tcpHandler_t *handle, int fd) {
-    celixThreadRwlock_readLock(&handle->dbLock);
-    psa_tcp_connection_entry_t *entry = hashMap_get(handle->connection_fd_map, (void *) (intptr_t) fd);
-    if (entry)
-        if ((!entry->connected)) {
-            // tell sender that an receiver is connected
-            if (handle->receiverConnectMessageCallback)
-                handle->receiverConnectMessageCallback(handle->receiverConnectPayload, entry->url, false);
-            entry->connected = true;
-        }
-    celixThreadRwlock_unlock(&handle->dbLock);
-}
-
-#if defined(__APPLE__)
-//
-// The main socket event loop
-//
-static inline
-void pubsub_tcpHandler_handler(pubsub_tcpHandler_t *handle) {
-  int rc = 0;
-  if (handle->efd >= 0) {
-    int nof_events = 0;
-    //  Wait for events.
-    struct kevent events[MAX_EVENTS];
-    struct timespec ts = {handle->timeout / 1000, (handle->timeout  % 1000) * 1000000};
-    nof_events = kevent (handle->efd, NULL, 0, &events[0], MAX_EVENTS, handle->timeout ? &ts : NULL);
-    if (nof_events < 0) {
-      if ((errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) {
-      } else
-        L_ERROR("[TCP Socket] Cannot create poll wait (%d) %s\n", nof_events, strerror(errno));
-    }
-    for (int i = 0; i < nof_events; i++) {
-      hash_map_iterator_t iter = hashMapIterator_construct(handle->interface_fd_map);
-      psa_tcp_connection_entry_t *pendingConnectionEntry = NULL;
-      while (hashMapIterator_hasNext(&iter)) {
-        psa_tcp_connection_entry_t *entry = hashMapIterator_nextValue(&iter);
-        if (events[i].ident == entry->fd)
-          pendingConnectionEntry = entry;
-      }
-      if (pendingConnectionEntry) {
-        int fd = pubsub_tcpHandler_acceptHandler(handle, pendingConnectionEntry);
-        pubsub_tcpHandler_connectionHandler(handle, fd);
-      } else if (events[i].filter & EVFILT_READ) {
-        int rc = pubsub_tcpHandler_read(handle, events[i].ident);
-        if (rc == 0) pubsub_tcpHandler_close(handle, events[i].ident);
-      } else if (events[i].flags & EV_EOF) {
-        int err = 0;
-        socklen_t len = sizeof(int);
-        rc = getsockopt(events[i].ident, SOL_SOCKET, SO_ERROR, &err, &len);
-        if (rc != 0) {
-          L_ERROR("[TCP Socket]:EPOLLRDHUP ERROR read from socket %s\n", strerror(errno));
-          continue;
-        }
-        pubsub_tcpHandler_close(handle, events[i].ident);
-      } else if (events[i].flags & EV_ERROR) {
-        L_ERROR("[TCP Socket]:EPOLLERR  ERROR read from socket %s\n", strerror(errno));
-        pubsub_tcpHandler_close(handle, events[i].ident);
-        continue;
-      }
-    }
-  }
-  return;
-}
-
-#else
-
-//
-// The main socket event loop
-//
-static inline
-void pubsub_tcpHandler_handler(pubsub_tcpHandler_t *handle) {
-    int rc = 0;
-    if (handle->efd >= 0) {
-        int nof_events = 0;
-        struct epoll_event events[MAX_EVENTS];
-        nof_events = epoll_wait(handle->efd, events, MAX_EVENTS, (int)handle->timeout);
-        if (nof_events < 0) {
-            if ((errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) {
-            } else
-                L_ERROR("[TCP Socket] Cannot create epoll wait (%d) %s\n", nof_events, strerror(errno));
-        }
-        for (int i = 0; i < nof_events; i++) {
-            hash_map_iterator_t iter = hashMapIterator_construct(handle->interface_fd_map);
-            psa_tcp_connection_entry_t *pendingConnectionEntry = NULL;
-            while (hashMapIterator_hasNext(&iter)) {
-                psa_tcp_connection_entry_t *entry = hashMapIterator_nextValue(&iter);
-                if (events[i].data.fd == entry->fd)
-                    pendingConnectionEntry = entry;
-            }
-            if (pendingConnectionEntry) {
-               int fd = pubsub_tcpHandler_acceptHandler(handle, pendingConnectionEntry);
-               pubsub_tcpHandler_connectionHandler(handle, fd);
-            } else if (events[i].events & EPOLLIN) {
-                rc = pubsub_tcpHandler_read(handle, events[i].data.fd);
-                if (rc == 0) pubsub_tcpHandler_close(handle, events[i].data.fd);
-            } else if (events[i].events & EPOLLRDHUP) {
-                int err = 0;
-                socklen_t len = sizeof(int);
-                rc = getsockopt(events[i].data.fd, SOL_SOCKET, SO_ERROR, &err, &len);
-                if (rc != 0) {
-                    L_ERROR("[TCP Socket]:EPOLLRDHUP ERROR read from socket %s\n", strerror(errno));
-                    continue;
-                }
-                pubsub_tcpHandler_close(handle, events[i].data.fd);
-            } else if (events[i].events & EPOLLERR) {
-                L_ERROR("[TCP Socket]:EPOLLERR  ERROR read from socket %s\n", strerror(errno));
-                pubsub_tcpHandler_close(handle, events[i].data.fd);
-                continue;
-            }
-        }
-    }
-}
-#endif
-
-//
-// The socket thread
-//
-static void *pubsub_tcpHandler_thread(void *data) {
-    pubsub_tcpHandler_t *handle = data;
-    celixThreadRwlock_readLock(&handle->dbLock);
-    bool running = handle->running;
-    celixThreadRwlock_unlock(&handle->dbLock);
-
-    while (running) {
-        pubsub_tcpHandler_handler(handle);
-        celixThreadRwlock_readLock(&handle->dbLock);
-        running = handle->running;
-        celixThreadRwlock_unlock(&handle->dbLock);
-    } // while
-    return NULL;
-}
diff --git a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_handler.h b/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_handler.h
deleted file mode 100644
index 2d97634..0000000
--- a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_handler.h
+++ /dev/null
@@ -1,92 +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_tcp_handler.h
- *
- *  \date       July 18, 2016
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-
-#ifndef _PUBSUB_TCP_BUFFER_HANDLER_H_
-#define _PUBSUB_TCP_BUFFER_HANDLER_H_
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <celix_log_helper.h>
-#include "celix_threads.h"
-#include "pubsub_utils_url.h"
-#include <pubsub_protocol.h>
-
-#ifndef MIN
-#define MIN(a, b) ((a<b) ? (a) : (b))
-#endif
-
-#ifndef MAX
-#define MAX(a, b) ((a>b) ? (a) : (b))
-#endif
-
-typedef struct pubsub_tcpHandler pubsub_tcpHandler_t;
-typedef void(*pubsub_tcpHandler_processMessage_callback_t)
-    (void *payload, const pubsub_protocol_message_t *header, bool *release, struct timespec *receiveTime);
-typedef void (*pubsub_tcpHandler_receiverConnectMessage_callback_t)(void *payload, const char *url, bool lock);
-typedef void (*pubsub_tcpHandler_acceptConnectMessage_callback_t)(void *payload, const char *url);
-
-pubsub_tcpHandler_t *pubsub_tcpHandler_create(pubsub_protocol_service_t *protocol, celix_log_helper_t *logHelper);
-void pubsub_tcpHandler_destroy(pubsub_tcpHandler_t *handle);
-int pubsub_tcpHandler_open(pubsub_tcpHandler_t *handle, char *url);
-int pubsub_tcpHandler_close(pubsub_tcpHandler_t *handle, int fd);
-int pubsub_tcpHandler_connect(pubsub_tcpHandler_t *handle, char *url);
-int pubsub_tcpHandler_disconnect(pubsub_tcpHandler_t *handle, char *url);
-int pubsub_tcpHandler_listen(pubsub_tcpHandler_t *handle, char *url);
-int pubsub_tcpHandler_setReceiveBufferSize(pubsub_tcpHandler_t *handle, unsigned int size);
-int pubsub_tcpHandler_setMaxMsgSize(pubsub_tcpHandler_t *handle, unsigned int size);
-void pubsub_tcpHandler_setTimeout(pubsub_tcpHandler_t *handle, unsigned int timeout);
-void pubsub_tcpHandler_setSendRetryCnt(pubsub_tcpHandler_t *handle, unsigned int count);
-void pubsub_tcpHandler_setReceiveRetryCnt(pubsub_tcpHandler_t *handle, unsigned int count);
-void pubsub_tcpHandler_setSendTimeOut(pubsub_tcpHandler_t *handle, double timeout);
-void pubsub_tcpHandler_setReceiveTimeOut(pubsub_tcpHandler_t *handle, double timeout);
-void pubsub_tcpHandler_enableReceiveEvent(pubsub_tcpHandler_t *handle, bool enable);
-
-int pubsub_tcpHandler_read(pubsub_tcpHandler_t *handle, int fd);
-int pubsub_tcpHandler_write(pubsub_tcpHandler_t *handle,
-                            pubsub_protocol_message_t *message,
-                            struct iovec *msg_iovec,
-                            size_t msg_iov_len,
-                            int flags);
-int pubsub_tcpHandler_addMessageHandler(pubsub_tcpHandler_t *handle,
-                                        void *payload,
-                                        pubsub_tcpHandler_processMessage_callback_t processMessageCallback);
-int pubsub_tcpHandler_addReceiverConnectionCallback(pubsub_tcpHandler_t *handle,
-                                                    void *payload,
-                                                    pubsub_tcpHandler_receiverConnectMessage_callback_t connectMessageCallback,
-                                                    pubsub_tcpHandler_receiverConnectMessage_callback_t disconnectMessageCallback);
-int pubsub_tcpHandler_addAcceptConnectionCallback(pubsub_tcpHandler_t *handle,
-                                                  void *payload,
-                                                  pubsub_tcpHandler_acceptConnectMessage_callback_t connectMessageCallback,
-                                                  pubsub_tcpHandler_acceptConnectMessage_callback_t disconnectMessageCallback);
-char *pubsub_tcpHandler_get_interface_url(pubsub_tcpHandler_t *handle);
-char *pubsub_tcpHandler_get_connection_url(pubsub_tcpHandler_t *handle);
-void pubsub_tcpHandler_setThreadPriority(pubsub_tcpHandler_t *handle, long prio, const char *sched);
-void pubsub_tcpHandler_setThreadName(pubsub_tcpHandler_t *handle, const char *topic, const char *scope);
-
-#endif /* _PUBSUB_TCP_BUFFER_HANDLER_H_ */
diff --git a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_topic_receiver.c b/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_topic_receiver.c
deleted file mode 100644
index aeda1c3..0000000
--- a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_topic_receiver.c
+++ /dev/null
@@ -1,804 +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 <pubsub_serializer.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <pubsub/subscriber.h>
-#include <memory.h>
-#include <pubsub_constants.h>
-#include <arpa/inet.h>
-#include <celix_log_helper.h>
-#include "pubsub_tcp_handler.h"
-#include "pubsub_tcp_topic_receiver.h"
-#include "pubsub_psa_tcp_constants.h"
-#include "pubsub_tcp_common.h"
-
-#include <uuid/uuid.h>
-#include <pubsub_admin_metrics.h>
-#include <pubsub_utils.h>
-#include <celix_api.h>
-
-#ifndef UUID_STR_LEN
-#define UUID_STR_LEN  37
-#endif
-
-#define L_DEBUG(...) \
-    celix_logHelper_log(receiver->logHelper, CELIX_LOG_LEVEL_DEBUG, __VA_ARGS__)
-#define L_INFO(...) \
-    celix_logHelper_log(receiver->logHelper, CELIX_LOG_LEVEL_INFO, __VA_ARGS__)
-#define L_WARN(...) \
-    celix_logHelper_log(receiver->logHelper, CELIX_LOG_LEVEL_WARNING, __VA_ARGS__)
-#define L_ERROR(...) \
-    celix_logHelper_log(receiver->logHelper, CELIX_LOG_LEVEL_ERROR, __VA_ARGS__)
-
-struct pubsub_tcp_topic_receiver {
-    celix_bundle_context_t *ctx;
-    celix_log_helper_t *logHelper;
-    long serializerSvcId;
-    pubsub_serializer_service_t *serializer;
-    long protocolSvcId;
-    pubsub_protocol_service_t *protocol;
-    char *scope;
-    char *topic;
-    size_t timeout;
-    bool metricsEnabled;
-    bool isPassive;
-    pubsub_tcpHandler_t *socketHandler;
-    pubsub_tcpHandler_t *sharedSocketHandler;
-
-    struct {
-        celix_thread_t thread;
-        celix_thread_mutex_t mutex;
-        bool running;
-    } thread;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = tcp url, value = psa_tcp_requested_connection_entry_t*
-        bool allConnected; //true if all requestedConnection are connected
-    } requestedConnections;
-
-    long subscriberTrackerId;
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = bnd id, value = psa_tcp_subscriber_entry_t
-        bool allInitialized;
-    } subscribers;
-};
-
-typedef struct psa_tcp_requested_connection_entry {
-    pubsub_tcp_topic_receiver_t *parent;
-    char *url;
-    bool connected;
-    bool statically; //true if the connection is statically configured through the topic properties.
-} psa_tcp_requested_connection_entry_t;
-
-typedef struct psa_tcp_subscriber_metrics_entry_t {
-    unsigned int msgTypeId;
-    uuid_t origin;
-
-    unsigned long nrOfMessagesReceived;
-    unsigned long nrOfSerializationErrors;
-    struct timespec lastMessageReceived;
-    double averageTimeBetweenMessagesInSeconds;
-    double averageSerializationTimeInSeconds;
-    double averageDelayInSeconds;
-    double maxDelayInSeconds;
-    double minDelayInSeconds;
-    unsigned long nrOfMissingSeqNumbers;
-} psa_tcp_subscriber_metrics_entry_t;
-
-typedef struct psa_tcp_subscriber_entry {
-    hash_map_t *msgTypes; //map from serializer svc
-    hash_map_t *metrics; //key = msg type id, value = hash_map (key = origin uuid, value = psa_tcp_subscriber_metrics_entry_t*
-    hash_map_t *subscriberServices; //key = servide id, value = pubsub_subscriber_t*
-    bool initialized; //true if the init function is called through the receive thread
-} psa_tcp_subscriber_entry_t;
-
-static void pubsub_tcpTopicReceiver_addSubscriber(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *owner);
-static void pubsub_tcpTopicReceiver_removeSubscriber(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *owner);
-static void *psa_tcp_recvThread(void *data);
-static void psa_tcp_connectToAllRequestedConnections(pubsub_tcp_topic_receiver_t *receiver);
-static void psa_tcp_initializeAllSubscribers(pubsub_tcp_topic_receiver_t *receiver);
-static void processMsg(void *handle, const pubsub_protocol_message_t *hdr, bool *release, struct timespec *receiveTime);
-static void psa_tcp_connectHandler(void *handle, const char *url, bool lock);
-static void psa_tcp_disConnectHandler(void *handle, const char *url, bool lock);
-static bool psa_tcp_checkVersion(version_pt msgVersion, uint16_t major, uint16_t minor);
-
-pubsub_tcp_topic_receiver_t *pubsub_tcpTopicReceiver_create(celix_bundle_context_t *ctx,
-                                                            celix_log_helper_t *logHelper,
-                                                            const char *scope,
-                                                            const char *topic,
-                                                            const celix_properties_t *topicProperties,
-                                                            pubsub_tcp_endPointStore_t *handlerStore,
-                                                            long serializerSvcId,
-                                                            pubsub_serializer_service_t *serializer,
-                                                            long protocolSvcId,
-                                                            pubsub_protocol_service_t *protocol) {
-    pubsub_tcp_topic_receiver_t *receiver = calloc(1, sizeof(*receiver));
-    receiver->ctx = ctx;
-    receiver->logHelper = logHelper;
-    receiver->serializerSvcId = serializerSvcId;
-    receiver->serializer = serializer;
-    receiver->protocolSvcId = protocolSvcId;
-    receiver->protocol = protocol;
-    receiver->scope = scope == NULL ? NULL : strndup(scope, 1024 * 1024);
-    receiver->topic = strndup(topic, 1024 * 1024);
-    const char *staticConnectUrls = pubsub_getEnvironmentVariableWithScopeTopic(ctx, PUBSUB_TCP_STATIC_CONNECT_URLS_FOR, topic, scope);
-    const char *isPassive = pubsub_getEnvironmentVariableWithScopeTopic(ctx, PUBSUB_TCP_PASSIVE_ENABLED, topic, scope);
-    const char *passiveKey = pubsub_getEnvironmentVariableWithScopeTopic(ctx, PUBSUB_TCP_PASSIVE_SELECTION_KEY, topic, scope);
-
-    if (isPassive) {
-        receiver->isPassive = psa_tcp_isPassive(isPassive);
-    }
-    if (topicProperties != NULL) {
-        if(staticConnectUrls == NULL) {
-            staticConnectUrls = celix_properties_get(topicProperties, PUBSUB_TCP_STATIC_CONNECT_URLS, NULL);
-        }
-        if (isPassive == NULL) {
-            receiver->isPassive = celix_properties_getAsBool(topicProperties, PUBSUB_TCP_PASSIVE_CONFIGURED, false);
-        }
-        if (passiveKey == NULL) {
-            passiveKey = celix_properties_get(topicProperties, PUBSUB_TCP_PASSIVE_KEY, NULL);
-        }
-    }
-
-    // Set receiver connection thread timeout.
-    // property is in ms, timeout value in us. (convert ms to us).
-    receiver->timeout = celix_bundleContext_getPropertyAsLong(ctx, PSA_TCP_SUBSCRIBER_CONNECTION_TIMEOUT,
-                                                              PSA_TCP_SUBSCRIBER_CONNECTION_DEFAULT_TIMEOUT) * 1000;
-    /* When it's an endpoint share the socket with the sender */
-    if (passiveKey != NULL) {
-        celixThreadMutex_lock(&handlerStore->mutex);
-        pubsub_tcpHandler_t *entry = hashMap_get(handlerStore->map, passiveKey);
-        if (entry == NULL) {
-            if (receiver->socketHandler == NULL)
-                receiver->socketHandler = pubsub_tcpHandler_create(receiver->protocol, receiver->logHelper);
-            entry = receiver->socketHandler;
-            receiver->sharedSocketHandler = receiver->socketHandler;
-            hashMap_put(handlerStore->map, (void *) passiveKey, entry);
-        } else {
-            receiver->socketHandler = entry;
-            receiver->sharedSocketHandler = entry;
-        }
-        celixThreadMutex_unlock(&handlerStore->mutex);
-    } else {
-        receiver->socketHandler = pubsub_tcpHandler_create(receiver->protocol, receiver->logHelper);
-    }
-
-    if (receiver->socketHandler != NULL) {
-        long prio = celix_properties_getAsLong(topicProperties, PUBSUB_TCP_THREAD_REALTIME_PRIO, -1L);
-        const char *sched = celix_properties_get(topicProperties, PUBSUB_TCP_THREAD_REALTIME_SCHED, NULL);
-        long retryCnt = celix_properties_getAsLong(topicProperties, PUBSUB_TCP_SUBSCRIBER_RETRY_CNT_KEY,
-                                                   PUBSUB_TCP_SUBSCRIBER_RETRY_CNT_DEFAULT);
-        double rcvTimeout = celix_properties_getAsDouble(topicProperties, PUBSUB_TCP_SUBSCRIBER_RCVTIMEO_KEY, PUBSUB_TCP_SUBSCRIBER_RCVTIMEO_DEFAULT);
-        long bufferSize = celix_bundleContext_getPropertyAsLong(ctx, PSA_TCP_RECV_BUFFER_SIZE,
-                                                                 PSA_TCP_DEFAULT_RECV_BUFFER_SIZE);
-        long timeout = celix_bundleContext_getPropertyAsLong(ctx, PSA_TCP_TIMEOUT, PSA_TCP_DEFAULT_TIMEOUT);
-
-        pubsub_tcpHandler_setThreadName(receiver->socketHandler, topic, scope);
-        pubsub_tcpHandler_setReceiveBufferSize(receiver->socketHandler, (unsigned int) bufferSize);
-        pubsub_tcpHandler_setTimeout(receiver->socketHandler, (unsigned int) timeout);
-        pubsub_tcpHandler_addMessageHandler(receiver->socketHandler, receiver, processMsg);
-        pubsub_tcpHandler_addReceiverConnectionCallback(receiver->socketHandler, receiver, psa_tcp_connectHandler,
-                                                        psa_tcp_disConnectHandler);
-        pubsub_tcpHandler_setThreadPriority(receiver->socketHandler, prio, sched);
-        pubsub_tcpHandler_setReceiveRetryCnt(receiver->socketHandler, (unsigned int) retryCnt);
-        pubsub_tcpHandler_setReceiveTimeOut(receiver->socketHandler, rcvTimeout);
-    }
-    receiver->metricsEnabled = celix_bundleContext_getPropertyAsBool(ctx, PSA_TCP_METRICS_ENABLED,
-                                                                          PSA_TCP_DEFAULT_METRICS_ENABLED);
-    celixThreadMutex_create(&receiver->subscribers.mutex, NULL);
-    celixThreadMutex_create(&receiver->requestedConnections.mutex, NULL);
-    celixThreadMutex_create(&receiver->thread.mutex, NULL);
-
-    receiver->subscribers.map = hashMap_create(NULL, NULL, NULL, NULL);
-    receiver->requestedConnections.map = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
-    if ((staticConnectUrls != NULL) && (receiver->socketHandler != NULL) && (!receiver->isPassive)) {
-        char *urlsCopy = strndup(staticConnectUrls, 1024 * 1024);
-        char *url;
-        char *save = urlsCopy;
-        while ((url = strtok_r(save, " ", &save))) {
-            psa_tcp_requested_connection_entry_t *entry = calloc(1, sizeof(*entry));
-            entry->statically = true;
-            entry->connected = false;
-            entry->url = strndup(url, 1024 * 1024);
-            entry->parent = receiver;
-            hashMap_put(receiver->requestedConnections.map, entry->url, entry);
-            receiver->requestedConnections.allConnected = false;
-        }
-        free(urlsCopy);
-    }
-
-    if (receiver->socketHandler != NULL && (!receiver->isPassive)) {
-        // Configure Receiver thread
-        receiver->thread.running = true;
-        celixThread_create(&receiver->thread.thread, NULL, psa_tcp_recvThread, receiver);
-        char name[64];
-        snprintf(name, 64, "TCP TR %s/%s", scope == NULL ? "(null)" : scope, topic);
-        celixThread_setName(&receiver->thread.thread, name);
-    }
-
-    //track subscribers
-    if (receiver->socketHandler != NULL) {
-        int size = snprintf(NULL, 0, "(%s=%s)", PUBSUB_SUBSCRIBER_TOPIC, topic);
-        char buf[size + 1];
-        snprintf(buf, (size_t) size + 1, "(%s=%s)", PUBSUB_SUBSCRIBER_TOPIC, topic);
-        celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
-        opts.filter.ignoreServiceLanguage = true;
-        opts.filter.serviceName = PUBSUB_SUBSCRIBER_SERVICE_NAME;
-        opts.filter.filter = buf;
-        opts.callbackHandle = receiver;
-        opts.addWithOwner = pubsub_tcpTopicReceiver_addSubscriber;
-        opts.removeWithOwner = pubsub_tcpTopicReceiver_removeSubscriber;
-        receiver->subscriberTrackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
-    }
-
-    if (receiver->socketHandler == NULL) {
-        if (receiver->scope != NULL) {
-            free(receiver->scope);
-        }
-        free(receiver->topic);
-        free(receiver);
-        receiver = NULL;
-        L_ERROR("[PSA_TCP] Cannot create TopicReceiver for %s/%s", scope == NULL ? "(null)" : scope, topic);
-    }
-    return receiver;
-}
-
-void pubsub_tcpTopicReceiver_destroy(pubsub_tcp_topic_receiver_t *receiver) {
-    if (receiver != NULL) {
-
-        celixThreadMutex_lock(&receiver->thread.mutex);
-        if (receiver->thread.running) {
-            receiver->thread.running = false;
-            celixThreadMutex_unlock(&receiver->thread.mutex);
-            celixThread_join(receiver->thread.thread, NULL);
-        }
-
-        celix_bundleContext_stopTracker(receiver->ctx, receiver->subscriberTrackerId);
-
-        celixThreadMutex_lock(&receiver->subscribers.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(receiver->subscribers.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_tcp_subscriber_entry_t *entry = hashMapIterator_nextValue(&iter);
-            if (entry != NULL) {
-                receiver->serializer->destroySerializerMap(receiver->serializer->handle, entry->msgTypes);
-                hashMap_destroy(entry->subscriberServices, false, false);
-                hash_map_iterator_t iter2 = hashMapIterator_construct(entry->metrics);
-                while (hashMapIterator_hasNext(&iter2)) {
-                    hash_map_t *origins = hashMapIterator_nextValue(&iter2);
-                    hashMap_destroy(origins, true, true);
-                }
-                hashMap_destroy(entry->metrics, false, false);
-                free(entry);
-            }
-        }
-        hashMap_destroy(receiver->subscribers.map, false, false);
-
-        celixThreadMutex_unlock(&receiver->subscribers.mutex);
-
-        celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-        iter = hashMapIterator_construct(receiver->requestedConnections.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_tcp_requested_connection_entry_t *entry = hashMapIterator_nextValue(&iter);
-            if (entry != NULL) {
-                free(entry->url);
-                free(entry);
-            }
-        }
-        hashMap_destroy(receiver->requestedConnections.map, false, false);
-        celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-
-        celixThreadMutex_destroy(&receiver->subscribers.mutex);
-        celixThreadMutex_destroy(&receiver->requestedConnections.mutex);
-        celixThreadMutex_destroy(&receiver->thread.mutex);
-
-        pubsub_tcpHandler_addMessageHandler(receiver->socketHandler, NULL, NULL);
-        pubsub_tcpHandler_addReceiverConnectionCallback(receiver->socketHandler, NULL, NULL, NULL);
-        if ((receiver->socketHandler) && (receiver->sharedSocketHandler == NULL)) {
-            pubsub_tcpHandler_destroy(receiver->socketHandler);
-            receiver->socketHandler = NULL;
-        }
-        if (receiver->scope != NULL) {
-            free(receiver->scope);
-        }
-        free(receiver->topic);
-    }
-    free(receiver);
-}
-
-const char *pubsub_tcpTopicReceiver_scope(pubsub_tcp_topic_receiver_t *receiver) {
-    return receiver->scope;
-}
-
-const char *pubsub_tcpTopicReceiver_topic(pubsub_tcp_topic_receiver_t *receiver) {
-    return receiver->topic;
-}
-
-long pubsub_tcpTopicReceiver_serializerSvcId(pubsub_tcp_topic_receiver_t *receiver) {
-    return receiver->serializerSvcId;
-}
-
-long pubsub_tcpTopicReceiver_protocolSvcId(pubsub_tcp_topic_receiver_t *receiver) {
-    return receiver->protocolSvcId;
-}
-
-void pubsub_tcpTopicReceiver_listConnections(pubsub_tcp_topic_receiver_t *receiver, celix_array_list_t *connectedUrls,
-                                             celix_array_list_t *unconnectedUrls) {
-    celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-    if (receiver->isPassive) {
-        char* interface_url = pubsub_tcpHandler_get_interface_url(receiver->socketHandler);
-        char *url = NULL;
-        asprintf(&url, "%s (passive)", interface_url ? interface_url : "");
-        if (interface_url) {
-            celix_arrayList_add(connectedUrls, url);
-        } else {
-            celix_arrayList_add(unconnectedUrls, url);
-        }
-        free(interface_url);
-    } else {
-        hash_map_iterator_t iter = hashMapIterator_construct(receiver->requestedConnections.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_tcp_requested_connection_entry_t *entry = hashMapIterator_nextValue(&iter);
-            char *url = NULL;
-            asprintf(&url, "%s%s", entry->url, entry->statically ? " (static)" : "");
-            if (entry->connected) {
-                celix_arrayList_add(connectedUrls, url);
-            } else {
-                celix_arrayList_add(unconnectedUrls, url);
-            }
-        }
-    }
-    celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-}
-
-bool pubsub_tcpTopicReceiver_isPassive(pubsub_tcp_topic_receiver_t *receiver) {
-    return receiver->isPassive;
-}
-
-void pubsub_tcpTopicReceiver_connectTo(
-    pubsub_tcp_topic_receiver_t *receiver,
-    const char *url) {
-    L_DEBUG("[PSA_TCP] TopicReceiver %s/%s connecting to tcp url %s",
-            receiver->scope == NULL ? "(null)" : receiver->scope,
-            receiver->topic,
-            url);
-
-    celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-    psa_tcp_requested_connection_entry_t *entry = hashMap_get(receiver->requestedConnections.map, url);
-    if (entry == NULL) {
-        entry = calloc(1, sizeof(*entry));
-        entry->url = strndup(url, 1024 * 1024);
-        entry->connected = false;
-        entry->statically = false;
-        entry->parent = receiver;
-        hashMap_put(receiver->requestedConnections.map, (void *) entry->url, entry);
-        receiver->requestedConnections.allConnected = false;
-    }
-    celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-
-    psa_tcp_connectToAllRequestedConnections(receiver);
-}
-
-void pubsub_tcpTopicReceiver_disconnectFrom(pubsub_tcp_topic_receiver_t *receiver, const char *url) {
-    L_DEBUG("[PSA TCP] TopicReceiver %s/%s disconnect from tcp url %s",
-            receiver->scope == NULL ? "(null)" : receiver->scope,
-            receiver->topic,
-            url);
-
-    celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-    psa_tcp_requested_connection_entry_t *entry = hashMap_remove(receiver->requestedConnections.map, url);
-    if (entry != NULL) {
-        int rc = pubsub_tcpHandler_disconnect(receiver->socketHandler, entry->url);
-        if (rc < 0)
-            L_WARN("[PSA_TCP] Error disconnecting from tcp url %s. (%s)", url, strerror(errno));
-    }
-    if (entry != NULL) {
-        free(entry->url);
-        free(entry);
-    }
-    celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-}
-
-static void pubsub_tcpTopicReceiver_addSubscriber(void *handle, void *svc, const celix_properties_t *props,
-                                                  const celix_bundle_t *bnd) {
-    pubsub_tcp_topic_receiver_t *receiver = handle;
-
-    long bndId = celix_bundle_getId(bnd);
-    long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1);
-    const char *subScope = celix_properties_get(props, PUBSUB_SUBSCRIBER_SCOPE, NULL);
-    if (receiver->scope == NULL) {
-        if (subScope != NULL) {
-            return;
-        }
-    } else if (subScope != NULL) {
-        if (strncmp(subScope, receiver->scope, strlen(receiver->scope)) != 0) {
-            //not the same scope. ignore
-            return;
-        }
-    } else {
-        //receiver scope is not NULL, but subScope is NULL -> ignore
-        return;
-    }
-
-    celixThreadMutex_lock(&receiver->subscribers.mutex);
-    psa_tcp_subscriber_entry_t *entry = hashMap_get(receiver->subscribers.map, (void *) bndId);
-    if (entry != NULL) {
-        hashMap_put(entry->subscriberServices, (void*)svcId, svc);
-    } else {
-        //new create entry
-        entry = calloc(1, sizeof(*entry));
-        entry->subscriberServices = hashMap_create(NULL, NULL, NULL, NULL);
-        entry->initialized = false;
-        receiver->subscribers.allInitialized = false;
-
-        hashMap_put(entry->subscriberServices, (void*)svcId, svc);
-
-        int rc = receiver->serializer->createSerializerMap(receiver->serializer->handle, (celix_bundle_t *) bnd, &entry->msgTypes);
-
-        if (rc == 0) {
-            entry->metrics = hashMap_create(NULL, NULL, NULL, NULL);
-            hash_map_iterator_t iter = hashMapIterator_construct(entry->msgTypes);
-            while (hashMapIterator_hasNext(&iter)) {
-                pubsub_msg_serializer_t *msgSer = hashMapIterator_nextValue(&iter);
-                hash_map_t *origins = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-                hashMap_put(entry->metrics, (void *) (uintptr_t) msgSer->msgId, origins);
-            }
-        }
-
-        if (rc == 0) {
-            hashMap_put(receiver->subscribers.map, (void *) bndId, entry);
-        } else {
-            L_ERROR("[PSA_TCP] Cannot create msg serializer map for TopicReceiver %s/%s",
-                    receiver->scope == NULL ? "(null)" : receiver->scope,
-                    receiver->topic);
-            free(entry);
-        }
-    }
-    celixThreadMutex_unlock(&receiver->subscribers.mutex);
-}
-
-static void pubsub_tcpTopicReceiver_removeSubscriber(void *handle, void *svc __attribute__((unused)), const celix_properties_t *props,
-                                                     const celix_bundle_t *bnd) {
-    pubsub_tcp_topic_receiver_t *receiver = handle;
-
-    long bndId = celix_bundle_getId(bnd);
-    long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1);
-
-    celixThreadMutex_lock(&receiver->subscribers.mutex);
-    psa_tcp_subscriber_entry_t *entry = hashMap_get(receiver->subscribers.map, (void *) bndId);
-    if (entry != NULL) {
-        hashMap_remove(entry->subscriberServices, (void*)svcId);
-    }
-    if (entry != NULL && hashMap_size(entry->subscriberServices) == 0) {
-        //remove entry
-        hashMap_remove(receiver->subscribers.map, (void *) bndId);
-        int rc = receiver->serializer->destroySerializerMap(receiver->serializer->handle, entry->msgTypes);
-        if (rc != 0) {
-            L_ERROR("[PSA_TCP] Cannot destroy msg serializers map for TopicReceiver %s/%s",
-                    receiver->scope == NULL ? "(null)" : receiver->scope,
-                    receiver->topic);
-        }
-        hash_map_iterator_t iter = hashMapIterator_construct(entry->metrics);
-        while (hashMapIterator_hasNext(&iter)) {
-            hash_map_t *origins = hashMapIterator_nextValue(&iter);
-            hashMap_destroy(origins, true, true);
-        }
-        hashMap_destroy(entry->metrics, false, false);
-        hashMap_destroy(entry->subscriberServices, false, false);
-        free(entry);
-    }
-    celixThreadMutex_unlock(&receiver->subscribers.mutex);
-}
-
-static inline void
-processMsgForSubscriberEntry(pubsub_tcp_topic_receiver_t *receiver, psa_tcp_subscriber_entry_t *entry,
-                             const pubsub_protocol_message_t *message, bool *releaseMsg, struct timespec *receiveTime __attribute__((unused))) {
-    //NOTE receiver->subscribers.mutex locked
-    pubsub_msg_serializer_t *msgSer = hashMap_get(entry->msgTypes, (void *) (uintptr_t) (message->header.msgId));
-    bool monitor = receiver->metricsEnabled;
-
-    //monitoring
-    struct timespec beginSer;
-    struct timespec endSer;
-    int updateReceiveCount = 0;
-    int updateSerError = 0;
-
-    if (msgSer != NULL) {
-        void *deSerializedMsg = NULL;
-        bool validVersion = psa_tcp_checkVersion(msgSer->msgVersion, message->header.msgMajorVersion,
-                                                 message->header.msgMinorVersion);
-        if (validVersion) {
-            if (monitor) {
-                clock_gettime(CLOCK_REALTIME, &beginSer);
-            }
-            struct iovec deSerializeBuffer;
-            deSerializeBuffer.iov_base = message->payload.payload;
-            deSerializeBuffer.iov_len = message->payload.length;
-            celix_status_t status = msgSer->deserialize(msgSer->handle, &deSerializeBuffer, 1, &deSerializedMsg);
-            if (monitor) {
-                clock_gettime(CLOCK_REALTIME, &endSer);
-            }
-            // When received payload pointer is the same as deserializedMsg, set ownership of pointer to topic receiver
-            if (message->payload.payload == deSerializedMsg) {
-                *releaseMsg = true;
-            }
-
-            if (status == CELIX_SUCCESS) {
-                bool release = true;
-                hash_map_iterator_t iter = hashMapIterator_construct(entry->subscriberServices);
-                while (hashMapIterator_hasNext(&iter)) {
-                    pubsub_subscriber_t *svc = hashMapIterator_nextValue(&iter);
-                    svc->receive(svc->handle, msgSer->msgName, msgSer->msgId, deSerializedMsg, message->metadata.metadata, &release);
-                    if (!release) {
-                        //receive function has taken ownership, deserialize again for new message
-                        status = msgSer->deserialize(msgSer->handle, &deSerializeBuffer, 1, &deSerializedMsg);
-                        if (status != CELIX_SUCCESS) {
-                            L_WARN("[PSA_TCP_TR] Cannot deserialize msg type %s for scope/topic %s/%s",
-                                   msgSer->msgName,
-                                   receiver->scope == NULL ? "(null)" : receiver->scope,
-                                   receiver->topic);
-                            break;
-                        }
-                        release = true;
-                    }
-                }
-                if (release) {
-                    msgSer->freeDeserializeMsg(msgSer->handle, deSerializedMsg);
-                }
-                if (message->metadata.metadata) {
-                    celix_properties_destroy(message->metadata.metadata);
-                }
-                updateReceiveCount += 1;
-            } else {
-                updateSerError += 1;
-                L_WARN("[PSA_TCP_TR] Cannot deserialize msg type %s for scope/topic %s/%s", msgSer->msgName,
-                       receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic);
-            }
-        }
-    } else {
-        L_WARN("[PSA_TCP_TR] Cannot find serializer for type id 0x%X. Received payload size is %u.", message->header.msgId, message->payload.length);
-    }
-}
-
-static void
-processMsg(void *handle, const pubsub_protocol_message_t *message, bool *release, struct timespec *receiveTime) {
-    pubsub_tcp_topic_receiver_t *receiver = handle;
-    celixThreadMutex_lock(&receiver->subscribers.mutex);
-    hash_map_iterator_t iter = hashMapIterator_construct(receiver->subscribers.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        psa_tcp_subscriber_entry_t *entry = hashMapIterator_nextValue(&iter);
-        if (entry != NULL) {
-            processMsgForSubscriberEntry(receiver, entry, message, release, receiveTime);
-        }
-    }
-    celixThreadMutex_unlock(&receiver->subscribers.mutex);
-}
-
-static void *psa_tcp_recvThread(void *data) {
-    pubsub_tcp_topic_receiver_t *receiver = data;
-
-    celixThreadMutex_lock(&receiver->thread.mutex);
-    bool running = receiver->thread.running;
-    celixThreadMutex_unlock(&receiver->thread.mutex);
-
-    celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-    bool allConnected = receiver->requestedConnections.allConnected;
-    celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-
-    celixThreadMutex_lock(&receiver->subscribers.mutex);
-    bool allInitialized = receiver->subscribers.allInitialized;
-    celixThreadMutex_unlock(&receiver->subscribers.mutex);
-
-    while (running) {
-        if (!allConnected) {
-            psa_tcp_connectToAllRequestedConnections(receiver);
-        }
-        if (!allInitialized) {
-            psa_tcp_initializeAllSubscribers(receiver);
-        }
-        usleep(receiver->timeout);
-
-        celixThreadMutex_lock(&receiver->thread.mutex);
-        running = receiver->thread.running;
-        celixThreadMutex_unlock(&receiver->thread.mutex);
-
-        celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-        allConnected = receiver->requestedConnections.allConnected;
-        celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-
-        celixThreadMutex_lock(&receiver->subscribers.mutex);
-        allInitialized = receiver->subscribers.allInitialized;
-        celixThreadMutex_unlock(&receiver->subscribers.mutex);
-    } // while
-    return NULL;
-}
-
-pubsub_admin_receiver_metrics_t *pubsub_tcpTopicReceiver_metrics(pubsub_tcp_topic_receiver_t *receiver) {
-    pubsub_admin_receiver_metrics_t *result = calloc(1, sizeof(*result));
-    snprintf(result->scope, PUBSUB_AMDIN_METRICS_NAME_MAX, "%s", receiver->scope == NULL ? PUBSUB_DEFAULT_ENDPOINT_SCOPE : receiver->scope);
-    snprintf(result->topic, PUBSUB_AMDIN_METRICS_NAME_MAX, "%s", receiver->topic);
-
-    int msgTypesCount = 0;
-    celixThreadMutex_lock(&receiver->subscribers.mutex);
-    hash_map_iterator_t iter = hashMapIterator_construct(receiver->subscribers.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        psa_tcp_subscriber_entry_t *entry = hashMapIterator_nextValue(&iter);
-        hash_map_iterator_t iter2 = hashMapIterator_construct(entry->metrics);
-        while (hashMapIterator_hasNext(&iter2)) {
-            hashMapIterator_nextValue(&iter2);
-            msgTypesCount += 1;
-        }
-    }
-
-    result->nrOfMsgTypes = (unsigned long) msgTypesCount;
-    result->msgTypes = calloc(msgTypesCount, sizeof(*result->msgTypes));
-    int i = 0;
-    iter = hashMapIterator_construct(receiver->subscribers.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        psa_tcp_subscriber_entry_t *entry = hashMapIterator_nextValue(&iter);
-        hash_map_iterator_t iter2 = hashMapIterator_construct(entry->metrics);
-        while (hashMapIterator_hasNext(&iter2)) {
-            hash_map_t *origins = hashMapIterator_nextValue(&iter2);
-            result->msgTypes[i].origins = calloc((size_t) hashMap_size(origins), sizeof(*(result->msgTypes[i].origins)));
-            result->msgTypes[i].nrOfOrigins = hashMap_size(origins);
-            int k = 0;
-            hash_map_iterator_t iter3 = hashMapIterator_construct(origins);
-            while (hashMapIterator_hasNext(&iter3)) {
-                psa_tcp_subscriber_metrics_entry_t *metrics = hashMapIterator_nextValue(&iter3);
-                result->msgTypes[i].typeId = metrics->msgTypeId;
-                pubsub_msg_serializer_t *msgSer = hashMap_get(entry->msgTypes, (void *) (uintptr_t) metrics->msgTypeId);
-                if (msgSer) {
-                    snprintf(result->msgTypes[i].typeFqn, PUBSUB_AMDIN_METRICS_NAME_MAX, "%s", msgSer->msgName);
-                    uuid_copy(result->msgTypes[i].origins[k].originUUID, metrics->origin);
-                    result->msgTypes[i].origins[k].nrOfMessagesReceived = metrics->nrOfMessagesReceived;
-                    result->msgTypes[i].origins[k].nrOfSerializationErrors = metrics->nrOfSerializationErrors;
-                    result->msgTypes[i].origins[k].averageDelayInSeconds = metrics->averageDelayInSeconds;
-                    result->msgTypes[i].origins[k].maxDelayInSeconds = metrics->maxDelayInSeconds;
-                    result->msgTypes[i].origins[k].minDelayInSeconds = metrics->minDelayInSeconds;
-                    result->msgTypes[i].origins[k].averageTimeBetweenMessagesInSeconds = metrics->averageTimeBetweenMessagesInSeconds;
-                    result->msgTypes[i].origins[k].averageSerializationTimeInSeconds = metrics->averageSerializationTimeInSeconds;
-                    result->msgTypes[i].origins[k].lastMessageReceived = metrics->lastMessageReceived;
-                    result->msgTypes[i].origins[k].nrOfMissingSeqNumbers = metrics->nrOfMissingSeqNumbers;
-
-                    k += 1;
-                } else {
-                    L_WARN("[PSA_TCP]: Error cannot find key 0x%X in msg map during metrics collection!\n",
-                           metrics->msgTypeId);
-                }
-            }
-            i += 1;
-        }
-    }
-    celixThreadMutex_unlock(&receiver->subscribers.mutex);
-    return result;
-}
-
-static void psa_tcp_connectToAllRequestedConnections(pubsub_tcp_topic_receiver_t *receiver) {
-    celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-    if (!receiver->requestedConnections.allConnected) {
-        bool allConnected = true;
-        hash_map_iterator_t iter = hashMapIterator_construct(receiver->requestedConnections.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_tcp_requested_connection_entry_t *entry = hashMapIterator_nextValue(&iter);
-            if ((entry) && (!entry->connected) && (!receiver->isPassive)) {
-                int rc = pubsub_tcpHandler_connect(entry->parent->socketHandler, entry->url);
-                if (rc < 0) {
-                    allConnected = false;
-                }
-            }
-        }
-        receiver->requestedConnections.allConnected = allConnected;
-    }
-    celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-}
-
-static void psa_tcp_connectHandler(void *handle, const char *url, bool lock) {
-    pubsub_tcp_topic_receiver_t *receiver = handle;
-    L_DEBUG("[PSA_TCP] TopicReceiver %s/%s connecting to tcp url %s",
-            receiver->scope == NULL ? "(null)" : receiver->scope,
-            receiver->topic,
-            url);
-    if (lock)
-        celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-    psa_tcp_requested_connection_entry_t *entry = hashMap_get(receiver->requestedConnections.map, url);
-    if (entry == NULL) {
-        entry = calloc(1, sizeof(*entry));
-        entry->parent = receiver;
-        entry->url = strndup(url, 1024 * 1024);
-        entry->statically = true;
-        hashMap_put(receiver->requestedConnections.map, (void *) entry->url, entry);
-        receiver->requestedConnections.allConnected = false;
-    }
-    entry->connected = true;
-    if (lock)
-        celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-}
-
-static void psa_tcp_disConnectHandler(void *handle, const char *url, bool lock) {
-    pubsub_tcp_topic_receiver_t *receiver = handle;
-    L_DEBUG("[PSA TCP] TopicReceiver %s/%s disconnect from tcp url %s",
-            receiver->scope == NULL ? "(null)" : receiver->scope,
-            receiver->topic,
-            url);
-    if (lock)
-        celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-    psa_tcp_requested_connection_entry_t *entry = hashMap_get(receiver->requestedConnections.map, url);
-    if (entry != NULL) {
-        entry->connected = false;
-        receiver->requestedConnections.allConnected = false;
-    }
-    if (lock)
-        celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-}
-
-static void psa_tcp_initializeAllSubscribers(pubsub_tcp_topic_receiver_t *receiver) {
-    celixThreadMutex_lock(&receiver->subscribers.mutex);
-    if (!receiver->subscribers.allInitialized) {
-        bool allInitialized = true;
-        hash_map_iterator_t iter = hashMapIterator_construct(receiver->subscribers.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_tcp_subscriber_entry_t *entry = hashMapIterator_nextValue(&iter);
-            if (!entry->initialized) {
-                hash_map_iterator_t iter2 = hashMapIterator_construct(entry->subscriberServices);
-                while (hashMapIterator_hasNext(&iter2)) {
-                    pubsub_subscriber_t *svc = hashMapIterator_nextValue(&iter2);
-                    int rc = 0;
-                    if (svc != NULL && svc->init != NULL) {
-                        rc = svc->init(svc->handle);
-                    }
-                    if (rc == 0) {
-                        //note now only initialized on first subscriber entries added.
-                        entry->initialized = true;
-                    } else {
-                        L_WARN("Cannot initialize subscriber svc. Got rc %i", rc);
-                        allInitialized = false;
-                    }
-                }
-            }
-        }
-        receiver->subscribers.allInitialized = allInitialized;
-    }
-    celixThreadMutex_unlock(&receiver->subscribers.mutex);
-}
-
-static bool psa_tcp_checkVersion(version_pt msgVersion, uint16_t major, uint16_t minor) {
-    bool check = false;
-
-    if (major == 0 && minor == 0) {
-        //no check
-        return true;
-    }
-
-    int versionMajor;
-    int versionMinor;
-    if (msgVersion!=NULL) {
-        version_getMajor(msgVersion, &versionMajor);
-        version_getMinor(msgVersion, &versionMinor);
-        if (major==((unsigned char)versionMajor)) { /* Different major means incompatible */
-            check = (minor>=((unsigned char)versionMinor)); /* Compatible only if the provider has a minor equals or greater (means compatible update) */
-        }
-    }
-
-    return check;
-}
diff --git a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_topic_receiver.h b/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_topic_receiver.h
deleted file mode 100644
index 118bf11..0000000
--- a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_topic_receiver.h
+++ /dev/null
@@ -1,57 +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 CELIX_PUBSUB_TCP_TOPIC_RECEIVER_H
-#define CELIX_PUBSUB_TCP_TOPIC_RECEIVER_H
-
-#include <pubsub_admin_metrics.h>
-#include "celix_bundle_context.h"
-#include <pubsub_protocol.h>
-#include "pubsub_tcp_common.h"
-
-typedef struct pubsub_tcp_topic_receiver pubsub_tcp_topic_receiver_t;
-
-pubsub_tcp_topic_receiver_t *pubsub_tcpTopicReceiver_create(celix_bundle_context_t *ctx,
-                                                            celix_log_helper_t *logHelper,
-                                                            const char *scope,
-                                                            const char *topic,
-                                                            const celix_properties_t *topicProperties,
-                                                            pubsub_tcp_endPointStore_t *handlerStore,
-                                                            long serializerSvcId,
-                                                            pubsub_serializer_service_t *serializer,
-                                                            long protocolSvcId,
-                                                            pubsub_protocol_service_t *protocol);
-void pubsub_tcpTopicReceiver_destroy(pubsub_tcp_topic_receiver_t *receiver);
-
-const char *pubsub_tcpTopicReceiver_scope(pubsub_tcp_topic_receiver_t *receiver);
-const char *pubsub_tcpTopicReceiver_topic(pubsub_tcp_topic_receiver_t *receiver);
-
-long pubsub_tcpTopicReceiver_serializerSvcId(pubsub_tcp_topic_receiver_t *receiver);
-long pubsub_tcpTopicReceiver_protocolSvcId(pubsub_tcp_topic_receiver_t *receiver);
-void pubsub_tcpTopicReceiver_listConnections(pubsub_tcp_topic_receiver_t *receiver,
-                                             celix_array_list_t *connectedUrls,
-                                             celix_array_list_t *unconnectedUrls);
-bool pubsub_tcpTopicReceiver_isPassive(pubsub_tcp_topic_receiver_t *sender);
-
-void pubsub_tcpTopicReceiver_connectTo(pubsub_tcp_topic_receiver_t *receiver, const char *url);
-void pubsub_tcpTopicReceiver_disconnectFrom(pubsub_tcp_topic_receiver_t *receiver, const char *url);
-
-pubsub_admin_receiver_metrics_t *pubsub_tcpTopicReceiver_metrics(pubsub_tcp_topic_receiver_t *receiver);
-
-#endif //CELIX_PUBSUB_TCP_TOPIC_RECEIVER_H
diff --git a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_topic_sender.c b/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_topic_sender.c
deleted file mode 100644
index 7bea628..0000000
--- a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_topic_sender.c
+++ /dev/null
@@ -1,613 +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 <pubsub_serializer.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <memory.h>
-#include <pubsub_constants.h>
-#include <pubsub/publisher.h>
-#include <utils.h>
-#include <zconf.h>
-#include <arpa/inet.h>
-#include <celix_log_helper.h>
-#include "pubsub_psa_tcp_constants.h"
-#include "pubsub_tcp_topic_sender.h"
-#include "pubsub_tcp_handler.h"
-#include "pubsub_tcp_common.h"
-#include <uuid/uuid.h>
-#include "celix_constants.h"
-#include <pubsub_utils.h>
-
-#define TCP_BIND_MAX_RETRY                      10
-
-#define L_DEBUG(...) \
-    celix_logHelper_log(sender->logHelper, CELIX_LOG_LEVEL_DEBUG, __VA_ARGS__)
-#define L_INFO(...) \
-    celix_logHelper_log(sender->logHelper, CELIX_LOG_LEVEL_INFO, __VA_ARGS__)
-#define L_WARN(...) \
-    celix_logHelper_log(sender->logHelper, CELIX_LOG_LEVEL_WARNING, __VA_ARGS__)
-#define L_ERROR(...) \
-    celix_logHelper_log(sender->logHelper, CELIX_LOG_LEVEL_ERROR, __VA_ARGS__)
-
-struct pubsub_tcp_topic_sender {
-    celix_bundle_context_t *ctx;
-    celix_log_helper_t *logHelper;
-    long serializerSvcId;
-    pubsub_serializer_service_t *serializer;
-    long protocolSvcId;
-    pubsub_protocol_service_t *protocol;
-    uuid_t fwUUID;
-    bool metricsEnabled;
-    pubsub_tcpHandler_t *socketHandler;
-    pubsub_tcpHandler_t *sharedSocketHandler;
-
-    char *scope;
-    char *topic;
-    char *url;
-    bool isStatic;
-    bool isPassive;
-    bool verbose;
-    unsigned long send_delay;
-
-    struct {
-        long svcId;
-        celix_service_factory_t factory;
-    } publisher;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map;  //key = bndId, value = psa_tcp_bounded_service_entry_t
-    } boundedServices;
-};
-
-typedef struct psa_tcp_send_msg_entry {
-    uint32_t type; //msg type id (hash of fqn)
-    uint8_t major;
-    uint8_t minor;
-    unsigned char originUUID[16];
-    pubsub_msg_serializer_t *msgSer;
-    pubsub_protocol_service_t *protSer;
-    struct iovec *serializedIoVecOutput;
-    size_t serializedIoVecOutputLen;
-    unsigned int seqNr;
-    struct {
-        celix_thread_mutex_t mutex; //protects entries in struct
-        unsigned long nrOfMessagesSend;
-        unsigned long nrOfMessagesSendFailed;
-        unsigned long nrOfSerializationErrors;
-        struct timespec lastMessageSend;
-        double averageTimeBetweenMessagesInSeconds;
-        double averageSerializationTimeInSeconds;
-    } metrics;
-} psa_tcp_send_msg_entry_t;
-
-typedef struct psa_tcp_bounded_service_entry {
-    pubsub_tcp_topic_sender_t *parent;
-    pubsub_publisher_t service;
-    long bndId;
-    hash_map_t *msgTypes; //key = msg type id, value = pubsub_msg_serializer_t
-    hash_map_t *msgTypeIds; // key = msg name, value = msg type id
-    hash_map_t *msgEntries; //key = msg type id, value = psa_tcp_send_msg_entry_t
-    int getCount;
-} psa_tcp_bounded_service_entry_t;
-
-static int psa_tcp_localMsgTypeIdForMsgType(void *handle, const char *msgType, unsigned int *msgTypeId);
-
-static void *psa_tcp_getPublisherService(void *handle, const celix_bundle_t *requestingBundle,
-                                         const celix_properties_t *svcProperties);
-
-static void psa_tcp_ungetPublisherService(void *handle, const celix_bundle_t *requestingBundle,
-                                          const celix_properties_t *svcProperties);
-
-static void delay_first_send_for_late_joiners(pubsub_tcp_topic_sender_t *sender);
-
-static int
-psa_tcp_topicPublicationSend(void *handle, unsigned int msgTypeId, const void *msg, celix_properties_t *metadata);
-
-pubsub_tcp_topic_sender_t *pubsub_tcpTopicSender_create(
-    celix_bundle_context_t *ctx,
-    celix_log_helper_t *logHelper,
-    const char *scope,
-    const char *topic,
-    const celix_properties_t *topicProperties,
-    pubsub_tcp_endPointStore_t *handlerStore,
-    long serializerSvcId,
-    pubsub_serializer_service_t *ser,
-    long protocolSvcId,
-    pubsub_protocol_service_t *protocol) {
-    pubsub_tcp_topic_sender_t *sender = calloc(1, sizeof(*sender));
-    sender->ctx = ctx;
-    sender->logHelper = logHelper;
-    sender->serializerSvcId = serializerSvcId;
-    sender->serializer = ser;
-    sender->protocolSvcId = protocolSvcId;
-    sender->protocol = protocol;
-    const char *uuid = celix_bundleContext_getProperty(ctx, OSGI_FRAMEWORK_FRAMEWORK_UUID, NULL);
-    if (uuid != NULL) {
-        uuid_parse(uuid, sender->fwUUID);
-    }
-    sender->isPassive = false;
-    sender->metricsEnabled = celix_bundleContext_getPropertyAsBool(ctx, PSA_TCP_METRICS_ENABLED, PSA_TCP_DEFAULT_METRICS_ENABLED);
-    char *urls = NULL;
-    const char *ip = celix_bundleContext_getProperty(ctx, PUBSUB_TCP_PSA_IP_KEY, NULL);
-    const char *discUrl = pubsub_getEnvironmentVariableWithScopeTopic(ctx, PUBSUB_TCP_STATIC_BIND_URL_FOR, topic, scope);
-    const char *isPassive = pubsub_getEnvironmentVariableWithScopeTopic(ctx, PUBSUB_TCP_PASSIVE_ENABLED, topic, scope);
-    const char *passiveKey = pubsub_getEnvironmentVariableWithScopeTopic(ctx, PUBSUB_TCP_PASSIVE_SELECTION_KEY, topic, scope);
-
-    if (isPassive) {
-        sender->isPassive = psa_tcp_isPassive(isPassive);
-    }
-    if (topicProperties != NULL) {
-        if (discUrl == NULL) {
-            discUrl = celix_properties_get(topicProperties, PUBSUB_TCP_STATIC_DISCOVER_URL, NULL);
-        }
-        if (isPassive == NULL) {
-            sender->isPassive = celix_properties_getAsBool(topicProperties, PUBSUB_TCP_PASSIVE_CONFIGURED, false);
-        }
-        if (passiveKey == NULL) {
-            passiveKey = celix_properties_get(topicProperties, PUBSUB_TCP_PASSIVE_KEY, NULL);
-        }
-    }
-    /* When it's an endpoint share the socket with the receiver */
-    if (passiveKey != NULL) {
-        celixThreadMutex_lock(&handlerStore->mutex);
-        pubsub_tcpHandler_t *entry = hashMap_get(handlerStore->map, passiveKey);
-        if (entry == NULL) {
-            if (sender->socketHandler == NULL)
-                sender->socketHandler = pubsub_tcpHandler_create(sender->protocol, sender->logHelper);
-            entry = sender->socketHandler;
-            sender->sharedSocketHandler = sender->socketHandler;
-            hashMap_put(handlerStore->map, (void *) passiveKey, entry);
-        } else {
-            sender->socketHandler = entry;
-            sender->sharedSocketHandler = entry;
-        }
-        celixThreadMutex_unlock(&handlerStore->mutex);
-    } else {
-        sender->socketHandler = pubsub_tcpHandler_create(sender->protocol, sender->logHelper);
-    }
-
-    if ((sender->socketHandler != NULL) && (topicProperties != NULL)) {
-        long prio = celix_properties_getAsLong(topicProperties, PUBSUB_TCP_THREAD_REALTIME_PRIO, -1L);
-        const char *sched = celix_properties_get(topicProperties, PUBSUB_TCP_THREAD_REALTIME_SCHED, NULL);
-        long retryCnt = celix_properties_getAsLong(topicProperties, PUBSUB_TCP_PUBLISHER_RETRY_CNT_KEY, PUBSUB_TCP_PUBLISHER_RETRY_CNT_DEFAULT);
-        double sendTimeout = celix_properties_getAsDouble(topicProperties, PUBSUB_TCP_PUBLISHER_SNDTIMEO_KEY, PUBSUB_TCP_PUBLISHER_SNDTIMEO_DEFAULT);
-        long maxMsgSize = celix_properties_getAsLong(topicProperties, PSA_TCP_MAX_MESSAGE_SIZE, PSA_TCP_DEFAULT_MAX_MESSAGE_SIZE);
-        long timeout = celix_bundleContext_getPropertyAsLong(ctx, PSA_TCP_TIMEOUT, PSA_TCP_DEFAULT_TIMEOUT);
-        sender->send_delay = celix_bundleContext_getPropertyAsLong(ctx,  PUBSUB_UTILS_PSA_SEND_DELAY, PUBSUB_UTILS_PSA_DEFAULT_SEND_DELAY);
-        pubsub_tcpHandler_setThreadName(sender->socketHandler, topic, scope);
-        pubsub_tcpHandler_setThreadPriority(sender->socketHandler, prio, sched);
-        pubsub_tcpHandler_setSendRetryCnt(sender->socketHandler, (unsigned int) retryCnt);
-        pubsub_tcpHandler_setSendTimeOut(sender->socketHandler, sendTimeout);
-        pubsub_tcpHandler_setMaxMsgSize(sender->socketHandler, (unsigned int) maxMsgSize);
-        // Hhen passiveKey is specified, enable receive event for full-duplex connection using key.
-        // Because the topic receiver is already started, enable the receive event.
-        pubsub_tcpHandler_enableReceiveEvent(sender->socketHandler, (passiveKey) ? true : false);
-        pubsub_tcpHandler_setTimeout(sender->socketHandler, (unsigned int) timeout);
-    }
-
-    if (!sender->isPassive) {
-        //setting up tcp socket for TCP TopicSender
-        if (discUrl != NULL) {
-            urls = strndup(discUrl, 1024 * 1024);
-            sender->isStatic = true;
-        } else if (ip != NULL) {
-            urls = strndup(ip, 1024 * 1024);
-        } else {
-            struct sockaddr_in *sin = pubsub_utils_url_getInAddr(NULL, 0);
-            urls = pubsub_utils_url_get_url(sin, NULL);
-            free(sin);
-        }
-        if (!sender->url) {
-            char *urlsCopy = strndup(urls, 1024 * 1024);
-            char *url;
-            char *save = urlsCopy;
-            while ((url = strtok_r(save, " ", &save))) {
-                int retry = 0;
-                while (url && retry < TCP_BIND_MAX_RETRY) {
-                    pubsub_utils_url_t *urlInfo = pubsub_utils_url_parse(url);
-                    int rc = pubsub_tcpHandler_listen(sender->socketHandler, urlInfo->url);
-                    if (rc < 0) {
-                        L_WARN("Error for tcp_bind using dynamic bind url '%s'. %s", urlInfo->url, strerror(errno));
-                    } else {
-                        url = NULL;
-                    }
-                    pubsub_utils_url_free(urlInfo);
-                    retry++;
-                }
-            }
-            free(urlsCopy);
-            sender->url = pubsub_tcpHandler_get_interface_url(sender->socketHandler);
-        }
-        free(urls);
-    }
-
-    //register publisher services using a service factory
-    if ((sender->url != NULL) ||  (sender->isPassive)) {
-        sender->scope = scope == NULL ? NULL : strndup(scope, 1024 * 1024);
-        sender->topic = strndup(topic, 1024 * 1024);
-
-        celixThreadMutex_create(&sender->boundedServices.mutex, NULL);
-        sender->boundedServices.map = hashMap_create(NULL, NULL, NULL, NULL);
-
-        sender->publisher.factory.handle = sender;
-        sender->publisher.factory.getService = psa_tcp_getPublisherService;
-        sender->publisher.factory.ungetService = psa_tcp_ungetPublisherService;
-
-        celix_properties_t *props = celix_properties_create();
-        celix_properties_set(props, PUBSUB_PUBLISHER_TOPIC, sender->topic);
-        if (sender->scope != NULL) {
-            celix_properties_set(props, PUBSUB_PUBLISHER_SCOPE, sender->scope);
-        }
-
-        celix_service_registration_options_t opts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS;
-        opts.factory = &sender->publisher.factory;
-        opts.serviceName = PUBSUB_PUBLISHER_SERVICE_NAME;
-        opts.serviceVersion = PUBSUB_PUBLISHER_SERVICE_VERSION;
-        opts.properties = props;
-
-        sender->publisher.svcId = celix_bundleContext_registerServiceWithOptions(ctx, &opts);
-    } else {
-        free(sender);
-        sender = NULL;
-    }
-
-    return sender;
-}
-
-void pubsub_tcpTopicSender_destroy(pubsub_tcp_topic_sender_t *sender) {
-    if (sender != NULL) {
-
-        celix_bundleContext_unregisterService(sender->ctx, sender->publisher.svcId);
-
-        celixThreadMutex_lock(&sender->boundedServices.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(sender->boundedServices.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_tcp_bounded_service_entry_t *entry = hashMapIterator_nextValue(&iter);
-            if (entry != NULL) {
-                sender->serializer->destroySerializerMap(sender->serializer->handle, entry->msgTypes);
-                hash_map_iterator_t iter2 = hashMapIterator_construct(entry->msgEntries);
-                while (hashMapIterator_hasNext(&iter2)) {
-                    psa_tcp_send_msg_entry_t *msgEntry = hashMapIterator_nextValue(&iter2);
-                    if (msgEntry->serializedIoVecOutput)
-                        free(msgEntry->serializedIoVecOutput);
-                    msgEntry->serializedIoVecOutput = NULL;
-                    celixThreadMutex_destroy(&msgEntry->metrics.mutex);
-                    free(msgEntry);
-                }
-                hashMap_destroy(entry->msgEntries, false, false);
-                free(entry);
-            }
-        }
-        hashMap_destroy(sender->boundedServices.map, false, false);
-        celixThreadMutex_unlock(&sender->boundedServices.mutex);
-        celixThreadMutex_destroy(&sender->boundedServices.mutex);
-
-        if ((sender->socketHandler) && (sender->sharedSocketHandler == NULL)) {
-            pubsub_tcpHandler_destroy(sender->socketHandler);
-            sender->socketHandler = NULL;
-        }
-
-        if (sender->scope != NULL) {
-            free(sender->scope);
-        }
-        free(sender->topic);
-        free(sender->url);
-        free(sender);
-    }
-}
-
-long pubsub_tcpTopicSender_serializerSvcId(pubsub_tcp_topic_sender_t *sender) {
-    return sender->serializerSvcId;
-}
-
-long pubsub_tcpTopicSender_protocolSvcId(pubsub_tcp_topic_sender_t *sender) {
-    return sender->protocolSvcId;
-}
-
-const char *pubsub_tcpTopicSender_scope(pubsub_tcp_topic_sender_t *sender) {
-    return sender->scope;
-}
-
-const char *pubsub_tcpTopicSender_topic(pubsub_tcp_topic_sender_t *sender) {
-    return sender->topic;
-}
-
-const char *pubsub_tcpTopicSender_url(pubsub_tcp_topic_sender_t *sender) {
-    if (sender->isPassive) {
-        return pubsub_tcpHandler_get_connection_url(sender->socketHandler);
-    } else {
-        return sender->url;
-    }
-}
-bool pubsub_tcpTopicSender_isStatic(pubsub_tcp_topic_sender_t *sender) {
-    return sender->isStatic;
-}
-
-bool pubsub_tcpTopicSender_isPassive(pubsub_tcp_topic_sender_t *sender) {
-    return sender->isPassive;
-}
-
-void pubsub_tcpTopicSender_connectTo(pubsub_tcp_topic_sender_t *sender __attribute__((unused)), const celix_properties_t *endpoint __attribute__((unused))) {
-    //TODO subscriber count -> topic info
-}
-
-void pubsub_tcpTopicSender_disconnectFrom(pubsub_tcp_topic_sender_t *sender __attribute__((unused)), const celix_properties_t *endpoint __attribute__((unused))) {
-    //TODO
-}
-
-static int psa_tcp_localMsgTypeIdForMsgType(void *handle, const char *msgType, unsigned int *msgTypeId) {
-    psa_tcp_bounded_service_entry_t *entry = (psa_tcp_bounded_service_entry_t *) handle;
-    *msgTypeId = (unsigned int) (uintptr_t) hashMap_get(entry->msgTypeIds, msgType);
-    return 0;
-}
-
-static void *psa_tcp_getPublisherService(void *handle, const celix_bundle_t *requestingBundle,
-                                         const celix_properties_t *svcProperties __attribute__((unused))) {
-    pubsub_tcp_topic_sender_t *sender = handle;
-    long bndId = celix_bundle_getId(requestingBundle);
-
-    celixThreadMutex_lock(&sender->boundedServices.mutex);
-    psa_tcp_bounded_service_entry_t *entry = hashMap_get(sender->boundedServices.map, (void *) bndId);
-    if (entry != NULL) {
-        entry->getCount += 1;
-    } else {
-        entry = calloc(1, sizeof(*entry));
-        entry->getCount = 1;
-        entry->parent = sender;
-        entry->bndId = bndId;
-        entry->msgEntries = hashMap_create(NULL, NULL, NULL, NULL);
-        entry->msgTypeIds = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
-        int rc = sender->serializer->createSerializerMap(sender->serializer->handle,
-                                                         (celix_bundle_t *) requestingBundle, &entry->msgTypes);
-        if (rc == 0) {
-            hash_map_iterator_t iter = hashMapIterator_construct(entry->msgTypes);
-            while (hashMapIterator_hasNext(&iter)) {
-                hash_map_entry_t *hashMapEntry = hashMapIterator_nextEntry(&iter);
-                void *key = hashMapEntry_getKey(hashMapEntry);
-                psa_tcp_send_msg_entry_t *sendEntry = calloc(1, sizeof(*sendEntry));
-                sendEntry->msgSer = hashMapEntry_getValue(hashMapEntry);
-                sendEntry->protSer = sender->protocol;
-                sendEntry->type = (int32_t) sendEntry->msgSer->msgId;
-                int major;
-                int minor;
-                version_getMajor(sendEntry->msgSer->msgVersion, &major);
-                version_getMinor(sendEntry->msgSer->msgVersion, &minor);
-                sendEntry->major = (uint8_t) major;
-                sendEntry->minor = (uint8_t) minor;
-                uuid_copy(sendEntry->originUUID, sender->fwUUID);
-                celixThreadMutex_create(&sendEntry->metrics.mutex, NULL);
-                hashMap_put(entry->msgEntries, key, sendEntry);
-                hashMap_put(entry->msgTypeIds, strndup(sendEntry->msgSer->msgName, 1024),
-                            (void *) (uintptr_t) sendEntry->msgSer->msgId);
-            }
-            entry->service.handle = entry;
-            entry->service.localMsgTypeIdForMsgType = psa_tcp_localMsgTypeIdForMsgType;
-            entry->service.send = psa_tcp_topicPublicationSend;
-            hashMap_put(sender->boundedServices.map, (void *) bndId, entry);
-        } else {
-            L_ERROR("Error creating serializer map for TCP TopicSender %s/%s", sender->scope == NULL ? "(null)" : sender->scope, sender->topic);
-        }
-    }
-    celixThreadMutex_unlock(&sender->boundedServices.mutex);
-
-    return &entry->service;
-}
-
-static void psa_tcp_ungetPublisherService(void *handle, const celix_bundle_t *requestingBundle,
-                                          const celix_properties_t *svcProperties __attribute__((unused))) {
-    pubsub_tcp_topic_sender_t *sender = handle;
-    long bndId = celix_bundle_getId(requestingBundle);
-
-    celixThreadMutex_lock(&sender->boundedServices.mutex);
-    psa_tcp_bounded_service_entry_t *entry = hashMap_get(sender->boundedServices.map, (void *) bndId);
-    if (entry != NULL) {
-        entry->getCount -= 1;
-    }
-    if (entry != NULL && entry->getCount == 0) {
-        //free entry
-        hashMap_remove(sender->boundedServices.map, (void *) bndId);
-        int rc = sender->serializer->destroySerializerMap(sender->serializer->handle, entry->msgTypes);
-        if (rc != 0) {
-            L_ERROR("Error destroying publisher service, serializer not available / cannot get msg serializer map\n");
-        }
-
-        hash_map_iterator_t iter = hashMapIterator_construct(entry->msgEntries);
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_tcp_send_msg_entry_t *msgEntry = hashMapIterator_nextValue(&iter);
-            if (msgEntry->serializedIoVecOutput)
-                free(msgEntry->serializedIoVecOutput);
-            msgEntry->serializedIoVecOutput = NULL;
-            celixThreadMutex_destroy(&msgEntry->metrics.mutex);
-            free(msgEntry);
-        }
-        hashMap_destroy(entry->msgEntries, false, false);
-
-        hashMap_destroy(entry->msgTypeIds, true, false);
-        free(entry);
-    }
-    celixThreadMutex_unlock(&sender->boundedServices.mutex);
-
-}
-
-pubsub_admin_sender_metrics_t *pubsub_tcpTopicSender_metrics(pubsub_tcp_topic_sender_t *sender) {
-    pubsub_admin_sender_metrics_t *result = calloc(1, sizeof(*result));
-    snprintf(result->scope, PUBSUB_AMDIN_METRICS_NAME_MAX, "%s", sender->scope == NULL ? PUBSUB_DEFAULT_ENDPOINT_SCOPE : sender->scope);
-    snprintf(result->topic, PUBSUB_AMDIN_METRICS_NAME_MAX, "%s", sender->topic);
-    celixThreadMutex_lock(&sender->boundedServices.mutex);
-    size_t count = 0;
-    hash_map_iterator_t iter = hashMapIterator_construct(sender->boundedServices.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        psa_tcp_bounded_service_entry_t *entry = hashMapIterator_nextValue(&iter);
-        hash_map_iterator_t iter2 = hashMapIterator_construct(entry->msgEntries);
-        while (hashMapIterator_hasNext(&iter2)) {
-            hashMapIterator_nextValue(&iter2);
-            count += 1;
-        }
-    }
-
-    result->msgMetrics = calloc(count, sizeof(*result));
-
-    iter = hashMapIterator_construct(sender->boundedServices.map);
-    int i = 0;
-    while (hashMapIterator_hasNext(&iter)) {
-        psa_tcp_bounded_service_entry_t *entry = hashMapIterator_nextValue(&iter);
-        hash_map_iterator_t iter2 = hashMapIterator_construct(entry->msgEntries);
-        while (hashMapIterator_hasNext(&iter2)) {
-            psa_tcp_send_msg_entry_t *mEntry = hashMapIterator_nextValue(&iter2);
-            celixThreadMutex_lock(&mEntry->metrics.mutex);
-            result->msgMetrics[i].nrOfMessagesSend = mEntry->metrics.nrOfMessagesSend;
-            result->msgMetrics[i].nrOfMessagesSendFailed = mEntry->metrics.nrOfMessagesSendFailed;
-            result->msgMetrics[i].nrOfSerializationErrors = mEntry->metrics.nrOfSerializationErrors;
-            result->msgMetrics[i].averageSerializationTimeInSeconds = mEntry->metrics.averageSerializationTimeInSeconds;
-            result->msgMetrics[i].averageTimeBetweenMessagesInSeconds = mEntry->metrics.averageTimeBetweenMessagesInSeconds;
-            result->msgMetrics[i].lastMessageSend = mEntry->metrics.lastMessageSend;
-            result->msgMetrics[i].bndId = entry->bndId;
-            result->msgMetrics[i].typeId = mEntry->type;
-            snprintf(result->msgMetrics[i].typeFqn, PUBSUB_AMDIN_METRICS_NAME_MAX, "%s", mEntry->msgSer->msgName);
-            i += 1;
-            celixThreadMutex_unlock(&mEntry->metrics.mutex);
-        }
-    }
-
-    celixThreadMutex_unlock(&sender->boundedServices.mutex);
-    result->nrOfmsgMetrics = (int) count;
-    return result;
-}
-
-static int
-psa_tcp_topicPublicationSend(void *handle, unsigned int msgTypeId, const void *inMsg, celix_properties_t *metadata) {
-    int status = CELIX_SUCCESS;
-    psa_tcp_bounded_service_entry_t *bound = handle;
-    pubsub_tcp_topic_sender_t *sender = bound->parent;
-    bool monitor = sender->metricsEnabled;
-
-    psa_tcp_send_msg_entry_t *entry = hashMap_get(bound->msgEntries, (void *) (uintptr_t) (msgTypeId));
-
-    //metrics updates
-    struct timespec sendTime = {0, 0};
-    struct timespec serializationStart;
-    struct timespec serializationEnd;
-
-    int sendErrorUpdate = 0;
-    int serializationErrorUpdate = 0;
-    int sendCountUpdate = 0;
-
-    if (entry != NULL) {
-        delay_first_send_for_late_joiners(sender);
-        if (monitor) {
-            clock_gettime(CLOCK_REALTIME, &serializationStart);
-        }
-
-        size_t serializedIoVecOutputLen = 0; //entry->serializedIoVecOutputLen;
-        struct iovec *serializedIoVecOutput = NULL;
-        status = entry->msgSer->serialize(entry->msgSer->handle, inMsg, &serializedIoVecOutput,
-                                          &serializedIoVecOutputLen);
-        entry->serializedIoVecOutputLen = MAX(serializedIoVecOutputLen, entry->serializedIoVecOutputLen);
-
-        if (monitor) {
-            clock_gettime(CLOCK_REALTIME, &serializationEnd);
-        }
-
-        pubsub_protocol_message_t message;
-        message.metadata.metadata = NULL;
-        message.payload.payload = NULL;
-        message.payload.length = 0;
-        if (serializedIoVecOutput) {
-            message.payload.payload = serializedIoVecOutput->iov_base;
-            message.payload.length = serializedIoVecOutput->iov_len;
-        }
-        message.header.msgId = msgTypeId;
-        message.header.seqNr = entry->seqNr;
-        message.header.msgMajorVersion = entry->major;
-        message.header.msgMinorVersion = entry->minor;
-        message.header.payloadSize = 0;
-        message.header.payloadPartSize = 0;
-        message.header.payloadOffset = 0;
-        message.header.metadataSize = 0;
-        if (metadata != NULL)
-            message.metadata.metadata = metadata;
-        entry->seqNr++;
-        bool sendOk = true;
-        {
-            int rc = pubsub_tcpHandler_write(sender->socketHandler, &message, serializedIoVecOutput, serializedIoVecOutputLen, 0);
-            if (rc < 0) {
-                status = -1;
-                sendOk = false;
-            }
-            if (message.metadata.metadata)
-                celix_properties_destroy(message.metadata.metadata);
-            if (serializedIoVecOutput) {
-                entry->msgSer->freeSerializeMsg(entry->msgSer->handle,
-                                                serializedIoVecOutput,
-                                                serializedIoVecOutputLen);
-                serializedIoVecOutput = NULL;
-            }
-        }
-
-        if (sendOk) {
-            sendCountUpdate = 1;
-        } else {
-            sendErrorUpdate = 1;
-            L_WARN("[PSA_TCP_TS] Error sending msg. %s", strerror(errno));
-        }
-    } else {
-        //unknownMessageCountUpdate = 1;
-        status = CELIX_SERVICE_EXCEPTION;
-        L_WARN("[PSA_TCP_TS] Error cannot serialize message with msg type id %i for scope/topic %s/%s", msgTypeId,
-               sender->scope == NULL ? "(null)" : sender->scope, sender->topic);
-    }
-
-    if (monitor && entry != NULL) {
-        celixThreadMutex_lock(&entry->metrics.mutex);
-        long n = entry->metrics.nrOfMessagesSend + entry->metrics.nrOfMessagesSendFailed;
-        double diff = celix_difftime(&serializationStart, &serializationEnd);
-        double average = (entry->metrics.averageSerializationTimeInSeconds * n + diff) / (n + 1);
-        entry->metrics.averageSerializationTimeInSeconds = average;
-
-        if (entry->metrics.nrOfMessagesSend > 2) {
-            diff = celix_difftime(&entry->metrics.lastMessageSend, &sendTime);
-            n = entry->metrics.nrOfMessagesSend;
-            average = (entry->metrics.averageTimeBetweenMessagesInSeconds * n + diff) / (n + 1);
-            entry->metrics.averageTimeBetweenMessagesInSeconds = average;
-        }
-
-        entry->metrics.lastMessageSend = sendTime;
-        entry->metrics.nrOfMessagesSend += sendCountUpdate;
-        entry->metrics.nrOfMessagesSendFailed += sendErrorUpdate;
-        entry->metrics.nrOfSerializationErrors += serializationErrorUpdate;
-        celixThreadMutex_unlock(&entry->metrics.mutex);
-    }
-    return status;
-}
-
-static void delay_first_send_for_late_joiners(pubsub_tcp_topic_sender_t *sender) {
-
-    static bool firstSend = true;
-
-    if (firstSend) {
-        if (sender->send_delay ) {
-            L_INFO("PSA_TCP_TP: Delaying first send for late joiners...\n");
-        }
-        usleep(sender->send_delay * 1000);
-        firstSend = false;
-    }
-}
\ No newline at end of file
diff --git a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_topic_sender.h b/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_topic_sender.h
deleted file mode 100644
index 167c208..0000000
--- a/bundles/pubsub/pubsub_admin_tcp/v1/src/pubsub_tcp_topic_sender.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.
- */
-
-#ifndef CELIX_PUBSUB_TCP_TOPIC_SENDER_H
-#define CELIX_PUBSUB_TCP_TOPIC_SENDER_H
-
-#include "celix_bundle_context.h"
-#include "pubsub_admin_metrics.h"
-#include "pubsub_protocol.h"
-#include "pubsub_tcp_common.h"
-
-typedef struct pubsub_tcp_topic_sender pubsub_tcp_topic_sender_t;
-
-pubsub_tcp_topic_sender_t *pubsub_tcpTopicSender_create(
-    celix_bundle_context_t *ctx,
-    celix_log_helper_t *logHelper,
-    const char *scope,
-    const char *topic,
-    const celix_properties_t *topicProperties,
-    pubsub_tcp_endPointStore_t *handlerStore,
-    long serializerSvcId,
-    pubsub_serializer_service_t *ser,
-    long protocolSvcId,
-    pubsub_protocol_service_t *prot);
-
-void pubsub_tcpTopicSender_destroy(pubsub_tcp_topic_sender_t *sender);
-const char *pubsub_tcpTopicSender_scope(pubsub_tcp_topic_sender_t *sender);
-const char *pubsub_tcpTopicSender_topic(pubsub_tcp_topic_sender_t *sender);
-const char *pubsub_tcpTopicSender_url(pubsub_tcp_topic_sender_t *sender);
-bool pubsub_tcpTopicSender_isStatic(pubsub_tcp_topic_sender_t *sender);
-bool pubsub_tcpTopicSender_isPassive(pubsub_tcp_topic_sender_t *sender);
-long pubsub_tcpTopicSender_protocolSvcId(pubsub_tcp_topic_sender_t *sender);
-long pubsub_tcpTopicSender_serializerSvcId(pubsub_tcp_topic_sender_t *sender);
-/* Note this functions are deprecated and not used */
-void pubsub_tcpTopicSender_connectTo(pubsub_tcp_topic_sender_t *sender, const celix_properties_t *endpoint);
-/* Note this functions are deprecated and not used */
-void pubsub_tcpTopicSender_disconnectFrom(pubsub_tcp_topic_sender_t *sender, const celix_properties_t *endpoint);
-
-/**
- * Returns a array of pubsub_admin_sender_msg_type_metrics_t entries for every msg_type/bundle send with the topic sender.
- */
-pubsub_admin_sender_metrics_t *pubsub_tcpTopicSender_metrics(pubsub_tcp_topic_sender_t *sender);
-
-#endif //CELIX_PUBSUB_TCP_TOPIC_SENDER_H
diff --git a/bundles/pubsub/pubsub_admin_websocket/v2/CMakeLists.txt b/bundles/pubsub/pubsub_admin_websocket/CMakeLists.txt
similarity index 100%
rename from bundles/pubsub/pubsub_admin_websocket/v2/CMakeLists.txt
rename to bundles/pubsub/pubsub_admin_websocket/CMakeLists.txt
diff --git a/bundles/pubsub/pubsub_admin_websocket/v2/src/psa_activator.c b/bundles/pubsub/pubsub_admin_websocket/src/psa_activator.c
similarity index 100%
rename from bundles/pubsub/pubsub_admin_websocket/v2/src/psa_activator.c
rename to bundles/pubsub/pubsub_admin_websocket/src/psa_activator.c
diff --git a/bundles/pubsub/pubsub_admin_websocket/v2/src/pubsub_psa_websocket_constants.h b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_psa_websocket_constants.h
similarity index 100%
rename from bundles/pubsub/pubsub_admin_websocket/v2/src/pubsub_psa_websocket_constants.h
rename to bundles/pubsub/pubsub_admin_websocket/src/pubsub_psa_websocket_constants.h
diff --git a/bundles/pubsub/pubsub_admin_websocket/v2/src/pubsub_websocket_admin.c b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_admin.c
similarity index 100%
rename from bundles/pubsub/pubsub_admin_websocket/v2/src/pubsub_websocket_admin.c
rename to bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_admin.c
diff --git a/bundles/pubsub/pubsub_admin_websocket/v2/src/pubsub_websocket_admin.h b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_admin.h
similarity index 100%
rename from bundles/pubsub/pubsub_admin_websocket/v2/src/pubsub_websocket_admin.h
rename to bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_admin.h
diff --git a/bundles/pubsub/pubsub_admin_websocket/v2/src/pubsub_websocket_common.c b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_common.c
similarity index 100%
rename from bundles/pubsub/pubsub_admin_websocket/v2/src/pubsub_websocket_common.c
rename to bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_common.c
diff --git a/bundles/pubsub/pubsub_admin_websocket/v2/src/pubsub_websocket_common.h b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_common.h
similarity index 100%
rename from bundles/pubsub/pubsub_admin_websocket/v2/src/pubsub_websocket_common.h
rename to bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_common.h
diff --git a/bundles/pubsub/pubsub_admin_websocket/v2/src/pubsub_websocket_topic_receiver.c b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_receiver.c
similarity index 100%
rename from bundles/pubsub/pubsub_admin_websocket/v2/src/pubsub_websocket_topic_receiver.c
rename to bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_receiver.c
diff --git a/bundles/pubsub/pubsub_admin_websocket/v2/src/pubsub_websocket_topic_receiver.h b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_receiver.h
similarity index 100%
rename from bundles/pubsub/pubsub_admin_websocket/v2/src/pubsub_websocket_topic_receiver.h
rename to bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_receiver.h
diff --git a/bundles/pubsub/pubsub_admin_websocket/v2/src/pubsub_websocket_topic_sender.c b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_sender.c
similarity index 100%
rename from bundles/pubsub/pubsub_admin_websocket/v2/src/pubsub_websocket_topic_sender.c
rename to bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_sender.c
diff --git a/bundles/pubsub/pubsub_admin_websocket/v2/src/pubsub_websocket_topic_sender.h b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_sender.h
similarity index 100%
rename from bundles/pubsub/pubsub_admin_websocket/v2/src/pubsub_websocket_topic_sender.h
rename to bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_sender.h
diff --git a/bundles/pubsub/pubsub_admin_websocket/v1/CMakeLists.txt b/bundles/pubsub/pubsub_admin_websocket/v1/CMakeLists.txt
deleted file mode 100644
index a38ac85..0000000
--- a/bundles/pubsub/pubsub_admin_websocket/v1/CMakeLists.txt
+++ /dev/null
@@ -1,47 +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.
-
-message(STATUS "PubSub Websocket Admin V1 is deprecated, and will eventually be replaced with PubSub Websocket Admin v2")
-
-find_package(Jansson REQUIRED)
-find_package(UUID REQUIRED)
-
-add_celix_bundle(celix_pubsub_admin_websocket
-    BUNDLE_SYMBOLICNAME "apache_celix_pubsub_admin_websocket"
-    VERSION "1.0.0"
-    GROUP "Celix/PubSub"
-    SOURCES
-        src/psa_activator.c
-        src/pubsub_websocket_admin.c
-        src/pubsub_websocket_topic_sender.c
-        src/pubsub_websocket_topic_receiver.c
-        src/pubsub_websocket_common.c
-)
-
-set_target_properties(celix_pubsub_admin_websocket PROPERTIES INSTALL_RPATH "$ORIGIN")
-target_link_libraries(celix_pubsub_admin_websocket PRIVATE
-        Celix::framework Celix::dfi Celix::log_helper Celix::utils
-        Celix::http_admin_api
-)
-target_link_libraries(celix_pubsub_admin_websocket PRIVATE Celix::pubsub_spi Celix::pubsub_utils )
-target_include_directories(celix_pubsub_admin_websocket PRIVATE
-    src
-)
-
-install_celix_bundle(celix_pubsub_admin_websocket EXPORT celix COMPONENT pubsub)
-target_link_libraries(celix_pubsub_admin_websocket PRIVATE Celix::shell_api)
-add_library(Celix::celix_pubsub_admin_websocket ALIAS celix_pubsub_admin_websocket)
diff --git a/bundles/pubsub/pubsub_admin_websocket/v1/src/psa_activator.c b/bundles/pubsub/pubsub_admin_websocket/v1/src/psa_activator.c
deleted file mode 100644
index 2f4b8cc..0000000
--- a/bundles/pubsub/pubsub_admin_websocket/v1/src/psa_activator.c
+++ /dev/null
@@ -1,112 +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 <stdlib.h>
-
-#include "celix_api.h"
-#include "pubsub_serializer.h"
-#include "celix_log_helper.h"
-
-#include "pubsub_admin.h"
-#include "pubsub_admin_metrics.h"
-#include "pubsub_websocket_admin.h"
-#include "celix_shell_command.h"
-
-typedef struct psa_websocket_activator {
-    celix_log_helper_t *logHelper;
-
-    pubsub_websocket_admin_t *admin;
-
-    long serializersTrackerId;
-
-    pubsub_admin_service_t adminService;
-    long adminSvcId;
-
-    celix_shell_command_t cmdSvc;
-    long cmdSvcId;
-} psa_websocket_activator_t;
-
-int psa_websocket_start(psa_websocket_activator_t *act, celix_bundle_context_t *ctx) {
-    act->adminSvcId = -1L;
-    act->cmdSvcId = -1L;
-    act->serializersTrackerId = -1L;
-
-    act->logHelper = celix_logHelper_create(ctx, "celix_psa_admin_websocket");
-
-    act->admin = pubsub_websocketAdmin_create(ctx, act->logHelper);
-    celix_status_t status = act->admin != NULL ? CELIX_SUCCESS : CELIX_BUNDLE_EXCEPTION;
-
-    //track serializers (only json)
-    if (status == CELIX_SUCCESS) {
-        celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
-        opts.filter.serviceName = PUBSUB_SERIALIZER_SERVICE_NAME;
-        opts.filter.filter = "(pubsub.serializer=json)";
-        opts.filter.ignoreServiceLanguage = true;
-        opts.callbackHandle = act->admin;
-        opts.addWithProperties = pubsub_websocketAdmin_addSerializerSvc;
-        opts.removeWithProperties = pubsub_websocketAdmin_removeSerializerSvc;
-        act->serializersTrackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
-    }
-
-    //register pubsub admin service
-    if (status == CELIX_SUCCESS) {
-        pubsub_admin_service_t *psaSvc = &act->adminService;
-        psaSvc->handle = act->admin;
-        psaSvc->matchPublisher = pubsub_websocketAdmin_matchPublisher;
-        psaSvc->matchSubscriber = pubsub_websocketAdmin_matchSubscriber;
-        psaSvc->matchDiscoveredEndpoint = pubsub_websocketAdmin_matchDiscoveredEndpoint;
-        psaSvc->setupTopicSender = pubsub_websocketAdmin_setupTopicSender;
-        psaSvc->teardownTopicSender = pubsub_websocketAdmin_teardownTopicSender;
-        psaSvc->setupTopicReceiver = pubsub_websocketAdmin_setupTopicReceiver;
-        psaSvc->teardownTopicReceiver = pubsub_websocketAdmin_teardownTopicReceiver;
-        psaSvc->addDiscoveredEndpoint = pubsub_websocketAdmin_addDiscoveredEndpoint;
-        psaSvc->removeDiscoveredEndpoint = pubsub_websocketAdmin_removeDiscoveredEndpoint;
-
-        celix_properties_t *props = celix_properties_create();
-        celix_properties_set(props, PUBSUB_ADMIN_SERVICE_TYPE, PUBSUB_WEBSOCKET_ADMIN_TYPE);
-
-        act->adminSvcId = celix_bundleContext_registerService(ctx, psaSvc, PUBSUB_ADMIN_SERVICE_NAME, props);
-    }
-
-    //register shell command service
-    {
-        act->cmdSvc.handle = act->admin;
-        act->cmdSvc.executeCommand = pubsub_websocketAdmin_executeCommand;
-        celix_properties_t *props = celix_properties_create();
-        celix_properties_set(props, CELIX_SHELL_COMMAND_NAME, "celix::psa_websocket");
-        celix_properties_set(props, CELIX_SHELL_COMMAND_USAGE, "psa_websocket");
-        celix_properties_set(props, CELIX_SHELL_COMMAND_DESCRIPTION, "Print the information about the TopicSender and TopicReceivers for the websocket PSA");
-        act->cmdSvcId = celix_bundleContext_registerService(ctx, &act->cmdSvc, CELIX_SHELL_COMMAND_SERVICE_NAME, props);
-    }
-
-    return status;
-}
-
-int psa_websocket_stop(psa_websocket_activator_t *act, celix_bundle_context_t *ctx) {
-    celix_bundleContext_unregisterService(ctx, act->adminSvcId);
-    celix_bundleContext_unregisterService(ctx, act->cmdSvcId);
-    celix_bundleContext_stopTracker(ctx, act->serializersTrackerId);
-    pubsub_websocketAdmin_destroy(act->admin);
-
-    celix_logHelper_destroy(act->logHelper);
-
-    return CELIX_SUCCESS;
-}
-
-CELIX_GEN_BUNDLE_ACTIVATOR(psa_websocket_activator_t, psa_websocket_start, psa_websocket_stop);
diff --git a/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_psa_websocket_constants.h b/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_psa_websocket_constants.h
deleted file mode 100644
index ada218b..0000000
--- a/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_psa_websocket_constants.h
+++ /dev/null
@@ -1,54 +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_PSA_WEBSOCKET_CONSTANTS_H_
-#define PUBSUB_PSA_WEBSOCKET_CONSTANTS_H_
-
-#define PSA_WEBSOCKET_DEFAULT_QOS_SAMPLE_SCORE        30
-#define PSA_WEBSOCKET_DEFAULT_QOS_CONTROL_SCORE       70
-#define PSA_WEBSOCKET_DEFAULT_SCORE                   30
-
-#define PSA_WEBSOCKET_QOS_SAMPLE_SCORE_KEY            "PSA_WEBSOCKET_QOS_SAMPLE_SCORE"
-#define PSA_WEBSOCKET_QOS_CONTROL_SCORE_KEY           "PSA_WEBSOCKET_QOS_CONTROL_SCORE"
-#define PSA_WEBSOCKET_DEFAULT_SCORE_KEY               "PSA_WEBSOCKET_DEFAULT_SCORE"
-
-
-#define PSA_WEBSOCKET_METRICS_ENABLED                 "PSA_WEBSOCKET_METRICS_ENABLED"
-#define PSA_WEBSOCKET_DEFAULT_METRICS_ENABLED         true
-
-#define PUBSUB_WEBSOCKET_VERBOSE_KEY                  "PSA_WEBSOCKET_VERBOSE"
-#define PUBSUB_WEBSOCKET_VERBOSE_DEFAULT              true
-
-#define PUBSUB_WEBSOCKET_ADMIN_TYPE                   "websocket"
-#define PUBSUB_WEBSOCKET_ADDRESS_KEY                  "websocket.socket_address"
-#define PUBSUB_WEBSOCKET_PORT_KEY                     "websocket.socket_port"
-
-/**
- * The static url which a subscriber should try to connect to.
- * The urls are space separated
- */
-#define PUBSUB_WEBSOCKET_STATIC_CONNECT_SOCKET_ADDRESSES    "websocket.static.connect.socket_addresses"
-
-/**
- * Name of environment variable with space-separated list of ips/urls to connect to
- * e.g. PUBSUB_WEBSOCKET_STATIC_CONNECT_SOCKET_ADDRESSES_FOR_topic_scope="tcp://127.0.0.1:4444 tcp://127.0.0.2:4444"
- */
-#define PUBSUB_WEBSOCKET_STATIC_CONNECT_SOCKET_ADDRESSES_FOR "PUBSUB_WEBSOCKET_STATIC_CONNECT_SOCKET_ADDRESSES_FOR_"
-
-#endif /* PUBSUB_PSA_WEBSOCKET_CONSTANTS_H_ */
diff --git a/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_admin.c b/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_admin.c
deleted file mode 100644
index 9c4633a..0000000
--- a/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_admin.c
+++ /dev/null
@@ -1,605 +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 <memory.h>
-#include <pubsub_endpoint.h>
-#include <pubsub_serializer.h>
-#include <ip_utils.h>
-
-#include "pubsub_utils.h"
-#include "pubsub_websocket_admin.h"
-#include "pubsub_psa_websocket_constants.h"
-#include "pubsub_websocket_topic_sender.h"
-#include "pubsub_websocket_topic_receiver.h"
-#include "pubsub_websocket_common.h"
-
-#define L_DEBUG(...) \
-    celix_logHelper_log(psa->log, CELIX_LOG_LEVEL_DEBUG, __VA_ARGS__)
-#define L_INFO(...) \
-    celix_logHelper_log(psa->log, CELIX_LOG_LEVEL_INFO, __VA_ARGS__)
-#define L_WARN(...) \
-    celix_logHelper_log(psa->log, CELIX_LOG_LEVEL_WARNING, __VA_ARGS__)
-#define L_ERROR(...) \
-    celix_logHelper_log(psa->log, CELIX_LOG_LEVEL_ERROR, __VA_ARGS__)
-
-struct pubsub_websocket_admin {
-    celix_bundle_context_t *ctx;
-    celix_log_helper_t *log;
-    const char *fwUUID;
-
-    double qosSampleScore;
-    double qosControlScore;
-    double defaultScore;
-
-    bool verbose;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = svcId, value = psa_websocket_serializer_entry_t*
-    } serializers;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = scope:topic key, value = pubsub_websocket_topic_sender_t*
-    } topicSenders;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = scope:topic key, value = pubsub_websocket_topic_sender_t*
-    } topicReceivers;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = endpoint uuid, value = celix_properties_t* (endpoint)
-    } discoveredEndpoints;
-
-};
-
-typedef struct psa_websocket_serializer_entry {
-    const char *serType;
-    long svcId;
-    pubsub_serializer_service_t *svc;
-} psa_websocket_serializer_entry_t;
-
-static celix_status_t pubsub_websocketAdmin_connectEndpointToReceiver(pubsub_websocket_admin_t* psa, pubsub_websocket_topic_receiver_t *receiver, const celix_properties_t *endpoint);
-static celix_status_t pubsub_websocketAdmin_disconnectEndpointFromReceiver(pubsub_websocket_admin_t* psa, pubsub_websocket_topic_receiver_t *receiver, const celix_properties_t *endpoint);
-
-
-pubsub_websocket_admin_t* pubsub_websocketAdmin_create(celix_bundle_context_t *ctx, celix_log_helper_t *logHelper) {
-    pubsub_websocket_admin_t *psa = calloc(1, sizeof(*psa));
-    psa->ctx = ctx;
-    psa->log = logHelper;
-    psa->verbose = celix_bundleContext_getPropertyAsBool(ctx, PUBSUB_WEBSOCKET_VERBOSE_KEY, PUBSUB_WEBSOCKET_VERBOSE_DEFAULT);
-    psa->fwUUID = celix_bundleContext_getProperty(ctx, OSGI_FRAMEWORK_FRAMEWORK_UUID, NULL);
-
-    psa->defaultScore = celix_bundleContext_getPropertyAsDouble(ctx, PSA_WEBSOCKET_DEFAULT_SCORE_KEY, PSA_WEBSOCKET_DEFAULT_SCORE);
-    psa->qosSampleScore = celix_bundleContext_getPropertyAsDouble(ctx, PSA_WEBSOCKET_QOS_SAMPLE_SCORE_KEY, PSA_WEBSOCKET_DEFAULT_QOS_SAMPLE_SCORE);
-    psa->qosControlScore = celix_bundleContext_getPropertyAsDouble(ctx, PSA_WEBSOCKET_QOS_CONTROL_SCORE_KEY, PSA_WEBSOCKET_DEFAULT_QOS_CONTROL_SCORE);
-
-    celixThreadMutex_create(&psa->serializers.mutex, NULL);
-    psa->serializers.map = hashMap_create(NULL, NULL, NULL, NULL);
-
-    celixThreadMutex_create(&psa->topicSenders.mutex, NULL);
-    psa->topicSenders.map = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
-    celixThreadMutex_create(&psa->topicReceivers.mutex, NULL);
-    psa->topicReceivers.map = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
-    celixThreadMutex_create(&psa->discoveredEndpoints.mutex, NULL);
-    psa->discoveredEndpoints.map = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
-    return psa;
-}
-
-void pubsub_websocketAdmin_destroy(pubsub_websocket_admin_t *psa) {
-    if (psa == NULL) {
-        return;
-    }
-
-    //note assuming al psa register services and service tracker are removed.
-
-    celixThreadMutex_lock(&psa->topicSenders.mutex);
-    hash_map_iterator_t iter = hashMapIterator_construct(psa->topicSenders.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        pubsub_websocket_topic_sender_t *sender = hashMapIterator_nextValue(&iter);
-        pubsub_websocketTopicSender_destroy(sender);
-    }
-    celixThreadMutex_unlock(&psa->topicSenders.mutex);
-
-    celixThreadMutex_lock(&psa->topicReceivers.mutex);
-    iter = hashMapIterator_construct(psa->topicReceivers.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        pubsub_websocket_topic_receiver_t *recv = hashMapIterator_nextValue(&iter);
-        pubsub_websocketTopicReceiver_destroy(recv);
-    }
-    celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-
-    celixThreadMutex_lock(&psa->discoveredEndpoints.mutex);
-    iter = hashMapIterator_construct(psa->discoveredEndpoints.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        celix_properties_t *ep = hashMapIterator_nextValue(&iter);
-        celix_properties_destroy(ep);
-    }
-    celixThreadMutex_unlock(&psa->discoveredEndpoints.mutex);
-
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    iter = hashMapIterator_construct(psa->serializers.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        psa_websocket_serializer_entry_t *entry = hashMapIterator_nextValue(&iter);
-        free(entry);
-    }
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-
-    celixThreadMutex_destroy(&psa->topicSenders.mutex);
-    hashMap_destroy(psa->topicSenders.map, true, false);
-
-    celixThreadMutex_destroy(&psa->topicReceivers.mutex);
-    hashMap_destroy(psa->topicReceivers.map, true, false);
-
-    celixThreadMutex_destroy(&psa->discoveredEndpoints.mutex);
-    hashMap_destroy(psa->discoveredEndpoints.map, false, false);
-
-    celixThreadMutex_destroy(&psa->serializers.mutex);
-    hashMap_destroy(psa->serializers.map, false, false);
-
-    free(psa);
-}
-
-void pubsub_websocketAdmin_addSerializerSvc(void *handle, void *svc, const celix_properties_t *props) {
-    pubsub_websocket_admin_t *psa = handle;
-
-    const char *serType = celix_properties_get(props, PUBSUB_SERIALIZER_TYPE_KEY, NULL);
-    long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
-
-    if (serType == NULL) {
-        L_INFO("[PSA_WEBSOCKET] Ignoring serializer service without %s property", PUBSUB_SERIALIZER_TYPE_KEY);
-        return;
-    }
-
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    psa_websocket_serializer_entry_t *entry = hashMap_get(psa->serializers.map, (void*)svcId);
-    if (entry == NULL) {
-        entry = calloc(1, sizeof(*entry));
-        entry->serType = serType;
-        entry->svcId = svcId;
-        entry->svc = svc;
-        hashMap_put(psa->serializers.map, (void*)svcId, entry);
-    }
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-}
-
-void pubsub_websocketAdmin_removeSerializerSvc(void *handle, void *svc, const celix_properties_t *props) {
-    pubsub_websocket_admin_t *psa = handle;
-    long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
-
-    //remove serializer
-    // 1) First find entry and
-    // 2) loop and destroy all topic sender using the serializer and
-    // 3) loop and destroy all topic receivers using the serializer
-    // Note that it is the responsibility of the topology manager to create new topic senders/receivers
-
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    psa_websocket_serializer_entry_t *entry = hashMap_remove(psa->serializers.map, (void*)svcId);
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-
-    if (entry != NULL) {
-        celixThreadMutex_lock(&psa->topicSenders.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(psa->topicSenders.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            hash_map_entry_t *senderEntry = hashMapIterator_nextEntry(&iter);
-            pubsub_websocket_topic_sender_t *sender = hashMapEntry_getValue(senderEntry);
-            if (sender != NULL && entry->svcId == pubsub_websocketTopicSender_serializerSvcId(sender)) {
-                char *key = hashMapEntry_getKey(senderEntry);
-                hashMapIterator_remove(&iter);
-                pubsub_websocketTopicSender_destroy(sender);
-                free(key);
-            }
-        }
-        celixThreadMutex_unlock(&psa->topicSenders.mutex);
-
-        celixThreadMutex_lock(&psa->topicReceivers.mutex);
-        iter = hashMapIterator_construct(psa->topicReceivers.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            hash_map_entry_t *senderEntry = hashMapIterator_nextEntry(&iter);
-            pubsub_websocket_topic_receiver_t *receiver = hashMapEntry_getValue(senderEntry);
-            if (receiver != NULL && entry->svcId == pubsub_websocketTopicReceiver_serializerSvcId(receiver)) {
-                char *key = hashMapEntry_getKey(senderEntry);
-                hashMapIterator_remove(&iter);
-                pubsub_websocketTopicReceiver_destroy(receiver);
-                free(key);
-            }
-        }
-        celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-
-        free(entry);
-    }
-}
-
-celix_status_t pubsub_websocketAdmin_matchPublisher(void *handle, long svcRequesterBndId, const celix_filter_t *svcFilter, celix_properties_t **topicProperties, double *outScore, long *outSerializerSvcId, long *outProtocolSvcId) {
-    pubsub_websocket_admin_t *psa = handle;
-    L_DEBUG("[PSA_WEBSOCKET] pubsub_websocketAdmin_matchPublisher");
-    celix_status_t  status = CELIX_SUCCESS;
-    double score = pubsubEndpoint_matchPublisher(psa->ctx, svcRequesterBndId, svcFilter->filterStr, PUBSUB_WEBSOCKET_ADMIN_TYPE,
-                                               psa->qosSampleScore, psa->qosControlScore, psa->defaultScore,
-                                               false, topicProperties, outSerializerSvcId, outProtocolSvcId);
-    *outScore = score;
-
-    return status;
-}
-
-celix_status_t pubsub_websocketAdmin_matchSubscriber(void *handle, long svcProviderBndId, const celix_properties_t *svcProperties, celix_properties_t **topicProperties, double *outScore, long *outSerializerSvcId, long *outProtocolSvcId) {
-    pubsub_websocket_admin_t *psa = handle;
-    L_DEBUG("[PSA_WEBSOCKET] pubsub_websocketAdmin_matchSubscriber");
-    celix_status_t  status = CELIX_SUCCESS;
-    double score = pubsubEndpoint_matchSubscriber(psa->ctx, svcProviderBndId, svcProperties, PUBSUB_WEBSOCKET_ADMIN_TYPE,
-                                                psa->qosSampleScore, psa->qosControlScore, psa->defaultScore,
-                                                false, topicProperties, outSerializerSvcId, outProtocolSvcId);
-    if (outScore != NULL) {
-        *outScore = score;
-    }
-    return status;
-}
-
-celix_status_t pubsub_websocketAdmin_matchDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint, bool *outMatch) {
-    pubsub_websocket_admin_t *psa = handle;
-    L_DEBUG("[PSA_WEBSOCKET] pubsub_websocketAdmin_matchEndpoint");
-    celix_status_t  status = CELIX_SUCCESS;
-    bool match = pubsubEndpoint_match(psa->ctx, psa->log, endpoint, PUBSUB_WEBSOCKET_ADMIN_TYPE, false, NULL, NULL);
-    if (outMatch != NULL) {
-        *outMatch = match;
-    }
-    return status;
-}
-
-celix_status_t pubsub_websocketAdmin_setupTopicSender(void *handle, const char *scope, const char *topic, const celix_properties_t *topicProperties, long serializerSvcId, long protocolSvcId, celix_properties_t **outPublisherEndpoint) {
-    pubsub_websocket_admin_t *psa = handle;
-    celix_status_t  status = CELIX_SUCCESS;
-
-    //1) Create TopicSender
-    //2) Store TopicSender
-    //3) Connect existing endpoints
-    //4) set outPublisherEndpoint
-
-    celix_properties_t *newEndpoint = NULL;
-
-    char *key = pubsubEndpoint_createScopeTopicKey(scope, topic);
-
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    celixThreadMutex_lock(&psa->topicSenders.mutex);
-    pubsub_websocket_topic_sender_t *sender = hashMap_get(psa->topicSenders.map, key);
-    if (sender == NULL) {
-        psa_websocket_serializer_entry_t *serEntry = hashMap_get(psa->serializers.map, (void*)serializerSvcId);
-        if (serEntry != NULL) {
-            sender = pubsub_websocketTopicSender_create(psa->ctx, psa->log, scope, topic, serializerSvcId, serEntry->svc);
-        }
-        if (sender != NULL) {
-            const char *psaType = PUBSUB_WEBSOCKET_ADMIN_TYPE;
-            const char *serType = serEntry->serType;
-            newEndpoint = pubsubEndpoint_create(psa->fwUUID, scope, topic, PUBSUB_PUBLISHER_ENDPOINT_TYPE, psaType,
-                                                serType, NULL, NULL);
-
-            //Set endpoint visibility to local because the http server handles discovery
-            celix_properties_set(newEndpoint, PUBSUB_ENDPOINT_VISIBILITY, PUBSUB_ENDPOINT_LOCAL_VISIBILITY);
-
-            //if available also set container name
-            const char *cn = celix_bundleContext_getProperty(psa->ctx, "CELIX_CONTAINER_NAME", NULL);
-            if (cn != NULL) {
-                celix_properties_set(newEndpoint, "container_name", cn);
-            }
-            hashMap_put(psa->topicSenders.map, key, sender);
-        } else {
-            L_ERROR("[PSA_WEBSOCKET] Error creating a TopicSender");
-            free(key);
-        }
-    } else {
-        free(key);
-        L_ERROR("[PSA_WEBSOCKET] Cannot setup already existing TopicSender for scope/topic %s/%s!", scope == NULL ? "(null)" : scope, topic);
-    }
-    celixThreadMutex_unlock(&psa->topicSenders.mutex);
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-
-    if (newEndpoint != NULL && outPublisherEndpoint != NULL) {
-        *outPublisherEndpoint = newEndpoint;
-    }
-
-    return status;
-}
-
-celix_status_t pubsub_websocketAdmin_teardownTopicSender(void *handle, const char *scope, const char *topic) {
-    pubsub_websocket_admin_t *psa = handle;
-    celix_status_t  status = CELIX_SUCCESS;
-
-    //1) Find and remove TopicSender from map
-    //2) destroy topic sender
-
-    char *key = pubsubEndpoint_createScopeTopicKey(scope, topic);
-    celixThreadMutex_lock(&psa->topicSenders.mutex);
-    hash_map_entry_t *entry = hashMap_getEntry(psa->topicSenders.map, key);
-    if (entry != NULL) {
-        char *mapKey = hashMapEntry_getKey(entry);
-        pubsub_websocket_topic_sender_t *sender = hashMap_remove(psa->topicSenders.map, key);
-        free(mapKey);
-        pubsub_websocketTopicSender_destroy(sender);
-    } else {
-        L_ERROR("[PSA_WEBSOCKET] Cannot teardown TopicSender with scope/topic %s/%s. Does not exists", scope == NULL ? "(null)" : scope, topic);
-    }
-    celixThreadMutex_unlock(&psa->topicSenders.mutex);
-    free(key);
-
-    return status;
-}
-
-celix_status_t pubsub_websocketAdmin_setupTopicReceiver(void *handle, const char *scope, const char *topic, const celix_properties_t *topicProperties, long serializerSvcId, long protocolSvcId, celix_properties_t **outSubscriberEndpoint) {
-    pubsub_websocket_admin_t *psa = handle;
-
-    celix_properties_t *newEndpoint = NULL;
-
-    char *key = pubsubEndpoint_createScopeTopicKey(scope, topic);
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    celixThreadMutex_lock(&psa->topicReceivers.mutex);
-    pubsub_websocket_topic_receiver_t *receiver = hashMap_get(psa->topicReceivers.map, key);
-    if (receiver == NULL) {
-        psa_websocket_serializer_entry_t *serEntry = hashMap_get(psa->serializers.map, (void*)serializerSvcId);
-        if (serEntry != NULL) {
-            receiver = pubsub_websocketTopicReceiver_create(psa->ctx, psa->log, scope, topic, topicProperties, serializerSvcId, serEntry->svc);
-        } else {
-            L_ERROR("[PSA_WEBSOCKET] Cannot find serializer for TopicSender %s/%s", scope == NULL ? "(null)" : scope, topic);
-        }
-        if (receiver != NULL) {
-            const char *psaType = PUBSUB_WEBSOCKET_ADMIN_TYPE;
-            const char *serType = serEntry->serType;
-            newEndpoint = pubsubEndpoint_create(psa->fwUUID, scope, topic,
-                                                PUBSUB_SUBSCRIBER_ENDPOINT_TYPE, psaType, serType, NULL, NULL);
-
-            //Set endpoint visibility to local because the http server handles discovery
-            celix_properties_set(newEndpoint, PUBSUB_ENDPOINT_VISIBILITY, PUBSUB_ENDPOINT_LOCAL_VISIBILITY);
-
-            //if available also set container name
-            const char *cn = celix_bundleContext_getProperty(psa->ctx, "CELIX_CONTAINER_NAME", NULL);
-            if (cn != NULL) {
-                celix_properties_set(newEndpoint, "container_name", cn);
-            }
-            hashMap_put(psa->topicReceivers.map, key, receiver);
-        } else {
-            L_ERROR("[PSA_WEBSOCKET] Error creating a TopicReceiver.");
-            free(key);
-        }
-    } else {
-        free(key);
-        L_ERROR("[PSA_WEBSOCKET] Cannot setup already existing TopicReceiver for scope/topic %s/%s!", scope == NULL ? "(null)" : scope, topic);
-    }
-    celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-
-    if (receiver != NULL && newEndpoint != NULL) {
-        celixThreadMutex_lock(&psa->discoveredEndpoints.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(psa->discoveredEndpoints.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            celix_properties_t *endpoint = hashMapIterator_nextValue(&iter);
-            const char *type = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TYPE, NULL);
-            if (type != NULL && strncmp(PUBSUB_PUBLISHER_ENDPOINT_TYPE, type, strlen(PUBSUB_PUBLISHER_ENDPOINT_TYPE)) == 0 && pubsubEndpoint_matchWithTopicAndScope(endpoint, topic, scope)) {
-                pubsub_websocketAdmin_connectEndpointToReceiver(psa, receiver, endpoint);
-            }
-        }
-        celixThreadMutex_unlock(&psa->discoveredEndpoints.mutex);
-    }
-
-    if (newEndpoint != NULL && outSubscriberEndpoint != NULL) {
-        *outSubscriberEndpoint = newEndpoint;
-    }
-
-    celix_status_t status = CELIX_SUCCESS;
-    return status;
-}
-
-celix_status_t pubsub_websocketAdmin_teardownTopicReceiver(void *handle, const char *scope, const char *topic) {
-    pubsub_websocket_admin_t *psa = handle;
-
-    char *key = pubsubEndpoint_createScopeTopicKey(scope, topic);
-    celixThreadMutex_lock(&psa->topicReceivers.mutex);
-    hash_map_entry_t *entry = hashMap_getEntry(psa->topicReceivers.map, key);
-    free(key);
-    if (entry != NULL) {
-        char *receiverKey = hashMapEntry_getKey(entry);
-        pubsub_websocket_topic_receiver_t *receiver = hashMapEntry_getValue(entry);
-        hashMap_remove(psa->topicReceivers.map, receiverKey);
-
-        free(receiverKey);
-        pubsub_websocketTopicReceiver_destroy(receiver);
-    }
-    celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-
-    celix_status_t  status = CELIX_SUCCESS;
-    return status;
-}
-
-static celix_status_t pubsub_websocketAdmin_connectEndpointToReceiver(pubsub_websocket_admin_t* psa, pubsub_websocket_topic_receiver_t *receiver, const celix_properties_t *endpoint) {
-    //note can be called with discoveredEndpoint.mutex lock
-    celix_status_t status = CELIX_SUCCESS;
-
-    const char *type = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TYPE, NULL);
-    const char *sockAddress = celix_properties_get(endpoint, PUBSUB_WEBSOCKET_ADDRESS_KEY, NULL);
-    long sockPort = celix_properties_getAsLong(endpoint, PUBSUB_WEBSOCKET_PORT_KEY, -1L);
-
-    bool publisher = type != NULL && strncmp(PUBSUB_PUBLISHER_ENDPOINT_TYPE, type, strlen(PUBSUB_PUBLISHER_ENDPOINT_TYPE)) == 0;
-
-    if (publisher && (sockAddress == NULL || sockPort < 0)) {
-        L_WARN("[PSA WEBSOCKET] Error got endpoint without websocket address/port or endpoint type. Properties:");
-        const char *key = NULL;
-        CELIX_PROPERTIES_FOR_EACH(endpoint, key) {
-            L_WARN("[PSA WEBSOCKET] |- %s=%s\n", key, celix_properties_get(endpoint, key, NULL));
-        }
-        status = CELIX_BUNDLE_EXCEPTION;
-    } else {
-        pubsub_websocketTopicReceiver_connectTo(receiver, sockAddress, sockPort);
-    }
-
-    return status;
-}
-
-celix_status_t pubsub_websocketAdmin_addDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint) {
-    pubsub_websocket_admin_t *psa = handle;
-
-    const char *type = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TYPE, NULL);
-
-    if (type != NULL && strncmp(PUBSUB_PUBLISHER_ENDPOINT_TYPE, type, strlen(PUBSUB_PUBLISHER_ENDPOINT_TYPE)) == 0) {
-        celixThreadMutex_lock(&psa->topicReceivers.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(psa->topicReceivers.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            pubsub_websocket_topic_receiver_t *receiver = hashMapIterator_nextValue(&iter);
-            if (pubsubEndpoint_matchWithTopicAndScope(endpoint, pubsub_websocketTopicReceiver_topic(receiver), pubsub_websocketTopicReceiver_scope(receiver))) {
-                pubsub_websocketAdmin_connectEndpointToReceiver(psa, receiver, endpoint);
-            }
-        }
-        celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-    }
-
-    celixThreadMutex_lock(&psa->discoveredEndpoints.mutex);
-    celix_properties_t *cpy = celix_properties_copy(endpoint);
-    const char *uuid = celix_properties_get(cpy, PUBSUB_ENDPOINT_UUID, NULL);
-    hashMap_put(psa->discoveredEndpoints.map, (void*)uuid, cpy);
-    celixThreadMutex_unlock(&psa->discoveredEndpoints.mutex);
-
-    celix_status_t  status = CELIX_SUCCESS;
-    return status;
-}
-
-
-static celix_status_t pubsub_websocketAdmin_disconnectEndpointFromReceiver(pubsub_websocket_admin_t* psa, pubsub_websocket_topic_receiver_t *receiver, const celix_properties_t *endpoint) {
-    //note can be called with discoveredEndpoint.mutex lock
-    celix_status_t status = CELIX_SUCCESS;
-
-    const char *scope = pubsub_websocketTopicReceiver_scope(receiver);
-    const char *topic = pubsub_websocketTopicReceiver_topic(receiver);
-
-    const char *type = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TYPE, NULL);
-    const char *eScope = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TOPIC_SCOPE, NULL);
-    const char *eTopic = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TOPIC_NAME, NULL);
-    const char *sockAddress = celix_properties_get(endpoint, PUBSUB_WEBSOCKET_ADDRESS_KEY, NULL);
-    long sockPort = celix_properties_getAsLong(endpoint, PUBSUB_WEBSOCKET_PORT_KEY, -1L);
-
-    bool publisher = type != NULL && strncmp(PUBSUB_PUBLISHER_ENDPOINT_TYPE, type, strlen(PUBSUB_PUBLISHER_ENDPOINT_TYPE)) == 0;
-
-    if (publisher && (sockAddress == NULL || sockPort < 0)) {
-        L_WARN("[PSA WEBSOCKET] Error got endpoint without websocket address/port or endpoint type. Properties:");
-        const char *key = NULL;
-        CELIX_PROPERTIES_FOR_EACH(endpoint, key) {
-            L_WARN("[PSA WEBSOCKET] |- %s=%s\n", key, celix_properties_get(endpoint, key, NULL));
-        }
-        status = CELIX_BUNDLE_EXCEPTION;
-    } else if (eTopic != NULL && strncmp(eTopic, topic, 1024 * 1024) == 0) {
-        if ((scope == NULL && eScope == NULL) || (scope != NULL && eScope != NULL && strncmp(eScope, scope, 1024 * 1024) == 0)) {
-            pubsub_websocketTopicReceiver_disconnectFrom(receiver, sockAddress, sockPort);
-        }
-    }
-
-    return status;
-}
-
-celix_status_t pubsub_websocketAdmin_removeDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint) {
-    pubsub_websocket_admin_t *psa = handle;
-
-    const char *type = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TYPE, NULL);
-
-    if (type != NULL && strncmp(PUBSUB_PUBLISHER_ENDPOINT_TYPE, type, strlen(PUBSUB_PUBLISHER_ENDPOINT_TYPE)) == 0) {
-        celixThreadMutex_lock(&psa->topicReceivers.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(psa->topicReceivers.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            pubsub_websocket_topic_receiver_t *receiver = hashMapIterator_nextValue(&iter);
-            pubsub_websocketAdmin_disconnectEndpointFromReceiver(psa, receiver, endpoint);
-        }
-        celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-    }
-
-    celixThreadMutex_lock(&psa->discoveredEndpoints.mutex);
-    const char *uuid = celix_properties_get(endpoint, PUBSUB_ENDPOINT_UUID, NULL);
-    celix_properties_t *found = hashMap_remove(psa->discoveredEndpoints.map, (void*)uuid);
-    celixThreadMutex_unlock(&psa->discoveredEndpoints.mutex);
-
-    if (found != NULL) {
-        celix_properties_destroy(found);
-    }
-
-    celix_status_t  status = CELIX_SUCCESS;
-    return status;
-}
-
-bool pubsub_websocketAdmin_executeCommand(void *handle, const char *commandLine __attribute__((unused)), FILE *out, FILE *errStream __attribute__((unused))) {
-    pubsub_websocket_admin_t *psa = handle;
-
-    fprintf(out, "\n");
-    fprintf(out, "Topic Senders:\n");
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    celixThreadMutex_lock(&psa->topicSenders.mutex);
-    hash_map_iterator_t iter = hashMapIterator_construct(psa->topicSenders.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        pubsub_websocket_topic_sender_t *sender = hashMapIterator_nextValue(&iter);
-        long serSvcId = pubsub_websocketTopicSender_serializerSvcId(sender);
-        psa_websocket_serializer_entry_t *serEntry = hashMap_get(psa->serializers.map, (void*)serSvcId);
-        const char *serType = serEntry == NULL ? "!Error!" : serEntry->serType;
-        const char *scope = pubsub_websocketTopicSender_scope(sender);
-        const char *topic = pubsub_websocketTopicSender_topic(sender);
-        const char *url = pubsub_websocketTopicSender_url(sender);
-        fprintf(out, "|- Topic Sender %s/%s\n", scope == NULL ? "(null)" : scope, topic);
-        fprintf(out, "   |- serializer type = %s\n", serType);
-        fprintf(out, "   |- url             = %s\n", url);
-    }
-    celixThreadMutex_unlock(&psa->topicSenders.mutex);
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-
-    fprintf(out, "\n");
-    fprintf(out, "\nTopic Receivers:\n");
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    celixThreadMutex_lock(&psa->topicReceivers.mutex);
-    iter = hashMapIterator_construct(psa->topicReceivers.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        pubsub_websocket_topic_receiver_t *receiver = hashMapIterator_nextValue(&iter);
-        long serSvcId = pubsub_websocketTopicReceiver_serializerSvcId(receiver);
-        psa_websocket_serializer_entry_t *serEntry = hashMap_get(psa->serializers.map, (void*)serSvcId);
-        const char *serType = serEntry == NULL ? "!Error!" : serEntry->serType;
-        const char *scope = pubsub_websocketTopicReceiver_scope(receiver);
-        const char *topic = pubsub_websocketTopicReceiver_topic(receiver);
-        const char *urlEndp = pubsub_websocketTopicReceiver_url(receiver);
-
-        celix_array_list_t *connected = celix_arrayList_create();
-        celix_array_list_t *unconnected = celix_arrayList_create();
-        pubsub_websocketTopicReceiver_listConnections(receiver, connected, unconnected);
-
-        fprintf(out, "|- Topic Receiver %s/%s\n", scope == NULL ? "(null)" : scope, topic);
-        fprintf(out, "   |- serializer type      = %s\n", serType);
-        fprintf(out, "   |- url                  = %s\n", urlEndp);
-        for (int i = 0; i < celix_arrayList_size(connected); ++i) {
-            char *url = celix_arrayList_get(connected, i);
-            fprintf(out, "   |- connected endpoint   = %s\n", url);
-            free(url);
-        }
-        for (int i = 0; i < celix_arrayList_size(unconnected); ++i) {
-            char *url = celix_arrayList_get(unconnected, i);
-            fprintf(out, "   |- unconnected endpoint = %s\n", url);
-            free(url);
-        }
-        celix_arrayList_destroy(connected);
-        celix_arrayList_destroy(unconnected);
-    }
-    celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-    fprintf(out, "\n");
-
-    return true;
-}
diff --git a/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_admin.h b/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_admin.h
deleted file mode 100644
index bae6333..0000000
--- a/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_admin.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.
- */
-
-#ifndef CELIX_PUBSUB_WEBSOCKET_ADMIN_H
-#define CELIX_PUBSUB_WEBSOCKET_ADMIN_H
-
-#include <pubsub_admin_metrics.h>
-#include "celix_api.h"
-#include "celix_log_helper.h"
-#include "pubsub_psa_websocket_constants.h"
-
-typedef struct pubsub_websocket_admin pubsub_websocket_admin_t;
-
-pubsub_websocket_admin_t* pubsub_websocketAdmin_create(celix_bundle_context_t *ctx, celix_log_helper_t *logHelper);
-void pubsub_websocketAdmin_destroy(pubsub_websocket_admin_t *psa);
-
-celix_status_t pubsub_websocketAdmin_matchPublisher(void *handle, long svcRequesterBndId, const celix_filter_t *svcFilter, celix_properties_t **topicProperties, double *score, long *serializerSvcId, long *protocolSvcId);
-celix_status_t pubsub_websocketAdmin_matchSubscriber(void *handle, long svcProviderBndId, const celix_properties_t *svcProperties, celix_properties_t **topicProperties, double *score, long *serializerSvcId, long *protocolSvcId);
-celix_status_t pubsub_websocketAdmin_matchDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint, bool *match);
-
-celix_status_t pubsub_websocketAdmin_setupTopicSender(void *handle, const char *scope, const char *topic, const celix_properties_t* topicProperties, long serializerSvcId, long protocolSvcId, celix_properties_t **publisherEndpoint);
-celix_status_t pubsub_websocketAdmin_teardownTopicSender(void *handle, const char *scope, const char *topic);
-
-celix_status_t pubsub_websocketAdmin_setupTopicReceiver(void *handle, const char *scope, const char *topic, const celix_properties_t* topicProperties, long serializerSvcId, long protocolSvcId, celix_properties_t **subscriberEndpoint);
-celix_status_t pubsub_websocketAdmin_teardownTopicReceiver(void *handle, const char *scope, const char *topic);
-
-celix_status_t pubsub_websocketAdmin_addDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint);
-celix_status_t pubsub_websocketAdmin_removeDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint);
-
-void pubsub_websocketAdmin_addSerializerSvc(void *handle, void *svc, const celix_properties_t *props);
-void pubsub_websocketAdmin_removeSerializerSvc(void *handle, void *svc, const celix_properties_t *props);
-
-bool pubsub_websocketAdmin_executeCommand(void *handle, const char *commandLine, FILE *outStream, FILE *errStream);
-
-#endif //CELIX_PUBSUB_WEBSOCKET_ADMIN_H
-
diff --git a/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_common.c b/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_common.c
deleted file mode 100644
index fe389bc..0000000
--- a/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_common.c
+++ /dev/null
@@ -1,68 +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 <memory.h>
-#include <assert.h>
-#include <stdio.h>
-#include "pubsub_websocket_common.h"
-
-bool psa_websocket_checkVersion(version_pt msgVersion, const pubsub_websocket_msg_header_t *hdr) {
-    bool check=false;
-    int major=0,minor=0;
-
-    if (hdr->major == 0 && hdr->minor == 0) {
-        //no check
-        return true;
-    }
-
-    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;
-}
-
-void psa_websocket_setScopeAndTopicFilter(const char* scope, const char *topic, char *filter) {
-    for (int i = 0; i < 5; ++i) {
-        filter[i] = '\0';
-    }
-    if (scope != NULL && strnlen(scope, 3) >= 2)  {
-        filter[0] = scope[0];
-        filter[1] = scope[1];
-    }
-    if (topic != NULL && strnlen(topic, 3) >= 2)  {
-        filter[2] = topic[0];
-        filter[3] = topic[1];
-    }
-}
-
-char *psa_websocket_createURI(const char *scope, const char *topic) {
-    char *uri = NULL;
-    if(scope != NULL && topic != NULL) {
-        asprintf(&uri, "/pubsub/%s/%s", scope, topic);
-    }
-    else if(scope == NULL && topic != NULL) {
-        asprintf(&uri, "/pubsub/default/%s", topic);
-    }
-    return uri;
-}
diff --git a/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_common.h b/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_common.h
deleted file mode 100644
index 4c22319..0000000
--- a/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_common.h
+++ /dev/null
@@ -1,43 +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 CELIX_PUBSUB_WEBSOCKET_COMMON_H
-#define CELIX_PUBSUB_WEBSOCKET_COMMON_H
-
-#include <utils.h>
-#include <stdint.h>
-
-#include "version.h"
-
-
-struct pubsub_websocket_msg_header {
-    const char *id; //FQN
-    uint8_t major;
-    uint8_t minor;
-    uint32_t seqNr;
-};
-
-typedef struct pubsub_websocket_msg_header pubsub_websocket_msg_header_t;
-
-void psa_websocket_setScopeAndTopicFilter(const char* scope, const char *topic, char *filter);
-char *psa_websocket_createURI(const char *scope, const char *topic);
-
-bool psa_websocket_checkVersion(version_pt msgVersion, const pubsub_websocket_msg_header_t *hdr);
-
-#endif //CELIX_PUBSUB_WEBSOCKET_COMMON_H
diff --git a/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_topic_receiver.c b/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_topic_receiver.c
deleted file mode 100644
index 7b2cfcc..0000000
--- a/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_topic_receiver.c
+++ /dev/null
@@ -1,774 +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 <pubsub_serializer.h>
-#include <stdlib.h>
-#include <pubsub/subscriber.h>
-#include <memory.h>
-#include <pubsub_constants.h>
-#include <assert.h>
-#include <pubsub_endpoint.h>
-#include <arpa/inet.h>
-#include <celix_log_helper.h>
-#include <math.h>
-#include "pubsub_websocket_topic_receiver.h"
-#include "pubsub_psa_websocket_constants.h"
-#include "pubsub_websocket_common.h"
-
-#include <uuid/uuid.h>
-#include <http_admin/api.h>
-#include <jansson.h>
-#include <pubsub_utils.h>
-#include <celix_api.h>
-
-#ifndef UUID_STR_LEN
-#define UUID_STR_LEN 37
-#endif
-
-
-#define L_DEBUG(...) \
-    celix_logHelper_log(receiver->logHelper, CELIX_LOG_LEVEL_DEBUG, __VA_ARGS__)
-#define L_INFO(...) \
-    celix_logHelper_log(receiver->logHelper, CELIX_LOG_LEVEL_INFO, __VA_ARGS__)
-#define L_WARN(...) \
-    celix_logHelper_log(receiver->logHelper, CELIX_LOG_LEVEL_WARNING, __VA_ARGS__)
-#define L_ERROR(...) \
-    celix_logHelper_log(receiver->logHelper, CELIX_LOG_LEVEL_ERROR, __VA_ARGS__)
-
-typedef struct pubsub_websocket_rcv_buffer {
-    celix_thread_mutex_t mutex;
-    celix_array_list_t *list;     //List of received websocket messages (type: pubsub_websocket_msg_entry_t *)
-} pubsub_websocket_rcv_buffer_t;
-
-typedef struct pubsub_websocket_msg_entry {
-    size_t msgSize;
-    const char *msgData;
-} pubsub_websocket_msg_entry_t;
-
-struct pubsub_websocket_topic_receiver {
-    celix_bundle_context_t *ctx;
-    celix_log_helper_t *logHelper;
-    long serializerSvcId;
-    pubsub_serializer_service_t *serializer;
-    char *scope;
-    char *topic;
-    char scopeAndTopicFilter[5];
-    char *uri;
-
-    celix_websocket_service_t sockSvc;
-    long svcId;
-
-    pubsub_websocket_rcv_buffer_t recvBuffer;
-
-    struct {
-        celix_thread_t thread;
-        celix_thread_mutex_t mutex;
-        bool running;
-    } recvThread;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = url (host:port), value = psa_websocket_requested_connection_entry_t*
-        bool allConnected; //true if all requestedConnectection are connected
-    } requestedConnections;
-
-    long subscriberTrackerId;
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = bnd id, value = psa_websocket_subscriber_entry_t
-        bool allInitialized;
-    } subscribers;
-};
-
-typedef struct psa_websocket_requested_connection_entry {
-    char *key; //host:port
-    char *socketAddress;
-    long socketPort;
-    char *uri;
-    struct mg_connection *sockConnection;
-    int connectRetryCount;
-    bool connected;
-    bool statically; //true if the connection is statically configured through the topic properties.
-    bool passive; //true if the connection is initiated by another resource (e.g. webpage)
-} psa_websocket_requested_connection_entry_t;
-
-typedef struct psa_websocket_subscriber_entry {
-    hash_map_t *msgTypes; //key = msg type id, value = pubsub_msg_serializer_t
-    hash_map_t *subscriberServices; //key = servide id, value = pubsub_subscriber_t*
-    bool initialized; //true if the init function is called through the receive thread
-} psa_websocket_subscriber_entry_t;
-
-
-static void pubsub_websocketTopicReceiver_addSubscriber(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *owner);
-static void pubsub_websocketTopicReceiver_removeSubscriber(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *owner);
-static void* psa_websocket_recvThread(void * data);
-static void psa_websocket_connectToAllRequestedConnections(pubsub_websocket_topic_receiver_t *receiver);
-static void psa_websocket_initializeAllSubscribers(pubsub_websocket_topic_receiver_t *receiver);
-static void *psa_websocket_getMsgTypeIdFromFqn(const char *fqn, hash_map_t *msg_type_id_map);
-
-static void psa_websocketTopicReceiver_ready(struct mg_connection *connection, void *handle);
-static int psa_websocketTopicReceiver_data(struct mg_connection *connection, int op_code, char *data, size_t length, void *handle);
-static void psa_websocketTopicReceiver_close(const struct mg_connection *connection, void *handle);
-
-
-pubsub_websocket_topic_receiver_t* pubsub_websocketTopicReceiver_create(celix_bundle_context_t *ctx,
-                                                              celix_log_helper_t *logHelper,
-                                                              const char *scope,
-                                                              const char *topic,
-                                                              const celix_properties_t *topicProperties,
-                                                              long serializerSvcId,
-                                                              pubsub_serializer_service_t *serializer) {
-    pubsub_websocket_topic_receiver_t *receiver = calloc(1, sizeof(*receiver));
-    receiver->ctx = ctx;
-    receiver->logHelper = logHelper;
-    receiver->serializerSvcId = serializerSvcId;
-    receiver->serializer = serializer;
-    receiver->scope = scope == NULL ? NULL : strndup(scope, 1024 * 1024);
-    receiver->topic = strndup(topic, 1024 * 1024);
-    psa_websocket_setScopeAndTopicFilter(scope, topic, receiver->scopeAndTopicFilter);
-
-    receiver->uri = psa_websocket_createURI(scope, topic);
-
-    if (receiver->uri != NULL) {
-        celixThreadMutex_create(&receiver->subscribers.mutex, NULL);
-        celixThreadMutex_create(&receiver->requestedConnections.mutex, NULL);
-        celixThreadMutex_create(&receiver->recvThread.mutex, NULL);
-        celixThreadMutex_create(&receiver->recvBuffer.mutex, NULL);
-
-        receiver->subscribers.map = hashMap_create(NULL, NULL, NULL, NULL);
-        receiver->requestedConnections.map = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-        arrayList_create(&receiver->recvBuffer.list);
-    }
-
-    //track subscribers
-    if (receiver->uri != NULL) {
-        int size = snprintf(NULL, 0, "(%s=%s)", PUBSUB_SUBSCRIBER_TOPIC, topic);
-        char buf[size+1];
-        snprintf(buf, (size_t)size+1, "(%s=%s)", PUBSUB_SUBSCRIBER_TOPIC, topic);
-        celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
-        opts.filter.ignoreServiceLanguage = true;
-        opts.filter.serviceName = PUBSUB_SUBSCRIBER_SERVICE_NAME;
-        opts.filter.filter = buf;
-        opts.callbackHandle = receiver;
-        opts.addWithOwner = pubsub_websocketTopicReceiver_addSubscriber;
-        opts.removeWithOwner = pubsub_websocketTopicReceiver_removeSubscriber;
-
-        receiver->subscriberTrackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
-    }
-
-    //Register a websocket endpoint for this topic receiver
-    if(receiver->uri != NULL){
-        //Register a websocket svc first
-        celix_properties_t *props = celix_properties_create();
-        celix_properties_set(props, WEBSOCKET_ADMIN_URI, receiver->uri);
-        receiver->sockSvc.handle = receiver;
-        //Set callbacks to monitor any incoming connections (passive), data events or close events
-        receiver->sockSvc.ready = psa_websocketTopicReceiver_ready;
-        receiver->sockSvc.data = psa_websocketTopicReceiver_data;
-        receiver->sockSvc.close = psa_websocketTopicReceiver_close;
-        receiver->svcId = celix_bundleContext_registerService(receiver->ctx, &receiver->sockSvc,
-                                                           WEBSOCKET_ADMIN_SERVICE_NAME, props);
-    }
-
-    const char *staticConnects = pubsub_getEnvironmentVariableWithScopeTopic(ctx, PUBSUB_WEBSOCKET_STATIC_CONNECT_SOCKET_ADDRESSES_FOR, topic, scope);
-    if(staticConnects == NULL) {
-        staticConnects = celix_properties_get(topicProperties, PUBSUB_WEBSOCKET_STATIC_CONNECT_SOCKET_ADDRESSES, NULL);
-    }
-    if (staticConnects != NULL) {
-        char *copy = strndup(staticConnects, 1024*1024);
-        char* addr;
-        char* save = copy;
-
-        while ((addr = strtok_r(save, " ", &save))) {
-            char *colon = strchr(addr, ':');
-            if (colon == NULL) {
-                continue;
-            }
-
-            char *sockAddr = NULL;
-            asprintf(&sockAddr, "%.*s", (int)(colon - addr), addr);
-
-            long sockPort = atol((colon + 1));
-
-            char *key = NULL;
-            asprintf(&key, "%s:%li", sockAddr, sockPort);
-
-
-            if (sockPort > 0) {
-                psa_websocket_requested_connection_entry_t *entry = calloc(1, sizeof(*entry));
-                entry->key = key;
-                entry->uri = strndup(receiver->uri, 1024 * 1024);
-                entry->socketAddress = sockAddr;
-                entry->socketPort = sockPort;
-                entry->connected = false;
-                entry->statically = true;
-                entry->passive = false;
-                hashMap_put(receiver->requestedConnections.map, (void *) entry->key, entry);
-            } else {
-                L_WARN("[PSA_WEBSOCKET_TR] Invalid static socket address %s", addr);
-                free(key);
-                free(sockAddr);
-            }
-        }
-        free(copy);
-    }
-
-
-    if (receiver->uri != NULL) {
-        receiver->recvThread.running = true;
-        celixThread_create(&receiver->recvThread.thread, NULL, psa_websocket_recvThread, receiver);
-        char name[64];
-        snprintf(name, 64, "WEBSOCKET TR %s/%s", scope == NULL ? "(null)" : scope, topic);
-        celixThread_setName(&receiver->recvThread.thread, name);
-    }
-
-    if (receiver->uri == NULL) {
-        free(receiver->scope);
-        free(receiver->topic);
-        free(receiver);
-        receiver = NULL;
-        L_ERROR("[PSA_WEBSOCKET] Cannot create TopicReceiver for %s/%s", scope == NULL ? "(null)" : scope, topic);
-    }
-
-    return receiver;
-}
-
-void pubsub_websocketTopicReceiver_destroy(pubsub_websocket_topic_receiver_t *receiver) {
-    if (receiver != NULL) {
-
-        celixThreadMutex_lock(&receiver->recvThread.mutex);
-        receiver->recvThread.running = false;
-        celixThreadMutex_unlock(&receiver->recvThread.mutex);
-        celixThread_join(receiver->recvThread.thread, NULL);
-
-        celix_bundleContext_stopTracker(receiver->ctx, receiver->subscriberTrackerId);
-
-        celix_bundleContext_unregisterService(receiver->ctx, receiver->svcId);
-
-        celixThreadMutex_lock(&receiver->subscribers.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(receiver->subscribers.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_websocket_subscriber_entry_t *entry = hashMapIterator_nextValue(&iter);
-            if (entry != NULL)  {
-                receiver->serializer->destroySerializerMap(receiver->serializer->handle, entry->msgTypes);
-                hashMap_destroy(entry->subscriberServices, false, false);
-                free(entry);
-            }
-
-        }
-        hashMap_destroy(receiver->subscribers.map, false, false);
-
-
-        celixThreadMutex_unlock(&receiver->subscribers.mutex);
-
-        celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-        iter = hashMapIterator_construct(receiver->requestedConnections.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_websocket_requested_connection_entry_t *entry = hashMapIterator_nextValue(&iter);
-            if (entry != NULL) {
-                if(entry->connected) {
-                    mg_close_connection(entry->sockConnection);
-                }
-                free(entry->uri);
-                free(entry->socketAddress);
-                free(entry->key);
-                free(entry);
-            }
-        }
-        hashMap_destroy(receiver->requestedConnections.map, false, false);
-        celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-
-        celixThreadMutex_destroy(&receiver->subscribers.mutex);
-        celixThreadMutex_destroy(&receiver->requestedConnections.mutex);
-        celixThreadMutex_destroy(&receiver->recvThread.mutex);
-
-        celixThreadMutex_destroy(&receiver->recvBuffer.mutex);
-        int msgBufSize = celix_arrayList_size(receiver->recvBuffer.list);
-        while(msgBufSize > 0) {
-            pubsub_websocket_msg_entry_t *msg = celix_arrayList_get(receiver->recvBuffer.list, msgBufSize - 1);
-            free((void *) msg->msgData);
-            free(msg);
-            msgBufSize--;
-        }
-        celix_arrayList_destroy(receiver->recvBuffer.list);
-
-        free(receiver->uri);
-        free(receiver->scope);
-        free(receiver->topic);
-    }
-    free(receiver);
-}
-
-const char* pubsub_websocketTopicReceiver_scope(pubsub_websocket_topic_receiver_t *receiver) {
-    return receiver->scope;
-}
-const char* pubsub_websocketTopicReceiver_topic(pubsub_websocket_topic_receiver_t *receiver) {
-    return receiver->topic;
-}
-const char* pubsub_websocketTopicReceiver_url(pubsub_websocket_topic_receiver_t *receiver) {
-    return receiver->uri;
-}
-
-long pubsub_websocketTopicReceiver_serializerSvcId(pubsub_websocket_topic_receiver_t *receiver) {
-    return receiver->serializerSvcId;
-}
-
-void pubsub_websocketTopicReceiver_listConnections(pubsub_websocket_topic_receiver_t *receiver, celix_array_list_t *connectedUrls, celix_array_list_t *unconnectedUrls) {
-    celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-    hash_map_iterator_t iter = hashMapIterator_construct(receiver->requestedConnections.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        psa_websocket_requested_connection_entry_t *entry = hashMapIterator_nextValue(&iter);
-        char *url = NULL;
-        asprintf(&url, "%s:%li%s%s", entry->socketAddress, entry->socketPort, entry->statically ? " (static)" : "", entry->passive ? " (passive)" : "");
-        if (entry->connected) {
-            celix_arrayList_add(connectedUrls, url);
-        } else {
-            celix_arrayList_add(unconnectedUrls, url);
-        }
-    }
-    celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-}
-
-
-void pubsub_websocketTopicReceiver_connectTo(pubsub_websocket_topic_receiver_t *receiver, const char *socketAddress, long socketPort) {
-    L_DEBUG("[PSA_WEBSOCKET] TopicReceiver %s/%s ('%s') connecting to websocket address %s:li", receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic, receiver->uri, socketAddress, socketPort);
-
-    char *key = NULL;
-    asprintf(&key, "%s:%li", socketAddress, socketPort);
-
-    celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-    psa_websocket_requested_connection_entry_t *entry = hashMap_get(receiver->requestedConnections.map, key);
-    if (entry == NULL) {
-        entry = calloc(1, sizeof(*entry));
-        entry->key = key;
-        entry->uri = strndup(receiver->uri, 1024 * 1024);
-        entry->socketAddress = strndup(socketAddress, 1024 * 1024);
-        entry->socketPort = socketPort;
-        entry->connected = false;
-        entry->statically = false;
-        entry->passive = false;
-        hashMap_put(receiver->requestedConnections.map, (void*)entry->key, entry);
-        receiver->requestedConnections.allConnected = false;
-    } else {
-        free(key);
-    }
-    celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-
-    psa_websocket_connectToAllRequestedConnections(receiver);
-}
-
-void pubsub_websocketTopicReceiver_disconnectFrom(pubsub_websocket_topic_receiver_t *receiver, const char *socketAddress, long socketPort) {
-    L_DEBUG("[PSA_WEBSOCKET] TopicReceiver %s/%s ('%s') disconnect from websocket address %s:%li", receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic, receiver->uri, socketAddress, socketPort);
-
-    char *key = NULL;
-    asprintf(&key, "%s:%li", socketAddress, socketPort);
-
-    celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-
-    psa_websocket_requested_connection_entry_t *entry = hashMap_remove(receiver->requestedConnections.map, key);
-    if (entry != NULL && entry->connected) {
-        mg_close_connection(entry->sockConnection);
-    }
-    if (entry != NULL) {
-        free(entry->socketAddress);
-        free(entry->uri);
-        free(entry->key);
-        free(entry);
-    }
-    celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-    free(key);
-}
-
-static void pubsub_websocketTopicReceiver_addSubscriber(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *bnd) {
-    pubsub_websocket_topic_receiver_t *receiver = handle;
-
-    long bndId = celix_bundle_getId(bnd);
-    long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1);
-    const char *subScope = celix_properties_get(props, PUBSUB_SUBSCRIBER_SCOPE, NULL);
-    if (receiver->scope == NULL){
-        if (subScope != NULL){
-            return;
-        }
-    } else if (subScope != NULL) {
-        if (strncmp(subScope, receiver->scope, strlen(receiver->scope)) != 0) {
-            //not the same scope. ignore
-            return;
-        }
-    } else {
-        //receiver scope is not NULL, but subScope is NULL -> ignore
-        return;
-    }
-
-    celixThreadMutex_lock(&receiver->subscribers.mutex);
-    psa_websocket_subscriber_entry_t *entry = hashMap_get(receiver->subscribers.map, (void*)bndId);
-    if (entry != NULL) {
-        hashMap_put(entry->subscriberServices, (void*)svcId, svc);
-    } else {
-        //new create entry
-        entry = calloc(1, sizeof(*entry));
-        entry->subscriberServices = hashMap_create(NULL, NULL, NULL, NULL);
-        entry->initialized = false;
-        hashMap_put(entry->subscriberServices, (void*)svcId, svc);
-
-        int rc = receiver->serializer->createSerializerMap(receiver->serializer->handle, (celix_bundle_t*)bnd, &entry->msgTypes);
-
-        if (rc == 0) {
-            hashMap_put(receiver->subscribers.map, (void*)bndId, entry);
-        } else {
-            L_ERROR("[PSA_WEBSOCKET] Cannot create msg serializer map for TopicReceiver %s/%s", receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic);
-            free(entry);
-        }
-    }
-    celixThreadMutex_unlock(&receiver->subscribers.mutex);
-}
-
-static void pubsub_websocketTopicReceiver_removeSubscriber(void *handle, void *svc __attribute__((unused)), const celix_properties_t *props __attribute__((unused)), const celix_bundle_t *bnd) {
-    pubsub_websocket_topic_receiver_t *receiver = handle;
-
-    long bndId = celix_bundle_getId(bnd);
-    long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1);
-
-
-    celixThreadMutex_lock(&receiver->subscribers.mutex);
-    psa_websocket_subscriber_entry_t *entry = hashMap_get(receiver->subscribers.map, (void*)bndId);
-    if (entry != NULL) {
-        hashMap_remove(entry->subscriberServices, (void*)svcId);
-    }
-    if (entry != NULL && hashMap_size(entry->subscriberServices) == 0) {
-        //remove entry
-        hashMap_remove(receiver->subscribers.map, (void*)bndId);
-        int rc = receiver->serializer->destroySerializerMap(receiver->serializer->handle, entry->msgTypes);
-        if (rc != 0) {
-            L_ERROR("[PSA_WEBSOCKET] Cannot destroy msg serializers map for TopicReceiver %s/%s", receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic);
-        }
-        hashMap_destroy(entry->subscriberServices, false, false);
-        free(entry);
-    }
-    celixThreadMutex_unlock(&receiver->subscribers.mutex);
-}
-
-static void * psa_websocket_getMsgTypeIdFromFqn(const char *fqn, hash_map_t *msg_type_id_map) {
-    void *msgTypeId = NULL;
-    if(fqn != NULL && msg_type_id_map != NULL) {
-        hash_map_iterator_t iter = hashMapIterator_construct(msg_type_id_map);
-        while (hashMapIterator_hasNext(&iter)) {
-            hash_map_entry_t *entry = hashMapIterator_nextEntry(&iter);
-            pubsub_msg_serializer_t *serializer = hashMapEntry_getValue(entry);
-            if(strcmp(serializer->msgName, fqn) == 0) {
-                msgTypeId =  hashMapEntry_getKey(entry);
-                return msgTypeId;
-            }
-        }
-    }
-
-    return msgTypeId;
-}
-
-static inline void processMsgForSubscriberEntry(pubsub_websocket_topic_receiver_t *receiver, psa_websocket_subscriber_entry_t* entry, pubsub_websocket_msg_header_t *hdr, const char* payload, size_t payloadSize) {
-    //NOTE receiver->subscribers.mutex locked
-    void *msgTypeId = psa_websocket_getMsgTypeIdFromFqn(hdr->id, entry->msgTypes);
-    pubsub_msg_serializer_t* msgSer = hashMap_get(entry->msgTypes, msgTypeId);
-
-    if (msgSer!= NULL && msgTypeId != 0) {
-        void *deSerializedMsg = NULL;
-        bool validVersion = psa_websocket_checkVersion(msgSer->msgVersion, hdr);
-        if (validVersion) {
-            struct iovec deSerializeBuffer;
-            deSerializeBuffer.iov_base = (void *)payload;
-            deSerializeBuffer.iov_len  = payloadSize;
-            celix_status_t status = msgSer->deserialize(msgSer->handle, &deSerializeBuffer, 0, &deSerializedMsg);
-
-            if (status == CELIX_SUCCESS) {
-                hash_map_iterator_t iter = hashMapIterator_construct(entry->subscriberServices);
-                bool release = true;
-                while (hashMapIterator_hasNext(&iter)) {
-                    pubsub_subscriber_t *svc = hashMapIterator_nextValue(&iter);
-                    svc->receive(svc->handle, msgSer->msgName, msgSer->msgId, deSerializedMsg, NULL, &release);
-                    if (!release) {
-                        //receive function has taken ownership, deserialize again for new message
-                        status = msgSer->deserialize(msgSer->handle, &deSerializeBuffer, 0, &deSerializedMsg);
-                        if (status != CELIX_SUCCESS) {
-                            L_WARN("[PSA_WEBSOCKET_TR] Cannot deserialize msg type %s for scope/topic %s/%s", msgSer->msgName, receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic);
-                            break;
-                        }
-                        release = true;
-                    }
-                }
-                if (release) {
-                    msgSer->freeDeserializeMsg(msgSer->handle, deSerializedMsg);
-                }
-            } else {
-                L_WARN("[PSA_WEBSOCKET_TR] Cannot deserialize msg type %s for scope/topic %s/%s", msgSer->msgName, receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic);
-            }
-        }
-    } else {
-        L_WARN("[PSA_WEBSOCKET_TR] Cannot find serializer for type id 0x%X, fqn %s", msgTypeId, hdr->id);
-    }
-}
-
-static inline void processMsg(pubsub_websocket_topic_receiver_t *receiver, const char *msg, size_t msgSize) {
-    json_error_t error;
-    json_t *jsMsg = json_loadb(msg, msgSize, 0, &error);
-    if(jsMsg != NULL) {
-        json_t *jsId = json_object_get(jsMsg, "id");
-        json_t *jsMajor = json_object_get(jsMsg, "major");
-        json_t *jsMinor = json_object_get(jsMsg, "minor");
-        json_t *jsSeqNr = json_object_get(jsMsg, "seqNr");
-        json_t *jsData = json_object_get(jsMsg, "data");
-
-        if (jsId && jsMajor && jsMinor && jsSeqNr && jsData) {
-            pubsub_websocket_msg_header_t hdr;
-            hdr.id = json_string_value(jsId);
-            hdr.major = (uint8_t) json_integer_value(jsMajor);
-            hdr.minor = (uint8_t) json_integer_value(jsMinor);
-            hdr.seqNr = (uint32_t) json_integer_value(jsSeqNr);
-            const char *payload = json_dumps(jsData, 0);
-            size_t payloadSize = strlen(payload);
-            printf("Received msg: id %s\tmajor %u\tminor %u\tseqNr %u\tdata %s\n", hdr.id, hdr.major, hdr.minor, hdr.seqNr, payload);
-
-            celixThreadMutex_lock(&receiver->subscribers.mutex);
-            hash_map_iterator_t iter = hashMapIterator_construct(receiver->subscribers.map);
-            while (hashMapIterator_hasNext(&iter)) {
-                psa_websocket_subscriber_entry_t *entry = hashMapIterator_nextValue(&iter);
-                if (entry != NULL) {
-                    processMsgForSubscriberEntry(receiver, entry, &hdr, payload, payloadSize);
-                }
-            }
-            celixThreadMutex_unlock(&receiver->subscribers.mutex);
-            free((void *) payload);
-        } else {
-            L_WARN("[PSA_WEBSOCKET_TR] Received unsupported message: "
-                   "ID = %s, major = %d, minor = %d, seqNr = %d, data valid? %s",
-                   (jsId ? json_string_value(jsId) : "ERROR"),
-                   json_integer_value(jsMajor), json_integer_value(jsMinor),
-                   json_integer_value(jsSeqNr), (jsData ? "TRUE" : "FALSE"));
-        }
-        json_decref(jsMsg);
-    } else {
-        L_WARN("[PSA_WEBSOCKET_TR] Failed to load websocket JSON message, error line: %d, error message: %s", error.line, error.text);
-        return;
-    }
-
-}
-
-static void* psa_websocket_recvThread(void * data) {
-    pubsub_websocket_topic_receiver_t *receiver = data;
-
-    celixThreadMutex_lock(&receiver->recvThread.mutex);
-    bool running = receiver->recvThread.running;
-    celixThreadMutex_unlock(&receiver->recvThread.mutex);
-
-    celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-    bool allConnected = receiver->requestedConnections.allConnected;
-    celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-
-    celixThreadMutex_lock(&receiver->subscribers.mutex);
-    bool allInitialized = receiver->subscribers.allInitialized;
-    celixThreadMutex_unlock(&receiver->subscribers.mutex);
-
-
-    while (running) {
-        if (!allConnected) {
-            psa_websocket_connectToAllRequestedConnections(receiver);
-        }
-        if (!allInitialized) {
-            psa_websocket_initializeAllSubscribers(receiver);
-        }
-
-        while(celix_arrayList_size(receiver->recvBuffer.list) > 0) {
-            celixThreadMutex_lock(&receiver->recvBuffer.mutex);
-            pubsub_websocket_msg_entry_t *msg = (pubsub_websocket_msg_entry_t *) celix_arrayList_get(receiver->recvBuffer.list, 0);
-            celix_arrayList_removeAt(receiver->recvBuffer.list, 0);
-            celixThreadMutex_unlock(&receiver->recvBuffer.mutex);
-
-            processMsg(receiver, msg->msgData, msg->msgSize);
-            free((void *)msg->msgData);
-            free(msg);
-        }
-
-        celixThreadMutex_lock(&receiver->recvThread.mutex);
-        running = receiver->recvThread.running;
-        celixThreadMutex_unlock(&receiver->recvThread.mutex);
-
-        celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-        allConnected = receiver->requestedConnections.allConnected;
-        celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-
-        celixThreadMutex_lock(&receiver->subscribers.mutex);
-        allInitialized = receiver->subscribers.allInitialized;
-        celixThreadMutex_unlock(&receiver->subscribers.mutex);
-    } // while
-
-    return NULL;
-}
-
-static void psa_websocketTopicReceiver_ready(struct mg_connection *connection, void *handle) {
-    if (handle != NULL) {
-        pubsub_websocket_topic_receiver_t *receiver = (pubsub_websocket_topic_receiver_t *) handle;
-
-        //Get request info with host, port and uri information
-        const struct mg_request_info *ri = mg_get_request_info(connection);
-        if (ri != NULL && strcmp(receiver->uri, ri->request_uri) == 0) {
-            char *key = NULL;
-            asprintf(&key, "%s:%i", ri->remote_addr, ri->remote_port);
-
-            celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-            psa_websocket_requested_connection_entry_t *entry = hashMap_get(receiver->requestedConnections.map, key);
-            if (entry == NULL) {
-                entry = calloc(1, sizeof(*entry));
-                entry->key = key;
-                entry->uri = strndup(ri->request_uri, 1024 * 1024);
-                entry->socketAddress = strndup(ri->remote_addr, 1024 * 1024);
-                entry->socketPort = ri->remote_port;
-                entry->connected = true;
-                entry->statically = false;
-                entry->passive = true;
-                hashMap_put(receiver->requestedConnections.map, (void *) entry->key, entry);
-                receiver->requestedConnections.allConnected = false;
-            } else {
-                free(key);
-            }
-
-            celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-        }
-    }
-}
-
-
-static int psa_websocketTopicReceiver_data(struct mg_connection *connection __attribute__((unused)),
-                                            int op_code __attribute__((unused)),
-                                            char *data,
-                                            size_t length,
-                                            void *handle) {
-    //Received a websocket message, append this message to the buffer of the receiver.
-    if (handle != NULL) {
-        pubsub_websocket_topic_receiver_t *receiver = (pubsub_websocket_topic_receiver_t *) handle;
-
-        celixThreadMutex_lock(&receiver->recvBuffer.mutex);
-        pubsub_websocket_msg_entry_t *msg = malloc(sizeof(*msg));
-        const char *rcvdMsgData = malloc(length);
-        memcpy((void *) rcvdMsgData, data, length);
-        msg->msgData = rcvdMsgData;
-        msg->msgSize = length;
-        celix_arrayList_add(receiver->recvBuffer.list, msg);
-        celixThreadMutex_unlock(&receiver->recvBuffer.mutex);
-    }
-
-    return 1; //keep open (non-zero), 0 to close the socket
-}
-
-static void psa_websocketTopicReceiver_close(const struct mg_connection *connection, void *handle) {
-    //Reset connection for this receiver entry
-    if (handle != NULL) {
-        pubsub_websocket_topic_receiver_t *receiver = (pubsub_websocket_topic_receiver_t *) handle;
-
-        //Get request info with host, port and uri information
-        const struct mg_request_info *ri = mg_get_request_info(connection);
-        if (ri != NULL && strcmp(receiver->uri, ri->request_uri) == 0) {
-            char *key = NULL;
-            asprintf(&key, "%s:%i", ri->remote_addr, ri->remote_port);
-
-            celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-            psa_websocket_requested_connection_entry_t *entry = hashMap_get(receiver->requestedConnections.map, key);
-            if (entry != NULL) {
-                entry->connected = false;
-                entry->sockConnection = NULL;
-                if(entry->passive) {
-                    hashMap_remove(receiver->requestedConnections.map, key);
-                    free(entry->key);
-                    free(entry->uri);
-                    free(entry->socketAddress);
-                    free(entry);
-                }
-            }
-            celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-            free(key);
-        }
-    }
-}
-
-
-static void psa_websocket_connectToAllRequestedConnections(pubsub_websocket_topic_receiver_t *receiver) {
-    celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-    if (!receiver->requestedConnections.allConnected) {
-        bool allConnected = true;
-        hash_map_iterator_t iter = hashMapIterator_construct(receiver->requestedConnections.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_websocket_requested_connection_entry_t *entry = hashMapIterator_nextValue(&iter);
-            if (!entry->connected && !entry->passive) {
-                char errBuf[100] = {0};
-                entry->sockConnection = mg_connect_websocket_client(entry->socketAddress,
-                                                                    (int) entry->socketPort,
-                                                                    0, // No ssl
-                                                                    errBuf,
-                                                                    (size_t) sizeof(errBuf),
-                                                                    entry->uri,
-                                                                    NULL,
-                                                                    psa_websocketTopicReceiver_data,
-                                                                    psa_websocketTopicReceiver_close,
-                                                                    receiver);
-                if(entry->sockConnection != NULL) {
-                    entry->connected = true;
-                    entry->connectRetryCount = 0;
-                } else {
-                    entry->connectRetryCount += 1;
-                    allConnected = false;
-                    if((entry->connectRetryCount % 10) == 0) {
-                        L_WARN("[PSA_WEBSOCKET] Error connecting to websocket %s:%li/%s. Error: %s",
-                               entry->socketAddress,
-                               entry->socketPort,
-                               entry->uri, errBuf);
-                    }
-                }
-            }
-        }
-        receiver->requestedConnections.allConnected = allConnected;
-    }
-    celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-}
-
-static void psa_websocket_initializeAllSubscribers(pubsub_websocket_topic_receiver_t *receiver) {
-    celixThreadMutex_lock(&receiver->subscribers.mutex);
-    if (!receiver->subscribers.allInitialized) {
-        bool allInitialized = true;
-        hash_map_iterator_t iter = hashMapIterator_construct(receiver->subscribers.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_websocket_subscriber_entry_t *entry = hashMapIterator_nextValue(&iter);
-            if (!entry->initialized) {
-                hash_map_iterator_t iter2 = hashMapIterator_construct(entry->subscriberServices);
-                while (hashMapIterator_hasNext(&iter2)) {
-                    pubsub_subscriber_t *svc = hashMapIterator_nextValue(&iter2);
-                    int rc = 0;
-                    if (svc != NULL && svc->init != NULL) {
-                        rc = svc->init(svc->handle);
-                    }
-                    if (rc == 0) {
-                        //note now only initialized on first subscriber entries added.
-                        entry->initialized = true;
-                    } else {
-                        L_WARN("Cannot initialize subscriber svc. Got rc %i", rc);
-                        allInitialized = false;
-                    }
-                }
-            }
-        }
-        receiver->subscribers.allInitialized = allInitialized;
-    }
-    celixThreadMutex_unlock(&receiver->subscribers.mutex);
-}
diff --git a/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_topic_receiver.h b/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_topic_receiver.h
deleted file mode 100644
index 4df42a0..0000000
--- a/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_topic_receiver.h
+++ /dev/null
@@ -1,47 +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 CELIX_PUBSUB_WEBSOCKET_TOPIC_RECEIVER_H
-#define CELIX_PUBSUB_WEBSOCKET_TOPIC_RECEIVER_H
-
-#include <pubsub_admin_metrics.h>
-#include "celix_bundle_context.h"
-
-typedef struct pubsub_websocket_topic_receiver pubsub_websocket_topic_receiver_t;
-
-pubsub_websocket_topic_receiver_t* pubsub_websocketTopicReceiver_create(celix_bundle_context_t *ctx,
-        celix_log_helper_t *logHelper,
-        const char *scope,
-        const char *topic,
-        const celix_properties_t *topicProperties,
-        long serializerSvcId,
-        pubsub_serializer_service_t *serializer);
-void pubsub_websocketTopicReceiver_destroy(pubsub_websocket_topic_receiver_t *receiver);
-
-const char* pubsub_websocketTopicReceiver_scope(pubsub_websocket_topic_receiver_t *receiver);
-const char* pubsub_websocketTopicReceiver_topic(pubsub_websocket_topic_receiver_t *receiver);
-const char* pubsub_websocketTopicReceiver_url(pubsub_websocket_topic_receiver_t *receiver);
-
-long pubsub_websocketTopicReceiver_serializerSvcId(pubsub_websocket_topic_receiver_t *receiver);
-void pubsub_websocketTopicReceiver_listConnections(pubsub_websocket_topic_receiver_t *receiver, celix_array_list_t *connectedUrls, celix_array_list_t *unconnectedUrls);
-
-void pubsub_websocketTopicReceiver_connectTo(pubsub_websocket_topic_receiver_t *receiver, const char *socketAddress, long socketPort);
-void pubsub_websocketTopicReceiver_disconnectFrom(pubsub_websocket_topic_receiver_t *receiver, const char *socketAddress, long socketPort);
-
-#endif //CELIX_PUBSUB_WEBSOCKET_TOPIC_RECEIVER_H
diff --git a/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_topic_sender.c b/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_topic_sender.c
deleted file mode 100644
index ac3108c..0000000
--- a/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_topic_sender.c
+++ /dev/null
@@ -1,381 +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 <pubsub_serializer.h>
-#include <stdlib.h>
-#include <memory.h>
-#include <pubsub_constants.h>
-#include <pubsub/publisher.h>
-#include <utils.h>
-#include <zconf.h>
-#include <celix_log_helper.h>
-#include "pubsub_websocket_topic_sender.h"
-#include "pubsub_psa_websocket_constants.h"
-#include "pubsub_websocket_common.h"
-#include <uuid/uuid.h>
-#include <jansson.h>
-#include "celix_constants.h"
-#include "http_admin/api.h"
-#include "civetweb.h"
-
-#define FIRST_SEND_DELAY_IN_SECONDS             2
-
-#define L_DEBUG(...) \
-    celix_logHelper_log(sender->logHelper, CELIX_LOG_LEVEL_DEBUG, __VA_ARGS__)
-#define L_INFO(...) \
-    celix_logHelper_log(sender->logHelper, CELIX_LOG_LEVEL_INFO, __VA_ARGS__)
-#define L_WARN(...) \
-    celix_logHelper_log(sender->logHelper, CELIX_LOG_LEVEL_WARNING, __VA_ARGS__)
-#define L_ERROR(...) \
-    celix_logHelper_log(sender->logHelper, CELIX_LOG_LEVEL_ERROR, __VA_ARGS__)
-
-struct pubsub_websocket_topic_sender {
-    celix_bundle_context_t *ctx;
-    celix_log_helper_t *logHelper;
-    long serializerSvcId;
-    pubsub_serializer_service_t *serializer;
-
-    char *scope;
-    char *topic;
-    char scopeAndTopicFilter[5];
-    char *uri;
-
-    celix_websocket_service_t websockSvc;
-    long websockSvcId;
-    struct mg_connection *sockConnection;
-
-    struct {
-        long svcId;
-        celix_service_factory_t factory;
-    } publisher;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map;  //key = bndId, value = psa_websocket_bounded_service_entry_t
-    } boundedServices;
-};
-
-typedef struct psa_websocket_send_msg_entry {
-    pubsub_websocket_msg_header_t header; //partially filled header (only seqnr and time needs to be updated per send)
-    pubsub_msg_serializer_t *msgSer;
-    celix_thread_mutex_t sendLock; //protects send & header(.seqNr)
-} psa_websocket_send_msg_entry_t;
-
-typedef struct psa_websocket_bounded_service_entry {
-    pubsub_websocket_topic_sender_t *parent;
-    pubsub_publisher_t service;
-    long bndId;
-    hash_map_t *msgTypes; //key = msg type id, value = pubsub_msg_serializer_t
-    hash_map_t *msgTypeIds; //key = msg name, value = msg type id
-    hash_map_t *msgEntries; //key = msg type id, value = psa_websocket_send_msg_entry_t
-    int getCount;
-} psa_websocket_bounded_service_entry_t;
-
-static int psa_websocket_localMsgTypeIdForMsgType(void* handle __attribute__((unused)), const char* msgType, unsigned int* msgTypeId);
-static void* psa_websocket_getPublisherService(void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties);
-static void psa_websocket_ungetPublisherService(void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties);
-static void delay_first_send_for_late_joiners(pubsub_websocket_topic_sender_t *sender);
-
-static int psa_websocket_topicPublicationSend(void* handle, unsigned int msgTypeId, const void *msg, celix_properties_t *metadata);
-
-static void psa_websocketTopicSender_ready(struct mg_connection *connection, void *handle);
-static void psa_websocketTopicSender_close(const struct mg_connection *connection, void *handle);
-
-pubsub_websocket_topic_sender_t* pubsub_websocketTopicSender_create(
-        celix_bundle_context_t *ctx,
-        celix_log_helper_t *logHelper,
-        const char *scope,
-        const char *topic,
-        long serializerSvcId,
-        pubsub_serializer_service_t *ser) {
-    pubsub_websocket_topic_sender_t *sender = calloc(1, sizeof(*sender));
-    sender->ctx = ctx;
-    sender->logHelper = logHelper;
-    sender->serializerSvcId = serializerSvcId;
-    sender->serializer = ser;
-    psa_websocket_setScopeAndTopicFilter(scope, topic, sender->scopeAndTopicFilter);
-    sender->uri = psa_websocket_createURI(scope, topic);
-
-    if (sender->uri != NULL) {
-        celix_properties_t *props = celix_properties_create();
-        celix_properties_set(props, WEBSOCKET_ADMIN_URI, sender->uri);
-
-        sender->websockSvc.handle = sender;
-        sender->websockSvc.ready = psa_websocketTopicSender_ready;
-        sender->websockSvc.close = psa_websocketTopicSender_close;
-        sender->websockSvcId = celix_bundleContext_registerService(ctx, &sender->websockSvc,
-                                                                   WEBSOCKET_ADMIN_SERVICE_NAME, props);
-    } else {
-        sender->websockSvcId = -1;
-    }
-
-    if (sender->websockSvcId > 0) {
-        sender->scope = scope == NULL ? NULL : strndup(scope, 1024 * 1024);
-        sender->topic = strndup(topic, 1024 * 1024);
-
-        celixThreadMutex_create(&sender->boundedServices.mutex, NULL);
-        sender->boundedServices.map = hashMap_create(NULL, NULL, NULL, NULL);
-    }
-
-    //register publisher services using a service factory
-    if (sender->websockSvcId > 0) {
-        sender->publisher.factory.handle = sender;
-        sender->publisher.factory.getService = psa_websocket_getPublisherService;
-        sender->publisher.factory.ungetService = psa_websocket_ungetPublisherService;
-
-        celix_properties_t *props = celix_properties_create();
-        celix_properties_set(props, PUBSUB_PUBLISHER_TOPIC, sender->topic);
-        if (sender->scope != NULL) {
-            celix_properties_set(props, PUBSUB_PUBLISHER_SCOPE, sender->scope);
-        }
-
-        celix_service_registration_options_t opts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS;
-        opts.factory = &sender->publisher.factory;
-        opts.serviceName = PUBSUB_PUBLISHER_SERVICE_NAME;
-        opts.serviceVersion = PUBSUB_PUBLISHER_SERVICE_VERSION;
-        opts.properties = props;
-
-        sender->publisher.svcId = celix_bundleContext_registerServiceWithOptions(ctx, &opts);
-    }
-
-    if (sender->websockSvcId < 0) {
-        free(sender);
-        sender = NULL;
-    }
-
-    return sender;
-}
-
-void pubsub_websocketTopicSender_destroy(pubsub_websocket_topic_sender_t *sender) {
-    if (sender != NULL) {
-        celix_bundleContext_unregisterService(sender->ctx, sender->publisher.svcId);
-
-        celixThreadMutex_lock(&sender->boundedServices.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(sender->boundedServices.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_websocket_bounded_service_entry_t *entry = hashMapIterator_nextValue(&iter);
-            if (entry != NULL) {
-                sender->serializer->destroySerializerMap(sender->serializer->handle, entry->msgTypes);
-
-                hash_map_iterator_t iter2 = hashMapIterator_construct(entry->msgEntries);
-                while (hashMapIterator_hasNext(&iter2)) {
-                    psa_websocket_send_msg_entry_t *msgEntry = hashMapIterator_nextValue(&iter2);
-                    free(msgEntry);
-
-                }
-                hashMap_destroy(entry->msgEntries, false, false);
-
-                free(entry);
-            }
-        }
-        hashMap_destroy(sender->boundedServices.map, false, false);
-        celixThreadMutex_unlock(&sender->boundedServices.mutex);
-
-        celixThreadMutex_destroy(&sender->boundedServices.mutex);
-
-        celix_bundleContext_unregisterService(sender->ctx, sender->websockSvcId);
-
-        if (sender->scope != NULL) {
-            free(sender->scope);
-        }
-        free(sender->topic);
-        free(sender->uri);
-        free(sender);
-    }
-}
-
-long pubsub_websocketTopicSender_serializerSvcId(pubsub_websocket_topic_sender_t *sender) {
-    return sender->serializerSvcId;
-}
-
-const char* pubsub_websocketTopicSender_scope(pubsub_websocket_topic_sender_t *sender) {
-    return sender->scope;
-}
-
-const char* pubsub_websocketTopicSender_topic(pubsub_websocket_topic_sender_t *sender) {
-    return sender->topic;
-}
-
-const char* pubsub_websocketTopicSender_url(pubsub_websocket_topic_sender_t *sender) {
-    return sender->uri;
-}
-
-static int psa_websocket_localMsgTypeIdForMsgType(void* handle, const char* msgType, unsigned int* msgTypeId) {
-    psa_websocket_bounded_service_entry_t *entry = (psa_websocket_bounded_service_entry_t *) handle;
-    *msgTypeId = (unsigned int)(uintptr_t) hashMap_get(entry->msgTypeIds, msgType);
-    return 0;
-}
-
-static void* psa_websocket_getPublisherService(void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties __attribute__((unused))) {
-    pubsub_websocket_topic_sender_t *sender = handle;
-    long bndId = celix_bundle_getId(requestingBundle);
-
-    celixThreadMutex_lock(&sender->boundedServices.mutex);
-    psa_websocket_bounded_service_entry_t *entry = hashMap_get(sender->boundedServices.map, (void*)bndId);
-    if (entry != NULL) {
-        entry->getCount += 1;
-    } else {
-        entry = calloc(1, sizeof(*entry));
-        entry->getCount = 1;
-        entry->parent = sender;
-        entry->bndId = bndId;
-        entry->msgEntries = hashMap_create(NULL, NULL, NULL, NULL);
-        entry->msgTypeIds = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
-        int rc = sender->serializer->createSerializerMap(sender->serializer->handle, (celix_bundle_t*)requestingBundle, &entry->msgTypes);
-        if (rc == 0) {
-            hash_map_iterator_t iter = hashMapIterator_construct(entry->msgTypes);
-            while (hashMapIterator_hasNext(&iter)) {
-                hash_map_entry_t *hashMapEntry = hashMapIterator_nextEntry(&iter);
-                void *key = hashMapEntry_getKey(hashMapEntry);
-                psa_websocket_send_msg_entry_t *sendEntry = calloc(1, sizeof(*sendEntry));
-                sendEntry->msgSer = hashMapEntry_getValue(hashMapEntry);
-                sendEntry->header.id = sendEntry->msgSer->msgName;
-                int major;
-                int minor;
-                version_getMajor(sendEntry->msgSer->msgVersion, &major);
-                version_getMinor(sendEntry->msgSer->msgVersion, &minor);
-                sendEntry->header.major = (uint8_t)major;
-                sendEntry->header.minor = (uint8_t)minor;
-                hashMap_put(entry->msgEntries, key, sendEntry);
-                hashMap_put(entry->msgTypeIds, strndup(sendEntry->msgSer->msgName, 1024), (void *)(uintptr_t) sendEntry->msgSer->msgId);
-            }
-            entry->service.handle = entry;
-            entry->service.localMsgTypeIdForMsgType = psa_websocket_localMsgTypeIdForMsgType;
-            entry->service.send = psa_websocket_topicPublicationSend;
-            hashMap_put(sender->boundedServices.map, (void*)bndId, entry);
-        } else {
-            L_ERROR("Error creating serializer map for websocket TopicSender %s/%s", sender->scope == NULL ? "(null)" : sender->scope, sender->topic);
-        }
-    }
-    celixThreadMutex_unlock(&sender->boundedServices.mutex);
-
-    return &entry->service;
-}
-
-static void psa_websocket_ungetPublisherService(void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties __attribute__((unused))) {
-    pubsub_websocket_topic_sender_t *sender = handle;
-    long bndId = celix_bundle_getId(requestingBundle);
-
-    celixThreadMutex_lock(&sender->boundedServices.mutex);
-    psa_websocket_bounded_service_entry_t *entry = hashMap_get(sender->boundedServices.map, (void*)bndId);
-    if (entry != NULL) {
-        entry->getCount -= 1;
-    }
-    if (entry != NULL && entry->getCount == 0) {
-        //free entry
-        hashMap_remove(sender->boundedServices.map, (void*)bndId);
-        int rc = sender->serializer->destroySerializerMap(sender->serializer->handle, entry->msgTypes);
-        if (rc != 0) {
-            L_ERROR("Error destroying publisher service, serializer not available / cannot get msg serializer map\n");
-        }
-
-        hash_map_iterator_t iter = hashMapIterator_construct(entry->msgEntries);
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_websocket_send_msg_entry_t *msgEntry = hashMapIterator_nextValue(&iter);
-            free(msgEntry);
-        }
-        hashMap_destroy(entry->msgEntries, false, false);
-
-        hashMap_destroy(entry->msgTypeIds, true, false);
-        free(entry);
-    }
-    celixThreadMutex_unlock(&sender->boundedServices.mutex);
-}
-
-static int psa_websocket_topicPublicationSend(void* handle, unsigned int msgTypeId, const void *inMsg, celix_properties_t *metadata) {
-    int status = CELIX_SERVICE_EXCEPTION;
-    psa_websocket_bounded_service_entry_t *bound = handle;
-    pubsub_websocket_topic_sender_t *sender = bound->parent;
-    psa_websocket_send_msg_entry_t *entry = hashMap_get(bound->msgEntries, (void *) (uintptr_t) (msgTypeId));
-
-    if (sender->sockConnection != NULL && entry != NULL) {
-        delay_first_send_for_late_joiners(sender);
-        size_t serializedOutputLen = 0;
-        struct iovec* serializedOutput = NULL;
-        status = entry->msgSer->serialize(entry->msgSer->handle, inMsg, &serializedOutput, &serializedOutputLen);
-
-        if (status == CELIX_SUCCESS /*ser ok*/) {
-            json_error_t jsError;
-            unsigned char *hdrEncoded = calloc(sizeof(pubsub_websocket_msg_header_t), sizeof(unsigned char));
-
-            celixThreadMutex_lock(&entry->sendLock);
-
-            json_t *jsMsg = json_object();
-            json_object_set_new_nocheck(jsMsg, "id", json_string(entry->header.id));
-            json_object_set_new_nocheck(jsMsg, "major", json_integer(entry->header.major));
-            json_object_set_new_nocheck(jsMsg, "minor", json_integer(entry->header.minor));
-            json_object_set_new_nocheck(jsMsg, "seqNr", json_integer(entry->header.seqNr++));
-
-            json_t *jsData;
-            jsData = json_loadb((const char *)serializedOutput->iov_base, serializedOutput->iov_len, 0, &jsError);
-            if(jsData != NULL) {
-                json_object_set_new_nocheck(jsMsg, "data", jsData);
-                const char *msg = json_dumps(jsMsg, 0);
-                size_t bytes_to_write = strlen(msg);
-                int bytes_written = mg_websocket_write(sender->sockConnection, MG_WEBSOCKET_OPCODE_TEXT, msg,
-                                                              bytes_to_write);
-                free((void *) msg);
-                json_decref(jsData); //Decrease ref count means freeing the object
-                if (bytes_written != (int) bytes_to_write) {
-                    L_WARN("[PSA_WEBSOCKET_TS] Error sending websocket, written %d of total %lu bytes", bytes_written, bytes_to_write);
-                }
-            } else {
-                L_WARN("[PSA_WEBSOCKET_TS] Error sending websocket, serialized data corrupt. Error(%d;%d;%d): %s", jsError.column, jsError.line, jsError.position, jsError.text);
-            }
-            celixThreadMutex_unlock(&entry->sendLock);
-
-            json_decref(jsMsg); //Decrease ref count means freeing the object
-            free(hdrEncoded);
-            entry->msgSer->freeSerializeMsg(entry->msgSer->handle, serializedOutput, serializedOutputLen);
-        } else {
-            L_WARN("[PSA_WEBSOCKET_TS] Error serialize message of type %s for scope/topic %s/%s",
-                   entry->msgSer->msgName, sender->scope == NULL ? "(null)" : sender->scope, sender->topic);
-        }
-    } else if (entry == NULL){
-        L_WARN("[PSA_WEBSOCKET_TS] Error sending message with msg type id %i for scope/topic %s/%s", msgTypeId, sender->scope == NULL ? "(null)" : sender->scope, sender->topic);
-    } else { // when (sender->sockConnection == NULL) we dont have a client, but we do have a valid entry
-    	status = CELIX_SUCCESS; // Not an error, just nothing to do
-    }
-
-    return status;
-}
-
-static void psa_websocketTopicSender_ready(struct mg_connection *connection, void *handle) {
-    //Connection succeeded so save connection to use for sending the messages
-    pubsub_websocket_topic_sender_t *sender = (pubsub_websocket_topic_sender_t *) handle;
-    sender->sockConnection = connection;
-}
-
-static void psa_websocketTopicSender_close(const struct mg_connection *connection __attribute__((unused)), void *handle) {
-    //Connection closed so reset connection
-    pubsub_websocket_topic_sender_t *sender = (pubsub_websocket_topic_sender_t *) handle;
-    sender->sockConnection = NULL;
-}
-
-static void delay_first_send_for_late_joiners(pubsub_websocket_topic_sender_t *sender) {
-
-    static bool firstSend = true;
-
-    if (firstSend) {
-        L_INFO("PSA_WEBSOCKET_TP: Delaying first send for late joiners...\n");
-        sleep(FIRST_SEND_DELAY_IN_SECONDS);
-        firstSend = false;
-    }
-}
diff --git a/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_topic_sender.h b/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_topic_sender.h
deleted file mode 100644
index 7a839d1..0000000
--- a/bundles/pubsub/pubsub_admin_websocket/v1/src/pubsub_websocket_topic_sender.h
+++ /dev/null
@@ -1,43 +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 CELIX_PUBSUB_WEBSOCKET_TOPIC_SENDER_H
-#define CELIX_PUBSUB_WEBSOCKET_TOPIC_SENDER_H
-
-#include "celix_bundle_context.h"
-#include "pubsub_admin_metrics.h"
-
-typedef struct pubsub_websocket_topic_sender pubsub_websocket_topic_sender_t;
-
-pubsub_websocket_topic_sender_t* pubsub_websocketTopicSender_create(
-        celix_bundle_context_t *ctx,
-        celix_log_helper_t *logHelper,
-        const char *scope,
-        const char *topic,
-        long serializerSvcId,
-        pubsub_serializer_service_t *ser);
-void pubsub_websocketTopicSender_destroy(pubsub_websocket_topic_sender_t *sender);
-
-const char* pubsub_websocketTopicSender_scope(pubsub_websocket_topic_sender_t *sender);
-const char* pubsub_websocketTopicSender_topic(pubsub_websocket_topic_sender_t *sender);
-const char* pubsub_websocketTopicSender_url(pubsub_websocket_topic_sender_t *sender);
-
-long pubsub_websocketTopicSender_serializerSvcId(pubsub_websocket_topic_sender_t *sender);
-
-#endif //CELIX_PUBSUB_WEBSOCKET_TOPIC_SENDER_H
diff --git a/bundles/pubsub/pubsub_admin_zmq/v2/CMakeLists.txt b/bundles/pubsub/pubsub_admin_zmq/CMakeLists.txt
similarity index 100%
rename from bundles/pubsub/pubsub_admin_zmq/v2/CMakeLists.txt
rename to bundles/pubsub/pubsub_admin_zmq/CMakeLists.txt
diff --git a/bundles/pubsub/pubsub_admin_zmq/v2/src/psa_activator.c b/bundles/pubsub/pubsub_admin_zmq/src/psa_activator.c
similarity index 100%
rename from bundles/pubsub/pubsub_admin_zmq/v2/src/psa_activator.c
rename to bundles/pubsub/pubsub_admin_zmq/src/psa_activator.c
diff --git a/bundles/pubsub/pubsub_admin_zmq/v2/src/pubsub_psa_zmq_constants.h b/bundles/pubsub/pubsub_admin_zmq/src/pubsub_psa_zmq_constants.h
similarity index 100%
rename from bundles/pubsub/pubsub_admin_zmq/v2/src/pubsub_psa_zmq_constants.h
rename to bundles/pubsub/pubsub_admin_zmq/src/pubsub_psa_zmq_constants.h
diff --git a/bundles/pubsub/pubsub_admin_zmq/v2/src/pubsub_zmq_admin.c b/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_admin.c
similarity index 100%
rename from bundles/pubsub/pubsub_admin_zmq/v2/src/pubsub_zmq_admin.c
rename to bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_admin.c
diff --git a/bundles/pubsub/pubsub_admin_zmq/v2/src/pubsub_zmq_admin.h b/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_admin.h
similarity index 100%
rename from bundles/pubsub/pubsub_admin_zmq/v2/src/pubsub_zmq_admin.h
rename to bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_admin.h
diff --git a/bundles/pubsub/pubsub_admin_zmq/v2/src/pubsub_zmq_topic_receiver.c b/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_receiver.c
similarity index 100%
rename from bundles/pubsub/pubsub_admin_zmq/v2/src/pubsub_zmq_topic_receiver.c
rename to bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_receiver.c
diff --git a/bundles/pubsub/pubsub_admin_zmq/v2/src/pubsub_zmq_topic_receiver.h b/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_receiver.h
similarity index 100%
rename from bundles/pubsub/pubsub_admin_zmq/v2/src/pubsub_zmq_topic_receiver.h
rename to bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_receiver.h
diff --git a/bundles/pubsub/pubsub_admin_zmq/v2/src/pubsub_zmq_topic_sender.c b/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_sender.c
similarity index 100%
rename from bundles/pubsub/pubsub_admin_zmq/v2/src/pubsub_zmq_topic_sender.c
rename to bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_sender.c
diff --git a/bundles/pubsub/pubsub_admin_zmq/v2/src/pubsub_zmq_topic_sender.h b/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_sender.h
similarity index 100%
rename from bundles/pubsub/pubsub_admin_zmq/v2/src/pubsub_zmq_topic_sender.h
rename to bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_sender.h
diff --git a/bundles/pubsub/pubsub_admin_zmq/v2/src/zmq_crypto.c b/bundles/pubsub/pubsub_admin_zmq/src/zmq_crypto.c
similarity index 100%
rename from bundles/pubsub/pubsub_admin_zmq/v2/src/zmq_crypto.c
rename to bundles/pubsub/pubsub_admin_zmq/src/zmq_crypto.c
diff --git a/bundles/pubsub/pubsub_admin_zmq/v2/src/zmq_crypto.h b/bundles/pubsub/pubsub_admin_zmq/src/zmq_crypto.h
similarity index 100%
rename from bundles/pubsub/pubsub_admin_zmq/v2/src/zmq_crypto.h
rename to bundles/pubsub/pubsub_admin_zmq/src/zmq_crypto.h
diff --git a/bundles/pubsub/pubsub_admin_zmq/v1/CMakeLists.txt b/bundles/pubsub/pubsub_admin_zmq/v1/CMakeLists.txt
deleted file mode 100644
index 2427425..0000000
--- a/bundles/pubsub/pubsub_admin_zmq/v1/CMakeLists.txt
+++ /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.
-
-message(STATUS "PubSub ZMQ Admin V1 is deprecated, and will eventually be replaced with PubSub ZMQ Admin v2")
-
-find_package(ZMQ REQUIRED)
-find_package(CZMQ REQUIRED)
-find_package(Jansson REQUIRED)
-find_package(UUID REQUIRED)
-
-set(OPTIONAL_OPENSSL_LIB )
-if (BUILD_ZMQ_SECURITY)
-    add_definitions(-DBUILD_WITH_ZMQ_SECURITY=1)
-
-    find_package(OpenSSL 1.1.0 REQUIRED)
-    include_directories("${OPENSSL_INCLUDE_DIR}")
-    set(OPTIONAL_OPENSSL_LIB OpenSSL::SSL)
-
-    set (ZMQ_CRYPTO_C "src/zmq_crypto.c")
-endif()
-
-add_celix_bundle(celix_pubsub_admin_zmq
-    BUNDLE_SYMBOLICNAME "apache_celix_pubsub_admin_zmq"
-    VERSION "1.1.0"
-    GROUP "Celix/PubSub"
-    SOURCES
-        src/psa_activator.c
-        src/pubsub_zmq_admin.c
-        src/pubsub_zmq_topic_sender.c
-        src/pubsub_zmq_topic_receiver.c
-        ${ZMQ_CRYPTO_C}
-)
-
-set_target_properties(celix_pubsub_admin_zmq PROPERTIES INSTALL_RPATH "$ORIGIN")
-target_link_libraries(celix_pubsub_admin_zmq PRIVATE
-
-        Celix::framework Celix::dfi Celix::log_helper Celix::utils
-        ZMQ::lib CZMQ::lib ${OPTIONAL_OPENSSL_LIB}
-)
-target_link_libraries(celix_pubsub_admin_zmq PRIVATE Celix::pubsub_spi Celix::pubsub_utils )
-target_include_directories(celix_pubsub_admin_zmq PRIVATE
-    src
-)
-
-install_celix_bundle(celix_pubsub_admin_zmq EXPORT celix COMPONENT pubsub)
-target_link_libraries(celix_pubsub_admin_zmq PRIVATE Celix::shell_api)
-add_library(Celix::celix_pubsub_admin_zmq ALIAS celix_pubsub_admin_zmq)
diff --git a/bundles/pubsub/pubsub_admin_zmq/v1/src/psa_activator.c b/bundles/pubsub/pubsub_admin_zmq/v1/src/psa_activator.c
deleted file mode 100644
index cb9dac2..0000000
--- a/bundles/pubsub/pubsub_admin_zmq/v1/src/psa_activator.c
+++ /dev/null
@@ -1,141 +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 <stdlib.h>
-
-#include "celix_api.h"
-#include "pubsub_serializer.h"
-#include "pubsub_protocol.h"
-#include "celix_log_helper.h"
-
-#include "pubsub_admin.h"
-#include "pubsub_admin_metrics.h"
-#include "pubsub_zmq_admin.h"
-#include "celix_shell_command.h"
-
-typedef struct psa_zmq_activator {
-    celix_log_helper_t *logHelper;
-
-    pubsub_zmq_admin_t *admin;
-
-    long serializersTrackerId;
-
-    long protocolsTrackerId;
-
-    pubsub_admin_service_t adminService;
-    long adminSvcId;
-
-    pubsub_admin_metrics_service_t adminMetricsService;
-    long adminMetricsSvcId;
-
-    celix_shell_command_t cmdSvc;
-    long cmdSvcId;
-} psa_zmq_activator_t;
-
-int psa_zmq_start(psa_zmq_activator_t *act, celix_bundle_context_t *ctx) {
-    act->adminSvcId = -1L;
-    act->cmdSvcId = -1L;
-    act->serializersTrackerId = -1L;
-    act->protocolsTrackerId = -1L;
-
-    act->logHelper = celix_logHelper_create(ctx, "celix_psa_zmq");
-
-    act->admin = pubsub_zmqAdmin_create(ctx, act->logHelper);
-    celix_status_t status = act->admin != NULL ? CELIX_SUCCESS : CELIX_BUNDLE_EXCEPTION;
-
-    //track serializers
-    if (status == CELIX_SUCCESS) {
-        celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
-        opts.filter.serviceName = PUBSUB_SERIALIZER_SERVICE_NAME;
-        opts.filter.ignoreServiceLanguage = true;
-        opts.callbackHandle = act->admin;
-        opts.addWithProperties = pubsub_zmqAdmin_addSerializerSvc;
-        opts.removeWithProperties = pubsub_zmqAdmin_removeSerializerSvc;
-        act->serializersTrackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
-    }
-
-    //track protocols
-    if (status == CELIX_SUCCESS) {
-        celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
-        opts.filter.serviceName = PUBSUB_PROTOCOL_SERVICE_NAME;
-        opts.filter.ignoreServiceLanguage = true;
-        opts.callbackHandle = act->admin;
-        opts.addWithProperties = pubsub_zmqAdmin_addProtocolSvc;
-        opts.removeWithProperties = pubsub_zmqAdmin_removeProtocolSvc;
-        act->protocolsTrackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
-    }
-
-    //register pubsub admin service
-    if (status == CELIX_SUCCESS) {
-        pubsub_admin_service_t *psaSvc = &act->adminService;
-        psaSvc->handle = act->admin;
-        psaSvc->matchPublisher = pubsub_zmqAdmin_matchPublisher;
-        psaSvc->matchSubscriber = pubsub_zmqAdmin_matchSubscriber;
-        psaSvc->matchDiscoveredEndpoint = pubsub_zmqAdmin_matchDiscoveredEndpoint;
-        psaSvc->setupTopicSender = pubsub_zmqAdmin_setupTopicSender;
-        psaSvc->teardownTopicSender = pubsub_zmqAdmin_teardownTopicSender;
-        psaSvc->setupTopicReceiver = pubsub_zmqAdmin_setupTopicReceiver;
-        psaSvc->teardownTopicReceiver = pubsub_zmqAdmin_teardownTopicReceiver;
-        psaSvc->addDiscoveredEndpoint = pubsub_zmqAdmin_addDiscoveredEndpoint;
-        psaSvc->removeDiscoveredEndpoint = pubsub_zmqAdmin_removeDiscoveredEndpoint;
-
-        celix_properties_t *props = celix_properties_create();
-        celix_properties_set(props, PUBSUB_ADMIN_SERVICE_TYPE, PUBSUB_ZMQ_ADMIN_TYPE);
-
-        act->adminSvcId = celix_bundleContext_registerService(ctx, psaSvc, PUBSUB_ADMIN_SERVICE_NAME, props);
-    }
-
-    if (status == CELIX_SUCCESS) {
-        act->adminMetricsService.handle = act->admin;
-        act->adminMetricsService.metrics = pubsub_zmqAdmin_metrics;
-
-        celix_properties_t *props = celix_properties_create();
-        celix_properties_set(props, PUBSUB_ADMIN_SERVICE_TYPE, PUBSUB_ZMQ_ADMIN_TYPE);
-
-        act->adminMetricsSvcId = celix_bundleContext_registerService(ctx, &act->adminMetricsService, PUBSUB_ADMIN_METRICS_SERVICE_NAME, props);
-    }
-
-    //register shell command service
-    {
-        act->cmdSvc.handle = act->admin;
-        act->cmdSvc.executeCommand = pubsub_zmqAdmin_executeCommand;
-        celix_properties_t *props = celix_properties_create();
-        celix_properties_set(props, CELIX_SHELL_COMMAND_NAME, "celix::psa_zmq");
-        celix_properties_set(props, CELIX_SHELL_COMMAND_USAGE, "psa_zmq");
-        celix_properties_set(props, CELIX_SHELL_COMMAND_DESCRIPTION, "Print the information about the TopicSender and TopicReceivers for the ZMQ PSA");
-        act->cmdSvcId = celix_bundleContext_registerService(ctx, &act->cmdSvc, CELIX_SHELL_COMMAND_SERVICE_NAME, props);
-    }
-
-    return status;
-}
-
-int psa_zmq_stop(psa_zmq_activator_t *act, celix_bundle_context_t *ctx) {
-    celix_bundleContext_unregisterService(ctx, act->adminSvcId);
-    celix_bundleContext_unregisterService(ctx, act->cmdSvcId);
-    celix_bundleContext_unregisterService(ctx, act->adminMetricsSvcId);
-    celix_bundleContext_stopTracker(ctx, act->serializersTrackerId);
-    celix_bundleContext_stopTracker(ctx, act->protocolsTrackerId);
-    pubsub_zmqAdmin_destroy(act->admin);
-
-    celix_logHelper_destroy(act->logHelper);
-
-    return CELIX_SUCCESS;
-}
-
-CELIX_GEN_BUNDLE_ACTIVATOR(psa_zmq_activator_t, psa_zmq_start, psa_zmq_stop);
diff --git a/bundles/pubsub/pubsub_admin_zmq/v1/src/pubsub_psa_zmq_constants.h b/bundles/pubsub/pubsub_admin_zmq/v1/src/pubsub_psa_zmq_constants.h
deleted file mode 100644
index c50006a..0000000
--- a/bundles/pubsub/pubsub_admin_zmq/v1/src/pubsub_psa_zmq_constants.h
+++ /dev/null
@@ -1,112 +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_PSA_ZMQ_CONSTANTS_H_
-#define PUBSUB_PSA_ZMQ_CONSTANTS_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 PSA_ZMQ_DEFAULT_QOS_SAMPLE_SCORE        30
-#define PSA_ZMQ_DEFAULT_QOS_CONTROL_SCORE       70
-#define PSA_ZMQ_DEFAULT_SCORE                   30
-
-#define PSA_ZMQ_QOS_SAMPLE_SCORE_KEY            "PSA_ZMQ_QOS_SAMPLE_SCORE"
-#define PSA_ZMQ_QOS_CONTROL_SCORE_KEY           "PSA_ZMQ_QOS_CONTROL_SCORE"
-#define PSA_ZMQ_DEFAULT_SCORE_KEY               "PSA_ZMQ_DEFAULT_SCORE"
-
-
-#define PSA_ZMQ_METRICS_ENABLED "PSA_ZMQ_METRICS_ENABLED"
-#define PSA_ZMQ_DEFAULT_METRICS_ENABLED true
-
-#define PSA_ZMQ_ZEROCOPY_ENABLED "PSA_ZMQ_ZEROCOPY_ENABLED"
-#define PSA_ZMQ_DEFAULT_ZEROCOPY_ENABLED false
-
-
-#define PUBSUB_ZMQ_VERBOSE_KEY      "PSA_ZMQ_VERBOSE"
-#define PUBSUB_ZMQ_VERBOSE_DEFAULT  true
-
-#define PUBSUB_ZMQ_PSA_IP_KEY       "PSA_IP"
-#define PUBSUB_ZMQ_PSA_ITF_KEY      "PSA_INTERFACE"
-#define PUBSUB_ZMQ_NR_THREADS_KEY   "PSA_ZMQ_NR_THREADS"
-
-#define PUBSUB_ZMQ_DEFAULT_IP       "127.0.0.1"
-
-#define PUBSUB_ZMQ_ADMIN_TYPE       "zmq"
-
-/**
- * The ZMQ url key for the topic sender endpoints
- */
-#define PUBSUB_ZMQ_URL_KEY          "zmq.url"
-
-
-
-/**
- * Can be set in the topic properties to fix a static bind url
- */
-#define PUBSUB_ZMQ_STATIC_BIND_URL       "zmq.static.bind.url"
-
-/**
- * Name of environment variable with ip/url to bind to
- * e.g. PSA_ZMQ_STATIC_BIND_FOR_topic_scope="ipc:///tmp/pubsub-pingtest"
- */
-#define PUBSUB_ZMQ_STATIC_BIND_URL_FOR "PSA_ZMQ_STATIC_BIND_URL_FOR_"
-
-/**
- * Can be set in the topic properties to fix a static url used for discovery
- */
-#define PUBSUB_ZMQ_STATIC_DISCOVER_URL       "zmq.static.bind.url"
-
-/**
- * If set true on the endpoint, the zmq TopicSender bind and/or discovery url is statically configured.
- */
-#define PUBSUB_ZMQ_STATIC_CONFIGURED       "zmq.static.configured"
-
-/**
- * The static url which a subscriber should try to connect to.
- * The urls are space separated.
- * Can be set in the topic properties.
- */
-#define PUBSUB_ZMQ_STATIC_CONNECT_URLS    "zmq.static.connect.urls"
-
-/**
- * Name of environment variable with space-separated list of ips/urls to connect to
- * e.g. PSA_ZMQ_STATIC_CONNECT_FOR_topic_scope="ipc:///tmp/pubsub-pingtest ipc:///tmp/pubsub-pongtest"
- */
-#define PUBSUB_ZMQ_STATIC_CONNECT_URLS_FOR "PSA_ZMQ_STATIC_CONNECT_URL_FOR_"
-
-/**
- * Realtime thread prio and scheduling information. This is used to setup the thread prio/sched of the
- * internal ZMQ threads.
- * Can be set in the topic properties.
- */
-#define PUBSUB_ZMQ_THREAD_REALTIME_PRIO    "thread.realtime.prio"
-#define PUBSUB_ZMQ_THREAD_REALTIME_SCHED   "thread.realtime.sched"
-
-/**
- * High Water Mark option. See ZMQ doc for more information
- * Note expected type is longs
- */
-#define PUBSUB_ZMQ_HWM                      "zmq.hwm"
-
-#endif /* PUBSUB_PSA_ZMQ_CONSTANTS_H_ */
diff --git a/bundles/pubsub/pubsub_admin_zmq/v1/src/pubsub_zmq_admin.c b/bundles/pubsub/pubsub_admin_zmq/v1/src/pubsub_zmq_admin.c
deleted file mode 100644
index 09c7ae5..0000000
--- a/bundles/pubsub/pubsub_admin_zmq/v1/src/pubsub_zmq_admin.c
+++ /dev/null
@@ -1,885 +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 <memory.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <ifaddrs.h>
-#include <pubsub_endpoint.h>
-#include <czmq.h>
-#include <pubsub_serializer.h>
-#include <pubsub_protocol.h>
-#include <ip_utils.h>
-
-#include "pubsub_utils.h"
-#include "pubsub_zmq_admin.h"
-#include "pubsub_psa_zmq_constants.h"
-#include "pubsub_zmq_topic_sender.h"
-#include "pubsub_zmq_topic_receiver.h"
-
-#define L_DEBUG(...) \
-    celix_logHelper_log(psa->log, CELIX_LOG_LEVEL_DEBUG, __VA_ARGS__)
-#define L_INFO(...) \
-    celix_logHelper_log(psa->log, CELIX_LOG_LEVEL_INFO, __VA_ARGS__)
-#define L_WARN(...) \
-    celix_logHelper_log(psa->log, CELIX_LOG_LEVEL_WARNING, __VA_ARGS__)
-#define L_ERROR(...) \
-    celix_logHelper_log(psa->log, CELIX_LOG_LEVEL_ERROR, __VA_ARGS__)
-
-struct pubsub_zmq_admin {
-    celix_bundle_context_t *ctx;
-    celix_log_helper_t *log;
-    const char *fwUUID;
-
-    char *ipAddress;
-    zactor_t *zmq_auth;
-
-    unsigned int basePort;
-    unsigned int maxPort;
-
-    double qosSampleScore;
-    double qosControlScore;
-    double defaultScore;
-
-    bool verbose;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = svcId, value = psa_zmq_serializer_entry_t*
-    } serializers;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = svcId, value = psa_zmq_protocol_entry_t*
-    } protocols;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = scope:topic key, value = pubsub_zmq_topic_sender_t*
-    } topicSenders;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = scope:topic key, value = pubsub_zmq_topic_sender_t*
-    } topicReceivers;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = endpoint uuid, value = celix_properties_t* (endpoint)
-    } discoveredEndpoints;
-
-};
-
-typedef struct psa_zmq_serializer_entry {
-    const char *serType;
-    long svcId;
-    pubsub_serializer_service_t *svc;
-} psa_zmq_serializer_entry_t;
-
-typedef struct psa_zmq_protocol_entry {
-    const char *protType;
-    long svcId;
-    pubsub_protocol_service_t *svc;
-} psa_zmq_protocol_entry_t;
-
-static celix_status_t zmq_getIpAddress(const char* interface, char** ip);
-static celix_status_t pubsub_zmqAdmin_connectEndpointToReceiver(pubsub_zmq_admin_t* psa, pubsub_zmq_topic_receiver_t *receiver, const celix_properties_t *endpoint);
-static celix_status_t pubsub_zmqAdmin_disconnectEndpointFromReceiver(pubsub_zmq_admin_t* psa, pubsub_zmq_topic_receiver_t *receiver, const celix_properties_t *endpoint);
-
-static bool pubsub_zmqAdmin_endpointIsPublisher(const celix_properties_t *endpoint) {
-    const char *type = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TYPE, NULL);
-    return type != NULL && strncmp(PUBSUB_PUBLISHER_ENDPOINT_TYPE, type, strlen(PUBSUB_PUBLISHER_ENDPOINT_TYPE)) == 0;
-}
-
-pubsub_zmq_admin_t* pubsub_zmqAdmin_create(celix_bundle_context_t *ctx, celix_log_helper_t *logHelper) {
-    pubsub_zmq_admin_t *psa = calloc(1, sizeof(*psa));
-    psa->ctx = ctx;
-    psa->log = logHelper;
-    psa->verbose = celix_bundleContext_getPropertyAsBool(ctx, PUBSUB_ZMQ_VERBOSE_KEY, PUBSUB_ZMQ_VERBOSE_DEFAULT);
-    psa->fwUUID = celix_bundleContext_getProperty(ctx, OSGI_FRAMEWORK_FRAMEWORK_UUID, NULL);
-
-    char *ip = NULL;
-    const char *confIp = celix_bundleContext_getProperty(ctx, PUBSUB_ZMQ_PSA_IP_KEY , NULL);
-    if (confIp != NULL) {
-        if (strchr(confIp, '/') != NULL) {
-            // IP with subnet prefix specified
-            ip = ipUtils_findIpBySubnet(confIp);
-            if (ip == NULL) {
-                L_WARN("[PSA_ZMQ] Could not find interface for requested subnet %s", confIp);
-            }
-        } else {
-            // IP address specified
-            ip = strndup(confIp, 1024);
-        }
-    }
-
-    if (ip == NULL) {
-        //try to get ip from itf
-        const char *interface = celix_bundleContext_getProperty(ctx, PUBSUB_ZMQ_PSA_ITF_KEY, NULL);
-        zmq_getIpAddress(interface, &ip);
-    }
-
-    if (ip == NULL) {
-        L_WARN("[PSA_ZMQ] Could not determine IP address for PSA, using default ip (%s)", PUBSUB_ZMQ_DEFAULT_IP);
-        ip = strndup(PUBSUB_ZMQ_DEFAULT_IP, 1024);
-    }
-
-    psa->ipAddress = ip;
-    if (psa->verbose) {
-        L_INFO("[PSA_ZMQ] Using %s for service annunciation", ip);
-    }
-
-
-    long basePort = celix_bundleContext_getPropertyAsLong(ctx, PSA_ZMQ_BASE_PORT, PSA_ZMQ_DEFAULT_BASE_PORT);
-    long maxPort = celix_bundleContext_getPropertyAsLong(ctx, PSA_ZMQ_MAX_PORT, PSA_ZMQ_DEFAULT_MAX_PORT);
-    psa->basePort = (unsigned int)basePort;
-    psa->maxPort = (unsigned int)maxPort;
-    if (psa->verbose) {
-        L_INFO("[PSA_ZMQ] Using base till max port: %i till %i", psa->basePort, psa->maxPort);
-    }
-
-    // Disable Signal Handling by CZMQ
-    setenv("ZSYS_SIGHANDLER", "false", true);
-
-    long nrThreads = celix_bundleContext_getPropertyAsLong(ctx, PUBSUB_ZMQ_NR_THREADS_KEY, 0);
-    if (nrThreads > 0) {
-        zsys_set_io_threads((size_t)nrThreads);
-        L_INFO("[PSA_ZMQ] Using %d threads for ZMQ", (size_t)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
-
-    psa->defaultScore = celix_bundleContext_getPropertyAsDouble(ctx, PSA_ZMQ_DEFAULT_SCORE_KEY, PSA_ZMQ_DEFAULT_SCORE);
-    psa->qosSampleScore = celix_bundleContext_getPropertyAsDouble(ctx, PSA_ZMQ_QOS_SAMPLE_SCORE_KEY, PSA_ZMQ_DEFAULT_QOS_SAMPLE_SCORE);
-    psa->qosControlScore = celix_bundleContext_getPropertyAsDouble(ctx, PSA_ZMQ_QOS_CONTROL_SCORE_KEY, PSA_ZMQ_DEFAULT_QOS_CONTROL_SCORE);
-
-    celixThreadMutex_create(&psa->serializers.mutex, NULL);
-    psa->serializers.map = hashMap_create(NULL, NULL, NULL, NULL);
-
-    celixThreadMutex_create(&psa->protocols.mutex, NULL);
-    psa->protocols.map = hashMap_create(NULL, NULL, NULL, NULL);
-
-    celixThreadMutex_create(&psa->topicSenders.mutex, NULL);
-    psa->topicSenders.map = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
-    celixThreadMutex_create(&psa->topicReceivers.mutex, NULL);
-    psa->topicReceivers.map = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
-    celixThreadMutex_create(&psa->discoveredEndpoints.mutex, NULL);
-    psa->discoveredEndpoints.map = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
-    return psa;
-}
-
-void pubsub_zmqAdmin_destroy(pubsub_zmq_admin_t *psa) {
-    if (psa == NULL) {
-        return;
-    }
-
-    //note assuming al psa register services and service tracker are removed.
-
-    celixThreadMutex_lock(&psa->topicSenders.mutex);
-    hash_map_iterator_t iter = hashMapIterator_construct(psa->topicSenders.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        pubsub_zmq_topic_sender_t *sender = hashMapIterator_nextValue(&iter);
-        pubsub_zmqTopicSender_destroy(sender);
-    }
-    celixThreadMutex_unlock(&psa->topicSenders.mutex);
-
-    celixThreadMutex_lock(&psa->topicReceivers.mutex);
-    iter = hashMapIterator_construct(psa->topicReceivers.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        pubsub_zmq_topic_receiver_t *recv = hashMapIterator_nextValue(&iter);
-        pubsub_zmqTopicReceiver_destroy(recv);
-    }
-    celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-
-    celixThreadMutex_lock(&psa->discoveredEndpoints.mutex);
-    iter = hashMapIterator_construct(psa->discoveredEndpoints.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        celix_properties_t *ep = hashMapIterator_nextValue(&iter);
-        celix_properties_destroy(ep);
-    }
-    celixThreadMutex_unlock(&psa->discoveredEndpoints.mutex);
-
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    iter = hashMapIterator_construct(psa->serializers.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        psa_zmq_serializer_entry_t *entry = hashMapIterator_nextValue(&iter);
-        free(entry);
-    }
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-
-    celixThreadMutex_lock(&psa->protocols.mutex);
-    iter = hashMapIterator_construct(psa->protocols.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        psa_zmq_protocol_entry_t *entry = hashMapIterator_nextValue(&iter);
-        free(entry);
-    }
-    celixThreadMutex_unlock(&psa->protocols.mutex);
-
-    celixThreadMutex_destroy(&psa->topicSenders.mutex);
-    hashMap_destroy(psa->topicSenders.map, true, false);
-
-    celixThreadMutex_destroy(&psa->topicReceivers.mutex);
-    hashMap_destroy(psa->topicReceivers.map, true, false);
-
-    celixThreadMutex_destroy(&psa->discoveredEndpoints.mutex);
-    hashMap_destroy(psa->discoveredEndpoints.map, false, false);
-
-    celixThreadMutex_destroy(&psa->serializers.mutex);
-    hashMap_destroy(psa->serializers.map, false, false);
-
-    celixThreadMutex_destroy(&psa->protocols.mutex);
-    hashMap_destroy(psa->protocols.map, false, false);
-
-    if (psa->zmq_auth != NULL) {
-        zactor_destroy(&psa->zmq_auth);
-    }
-
-    free(psa->ipAddress);
-
-    free(psa);
-}
-
-void pubsub_zmqAdmin_addSerializerSvc(void *handle, void *svc, const celix_properties_t *props) {
-    pubsub_zmq_admin_t *psa = handle;
-
-    const char *serType = celix_properties_get(props, PUBSUB_SERIALIZER_TYPE_KEY, NULL);
-    long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
-
-    if (serType == NULL) {
-        L_INFO("[PSA_ZMQ] Ignoring serializer service without %s property", PUBSUB_SERIALIZER_TYPE_KEY);
-        return;
-    }
-
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    psa_zmq_serializer_entry_t *entry = hashMap_get(psa->serializers.map, (void*)svcId);
-    if (entry == NULL) {
-        entry = calloc(1, sizeof(*entry));
-        entry->serType = serType;
-        entry->svcId = svcId;
-        entry->svc = svc;
-        hashMap_put(psa->serializers.map, (void*)svcId, entry);
-    }
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-}
-
-void pubsub_zmqAdmin_removeSerializerSvc(void *handle, void *svc, const celix_properties_t *props) {
-    pubsub_zmq_admin_t *psa = handle;
-    long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
-
-    //remove serializer
-    // 1) First find entry and
-    // 2) loop and destroy all topic sender using the serializer and
-    // 3) loop and destroy all topic receivers using the serializer
-    // Note that it is the responsibility of the topology manager to create new topic senders/receivers
-
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    psa_zmq_serializer_entry_t *entry = hashMap_remove(psa->serializers.map, (void*)svcId);
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-
-    if (entry != NULL) {
-        celixThreadMutex_lock(&psa->topicSenders.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(psa->topicSenders.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            hash_map_entry_t *senderEntry = hashMapIterator_nextEntry(&iter);
-            pubsub_zmq_topic_sender_t *sender = hashMapEntry_getValue(senderEntry);
-            if (sender != NULL && entry->svcId == pubsub_zmqTopicSender_serializerSvcId(sender)) {
-                char *key = hashMapEntry_getKey(senderEntry);
-                hashMapIterator_remove(&iter);
-                pubsub_zmqTopicSender_destroy(sender);
-                free(key);
-            }
-        }
-        celixThreadMutex_unlock(&psa->topicSenders.mutex);
-
-        celixThreadMutex_lock(&psa->topicReceivers.mutex);
-        iter = hashMapIterator_construct(psa->topicReceivers.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            hash_map_entry_t *senderEntry = hashMapIterator_nextEntry(&iter);
-            pubsub_zmq_topic_receiver_t *receiver = hashMapEntry_getValue(senderEntry);
-            if (receiver != NULL && entry->svcId == pubsub_zmqTopicReceiver_serializerSvcId(receiver)) {
-                char *key = hashMapEntry_getKey(senderEntry);
-                hashMapIterator_remove(&iter);
-                pubsub_zmqTopicReceiver_destroy(receiver);
-                free(key);
-            }
-        }
-        celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-
-        free(entry);
-    }
-}
-
-void pubsub_zmqAdmin_addProtocolSvc(void *handle, void *svc, const celix_properties_t *props) {
-    pubsub_zmq_admin_t *psa = handle;
-
-    const char *protType = celix_properties_get(props, PUBSUB_PROTOCOL_TYPE_KEY, NULL);
-    long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
-
-    if (protType == NULL) {
-        L_INFO("[PSA_ZMQ] Ignoring protocol service without %s property", PUBSUB_PROTOCOL_TYPE_KEY);
-        return;
-    }
-
-    celixThreadMutex_lock(&psa->protocols.mutex);
-    psa_zmq_protocol_entry_t *entry = hashMap_get(psa->protocols.map, (void*)svcId);
-    if (entry == NULL) {
-        entry = calloc(1, sizeof(*entry));
-        entry->protType = protType;
-        entry->svcId = svcId;
-        entry->svc = svc;
-        hashMap_put(psa->protocols.map, (void*)svcId, entry);
-    }
-    celixThreadMutex_unlock(&psa->protocols.mutex);
-}
-
-void pubsub_zmqAdmin_removeProtocolSvc(void *handle, void *svc, const celix_properties_t *props) {
-    pubsub_zmq_admin_t *psa = handle;
-    long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
-
-    //remove protocol
-    // 1) First find entry and
-    // 2) loop and destroy all topic sender using the protocol and
-    // 3) loop and destroy all topic receivers using the protocol
-    // Note that it is the responsibility of the topology manager to create new topic senders/receivers
-
-    celixThreadMutex_lock(&psa->protocols.mutex);
-    psa_zmq_protocol_entry_t *entry = hashMap_remove(psa->protocols.map, (void*)svcId);
-    celixThreadMutex_unlock(&psa->protocols.mutex);
-
-    if (entry != NULL) {
-        celixThreadMutex_lock(&psa->topicSenders.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(psa->topicSenders.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            hash_map_entry_t *senderEntry = hashMapIterator_nextEntry(&iter);
-            pubsub_zmq_topic_sender_t *sender = hashMapEntry_getValue(senderEntry);
-            if (sender != NULL && entry->svcId == pubsub_zmqTopicSender_protocolSvcId(sender)) {
-                char *key = hashMapEntry_getKey(senderEntry);
-                hashMapIterator_remove(&iter);
-                pubsub_zmqTopicSender_destroy(sender);
-                free(key);
-            }
-        }
-        celixThreadMutex_unlock(&psa->topicSenders.mutex);
-
-        celixThreadMutex_lock(&psa->topicReceivers.mutex);
-        iter = hashMapIterator_construct(psa->topicReceivers.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            hash_map_entry_t *senderEntry = hashMapIterator_nextEntry(&iter);
-            pubsub_zmq_topic_receiver_t *receiver = hashMapEntry_getValue(senderEntry);
-            if (receiver != NULL && entry->svcId == pubsub_zmqTopicReceiver_protocolSvcId(receiver)) {
-                char *key = hashMapEntry_getKey(senderEntry);
-                hashMapIterator_remove(&iter);
-                pubsub_zmqTopicReceiver_destroy(receiver);
-                free(key);
-            }
-        }
-        celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-
-        free(entry);
-    }
-}
-
-celix_status_t pubsub_zmqAdmin_matchPublisher(void *handle, long svcRequesterBndId, const celix_filter_t *svcFilter, celix_properties_t **topicProperties, double *outScore, long *outSerializerSvcId, long *outProtocolSvcId) {
-    pubsub_zmq_admin_t *psa = handle;
-    L_DEBUG("[PSA_ZMQ] pubsub_zmqAdmin_matchPublisher");
-    celix_status_t  status = CELIX_SUCCESS;
-    double score = pubsubEndpoint_matchPublisher(psa->ctx, svcRequesterBndId, svcFilter->filterStr, PUBSUB_ZMQ_ADMIN_TYPE,
-                                                psa->qosSampleScore, psa->qosControlScore, psa->defaultScore, true, topicProperties, outSerializerSvcId, outProtocolSvcId);
-    *outScore = score;
-
-    return status;
-}
-
-celix_status_t pubsub_zmqAdmin_matchSubscriber(void *handle, long svcProviderBndId, const celix_properties_t *svcProperties, celix_properties_t **topicProperties, double *outScore, long *outSerializerSvcId, long *outProtocolSvcId) {
-    pubsub_zmq_admin_t *psa = handle;
-    L_DEBUG("[PSA_ZMQ] pubsub_zmqAdmin_matchSubscriber");
-    celix_status_t  status = CELIX_SUCCESS;
-    double score = pubsubEndpoint_matchSubscriber(psa->ctx, svcProviderBndId, svcProperties, PUBSUB_ZMQ_ADMIN_TYPE,
-            psa->qosSampleScore, psa->qosControlScore, psa->defaultScore, true, topicProperties, outSerializerSvcId, outProtocolSvcId);
-    if (outScore != NULL) {
-        *outScore = score;
-    }
-    return status;
-}
-
-celix_status_t pubsub_zmqAdmin_matchDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint, bool *outMatch) {
-    pubsub_zmq_admin_t *psa = handle;
-    L_DEBUG("[PSA_ZMQ] pubsub_zmqAdmin_matchEndpoint");
-    celix_status_t  status = CELIX_SUCCESS;
-    bool match = pubsubEndpoint_match(psa->ctx, psa->log, endpoint, PUBSUB_ZMQ_ADMIN_TYPE, true, NULL, NULL);
-    if (outMatch != NULL) {
-        *outMatch = match;
-    }
-    return status;
-}
-
-celix_status_t pubsub_zmqAdmin_setupTopicSender(void *handle, const char *scope, const char *topic, const celix_properties_t *topicProperties, long serializerSvcId, long protocolSvcId, celix_properties_t **outPublisherEndpoint) {
-    pubsub_zmq_admin_t *psa = handle;
-    celix_status_t  status = CELIX_SUCCESS;
-
-    //1) Create TopicSender
-    //2) Store TopicSender
-    //3) Connect existing endpoints
-    //4) set outPublisherEndpoint
-
-    celix_properties_t *newEndpoint = NULL;
-
-    const char *staticBindUrl = pubsub_getEnvironmentVariableWithScopeTopic(psa->ctx, PUBSUB_ZMQ_STATIC_BIND_URL_FOR, topic, scope);
-    if(staticBindUrl == NULL && topicProperties != NULL) {
-        staticBindUrl = celix_properties_get(topicProperties, PUBSUB_ZMQ_STATIC_BIND_URL, NULL);
-    }
-    char *key = pubsubEndpoint_createScopeTopicKey(scope, topic);
-
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    celixThreadMutex_lock(&psa->protocols.mutex);
-    celixThreadMutex_lock(&psa->topicSenders.mutex);
-    pubsub_zmq_topic_sender_t *sender = hashMap_get(psa->topicSenders.map, key);
-    if (sender == NULL) {
-        psa_zmq_serializer_entry_t *serEntry = hashMap_get(psa->serializers.map, (void*)serializerSvcId);
-        psa_zmq_protocol_entry_t *protEntry = hashMap_get(psa->protocols.map, (void*)protocolSvcId);
-        if (serEntry != NULL && protEntry != NULL) {
-            sender = pubsub_zmqTopicSender_create(psa->ctx, psa->log, scope, topic, serializerSvcId, serEntry->svc,
-                    protocolSvcId, protEntry->svc, psa->ipAddress, staticBindUrl, psa->basePort, psa->maxPort);
-        }
-        if (sender != NULL) {
-            const char *psaType = PUBSUB_ZMQ_ADMIN_TYPE;
-            const char *serType = serEntry->serType;
-            const char *protType = protEntry->protType;
-            newEndpoint = pubsubEndpoint_create(psa->fwUUID, scope, topic, PUBSUB_PUBLISHER_ENDPOINT_TYPE, psaType,
-                                                serType, protType, NULL);
-            celix_properties_set(newEndpoint, PUBSUB_ZMQ_URL_KEY, pubsub_zmqTopicSender_url(sender));
-
-            //if configured use a static discover url
-            const char *staticDiscUrl = celix_properties_get(topicProperties, PUBSUB_ZMQ_STATIC_DISCOVER_URL, NULL);
-            if (staticDiscUrl != NULL) {
-                celix_properties_set(newEndpoint, PUBSUB_ZMQ_URL_KEY, staticDiscUrl);
-            }
-            celix_properties_setBool(newEndpoint, PUBSUB_ZMQ_STATIC_CONFIGURED, staticBindUrl != NULL || staticDiscUrl != NULL);
-
-            //if url starts with ipc:// constrain discovery to host visibility, else use system visibility
-            const char *u = celix_properties_get(newEndpoint, PUBSUB_ZMQ_URL_KEY, "");
-            if (strncmp("ipc://", u, strlen("ipc://")) == 0) {
-                celix_properties_set(newEndpoint, PUBSUB_ENDPOINT_VISIBILITY, PUBSUB_ENDPOINT_HOST_VISIBILITY);
-            } else {
-                celix_properties_set(newEndpoint, PUBSUB_ENDPOINT_VISIBILITY, PUBSUB_ENDPOINT_SYSTEM_VISIBILITY);
-            }
-
-            //if available also set container name
-            const char *cn = celix_bundleContext_getProperty(psa->ctx, "CELIX_CONTAINER_NAME", NULL);
-            if (cn != NULL) {
-                celix_properties_set(newEndpoint, "container_name", cn);
-            }
-            hashMap_put(psa->topicSenders.map, key, sender);
-        } else {
-            L_ERROR("[PSA ZMQ] Error creating a TopicSender");
-            free(key);
-        }
-    } else {
-        free(key);
-        L_ERROR("[PSA_ZMQ] Cannot setup already existing TopicSender for scope/topic %s/%s!", scope == NULL ? "(null)" : scope, topic);
-    }
-    celixThreadMutex_unlock(&psa->topicSenders.mutex);
-    celixThreadMutex_unlock(&psa->protocols.mutex);
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-
-    if (sender != NULL && newEndpoint != NULL) {
-        //TODO connect endpoints to sender, NOTE is this needed for a zmq topic sender?
-    }
-
-    if (newEndpoint != NULL && outPublisherEndpoint != NULL) {
-        *outPublisherEndpoint = newEndpoint;
-    }
-
-    return status;
-}
-
-celix_status_t pubsub_zmqAdmin_teardownTopicSender(void *handle, const char *scope, const char *topic) {
-    pubsub_zmq_admin_t *psa = handle;
-    celix_status_t  status = CELIX_SUCCESS;
-
-    //1) Find and remove TopicSender from map
-    //2) destroy topic sender
-
-    char *key = pubsubEndpoint_createScopeTopicKey(scope, topic);
-    celixThreadMutex_lock(&psa->topicSenders.mutex);
-    hash_map_entry_t *entry = hashMap_getEntry(psa->topicSenders.map, key);
-    if (entry != NULL) {
-        char *mapKey = hashMapEntry_getKey(entry);
-        pubsub_zmq_topic_sender_t *sender = hashMap_remove(psa->topicSenders.map, key);
-        free(mapKey);
-        //TODO disconnect endpoints to sender. note is this needed for a zmq topic sender?
-        pubsub_zmqTopicSender_destroy(sender);
-    } else {
-        L_ERROR("[PSA ZMQ] Cannot teardown TopicSender with scope/topic %s/%s. Does not exists", scope == NULL ? "(null)" : scope, topic);
-    }
-    celixThreadMutex_unlock(&psa->topicSenders.mutex);
-    free(key);
-
-    return status;
-}
-
-celix_status_t pubsub_zmqAdmin_setupTopicReceiver(void *handle, const char *scope, const char *topic, const celix_properties_t *topicProperties, long serializerSvcId, long protocolSvcId, celix_properties_t **outSubscriberEndpoint) {
-    pubsub_zmq_admin_t *psa = handle;
-
-    celix_properties_t *newEndpoint = NULL;
-
-    char *key = pubsubEndpoint_createScopeTopicKey(scope, topic);
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    celixThreadMutex_lock(&psa->protocols.mutex);
-    celixThreadMutex_lock(&psa->topicReceivers.mutex);
-    pubsub_zmq_topic_receiver_t *receiver = hashMap_get(psa->topicReceivers.map, key);
-    if (receiver == NULL) {
-        psa_zmq_serializer_entry_t *serEntry = hashMap_get(psa->serializers.map, (void*)serializerSvcId);
-        psa_zmq_protocol_entry_t *protEntry = hashMap_get(psa->protocols.map, (void*)protocolSvcId);
-        if (serEntry != NULL && protEntry != NULL) {
-            receiver = pubsub_zmqTopicReceiver_create(psa->ctx, psa->log, scope, topic, topicProperties, serializerSvcId, serEntry->svc, protocolSvcId, protEntry->svc);
-        } else {
-            L_ERROR("[PSA_ZMQ] Cannot find serializer or protocol for TopicSender %s/%s", scope == NULL ? "(null)" : scope, topic);
-        }
-        if (receiver != NULL) {
-            const char *psaType = PUBSUB_ZMQ_ADMIN_TYPE;
-            const char *serType = serEntry->serType;
-            const char *protType = protEntry->protType;
-            newEndpoint = pubsubEndpoint_create(psa->fwUUID, scope, topic,
-                                                PUBSUB_SUBSCRIBER_ENDPOINT_TYPE, psaType, serType, protType, NULL);
-            //if available also set container name
-            const char *cn = celix_bundleContext_getProperty(psa->ctx, "CELIX_CONTAINER_NAME", NULL);
-            if (cn != NULL) {
-                celix_properties_set(newEndpoint, "container_name", cn);
-            }
-            hashMap_put(psa->topicReceivers.map, key, receiver);
-        } else {
-            L_ERROR("[PSA ZMQ] Error creating a TopicReceiver.");
-            free(key);
-        }
-    } else {
-        free(key);
-        L_ERROR("[PSA_ZMQ] Cannot setup already existing TopicReceiver for scope/topic %s/%s!", scope == NULL ? "(null)" : scope, topic);
-    }
-    celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-    celixThreadMutex_unlock(&psa->protocols.mutex);
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-
-    if (receiver != NULL && newEndpoint != NULL) {
-        celixThreadMutex_lock(&psa->discoveredEndpoints.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(psa->discoveredEndpoints.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            celix_properties_t *endpoint = hashMapIterator_nextValue(&iter);
-            if (pubsub_zmqAdmin_endpointIsPublisher(endpoint) && pubsubEndpoint_matchWithTopicAndScope(endpoint, topic, scope)) {
-                pubsub_zmqAdmin_connectEndpointToReceiver(psa, receiver, endpoint);
-            }
-        }
-        celixThreadMutex_unlock(&psa->discoveredEndpoints.mutex);
-    }
-
-    if (newEndpoint != NULL && outSubscriberEndpoint != NULL) {
-        *outSubscriberEndpoint = newEndpoint;
-    }
-
-    celix_status_t  status = CELIX_SUCCESS;
-    return status;
-}
-
-celix_status_t pubsub_zmqAdmin_teardownTopicReceiver(void *handle, const char *scope, const char *topic) {
-    pubsub_zmq_admin_t *psa = handle;
-
-    char *key = pubsubEndpoint_createScopeTopicKey(scope, topic);
-    celixThreadMutex_lock(&psa->topicReceivers.mutex);
-    hash_map_entry_t *entry = hashMap_getEntry(psa->topicReceivers.map, key);
-    free(key);
-    if (entry != NULL) {
-        char *receiverKey = hashMapEntry_getKey(entry);
-        pubsub_zmq_topic_receiver_t *receiver = hashMapEntry_getValue(entry);
-        hashMap_remove(psa->topicReceivers.map, receiverKey);
-
-        free(receiverKey);
-        pubsub_zmqTopicReceiver_destroy(receiver);
-    }
-    celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-
-    celix_status_t  status = CELIX_SUCCESS;
-    return status;
-}
-
-static celix_status_t pubsub_zmqAdmin_connectEndpointToReceiver(pubsub_zmq_admin_t* psa, pubsub_zmq_topic_receiver_t *receiver, const celix_properties_t *endpoint) {
-    //note can be called with discoveredEndpoint.mutex lock
-    celix_status_t status = CELIX_SUCCESS;
-
-    const char *url = celix_properties_get(endpoint, PUBSUB_ZMQ_URL_KEY, NULL);
-
-    if (url == NULL) {
-        const char *admin = celix_properties_get(endpoint, PUBSUB_ENDPOINT_ADMIN_TYPE, NULL);
-        const char *type = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TYPE, NULL);
-        L_WARN("[PSA ZMQ] Error got endpoint without a zmq url (admin: %s, type: %s)", admin , type);
-        status = CELIX_BUNDLE_EXCEPTION;
-    } else {
-        pubsub_zmqTopicReceiver_connectTo(receiver, url);
-    }
-
-    return status;
-}
-
-celix_status_t pubsub_zmqAdmin_addDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint) {
-    pubsub_zmq_admin_t *psa = handle;
-
-    if (pubsub_zmqAdmin_endpointIsPublisher(endpoint)) {
-        celixThreadMutex_lock(&psa->topicReceivers.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(psa->topicReceivers.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            pubsub_zmq_topic_receiver_t *receiver = hashMapIterator_nextValue(&iter);
-            if (pubsubEndpoint_matchWithTopicAndScope(endpoint, pubsub_zmqTopicReceiver_topic(receiver), pubsub_zmqTopicReceiver_scope(receiver))) {
-                pubsub_zmqAdmin_connectEndpointToReceiver(psa, receiver, endpoint);
-            }
-        }
-        celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-    }
-
-    celixThreadMutex_lock(&psa->discoveredEndpoints.mutex);
-    celix_properties_t *cpy = celix_properties_copy(endpoint);
-    const char *uuid = celix_properties_get(cpy, PUBSUB_ENDPOINT_UUID, NULL);
-    hashMap_put(psa->discoveredEndpoints.map, (void*)uuid, cpy);
-    celixThreadMutex_unlock(&psa->discoveredEndpoints.mutex);
-
-    celix_status_t  status = CELIX_SUCCESS;
-    return status;
-}
-
-
-static celix_status_t pubsub_zmqAdmin_disconnectEndpointFromReceiver(pubsub_zmq_admin_t* psa, pubsub_zmq_topic_receiver_t *receiver, const celix_properties_t *endpoint) {
-    //note can be called with discoveredEndpoint.mutex lock
-    celix_status_t status = CELIX_SUCCESS;
-
-    const char *url = celix_properties_get(endpoint, PUBSUB_ZMQ_URL_KEY, NULL);
-
-    if (url == NULL) {
-        L_WARN("[PSA ZMQ] Error got endpoint without zmq url");
-        status = CELIX_BUNDLE_EXCEPTION;
-    } else {
-        pubsub_zmqTopicReceiver_disconnectFrom(receiver, url);
-    }
-
-    return status;
-}
-
-celix_status_t pubsub_zmqAdmin_removeDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint) {
-    pubsub_zmq_admin_t *psa = handle;
-
-    if (pubsub_zmqAdmin_endpointIsPublisher(endpoint)) {
-        celixThreadMutex_lock(&psa->topicReceivers.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(psa->topicReceivers.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            pubsub_zmq_topic_receiver_t *receiver = hashMapIterator_nextValue(&iter);
-            pubsub_zmqAdmin_disconnectEndpointFromReceiver(psa, receiver, endpoint);
-        }
-        celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-    }
-
-    celixThreadMutex_lock(&psa->discoveredEndpoints.mutex);
-    const char *uuid = celix_properties_get(endpoint, PUBSUB_ENDPOINT_UUID, NULL);
-    celix_properties_t *found = hashMap_remove(psa->discoveredEndpoints.map, (void*)uuid);
-    celixThreadMutex_unlock(&psa->discoveredEndpoints.mutex);
-
-    if (found != NULL) {
-        celix_properties_destroy(found);
-    }
-
-    celix_status_t  status = CELIX_SUCCESS;
-    return status;
-}
-
-bool pubsub_zmqAdmin_executeCommand(void *handle, const char *commandLine, FILE *out, FILE *errStream __attribute__((unused))) {
-    pubsub_zmq_admin_t *psa = handle;
-    celix_status_t  status = CELIX_SUCCESS;
-
-
-    char *line = celix_utils_strdup(commandLine);
-    char *token = line;
-    strtok_r(line, " ", &token); //first token is command name
-    strtok_r(NULL, " ", &token); //second token is sub command
-
-    if (celix_utils_stringEquals(token, "nr_of_receivers")) {
-        celixThreadMutex_lock(&psa->topicReceivers.mutex);
-        fprintf(out,"%i\n", hashMap_size(psa->topicReceivers.map));
-        celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-    }
-    if (celix_utils_stringEquals(token, "nr_of_senders")) {
-        celixThreadMutex_lock(&psa->topicSenders.mutex);
-        fprintf(out, "%i\n", hashMap_size(psa->topicSenders.map));
-        celixThreadMutex_unlock(&psa->topicSenders.mutex);
-    }
-
-    fprintf(out, "\n");
-    fprintf(out, "Topic Senders:\n");
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    celixThreadMutex_lock(&psa->protocols.mutex);
-    celixThreadMutex_lock(&psa->topicSenders.mutex);
-    hash_map_iterator_t iter = hashMapIterator_construct(psa->topicSenders.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        pubsub_zmq_topic_sender_t *sender = hashMapIterator_nextValue(&iter);
-
-        long serSvcId = pubsub_zmqTopicSender_serializerSvcId(sender);
-        psa_zmq_serializer_entry_t *serEntry = hashMap_get(psa->serializers.map, (void*)serSvcId);
-
-        long protSvcId = pubsub_zmqTopicSender_protocolSvcId(sender);
-        psa_zmq_protocol_entry_t *protEntry = hashMap_get(psa->protocols.map, (void*)protSvcId);
-
-        const char *serType = serEntry == NULL ? "!Error!" : serEntry->serType;
-        const char *protType = protEntry == NULL ? "!Error!" : protEntry->protType;
-        const char *scope = pubsub_zmqTopicSender_scope(sender);
-        const char *topic = pubsub_zmqTopicSender_topic(sender);
-        const char *url = pubsub_zmqTopicSender_url(sender);
-        const char *postUrl = pubsub_zmqTopicSender_isStatic(sender) ? " (static)" : "";
-        fprintf(out, "|- Topic Sender %s/%s\n", scope == NULL ? "(null)" : scope, topic);
-        fprintf(out, "   |- serializer type = %s\n", serType);
-        fprintf(out, "   |- protocol type = %s\n", protType);
-        fprintf(out, "   |- url            = %s%s\n", url, postUrl);
-    }
-    celixThreadMutex_unlock(&psa->topicSenders.mutex);
-    celixThreadMutex_unlock(&psa->protocols.mutex);
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-
-    fprintf(out, "\n");
-    fprintf(out, "\nTopic Receivers:\n");
-    celixThreadMutex_lock(&psa->serializers.mutex);
-    celixThreadMutex_lock(&psa->protocols.mutex);
-    celixThreadMutex_lock(&psa->topicReceivers.mutex);
-    iter = hashMapIterator_construct(psa->topicReceivers.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        pubsub_zmq_topic_receiver_t *receiver = hashMapIterator_nextValue(&iter);
-        long serSvcId = pubsub_zmqTopicReceiver_serializerSvcId(receiver);
-        psa_zmq_serializer_entry_t *serEntry = hashMap_get(psa->serializers.map, (void*)serSvcId);
-
-        long protSvcId = pubsub_zmqTopicReceiver_protocolSvcId(receiver);
-        psa_zmq_protocol_entry_t *protEntry = hashMap_get(psa->protocols.map, (void*)protSvcId);
-
-
-        const char *serType = serEntry == NULL ? "!Error!" : serEntry->serType;
-        const char *protType = protEntry == NULL ? "!Error!" : protEntry->protType;
-        const char *scope = pubsub_zmqTopicReceiver_scope(receiver);
-        const char *topic = pubsub_zmqTopicReceiver_topic(receiver);
-
-        celix_array_list_t *connected = celix_arrayList_create();
-        celix_array_list_t *unconnected = celix_arrayList_create();
-        pubsub_zmqTopicReceiver_listConnections(receiver, connected, unconnected);
-
-        fprintf(out, "|- Topic Receiver %s/%s\n", scope == NULL ? "(null)" : scope, topic);
-        fprintf(out, "   |- serializer type = %s\n", serType);
-        fprintf(out, "   |- protocol type = %s\n", protType);
-        for (int i = 0; i < celix_arrayList_size(connected); ++i) {
-            char *url = celix_arrayList_get(connected, i);
-            fprintf(out, "   |- connected url   = %s\n", url);
-            free(url);
-        }
-        for (int i = 0; i < celix_arrayList_size(unconnected); ++i) {
-            char *url = celix_arrayList_get(unconnected, i);
-            fprintf(out, "   |- unconnected url = %s\n", url);
-            free(url);
-        }
-        celix_arrayList_destroy(connected);
-        celix_arrayList_destroy(unconnected);
-    }
-    celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-    celixThreadMutex_unlock(&psa->protocols.mutex);
-    celixThreadMutex_unlock(&psa->serializers.mutex);
-    fprintf(out, "\n");
-    free(line);
-
-    return status;
-}
-
-pubsub_admin_metrics_t* pubsub_zmqAdmin_metrics(void *handle) {
-    pubsub_zmq_admin_t *psa = handle;
-    pubsub_admin_metrics_t *result = calloc(1, sizeof(*result));
-    snprintf(result->psaType, PUBSUB_AMDIN_METRICS_NAME_MAX, "%s", PUBSUB_ZMQ_ADMIN_TYPE);
-    result->senders = celix_arrayList_create();
-    result->receivers = celix_arrayList_create();
-
-    celixThreadMutex_lock(&psa->topicSenders.mutex);
-    hash_map_iterator_t iter = hashMapIterator_construct(psa->topicSenders.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        pubsub_zmq_topic_sender_t *sender = hashMapIterator_nextValue(&iter);
-        pubsub_admin_sender_metrics_t *metrics = pubsub_zmqTopicSender_metrics(sender);
-        celix_arrayList_add(result->senders, metrics);
-    }
-    celixThreadMutex_unlock(&psa->topicSenders.mutex);
-
-    celixThreadMutex_lock(&psa->topicReceivers.mutex);
-    iter = hashMapIterator_construct(psa->topicReceivers.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        pubsub_zmq_topic_receiver_t *receiver = hashMapIterator_nextValue(&iter);
-        pubsub_admin_receiver_metrics_t *metrics = pubsub_zmqTopicReceiver_metrics(receiver);
-        celix_arrayList_add(result->receivers, metrics);
-    }
-    celixThreadMutex_unlock(&psa->topicReceivers.mutex);
-
-    return result;
-}
-
-#ifndef ANDROID
-static celix_status_t zmq_getIpAddress(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
\ No newline at end of file
diff --git a/bundles/pubsub/pubsub_admin_zmq/v1/src/pubsub_zmq_admin.h b/bundles/pubsub/pubsub_admin_zmq/v1/src/pubsub_zmq_admin.h
deleted file mode 100644
index d241f1f..0000000
--- a/bundles/pubsub/pubsub_admin_zmq/v1/src/pubsub_zmq_admin.h
+++ /dev/null
@@ -1,57 +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 CELIX_PUBSUB_ZMQ_ADMIN_H
-#define CELIX_PUBSUB_ZMQ_ADMIN_H
-
-#include <pubsub_admin_metrics.h>
-#include "celix_api.h"
-#include "celix_log_helper.h"
-#include "pubsub_psa_zmq_constants.h"
-
-typedef struct pubsub_zmq_admin pubsub_zmq_admin_t;
-
-pubsub_zmq_admin_t* pubsub_zmqAdmin_create(celix_bundle_context_t *ctx, celix_log_helper_t *logHelper);
-void pubsub_zmqAdmin_destroy(pubsub_zmq_admin_t *psa);
-
-celix_status_t pubsub_zmqAdmin_matchPublisher(void *handle, long svcRequesterBndId, const celix_filter_t *svcFilter, celix_properties_t **topicProperties, double *score, long *serializerSvcId, long *ProtocolSvcId);
-celix_status_t pubsub_zmqAdmin_matchSubscriber(void *handle, long svcProviderBndId, const celix_properties_t *svcProperties, celix_properties_t **topicProperties, double *score, long *serializerSvcId, long *ProtocolSvcId);
-celix_status_t pubsub_zmqAdmin_matchDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint, bool *match);
-
-celix_status_t pubsub_zmqAdmin_setupTopicSender(void *handle, const char *scope, const char *topic, const celix_properties_t* topicProperties, long serializerSvcId, long protocolSvcId, celix_properties_t **publisherEndpoint);
-celix_status_t pubsub_zmqAdmin_teardownTopicSender(void *handle, const char *scope, const char *topic);
-
-celix_status_t pubsub_zmqAdmin_setupTopicReceiver(void *handle, const char *scope, const char *topic, const celix_properties_t* topicProperties, long serializerSvcId, long protocolSvcId, celix_properties_t **subscriberEndpoint);
-celix_status_t pubsub_zmqAdmin_teardownTopicReceiver(void *handle, const char *scope, const char *topic);
-
-celix_status_t pubsub_zmqAdmin_addDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint);
-celix_status_t pubsub_zmqAdmin_removeDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint);
-
-void pubsub_zmqAdmin_addSerializerSvc(void *handle, void *svc, const celix_properties_t *props);
-void pubsub_zmqAdmin_removeSerializerSvc(void *handle, void *svc, const celix_properties_t *props);
-
-void pubsub_zmqAdmin_addProtocolSvc(void *handle, void *svc, const celix_properties_t *props);
-void pubsub_zmqAdmin_removeProtocolSvc(void *handle, void *svc, const celix_properties_t *props);
-
-bool pubsub_zmqAdmin_executeCommand(void *handle, const char *commandLine, FILE *outStream, FILE *errStream);
-
-pubsub_admin_metrics_t* pubsub_zmqAdmin_metrics(void *handle);
-
-#endif //CELIX_PUBSUB_ZMQ_ADMIN_H
-
diff --git a/bundles/pubsub/pubsub_admin_zmq/v1/src/pubsub_zmq_topic_receiver.c b/bundles/pubsub/pubsub_admin_zmq/v1/src/pubsub_zmq_topic_receiver.c
deleted file mode 100644
index 28146af..0000000
--- a/bundles/pubsub/pubsub_admin_zmq/v1/src/pubsub_zmq_topic_receiver.c
+++ /dev/null
@@ -1,855 +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 <pubsub_serializer.h>
-#include <pubsub_protocol.h>
-#include <stdlib.h>
-#include <pubsub/subscriber.h>
-#include <memory.h>
-#include <pubsub_constants.h>
-#if !defined(__APPLE__)
-    #include <sys/epoll.h>
-#endif
-#include <assert.h>
-#include <pubsub_endpoint.h>
-#include <arpa/inet.h>
-#include <czmq.h>
-#include <celix_log_helper.h>
-#include "pubsub_zmq_topic_receiver.h"
-#include "pubsub_psa_zmq_constants.h"
-
-#include <uuid/uuid.h>
-#include <pubsub_admin_metrics.h>
-#include <pubsub_utils.h>
-#include <celix_api.h>
-
-#include "celix_utils_api.h"
-
-#define PSA_ZMQ_RECV_TIMEOUT 1000
-
-#ifndef UUID_STR_LEN
-#define UUID_STR_LEN 37
-#endif
-
-
-#define L_DEBUG(...) \
-    celix_logHelper_log(receiver->logHelper, CELIX_LOG_LEVEL_DEBUG, __VA_ARGS__)
-#define L_INFO(...) \
-    celix_logHelper_log(receiver->logHelper, CELIX_LOG_LEVEL_INFO, __VA_ARGS__)
-#define L_WARN(...) \
-    celix_logHelper_log(receiver->logHelper, CELIX_LOG_LEVEL_WARNING, __VA_ARGS__)
-#define L_ERROR(...) \
-    celix_logHelper_log(receiver->logHelper, CELIX_LOG_LEVEL_ERROR, __VA_ARGS__)
-
-struct pubsub_zmq_topic_receiver {
-    celix_bundle_context_t *ctx;
-    celix_log_helper_t *logHelper;
-    long serializerSvcId;
-    pubsub_serializer_service_t *serializer;
-    long protocolSvcId;
-    pubsub_protocol_service_t *protocol;
-    char *scope;
-    char *topic;
-    bool metricsEnabled;
-
-    void *zmqCtx;
-    void *zmqSock;
-
-    char sync[8];
-
-    struct {
-        celix_thread_t thread;
-        celix_thread_mutex_t mutex;
-        bool running;
-    } recvThread;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = zmq url, value = psa_zmq_requested_connection_entry_t*
-        bool allConnected; //true if all requestedConnectection are connected
-    } requestedConnections;
-
-    long subscriberTrackerId;
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map; //key = bnd id, value = psa_zmq_subscriber_entry_t
-        bool allInitialized;
-    } subscribers;
-};
-
-typedef struct psa_zmq_requested_connection_entry {
-    char *url;
-    bool connected;
-    bool statically; //true if the connection is statically configured through the topic properties.
-} psa_zmq_requested_connection_entry_t;
-
-typedef struct psa_zmq_subscriber_metrics_entry_t {
-    unsigned int msgTypeId;
-    uuid_t origin;
-
-    unsigned long nrOfMessagesReceived;
-    unsigned long nrOfSerializationErrors;
-    struct timespec lastMessageReceived;
-    double averageTimeBetweenMessagesInSeconds;
-    double averageSerializationTimeInSeconds;
-    double averageDelayInSeconds;
-    double maxDelayInSeconds;
-    double minDelayInSeconds;
-    unsigned int lastSeqNr;
-    unsigned long nrOfMissingSeqNumbers;
-} psa_zmq_subscriber_metrics_entry_t;
-
-typedef struct psa_zmq_subscriber_entry {
-    hash_map_t *msgTypes; //map from serializer svc
-    hash_map_t *metrics; //key = msg type id, value = hash_map (key = origin uuid, value = psa_zmq_subscriber_metrics_entry_t*
-    hash_map_t *subscriberServices; //key = servide id, value = pubsub_subscriber_t*
-    bool initialized; //true if the init function is called through the receive thread
-} psa_zmq_subscriber_entry_t;
-
-
-static void pubsub_zmqTopicReceiver_addSubscriber(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *owner);
-static void pubsub_zmqTopicReceiver_removeSubscriber(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *owner);
-static void* psa_zmq_recvThread(void * data);
-static void psa_zmq_connectToAllRequestedConnections(pubsub_zmq_topic_receiver_t *receiver);
-static void psa_zmq_initializeAllSubscribers(pubsub_zmq_topic_receiver_t *receiver);
-static void psa_zmq_setupZmqContext(pubsub_zmq_topic_receiver_t *receiver, const celix_properties_t *topicProperties);
-static void psa_zmq_setupZmqSocket(pubsub_zmq_topic_receiver_t *receiver, const celix_properties_t *topicProperties);
-static bool psa_zmq_checkVersion(version_pt msgVersion, uint16_t major, uint16_t minor);
-
-
-pubsub_zmq_topic_receiver_t* pubsub_zmqTopicReceiver_create(celix_bundle_context_t *ctx,
-                                                              celix_log_helper_t *logHelper,
-                                                              const char *scope,
-                                                              const char *topic,
-                                                              const celix_properties_t *topicProperties,
-                                                              long serializerSvcId,
-                                                              pubsub_serializer_service_t *serializer,
-                                                              long protocolSvcId,
-                                                              pubsub_protocol_service_t *protocol) {
-    pubsub_zmq_topic_receiver_t *receiver = calloc(1, sizeof(*receiver));
-    receiver->ctx = ctx;
-    receiver->logHelper = logHelper;
-    receiver->serializerSvcId = serializerSvcId;
-    receiver->serializer = serializer;
-    receiver->protocolSvcId = protocolSvcId;
-    receiver->protocol = protocol;
-    receiver->scope = scope == NULL ? NULL : strndup(scope, 1024 * 1024);
-    receiver->topic = strndup(topic, 1024 * 1024);
-    receiver->metricsEnabled = celix_bundleContext_getPropertyAsBool(ctx, PSA_ZMQ_METRICS_ENABLED, PSA_ZMQ_DEFAULT_METRICS_ENABLED);
-
-#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
-    receiver->zmqCtx = zmq_ctx_new();
-    if (receiver->zmqCtx != NULL) {
-        psa_zmq_setupZmqContext(receiver, topicProperties);
-        receiver->zmqSock = zmq_socket(receiver->zmqCtx, ZMQ_SUB);
-    } else {
-        //LOG ctx problem
-    }
-    if (receiver->zmqSock != NULL) {
-        psa_zmq_setupZmqSocket(receiver, topicProperties);
-    } else if (receiver->zmqCtx != NULL) {
-        //LOG sock problem
-    }
-
-    if (receiver->zmqSock == NULL) {
-#ifdef BUILD_WITH_ZMQ_SECURITY
-        zcert_destroy(&sub_cert);
-        zcert_destroy(&pub_cert);
-#endif
-    }
-
-
-    if (receiver->zmqSock != NULL) {
-        celixThreadMutex_create(&receiver->subscribers.mutex, NULL);
-        celixThreadMutex_create(&receiver->requestedConnections.mutex, NULL);
-        celixThreadMutex_create(&receiver->recvThread.mutex, NULL);
-
-        receiver->subscribers.map = hashMap_create(NULL, NULL, NULL, NULL);
-        receiver->requestedConnections.map = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-    }
-
-    const char *staticConnectUrls = pubsub_getEnvironmentVariableWithScopeTopic(ctx, PUBSUB_ZMQ_STATIC_CONNECT_URLS_FOR, topic, scope);
-    if(staticConnectUrls == NULL) {
-        staticConnectUrls = celix_properties_get(topicProperties, PUBSUB_ZMQ_STATIC_CONNECT_URLS, NULL);
-    }
-    if (receiver->zmqSock != NULL && staticConnectUrls != NULL) {
-        char *urlsCopy = strndup(staticConnectUrls, 1024*1024);
-        char* url;
-        char* save = urlsCopy;
-
-        while ((url = strtok_r(save, " ", &save))) {
-            psa_zmq_requested_connection_entry_t *entry = calloc(1, sizeof(*entry));
-            entry->statically = true;
-            entry->connected = false;
-            entry->url = strndup(url, 1024*1024);
-            hashMap_put(receiver->requestedConnections.map, entry->url, entry);
-            receiver->requestedConnections.allConnected = false;
-        }
-        free(urlsCopy);
-    }
-
-    //track subscribers
-    if (receiver->zmqSock != NULL ) {
-        int size = snprintf(NULL, 0, "(%s=%s)", PUBSUB_SUBSCRIBER_TOPIC, topic);
-        char buf[size+1];
-        snprintf(buf, (size_t)size+1, "(%s=%s)", PUBSUB_SUBSCRIBER_TOPIC, topic);
-        celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
-        opts.filter.ignoreServiceLanguage = true;
-        opts.filter.serviceName = PUBSUB_SUBSCRIBER_SERVICE_NAME;
-        opts.filter.filter = buf;
-        opts.callbackHandle = receiver;
-        opts.addWithOwner = pubsub_zmqTopicReceiver_addSubscriber;
-        opts.removeWithOwner = pubsub_zmqTopicReceiver_removeSubscriber;
-
-        receiver->subscriberTrackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
-    }
-
-    if (receiver->zmqSock != NULL ) {
-        receiver->recvThread.running = true;
-        celixThread_create(&receiver->recvThread.thread, NULL, psa_zmq_recvThread, receiver);
-        char name[64];
-        snprintf(name, 64, "ZMQ TR %s/%s", scope == NULL ? "(null)" : scope, topic);
-        celixThread_setName(&receiver->recvThread.thread, name);
-    }
-
-    if (receiver->zmqSock == NULL) {
-        if (receiver->scope != NULL) {
-            free(receiver->scope);
-        }
-        free(receiver->topic);
-        free(receiver);
-        receiver = NULL;
-        L_ERROR("[PSA_ZMQ] Cannot create TopicReceiver for %s/%s", scope == NULL ? "(null)" : scope, topic);
-    }
-
-    return receiver;
-}
-
-void pubsub_zmqTopicReceiver_destroy(pubsub_zmq_topic_receiver_t *receiver) {
-    if (receiver != NULL) {
-
-        celixThreadMutex_lock(&receiver->recvThread.mutex);
-        receiver->recvThread.running = false;
-        celixThreadMutex_unlock(&receiver->recvThread.mutex);
-        celixThread_join(receiver->recvThread.thread, NULL);
-
-        celix_bundleContext_stopTracker(receiver->ctx, receiver->subscriberTrackerId);
-
-        celixThreadMutex_lock(&receiver->subscribers.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(receiver->subscribers.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_zmq_subscriber_entry_t *entry = hashMapIterator_nextValue(&iter);
-            if (entry != NULL)  {
-                receiver->serializer->destroySerializerMap(receiver->serializer->handle, entry->msgTypes);
-                hashMap_destroy(entry->subscriberServices, false, false);
-                free(entry);
-            }
-
-            hash_map_iterator_t iter2 = hashMapIterator_construct(entry->metrics);
-            while (hashMapIterator_hasNext(&iter2)) {
-                hash_map_t *origins = hashMapIterator_nextValue(&iter2);
-                hashMap_destroy(origins, true, true);
-            }
-            hashMap_destroy(entry->metrics, false, false);
-        }
-        hashMap_destroy(receiver->subscribers.map, false, false);
-
-
-        celixThreadMutex_unlock(&receiver->subscribers.mutex);
-
-        celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-        iter = hashMapIterator_construct(receiver->requestedConnections.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_zmq_requested_connection_entry_t *entry = hashMapIterator_nextValue(&iter);
-            if (entry != NULL) {
-                free(entry->url);
-                free(entry);
-            }
-        }
-        hashMap_destroy(receiver->requestedConnections.map, false, false);
-        celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-
-        celixThreadMutex_destroy(&receiver->subscribers.mutex);
-        celixThreadMutex_destroy(&receiver->requestedConnections.mutex);
-        celixThreadMutex_destroy(&receiver->recvThread.mutex);
-
-        zmq_close(receiver->zmqSock);
-        zmq_ctx_term(receiver->zmqCtx);
-
-        free(receiver->scope);
-        free(receiver->topic);
-    }
-    free(receiver);
-}
-
-const char* pubsub_zmqTopicReceiver_scope(pubsub_zmq_topic_receiver_t *receiver) {
-    return receiver->scope;
-}
-const char* pubsub_zmqTopicReceiver_topic(pubsub_zmq_topic_receiver_t *receiver) {
-    return receiver->topic;
-}
-
-long pubsub_zmqTopicReceiver_serializerSvcId(pubsub_zmq_topic_receiver_t *receiver) {
-    return receiver->serializerSvcId;
-}
-
-long pubsub_zmqTopicReceiver_protocolSvcId(pubsub_zmq_topic_receiver_t *receiver) {
-    return receiver->protocolSvcId;
-}
-
-void pubsub_zmqTopicReceiver_listConnections(pubsub_zmq_topic_receiver_t *receiver, celix_array_list_t *connectedUrls, celix_array_list_t *unconnectedUrls) {
-    celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-    hash_map_iterator_t iter = hashMapIterator_construct(receiver->requestedConnections.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        psa_zmq_requested_connection_entry_t *entry = hashMapIterator_nextValue(&iter);
-        char *url = NULL;
-        asprintf(&url, "%s%s", entry->url, entry->statically ? " (static)" : "");
-        if (entry->connected) {
-            celix_arrayList_add(connectedUrls, url);
-        } else {
-            celix_arrayList_add(unconnectedUrls, url);
-        }
-    }
-    celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-}
-
-
-void pubsub_zmqTopicReceiver_connectTo(
-        pubsub_zmq_topic_receiver_t *receiver,
-        const char *url) {
-    L_DEBUG("[PSA_ZMQ] TopicReceiver %s/%s connecting to zmq url %s", receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic, url);
-
-    celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-    psa_zmq_requested_connection_entry_t *entry = hashMap_get(receiver->requestedConnections.map, url);
-    if (entry == NULL) {
-        entry = calloc(1, sizeof(*entry));
-        entry->url = strndup(url, 1024*1024);
-        entry->connected = false;
-        entry->statically = false;
-        hashMap_put(receiver->requestedConnections.map, (void*)entry->url, entry);
-        receiver->requestedConnections.allConnected = false;
-    }
-    celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-
-    psa_zmq_connectToAllRequestedConnections(receiver);
-}
-
-void pubsub_zmqTopicReceiver_disconnectFrom(pubsub_zmq_topic_receiver_t *receiver, const char *url) {
-    L_DEBUG("[PSA ZMQ] TopicReceiver %s/%s disconnect from zmq url %s", receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic, url);
-
-    celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-    psa_zmq_requested_connection_entry_t *entry = hashMap_remove(receiver->requestedConnections.map, url);
-    if (entry != NULL && entry->connected) {
-        if (zmq_disconnect(receiver->zmqSock, url) == 0) {
-            entry->connected = false;
-        } else {
-            L_WARN("[PSA_ZMQ] Error disconnecting from zmq url %s. (%s)", url, strerror(errno));
-        }
-    }
-    if (entry != NULL) {
-        free(entry->url);
-        free(entry);
-    }
-    celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-}
-
-static void pubsub_zmqTopicReceiver_addSubscriber(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *bnd) {
-    pubsub_zmq_topic_receiver_t *receiver = handle;
-
-    long bndId = celix_bundle_getId(bnd);
-    long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1);
-    const char *subScope = celix_properties_get(props, PUBSUB_SUBSCRIBER_SCOPE, NULL);
-    if (receiver->scope == NULL) {
-        if (subScope != NULL) {
-            return;
-        }
-    } else if (subScope != NULL) {
-        if (strncmp(subScope, receiver->scope, strlen(receiver->scope)) != 0) {
-            //not the same scope. ignore
-            return;
-        }
-    } else {
-        //receiver scope is not NULL, but subScope is NULL -> ignore
-        return;
-    }
-
-    celixThreadMutex_lock(&receiver->subscribers.mutex);
-    psa_zmq_subscriber_entry_t *entry = hashMap_get(receiver->subscribers.map, (void*)bndId);
-    if (entry != NULL) {
-        hashMap_put(entry->subscriberServices, (void*)svcId, svc);
-    } else {
-        //new create entry
-        entry = calloc(1, sizeof(*entry));
-        entry->subscriberServices = hashMap_create(NULL, NULL, NULL, NULL);
-        entry->initialized = false;
-        hashMap_put(entry->subscriberServices, (void*)svcId, svc);
-
-        int rc = receiver->serializer->createSerializerMap(receiver->serializer->handle, (celix_bundle_t*)bnd, &entry->msgTypes);
-
-        if (rc == 0) {
-            entry->metrics = hashMap_create(NULL, NULL, NULL, NULL);
-            hash_map_iterator_t iter = hashMapIterator_construct(entry->msgTypes);
-            while (hashMapIterator_hasNext(&iter)) {
-                pubsub_msg_serializer_t *msgSer = hashMapIterator_nextValue(&iter);
-                hash_map_t *origins = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-                hashMap_put(entry->metrics, (void*)(uintptr_t)msgSer->msgId, origins);
-            }
-        }
-
-        if (rc == 0) {
-            hashMap_put(receiver->subscribers.map, (void*)bndId, entry);
-        } else {
-            L_ERROR("[PSA_ZMQ] Cannot create msg serializer map for TopicReceiver %s/%s", receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic);
-            free(entry);
-        }
-    }
-    celixThreadMutex_unlock(&receiver->subscribers.mutex);
-}
-
-static void pubsub_zmqTopicReceiver_removeSubscriber(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *bnd) {
-    pubsub_zmq_topic_receiver_t *receiver = handle;
-
-    long bndId = celix_bundle_getId(bnd);
-    long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1);
-
-    celixThreadMutex_lock(&receiver->subscribers.mutex);
-    psa_zmq_subscriber_entry_t *entry = hashMap_get(receiver->subscribers.map, (void*)bndId);
-    if (entry != NULL) {
-        hashMap_remove(entry->subscriberServices, (void*)svcId);
-    }
-    if (entry != NULL && hashMap_size(entry->subscriberServices) == 0) {
-        //remove entry
-        hashMap_remove(receiver->subscribers.map, (void*)bndId);
-        int rc = receiver->serializer->destroySerializerMap(receiver->serializer->handle, entry->msgTypes);
-        if (rc != 0) {
-            L_ERROR("[PSA_ZMQ] Cannot destroy msg serializers map for TopicReceiver %s/%s", receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic);
-        }
-        hash_map_iterator_t iter = hashMapIterator_construct(entry->metrics);
-        while (hashMapIterator_hasNext(&iter)) {
-            hash_map_t *origins = hashMapIterator_nextValue(&iter);
-            hashMap_destroy(origins, true, true);
-        }
-        hashMap_destroy(entry->metrics, false, false);
-        hashMap_destroy(entry->subscriberServices, false, false);
-        free(entry);
-    }
-    celixThreadMutex_unlock(&receiver->subscribers.mutex);
-}
-
-static inline void processMsgForSubscriberEntry(pubsub_zmq_topic_receiver_t *receiver, psa_zmq_subscriber_entry_t* entry, pubsub_protocol_message_t *message, struct timespec *receiveTime) {
-    //NOTE receiver->subscribers.mutex locked
-    pubsub_msg_serializer_t* msgSer = hashMap_get(entry->msgTypes, (void*)(uintptr_t)(message->header.msgId));
-    bool monitor = receiver->metricsEnabled;
-
-    //monitoring
-    struct timespec beginSer;
-    struct timespec endSer;
-    int updateReceiveCount = 0;
-    int updateSerError = 0;
-
-    if (msgSer!= NULL) {
-        void *deserializedMsg = NULL;
-        bool validVersion = psa_zmq_checkVersion(msgSer->msgVersion, message->header.msgMajorVersion, message->header.msgMinorVersion);
-        if (validVersion) {
-            if (monitor) {
-                clock_gettime(CLOCK_REALTIME, &beginSer);
-            }
-            struct iovec deSerializeBuffer;
-            deSerializeBuffer.iov_base = message->payload.payload;
-            deSerializeBuffer.iov_len  = message->payload.length;
-            celix_status_t status = msgSer->deserialize(msgSer->handle, &deSerializeBuffer, 0, &deserializedMsg);
-            if (monitor) {
-                clock_gettime(CLOCK_REALTIME, &endSer);
-            }
-            if (status == CELIX_SUCCESS) {
-                celix_properties_t *metadata = message->metadata.metadata;
-                bool release = true;
-                hash_map_iterator_t iter2 = hashMapIterator_construct(entry->subscriberServices);
-                while (hashMapIterator_hasNext(&iter2)) {
-                    pubsub_subscriber_t *svc = hashMapIterator_nextValue(&iter2);
-                    svc->receive(svc->handle, msgSer->msgName, msgSer->msgId, deserializedMsg, metadata, &release);
-                    if (!release) {
-                        //receive function has taken ownership deserialize again for new message
-                        status = msgSer->deserialize(msgSer->handle, &deSerializeBuffer, 0, &deserializedMsg);
-                        if (status != CELIX_SUCCESS) {
-                            L_WARN("[PSA_ZMQ_TR] Cannot deserialize msg type %s for scope/topic %s/%s", msgSer->msgName, receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic);
-                            break;
-                        }
-                        release = true;
-                    }
-                }
-                if (release) {
-                    msgSer->freeDeserializeMsg(msgSer->handle, deserializedMsg);
-                }
-                updateReceiveCount += 1;
-            } else {
-                updateSerError += 1;
-                L_WARN("[PSA_ZMQ_TR] Cannot deserialize msg type %s for scope/topic %s/%s", msgSer->msgName, receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic);
-            }
-        }
-    } else {
-        L_WARN("[PSA_ZMQ_TR] Cannot find serializer for type id 0x%X", message->header.msgId);
-    }
-}
-
-static inline void processMsg(pubsub_zmq_topic_receiver_t *receiver, pubsub_protocol_message_t *message, struct timespec *receiveTime) {
-    celixThreadMutex_lock(&receiver->subscribers.mutex);
-    hash_map_iterator_t iter = hashMapIterator_construct(receiver->subscribers.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        psa_zmq_subscriber_entry_t *entry = hashMapIterator_nextValue(&iter);
-        if (entry != NULL) {
-            processMsgForSubscriberEntry(receiver, entry, message, receiveTime);
-        }
-    }
-    celixThreadMutex_unlock(&receiver->subscribers.mutex);
-}
-
-static void* psa_zmq_recvThread(void * data) {
-    pubsub_zmq_topic_receiver_t *receiver = data;
-
-    celixThreadMutex_lock(&receiver->recvThread.mutex);
-    bool running = receiver->recvThread.running;
-    celixThreadMutex_unlock(&receiver->recvThread.mutex);
-
-    celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-    bool allConnected = receiver->requestedConnections.allConnected;
-    celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-
-    celixThreadMutex_lock(&receiver->subscribers.mutex);
-    bool allInitialized = receiver->subscribers.allInitialized;
-    celixThreadMutex_unlock(&receiver->subscribers.mutex);
-
-    while (running) {
-        if (!allConnected) {
-            psa_zmq_connectToAllRequestedConnections(receiver);
-        }
-        if (!allInitialized) {
-            psa_zmq_initializeAllSubscribers(receiver);
-        }
-
-        zmsg_t *zmsg = zmsg_recv(receiver->zmqSock);
-        if (zmsg != NULL) {
-            if (zmsg_size(zmsg) < 2) {
-                L_WARN("[PSA_ZMQ_TR] Always expecting at least frames per zmsg (header + payload (+ metadata) (+ footer)), got %i frames", (int)zmsg_size(zmsg));
-            } else {
-                zframe_t *header = zmsg_pop(zmsg); // header
-                zframe_t *payload = NULL;
-                zframe_t *metadata = NULL;
-                zframe_t *footer = NULL;
-
-                pubsub_protocol_message_t message;
-                size_t footerSize = 0;
-                receiver->protocol->getFooterSize(receiver->protocol->handle, &footerSize);
-                receiver->protocol->decodeHeader(receiver->protocol->handle, zframe_data(header), zframe_size(header), &message);
-                if (message.header.payloadSize > 0) {
-                    payload = zmsg_pop(zmsg);
-                    receiver->protocol->decodePayload(receiver->protocol->handle, zframe_data(payload), zframe_size(payload), &message);
-                } else {
-                    message.payload.payload = NULL;
-                    message.payload.length = 0;
-                }
-                if (message.header.metadataSize > 0) {
-                    metadata = zmsg_pop(zmsg);
-                    receiver->protocol->decodeMetadata(receiver->protocol->handle, zframe_data(metadata), zframe_size(metadata), &message);
-                } else {
-                    message.metadata.metadata = NULL;
-                }
-                if (footerSize > 0) {
-                    footer = zmsg_pop(zmsg); // footer
-                    receiver->protocol->decodeFooter(receiver->protocol->handle, zframe_data(footer), zframe_size(footer), &message);
-                }
-                if (header != NULL && payload != NULL) {
-                    struct timespec receiveTime;
-                    clock_gettime(CLOCK_REALTIME, &receiveTime);
-                    processMsg(receiver, &message, &receiveTime);
-                }
-                celix_properties_destroy(message.metadata.metadata);
-                zframe_destroy(&header);
-                zframe_destroy(&payload);
-                zframe_destroy(&metadata);
-                zframe_destroy(&footer);
-            }
-            zmsg_destroy(&zmsg);
-        } else {
-            if (errno == EAGAIN) {
-                //nop
-            } else if (errno == EINTR) {
-                L_DEBUG("[PSA_ZMQ_TR] zmsg_recv interrupted");
-            } else {
-                L_WARN("[PSA_ZMQ_TR] Error receiving zmq message: %s", strerror(errno));
-            }
-        }
-
-        celixThreadMutex_lock(&receiver->recvThread.mutex);
-        running = receiver->recvThread.running;
-        celixThreadMutex_unlock(&receiver->recvThread.mutex);
-
-        celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-        allConnected = receiver->requestedConnections.allConnected;
-        celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-
-        celixThreadMutex_lock(&receiver->subscribers.mutex);
-        allInitialized = receiver->subscribers.allInitialized;
-        celixThreadMutex_unlock(&receiver->subscribers.mutex);
-    } // while
-
-    return NULL;
-}
-
-pubsub_admin_receiver_metrics_t* pubsub_zmqTopicReceiver_metrics(pubsub_zmq_topic_receiver_t *receiver) {
-    pubsub_admin_receiver_metrics_t *result = calloc(1, sizeof(*result));
-    snprintf(result->scope, PUBSUB_AMDIN_METRICS_NAME_MAX, "%s", receiver->scope == NULL ? PUBSUB_DEFAULT_ENDPOINT_SCOPE : receiver->scope);
-    snprintf(result->topic, PUBSUB_AMDIN_METRICS_NAME_MAX, "%s", receiver->topic);
-
-    int msgTypesCount = 0;
-    celixThreadMutex_lock(&receiver->subscribers.mutex);
-    hash_map_iterator_t iter = hashMapIterator_construct(receiver->subscribers.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        psa_zmq_subscriber_entry_t *entry = hashMapIterator_nextValue(&iter);
-        hash_map_iterator_t iter2 = hashMapIterator_construct(entry->metrics);
-        while (hashMapIterator_hasNext(&iter2)) {
-            hashMapIterator_nextValue(&iter2);
-            msgTypesCount += 1;
-        }
-    }
-
-    result->nrOfMsgTypes = (unsigned long)msgTypesCount;
-    result->msgTypes = calloc(msgTypesCount, sizeof(*result->msgTypes));
-    int i = 0;
-    iter = hashMapIterator_construct(receiver->subscribers.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        psa_zmq_subscriber_entry_t *entry = hashMapIterator_nextValue(&iter);
-        hash_map_iterator_t iter2 = hashMapIterator_construct(entry->metrics);
-        while (hashMapIterator_hasNext(&iter2)) {
-            hash_map_t *origins = hashMapIterator_nextValue(&iter2);
-            result->msgTypes[i].origins = calloc((size_t)hashMap_size(origins), sizeof(*(result->msgTypes[i].origins)));
-            result->msgTypes[i].nrOfOrigins = hashMap_size(origins);
-            int k = 0;
-            hash_map_iterator_t iter3 = hashMapIterator_construct(origins);
-            while (hashMapIterator_hasNext(&iter3)) {
-                psa_zmq_subscriber_metrics_entry_t *metrics = hashMapIterator_nextValue(&iter3);
-                result->msgTypes[i].typeId = metrics->msgTypeId;
-                pubsub_msg_serializer_t *msgSer = hashMap_get(entry->msgTypes, (void*)(uintptr_t)metrics->msgTypeId);
-                if (msgSer) {
-                    snprintf(result->msgTypes[i].typeFqn, PUBSUB_AMDIN_METRICS_NAME_MAX, "%s", msgSer->msgName);
-                    uuid_copy(result->msgTypes[i].origins[k].originUUID, metrics->origin);
-                    result->msgTypes[i].origins[k].nrOfMessagesReceived = metrics->nrOfMessagesReceived;
-                    result->msgTypes[i].origins[k].nrOfSerializationErrors = metrics->nrOfSerializationErrors;
-                    result->msgTypes[i].origins[k].averageDelayInSeconds = metrics->averageDelayInSeconds;
-                    result->msgTypes[i].origins[k].maxDelayInSeconds = metrics->maxDelayInSeconds;
-                    result->msgTypes[i].origins[k].minDelayInSeconds = metrics->minDelayInSeconds;
-                    result->msgTypes[i].origins[k].averageTimeBetweenMessagesInSeconds = metrics->averageTimeBetweenMessagesInSeconds;
-                    result->msgTypes[i].origins[k].averageSerializationTimeInSeconds = metrics->averageSerializationTimeInSeconds;
-                    result->msgTypes[i].origins[k].lastMessageReceived = metrics->lastMessageReceived;
-                    result->msgTypes[i].origins[k].nrOfMissingSeqNumbers = metrics->nrOfMissingSeqNumbers;
-
-                    k += 1;
-                } else {
-                    L_WARN("[PSA_ZMQ]: Error cannot find key 0x%X in msg map during metrics collection!\n", metrics->msgTypeId);
-                }
-            }
-            i +=1 ;
-        }
-    }
-
-    celixThreadMutex_unlock(&receiver->subscribers.mutex);
-
-    return result;
-}
-
-
-static void psa_zmq_connectToAllRequestedConnections(pubsub_zmq_topic_receiver_t *receiver) {
-    celixThreadMutex_lock(&receiver->requestedConnections.mutex);
-    if (!receiver->requestedConnections.allConnected) {
-        bool allConnected = true;
-        hash_map_iterator_t iter = hashMapIterator_construct(receiver->requestedConnections.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_zmq_requested_connection_entry_t *entry = hashMapIterator_nextValue(&iter);
-            if (!entry->connected) {
-                if (zmq_connect(receiver->zmqSock, entry->url) == 0) {
-                    entry->connected = true;
-                } else {
-                    L_WARN("[PSA_ZMQ] Error connecting to zmq url %s. (%s)", entry->url, strerror(errno));
-                    allConnected = false;
-                }
-            }
-        }
-        receiver->requestedConnections.allConnected = allConnected;
-    }
-    celixThreadMutex_unlock(&receiver->requestedConnections.mutex);
-}
-
-static void psa_zmq_initializeAllSubscribers(pubsub_zmq_topic_receiver_t *receiver) {
-    celixThreadMutex_lock(&receiver->subscribers.mutex);
-    if (!receiver->subscribers.allInitialized) {
-        bool allInitialized = true;
-        hash_map_iterator_t iter = hashMapIterator_construct(receiver->subscribers.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_zmq_subscriber_entry_t *entry = hashMapIterator_nextValue(&iter);
-            if (!entry->initialized) {
-                hash_map_iterator_t iter2 = hashMapIterator_construct(entry->subscriberServices);
-                while (hashMapIterator_hasNext(&iter2)) {
-                    pubsub_subscriber_t *svc = hashMapIterator_nextValue(&iter2);
-                    int rc = 0;
-                    if (svc != NULL && svc->init != NULL) {
-                        rc = svc->init(svc->handle);
-                    }
-                    if (rc == 0) {
-                        //note now only initialized on first subscriber entries added.
-                        entry->initialized = true;
-                    } else {
-                        L_WARN("Cannot initialize subscriber svc. Got rc %i", rc);
-                        allInitialized = false;
-                    }
-                }
-            }
-        }
-        receiver->subscribers.allInitialized = allInitialized;
-    }
-    celixThreadMutex_unlock(&receiver->subscribers.mutex);
-}
-
-static void psa_zmq_setupZmqContext(pubsub_zmq_topic_receiver_t *receiver, const celix_properties_t *topicProperties) {
-    //NOTE. ZMQ will abort when performing a sched_setscheduler without permission.
-    //As result permission has to be checked first.
-    //TODO update this to use cap_get_pid and cap-get_flag instead of check user is root (note adds dep to -lcap)
-    bool gotPermission = false;
-    if (getuid() == 0) {
-        gotPermission = true;
-    }
-
-
-    long prio = celix_properties_getAsLong(topicProperties, PUBSUB_ZMQ_THREAD_REALTIME_PRIO, -1L);
-    if (prio > 0 && prio < 100) {
-        if (gotPermission) {
-            zmq_ctx_set(receiver->zmqCtx, ZMQ_THREAD_PRIORITY, (int) prio);
-        } else {
-            L_INFO("Skipping configuration of thread prio to %i. No permission\n", (int)prio);
-        }
-    }
-
-    const char *sched = celix_properties_get(topicProperties, PUBSUB_ZMQ_THREAD_REALTIME_SCHED, NULL);
-    if (sched != NULL) {
-        int policy = ZMQ_THREAD_SCHED_POLICY_DFLT;
-        if (strncmp("SCHED_OTHER", sched, 16) == 0) {
-            policy = SCHED_OTHER;
-#if !defined(__APPLE__)
-        } else if (strncmp("SCHED_BATCH", sched, 16) == 0) {
-            policy = SCHED_BATCH;
-        } else if (strncmp("SCHED_IDLE", sched, 16) == 0) {
-            policy = SCHED_IDLE;
-#endif
-        } else if (strncmp("SCHED_FIFO", sched, 16) == 0) {
-            policy = SCHED_FIFO;
-        } else if (strncmp("SCHED_RR", sched, 16) == 0) {
-            policy = SCHED_RR;
-        }
-        if (gotPermission) {
-            zmq_ctx_set(receiver->zmqCtx, ZMQ_THREAD_SCHED_POLICY, policy);
-        } else {
-            L_INFO("Skipping configuration of thread scheduling to %s. No permission\n", sched);
-        }
-    }
-}
-
-static void psa_zmq_setupZmqSocket(pubsub_zmq_topic_receiver_t *receiver, const celix_properties_t *topicProperties) {
-    int timeout = PSA_ZMQ_RECV_TIMEOUT;
-    int res = zmq_setsockopt(receiver->zmqSock, ZMQ_RCVTIMEO, &timeout, sizeof(timeout));
-    if (res) {
-        L_ERROR("[PSA_ZMQ] Cannot set ZMQ socket option ZMQ_RCVTIMEO errno=%d", errno);
-    }
-
-#ifdef ZMQ_HWM
-    long hwmProp = celix_properties_getAsLong(topicProperties, PUBSUB_ZMQ_HWM, -1L);
-    if (hwmProp >= 0) {
-        unsigned long hwm = (unsigned long)hwmProp;
-        zmq_setsockopt(receiver->zmqSock, ZMQ_HWM, &hwm, sizeof(hwm));
-    }
-#endif
-
-#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
-    receiver->protocol->getSyncHeader(receiver->protocol->handle, receiver->sync);
-    zsock_set_subscribe(receiver->zmqSock, receiver->sync);
-
-#ifdef BUILD_WITH_ZMQ_SECURITY
-    ts->zmq_cert = sub_cert;
-    ts->zmq_pub_cert = pub_cert;
-#endif
-}
-
-static bool psa_zmq_checkVersion(version_pt msgVersion, uint16_t major, uint16_t minor) {
-    bool check=false;
-
-    if (major == 0 && minor == 0) {
-        //no check
-        return true;
-    }
-
-    int versionMajor;
-    int versionMinor;
-    if (msgVersion!=NULL) {
-        version_getMajor(msgVersion, &versionMajor);
-        version_getMinor(msgVersion, &versionMinor);
-        if (major==((unsigned char)versionMajor)) { /* Different major means incompatible */
-            check = (minor>=((unsigned char)versionMinor)); /* Compatible only if the provider has a minor equals or greater (means compatible update) */
-        }
-    }
-
-    return check;
-}
diff --git a/bundles/pubsub/pubsub_admin_zmq/v1/src/pubsub_zmq_topic_receiver.h b/bundles/pubsub/pubsub_admin_zmq/v1/src/pubsub_zmq_topic_receiver.h
deleted file mode 100644
index 26330f3..0000000
--- a/bundles/pubsub/pubsub_admin_zmq/v1/src/pubsub_zmq_topic_receiver.h
+++ /dev/null
@@ -1,53 +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 CELIX_PUBSUB_ZMQ_TOPIC_RECEIVER_H
-#define CELIX_PUBSUB_ZMQ_TOPIC_RECEIVER_H
-
-#include <pubsub_admin_metrics.h>
-#include "celix_bundle_context.h"
-
-typedef struct pubsub_zmq_topic_receiver pubsub_zmq_topic_receiver_t;
-
-pubsub_zmq_topic_receiver_t* pubsub_zmqTopicReceiver_create(celix_bundle_context_t *ctx,
-                                                            celix_log_helper_t *logHelper,
-        const char *scope,
-        const char *topic,
-        const celix_properties_t *topicProperties,
-        long serializerSvcId,
-        pubsub_serializer_service_t *serializer,
-        long protocolSvcId,
-        pubsub_protocol_service_t *protocol);
-void pubsub_zmqTopicReceiver_destroy(pubsub_zmq_topic_receiver_t *receiver);
-
-const char* pubsub_zmqTopicReceiver_scope(pubsub_zmq_topic_receiver_t *receiver);
-const char* pubsub_zmqTopicReceiver_topic(pubsub_zmq_topic_receiver_t *receiver);
-
-long pubsub_zmqTopicReceiver_serializerSvcId(pubsub_zmq_topic_receiver_t *receiver);
-long pubsub_zmqTopicReceiver_protocolSvcId(pubsub_zmq_topic_receiver_t *receiver);
-void pubsub_zmqTopicReceiver_listConnections(pubsub_zmq_topic_receiver_t *receiver, celix_array_list_t *connectedUrls, celix_array_list_t *unconnectedUrls);
-
-void pubsub_zmqTopicReceiver_connectTo(pubsub_zmq_topic_receiver_t *receiver, const char *url);
-void pubsub_zmqTopicReceiver_disconnectFrom(pubsub_zmq_topic_receiver_t *receiver, const char *url);
-
-
-pubsub_admin_receiver_metrics_t* pubsub_zmqTopicReceiver_metrics(pubsub_zmq_topic_receiver_t *receiver);
-
-
-#endif //CELIX_PUBSUB_ZMQ_TOPIC_RECEIVER_H
diff --git a/bundles/pubsub/pubsub_admin_zmq/v1/src/pubsub_zmq_topic_sender.c b/bundles/pubsub/pubsub_admin_zmq/v1/src/pubsub_zmq_topic_sender.c
deleted file mode 100644
index 19c4660..0000000
--- a/bundles/pubsub/pubsub_admin_zmq/v1/src/pubsub_zmq_topic_sender.c
+++ /dev/null
@@ -1,748 +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 <pubsub_serializer.h>
-#include <pubsub_protocol.h>
-#include <stdlib.h>
-#include <memory.h>
-#include <pubsub_constants.h>
-#include <pubsub/publisher.h>
-#include <utils.h>
-#include <zconf.h>
-#include <arpa/inet.h>
-#include <czmq.h>
-#include <celix_log_helper.h>
-#include "pubsub_zmq_topic_sender.h"
-#include "pubsub_psa_zmq_constants.h"
-#include <uuid/uuid.h>
-#include "celix_constants.h"
-
-#define FIRST_SEND_DELAY_IN_SECONDS             2
-#define ZMQ_BIND_MAX_RETRY                      10
-
-#define L_DEBUG(...) \
-    celix_logHelper_log(sender->logHelper, CELIX_LOG_LEVEL_DEBUG, __VA_ARGS__)
-#define L_INFO(...) \
-    celix_logHelper_log(sender->logHelper, CELIX_LOG_LEVEL_INFO, __VA_ARGS__)
-#define L_WARN(...) \
-    celix_logHelper_log(sender->logHelper, CELIX_LOG_LEVEL_WARNING, __VA_ARGS__)
-#define L_ERROR(...) \
-    celix_logHelper_log(sender->logHelper, CELIX_LOG_LEVEL_ERROR, __VA_ARGS__)
-
-struct pubsub_zmq_topic_sender {
-    celix_bundle_context_t *ctx;
-    celix_log_helper_t *logHelper;
-    long serializerSvcId;
-    pubsub_serializer_service_t *serializer;
-    long protocolSvcId;
-    pubsub_protocol_service_t *protocol;
-    uuid_t fwUUID;
-    bool metricsEnabled;
-    bool zeroCopyEnabled;
-
-    char *scope;
-    char *topic;
-    char *url;
-    bool isStatic;
-
-    struct {
-        zsock_t *socket;
-        zcert_t *cert;
-    } zmq;
-
-    struct {
-        long svcId;
-        celix_service_factory_t factory;
-    } publisher;
-
-    struct {
-        celix_thread_mutex_t mutex;
-        hash_map_t *map;  //key = bndId, value = psa_zmq_bounded_service_entry_t
-    } boundedServices;
-};
-
-typedef struct psa_zmq_send_msg_entry {
-    uint32_t type; //msg type id (hash of fqn)
-    uint8_t major;
-    uint8_t minor;
-    unsigned char originUUID[16];
-    pubsub_msg_serializer_t *msgSer;
-    pubsub_protocol_service_t *protSer;
-    unsigned int seqNr;
-    void *headerBuffer;
-    size_t headerBufferSize;
-    void *metadataBuffer;
-    size_t metadataBufferSize;
-    void *footerBuffer;
-    size_t footerBufferSize;
-    bool dataLocked; // protected ZMQ functions and seqNr
-    struct {
-        celix_thread_mutex_t mutex; //protects entries in struct
-        unsigned long nrOfMessagesSend;
-        unsigned long nrOfMessagesSendFailed;
-        unsigned long nrOfSerializationErrors;
-        struct timespec lastMessageSend;
-        double averageTimeBetweenMessagesInSeconds;
-        double averageSerializationTimeInSeconds;
-    } metrics;
-} psa_zmq_send_msg_entry_t;
-
-typedef struct psa_zmq_bounded_service_entry {
-    pubsub_zmq_topic_sender_t *parent;
-    pubsub_publisher_t service;
-    long bndId;
-    hash_map_t *msgTypes; //key = msg type id, value = pubsub_msg_serializer_t
-    hash_map_t *msgTypeIds; //key = msg name, value = msg type id
-    hash_map_t *msgEntries; //key = msg type id, value = psa_zmq_send_msg_entry_t
-    int getCount;
-} psa_zmq_bounded_service_entry_t;
-
-typedef struct psa_zmq_zerocopy_free_entry {
-    pubsub_msg_serializer_t *msgSer;
-    struct iovec *serializedOutput;
-    size_t serializedOutputLen;
-} psa_zmq_zerocopy_free_entry;
-
-
-static void* psa_zmq_getPublisherService(void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties);
-static void psa_zmq_ungetPublisherService(void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties);
-static unsigned int rand_range(unsigned int min, unsigned int max);
-static void delay_first_send_for_late_joiners(pubsub_zmq_topic_sender_t *sender);
-
-static int psa_zmq_topicPublicationSend(void* handle, unsigned int msgTypeId, const void *msg, celix_properties_t *metadata);
-
-pubsub_zmq_topic_sender_t* pubsub_zmqTopicSender_create(
-        celix_bundle_context_t *ctx,
-        celix_log_helper_t *logHelper,
-        const char *scope,
-        const char *topic,
-        long serializerSvcId,
-        pubsub_serializer_service_t *ser,
-        long protocolSvcId,
-        pubsub_protocol_service_t *prot,
-        const char *bindIP,
-        const char *staticBindUrl,
-        unsigned int basePort,
-        unsigned int maxPort) {
-    pubsub_zmq_topic_sender_t *sender = calloc(1, sizeof(*sender));
-    sender->ctx = ctx;
-    sender->logHelper = logHelper;
-    sender->serializerSvcId = serializerSvcId;
-    sender->serializer = ser;
-    sender->protocolSvcId = protocolSvcId;
-    sender->protocol = prot;
-    const char* uuid = celix_bundleContext_getProperty(ctx, OSGI_FRAMEWORK_FRAMEWORK_UUID, NULL);
-    if (uuid != NULL) {
-        uuid_parse(uuid, sender->fwUUID);
-    }
-    sender->metricsEnabled = celix_bundleContext_getPropertyAsBool(ctx, PSA_ZMQ_METRICS_ENABLED, PSA_ZMQ_DEFAULT_METRICS_ENABLED);
-    sender->zeroCopyEnabled = celix_bundleContext_getPropertyAsBool(ctx, PSA_ZMQ_ZEROCOPY_ENABLED, PSA_ZMQ_DEFAULT_ZEROCOPY_ENABLED);
-
-    //setting up zmq socket for ZMQ TopicSender
-    {
-#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* zmqSocket = zsock_new(ZMQ_PUB);
-        if (zmqSocket==NULL) {
-#ifdef BUILD_WITH_ZMQ_SECURITY
-            if (pubEP->is_secure) {
-                zcert_destroy(&pub_cert);
-            }
-#endif
-            perror("Error for zmq_socket");
-        }
-#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
-
-        if (zmqSocket != NULL && staticBindUrl != NULL) {
-            int rv = zsock_bind (zmqSocket, "%s", staticBindUrl);
-            if (rv == -1) {
-                L_WARN("Error for zmq_bind using static bind url '%s'. %s", staticBindUrl, strerror(errno));
-            } else {
-                sender->url = strndup(staticBindUrl, 1024*1024);
-                sender->isStatic = true;
-            }
-        } else if (zmqSocket != NULL) {
-
-            int retry = 0;
-            while (sender->url == NULL && retry < ZMQ_BIND_MAX_RETRY) {
-                /* Randomized part due to same bundle publishing on different topics */
-                unsigned int port = rand_range(basePort, maxPort);
-
-                char *url = NULL;
-                asprintf(&url, "tcp://%s:%u", bindIP, port);
-
-                char *bindUrl = NULL;
-                asprintf(&bindUrl, "tcp://0.0.0.0:%u", port);
-
-
-                int rv = zsock_bind(zmqSocket, "%s", bindUrl);
-                if (rv == -1) {
-                    L_WARN("Error for zmq_bind using dynamic bind url '%s'. %s", bindUrl, strerror(errno));
-                    free(url);
-                } else {
-                    sender->url = url;
-                }
-                retry++;
-                free(bindUrl);
-            }
-        }
-
-        if (sender->url == NULL)  {
-            zsock_destroy(&zmqSocket);
-        } else {
-            sender->zmq.socket = zmqSocket;
-        }
-    }
-
-    if (sender->url != NULL) {
-        sender->scope = scope == NULL ? NULL : strndup(scope, 1024 * 1024);
-        sender->topic = strndup(topic, 1024 * 1024);
-
-        celixThreadMutex_create(&sender->boundedServices.mutex, NULL);
-        sender->boundedServices.map = hashMap_create(NULL, NULL, NULL, NULL);
-    }
-
-    //register publisher services using a service factory
-    if (sender->url != NULL) {
-        sender->publisher.factory.handle = sender;
-        sender->publisher.factory.getService = psa_zmq_getPublisherService;
-        sender->publisher.factory.ungetService = psa_zmq_ungetPublisherService;
-
-        celix_properties_t *props = celix_properties_create();
-        celix_properties_set(props, PUBSUB_PUBLISHER_TOPIC, sender->topic);
-        if (sender->scope != NULL) {
-            celix_properties_set(props, PUBSUB_PUBLISHER_SCOPE, sender->scope);
-        }
-
-        celix_service_registration_options_t opts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS;
-        opts.factory = &sender->publisher.factory;
-        opts.serviceName = PUBSUB_PUBLISHER_SERVICE_NAME;
-        opts.serviceVersion = PUBSUB_PUBLISHER_SERVICE_VERSION;
-        opts.properties = props;
-
-        sender->publisher.svcId = celix_bundleContext_registerServiceWithOptions(ctx, &opts);
-    }
-
-    if (sender->url == NULL) {
-        free(sender);
-        sender = NULL;
-    }
-
-    return sender;
-}
-
-static void pubsub_zmqTopicSender_destroyEntry(psa_zmq_send_msg_entry_t *msgEntry) {
-    celixThreadMutex_destroy(&msgEntry->metrics.mutex);
-    if(msgEntry->headerBuffer != NULL) {
-        free(msgEntry->headerBuffer);
-    }
-    if(msgEntry->metadataBuffer != NULL) {
-        free(msgEntry->metadataBuffer);
-    }
-    if(msgEntry->footerBuffer != NULL) {
-        free(msgEntry->footerBuffer);
-    }
-    free(msgEntry);
-}
-
-void pubsub_zmqTopicSender_destroy(pubsub_zmq_topic_sender_t *sender) {
-    if (sender != NULL) {
-        celix_bundleContext_unregisterService(sender->ctx, sender->publisher.svcId);
-
-        zsock_destroy(&sender->zmq.socket);
-
-        celixThreadMutex_lock(&sender->boundedServices.mutex);
-        hash_map_iterator_t iter = hashMapIterator_construct(sender->boundedServices.map);
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_zmq_bounded_service_entry_t *entry = hashMapIterator_nextValue(&iter);
-            if (entry != NULL) {
-                sender->serializer->destroySerializerMap(sender->serializer->handle, entry->msgTypes);
-
-                hash_map_iterator_t iter2 = hashMapIterator_construct(entry->msgEntries);
-                while (hashMapIterator_hasNext(&iter2)) {
-                    psa_zmq_send_msg_entry_t *msgEntry = hashMapIterator_nextValue(&iter2);
-                    pubsub_zmqTopicSender_destroyEntry(msgEntry);
-                }
-                hashMap_destroy(entry->msgEntries, false, false);
-
-                free(entry);
-            }
-        }
-        hashMap_destroy(sender->boundedServices.map, false, false);
-        celixThreadMutex_unlock(&sender->boundedServices.mutex);
-
-        celixThreadMutex_destroy(&sender->boundedServices.mutex);
-
-        if (sender->scope != NULL) {
-            free(sender->scope);
-        }
-        free(sender->topic);
-        free(sender->url);
-        free(sender);
-    }
-}
-
-long pubsub_zmqTopicSender_serializerSvcId(pubsub_zmq_topic_sender_t *sender) {
-    return sender->serializerSvcId;
-}
-
-long pubsub_zmqTopicSender_protocolSvcId(pubsub_zmq_topic_sender_t *sender) {
-    return sender->protocolSvcId;
-}
-
-const char* pubsub_zmqTopicSender_scope(pubsub_zmq_topic_sender_t *sender) {
-    return sender->scope;
-}
-
-const char* pubsub_zmqTopicSender_topic(pubsub_zmq_topic_sender_t *sender) {
-    return sender->topic;
-}
-
-const char* pubsub_zmqTopicSender_url(pubsub_zmq_topic_sender_t *sender) {
-    return sender->url;
-}
-
-bool pubsub_zmqTopicSender_isStatic(pubsub_zmq_topic_sender_t *sender) {
-    return sender->isStatic;
-}
-
-void pubsub_zmqTopicSender_connectTo(pubsub_zmq_topic_sender_t *sender  __attribute__((unused)), const celix_properties_t *endpoint __attribute__((unused))) {
-    /*nop*/
-}
-
-void pubsub_zmqTopicSender_disconnectFrom(pubsub_zmq_topic_sender_t *sender __attribute__((unused)), const celix_properties_t *endpoint __attribute__((unused))) {
-    /*nop*/
-}
-
-static int psa_zmq_localMsgTypeIdForMsgType(void* handle, const char* msgType, unsigned int* msgTypeId) {
-    psa_zmq_bounded_service_entry_t *entry = (psa_zmq_bounded_service_entry_t *) handle;
-    *msgTypeId = (unsigned int)(uintptr_t) hashMap_get(entry->msgTypeIds, msgType);
-    return 0;
-}
-
-static void* psa_zmq_getPublisherService(void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties __attribute__((unused))) {
-    pubsub_zmq_topic_sender_t *sender = handle;
-    long bndId = celix_bundle_getId(requestingBundle);
-
-    celixThreadMutex_lock(&sender->boundedServices.mutex);
-    psa_zmq_bounded_service_entry_t *entry = hashMap_get(sender->boundedServices.map, (void*)bndId);
-    if (entry != NULL) {
-        entry->getCount += 1;
-    } else {
-        entry = calloc(1, sizeof(*entry));
-        entry->getCount = 1;
-        entry->parent = sender;
-        entry->bndId = bndId;
-        entry->msgEntries = hashMap_create(NULL, NULL, NULL, NULL);
-        entry->msgTypeIds = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
-
-        int rc = sender->serializer->createSerializerMap(sender->serializer->handle, (celix_bundle_t*)requestingBundle, &entry->msgTypes);
-        if (rc == 0) {
-            hash_map_iterator_t iter = hashMapIterator_construct(entry->msgTypes);
-            while (hashMapIterator_hasNext(&iter)) {
-                hash_map_entry_t *hashMapEntry = hashMapIterator_nextEntry(&iter);
-                void *key = hashMapEntry_getKey(hashMapEntry);
-                psa_zmq_send_msg_entry_t *sendEntry = calloc(1, sizeof(*sendEntry));
-                sendEntry->msgSer = hashMapEntry_getValue(hashMapEntry);
-                sendEntry->protSer = sender->protocol;
-                sendEntry->type = (int32_t)sendEntry->msgSer->msgId;
-                int major;
-                int minor;
-                version_getMajor(sendEntry->msgSer->msgVersion, &major);
-                version_getMinor(sendEntry->msgSer->msgVersion, &minor);
-                sendEntry->major = (uint8_t)major;
-                sendEntry->minor = (uint8_t)minor;
-                uuid_copy(sendEntry->originUUID, sender->fwUUID);
-                celixThreadMutex_create(&sendEntry->metrics.mutex, NULL);
-                hashMap_put(entry->msgEntries, key, sendEntry);
-                hashMap_put(entry->msgTypeIds, strndup(sendEntry->msgSer->msgName, 1024), (void *)(uintptr_t) sendEntry->msgSer->msgId);
-            }
-            entry->service.handle = entry;
-            entry->service.localMsgTypeIdForMsgType = psa_zmq_localMsgTypeIdForMsgType;
-            entry->service.send = psa_zmq_topicPublicationSend;
-            hashMap_put(sender->boundedServices.map, (void*)bndId, entry);
-        } else {
-            L_ERROR("Error creating serializer map for ZMQ TopicSender %s/%s", sender->scope == NULL ? "(null)" : sender->scope, sender->topic);
-        }
-    }
-    celixThreadMutex_unlock(&sender->boundedServices.mutex);
-
-    return &entry->service;
-}
-
-static void psa_zmq_ungetPublisherService(void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties __attribute__((unused))) {
-    pubsub_zmq_topic_sender_t *sender = handle;
-    long bndId = celix_bundle_getId(requestingBundle);
-
-    celixThreadMutex_lock(&sender->boundedServices.mutex);
-    psa_zmq_bounded_service_entry_t *entry = hashMap_get(sender->boundedServices.map, (void*)bndId);
-    if (entry != NULL) {
-        entry->getCount -= 1;
-    }
-    if (entry != NULL && entry->getCount == 0) {
-        //free entry
-        hashMap_remove(sender->boundedServices.map, (void*)bndId);
-        int rc = sender->serializer->destroySerializerMap(sender->serializer->handle, entry->msgTypes);
-        if (rc != 0) {
-            L_ERROR("Error destroying publisher service, serializer not available / cannot get msg serializer map\n");
-        }
-
-        hash_map_iterator_t iter = hashMapIterator_construct(entry->msgEntries);
-        while (hashMapIterator_hasNext(&iter)) {
-            psa_zmq_send_msg_entry_t *msgEntry = hashMapIterator_nextValue(&iter);
-            pubsub_zmqTopicSender_destroyEntry(msgEntry);
-        }
-        hashMap_destroy(entry->msgEntries, false, false);
-
-        hashMap_destroy(entry->msgTypeIds, true, false);
-        free(entry);
-    }
-    celixThreadMutex_unlock(&sender->boundedServices.mutex);
-}
-
-pubsub_admin_sender_metrics_t* pubsub_zmqTopicSender_metrics(pubsub_zmq_topic_sender_t *sender) {
-    pubsub_admin_sender_metrics_t *result = calloc(1, sizeof(*result));
-    snprintf(result->scope, PUBSUB_AMDIN_METRICS_NAME_MAX, "%s", sender->scope == NULL ? PUBSUB_DEFAULT_ENDPOINT_SCOPE : sender->scope);
-    snprintf(result->topic, PUBSUB_AMDIN_METRICS_NAME_MAX, "%s", sender->topic);
-    celixThreadMutex_lock(&sender->boundedServices.mutex);
-    size_t count = 0;
-    hash_map_iterator_t iter = hashMapIterator_construct(sender->boundedServices.map);
-    while (hashMapIterator_hasNext(&iter)) {
-        psa_zmq_bounded_service_entry_t *entry = hashMapIterator_nextValue(&iter);
-        hash_map_iterator_t iter2 = hashMapIterator_construct(entry->msgEntries);
-        while (hashMapIterator_hasNext(&iter2)) {
-            hashMapIterator_nextValue(&iter2);
-            count += 1;
-        }
-    }
-
-    result->msgMetrics = calloc(count, sizeof(*result));
-
-    iter = hashMapIterator_construct(sender->boundedServices.map);
-    int i = 0;
-    while (hashMapIterator_hasNext(&iter)) {
-        psa_zmq_bounded_service_entry_t *entry = hashMapIterator_nextValue(&iter);
-        hash_map_iterator_t iter2 = hashMapIterator_construct(entry->msgEntries);
-        while (hashMapIterator_hasNext(&iter2)) {
-            psa_zmq_send_msg_entry_t *mEntry = hashMapIterator_nextValue(&iter2);
-            celixThreadMutex_lock(&mEntry->metrics.mutex);
-            result->msgMetrics[i].nrOfMessagesSend = mEntry->metrics.nrOfMessagesSend;
-            result->msgMetrics[i].nrOfMessagesSendFailed = mEntry->metrics.nrOfMessagesSendFailed;
-            result->msgMetrics[i].nrOfSerializationErrors = mEntry->metrics.nrOfSerializationErrors;
-            result->msgMetrics[i].averageSerializationTimeInSeconds = mEntry->metrics.averageSerializationTimeInSeconds;
-            result->msgMetrics[i].averageTimeBetweenMessagesInSeconds = mEntry->metrics.averageTimeBetweenMessagesInSeconds;
-            result->msgMetrics[i].lastMessageSend = mEntry->metrics.lastMessageSend;
-            result->msgMetrics[i].bndId = entry->bndId;
-            result->msgMetrics[i].typeId = mEntry->type;
-            snprintf(result->msgMetrics[i].typeFqn, PUBSUB_AMDIN_METRICS_NAME_MAX, "%s", mEntry->msgSer->msgName);
-            i += 1;
-            celixThreadMutex_unlock(&mEntry->metrics.mutex);
-        }
-    }
-
-    celixThreadMutex_unlock(&sender->boundedServices.mutex);
-    result->nrOfmsgMetrics = (int)count;
-    return result;
-}
-
-static void psa_zmq_freeMsg(void *msg, void *hint) {
-    psa_zmq_zerocopy_free_entry *entry = hint;
-    entry->msgSer->freeSerializeMsg(entry->msgSer->handle, entry->serializedOutput, entry->serializedOutputLen);
-    free(entry);
-}
-
-static void psa_zmq_unlockData(void *unused __attribute__((unused)), void *hint) {
-    psa_zmq_send_msg_entry_t *entry = hint;
-    __atomic_store_n(&entry->dataLocked, false, __ATOMIC_RELEASE);
-}
-
-static int psa_zmq_topicPublicationSend(void* handle, unsigned int msgTypeId, const void *inMsg, celix_properties_t *metadata) {
-    int status = CELIX_SUCCESS;
-    psa_zmq_bounded_service_entry_t *bound = handle;
-    pubsub_zmq_topic_sender_t *sender = bound->parent;
-    bool monitor = sender->metricsEnabled;
-
-    psa_zmq_send_msg_entry_t *entry = hashMap_get(bound->msgEntries, (void*)(uintptr_t)(msgTypeId));
-
-    //metrics updates
-    struct timespec sendTime = { 0, 0 };
-    struct timespec serializationStart;
-    struct timespec serializationEnd;
-    //int unknownMessageCountUpdate = 0;
-    int sendErrorUpdate = 0;
-    int serializationErrorUpdate = 0;
-    int sendCountUpdate = 0;
-
-    if (entry != NULL) {
-        delay_first_send_for_late_joiners(sender);
-
-
-
-        if (monitor) {
-            clock_gettime(CLOCK_REALTIME, &serializationStart);
-        }
-        size_t serializedOutputLen = 0;
-        struct iovec *serializedOutput = NULL;
-        status = entry->msgSer->serialize(entry->msgSer->handle, inMsg, &serializedOutput, &serializedOutputLen);
-
-        if (monitor) {
-            clock_gettime(CLOCK_REALTIME, &serializationEnd);
-        }
-
-        if (status == CELIX_SUCCESS /*ser ok*/) {
-            // Some ZMQ functions are not thread-safe, but this atomic compare exchange ensures one access at a time.
-            bool expected = false;
-            while(!__atomic_compare_exchange_n(&entry->dataLocked, &expected, true, false, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) {
-                expected = false;
-                usleep(500);
-            }
-
-            pubsub_protocol_message_t message;
-            message.payload.payload = serializedOutput->iov_base;
-            message.payload.length = serializedOutput->iov_len;
-
-            void *payloadData = NULL;
-            size_t payloadLength = 0;
-            entry->protSer->encodePayload(entry->protSer->handle, &message, &payloadData, &payloadLength);
-
-            if (metadata != NULL) {
-                message.metadata.metadata = metadata;
-                entry->protSer->encodeMetadata(entry->protSer->handle, &message, &entry->metadataBuffer, &entry->metadataBufferSize);
-            } else {
-                message.metadata.metadata = NULL;
-            }
-
-            entry->protSer->encodeFooter(entry->protSer->handle, &message, &entry->footerBuffer, &entry->footerBufferSize);
-
-            message.header.msgId = msgTypeId;
-            message.header.seqNr = entry->seqNr;
-            message.header.msgMajorVersion = 0;
-            message.header.msgMinorVersion = 0;
-            message.header.payloadSize = payloadLength;
-            message.header.metadataSize = entry->metadataBufferSize;
-            message.header.payloadPartSize = payloadLength;
-            message.header.payloadOffset = 0;
-            message.header.isLastSegment = 1;
-            message.header.convertEndianess = 0;
-
-            // increase seqNr
-            entry->seqNr++;
-
-            entry->protSer->encodeHeader(entry->protSer->handle, &message, &entry->headerBuffer, &entry->headerBufferSize);
-
-            errno = 0;
-            bool sendOk;
-
-            if (bound->parent->zeroCopyEnabled) {
-
-                zmq_msg_t msg1; // Header
-                zmq_msg_t msg2; // Payload
-                zmq_msg_t msg3; // Metadata
-                zmq_msg_t msg4; // Footer
-                void *socket = zsock_resolve(sender->zmq.socket);
-                psa_zmq_zerocopy_free_entry *freeMsgEntry = malloc(sizeof(psa_zmq_zerocopy_free_entry));
-                freeMsgEntry->msgSer = entry->msgSer;
-                freeMsgEntry->serializedOutput = serializedOutput;
-                freeMsgEntry->serializedOutputLen = serializedOutputLen;
-
-                zmq_msg_init_data(&msg1, entry->headerBuffer, entry->headerBufferSize, psa_zmq_unlockData, entry);
-                //send header
-                int rc = zmq_msg_send(&msg1, socket, ZMQ_SNDMORE);
-                if (rc == -1) {
-                    L_WARN("Error sending header msg. %s", strerror(errno));
-                    zmq_msg_close(&msg1);
-                }
-
-                //send Payload
-                if (rc > 0) {
-                    int flag = ((entry->metadataBufferSize > 0)  || (entry->footerBufferSize > 0)) ? ZMQ_SNDMORE : 0;
-                    zmq_msg_init_data(&msg2, payloadData, payloadLength, psa_zmq_freeMsg, freeMsgEntry);
-                    rc = zmq_msg_send(&msg2, socket, flag);
-                    if (rc == -1) {
-                        L_WARN("Error sending payload msg. %s", strerror(errno));
-                        zmq_msg_close(&msg2);
-                    }
-                }
-
-                //send MetaData
-                if (rc > 0 && entry->metadataBufferSize > 0) {
-                    int flag = (entry->footerBufferSize > 0 ) ? ZMQ_SNDMORE : 0;
-                    zmq_msg_init_data(&msg3, entry->metadataBuffer, entry->metadataBufferSize, NULL, NULL);
-                    rc = zmq_msg_send(&msg3, socket, flag);
-                    if (rc == -1) {
-                        L_WARN("Error sending metadata msg. %s", strerror(errno));
-                        zmq_msg_close(&msg3);
-                    }
-                }
-
-                //send Footer
-                if (rc > 0 && entry->footerBufferSize > 0) {
-                    zmq_msg_init_data(&msg4, entry->footerBuffer, entry->footerBufferSize, NULL, NULL);
-                    rc = zmq_msg_send(&msg4, socket, 0);
-                    if (rc == -1) {
-                        L_WARN("Error sending footer msg. %s", strerror(errno));
-                        zmq_msg_close(&msg4);
-                    }
-                }
-
-                sendOk = rc > 0;
-            } else {
-                //no zero copy
-                zmsg_t *msg = zmsg_new();
-                zmsg_addmem(msg, entry->headerBuffer, entry->headerBufferSize);
-                zmsg_addmem(msg, payloadData, payloadLength);
-                if (entry->metadataBufferSize > 0) {
-                    zmsg_addmem(msg, entry->metadataBuffer, entry->metadataBufferSize);
-                }
-                if (entry->footerBufferSize > 0) {
-                    zmsg_addmem(msg, entry->footerBuffer, entry->footerBufferSize);
-                }
-                int rc = zmsg_send(&msg, sender->zmq.socket);
-                sendOk = rc == 0;
-
-                if (!sendOk) {
-                    zmsg_destroy(&msg); //if send was not ok, no owner change -> destroy msg
-                }
-
-                // Note: serialized Payload is deleted by serializer
-                if (payloadData && (payloadData != message.payload.payload)) {
-                    free(payloadData);
-                }
-
-                __atomic_store_n(&entry->dataLocked, false, __ATOMIC_RELEASE);
-            }
-
-            if (message.metadata.metadata) {
-                celix_properties_destroy(message.metadata.metadata);
-            }
-            if (!bound->parent->zeroCopyEnabled && serializedOutput) {
-                entry->msgSer->freeSerializeMsg(entry->msgSer->handle, serializedOutput, serializedOutputLen);
-            }
-
-            if (sendOk) {
-                sendCountUpdate = 1;
-            } else {
-                sendErrorUpdate = 1;
-                L_WARN("[PSA_ZMQ_TS] Error sending zmg. %s", strerror(errno));
-            }
-        } else {
-            serializationErrorUpdate = 1;
-            L_WARN("[PSA_ZMQ_TS] Error serialize message of type %s for scope/topic %s/%s", entry->msgSer->msgName, sender->scope == NULL ? "(null)" : sender->scope, sender->topic);
-        }
-    } else {
-        //unknownMessageCountUpdate = 1;
-        status = CELIX_SERVICE_EXCEPTION;
-        L_WARN("[PSA_ZMQ_TS] Error cannot serialize message with msg type id %i for scope/topic %s/%s", msgTypeId, sender->scope == NULL ? "(null)" : sender->scope, sender->topic);
-    }
-
-
-    if (monitor && entry != NULL) {
-        celixThreadMutex_lock(&entry->metrics.mutex);
-
-        long n = entry->metrics.nrOfMessagesSend + entry->metrics.nrOfMessagesSendFailed;
-        double diff = celix_difftime(&serializationStart, &serializationEnd);
... 444 lines suppressed ...

[celix] 02/02: Removes integration test for pubsub_admin _v1 versions

Posted by pn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch feature/remove_psa_versions_v1
in repository https://gitbox.apache.org/repos/asf/celix.git

commit f1efeaca317d6ab6423bb54b5c61d4224535563a
Author: Pepijn Noltes <pe...@gmail.com>
AuthorDate: Thu Oct 7 20:41:43 2021 +0200

    Removes integration test for pubsub_admin _v1 versions
---
 bundles/pubsub/integration/CMakeLists.txt | 307 +-----------------------------
 1 file changed, 4 insertions(+), 303 deletions(-)

diff --git a/bundles/pubsub/integration/CMakeLists.txt b/bundles/pubsub/integration/CMakeLists.txt
index 74d4909..6bec7f8 100644
--- a/bundles/pubsub/integration/CMakeLists.txt
+++ b/bundles/pubsub/integration/CMakeLists.txt
@@ -189,129 +189,6 @@ if (BUILD_PUBSUB_PSA_UDP_MC)
 endif()
 
 if (BUILD_PUBSUB_PSA_TCP)
-    add_celix_container(pubsub_tcp_wire_v1_tests
-            USE_CONFIG #ensures that a config.properties will be created with the launch bundles.
-            LAUNCHER_SRC ${CMAKE_CURRENT_LIST_DIR}/gtest/PubSubIntegrationTestSuite.cc
-            DIR ${CMAKE_CURRENT_BINARY_DIR}
-            PROPERTIES
-            LOGHELPER_STDOUT_FALLBACK_INCLUDE_DEBUG=true
-            CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=trace
-            BUNDLES
-            Celix::shell
-            Celix::shell_tui
-            Celix::celix_pubsub_serializer_json
-            Celix::celix_pubsub_protocol_wire_v1
-            Celix::celix_pubsub_topology_manager
-            Celix::celix_pubsub_admin_tcp
-            pubsub_sut
-            pubsub_tst
-            )
-    target_link_libraries(pubsub_tcp_wire_v1_tests PRIVATE Celix::pubsub_api Jansson Celix::dfi GTest::gtest GTest::gtest_main)
-    target_include_directories(pubsub_tcp_wire_v1_tests SYSTEM PRIVATE gtest)
-    add_test(NAME pubsub_tcp_wire_v1_tests COMMAND pubsub_tcp_wire_v1_tests WORKING_DIRECTORY $<TARGET_PROPERTY:pubsub_tcp_wire_v1_tests,CONTAINER_LOC>)
-    setup_target_for_coverage(pubsub_tcp_wire_v1_tests SCAN_DIR ..)
-
-    add_celix_container(pubsub_tcp_wire_v2_tests
-            USE_CONFIG #ensures that a config.properties will be created with the launch bundles.
-            LAUNCHER_SRC ${CMAKE_CURRENT_LIST_DIR}/gtest/PubSubIntegrationTestSuite.cc
-            DIR ${CMAKE_CURRENT_BINARY_DIR}
-            PROPERTIES
-            LOGHELPER_STDOUT_FALLBACK_INCLUDE_DEBUG=true
-            CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=trace
-            BUNDLES
-            Celix::shell
-            Celix::shell_tui
-            Celix::celix_pubsub_serializer_json
-            Celix::celix_pubsub_protocol_wire_v2
-            Celix::celix_pubsub_topology_manager
-            Celix::celix_pubsub_admin_tcp
-            pubsub_sut
-            pubsub_tst
-            )
-    target_link_libraries(pubsub_tcp_wire_v2_tests PRIVATE Celix::pubsub_api Jansson Celix::dfi GTest::gtest GTest::gtest_main)
-    target_include_directories(pubsub_tcp_wire_v2_tests SYSTEM PRIVATE gtest)
-    add_test(NAME pubsub_tcp_wire_v2_tests COMMAND pubsub_tcp_wire_v2_tests WORKING_DIRECTORY $<TARGET_PROPERTY:pubsub_tcp_wire_v2_tests,CONTAINER_LOC>)
-    setup_target_for_coverage(pubsub_tcp_wire_v2_tests SCAN_DIR ..)
-
-    add_celix_container(pubsub_tcp_wire_v2_with_no_scope_tests
-        USE_CONFIG #ensures that a config.properties will be created with the launch bundles.
-        LAUNCHER_SRC ${CMAKE_CURRENT_LIST_DIR}/gtest/PubSubIntegrationTestSuite.cc
-        DIR ${CMAKE_CURRENT_BINARY_DIR}
-        PROPERTIES
-            LOGHELPER_STDOUT_FALLBACK_INCLUDE_DEBUG=true
-            CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=trace
-            CELIX_PUBSUB_TEST_USE_NEGATIVE_SCOPE_FILTER=false
-        BUNDLES
-            Celix::shell
-            Celix::shell_tui
-            Celix::celix_pubsub_serializer_json
-            Celix::celix_pubsub_protocol_wire_v2
-            Celix::celix_pubsub_topology_manager
-            Celix::celix_pubsub_admin_tcp
-            pubsub_sut
-            pubsub_tst
-    )
-    target_link_libraries(pubsub_tcp_wire_v2_with_no_scope_tests PRIVATE Celix::pubsub_api Jansson Celix::dfi GTest::gtest GTest::gtest_main)
-    target_include_directories(pubsub_tcp_wire_v2_with_no_scope_tests SYSTEM PRIVATE gtest)
-    add_test(NAME pubsub_tcp_wire_v2_with_no_scope_tests COMMAND pubsub_tcp_wire_v2_with_no_scope_tests WORKING_DIRECTORY $<TARGET_PROPERTY:pubsub_tcp_wire_v2_with_no_scope_tests,CONTAINER_LOC>)
-    setup_target_for_coverage(pubsub_tcp_wire_v2_with_no_scope_tests SCAN_DIR ..)
-
-    add_celix_container(pubsub_tcp_endpoint_tests
-            USE_CONFIG #ensures that a config.properties will be created with the launch bundles.
-            LAUNCHER_SRC ${CMAKE_CURRENT_LIST_DIR}/gtest/PubSubEndpointIntegrationTestSuite.cc
-            DIR ${CMAKE_CURRENT_BINARY_DIR}
-            PROPERTIES
-            LOGHELPER_STDOUT_FALLBACK_INCLUDE_DEBUG=true
-            CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=trace
-            BUNDLES
-            Celix::shell
-            Celix::shell_tui
-            Celix::celix_pubsub_serializer_json
-            Celix::celix_pubsub_protocol_wire_v2
-            Celix::celix_pubsub_topology_manager
-            Celix::celix_pubsub_admin_tcp
-            pubsub_endpoint_tst
-            pubsub_endpoint_sut
-            pubsub_loopback
-            )
-    target_link_libraries(pubsub_tcp_endpoint_tests PRIVATE Celix::pubsub_api Jansson Celix::dfi GTest::gtest GTest::gtest_main)
-    target_include_directories(pubsub_tcp_endpoint_tests SYSTEM PRIVATE gtest)
-
-    add_celix_container(pstm_deadlock_tcp_test
-            USE_CONFIG #ensures that a config.properties will be created with the launch bundles.
-            LAUNCHER_SRC ${CMAKE_CURRENT_LIST_DIR}/pstm_deadlock_test/test_runner.cc
-            DIR ${CMAKE_CURRENT_BINARY_DIR}
-            PROPERTIES
-            LOGHELPER_STDOUT_FALLBACK_INCLUDE_DEBUG=true
-            CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=trace
-            BUNDLES
-            Celix::celix_pubsub_serializer_json
-            Celix::celix_pubsub_protocol_wire_v2
-            Celix::celix_pubsub_topology_manager
-            Celix::celix_pubsub_admin_tcp
-            Celix::shell
-            Celix::shell_tui
-            )
-    target_compile_definitions(pstm_deadlock_tcp_test PRIVATE -DDEADLOCK_SUT_BUNDLE_FILE=\"${DEADLOCK_SUT_BUNDLE_FILE}\")
-    target_link_libraries(pstm_deadlock_tcp_test PRIVATE Celix::pubsub_api GTest::gtest GTest::gtest_main Jansson Celix::dfi)
-    target_include_directories(pstm_deadlock_tcp_test SYSTEM PRIVATE pstm_deadlock_tcp_test)
-
-    #Note we do not link to bundles, as result (to ensure a bundle zip file is created) an dependency on the bundle is needed.
-    add_dependencies(pstm_deadlock_tcp_test pubsub_deadlock_sut_bundle)
-
-    #Framework "bundle" has no cache dir. Default as "cache dir" the cwd is used.
-    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/meta_data/msg.descriptor ${CMAKE_CURRENT_BINARY_DIR}/pstm_deadlock_tcp_gtest/META-INF/descriptors/msg.descriptor COPYONLY)
-    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/meta_data/deadlock.scope.properties ${CMAKE_CURRENT_BINARY_DIR}/pstm_deadlock_tcp_gtest/META-INF/topics/pub/deadlock.properties COPYONLY)
-
-    add_test(NAME pstm_deadlock_tcp_test COMMAND pstm_deadlock_tcp_test WORKING_DIRECTORY $<TARGET_PROPERTY:pstm_deadlock_tcp_test,CONTAINER_LOC>)
-    setup_target_for_coverage(pstm_deadlock_tcp_test SCAN_DIR ..)
-
-    #TCP Endpoint test is disabled because the test is not stable when running on Travis
-    if (ENABLE_PUBSUB_PSA_TCP_ENDPOINT_TEST)
-        add_test(NAME pubsub_tcp_endpoint_tests COMMAND pubsub_tcp_endpoint_tests WORKING_DIRECTORY $<TARGET_PROPERTY:pubsub_tcp_endpoint_tests,CONTAINER_LOC>)
-        setup_target_for_coverage(pubsub_tcp_endpoint_tests SCAN_DIR ..)
-    endif()
-
     # TCP v2 tests
 
     add_celix_container(pubsub_tcp_v2_wire_v1_tests
@@ -444,57 +321,6 @@ if (BUILD_PUBSUB_PSA_TCP)
 endif()
 
 if (BUILD_PUBSUB_PSA_WS)
-    add_celix_container(pubsub_websocket_tests
-            USE_CONFIG
-            LAUNCHER_SRC ${CMAKE_CURRENT_LIST_DIR}/gtest/PubSubIntegrationTestSuite.cc
-            DIR ${CMAKE_CURRENT_BINARY_DIR}
-            PROPERTIES
-            LOGHELPER_STDOUT_FALLBACK_INCLUDE_DEBUG=true
-            CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=trace
-            USE_WEBSOCKETS=true
-            LISTENING_PORTS=8080
-            BUNDLES
-            Celix::celix_pubsub_serializer_json
-            Celix::http_admin
-            Celix::celix_pubsub_topology_manager
-            Celix::celix_pubsub_admin_websocket
-            pubsub_sut
-            pubsub_tst
-            )
-    target_link_libraries(pubsub_websocket_tests PRIVATE Celix::pubsub_api Jansson Celix::dfi civetweb_shared GTest::gtest GTest::gtest_main)
-    target_include_directories(pubsub_websocket_tests SYSTEM PRIVATE gtest)
-    add_test(NAME pubsub_websocket_tests COMMAND pubsub_websocket_tests WORKING_DIRECTORY $<TARGET_PROPERTY:pubsub_websocket_tests,CONTAINER_LOC>)
-    setup_target_for_coverage(pubsub_websocket_tests SCAN_DIR ..)
-
-    add_celix_container(pstm_deadlock_websocket_test
-            USE_CONFIG #ensures that a config.properties will be created with the launch bundles.
-            LAUNCHER_SRC ${CMAKE_CURRENT_LIST_DIR}/pstm_deadlock_test/test_runner.cc
-            DIR ${CMAKE_CURRENT_BINARY_DIR}
-            PROPERTIES
-            LOGHELPER_STDOUT_FALLBACK_INCLUDE_DEBUG=true
-            CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=trace
-            BUNDLES
-            Celix::celix_pubsub_serializer_json
-            Celix::celix_pubsub_protocol_wire_v2
-            Celix::celix_pubsub_topology_manager
-            Celix::celix_pubsub_admin_websocket
-            Celix::shell
-            Celix::shell_tui
-            )
-    target_compile_definitions(pstm_deadlock_websocket_test PRIVATE -DDEADLOCK_SUT_BUNDLE_FILE=\"${DEADLOCK_SUT_BUNDLE_FILE}\")
-    target_link_libraries(pstm_deadlock_websocket_test PRIVATE Celix::pubsub_api GTest::gtest GTest::gtest_main Jansson Celix::dfi civetweb_shared)
-    target_include_directories(pstm_deadlock_websocket_test SYSTEM PRIVATE pstm_deadlock_websocket_test)
-
-    #Note we do not link to bundles, as result (to ensure a bundle zip file is created) an dependency on the bundle is needed.
-    add_dependencies(pstm_deadlock_websocket_test pubsub_deadlock_sut_bundle)
-
-    #Framework "bundle" has no cache dir. Default as "cache dir" the cwd is used.
-    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/meta_data/msg.descriptor ${CMAKE_CURRENT_BINARY_DIR}/pstm_deadlock_websocket_gtest/META-INF/descriptors/msg.descriptor COPYONLY)
-    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/meta_data/deadlock.scope.properties ${CMAKE_CURRENT_BINARY_DIR}/pstm_deadlock_websocket_gtest/META-INF/topics/pub/deadlock.properties COPYONLY)
-
-    add_test(NAME pstm_deadlock_websocket_test COMMAND pstm_deadlock_websocket_test WORKING_DIRECTORY $<TARGET_PROPERTY:pstm_deadlock_websocket_test,CONTAINER_LOC>)
-    setup_target_for_coverage(pstm_deadlock_websocket_test SCAN_DIR ..)
-
     add_celix_container(pubsub_websocket_v2_tests
             USE_CONFIG
             LAUNCHER_SRC ${CMAKE_CURRENT_LIST_DIR}/gtest/PubSubIntegrationTestSuite.cc
@@ -541,8 +367,8 @@ if (BUILD_PUBSUB_PSA_WS)
     add_dependencies(pstm_deadlock_websocket_v2_test pubsub_deadlock_sut_bundle)
 
     #Framework "bundle" has no cache dir. Default as "cache dir" the cwd is used.
-    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/meta_data/msg.descriptor ${CMAKE_CURRENT_BINARY_DIR}/pstm_deadlock_websocket_v2_gtest/META-INF/descriptors/msg.descriptor COPYONLY)
-    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/meta_data/deadlock.scope.properties ${CMAKE_CURRENT_BINARY_DIR}/pstm_deadlock_websocket_v2_gtest/META-INF/topics/pub/deadlock.properties COPYONLY)
+    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/meta_data/msg.descriptor ${CMAKE_CURRENT_BINARY_DIR}/pstm_deadlock_websocket_v2_test/META-INF/descriptors/msg.descriptor COPYONLY)
+    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/meta_data/deadlock.scope.properties ${CMAKE_CURRENT_BINARY_DIR}/pstm_deadlock_websocket_v2_test/META-INF/topics/pub/deadlock.properties COPYONLY)
 
     add_test(NAME pstm_deadlock_websocket_v2_test COMMAND pstm_deadlock_websocket_v2_test WORKING_DIRECTORY $<TARGET_PROPERTY:pstm_deadlock_websocket_v2_test,CONTAINER_LOC>)
     setup_target_for_coverage(pstm_deadlock_websocket_v2_test SCAN_DIR ..)
@@ -552,23 +378,6 @@ if (BUILD_PUBSUB_PSA_ZMQ)
     find_package(ZMQ REQUIRED)
     find_package(CZMQ REQUIRED)
 
-    add_celix_container(pubsub_zmq_tests
-            USE_CONFIG #ensures that a config.properties will be created with the launch bundles.
-            LAUNCHER_SRC ${CMAKE_CURRENT_LIST_DIR}/gtest/PubSubIntegrationTestSuite.cc
-            DIR ${CMAKE_CURRENT_BINARY_DIR}
-            PROPERTIES
-                LOGHELPER_STDOUT_FALLBACK_INCLUDE_DEBUG=true
-                CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=trace
-            BUNDLES
-                Celix::celix_pubsub_serializer_json
-                Celix::celix_pubsub_protocol_wire_v1
-                Celix::celix_pubsub_topology_manager
-                Celix::celix_pubsub_admin_zmq
-                pubsub_sut
-                pubsub_tst
-                pubsub_serializer
-    )
-
     add_celix_container(pubsub_zmq_v2_tests
             USE_CONFIG #ensures that a config.properties will be created with the launch bundles.
             LAUNCHER_SRC ${CMAKE_CURRENT_LIST_DIR}/gtest/PubSubIntegrationTestSuite.cc
@@ -586,59 +395,11 @@ if (BUILD_PUBSUB_PSA_ZMQ)
                 pubsub_serializer
             )
 
-    target_link_libraries(pubsub_zmq_tests PRIVATE Celix::pubsub_api Celix::dfi ZMQ::lib CZMQ::lib GTest::gtest GTest::gtest_main)
-    target_include_directories(pubsub_zmq_tests SYSTEM PRIVATE gtest)
-    add_test(NAME pubsub_zmq_tests COMMAND pubsub_zmq_tests WORKING_DIRECTORY $<TARGET_PROPERTY:pubsub_zmq_tests,CONTAINER_LOC>)
-    setup_target_for_coverage(pubsub_zmq_tests SCAN_DIR ..)
-
     target_link_libraries(pubsub_zmq_v2_tests PRIVATE Celix::pubsub_api Celix::dfi ZMQ::lib CZMQ::lib GTest::gtest GTest::gtest_main)
     target_include_directories(pubsub_zmq_v2_tests SYSTEM PRIVATE gtest)
     add_test(NAME pubsub_zmq_v2_tests COMMAND pubsub_zmq_v2_tests WORKING_DIRECTORY $<TARGET_PROPERTY:pubsub_zmq_v2_tests,CONTAINER_LOC>)
     setup_target_for_coverage(pubsub_zmq_v2_tests SCAN_DIR ..)
 
-    add_celix_container(pubsub_zmq_wire_v2_tests
-        USE_CONFIG #ensures that a config.properties will be created with the launch bundles.
-        LAUNCHER_SRC ${CMAKE_CURRENT_LIST_DIR}/gtest/PubSubIntegrationTestSuite.cc
-        DIR ${CMAKE_CURRENT_BINARY_DIR}
-        PROPERTIES
-        LOGHELPER_STDOUT_FALLBACK_INCLUDE_DEBUG=true
-        CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=trace
-        BUNDLES
-        Celix::celix_pubsub_serializer_json
-        Celix::celix_pubsub_protocol_wire_v2
-        Celix::celix_pubsub_topology_manager
-        Celix::celix_pubsub_admin_zmq
-        pubsub_sut
-        pubsub_tst
-        pubsub_serializer
-        )
-
-    target_link_libraries(pubsub_zmq_wire_v2_tests PRIVATE Celix::pubsub_api Jansson Celix::dfi ZMQ::lib CZMQ::lib GTest::gtest GTest::gtest_main)
-    target_include_directories(pubsub_zmq_wire_v2_tests SYSTEM PRIVATE gtest)
-    add_test(NAME pubsub_zmq_wire_v2_tests COMMAND pubsub_zmq_wire_v2_tests WORKING_DIRECTORY $<TARGET_PROPERTY:pubsub_zmq_wire_v2_tests,CONTAINER_LOC>)
-    setup_target_for_coverage(pubsub_zmq_wire_v2_tests SCAN_DIR ..)
-
-
-    add_celix_container(pubsub_zmq_zerocopy_tests
-            USE_CONFIG #ensures that a config.properties will be created with the launch bundles.
-            LAUNCHER_SRC ${CMAKE_CURRENT_LIST_DIR}/gtest/PubSubIntegrationTestSuite.cc
-            DIR ${CMAKE_CURRENT_BINARY_DIR}
-            PROPERTIES
-                LOGHELPER_STDOUT_FALLBACK_INCLUDE_DEBUG=true
-                PSA_ZMQ_ZEROCOPY_ENABLED=true
-                CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=trace
-            BUNDLES
-                Celix::celix_pubsub_serializer_json
-                Celix::celix_pubsub_protocol_wire_v1
-                Celix::celix_pubsub_topology_manager
-                Celix::celix_pubsub_admin_zmq
-                Celix::shell
-                Celix::shell_tui
-                pubsub_sut
-                pubsub_tst
-                pubsub_serializer
-    )
-
     add_celix_container(pubsub_zmq_v2_zerocopy_tests
             USE_CONFIG #ensures that a config.properties will be created with the launch bundles.
             LAUNCHER_SRC ${CMAKE_CURRENT_LIST_DIR}/gtest/PubSubIntegrationTestSuite.cc
@@ -658,11 +419,6 @@ if (BUILD_PUBSUB_PSA_ZMQ)
                 pubsub_tst
                 pubsub_serializer
             )
-    target_link_libraries(pubsub_zmq_zerocopy_tests PRIVATE Celix::pubsub_api Jansson Celix::dfi ZMQ::lib CZMQ::lib GTest::gtest GTest::gtest_main)
-    target_include_directories(pubsub_zmq_zerocopy_tests SYSTEM PRIVATE gtest)
-
-    add_test(NAME pubsub_zmq_zerocopy_tests COMMAND pubsub_zmq_zerocopy_tests WORKING_DIRECTORY $<TARGET_PROPERTY:pubsub_zmq_zerocopy_tests,CONTAINER_LOC>)
-    setup_target_for_coverage(pubsub_zmq_zerocopy_tests SCAN_DIR ..)
 
     target_link_libraries(pubsub_zmq_v2_zerocopy_tests PRIVATE Celix::pubsub_api Celix::dfi ZMQ::lib CZMQ::lib GTest::gtest GTest::gtest_main)
     target_include_directories(pubsub_zmq_v2_zerocopy_tests SYSTEM PRIVATE gtest)
@@ -670,48 +426,6 @@ if (BUILD_PUBSUB_PSA_ZMQ)
     add_test(NAME pubsub_zmq_v2_zerocopy_tests COMMAND pubsub_zmq_v2_zerocopy_tests WORKING_DIRECTORY $<TARGET_PROPERTY:pubsub_zmq_v2_zerocopy_tests,CONTAINER_LOC>)
     setup_target_for_coverage(pubsub_zmq_v2_zerocopy_tests SCAN_DIR ..)
 
-    add_celix_container(pubsub_zmq_zerocopy_wire_v2_tests
-        USE_CONFIG #ensures that a config.properties will be created with the launch bundles.
-        LAUNCHER_SRC ${CMAKE_CURRENT_LIST_DIR}/gtest/PubSubIntegrationTestSuite.cc
-        DIR ${CMAKE_CURRENT_BINARY_DIR}
-        PROPERTIES
-        LOGHELPER_STDOUT_FALLBACK_INCLUDE_DEBUG=true
-        PSA_ZMQ_ZEROCOPY_ENABLED=true
-        CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=trace
-        BUNDLES
-        Celix::celix_pubsub_serializer_json
-        Celix::celix_pubsub_protocol_wire_v2
-        Celix::celix_pubsub_topology_manager
-        Celix::celix_pubsub_admin_zmq
-        Celix::shell
-        Celix::shell_tui
-        pubsub_sut
-        pubsub_tst
-        pubsub_serializer
-        )
-    target_link_libraries(pubsub_zmq_zerocopy_wire_v2_tests PRIVATE Celix::pubsub_api Jansson Celix::dfi ZMQ::lib CZMQ::lib GTest::gtest GTest::gtest_main)
-    target_include_directories(pubsub_zmq_zerocopy_wire_v2_tests SYSTEM PRIVATE gtest)
-
-    add_test(NAME pubsub_zmq_zerocopy_wire_v2_tests COMMAND pubsub_zmq_zerocopy_wire_v2_tests WORKING_DIRECTORY $<TARGET_PROPERTY:pubsub_zmq_zerocopy_wire_v2_tests,CONTAINER_LOC>)
-    setup_target_for_coverage(pubsub_zmq_zerocopy_wire_v2_tests SCAN_DIR ..)
-
-    add_celix_container(pstm_deadlock_zmq_test
-            USE_CONFIG #ensures that a config.properties will be created with the launch bundles.
-            LAUNCHER_SRC ${CMAKE_CURRENT_LIST_DIR}/pstm_deadlock_test/test_runner.cc
-            DIR ${CMAKE_CURRENT_BINARY_DIR}
-            PROPERTIES
-            LOGHELPER_STDOUT_FALLBACK_INCLUDE_DEBUG=true
-            CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=trace
-            BUNDLES
-            Celix::celix_pubsub_serializer_json
-            Celix::celix_pubsub_protocol_wire_v2
-            Celix::celix_pubsub_topology_manager
-            Celix::celix_pubsub_admin_zmq
-            Celix::shell
-            Celix::shell_tui
-            )
-
-
     add_celix_container(pstm_deadlock_zmq_v2_test
             USE_CONFIG #ensures that a config.properties will be created with the launch bundles.
             LAUNCHER_SRC ${CMAKE_CURRENT_LIST_DIR}/pstm_deadlock_test/test_runner.cc
@@ -725,19 +439,6 @@ if (BUILD_PUBSUB_PSA_ZMQ)
             Celix::celix_pubsub_admin_zmq_v2
             Celix::celix_pubsub_protocol_wire_v2
             )
-    target_compile_definitions(pstm_deadlock_zmq_test PRIVATE -DDEADLOCK_SUT_BUNDLE_FILE=\"${DEADLOCK_SUT_BUNDLE_FILE}\")
-    target_link_libraries(pstm_deadlock_zmq_test PRIVATE Celix::pubsub_api GTest::gtest GTest::gtest_main Celix::dfi ZMQ::lib CZMQ::lib)
-    target_include_directories(pstm_deadlock_zmq_test SYSTEM PRIVATE pstm_deadlock_zmq_test)
-
-    #Note we do not link to bundles, as result (to ensure a bundle zip file is created) an dependency on the bundle is needed.
-    add_dependencies(pstm_deadlock_zmq_test pubsub_deadlock_sut_bundle)
-
-    #Framework "bundle" has no cache dir. Default as "cache dir" the cwd is used.
-    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/meta_data/msg.descriptor ${CMAKE_CURRENT_BINARY_DIR}/pstm_deadlock_zmq_gtest/META-INF/descriptors/msg.descriptor COPYONLY)
-    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/meta_data/deadlock.scope.properties ${CMAKE_CURRENT_BINARY_DIR}/pstm_deadlock_zmq_gtest/META-INF/topics/pub/deadlock.properties COPYONLY)
-
-    add_test(NAME pstm_deadlock_zmq_test COMMAND pstm_deadlock_zmq_test WORKING_DIRECTORY $<TARGET_PROPERTY:pstm_deadlock_zmq_test,CONTAINER_LOC>)
-    setup_target_for_coverage(pstm_deadlock_zmq_test SCAN_DIR ..)
 
     target_compile_definitions(pstm_deadlock_zmq_v2_test PRIVATE -DDEADLOCK_SUT_BUNDLE_FILE=\"${DEADLOCK_SUT_BUNDLE_FILE}\")
     target_link_libraries(pstm_deadlock_zmq_v2_test PRIVATE Celix::pubsub_api GTest::gtest GTest::gtest_main Celix::dfi ZMQ::lib CZMQ::lib)
@@ -747,8 +448,8 @@ if (BUILD_PUBSUB_PSA_ZMQ)
     add_dependencies(pstm_deadlock_zmq_v2_test pubsub_deadlock_sut_bundle)
 
     #Framework "bundle" has no cache dir. Default as "cache dir" the cwd is used.
-    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/meta_data/msg.descriptor ${CMAKE_CURRENT_BINARY_DIR}/pstm_deadlock_zmq_v2_gtest/META-INF/descriptors/msg.descriptor COPYONLY)
-    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/meta_data/deadlock.scope.properties ${CMAKE_CURRENT_BINARY_DIR}/pstm_deadlock_zmq_v2_gtest/META-INF/topics/pub/deadlock.properties COPYONLY)
+    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/meta_data/msg.descriptor ${CMAKE_CURRENT_BINARY_DIR}/pstm_deadlock_zmq_v2_test/META-INF/descriptors/msg.descriptor COPYONLY)
+    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/meta_data/deadlock.scope.properties ${CMAKE_CURRENT_BINARY_DIR}/pstm_deadlock_zmq_v2_test/META-INF/topics/pub/deadlock.properties COPYONLY)
 
     add_test(NAME pstm_deadlock_zmq_v2_test COMMAND pstm_deadlock_zmq_v2_test WORKING_DIRECTORY $<TARGET_PROPERTY:pstm_deadlock_zmq_v2_test,CONTAINER_LOC>)
     setup_target_for_coverage(pstm_deadlock_zmq_v2_test SCAN_DIR ..)