From 05b7f5f66b768e2b9d555995f0c5b1384afaf7f7 Mon Sep 17 00:00:00 2001 From: Pepijn Noltes Date: Sun, 3 Dec 2023 22:42:23 +0100 Subject: [PATCH 1/6] Remove pubsub and refactor cxx rsa example/integration --- bundles/CMakeLists.txt | 1 - .../integration/CMakeLists.txt | 50 +- .../Calculator$add$Invoke.descriptor | 9 - .../Calculator$add$Return.descriptor | 9 - .../Calculator$result$Event.descriptor | 9 - .../integration/src/CalculatorConsumer.cc | 12 + .../integration/src/CalculatorProvider.cc | 2 +- .../TestExportImportRemoteServiceFactory.cc | 470 +++--- bundles/pubsub/CMakeLists.txt | 36 - bundles/pubsub/README.md | 116 -- bundles/pubsub/doc/pubsub_serialization.adoc | 263 --- bundles/pubsub/examples/CMakeLists.txt | 361 ---- bundles/pubsub/examples/keys/README.md | 39 - .../examples/keys/publisher/private/.gitkeep | 14 - .../examples/keys/publisher/public/.gitkeep | 16 - .../examples/keys/subscriber/private/.gitkeep | 16 - .../examples/keys/subscriber/public/.gitkeep | 16 - bundles/pubsub/examples/pubsub/CMakeLists.txt | 28 - .../examples/pubsub/common/include/poi.h | 55 - .../examples/pubsub/common/include/poiCmd.h | 39 - .../pubsub/interceptors/CMakeLists.txt | 28 - .../include/first_interceptor_private.h | 43 - .../include/second_interceptor_private.h | 36 - .../interceptors/src/first_interceptor.c | 73 - .../src/ps_interceptor_activator.c | 95 -- .../interceptors/src/second_interceptor.c | 58 - .../msg_descriptors/msg_poi1.descriptor | 10 - .../msg_descriptors/msg_poi2.descriptor | 11 - .../msg_descriptors/msg_poiCmd.descriptor | 8 - .../pubsub/msg_descriptors/poi1.properties | 38 - .../pubsub/msg_descriptors/poi2.properties | 38 - .../pubsub/msg_descriptors/poiCmd.properties | 35 - .../examples/pubsub/publisher/CMakeLists.txt | 51 - .../include/pubsub_publisher_private.h | 55 - .../publisher/private/src/ps_pub_activator.c | 96 -- .../publisher/private/src/pubsub_publisher.c | 168 -- .../examples/pubsub/publisher2/CMakeLists.txt | 50 - .../pubsub/pubsub_websocket/CMakeLists.txt | 62 - .../include/pubsub_websocket_private.h | 97 -- .../private/src/ps_websocket_activator.c | 163 -- .../private/src/pubsub_websocket_example.c | 207 --- .../pubsub_websocket/resources/index.html | 60 - .../pubsub_websocket/resources/script.js | 54 - .../examples/pubsub/subscriber/CMakeLists.txt | 52 - .../include/pubsub_subscriber_private.h | 50 - .../subscriber/private/src/ps_sub_activator.c | 113 -- .../private/src/pubsub_subscriber.c | 71 - bundles/pubsub/integration/CMakeLists.txt | 505 ------ .../PubSubEndpointIntegrationTestSuite.cc | 70 - .../gtest/PubSubIntegrationTestSuite.cc | 119 -- .../gtest/PubSubInterceptorTestSuite.cc | 235 --- ...PubSubTopicAndScopeIntegrationTestSuite.cc | 69 - .../gtest/PubSubWebsocketTestMain.cc | 28 - .../integration/gtest/loopback_activator.c | 99 -- bundles/pubsub/integration/gtest/msg.h | 31 - .../integration/gtest/receive_count_service.h | 30 - .../integration/gtest/serializer_activator.cc | 87 - .../pubsub/integration/gtest/sut_activator.c | 118 -- .../gtest/sut_endpoint_activator.c | 120 -- .../pubsub/integration/gtest/tst_activator.c | 138 -- .../gtest/tst_endpoint_activator.c | 103 -- .../meta_data/deadlock.scope.properties | 28 - .../meta_data/deadlock.scope2.properties | 28 - .../integration/meta_data/msg.descriptor | 9 - .../integration/meta_data/ping.properties | 29 - .../integration/meta_data/ping2.properties | 23 - .../integration/meta_data/ping3.properties | 22 - .../integration/meta_data/pong2.properties | 23 - .../integration/meta_data/pong3.properties | 22 - .../pstm_deadlock_test/test_runner.cc | 161 -- bundles/pubsub/keygen/CMakeLists.txt | 30 - bundles/pubsub/keygen/ed_file.c | 309 ---- bundles/pubsub/keygen/makecert.c | 54 - .../pubsub/pubsub_admin_tcp/CMakeLists.txt | 45 - .../pubsub_admin_tcp/src/psa_activator.c | 128 -- .../src/pubsub_psa_tcp_constants.h | 140 -- .../pubsub_admin_tcp/src/pubsub_tcp_admin.c | 710 -------- .../pubsub_admin_tcp/src/pubsub_tcp_admin.h | 87 - .../pubsub_admin_tcp/src/pubsub_tcp_common.c | 39 - .../pubsub_admin_tcp/src/pubsub_tcp_common.h | 33 - .../pubsub_admin_tcp/src/pubsub_tcp_handler.c | 1451 ----------------- .../pubsub_admin_tcp/src/pubsub_tcp_handler.h | 92 -- .../src/pubsub_tcp_topic_receiver.c | 674 -------- .../src/pubsub_tcp_topic_receiver.h | 56 - .../src/pubsub_tcp_topic_sender.c | 435 ----- .../src/pubsub_tcp_topic_sender.h | 52 - .../pubsub_admin_websocket/CMakeLists.txt | 44 - .../src/psa_activator.c | 100 -- .../src/pubsub_psa_websocket_constants.h | 61 - .../src/pubsub_websocket_admin.c | 533 ------ .../src/pubsub_websocket_admin.h | 64 - .../src/pubsub_websocket_common.c | 68 - .../src/pubsub_websocket_common.h | 43 - .../src/pubsub_websocket_topic_receiver.c | 733 --------- .../src/pubsub_websocket_topic_receiver.h | 48 - .../src/pubsub_websocket_topic_sender.c | 330 ---- .../src/pubsub_websocket_topic_sender.h | 43 - .../pubsub/pubsub_admin_zmq/CMakeLists.txt | 58 - .../pubsub_admin_zmq/src/psa_activator.c | 115 -- .../src/pubsub_psa_zmq_constants.h | 108 -- .../pubsub_admin_zmq/src/pubsub_zmq_admin.c | 799 --------- .../pubsub_admin_zmq/src/pubsub_zmq_admin.h | 52 - .../src/pubsub_zmq_topic_receiver.c | 710 -------- .../src/pubsub_zmq_topic_receiver.h | 53 - .../src/pubsub_zmq_topic_sender.c | 559 ------- .../src/pubsub_zmq_topic_sender.h | 55 - .../pubsub/pubsub_admin_zmq/src/zmq_crypto.c | 278 ---- .../pubsub/pubsub_admin_zmq/src/zmq_crypto.h | 41 - bundles/pubsub/pubsub_api/CMakeLists.txt | 33 - .../pubsub/pubsub_api/include/pubsub/api.h | 28 - .../pubsub_api/include/pubsub/publisher.h | 78 - .../pubsub_api/include/pubsub/subscriber.h | 80 - .../pubsub/pubsub_discovery/CMakeLists.txt | 43 - .../pubsub_discovery/src/psd_activator.c | 105 -- .../src/pubsub_discovery_impl.c | 639 -------- .../src/pubsub_discovery_impl.h | 100 -- bundles/pubsub/pubsub_protocol/CMakeLists.txt | 21 - .../pubsub_protocol_lib/CMakeLists.txt | 26 - .../pubsub_protocol_lib/gtest/CMakeLists.txt | 32 - .../gtest/src/PS_WP_common_ei_tests.cc | 233 --- .../gtest/src/PS_WP_common_tests.cc | 311 ---- .../include/pubsub_wire_protocol_common.h | 86 - .../src/pubsub_wire_protocol_common.c | 313 ---- .../pubsub_protocol_wire_v1/CMakeLists.txt | 48 - .../gtest/CMakeLists.txt | 28 - .../gtest/src/PS_WP_tests.cc | 323 ---- .../pubsub_protocol_wire_v1/gtest/src/main.cc | 26 - .../src/ps_wire_protocol_activator.c | 72 - .../src/pubsub_wire_protocol_impl.c | 177 -- .../src/pubsub_wire_protocol_impl.h | 57 - .../pubsub_protocol_wire_v2/CMakeLists.txt | 45 - .../gtest/CMakeLists.txt | 28 - .../gtest/src/PS_WP_v2_tests.cc | 309 ---- .../pubsub_protocol_wire_v2/gtest/src/main.cc | 26 - .../src/ps_wire_v2_protocol_activator.c | 73 - .../src/pubsub_wire_v2_protocol_impl.c | 210 --- .../src/pubsub_wire_v2_protocol_impl.h | 58 - .../pubsub_serializer_avrobin/CMakeLists.txt | 46 - .../gtest/CMakeLists.txt | 36 - .../gtest/msg_descriptors/msg_poi1.descriptor | 10 - ...ubAvrobinSerializationProviderTestSuite.cc | 110 -- .../src/ps_avrobin_serializer_activator.c | 40 - .../pubsub_avrobin_serialization_provider.c | 120 -- .../pubsub_avrobin_serialization_provider.h | 40 - .../pubsub_serializer_json/CMakeLists.txt | 47 - .../gtest/CMakeLists.txt | 36 - .../gtest/msg_descriptors/msg_poi1.descriptor | 10 - ...ubSubJsonSerializationProviderTestSuite.cc | 117 -- .../src/ps_json_serializer_activator.c | 41 - .../src/pubsub_json_serialization_provider.c | 117 -- .../src/pubsub_json_serialization_provider.h | 43 - bundles/pubsub/pubsub_spi/CMakeLists.txt | 45 - .../pubsub/pubsub_spi/gtest/CMakeLists.txt | 24 - .../gtest/src/PubSubEndpointUtilsTestSuite.cc | 47 - .../pubsub/pubsub_spi/include/pubsub_admin.h | 67 - .../pubsub_spi/include/pubsub_admin_metrics.h | 113 -- .../pubsub_spi/include/pubsub_constants.h | 47 - .../pubsub_spi/include/pubsub_endpoint.h | 90 - .../pubsub_spi/include/pubsub_interceptor.h | 116 -- .../include/pubsub_interceptors_handler.h | 81 - .../pubsub_spi/include/pubsub_listeners.h | 57 - .../pubsub_message_serialization_marker.h | 67 - .../pubsub_message_serialization_service.h | 102 -- .../pubsub_spi/include/pubsub_protocol.h | 270 --- .../pubsub_spi/src/pubsub_admin_metrics.c | 51 - .../pubsub/pubsub_spi/src/pubsub_endpoint.c | 230 --- .../pubsub_spi/src/pubsub_endpoint_match.c | 35 - .../src/pubsub_interceptors_handler.c | 216 --- .../pubsub_topology_manager/CMakeLists.txt | 37 - .../src/pstm_activator.c | 162 -- .../src/pubsub_topology_manager.c | 1406 ---------------- .../src/pubsub_topology_manager.h | 136 -- bundles/pubsub/pubsub_utils/CMakeLists.txt | 44 - .../pubsub/pubsub_utils/gtest/CMakeLists.txt | 60 - .../gtest/msg_descriptors/fiets.properties | 39 - .../gtest/msg_descriptors/garbage.descriptor | 1 - .../gtest/msg_descriptors/int_calc.descriptor | 13 - .../gtest/msg_descriptors/msg_poi1.descriptor | 10 - .../msg_poi2_variant1.descriptor | 11 - .../msg_poi2_variant2.descriptor | 11 - .../msg_poi3_variant1.descriptor | 11 - .../msg_poi3_variant2.descriptor | 12 - .../msg_poi4_variant1.descriptor | 12 - .../msg_poi4_variant2.descriptor | 12 - .../msg_descriptors/msg_poiCmd.descriptor | 8 - .../gtest/src/PubSubMatchingTestSuite.cpp | 183 --- .../PubSubSerializationHandlerTestSuite.cc | 339 ---- .../PubSubSerializationProviderTestSuite.cc | 71 - .../pubsub_utils/include/pubsub_matching.h | 140 -- .../include/pubsub_serialization_provider.h | 127 -- .../include/pubsub_serializer_handler.h | 206 --- .../pubsub_utils/include/pubsub_utils.h | 99 -- .../pubsub_utils/include/pubsub_utils_url.h | 55 - .../pubsub/pubsub_utils/src/pubsub_matching.c | 302 ---- .../src/pubsub_serialization_provider.c | 729 --------- .../src/pubsub_serializer_handler.c | 482 ------ .../pubsub/pubsub_utils/src/pubsub_utils.c | 198 --- .../pubsub_utils/src/pubsub_utils_url.c | 344 ---- examples/conan_test_package/CMakeLists.txt | 82 - .../conan_test_package/my_psa_activator.c | 154 -- libs/pushstreams/api/celix/PushStream.h | 2 +- 201 files changed, 271 insertions(+), 26016 deletions(-) delete mode 100644 bundles/cxx_remote_services/integration/resources/Calculator$add$Invoke.descriptor delete mode 100644 bundles/cxx_remote_services/integration/resources/Calculator$add$Return.descriptor delete mode 100644 bundles/cxx_remote_services/integration/resources/Calculator$result$Event.descriptor delete mode 100644 bundles/pubsub/CMakeLists.txt delete mode 100644 bundles/pubsub/README.md delete mode 100644 bundles/pubsub/doc/pubsub_serialization.adoc delete mode 100644 bundles/pubsub/examples/CMakeLists.txt delete mode 100644 bundles/pubsub/examples/keys/README.md delete mode 100644 bundles/pubsub/examples/keys/publisher/private/.gitkeep delete mode 100644 bundles/pubsub/examples/keys/publisher/public/.gitkeep delete mode 100644 bundles/pubsub/examples/keys/subscriber/private/.gitkeep delete mode 100644 bundles/pubsub/examples/keys/subscriber/public/.gitkeep delete mode 100644 bundles/pubsub/examples/pubsub/CMakeLists.txt delete mode 100644 bundles/pubsub/examples/pubsub/common/include/poi.h delete mode 100644 bundles/pubsub/examples/pubsub/common/include/poiCmd.h delete mode 100644 bundles/pubsub/examples/pubsub/interceptors/CMakeLists.txt delete mode 100644 bundles/pubsub/examples/pubsub/interceptors/include/first_interceptor_private.h delete mode 100644 bundles/pubsub/examples/pubsub/interceptors/include/second_interceptor_private.h delete mode 100644 bundles/pubsub/examples/pubsub/interceptors/src/first_interceptor.c delete mode 100644 bundles/pubsub/examples/pubsub/interceptors/src/ps_interceptor_activator.c delete mode 100644 bundles/pubsub/examples/pubsub/interceptors/src/second_interceptor.c delete mode 100644 bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor delete mode 100644 bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor delete mode 100644 bundles/pubsub/examples/pubsub/msg_descriptors/msg_poiCmd.descriptor delete mode 100644 bundles/pubsub/examples/pubsub/msg_descriptors/poi1.properties delete mode 100644 bundles/pubsub/examples/pubsub/msg_descriptors/poi2.properties delete mode 100644 bundles/pubsub/examples/pubsub/msg_descriptors/poiCmd.properties delete mode 100644 bundles/pubsub/examples/pubsub/publisher/CMakeLists.txt delete mode 100644 bundles/pubsub/examples/pubsub/publisher/private/include/pubsub_publisher_private.h delete mode 100644 bundles/pubsub/examples/pubsub/publisher/private/src/ps_pub_activator.c delete mode 100644 bundles/pubsub/examples/pubsub/publisher/private/src/pubsub_publisher.c delete mode 100644 bundles/pubsub/examples/pubsub/publisher2/CMakeLists.txt delete mode 100644 bundles/pubsub/examples/pubsub/pubsub_websocket/CMakeLists.txt delete mode 100644 bundles/pubsub/examples/pubsub/pubsub_websocket/private/include/pubsub_websocket_private.h delete mode 100644 bundles/pubsub/examples/pubsub/pubsub_websocket/private/src/ps_websocket_activator.c delete mode 100644 bundles/pubsub/examples/pubsub/pubsub_websocket/private/src/pubsub_websocket_example.c delete mode 100644 bundles/pubsub/examples/pubsub/pubsub_websocket/resources/index.html delete mode 100644 bundles/pubsub/examples/pubsub/pubsub_websocket/resources/script.js delete mode 100644 bundles/pubsub/examples/pubsub/subscriber/CMakeLists.txt delete mode 100644 bundles/pubsub/examples/pubsub/subscriber/private/include/pubsub_subscriber_private.h delete mode 100644 bundles/pubsub/examples/pubsub/subscriber/private/src/ps_sub_activator.c delete mode 100644 bundles/pubsub/examples/pubsub/subscriber/private/src/pubsub_subscriber.c delete mode 100644 bundles/pubsub/integration/CMakeLists.txt delete mode 100644 bundles/pubsub/integration/gtest/PubSubEndpointIntegrationTestSuite.cc delete mode 100644 bundles/pubsub/integration/gtest/PubSubIntegrationTestSuite.cc delete mode 100644 bundles/pubsub/integration/gtest/PubSubInterceptorTestSuite.cc delete mode 100644 bundles/pubsub/integration/gtest/PubSubTopicAndScopeIntegrationTestSuite.cc delete mode 100644 bundles/pubsub/integration/gtest/PubSubWebsocketTestMain.cc delete mode 100644 bundles/pubsub/integration/gtest/loopback_activator.c delete mode 100644 bundles/pubsub/integration/gtest/msg.h delete mode 100644 bundles/pubsub/integration/gtest/receive_count_service.h delete mode 100644 bundles/pubsub/integration/gtest/serializer_activator.cc delete mode 100644 bundles/pubsub/integration/gtest/sut_activator.c delete mode 100644 bundles/pubsub/integration/gtest/sut_endpoint_activator.c delete mode 100644 bundles/pubsub/integration/gtest/tst_activator.c delete mode 100644 bundles/pubsub/integration/gtest/tst_endpoint_activator.c delete mode 100644 bundles/pubsub/integration/meta_data/deadlock.scope.properties delete mode 100644 bundles/pubsub/integration/meta_data/deadlock.scope2.properties delete mode 100644 bundles/pubsub/integration/meta_data/msg.descriptor delete mode 100644 bundles/pubsub/integration/meta_data/ping.properties delete mode 100644 bundles/pubsub/integration/meta_data/ping2.properties delete mode 100644 bundles/pubsub/integration/meta_data/ping3.properties delete mode 100644 bundles/pubsub/integration/meta_data/pong2.properties delete mode 100644 bundles/pubsub/integration/meta_data/pong3.properties delete mode 100644 bundles/pubsub/integration/pstm_deadlock_test/test_runner.cc delete mode 100644 bundles/pubsub/keygen/CMakeLists.txt delete mode 100644 bundles/pubsub/keygen/ed_file.c delete mode 100644 bundles/pubsub/keygen/makecert.c delete mode 100644 bundles/pubsub/pubsub_admin_tcp/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_admin_tcp/src/psa_activator.c delete mode 100644 bundles/pubsub/pubsub_admin_tcp/src/pubsub_psa_tcp_constants.h delete mode 100644 bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_admin.c delete mode 100644 bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_admin.h delete mode 100644 bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_common.c delete mode 100644 bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_common.h delete mode 100644 bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_handler.c delete mode 100644 bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_handler.h delete mode 100644 bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_receiver.c delete mode 100644 bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_receiver.h delete mode 100644 bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_sender.c delete mode 100644 bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_sender.h delete mode 100644 bundles/pubsub/pubsub_admin_websocket/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_admin_websocket/src/psa_activator.c delete mode 100644 bundles/pubsub/pubsub_admin_websocket/src/pubsub_psa_websocket_constants.h delete mode 100644 bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_admin.c delete mode 100644 bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_admin.h delete mode 100644 bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_common.c delete mode 100644 bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_common.h delete mode 100644 bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_receiver.c delete mode 100644 bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_receiver.h delete mode 100644 bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_sender.c delete mode 100644 bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_sender.h delete mode 100644 bundles/pubsub/pubsub_admin_zmq/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_admin_zmq/src/psa_activator.c delete mode 100644 bundles/pubsub/pubsub_admin_zmq/src/pubsub_psa_zmq_constants.h delete mode 100644 bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_admin.c delete mode 100644 bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_admin.h delete mode 100644 bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_receiver.c delete mode 100644 bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_receiver.h delete mode 100644 bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_sender.c delete mode 100644 bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_sender.h delete mode 100644 bundles/pubsub/pubsub_admin_zmq/src/zmq_crypto.c delete mode 100644 bundles/pubsub/pubsub_admin_zmq/src/zmq_crypto.h delete mode 100644 bundles/pubsub/pubsub_api/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_api/include/pubsub/api.h delete mode 100644 bundles/pubsub/pubsub_api/include/pubsub/publisher.h delete mode 100644 bundles/pubsub/pubsub_api/include/pubsub/subscriber.h delete mode 100644 bundles/pubsub/pubsub_discovery/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_discovery/src/psd_activator.c delete mode 100644 bundles/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c delete mode 100644 bundles/pubsub/pubsub_discovery/src/pubsub_discovery_impl.h delete mode 100644 bundles/pubsub/pubsub_protocol/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/gtest/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/gtest/src/PS_WP_common_ei_tests.cc delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/gtest/src/PS_WP_common_tests.cc delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/include/pubsub_wire_protocol_common.h delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/src/pubsub_wire_protocol_common.c delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/gtest/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/gtest/src/PS_WP_tests.cc delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/gtest/src/main.cc delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/src/ps_wire_protocol_activator.c delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/src/pubsub_wire_protocol_impl.c delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/src/pubsub_wire_protocol_impl.h delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/gtest/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/gtest/src/PS_WP_v2_tests.cc delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/gtest/src/main.cc delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/src/ps_wire_v2_protocol_activator.c delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/src/pubsub_wire_v2_protocol_impl.c delete mode 100644 bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/src/pubsub_wire_v2_protocol_impl.h delete mode 100644 bundles/pubsub/pubsub_serializer_avrobin/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_serializer_avrobin/gtest/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_serializer_avrobin/gtest/msg_descriptors/msg_poi1.descriptor delete mode 100644 bundles/pubsub/pubsub_serializer_avrobin/gtest/src/PubSubAvrobinSerializationProviderTestSuite.cc delete mode 100644 bundles/pubsub/pubsub_serializer_avrobin/src/ps_avrobin_serializer_activator.c delete mode 100644 bundles/pubsub/pubsub_serializer_avrobin/src/pubsub_avrobin_serialization_provider.c delete mode 100644 bundles/pubsub/pubsub_serializer_avrobin/src/pubsub_avrobin_serialization_provider.h delete mode 100644 bundles/pubsub/pubsub_serializer_json/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_serializer_json/gtest/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_serializer_json/gtest/msg_descriptors/msg_poi1.descriptor delete mode 100644 bundles/pubsub/pubsub_serializer_json/gtest/src/PubSubJsonSerializationProviderTestSuite.cc delete mode 100644 bundles/pubsub/pubsub_serializer_json/src/ps_json_serializer_activator.c delete mode 100644 bundles/pubsub/pubsub_serializer_json/src/pubsub_json_serialization_provider.c delete mode 100644 bundles/pubsub/pubsub_serializer_json/src/pubsub_json_serialization_provider.h delete mode 100644 bundles/pubsub/pubsub_spi/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_spi/gtest/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_spi/gtest/src/PubSubEndpointUtilsTestSuite.cc delete mode 100644 bundles/pubsub/pubsub_spi/include/pubsub_admin.h delete mode 100644 bundles/pubsub/pubsub_spi/include/pubsub_admin_metrics.h delete mode 100644 bundles/pubsub/pubsub_spi/include/pubsub_constants.h delete mode 100644 bundles/pubsub/pubsub_spi/include/pubsub_endpoint.h delete mode 100644 bundles/pubsub/pubsub_spi/include/pubsub_interceptor.h delete mode 100644 bundles/pubsub/pubsub_spi/include/pubsub_interceptors_handler.h delete mode 100644 bundles/pubsub/pubsub_spi/include/pubsub_listeners.h delete mode 100644 bundles/pubsub/pubsub_spi/include/pubsub_message_serialization_marker.h delete mode 100644 bundles/pubsub/pubsub_spi/include/pubsub_message_serialization_service.h delete mode 100644 bundles/pubsub/pubsub_spi/include/pubsub_protocol.h delete mode 100644 bundles/pubsub/pubsub_spi/src/pubsub_admin_metrics.c delete mode 100644 bundles/pubsub/pubsub_spi/src/pubsub_endpoint.c delete mode 100644 bundles/pubsub/pubsub_spi/src/pubsub_endpoint_match.c delete mode 100644 bundles/pubsub/pubsub_spi/src/pubsub_interceptors_handler.c delete mode 100644 bundles/pubsub/pubsub_topology_manager/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_topology_manager/src/pstm_activator.c delete mode 100644 bundles/pubsub/pubsub_topology_manager/src/pubsub_topology_manager.c delete mode 100644 bundles/pubsub/pubsub_topology_manager/src/pubsub_topology_manager.h delete mode 100644 bundles/pubsub/pubsub_utils/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_utils/gtest/CMakeLists.txt delete mode 100644 bundles/pubsub/pubsub_utils/gtest/msg_descriptors/fiets.properties delete mode 100644 bundles/pubsub/pubsub_utils/gtest/msg_descriptors/garbage.descriptor delete mode 100644 bundles/pubsub/pubsub_utils/gtest/msg_descriptors/int_calc.descriptor delete mode 100644 bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi1.descriptor delete mode 100644 bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi2_variant1.descriptor delete mode 100644 bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi2_variant2.descriptor delete mode 100644 bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi3_variant1.descriptor delete mode 100644 bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi3_variant2.descriptor delete mode 100644 bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi4_variant1.descriptor delete mode 100644 bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi4_variant2.descriptor delete mode 100644 bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poiCmd.descriptor delete mode 100644 bundles/pubsub/pubsub_utils/gtest/src/PubSubMatchingTestSuite.cpp delete mode 100644 bundles/pubsub/pubsub_utils/gtest/src/PubSubSerializationHandlerTestSuite.cc delete mode 100644 bundles/pubsub/pubsub_utils/gtest/src/PubSubSerializationProviderTestSuite.cc delete mode 100644 bundles/pubsub/pubsub_utils/include/pubsub_matching.h delete mode 100644 bundles/pubsub/pubsub_utils/include/pubsub_serialization_provider.h delete mode 100644 bundles/pubsub/pubsub_utils/include/pubsub_serializer_handler.h delete mode 100644 bundles/pubsub/pubsub_utils/include/pubsub_utils.h delete mode 100644 bundles/pubsub/pubsub_utils/include/pubsub_utils_url.h delete mode 100644 bundles/pubsub/pubsub_utils/src/pubsub_matching.c delete mode 100644 bundles/pubsub/pubsub_utils/src/pubsub_serialization_provider.c delete mode 100644 bundles/pubsub/pubsub_utils/src/pubsub_serializer_handler.c delete mode 100644 bundles/pubsub/pubsub_utils/src/pubsub_utils.c delete mode 100644 bundles/pubsub/pubsub_utils/src/pubsub_utils_url.c delete mode 100644 examples/conan_test_package/my_psa_activator.c diff --git a/bundles/CMakeLists.txt b/bundles/CMakeLists.txt index e2d92333e..deb285cfb 100644 --- a/bundles/CMakeLists.txt +++ b/bundles/CMakeLists.txt @@ -20,6 +20,5 @@ add_subdirectory(http_admin) add_subdirectory(logging) add_subdirectory(shell) add_subdirectory(remote_services) -add_subdirectory(pubsub) add_subdirectory(cxx_remote_services) add_subdirectory(components_ready_check) diff --git a/bundles/cxx_remote_services/integration/CMakeLists.txt b/bundles/cxx_remote_services/integration/CMakeLists.txt index 65ce33300..b19715fc2 100644 --- a/bundles/cxx_remote_services/integration/CMakeLists.txt +++ b/bundles/cxx_remote_services/integration/CMakeLists.txt @@ -20,14 +20,8 @@ if (CXX_RSA_INTEGRATION) add_celix_bundle(TestExportImportRemoteServiceFactory SOURCES src/TestExportImportRemoteServiceFactory.cc ) - target_link_libraries(TestExportImportRemoteServiceFactory PRIVATE Celix::rsa_spi Celix::pubsub_api Celix::Promises Celix::PushStreams Celix::log_helper) + target_link_libraries(TestExportImportRemoteServiceFactory PRIVATE Celix::rsa_spi Celix::Promises Celix::PushStreams Celix::log_helper) target_include_directories(TestExportImportRemoteServiceFactory PRIVATE include) - celix_bundle_files(TestExportImportRemoteServiceFactory - resources/Calculator$add$Invoke.descriptor - resources/Calculator$result$Event.descriptor - resources/Calculator$add$Return.descriptor - DESTINATION "META-INF/descriptors" - ) add_celix_bundle(CalculatorProvider SOURCES src/CalculatorProvider.cc @@ -42,30 +36,22 @@ if (CXX_RSA_INTEGRATION) target_link_libraries(CalculatorConsumer PRIVATE Celix::Promises Celix::PushStreams Celix::shell_api Celix::RsaConfiguredDiscovery_api) target_include_directories(CalculatorConsumer PRIVATE include) - if (ENABLE_TESTING) - add_subdirectory(gtest) - endif() +# if (ENABLE_TESTING) +# add_subdirectory(gtest) +# endif() ################# Integration examples ################################## if (BUILD_LAUNCHER) add_celix_container(RemoteCalculatorProvider - LAUNCHER Celix::launcher - GROUP rsa - USE_CONFIG - PROPERTIES - CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=trace - BUNDLES + CXX + GROUP rsa + PROPERTIES + CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=debug + BUNDLES Celix::ShellCxx Celix::shell_tui - #Pubsub needed for remote services on pubsub - Celix::celix_pubsub_serializer_json - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_zmq - Celix::celix_pubsub_protocol_wire_v2 - Celix::celix_pubsub_discovery_etcd - #Remote Services Celix::RemoteServiceAdmin TestExportImportRemoteServiceFactory #needed to be able to create a ExportedService for ICalculator @@ -74,22 +60,14 @@ if (CXX_RSA_INTEGRATION) ) add_celix_container(RemoteCalculatorConsumer - LAUNCHER Celix::launcher - GROUP rsa - USE_CONFIG - PROPERTIES - CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=trace - BUNDLES + CXX + GROUP rsa + PROPERTIES + CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=debug + BUNDLES Celix::ShellCxx Celix::shell_tui - #Pubsub needed for remote services on pubsub - Celix::celix_pubsub_serializer_json - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_discovery_etcd - Celix::celix_pubsub_admin_zmq - Celix::celix_pubsub_protocol_wire_v2 - #Remote Services Celix::RsaConfiguredDiscovery Celix::RemoteServiceAdmin diff --git a/bundles/cxx_remote_services/integration/resources/Calculator$add$Invoke.descriptor b/bundles/cxx_remote_services/integration/resources/Calculator$add$Invoke.descriptor deleted file mode 100644 index 74777de40..000000000 --- a/bundles/cxx_remote_services/integration/resources/Calculator$add$Invoke.descriptor +++ /dev/null @@ -1,9 +0,0 @@ -:header -type=message -name=Calculator$add$Invoke -version=1.0.0 -:annotations -classname=Calculator$add$Invoke -:types -:message -{DD arg1 arg2} diff --git a/bundles/cxx_remote_services/integration/resources/Calculator$add$Return.descriptor b/bundles/cxx_remote_services/integration/resources/Calculator$add$Return.descriptor deleted file mode 100644 index 50e822816..000000000 --- a/bundles/cxx_remote_services/integration/resources/Calculator$add$Return.descriptor +++ /dev/null @@ -1,9 +0,0 @@ -:header -type=message -name=Calculator$add$Return -version=1.0.0 -:annotations -classname=Calculator$add$Return -:types -:message -{[Dt optionalReturnValue optionalError} diff --git a/bundles/cxx_remote_services/integration/resources/Calculator$result$Event.descriptor b/bundles/cxx_remote_services/integration/resources/Calculator$result$Event.descriptor deleted file mode 100644 index fb1e018a7..000000000 --- a/bundles/cxx_remote_services/integration/resources/Calculator$result$Event.descriptor +++ /dev/null @@ -1,9 +0,0 @@ -:header -type=message -name=Calculator$result$Event -version=1.0.0 -:annotations -classname=Calculator$result$Event -:types -:message -{[Dt optionalReturnValue optionalError} diff --git a/bundles/cxx_remote_services/integration/src/CalculatorConsumer.cc b/bundles/cxx_remote_services/integration/src/CalculatorConsumer.cc index 3e64082ef..35ceac042 100644 --- a/bundles/cxx_remote_services/integration/src/CalculatorConsumer.cc +++ b/bundles/cxx_remote_services/integration/src/CalculatorConsumer.cc @@ -47,8 +47,19 @@ class CalculatorConsumer final : public celix::IShellCommand { counter++; } + void start() { + stream = calculator->result(); + stream->forEach([](double val) { + fprintf(stdout, "calc result stream: %f\n", val); + }); + } + + void stop() { + stream.reset(); + } private: std::shared_ptr calculator{}; + std::shared_ptr> stream{}; }; class CalculatorConsumerActivator { @@ -60,6 +71,7 @@ class CalculatorConsumerActivator { .setCallbacks(&CalculatorConsumer::setCalculator); cmp.createProvidedService() .addProperty(celix::IShellCommand::COMMAND_NAME, "calc"); + cmp.setCallbacks(nullptr, &CalculatorConsumer::start, &CalculatorConsumer::stop, nullptr); cmp.build(); //bootstrap own configured import discovery to the configured discovery manager diff --git a/bundles/cxx_remote_services/integration/src/CalculatorProvider.cc b/bundles/cxx_remote_services/integration/src/CalculatorProvider.cc index da92530ad..57e86b00d 100644 --- a/bundles/cxx_remote_services/integration/src/CalculatorProvider.cc +++ b/bundles/cxx_remote_services/integration/src/CalculatorProvider.cc @@ -60,7 +60,7 @@ class CalculatorImpl final : public ICalculator { while(!stopThread) { ses->publish((double)counter); counter++; - std::this_thread::sleep_for(std::chrono::milliseconds{100}); + std::this_thread::sleep_for(std::chrono::milliseconds{5000}); } }); return CELIX_SUCCESS; diff --git a/bundles/cxx_remote_services/integration/src/TestExportImportRemoteServiceFactory.cc b/bundles/cxx_remote_services/integration/src/TestExportImportRemoteServiceFactory.cc index 75ec9487c..428e8d650 100644 --- a/bundles/cxx_remote_services/integration/src/TestExportImportRemoteServiceFactory.cc +++ b/bundles/cxx_remote_services/integration/src/TestExportImportRemoteServiceFactory.cc @@ -18,6 +18,8 @@ */ #include +#include +#include #include "celix/PromiseFactory.h" #include "celix/PushStream.h" @@ -28,40 +30,86 @@ #include "celix/LogHelper.h" #include "ICalculator.h" -#include "pubsub/publisher.h" -#include "pubsub/subscriber.h" constexpr auto INVOKE_TIMEOUT = std::chrono::milliseconds {500}; struct Calculator$add$Invoke { - double arg1{}; - double arg2{}; + long invokeId; + double arg1; + double arg2; }; struct Calculator$add$Return { - struct { - uint32_t cap{}; - uint32_t len{}; - double* buf{}; - } optionalReturnValue{}; - char* optionalError{}; + long invokeId; + double result; + bool hasError; + char errorMsg[512]; }; struct Calculator$result$Event { - struct { - uint32_t cap{}; - uint32_t len{}; - double* buf{}; - } optionalReturnValue{}; - char* optionalError{}; + double eventData; + bool hasError; + char errorMsg[512]; }; +struct Calculator$add$InvokeIpcMsg { + long mtype; //1 + Calculator$add$Invoke mtext; +}; + +struct Calculator$add$ReturnIpcMsg { + long mtype; //2 + Calculator$add$Return mtext; +}; + +struct Calculator$result$EventIpcMsg { + long mtype; //3 + Calculator$result$Event mtext; +}; + +class IpcException : public std::runtime_error { + public: + using std::runtime_error::runtime_error; +}; + +template +static std::optional receiveMsgFromIpc(const celix::LogHelper& logHelper, int qidReceiver, long mtype) { + T msg{}; + msg.mtype = mtype; + int rc = msgrcv(qidReceiver, &msg, sizeof(msg.mtext), mtype, MSG_NOERROR | IPC_NOWAIT); + if (rc == -1) { + if (errno != ENOMSG) { + throw IpcException{std::string{"Error receiving message from queue: "} + strerror(errno)}; + } else { + logHelper.trace("No message available for msgrcv()"); + } + return {}; + } else if (rc != sizeof(msg.mtext)) { + throw IpcException{ + "Error receiving message from queue: Received message size does not match expected size. Got " + + std::to_string(rc) + " expected " + std::to_string(sizeof(msg.mtext))}; + } + return msg; +} + +template +static void sendMsgWithIpc(const celix::LogHelper& logHelper, int qidSender, const T& msg) { + int rc = msgsnd(qidSender, &msg, sizeof(msg.mtext), IPC_NOWAIT); + if (rc == EAGAIN) { + logHelper.warning("Cannot send message to queue. Queue is full."); + } else if (rc == -1) { + logHelper.error("Error sending message to queue: %s", strerror(errno)); + } +} + /** * A importedCalculater which acts as a pubsub proxy to a imported remote service. */ class ImportedCalculator final : public ICalculator { public: - explicit ImportedCalculator(celix::LogHelper _logHelper) : logHelper{std::move(_logHelper)} {} + explicit ImportedCalculator(celix::LogHelper _logHelper) : logHelper{std::move(_logHelper)} { + setupMsgIpc(); + } ~ImportedCalculator() noexcept override { //failing al leftover deferreds @@ -72,93 +120,27 @@ class ImportedCalculator final : public ICalculator { } } }; -public: std::shared_ptr> result() override { return stream; } celix::Promise add(double a, double b) override { - //setup msg id - thread_local unsigned int invokeMsgId = 0; - if (invokeMsgId == 0) { - publisher->localMsgTypeIdForMsgType(publisher->handle, "Calculator$add$Invoke", &invokeMsgId); - } + //sending Calculator$add$Invoke (mtype=1) to qidSender + Calculator$add$InvokeIpcMsg msg{}; + msg.mtype = 1; + msg.mtext.invokeId = nextInvokeId++; + msg.mtext.arg1 = a; + msg.mtext.arg2 = b; + + sendMsgWithIpc(logHelper, qidSender, msg); - long invokeId = nextInvokeId++; std::lock_guard lck{mutex}; auto deferred = factory->deferred(); - deferreds.emplace(invokeId, deferred); - if (invokeMsgId > 0) { - Calculator$add$Invoke invoke; - invoke.arg1 = a; - invoke.arg2 = b; - auto* meta = celix_properties_create(); - celix_properties_setLong(meta, "invoke.id", invokeId); - int rc = publisher->send(publisher->handle, invokeMsgId, &invoke, meta); - if (rc != 0) { - constexpr auto msg = "error sending invoke msg"; - logHelper.error(msg); - deferred.fail(celix::rsa::RemoteServicesException{msg}); - } - } else { - constexpr auto msg = "error getting msg id for invoke msg"; - logHelper.error(msg); - deferred.fail(celix::rsa::RemoteServicesException{msg}); - } + deferreds.emplace(msg.mtext.invokeId, deferred); return deferred.getPromise().setTimeout(INVOKE_TIMEOUT); } - void receive(const char *msgType, unsigned int msgTypeId, void *msg, const celix_properties_t* meta) { - //setup message ids - thread_local unsigned int returnAddMsgId = 0; - thread_local unsigned int streamResultMsgId = 0; - - if (returnAddMsgId == 0 && celix_utils_stringEquals(msgType, "Calculator$add$Return")) { - returnAddMsgId = msgTypeId; - } - if (streamResultMsgId == 0 && celix_utils_stringEquals(msgType, "Calculator$result$Event")) { - streamResultMsgId = msgTypeId; - } - - //handle incoming messages - if (streamResultMsgId != 0 && streamResultMsgId == msgTypeId) { - long invokeId = celix_properties_getAsLong(meta, "invoke.id", -1); - if (invokeId == -1) { - logHelper.error("Cannot find invoke id on metadata"); - return; - } - auto* result = static_cast(msg); - if (result->optionalReturnValue.len == 1) { - ses->publish(result->optionalReturnValue.buf[0]); - } else { - ses->close(); - } - } else if (returnAddMsgId != 0 && returnAddMsgId == msgTypeId) { - long invokeId = celix_properties_getAsLong(meta, "invoke.id", -1); - if (invokeId == -1) { - logHelper.error("Cannot find invoke id on metadata"); - return; - } - auto* result = static_cast(msg); - std::unique_lock lock{mutex}; - auto it = deferreds.find(invokeId); - if (it == end(deferreds)) { - logHelper.error("Cannot find deferred for invoke id %li", invokeId); - return; - } - auto deferred = it->second; - deferreds.erase(it); - lock.unlock(); - if (result->optionalReturnValue.len == 1) { - deferred.resolve(result->optionalReturnValue.buf[0]); - } else { - deferred.fail(celix::rsa::RemoteServicesException{"Failed resolving remote promise"}); - } - } else { - logHelper.warning("Unexpected message type %s", msgType); - } - } int init() { return CELIX_SUCCESS; } @@ -166,10 +148,22 @@ class ImportedCalculator final : public ICalculator { int start() { ses = psp->createSynchronousEventSource(factory); stream = psp->createStream(ses, factory); + running.store(true, std::memory_order::memory_order_release); + receiveThread = std::thread{[this]{ + while (running.load(std::memory_order::memory_order_consume)) { + receiveMessages(); + cleanupResolvedDeferreds(); + //note for example purposes, sleep instead of blocking with cond is used. + std::this_thread::sleep_for(std::chrono::milliseconds{10}); + } + }}; return CELIX_SUCCESS; } int stop() { + running.store(false, std::memory_order::memory_order_release); + receiveThread.join(); + receiveThread = {}; ses->close(); ses.reset(); stream.reset(); @@ -180,11 +174,6 @@ class ImportedCalculator final : public ICalculator { return CELIX_SUCCESS; } - void setPublisher(const std::shared_ptr& pub) { - std::lock_guard lock{mutex}; - publisher = pub; - } - void setPromiseFactory(const std::shared_ptr& fac) { std::lock_guard lock{mutex}; factory = fac; @@ -196,15 +185,97 @@ class ImportedCalculator final : public ICalculator { } private: + void setupMsgIpc() { + int keySender = 1234; // TODO make configurable + int keyReceiver = 1235; // TODO make configurable + qidSender = msgget(keySender, 0666 | IPC_CREAT); + qidReceiver = msgget(keyReceiver, 0666 | IPC_CREAT); + + if (qidSender == -1 || qidReceiver == -1) { + throw std::logic_error{"RsaShmClient: Error creating msg queue."}; + } + } + + void receiveMessages() { + receiveCalculator$add$Return(); + receiveCalculator$result$Event(); + } + + void receiveCalculator$add$Return() { + //receiving Calculator$add$Return (mtype=2) from qidReceiver + try { + auto msg = receiveMsgFromIpc(logHelper, qidReceiver, 2); + if (!msg) { + return; // no message available (yet) + } + auto& ret = msg.value().mtext; + + std::unique_lock lock{mutex}; + auto it = deferreds.find(ret.invokeId); + if (it == end(deferreds)) { + logHelper.error("Cannot find deferred for invoke id %li", ret.invokeId); + return; + } + auto deferred = it->second; + deferreds.erase(it); + lock.unlock(); + + if (ret.hasError) { + deferred.fail(celix::rsa::RemoteServicesException{ret.errorMsg}); + } else { + deferred.resolve(ret.result); + } + } catch (const IpcException& e) { + logHelper.error("IpcException: %s", e.what()); + } + } + + void receiveCalculator$result$Event() { + try { + auto msg = receiveMsgFromIpc(logHelper, qidReceiver, 3); + if (!msg) { + return; // no message available (yet) + } + auto event = msg.value().mtext; + + if (event.hasError) { + logHelper.error("Received error event %s", event.errorMsg); + ses->close(); + } else { + ses->publish(event.eventData); + } + } catch (const IpcException& e) { + logHelper.error("IpcException: %s", e.what()); + } + } + + /** + * @brief Clean up deferreds which are resolved (because of a timeout). + */ + void cleanupResolvedDeferreds() { + std::lock_guard lock{mutex}; + for (auto it = begin(deferreds); it != end(deferreds);) { + if (it->second.getPromise().isDone()) { + it = deferreds.erase(it); + } else { + ++it; + } + } + } + celix::LogHelper logHelper; std::atomic nextInvokeId{0}; + std::atomic running{false}; + std::thread receiveThread{}; std::mutex mutex{}; //protects below std::shared_ptr factory{}; - std::shared_ptr publisher{}; std::unordered_map> deferreds{}; std::shared_ptr psp {}; std::shared_ptr> ses{}; std::shared_ptr> stream{}; + + int qidSender{-1}; + int qidReceiver{-1}; }; /** @@ -261,11 +332,6 @@ class CalculatorImportServiceFactory final : public celix::rsa::IImportServiceFa auto scope = endpoint.getProperties().get("endpoint.scope"); auto& cmp = ctx->getDependencyManager()->createComponent(std::make_unique(logHelper)); - cmp.createServiceDependency(PUBSUB_PUBLISHER_SERVICE_NAME) - .setRequired(true) - .setStrategy(DependencyUpdateStrategy::suspend) - .setFilter(std::string{"(&(topic="}.append(invokeTopic).append(")(scope=").append(scope).append("))")) - .setCallbacks(&ImportedCalculator::setPublisher); cmp.createServiceDependency() .setRequired(true) .setStrategy(DependencyUpdateStrategy::suspend) @@ -277,22 +343,6 @@ class CalculatorImportServiceFactory final : public celix::rsa::IImportServiceFa cmp.setCallbacks(&ImportedCalculator::init, &ImportedCalculator::start, &ImportedCalculator::stop, &ImportedCalculator::deinit); - auto subscriber = std::make_shared(); - subscriber->handle = &cmp.getInstance(); - subscriber->receive = [](void *handle, const char *msgType, unsigned int msgTypeId, void *msg, const celix_properties_t *metadata, bool */*release*/) -> int { - auto* inst = static_cast(handle); - try { - inst->receive(msgType, msgTypeId, msg, metadata); - } catch (...) { - return -1; - } - return 0; - }; - cmp.addContext(subscriber); - cmp.createProvidedCService(subscriber.get(), PUBSUB_SUBSCRIBER_SERVICE_NAME) - .addProperty("topic", returnTopic) - .addProperty("scope", scope); - //Adding the imported service as provide celix::Properties svcProps{}; for (const auto& entry : endpoint.getProperties()) { @@ -323,71 +373,7 @@ class CalculatorImportServiceFactory final : public celix::rsa::IImportServiceFa class ExportedCalculator final { public: explicit ExportedCalculator(celix::LogHelper _logHelper) : logHelper{std::move(_logHelper)} { - - } - - void receive(const char *msgType, unsigned int msgTypeId, void *msg, const celix_properties_t* meta) { - //setup message ids - thread_local unsigned int invokeAddMsgId = 0; - if (invokeAddMsgId == 0 && celix_utils_stringEquals(msgType, "Calculator$add$Invoke")) { - invokeAddMsgId = msgTypeId; - } - thread_local unsigned int returnMsgId = 0; - if (returnMsgId == 0) { - publisher->localMsgTypeIdForMsgType(publisher->handle, "Calculator$add$Return", &returnMsgId); - } - - //handle incoming messages - if (invokeAddMsgId != 0 && invokeAddMsgId == msgTypeId) { - auto* invoke = static_cast(msg); - long invokeId = celix_properties_getAsLong(meta, "invoke.id", -1); - if (invokeId == -1) { - logHelper.error("Cannot find invoke id on metadata"); - return; - } - - auto* metaProps = celix_properties_create(); - celix_properties_set(metaProps, "invoke.id", std::to_string(invokeId).c_str()); - std::lock_guard lock{mutex}; - auto promise = calculator->add(invoke->arg1, invoke->arg2); - promise - .onFailure([logHelper = logHelper, weakPub = std::weak_ptr{publisher}, msgId = returnMsgId, metaProps](const auto& exp) { - auto pub = weakPub.lock(); - if (pub) { - Calculator$add$Return ret; - ret.optionalReturnValue.buf = nullptr; - ret.optionalReturnValue.len = 0; - ret.optionalReturnValue.cap = 0; - ret.optionalError = celix_utils_strdup(exp.what()); - pub->send(pub->handle, msgId, &ret, metaProps); - } else { - logHelper.error("publisher is gone"); - } - }) - .onSuccess([logHelper = logHelper, weakSvc = std::weak_ptr{calculator}, weakPub = std::weak_ptr{publisher}, msgId = returnMsgId, metaProps](auto val) { - auto pub = weakPub.lock(); - auto svc = weakSvc.lock(); - if (pub && svc) { - Calculator$add$Return ret; - ret.optionalReturnValue.buf = (double *) malloc(sizeof(*ret.optionalReturnValue.buf)); - ret.optionalReturnValue.len = 1; - ret.optionalReturnValue.cap = 1; - ret.optionalReturnValue.buf[0] = val; - ret.optionalError = nullptr; - pub->send(pub->handle, msgId, &ret, metaProps); - free(ret.optionalReturnValue.buf); - } else { - logHelper.error("publisher is gone"); - } - }); - } else { - logHelper.warning("Unexpected message type %s", msgType); - } - } - - void setPublisher(const std::shared_ptr& pub) { - std::lock_guard lock{mutex}; - publisher = pub; + setupMsgIpc(); } void setPromiseFactory(const std::shared_ptr& fac) { @@ -401,33 +387,33 @@ class ExportedCalculator final { int start() { resultStream = calculator->result(); - auto streamEnded = resultStream->forEach([logHelper = logHelper, weakSvc = std::weak_ptr{calculator}, weakPub = std::weak_ptr{publisher}](const double& event){ - auto pub = weakPub.lock(); + auto streamEnded = resultStream->forEach([lh = logHelper, weakSvc = std::weak_ptr{calculator}, qidSnd = qidSender](const double& event) { auto svc = weakSvc.lock(); - if (pub && svc) { - thread_local unsigned int eventMsgId = 0; - if (eventMsgId == 0) { - pub->localMsgTypeIdForMsgType(pub->handle, "Calculator$result$Event", &eventMsgId); - } - - auto* metaProps = celix_properties_create(); - celix_properties_set(metaProps, "invoke.id", std::to_string(0).c_str()); - Calculator$result$Event wireEvent; - wireEvent.optionalReturnValue.buf = (double *) malloc(sizeof(*wireEvent.optionalReturnValue.buf)); - wireEvent.optionalReturnValue.len = 1; - wireEvent.optionalReturnValue.cap = 1; - wireEvent.optionalReturnValue.buf[0] = event; - wireEvent.optionalError = nullptr; - pub->send(pub->handle, eventMsgId, &wireEvent, metaProps); - free(wireEvent.optionalReturnValue.buf); + if (qidSnd != -1 && svc) { + Calculator$result$EventIpcMsg msg{}; + msg.mtype = 3; + msg.mtext.eventData = event; + msg.mtext.hasError = false; + sendMsgWithIpc(lh, qidSnd, msg); } else { - logHelper.error("publisher is gone"); + lh.error("Cannot send event, qidSender is -1 or service is gone"); } }); + running.store(true, std::memory_order::memory_order_release); + receiveThread = std::thread{[this]{ + while (running.load(std::memory_order::memory_order_consume)) { + receiveMessages(); + //note for example purposes, sleep instead of blocking with cond is used. + std::this_thread::sleep_for(std::chrono::milliseconds{10}); + } + }}; return CELIX_SUCCESS; } int stop() { + running.store(false, std::memory_order::memory_order_release); + receiveThread.join(); + receiveThread = {}; resultStream->close(); resultStream.reset(); return CELIX_SUCCESS; @@ -442,14 +428,66 @@ class ExportedCalculator final { calculator = calc; } private: + void setupMsgIpc() { + //note reverse order of sender and receiver compared to ImportedCalculator + int keySender = 1235; // TODO make configurable + int keyReceiver = 1234; // TODO make configurable + qidSender = msgget(keySender, 0666 | IPC_CREAT); + qidReceiver = msgget(keyReceiver, 0666 | IPC_CREAT); + + if (qidSender == -1 || qidReceiver == -1) { + throw std::logic_error{"RsaShmClient: Error creating msg queue."}; + } + } + + void receiveMessages() { + receiveCalculator$add$Invoke(); + } + + void receiveCalculator$add$Invoke() { + try { + auto msg = receiveMsgFromIpc(logHelper, qidReceiver, 1); + if (!msg) { + return; // no message available (yet) + } + auto& invoke = msg->mtext; + + auto promise = calculator->add(invoke.arg1, invoke.arg2); + promise.onFailure([lh = logHelper, id = invoke.invokeId, qidSnd = qidSender](const auto& exp) { + //sending Calculator$add$Return (mtype=2) to qidSender + Calculator$add$ReturnIpcMsg msg{}; + msg.mtype = 2; + msg.mtext.invokeId = id; + msg.mtext.result = 0.0; + msg.mtext.hasError = true; + snprintf(msg.mtext.errorMsg, sizeof(msg.mtext.errorMsg), "%s", exp.what()); + sendMsgWithIpc(lh, qidSnd, msg); + }); + promise.onSuccess([lh = logHelper, id = invoke.invokeId, qidSnd = qidSender](const auto& val) { + //sending Calculator$add$Return (mtype=2) to qidSender + Calculator$add$ReturnIpcMsg msg{}; + msg.mtype = 2; + msg.mtext.invokeId = id; + msg.mtext.result = val; + msg.mtext.hasError = false; + sendMsgWithIpc(lh, qidSnd, msg); + }); + } catch (const IpcException& e) { + logHelper.error("IpcException: %s", e.what()); + } + } + celix::LogHelper logHelper; - std::atomic nextInvokeId{0}; + std::atomic running{false}; + std::thread receiveThread{}; std::mutex mutex{}; //protects below std::shared_ptr calculator{}; std::shared_ptr factory{}; - std::shared_ptr publisher{}; std::unordered_map> deferreds{}; std::shared_ptr> resultStream{}; + + int qidSender{-1}; + int qidReceiver{-1}; }; /** @@ -513,11 +551,6 @@ class CalculatorExportServiceFactory final : public celix::rsa::IExportServiceFa auto svcId = serviceProperties.get(celix::SERVICE_ID); auto& cmp = ctx->getDependencyManager()->createComponent(std::make_unique(logHelper)); - cmp.createServiceDependency(PUBSUB_PUBLISHER_SERVICE_NAME) - .setRequired(true) - .setStrategy(DependencyUpdateStrategy::suspend) - .setFilter(std::string{"(&(topic="}.append(returnTopic).append(")(scope=").append(scope).append("))")) - .setCallbacks(&ExportedCalculator::setPublisher); cmp.createServiceDependency() .setRequired(true) @@ -532,23 +565,6 @@ class CalculatorExportServiceFactory final : public celix::rsa::IExportServiceFa cmp.setCallbacks(&ExportedCalculator::init, &ExportedCalculator::start, &ExportedCalculator::stop, &ExportedCalculator::deinit); - - auto subscriber = std::make_shared(); - subscriber->handle = &cmp.getInstance(); - subscriber->receive = [](void *handle, const char *msgType, unsigned int msgTypeId, void *msg, const celix_properties_t *metadata, bool */*release*/) -> int { - auto* inst = static_cast(handle); - try { - inst->receive(msgType, msgTypeId, msg, metadata); - } catch (...) { - return -1; - } - return 0; - }; - cmp.addContext(subscriber); - cmp.createProvidedCService(subscriber.get(), PUBSUB_SUBSCRIBER_SERVICE_NAME) - .addProperty("topic", invokeTopic) - .addProperty("scope", scope); - cmp.buildAsync(); return cmp.getUUID(); diff --git a/bundles/pubsub/CMakeLists.txt b/bundles/pubsub/CMakeLists.txt deleted file mode 100644 index 11513943b..000000000 --- a/bundles/pubsub/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -celix_subproject(PUBSUB "Option to build the pubsub bundles" ON) -if (PUBSUB) - add_subdirectory(pubsub_api) - add_subdirectory(pubsub_utils) - add_subdirectory(pubsub_spi) - add_subdirectory(pubsub_topology_manager) - add_subdirectory(pubsub_admin_zmq) - add_subdirectory(pubsub_admin_tcp) - add_subdirectory(pubsub_admin_websocket) - add_subdirectory(pubsub_discovery) - add_subdirectory(pubsub_serializer_json) - add_subdirectory(pubsub_serializer_avrobin) - add_subdirectory(pubsub_protocol) - add_subdirectory(keygen) - add_subdirectory(examples) - if (ENABLE_TESTING) - add_subdirectory(integration) - endif() -endif(PUBSUB) diff --git a/bundles/pubsub/README.md b/bundles/pubsub/README.md deleted file mode 100644 index 744cfd9a8..000000000 --- a/bundles/pubsub/README.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: Publisher / subscriber implementation ---- - - - -# Publisher / subscriber implementation - -This subdirectory contains an implementation for a publish-subscribe remote services system, that use dfi library for message serialization. -For low-level communication, TCP, UDP and ZMQ is used. - -# Description - -This publisher / subscriber implementation is based on the concepts of the remote service admin (i.e. rsa / topology / discovery pattern). - -Publishers are senders of data, subscribers can receive data. Publishers can publish/send data to certain channels (called 'topics' further on), subscribers can subscribe to these topics. For every topic a publisher service is created by the pubsub admin. This publisher is announced through etcd. So etcd is used for discovery of the publishers. Subscribers are also registered as a service by the pubsub admin and will watch etcd for changes and when a new publisher is announced, the subscriber will check if the topic matches its interests. If the subscriber is interested in/subscribed to a certain topic, a connection between publisher and subscriber will be instantiated by the pubsub admin. - -The dfi library is used for message serialization. The publisher / subscriber implementation will arrange that every message which will be send gets an unique id. - -For communication between publishers and subscribers TCP, UDP and ZeroMQ can be used. When using ZeroMQ it's also possible to setup a secure connection to encrypt the traffic being send between publishers and subscribers. This connection can be secured with ZeroMQ by using a curve25519 key pair per topic. - -The publisher/subscriber implementation supports sending of a single message and sending of multipart messages. - -## Getting started - -The publisher/subscriber implementation contains 3 different PubSubAdmins for managing connections: - * PubsubAdminUDP: This pubsub admin is using udp (multicast) linux sockets to setup a connection. - * PubsubAdminTCP: This pubsub admin is using tcp linux sockets to setup a connection. - * PubsubAdminZMQ (LGPL License): This pubsub admin is using ZeroMQ and is disabled as default. This is a because the pubsub admin is using ZeroMQ which is licensed as LGPL ([View ZeroMQ License](https://github.com/zeromq/libzmq#license)). - - The ZeroMQ pubsub admin can be enabled by specifying the build flag `BUILD_PUBSUB_PSA_ZMQ=ON`. To get the ZeroMQ pubsub admin running, [ZeroMQ](https://github.com/zeromq/libzmq) and [CZMQ](https://github.com/zeromq/czmq) need to be installed. Also, to make use of encrypted traffic, [OpenSSL](https://github.com/openssl/openssl) is required. - -## Running instructions - -### Running PSA UDP-Multicast - -1. Open a terminal -1. Run `etcd` -1. Open second terminal on project build location -1. Run `cd deploy/pubsub/pubsub_publisher_udp_mc` -1. Run `sh run.sh` -1. Open third terminal on project build location -1. Run `cd deploy/pubsub/pubsub_subscriber_udp_mc` -1. Run `sh run.sh` - -Design information can be found at pubsub\_admin\_udp\_mc/README.md - - -### Running PSA TCP - -1. Open a terminal -1. Run `cd runtimes/pubsub/tcp` -1. Run `sh start.sh` - -### Properties PSA TCP - -Some properties can be set to configure the PSA-TCP. If not configured defaults will be used. These -properties can be set in the config.properties file (= format) - - - PSA_IP The url address to be used by the TCP admin to publish its data. Default the first IP not on localhost - This can be hostname / IP address / IP address with postfix, e.g. 192.168.1.0/24 - - -### Running PSA ZMQ - -For ZeroMQ without encryption, skip the steps 1-12 below - -1. Run `touch ~/pubsub.keys` -1. Run `echo "aes_key:{AES_KEY here}" >> ~/pubsub.keys`. Note that AES_KEY is just a sequence of random bytes. To generate such a key, you can use the command `cat /dev/urandom | hexdump -v -e '/1 "%02X"' | head -c 32` (this will take out of /dev/urandom 16 bytes, thus a 128bit key) -1. Run `echo "aes_iv:{AES_IV here}" >> ~/pubsub.keys`. Note that AES_IV is just a sequence of random bytes. To generate such an initial vector , you can use the command `cat /dev/urandom | hexdump -v -e '/1 "%02X"' | head -c 16` (this will take out of /dev/urandom 8 bytes, thus a 64bit initial vector) -1. Run `touch ~/pubsub.conf` -1. Run `echo "keys.file.path=$HOME" >> ~/pubsub.conf` -1. Run `echo "keys.file.name=pubsub.keys" >> ~/pubsub.conf` -1. Generate ZMQ keypairs by running `pubsub/keygen/makecert pub_.pub pub_.key` -1. Encrypt the private key file using `pubsub/keygen/ed_file ~/pubsub.keys pub_.key pub_.key.enc` -1. Store the keys in the pubsub/examples/keys/ directory, as described in the pubsub/examples/keys/README. -1. Build project to include these keys (check the CMakeLists.txt files to be sure that the keys are included in the bundles) -1. Add to the config.properties the property SECURE_TOPICS= - -For ZeroMQ without encryption, start here - -1. Run `etcd` -1. Open second terminal on pubsub root -1. Run `cd deploy/pubsub/pubsub_publisher_zmq` -1. Run `cat ~/pubsub.conf >> config.properties` (only for ZeroMQ with encryption) -1. Run `sh run.sh` -1. Open third terminal on pubsub root -1. Run `cd deploy/pubsub/pubsub_subscriber_zmq` -1. Run `cat ~/pubsub.conf >> config.properties` (only for ZeroMQ with encryption) -1. Run `sh run.sh` - -### Properties PSA ZMQ - -Some properties can be set to configure the PSA-ZMQ. If not configured defaults will be used. These -properties can be set in the config.properties file (= format) - - - PSA_IP The local IP address to be used by the ZMQ admin to publish its data. Default the first IP not on localhost - PSA_INTERFACE The local ethernet interface to be used by the ZMQ admin to publish its data (ie eth0). Default the first non localhost interface - PSA_ZMQ_RECEIVE_TIMEOUT_MICROSEC Set the polling interval of the ZMQ receive thread. Default 1ms \ No newline at end of file diff --git a/bundles/pubsub/doc/pubsub_serialization.adoc b/bundles/pubsub/doc/pubsub_serialization.adoc deleted file mode 100644 index c4d7c1bc6..000000000 --- a/bundles/pubsub/doc/pubsub_serialization.adoc +++ /dev/null @@ -1,263 +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 Serialization - -WARNING: The PubSub Serialization Services are still work in progress. The current PubSubAdmins still work differently. - -PubSub serialization is realized by providing multiple message serialization services -(`pubsub_message_serialization_service_t`), a message serialization service per msg type. - -The message serialization services must provide a mandatory `serialization.type`. -This is used to identify the serialization "type" they belong to, for example "json" or "avrobin". - -The serialization services are used by the PubSubAdmins to find a matching serializer. -This is done by checking if a publisher requester or subscriber provider has configured a serialization type and -if this is not the case select the highest ranking available serialization service. - -The serialization services are also used by the PubSub Admins to send (serialize) and receive (deserialize) messages. -The PubSub Admins realizes the transport for messages and the serialization services serializes the serializations. - -Currently the Celix PubSub facilities delivers two serialiation types: "json" and "avrobin". -<> can be used to create additional serialization types. - -pubsub_message_serialization_service_t -[source,c] ----- -#define PUBSUB_MESSAGE_SERIALIZATION_SERVICE_NAME "pubsub_message_serialization_service" -#define PUBSUB_MESSAGE_SERIALIZATION_SERVICE_VERSION "1.0.0" -#define PUBSUB_MESSAGE_SERIALIZATION_SERVICE_RANGE "[1,2)" - -#define PUBSUB_MESSAGE_SERIALIZATION_SERVICE_SERIALIZATION_TYPE_PROPERTY "serialization.type" -#define PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_FQN_PROPERTY "msg.fqn" -#define PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_VERSION_PROPERTY "msg.version" -#define PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_ID_PROPERTY "msg.id" - -/** - * A message serialization service for a serialization type (e.g. json) and - * for a specific msg type (based on the fully qualified name) and version. - * - * The properties serialization.type, msg,fqn, msg.version and msg.id are mandatory - */ -typedef struct pubsub_message_serialization_service { - void* handle; - - celix_status_t (*serialize)(void* handle, const void* input, struct iovec** output, size_t* outputIovLen); - void (*freeSerializedMsg)(void* handle, struct iovec* input, size_t inputIovLen); - celix_status_t (*deserialize) - -(void* handle, const struct iovec* input, size_t inputIovLen, void** out); //note inputLen can be 0 if predefined size is not needed - void (*freeDeserializedMsg)(void* handle, void* msg); - -} pubsub_message_serialization_service_t; ----- - -== PubSub Serialization Matching - -TODO: Explain matching and usage service ranking on serialization service. - - -=== Match Serializer for Subscriber -[plantuml] ----- -@startuml -actor PubSubUser - -PubSubUser -> BundleContext: Register Subscriber Service -BundleContext -> Framework: Register Subscriber Service -Framework -> PubSubTopologyManager : Service Added (service tracker) -PubSubTopologyManager --> Framework -Framework --> BundleContext -BundleContext --> PubSubUser - -== PubSubAdmin Setup == - -loop psa handling thread -PubSubTopologyManager -> PubSubTopologyManager: pstm_setupTopicReceivers -activate PubSubTopologyManager -PubSubTopologyManager -> PubSubAdmin: matchSubscriber -PubSubAdmin -> PubSubUtils: matchSerializer -PubSubUtils --> PubSubAdmin -PubSubAdmin --> PubSubTopologyManager -PubSubTopologyManager -> PubSubAdmin: setupTopicReceiver -PubSubAdmin -> PubSubAdmin: create topic receiver -PubSubAdmin --> PubSubTopologyManager -deactivate PubSubTopologyManager -end - -@enduml ----- - -=== Match Serializer for Publisher -[plantuml] ----- -@startuml -actor PubSubUser - -PubSubUser -> BundleContext: Request Publisher Service -BundleContext -> Framework: Register Service Listener hook -Framework -> PubSubTopologyManager : Listener Added -PubSubTopologyManager --> Framework -Framework --> BundleContext -BundleContext --> PubSubUser - -== PubSubAdmin Setup == - -loop psa handling thread -PubSubTopologyManager -> PubSubTopologyManager: pstm_setupTopicSenders -activate PubSubTopologyManager -PubSubTopologyManager -> PubSubAdmin: matchPublisher -PubSubAdmin -> PubSubUtils: matchSerializer -PubSubUtils --> PubSubAdmin -PubSubAdmin --> PubSubTopologyManager -PubSubTopologyManager -> PubSubAdmin: setupTopicSender -PubSubAdmin -> PubSubAdmin: create topic sender -PubSubAdmin -> BundleContext: Register Publisher Service -BundleContext -> PubSubUser: Publisher Added -PubSubUser --> BundleContext -BundleContext --> PubSubAdmin -PubSubAdmin --> PubSubTopologyManager -deactivate PubSubTopologyManager -end - -@enduml ----- - -== PubSub Serialization Provider -The PubSub Serialization Provider (`pubsub_serialization_provider_t`) is a helper object which can be used to more easily -create serialization services based on descriptors (libdfi). It arranges tracking bundles, reading descriptor files, -generating errors for invalid descriptors and provides a shell command to interactively query the available descriptors. - -The PubSub Serialization Provider needs to be constructor with the serializations service functions -(`serialize`, `freeSerializedMsg`, `deserialize` and `freeDeserializedMsg`) - -The PubSub Serialization Provider is part of the `Celix::pubsub_utils` static library. - -[ditaa] ----- - +----------------+ - | PubSub User | - | (bundle) | +----------------+ - | | contains | | - | +------------->+ +-------------+--+ - | | | | | - +-------+--------+ | | +--------------+--+ - ^ | | | examples.Type | - | +-------------->+ | | (descriptor) | - tracks | | reads +----+ | - bundles | | | | | - | | +-+ | - | | | | - | | | {d} | - | | +-----------------+ - | | - | | - | | - +---------+-------+-+ - | JSON | - | Serialization | +----------------+ - | Provider +------------>+ | - | (bundle) | provides | +----------------+ - | | | | | | - | | | | +-----------+--+--+ - | | | | | | Properties: - | | | | | PubSub | o serialization.type = json - +--+--------------+-+ +----+ Message | o msg.fqn = examples.Type - | | | | Serialization | o msg.version = ... - | | +-+ Service | o msg.id = ... - | | | (service) | - specialize| | | | - | | +-----------------+ - | | - | | - v | +------------------+ -+-------------+-----+ | | | Properties: -| | | | PubSub | o serialization.type = json -| PubSub | | | Message | -| Serialization | +-------------->+ Serialization | -| Provider | provides | Marker | -| (library) | | (service) | -| | | | -| | +------------------+ -+-------------------+ ----- - -== PubSub Serialization Handler -The PubSub Serialization Handler (`pubsub_serialization_handler_t`) is a helper object which can be used to more easily -serialize/deserialize message. -The handler will track message serialization services for the provided serialization type (constructor argument) and -provides a more easy to use set of function for serialization. - -It will also check if the provided message serialization services do not clash on the msg id and msg fqn combination. -When multiple message serialization services are registered it will use the highest ranking services. - -serialization services based on descriptors (libdfi). It arranges tracking bundles, reading descriptor files, -generating errors for invalid descriptors and provides a shell command to interactively query the available descriptors. - -The PubSub Serialization Handler is part of the `Celix::pubsub_utils` static library. - -=== Serialization function for PubSub Serialization Handler -[source, c] ----- -/** - * Serialize a message into iovec structs (set of structures with buffer pointer and length) - * - * The correct message serialization services will be selected based on the provided msgId. - * - * @param handler The pubsub serialization handler. - * @param msgId The msg id for the message to be serialized. - * @param input A pointer to the message object - * @param output An output pointer to a array of iovec structs. - * @param outputIovLen The number of iovec struct created - * @return CELIX_SUCCESS on success, CELIX_ILLEGAL_ARGUMENT if the msg id is not known or serialization failed. - */ -celix_status_t pubsub_serializerHandler_serialize(pubsub_serializer_handler_t* handler, uint32_t msgId, const void* input, struct iovec** output, size_t* outputIovLen); - -/** - * Free the memory of for the serialized msg. - */ -celix_status_t pubsub_serializerHandler_freeSerializedMsg(pubsub_serializer_handler_t* handler, uint32_t msgId, struct iovec* input, size_t inputIovLen); - -/** - * Deserialize a message using the provided iovec buffers. - * - * The deserialize function will also check if the target major/minor version of the message is valid with the version - * of the serialized data. - * - * For some serialization types (e.g. JSON) newer versions of the serialized data can be deserialized. - * E.g. JSON serialized data with version 1.2.0 can be deserialized to a target message with version 1.0.0 - * But JSON serialized data with a version 2.0.0 will not be deserialized to a target message with version 1.0.0 - * This assume correct use of semantic versioning. - * - * @param handler The pubsub serialization handler. - * @param msgId The msg id for the message to be deserialized. - * @param serializedMajorVersion The major version of the serialized data - * @param serializedMinorVersion The minor version of the serialized data. - * @param input Pointer to the first element in a array of iovecs. - * @param inputIovLen Then number of iovecs. - * @param out The newly allocated and deserialized message object - * @return CELIX_SUCCESS on success. CELIX_ILLEGAL_ARGUMENT if the msg id is not known, - * or if the version do no match or deserialization failed. - */ -celix_status_t pubsub_serializerHandler_deserialize(pubsub_serializer_handler_t* handler, uint32_t msgId, int serializedMajorVersion, int serializedMinorVersion, const struct iovec* input, size_t inputIovLen, void** out); - -/** - * Free the memory for the deserialized message. - */ -celix_status_t pubsub_serializerHandler_freeDeserializedMsg(pubsub_serializer_handler_t* handler, uint32_t msgId, void* msg); ----- \ No newline at end of file diff --git a/bundles/pubsub/examples/CMakeLists.txt b/bundles/pubsub/examples/CMakeLists.txt deleted file mode 100644 index 5afeb5a67..000000000 --- a/bundles/pubsub/examples/CMakeLists.txt +++ /dev/null @@ -1,361 +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. - -celix_subproject(PUBSUB_EXAMPLES "Option to build the pubsub examples" ON) -if (PUBSUB_EXAMPLES) - add_subdirectory(pubsub) - - find_program(ETCD_CMD NAMES etcd) - find_program(XTERM_CMD NAMES xterm) - - if (BUILD_PUBSUB_PSA_TCP AND BUILD_LAUNCHER) - # TCP - add_celix_container(pubsub_publisher_tcp - LAUNCHER Celix::launcher - GROUP pubsub - BUNDLES - Celix::log_admin - Celix::shell - Celix::shell_tui - Celix::celix_pubsub_serializer_json - Celix::celix_pubsub_discovery_etcd - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_tcp - Celix::celix_pubsub_protocol_wire_v2 - celix_pubsub_poi_publisher - celix_pubsub_poi_publisher2 - USE_CONFIG - PROPERTIES - PSA_TCP_VERBOSE=true - PUBSUB_ETCD_DISCOVERY_VERBOSE=true - PUBSUB_TOPOLOGY_MANAGER_VERBOSE=true - ) - - add_celix_container(pubsub_subscriber_tcp - LAUNCHER Celix::launcher - GROUP pubsub - BUNDLES - Celix::log_admin - Celix::shell - Celix::shell_tui - Celix::celix_pubsub_serializer_json - Celix::celix_pubsub_discovery_etcd - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_tcp - Celix::celix_pubsub_protocol_wire_v2 - celix_pubsub_poi_subscriber - USE_CONFIG - PROPERTIES - PSA_TCP_VERBOSE=true - PUBSUB_ETCD_DISCOVERY_VERBOSE=true - PUBSUB_TOPOLOGY_MANAGER_VERBOSE=true - ) - - add_celix_container(pubsub_subscriber2_tcp - LAUNCHER Celix::launcher - GROUP pubsub - BUNDLES - Celix::log_admin - Celix::shell - Celix::shell_tui - Celix::celix_pubsub_serializer_json - Celix::celix_pubsub_discovery_etcd - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_tcp - Celix::celix_pubsub_protocol_wire_v2 - celix_pubsub_poi_subscriber - USE_CONFIG - PROPERTIES - PSA_TCP_VERBOSE=true - PUBSUB_ETCD_DISCOVERY_VERBOSE=true - PUBSUB_TOPOLOGY_MANAGER_VERBOSE=true - ) - - if (ETCD_CMD AND XTERM_CMD) - # Runtime starting a publish and subscriber for tcp - add_celix_runtime(pubsub_rt_tcp - NAME tcp - GROUP pubsub - CONTAINERS - pubsub_publisher_tcp - pubsub_subscriber_tcp - pubsub_subscriber2_tcp - COMMANDS - etcd - USE_TERM - ) - endif () - endif() - - if (BUILD_PUBSUB_PSA_ZMQ AND BUILD_LAUNCHER) - - if (BUILD_PUBSUB_PSA_TCP) - # Dynamic ZMQ / UDP / TCP admin - add_celix_container(pubsub_publisher - LAUNCHER Celix::launcher - GROUP "pubsub" - BUNDLES - Celix::shell - Celix::shell_tui - Celix::celix_pubsub_serializer_json - Celix::celix_pubsub_discovery_etcd - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_zmq - Celix::celix_pubsub_admin_tcp - Celix::celix_pubsub_protocol_wire_v1 - celix_pubsub_poi_publisher - celix_pubsub_poi_publisher2 - USE_CONFIG - ) - - add_celix_container(pubsub_subscriber - LAUNCHER Celix::launcher - GROUP "pubsub" - BUNDLES - Celix::shell - Celix::shell_tui - Celix::celix_pubsub_serializer_json - Celix::celix_pubsub_discovery_etcd - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_zmq - Celix::celix_pubsub_admin_tcp - Celix::celix_pubsub_protocol_wire_v1 - celix_pubsub_poi_subscriber - USE_CONFIG - ) - endif() - - # ZMQ - add_celix_container(pubsub_zmq - LAUNCHER Celix::launcher - GROUP "pubsub" - BUNDLES - Celix::shell - Celix::shell_tui - Celix::celix_pubsub_serializer_json - Celix::celix_pubsub_discovery_etcd - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_zmq - celix_pubsub_poi_publisher - celix_pubsub_poi_subscriber - USE_CONFIG - PROPERTIES - PSA_ZMQ_ZEROCOPY_ENABLED=true - ) - - add_celix_container(pubsub_publisher_zmq - LAUNCHER Celix::launcher - GROUP "pubsub" - BUNDLES - Celix::shell - Celix::shell_tui - Celix::celix_pubsub_serializer_json - Celix::celix_pubsub_protocol_wire_v1 - Celix::celix_pubsub_discovery_etcd - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_zmq - celix_pubsub_poi_publisher - celix_pubsub_poi_publisher2 - celix_pubsub_interceptors_example - USE_CONFIG - PROPERTIES - PSA_ZMQ_VERBOSE=true - PUBSUB_ETCD_DISCOVERY_VERBOSE=true - PUBSUB_TOPOLOGY_MANAGER_VERBOSE=true - PSA_ZMQ_ZEROCOPY_ENABLED=false - ) - - add_celix_container(pubsub_subscriber_zmq - LAUNCHER Celix::launcher - GROUP "pubsub" - BUNDLES - Celix::shell - Celix::shell_tui - Celix::celix_pubsub_serializer_json - Celix::celix_pubsub_protocol_wire_v1 - Celix::celix_pubsub_discovery_etcd - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_zmq - celix_pubsub_poi_subscriber - celix_pubsub_interceptors_example - USE_CONFIG - PROPERTIES - PSA_ZMQ_VERBOSE=true - PUBSUB_ETCD_DISCOVERY_VERBOSE=true - PUBSUB_TOPOLOGY_MANAGER_VERBOSE=true - ) - - add_celix_container(pubsub_subscriber2_zmq - LAUNCHER Celix::launcher - GROUP "pubsub" - BUNDLES - Celix::shell - Celix::shell_tui - Celix::celix_pubsub_serializer_json - Celix::celix_pubsub_discovery_etcd - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_zmq - celix_pubsub_poi_subscriber - USE_CONFIG - PROPERTIES - PSA_ZMQ_VERBOSE=true - PUBSUB_ETCD_DISCOVERY_VERBOSE=true - PUBSUB_TOPOLOGY_MANAGER_VERBOSE=true - ) - - if (ETCD_CMD AND XTERM_CMD) - # Runtime starting two bundles using both zmq and upd mc pubsub - add_celix_runtime(pubsub_rt_zmq_udpmc_combi - NAME combi - GROUP pubsub - CONTAINERS - pubsub_publisher_zmq - pubsub_subscriber_zmq - pubsub_subscriber_zmq - COMMANDS - etcd - USE_TERM - ) - - # Runtime starting a publish and 2 subscribers for zmq - add_celix_runtime(pubsub_rt_zmq - NAME zmq - GROUP pubsub - CONTAINERS - pubsub_publisher_zmq - pubsub_subscriber_zmq - pubsub_subscriber2_zmq - COMMANDS - etcd - USE_TERM - ) - endif () - endif() - - if (BUILD_PUBSUB_PSA_NANOMSG AND BUILD_LAUNCHER) - - add_celix_container(pubsub_publisher1_nanomsg - LAUNCHER Celix::launcher - GROUP "pubsub" - BUNDLES - Celix::shell - Celix::shell_tui - Celix::celix_pubsub_serializer_json - Celix::celix_pubsub_discovery_etcd - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_nanomsg - celix_pubsub_poi_publisher - USE_CONFIG - PROPERTIES - PSA_NANOMSG_VERBOSE=true - PUBSUB_ETCD_DISCOVERY_VERBOSE=true - PUBSUB_TOPOLOGY_MANAGER_VERBOSE=true - ) - - add_celix_container(pubsub_publisher2_nanomsg - LAUNCHER Celix::launcher - GROUP "pubsub" - BUNDLES - Celix::shell - Celix::shell_tui - Celix::celix_pubsub_serializer_json - Celix::celix_pubsub_discovery_etcd - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_nanomsg - celix_pubsub_poi_publisher - USE_CONFIG - PROPERTIES - PSA_NANOMSG_VERBOSE=true - PUBSUB_ETCD_DISCOVERY_VERBOSE=true - PUBSUB_TOPOLOGY_MANAGER_VERBOSE=true - ) - - add_celix_container(pubsub_subscriber1_nanomsg - LAUNCHER Celix::launcher - GROUP "pubsub" - BUNDLES - Celix::shell - Celix::shell_tui - Celix::celix_pubsub_serializer_json - Celix::celix_pubsub_discovery_etcd - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_nanomsg - celix_pubsub_poi_subscriber - USE_CONFIG - PROPERTIES - PSA_NANOMSG_VERBOSE=true - PUBSUB_ETCD_DISCOVERY_VERBOSE=true - PUBSUB_TOPOLOGY_MANAGER_VERBOSE=true - ) - - add_celix_container(pubsub_subscriber2_nanomsg - LAUNCHER Celix::launcher - GROUP "pubsub" - BUNDLES - Celix::shell - Celix::shell_tui - Celix::celix_pubsub_serializer_json - Celix::celix_pubsub_discovery_etcd - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_nanomsg - celix_pubsub_poi_subscriber - USE_CONFIG - PROPERTIES - PSA_NANOMSG_VERBOSE=true - PUBSUB_ETCD_DISCOVERY_VERBOSE=true - PUBSUB_TOPOLOGY_MANAGER_VERBOSE=true - ) - - if (ETCD_CMD AND XTERM_CMD) - # Runtime starting a publisher and 2 subscribers for nanomsg - add_celix_runtime(pubsub_rt_nanomsg - NAME nanomsg - GROUP pubsub - CONTAINERS - pubsub_publisher1_nanomsg - pubsub_publisher2_nanomsg - pubsub_subscriber1_nanomsg - pubsub_subscriber2_nanomsg - COMMANDS - etcd - USE_TERM - ) - endif () - - endif() - - if (BUILD_PUBSUB_PSA_WS) - add_celix_container(pubsub_websocket_example - GROUP pubsub - BUNDLES - Celix::log_admin - Celix::shell - Celix::shell_tui - Celix::http_admin - Celix::celix_pubsub_serializer_json - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_websocket - celix_pubsub_websocket_example - PROPERTIES - PSA_TCP_VERBOSE=true - PUBSUB_ETCD_DISCOVERY_VERBOSE=true - PUBSUB_TOPOLOGY_MANAGER_VERBOSE=true - CELIX_HTTP_ADMIN_LISTENING_PORTS=7660 - CELIX_HTTP_ADMIN_NUM_THREADS=5 - ) - endif() -endif () diff --git a/bundles/pubsub/examples/keys/README.md b/bundles/pubsub/examples/keys/README.md deleted file mode 100644 index b46438b36..000000000 --- a/bundles/pubsub/examples/keys/README.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Pubsub Keys ---- - - - -Store the AES key for encrypting and decrypting the encoded secret keys safe in a file! -Default file is `/etc/pubsub.keys` with the following format: -``` -aes_key:{32 character AES key here} -aes_iv:{16 character AES iv here} -``` - -Use the $PROJECT_BUILD/pubsub/keygen/makecert for generating keypairs -Use the $PROJECT_BUILD/pubsub/keygen/ed_file for encrypting and decrypting private keys - -Public keys need to be stored in the 'public' folder having the following format: -- pub_{topic}.pub -- sub_{topic}.pub - -Secret keys need to be stored in the 'private' folder having the following format: -- pub_{topic}.key.enc -- sub_{topic}.key.enc -These files need to be encrypted using the 'ed_file' executable. diff --git a/bundles/pubsub/examples/keys/publisher/private/.gitkeep b/bundles/pubsub/examples/keys/publisher/private/.gitkeep deleted file mode 100644 index 4ea9b315a..000000000 --- a/bundles/pubsub/examples/keys/publisher/private/.gitkeep +++ /dev/null @@ -1,14 +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. diff --git a/bundles/pubsub/examples/keys/publisher/public/.gitkeep b/bundles/pubsub/examples/keys/publisher/public/.gitkeep deleted file mode 100644 index 978b68af6..000000000 --- a/bundles/pubsub/examples/keys/publisher/public/.gitkeep +++ /dev/null @@ -1,16 +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. diff --git a/bundles/pubsub/examples/keys/subscriber/private/.gitkeep b/bundles/pubsub/examples/keys/subscriber/private/.gitkeep deleted file mode 100644 index 978b68af6..000000000 --- a/bundles/pubsub/examples/keys/subscriber/private/.gitkeep +++ /dev/null @@ -1,16 +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. diff --git a/bundles/pubsub/examples/keys/subscriber/public/.gitkeep b/bundles/pubsub/examples/keys/subscriber/public/.gitkeep deleted file mode 100644 index 978b68af6..000000000 --- a/bundles/pubsub/examples/keys/subscriber/public/.gitkeep +++ /dev/null @@ -1,16 +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. diff --git a/bundles/pubsub/examples/pubsub/CMakeLists.txt b/bundles/pubsub/examples/pubsub/CMakeLists.txt deleted file mode 100644 index 427dbd1e6..000000000 --- a/bundles/pubsub/examples/pubsub/CMakeLists.txt +++ /dev/null @@ -1,28 +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_directories("common/include") - -add_subdirectory(interceptors) -add_subdirectory(publisher) -add_subdirectory(publisher2) -if (BUILD_PUBSUB_PSA_WS) - add_subdirectory(pubsub_websocket) -endif() -add_subdirectory(subscriber) - - diff --git a/bundles/pubsub/examples/pubsub/common/include/poi.h b/bundles/pubsub/examples/pubsub/common/include/poi.h deleted file mode 100644 index 8f592220d..000000000 --- a/bundles/pubsub/examples/pubsub/common/include/poi.h +++ /dev/null @@ -1,55 +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. - */ -/** - * poi.h - * - * \date Nov 12, 2015 - * \author Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - -#ifndef POI_H_ -#define POI_H_ - -#define MIN_LAT -90.0F -#define MAX_LAT 90.0F -#define MIN_LON -180.0F -#define MAX_LON 180.0F - -#define MSG_POI_NAME "poi" //Has to match the message name in the msg descriptor! - -struct poi{ - double lat; - double lon; -}; - -typedef struct poi1 poi1_t; - -struct location{ - struct poi position; - char* name; - char* description; - char* extra; - char* data; -}; - -typedef struct location* location_t; - - -#endif /* POI_H_ */ diff --git a/bundles/pubsub/examples/pubsub/common/include/poiCmd.h b/bundles/pubsub/examples/pubsub/common/include/poiCmd.h deleted file mode 100644 index 1c9c0a3b2..000000000 --- a/bundles/pubsub/examples/pubsub/common/include/poiCmd.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -/** - * poiCmd.h - * - * \date Jan 16, 2020 - * \author Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - -#ifndef POICMD_H_ -#define POICMD_H_ - -#define MSG_POI_CMD_NAME "poiCmd" //Has to match the message name in the msg descriptor! - -struct poi_cmd{ - char* command; -}; - -typedef struct poi_cmd poi_cmd_t; - - -#endif /* POICMD_H_ */ diff --git a/bundles/pubsub/examples/pubsub/interceptors/CMakeLists.txt b/bundles/pubsub/examples/pubsub/interceptors/CMakeLists.txt deleted file mode 100644 index 0be810a39..000000000 --- a/bundles/pubsub/examples/pubsub/interceptors/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -add_celix_bundle(celix_pubsub_interceptors_example - SYMBOLIC_NAME "celix_pubsub_interceptors_example" - VERSION "1.0.0" - SOURCES - src/ps_interceptor_activator.c - src/first_interceptor.c - src/second_interceptor.c -) - -target_link_libraries(celix_pubsub_interceptors_example PRIVATE Celix::pubsub_spi) -target_include_directories(celix_pubsub_interceptors_example PRIVATE include) \ No newline at end of file diff --git a/bundles/pubsub/examples/pubsub/interceptors/include/first_interceptor_private.h b/bundles/pubsub/examples/pubsub/interceptors/include/first_interceptor_private.h deleted file mode 100644 index ddc5dbd91..000000000 --- a/bundles/pubsub/examples/pubsub/interceptors/include/first_interceptor_private.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_FIRST_INTERCEPTOR_PRIVATE_H -#define CELIX_FIRST_INTERCEPTOR_PRIVATE_H - -#include -#include "pubsub_interceptor.h" - -typedef struct first_interceptor { - - celix_thread_mutex_t mutex; - - uint64_t sequenceNumber; - -} first_interceptor_t; - -static const char *const SEQUENCE_NUMBER = "sequence.number"; - -celix_status_t firstInterceptor_create(first_interceptor_t **interceptor); -celix_status_t firstInterceptor_destroy(first_interceptor_t *interceptor); - -bool firstInterceptor_preSend(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, uint32_t msgTypeId, const void *message, celix_properties_t *metadata); -void firstInterceptor_postSend(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, uint32_t msgTypeId, const void *message, celix_properties_t *metadata); -bool firstInterceptor_preReceive(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, uint32_t msgTypeId, const void *message, celix_properties_t *metadata); -void firstInterceptor_postReceive(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, uint32_t msgTypeId, const void *message, celix_properties_t *metadata); - -#endif //CELIX_FIRST_INTERCEPTOR_PRIVATE_H diff --git a/bundles/pubsub/examples/pubsub/interceptors/include/second_interceptor_private.h b/bundles/pubsub/examples/pubsub/interceptors/include/second_interceptor_private.h deleted file mode 100644 index 4819277a8..000000000 --- a/bundles/pubsub/examples/pubsub/interceptors/include/second_interceptor_private.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -#ifndef CELIX_SECOND_INTERCEPTOR_PRIVATE_H -#define CELIX_SECOND_INTERCEPTOR_PRIVATE_H - -#include "pubsub_interceptor.h" - -typedef struct second_interceptor { - -} second_interceptor_t; - -celix_status_t secondInterceptor_create(second_interceptor_t **interceptor); -celix_status_t secondInterceptor_destroy(second_interceptor_t *interceptor); - -bool secondInterceptor_preSend(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, uint32_t msgTypeId, const void *message, celix_properties_t *metadata); -void secondInterceptor_postSend(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, uint32_t msgTypeId, const void *message, celix_properties_t *metadata); -bool secondInterceptor_preReceive(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, uint32_t msgTypeId, const void *message, celix_properties_t *metadata); -void secondInterceptor_postReceive(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, uint32_t msgTypeId, const void *message, celix_properties_t *metadata); - -#endif //CELIX_SECOND_INTERCEPTOR_PRIVATE_H diff --git a/bundles/pubsub/examples/pubsub/interceptors/src/first_interceptor.c b/bundles/pubsub/examples/pubsub/interceptors/src/first_interceptor.c deleted file mode 100644 index 62ce21d7c..000000000 --- a/bundles/pubsub/examples/pubsub/interceptors/src/first_interceptor.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -#include "first_interceptor_private.h" - -#include - -celix_status_t firstInterceptor_create(first_interceptor_t **interceptor) { - celix_status_t status = CELIX_SUCCESS; - - *interceptor = calloc(1, sizeof(**interceptor)); - if (!*interceptor) { - status = CELIX_ENOMEM; - } else { - (*interceptor)->sequenceNumber = 0; - - status = celixThreadMutex_create(&(*interceptor)->mutex, NULL); - } - - return status; -} - -celix_status_t firstInterceptor_destroy(first_interceptor_t *interceptor) { - free(interceptor); - return CELIX_SUCCESS; -} - - -bool firstInterceptor_preSend(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, const uint32_t msgTypeId, const void *message, celix_properties_t *metadata) { - first_interceptor_t *interceptor = handle; - celixThreadMutex_lock(&interceptor->mutex); - - printf("Invoked preSend on first interceptor\n"); - - celix_properties_setLong((celix_properties_t *) metadata, SEQUENCE_NUMBER, interceptor->sequenceNumber++); - - celixThreadMutex_unlock(&interceptor->mutex); - - return true; -} - -void firstInterceptor_postSend(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, uint32_t msgTypeId, const void *message, celix_properties_t *metadata) { - uint64_t sequence = celix_properties_getAsLong(metadata, SEQUENCE_NUMBER, 0); - printf("Invoked postSend on first interceptor, for message with sequenceNumber [%"PRIu64"]\n", sequence); -} - -bool firstInterceptor_preReceive(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, uint32_t msgTypeId, const void *message, celix_properties_t *metadata) { - uint64_t sequence = celix_properties_getAsLong(metadata, SEQUENCE_NUMBER, 0); - printf("Invoked preReceive on first interceptor, for message with sequenceNumber [%"PRIu64"]\n", sequence); - - return true; -} - -void firstInterceptor_postReceive(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, uint32_t msgTypeId, const void *message, celix_properties_t *metadata) { - uint64_t sequence = celix_properties_getAsLong(metadata, SEQUENCE_NUMBER, 0); - printf("Invoked postReceive on first interceptor, for message with sequenceNumber [%"PRIu64"]\n", sequence); -} - diff --git a/bundles/pubsub/examples/pubsub/interceptors/src/ps_interceptor_activator.c b/bundles/pubsub/examples/pubsub/interceptors/src/ps_interceptor_activator.c deleted file mode 100644 index 9bafd7555..000000000 --- a/bundles/pubsub/examples/pubsub/interceptors/src/ps_interceptor_activator.c +++ /dev/null @@ -1,95 +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 "celix_bundle_activator.h" -#include "celix_constants.h" - -#include "first_interceptor_private.h" -#include "second_interceptor_private.h" - -#include - -struct interceptorActivator { - first_interceptor_t *interceptor; - uint64_t interceptorSvcId; - pubsub_interceptor_t interceptorSvc; - - second_interceptor_t *secondInterceptor; - uint64_t secondInterceptorSvcId; - pubsub_interceptor_t secondInterceptorSvc; -}; - -static int interceptor_start(struct interceptorActivator *act, celix_bundle_context_t *ctx) { - first_interceptor_t *interceptor = NULL; - firstInterceptor_create(&interceptor); - - act->interceptorSvc.handle = interceptor; - act->interceptorSvc.preSend = firstInterceptor_preSend; - act->interceptorSvc.postSend = firstInterceptor_postSend; - act->interceptorSvc.preReceive = firstInterceptor_preReceive; - act->interceptorSvc.postReceive = firstInterceptor_postReceive; - - act->interceptor = interceptor; - - celix_properties_t *props = celix_properties_create(); - celix_properties_setLong(props, CELIX_FRAMEWORK_SERVICE_RANKING, 10); - - celix_service_registration_options_t opts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS; - opts.svc = &act->interceptorSvc; - opts.serviceName = PUBSUB_INTERCEPTOR_SERVICE_NAME; - opts.serviceVersion = PUBSUB_INTERCEPTOR_SERVICE_VERSION; - opts.properties = props; - - act->interceptorSvcId = celix_bundleContext_registerServiceWithOptions(ctx, &opts); - - second_interceptor_t *secondInterceptor = NULL; - secondInterceptor_create(&secondInterceptor); - - act->secondInterceptorSvc.handle = secondInterceptor; - act->secondInterceptorSvc.preSend = secondInterceptor_preSend; - act->secondInterceptorSvc.postSend = secondInterceptor_postSend; - act->secondInterceptorSvc.preReceive = secondInterceptor_preReceive; - act->secondInterceptorSvc.postReceive = secondInterceptor_postReceive; - - act->secondInterceptor = secondInterceptor; - - celix_properties_t *secondProps = celix_properties_create(); - celix_properties_setLong(secondProps, CELIX_FRAMEWORK_SERVICE_RANKING, 20); - - celix_service_registration_options_t secondOpts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS; - secondOpts.svc = &act->secondInterceptorSvc; - secondOpts.serviceName = PUBSUB_INTERCEPTOR_SERVICE_NAME; - secondOpts.serviceVersion = PUBSUB_INTERCEPTOR_SERVICE_VERSION; - secondOpts.properties = secondProps; - - act->secondInterceptorSvcId = celix_bundleContext_registerServiceWithOptions(ctx, &secondOpts); - - return 0; -} - -static int interceptor_stop(struct interceptorActivator *act, celix_bundle_context_t *ctx) { - celix_bundleContext_unregisterService(ctx, act->interceptorSvcId); - firstInterceptor_destroy(act->interceptor); - - celix_bundleContext_unregisterService(ctx, act->secondInterceptorSvcId); - secondInterceptor_destroy(act->secondInterceptor); - - return 0; -} - -CELIX_GEN_BUNDLE_ACTIVATOR(struct interceptorActivator, interceptor_start, interceptor_stop) \ No newline at end of file diff --git a/bundles/pubsub/examples/pubsub/interceptors/src/second_interceptor.c b/bundles/pubsub/examples/pubsub/interceptors/src/second_interceptor.c deleted file mode 100644 index be4d04e13..000000000 --- a/bundles/pubsub/examples/pubsub/interceptors/src/second_interceptor.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -#include "second_interceptor_private.h" - -celix_status_t secondInterceptor_create(second_interceptor_t **interceptor) { - celix_status_t status = CELIX_SUCCESS; - - *interceptor = calloc(1, sizeof(**interceptor)); - if (!*interceptor) { - status = CELIX_ENOMEM; - } else { - } - - return status; -} - -celix_status_t secondInterceptor_destroy(second_interceptor_t *interceptor) { - free(interceptor); - return CELIX_SUCCESS; -} - - -bool secondInterceptor_preSend(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, uint32_t msgTypeId, const void *message, celix_properties_t *metadata) { - printf("Invoked preSend on second interceptor\n"); - - return true; -} - -void secondInterceptor_postSend(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, uint32_t msgTypeId, const void *message, celix_properties_t *metadata) { - printf("Invoked postSend on second interceptor\n"); -} - -bool secondInterceptor_preReceive(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, uint32_t msgTypeId, const void *message, celix_properties_t *metadata) { - printf("Invoked preReceive on second interceptor\n"); - - return true; -} - -void secondInterceptor_postReceive(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, uint32_t msgTypeId, const void *message, celix_properties_t *metadata) { - printf("Invoked postReceive on second interceptor\n"); -} - diff --git a/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor b/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor deleted file mode 100644 index 367bf3482..000000000 --- a/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor +++ /dev/null @@ -1,10 +0,0 @@ -:header -type=message -name=poi1 -version=1.0.0 -:annotations -classname=org.example.PointOfInterest -:types -location={DD lat lon} -:message -{llocation;tttt location name description extra data} diff --git a/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor b/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor deleted file mode 100644 index 32870e85f..000000000 --- a/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor +++ /dev/null @@ -1,11 +0,0 @@ -:header -type=message -name=poi2 -version=1.0.0 -:annotations -classname=org.example.PointOfInterest -msgId=5555 -:types -location={DD lat lon} -:message -{llocation;tttt location name description extra data} diff --git a/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poiCmd.descriptor b/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poiCmd.descriptor deleted file mode 100644 index f4f263c2e..000000000 --- a/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poiCmd.descriptor +++ /dev/null @@ -1,8 +0,0 @@ -:header -type=message -name=poiCmd -version=1.0.0 -:annotations -classname=org.example.PointOfInterestCommand -:message -{t command} diff --git a/bundles/pubsub/examples/pubsub/msg_descriptors/poi1.properties b/bundles/pubsub/examples/pubsub/msg_descriptors/poi1.properties deleted file mode 100644 index 1a07f354a..000000000 --- a/bundles/pubsub/examples/pubsub/msg_descriptors/poi1.properties +++ /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. - -# -# included in the bundle at location META-INF/topics/[pub|sub]/poi1.properties -# - -#topic info -topic.name=poi1 -topic.id=poi1 - -#Interface info -interface.name=org.example.unknown -interface.version=1.0.0 -interface.messages=poi1 poi2 - -# Version info -interface.message.consumer.range@poi1=[0.0.0,1.0.0) -interface.message.provider.version@poi1=0.0.0 -interface.message.consumer.range@poi2=[0.0.0,1.0.0) -interface.message.provider.version@poi2=0.0.0 - - -qos=sample diff --git a/bundles/pubsub/examples/pubsub/msg_descriptors/poi2.properties b/bundles/pubsub/examples/pubsub/msg_descriptors/poi2.properties deleted file mode 100644 index c0c6e28a6..000000000 --- a/bundles/pubsub/examples/pubsub/msg_descriptors/poi2.properties +++ /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. - -# -# included in the bundle at location META-INF/topics/[pub|sub]/poi2.properties -# - -#topic info -topic.name=poi2 -topic.id=poi2 - -#Interface info -interface.name=org.example.unknown -interface.version=1.0.0 -interface.messages=poi1 poi2 - -# Version info -interface.message.consumer.range@poi1=[0.0.0,1.0.0) -interface.message.provider.version@poi1=0.0.0 -interface.message.consumer.range@poi2=[0.0.0,1.0.0) -interface.message.provider.version@poi2=0.0.0 - - -qos=control diff --git a/bundles/pubsub/examples/pubsub/msg_descriptors/poiCmd.properties b/bundles/pubsub/examples/pubsub/msg_descriptors/poiCmd.properties deleted file mode 100644 index ffecb9d34..000000000 --- a/bundles/pubsub/examples/pubsub/msg_descriptors/poiCmd.properties +++ /dev/null @@ -1,35 +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. - -# -# included in the bundle at location META-INF/topics/[pub|sub]/poi2.properties -# - -#topic info -topic.name=poiCmd -topic.id=poiCmd - -#Interface info -interface.name=org.example.unknown -interface.version=1.0.0 -interface.messages=poiCmd - -# Version info -interface.message.consumer.range@poiCmd=[0.0.0,1.0.0) -interface.message.provider.version@poiCmd=0.0.0 - -qos=control diff --git a/bundles/pubsub/examples/pubsub/publisher/CMakeLists.txt b/bundles/pubsub/examples/pubsub/publisher/CMakeLists.txt deleted file mode 100644 index b55d90777..000000000 --- a/bundles/pubsub/examples/pubsub/publisher/CMakeLists.txt +++ /dev/null @@ -1,51 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -add_celix_bundle(celix_pubsub_poi_publisher - SYMBOLIC_NAME "apache_celix_pubsub_poi_publisher" - VERSION "1.0.0" - SOURCES - private/src/ps_pub_activator.c - private/src/pubsub_publisher.c -) - -target_link_libraries(celix_pubsub_poi_publisher PRIVATE Celix::pubsub_api) -target_include_directories(celix_pubsub_poi_publisher PRIVATE private/include) -celix_deprecated_utils_headers(celix_pubsub_poi_publisher) -celix_deprecated_framework_headers(celix_pubsub_poi_publisher) - -celix_bundle_files(celix_pubsub_poi_publisher - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor - DESTINATION "META-INF/descriptors" -) - -celix_bundle_files(celix_pubsub_poi_publisher - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/pubsub/msg_descriptors/poi1.properties - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/pubsub/msg_descriptors/poi2.properties - DESTINATION "META-INF/topics/pub" -) - -celix_bundle_files(celix_pubsub_poi_publisher - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/keys/publisher - DESTINATION "META-INF/keys" -) - -celix_bundle_files(celix_pubsub_poi_publisher - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/keys/subscriber/public - DESTINATION "META-INF/keys/subscriber" -) diff --git a/bundles/pubsub/examples/pubsub/publisher/private/include/pubsub_publisher_private.h b/bundles/pubsub/examples/pubsub/publisher/private/include/pubsub_publisher_private.h deleted file mode 100644 index 12d422728..000000000 --- a/bundles/pubsub/examples/pubsub/publisher/private/include/pubsub_publisher_private.h +++ /dev/null @@ -1,55 +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_PUBLISHER_PRIVATE_H_ -#define PUBSUB_PUBLISHER_PRIVATE_H_ - -#include "celix_array_list.h" -#include "hash_map.h" -#include -#include "pubsub/publisher.h" - -struct pubsub_sender { - celix_array_list_t* trackers; - const char *ident; - hash_map_pt tid_map; //service -> tid - long bundleId; - bool stop; -}; -typedef struct pubsub_sender pubsub_sender_t; - -struct send_thread_struct { - pubsub_publisher_t *service; - pubsub_sender_t *publisher; - const char *topic; -}; -typedef struct send_thread_struct send_thread_struct_t; - -pubsub_sender_t* publisher_create(celix_array_list_t* trackers, const char* ident,long bundleId); - -void publisher_start(pubsub_sender_t *client); -void publisher_stop(pubsub_sender_t *client); - -void publisher_destroy(pubsub_sender_t *client); - -void publisher_publishSvcAdded(void * handle, void *svc, const celix_properties_t *props); -void publisher_publishSvcRemoved(void * handle, void *svc, const celix_properties_t *props); - - -#endif /* PUBSUB_PUBLISHER_PRIVATE_H_ */ diff --git a/bundles/pubsub/examples/pubsub/publisher/private/src/ps_pub_activator.c b/bundles/pubsub/examples/pubsub/publisher/private/src/ps_pub_activator.c deleted file mode 100644 index 7efc3ac13..000000000 --- a/bundles/pubsub/examples/pubsub/publisher/private/src/ps_pub_activator.c +++ /dev/null @@ -1,96 +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 -#include -#include - -#include "celix_bundle_activator.h" - -#include "pubsub/publisher.h" -#include "pubsub_publisher_private.h" - -static const char * PUB_TOPICS[] = { - "poi1", - "poi2", - NULL -}; - -struct publisherActivator { - pubsub_sender_t *client; - celix_array_list_t* trackerList;//List -}; - -static int pub_start(struct publisherActivator *act, celix_bundle_context_t *ctx) { - const char *fwUUID = celix_bundleContext_getProperty(ctx,CELIX_FRAMEWORK_UUID, NULL); - if (fwUUID == NULL) { - printf("PUBLISHER: Cannot retrieve fwUUID.\n"); - return CELIX_INVALID_BUNDLE_CONTEXT; - } - - - celix_bundle_t *bnd = celix_bundleContext_getBundle(ctx); - long bundleId = celix_bundle_getId(bnd); - - act->trackerList = celix_arrayList_create(); - act->client = publisher_create(act->trackerList, fwUUID, bundleId); - - int i; - char filter[128]; - for (i = 0; PUB_TOPICS[i] != NULL; i++) { - const char* topic = PUB_TOPICS[i]; - memset(filter,0,128); -#ifdef USE_SCOPE - char *scope; - asprintf(&scope, "my_scope_%d", i); - snprintf(filter, 128, "(%s=%s)(%s=%s)", PUBSUB_PUBLISHER_TOPIC, topic, PUBSUB_PUBLISHER_SCOPE, scope); - free(scope); -#else - snprintf(filter, 128, "(&(%s=%s)(!(%s=*)))", (char*) PUBSUB_PUBLISHER_TOPIC, topic, PUBSUB_PUBLISHER_SCOPE); -#endif - celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; - opts.callbackHandle = act->client; - opts.addWithProperties = publisher_publishSvcAdded; - opts.removeWithProperties = publisher_publishSvcRemoved; - opts.filter.serviceName = PUBSUB_PUBLISHER_SERVICE_NAME; - opts.filter.filter = filter; - long trackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts); - - celix_arrayList_addLong(act->trackerList,trackerId); - } - - publisher_start(act->client); - - return 0; -} - -static int pub_stop(struct publisherActivator *act, celix_bundle_context_t *ctx) { - for (int i = 0; i < celix_arrayList_size(act->trackerList); i++) { - long trkId = celix_arrayList_getLong(act->trackerList, i); - celix_bundleContext_stopTracker(ctx, trkId); - } - publisher_stop(act->client); - - publisher_destroy(act->client); - celix_arrayList_destroy(act->trackerList); - - return 0; -} - -CELIX_GEN_BUNDLE_ACTIVATOR(struct publisherActivator, pub_start, pub_stop) \ No newline at end of file diff --git a/bundles/pubsub/examples/pubsub/publisher/private/src/pubsub_publisher.c b/bundles/pubsub/examples/pubsub/publisher/private/src/pubsub_publisher.c deleted file mode 100644 index c65146f6b..000000000 --- a/bundles/pubsub/examples/pubsub/publisher/private/src/pubsub_publisher.c +++ /dev/null @@ -1,168 +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_publisher.c - * - * \date Sep 21, 2010 - * \author Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - -#include -#include -#include -#include - -#include "celix_threads.h" - -#include "poi.h" - -#include "pubsub_publisher_private.h" - -static double randCoordinate(double min, double max) { - double ret = min + (((double)random()) / (((double)RAND_MAX)/(max-min))); - return ret; -} - -static void* send_thread(void* arg) { - send_thread_struct_t *st_struct = (send_thread_struct_t *) arg; - - pubsub_publisher_t *publish_svc = st_struct->service; - pubsub_sender_t *publisher = st_struct->publisher; - - char fwUUID[9]; - memset(fwUUID, 0, 9); - memcpy(fwUUID, publisher->ident, 8); - - //poi_t point = calloc(1,sizeof(*point)); - location_t place = calloc(1, sizeof(*place)); - - char *desc = calloc(64, sizeof(char)); - snprintf(desc, 64, "fw-%s [TID=%lu]", fwUUID, (unsigned long)pthread_self()); - - char *name = calloc(64, sizeof(char)); - snprintf(name, 64, "Bundle#%ld", publisher->bundleId); - - place->name = name; - place->description = desc; - place->extra = "extra value"; - printf("TOPIC : %s\n", st_struct->topic); - - unsigned int msgId = 0; - - while (publisher->stop == false) { - if (msgId == 0) { - if (publish_svc->localMsgTypeIdForMsgType(publish_svc->handle, st_struct->topic, &msgId) != 0) { - printf("PUBLISHER: Cannot retrieve msgId for message '%s'\n", MSG_POI_NAME); - } - } - - if (msgId > 0) { - place->position.lat = randCoordinate(MIN_LAT, MAX_LAT); - place->position.lon = randCoordinate(MIN_LON, MAX_LON); - int nr_char = (int) randCoordinate(5, 100000); - place->data = calloc(nr_char, 1); - for (int i = 0; i < (nr_char - 1); i++) { - place->data[i] = i % 10 + '0'; - } - place->data[nr_char - 1] = '\0'; - if (publish_svc->send) { - celix_properties_t *metadata = celix_properties_create(); - celix_properties_set(metadata, "Key", "Value"); - if (publish_svc->send(publish_svc->handle, msgId, place, metadata) == 0) { - printf("Sent %s [%f, %f] (%s, %s) data len = %d\n", st_struct->topic, - place->position.lat, place->position.lon, place->name, place->description, nr_char); - } - } else { - printf("No send for %s\n", st_struct->topic); - } - - free(place->data); - } - sleep(2); - } - - free(place->description); - free(place->name); - free(place); - - free(st_struct); - - return NULL; -} - -pubsub_sender_t* publisher_create(celix_array_list_t* trackers,const char* ident,long bundleId) { - pubsub_sender_t *publisher = malloc(sizeof(*publisher)); - - publisher->trackers = trackers; - publisher->ident = ident; - publisher->bundleId = bundleId; - publisher->tid_map = hashMap_create(NULL, NULL, NULL, NULL); - publisher->stop = false; - - return publisher; -} - -void publisher_start(pubsub_sender_t *client) { - printf("PUBLISHER: starting up...\n"); -} - -void publisher_stop(pubsub_sender_t *client) { - printf("PUBLISHER: stopping...\n"); -} - -void publisher_destroy(pubsub_sender_t *client) { - hashMap_destroy(client->tid_map, false, false); - client->trackers = NULL; - client->ident = NULL; - free(client); -} - -void publisher_publishSvcAdded(void * handle, void *svc, const celix_properties_t *props) { - pubsub_publisher_t *publish_svc = (pubsub_publisher_t *) svc; - pubsub_sender_t *manager = (pubsub_sender_t *) handle; - manager->stop = false; - - printf("PUBLISHER: new publish service exported (%s).\n", manager->ident); - - send_thread_struct_t *data = calloc(1, sizeof(*data)); - data->service = publish_svc; - data->publisher = manager; - data->topic = celix_properties_get(props, PUBSUB_PUBLISHER_TOPIC, "!ERROR!"); - celix_thread_t *tid = malloc(sizeof(*tid)); - celixThread_create(tid, NULL, send_thread, (void*)data); - hashMap_put(manager->tid_map, publish_svc, tid); -} - -void publisher_publishSvcRemoved(void * handle, void *svc, const celix_properties_t *props) { - pubsub_sender_t *manager = (pubsub_sender_t *) handle; - celix_thread_t *tid = hashMap_get(manager->tid_map, svc); - manager->stop = true; - -#if defined(__APPLE__) && defined(__MACH__) - uint64_t threadid; - pthread_threadid_np(tid->thread, &threadid); - printf("PUBLISHER: publish service unexporting (%s) %llu!\n",manager->ident, threadid); -#else - printf("PUBLISHER: publish service unexporting (%s) %li!\n", manager->ident, tid->thread); -#endif - - celixThread_join(*tid,NULL); - free(tid); -} diff --git a/bundles/pubsub/examples/pubsub/publisher2/CMakeLists.txt b/bundles/pubsub/examples/pubsub/publisher2/CMakeLists.txt deleted file mode 100644 index 60392538e..000000000 --- a/bundles/pubsub/examples/pubsub/publisher2/CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -add_celix_bundle(celix_pubsub_poi_publisher2 - SYMBOLIC_NAME "apache_celix_pubsub_poi_publisher2" - VERSION "1.0.0" - SOURCES - ../publisher/private/src/ps_pub_activator.c - ../publisher/private/src/pubsub_publisher.c -) -target_link_libraries(celix_pubsub_poi_publisher2 PRIVATE Celix::pubsub_api) -target_include_directories(celix_pubsub_poi_publisher2 PRIVATE ../publisher/private/include) -celix_deprecated_utils_headers(celix_pubsub_poi_publisher2) - -celix_bundle_files(celix_pubsub_poi_publisher2 - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor - DESTINATION "META-INF/descriptors" -) - -celix_bundle_files(celix_pubsub_poi_publisher2 - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/pubsub/msg_descriptors/poi1.properties - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/pubsub/msg_descriptors/poi2.properties - DESTINATION "META-INF/topics/pub" -) - -celix_bundle_files(celix_pubsub_poi_publisher2 - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/keys/publisher - DESTINATION "META-INF/keys" -) - -celix_bundle_files(celix_pubsub_poi_publisher2 - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/keys/subscriber/public - DESTINATION "META-INF/keys/subscriber" -) - diff --git a/bundles/pubsub/examples/pubsub/pubsub_websocket/CMakeLists.txt b/bundles/pubsub/examples/pubsub/pubsub_websocket/CMakeLists.txt deleted file mode 100644 index b51ce1367..000000000 --- a/bundles/pubsub/examples/pubsub/pubsub_websocket/CMakeLists.txt +++ /dev/null @@ -1,62 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - - -add_celix_bundle(celix_pubsub_websocket_example - SYMBOLIC_NAME "apache_celix_pubsub_websocket_example" - VERSION "1.0.0" - SOURCES - private/src/ps_websocket_activator.c - private/src/pubsub_websocket_example.c -) -target_link_libraries(celix_pubsub_websocket_example PRIVATE Celix::pubsub_api) -target_include_directories(celix_pubsub_websocket_example PRIVATE private/include) -celix_deprecated_utils_headers(celix_pubsub_websocket_example) -celix_deprecated_framework_headers(celix_pubsub_websocket_example) - -celix_bundle_files(celix_pubsub_websocket_example - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poiCmd.descriptor - DESTINATION "META-INF/descriptors" -) - -celix_bundle_files(celix_pubsub_websocket_example - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/pubsub/msg_descriptors/poi1.properties - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/pubsub/msg_descriptors/poi2.properties - DESTINATION "META-INF/topics/pub" -) -celix_bundle_files(celix_pubsub_websocket_example - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/pubsub/msg_descriptors/poiCmd.properties - DESTINATION "META-INF/topics/sub" -) - -celix_bundle_files(celix_pubsub_websocket_example - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/keys/publisher - DESTINATION "META-INF/keys" -) - -celix_bundle_files(celix_pubsub_websocket_example - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/keys/subscriber/public - DESTINATION "META-INF/keys/subscriber" -) - -celix_bundle_add_dir(celix_pubsub_websocket_example resources DESTINATION ".") - -celix_bundle_headers(celix_pubsub_websocket_example - "X-Web-Resource: /example$/resources" -) diff --git a/bundles/pubsub/examples/pubsub/pubsub_websocket/private/include/pubsub_websocket_private.h b/bundles/pubsub/examples/pubsub/pubsub_websocket/private/include/pubsub_websocket_private.h deleted file mode 100644 index 5a26a684a..000000000 --- a/bundles/pubsub/examples/pubsub/pubsub_websocket/private/include/pubsub_websocket_private.h +++ /dev/null @@ -1,97 +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_websocket_private.h - * - * \date Jan 16, 2020 - * \author Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - -#ifndef PUBSUB_WEBSOCKET_PRIVATE_H_ -#define PUBSUB_WEBSOCKET_PRIVATE_H_ - - -#include - -#include "celix_api.h" - -#include "pubsub/subscriber.h" -#include "pubsub/publisher.h" - -struct pubsub_sender{ - array_list_t *trackers; - const char *ident; - hash_map_t *tid_map; //service -> tid - long bundleId; - bool stop; -}; -typedef struct pubsub_sender pubsub_sender_t; - -struct pubsub_receiver { - char *name; -}; - -typedef struct pubsub_receiver pubsub_receiver_t; - - -/** - * Shared Publisher and Subscriber types - * - */ -struct pubsub_info { - pubsub_sender_t *sender; - bool sending; - pubsub_receiver_t *receiver; -}; - -typedef struct pubsub_info pubsub_info_t; - -/** - * Publisher - */ -struct send_thread_struct { - pubsub_publisher_t *service; - pubsub_info_t *pubsub; - const char *topic; -}; -typedef struct send_thread_struct send_thread_struct_t; - -pubsub_sender_t* publisher_create(array_list_pt trackers, const char* ident,long bundleId); - -void publisher_start(pubsub_sender_t *client); -void publisher_stop(pubsub_sender_t *client); - -void publisher_destroy(pubsub_sender_t *client); - -void publisher_publishSvcAdded(void * handle, void *svc, const celix_properties_t *props); -void publisher_publishSvcRemoved(void * handle, void *svc, const celix_properties_t *props); - -/** - * Subscriber - */ -pubsub_receiver_t* subscriber_create(char* topics); -void subscriber_start(pubsub_receiver_t* client); -void subscriber_stop(pubsub_receiver_t* client); -void subscriber_destroy(pubsub_receiver_t* client); - -int pubsub_subscriber_recv(void* handle, const char* msgType, unsigned int msgTypeId, void* msg, const celix_properties_t *metadata, bool* release); - - -#endif /* PUBSUB_WEBSOCKET_PRIVATE_H_ */ diff --git a/bundles/pubsub/examples/pubsub/pubsub_websocket/private/src/ps_websocket_activator.c b/bundles/pubsub/examples/pubsub/pubsub_websocket/private/src/ps_websocket_activator.c deleted file mode 100644 index 5cd72d3e8..000000000 --- a/bundles/pubsub/examples/pubsub/pubsub_websocket/private/src/ps_websocket_activator.c +++ /dev/null @@ -1,163 +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. - */ -/** - * ps_websocket_activator.c - * - * \date Jan 16, 2020 - * \author Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - -#include -#include -#include - -#include "celix_api.h" - -#include "pubsub_websocket_private.h" - - -static const char * PUB_TOPICS[] = { - "poi1", - "poi2", - NULL -}; - - -#define SUB_NAME "poiCmd" -static const char * SUB_TOPICS[] = { - "poiCmd", - NULL -}; - -struct ps_websocketActivator { - pubsub_info_t *pubsub; - //Publisher vars - array_list_t *trackerList;//List - //Subscriber vars - array_list_t *registrationList; //List - pubsub_subscriber_t *subsvc; -}; - -static int pubsub_start(struct ps_websocketActivator *act, celix_bundle_context_t *ctx) { - const char *fwUUID = celix_bundleContext_getProperty(ctx,CELIX_FRAMEWORK_UUID, NULL); - if (fwUUID == NULL) { - printf("PUBLISHER: Cannot retrieve fwUUID.\n"); - return CELIX_INVALID_BUNDLE_CONTEXT; - } - - celix_bundle_t *bnd = celix_bundleContext_getBundle(ctx); - long bundleId = celix_bundle_getId(bnd); - - act->pubsub = calloc(1, sizeof(*act->pubsub)); - - //Publisher - act->trackerList = celix_arrayList_create(); - act->pubsub->sender = publisher_create(act->trackerList, fwUUID, bundleId); - - int i; - char filter[128]; - for (i = 0; PUB_TOPICS[i] != NULL; i++) { - const char* topic = PUB_TOPICS[i]; - memset(filter,0,128); -#ifdef USE_SCOPE - char *scope; - asprintf(&scope, "my_scope_%d", i); - snprintf(filter, 128, "(%s=%s)(%s=%s)", PUBSUB_PUBLISHER_TOPIC, topic, PUBSUB_PUBLISHER_SCOPE, scope); - free(scope); -#else - snprintf(filter, 128, "(%s=%s)", (char*) PUBSUB_PUBLISHER_TOPIC, topic); -#endif - celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; - opts.callbackHandle = act->pubsub; - opts.addWithProperties = publisher_publishSvcAdded; - opts.removeWithProperties = publisher_publishSvcRemoved; - opts.filter.serviceName = PUBSUB_PUBLISHER_SERVICE_NAME; - opts.filter.filter = filter; - long trackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts); - - celix_arrayList_addLong(act->trackerList,trackerId); - } - - publisher_start(act->pubsub->sender); - - //Subscriber - act->registrationList = celix_arrayList_create(); - - pubsub_subscriber_t *subsvc = calloc(1,sizeof(*subsvc)); - act->pubsub->receiver = subscriber_create(SUB_NAME); - subsvc->handle = act->pubsub; - subsvc->receive = pubsub_subscriber_recv; - - act->subsvc = subsvc; - - for (i = 0; SUB_TOPICS[i] != NULL; i++) { - const char* topic = SUB_TOPICS[i]; - celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, PUBSUB_SUBSCRIBER_TOPIC, topic); -#ifdef USE_SCOPE - char *scope; - asprintf(&scope, "my_scope_%d", i); - celix_properties_set(props, PUBSUB_SUBSCRIBER_SCOPE, scope); - free(scope); -#endif - service_registration_pt reg = NULL; - bundleContext_registerService(ctx, PUBSUB_SUBSCRIBER_SERVICE_NAME, subsvc, props, ®); - arrayList_add(act->registrationList,reg); - } - - subscriber_start((pubsub_receiver_t *) act->subsvc->handle); - - return 0; -} - -static int pubsub_stop(struct ps_websocketActivator *act, celix_bundle_context_t *ctx) { - int i; - - //Publishers - for (i = 0; i < celix_arrayList_size(act->trackerList); i++) { - long trkId = celix_arrayList_getLong(act->trackerList, i); - celix_bundleContext_stopTracker(ctx, trkId); - } - publisher_stop(act->pubsub->sender); - - publisher_destroy(act->pubsub->sender); - celix_arrayList_destroy(act->trackerList); - - //Subscriber - for (i = 0; i < celix_arrayList_size(act->registrationList); i++) { - service_registration_pt reg = celix_arrayList_get(act->registrationList, i); - serviceRegistration_unregister(reg); - } - - subscriber_stop((pubsub_receiver_t *) act->pubsub->receiver); - - act->subsvc->receive = NULL; - subscriber_destroy((pubsub_receiver_t *) act->pubsub->receiver); - act->subsvc->handle = NULL; - free(act->subsvc); - act->subsvc = NULL; - - celix_arrayList_destroy(act->registrationList); - free(act->pubsub); - - return CELIX_SUCCESS; -} - -CELIX_GEN_BUNDLE_ACTIVATOR(struct ps_websocketActivator, pubsub_start, pubsub_stop) \ No newline at end of file diff --git a/bundles/pubsub/examples/pubsub/pubsub_websocket/private/src/pubsub_websocket_example.c b/bundles/pubsub/examples/pubsub/pubsub_websocket/private/src/pubsub_websocket_example.c deleted file mode 100644 index 528b0d33f..000000000 --- a/bundles/pubsub/examples/pubsub/pubsub_websocket/private/src/pubsub_websocket_example.c +++ /dev/null @@ -1,207 +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_subscriber.c - * - * \date Sep 21, 2010 - * \author Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - -#include -#include -#include -#include -#include - -#include "poi.h" -#include "poiCmd.h" -#include "pubsub_websocket_private.h" - -#include "service_tracker.h" -#include "celix_threads.h" - - -static double randCoordinate(double min, double max) { - double ret = min + (((double)random()) / (((double)RAND_MAX)/(max-min))); - return ret; -} - -static void* send_thread(void* arg) { - send_thread_struct_t *st_struct = (send_thread_struct_t *) arg; - - pubsub_publisher_t *publish_svc = st_struct->service; - pubsub_info_t *pubsubInfo = st_struct->pubsub; - pubsub_sender_t *publisher = st_struct->pubsub->sender; - - char fwUUID[9]; - memset(fwUUID, 0, 9); - memcpy(fwUUID, publisher->ident, 8); - - location_t place = calloc(1, sizeof(*place)); - - char *desc = calloc(64, sizeof(char)); - snprintf(desc, 64, "fw-%s [TID=%lu]", fwUUID, (unsigned long)pthread_self()); - - char *name = calloc(64, sizeof(char)); - snprintf(name, 64, "Bundle#%ld", publisher->bundleId); - - place->name = name; - place->description = desc; - place->extra = "extra value"; - printf("TOPIC : %s\n", st_struct->topic); - - unsigned int msgId = 0; - - while (publisher->stop == false) { - if(pubsubInfo->sending) { - if (msgId == 0) { - if (publish_svc->localMsgTypeIdForMsgType(publish_svc->handle, st_struct->topic, &msgId) != 0) { - printf("PUBLISHER: Cannot retrieve msgId for message '%s'\n", MSG_POI_NAME); - } - } - - if (msgId > 0) { - place->position.lat = randCoordinate(MIN_LAT, MAX_LAT); - place->position.lon = randCoordinate(MIN_LON, MAX_LON); - int nr_char = (int) randCoordinate(5, 100000); - place->data = calloc(nr_char, 1); - for (int i = 0; i < (nr_char - 1); i++) { - place->data[i] = i % 10 + '0'; - } - place->data[nr_char - 1] = '\0'; - if (publish_svc->send) { - if (publish_svc->send(publish_svc->handle, msgId, place, NULL) == 0) { - printf("Sent %s [%f, %f] (%s, %s) data len = %d\n", st_struct->topic, - place->position.lat, place->position.lon, place->name, place->description, nr_char); - } - } else { - printf("No send for %s\n", st_struct->topic); - } - - free(place->data); - } - } - sleep(2); - } - - free(place->description); - free(place->name); - free(place); - - free(st_struct); - - return NULL; -} - -pubsub_sender_t* publisher_create(array_list_pt trackers,const char* ident,long bundleId) { - pubsub_sender_t *publisher = malloc(sizeof(*publisher)); - - publisher->trackers = trackers; - publisher->ident = ident; - publisher->bundleId = bundleId; - publisher->tid_map = hashMap_create(NULL, NULL, NULL, NULL); - publisher->stop = false; - - return publisher; -} - -void publisher_start(pubsub_sender_t *client) { - printf("PUBLISHER: starting up...\n"); -} - -void publisher_stop(pubsub_sender_t *client) { - printf("PUBLISHER: stopping...\n"); -} - -void publisher_destroy(pubsub_sender_t *client) { - hashMap_destroy(client->tid_map, false, false); - client->trackers = NULL; - client->ident = NULL; - free(client); -} - -void publisher_publishSvcAdded(void * handle, void *svc, const celix_properties_t *props) { - pubsub_publisher_t *publish_svc = (pubsub_publisher_t *) svc; - pubsub_info_t *manager = (pubsub_info_t *) handle; - manager->sender->stop = false; - - printf("PUBLISHER: new publish service exported (%s).\n", manager->sender->ident); - - send_thread_struct_t *data = calloc(1, sizeof(*data)); - data->service = publish_svc; - data->pubsub = manager; - data->topic = celix_properties_get(props, PUBSUB_PUBLISHER_TOPIC, "!ERROR!"); - celix_thread_t *tid = malloc(sizeof(*tid)); - celixThread_create(tid, NULL, send_thread, (void*)data); - hashMap_put(manager->sender->tid_map, publish_svc, tid); -} - -void publisher_publishSvcRemoved(void * handle, void *svc, const celix_properties_t *props) { - pubsub_info_t *manager = (pubsub_info_t *) handle; - celix_thread_t *tid = hashMap_get(manager->sender->tid_map, svc); - manager->sender->stop = true; - -#if defined(__APPLE__) && defined(__MACH__) - uint64_t threadid; - pthread_threadid_np(tid->thread, &threadid); - printf("PUBLISHER: publish service unexporting (%s) %llu!\n",manager->sender->ident, threadid); -#else - printf("PUBLISHER: publish service unexporting (%s) %li!\n", manager->sender->ident, tid->thread); -#endif - - celixThread_join(*tid,NULL); - free(tid); -} - -pubsub_receiver_t* subscriber_create(char* topics) { - pubsub_receiver_t *sub = calloc(1,sizeof(*sub)); - sub->name = strdup(topics); - return sub; -} - - -void subscriber_start(pubsub_receiver_t *subscriber) { - printf("Subscriber started...\n"); -} - -void subscriber_stop(pubsub_receiver_t *subscriber) { - printf("Subscriber stopped...\n"); -} - -void subscriber_destroy(pubsub_receiver_t *subscriber) { - if (subscriber->name != NULL) { - free(subscriber->name); - } - subscriber->name=NULL; - free(subscriber); -} - -int pubsub_subscriber_recv(void* handle, const char* msgType, unsigned int msgTypeId, void* msg, const celix_properties_t *metadata, bool* release) { - poi_cmd_t *cmd = (poi_cmd_t *) msg; - pubsub_info_t *pubsub = (pubsub_info_t *) handle; - printf("Received command %s\n", cmd->command); - - if(strcmp(cmd->command, "start") == 0) { - pubsub->sending = true; - } else { - pubsub->sending = false; - } - return 0; -} diff --git a/bundles/pubsub/examples/pubsub/pubsub_websocket/resources/index.html b/bundles/pubsub/examples/pubsub/pubsub_websocket/resources/index.html deleted file mode 100644 index 37c0daf45..000000000 --- a/bundles/pubsub/examples/pubsub/pubsub_websocket/resources/index.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - Apache Celix Websocket publisher example - - - -
-

Poi1 message:

-
-

-
-
-
-

Poi2 message:

-
-

-
-
-

Send start/stop message:

-
-
- - - - - -
-

Choose command:

-
- -
- -
-
- - - diff --git a/bundles/pubsub/examples/pubsub/pubsub_websocket/resources/script.js b/bundles/pubsub/examples/pubsub/pubsub_websocket/resources/script.js deleted file mode 100644 index 503db7a72..000000000 --- a/bundles/pubsub/examples/pubsub/pubsub_websocket/resources/script.js +++ /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. - */ - -var seqnr = 0; -var sendSocketP1; - -function docReady() { - var host = window.location.host; - var rcvSocketP1 = new WebSocket("ws://" + host + "/pubsub/default/poi1"); - var rcvSocketP2 = new WebSocket("ws://" + host + "/pubsub/default/poi2"); - sendSocketP1 = new WebSocket("ws://" + host + "/pubsub/default/poiCmd"); - - rcvSocketP1.onmessage = function (event) { - console.log(event); - var obj = JSON.parse(event.data); - document.getElementById("receivePoi1").innerHTML = "Received " + obj.id + " message with sequence nr: " - + obj.seqNr + "
latitude = " + JSON.stringify(obj.data.location.lat) + "
longitude = " + JSON.stringify(obj.data.location.lon); - }; - - rcvSocketP2.onmessage = function (event) { - console.log(event); - var obj = JSON.parse(event.data); - document.getElementById("receivePoi2").innerHTML = "Received " + obj.id + " message with sequence nr: " - + obj.seqNr + "
latitude = " + JSON.stringify(obj.data.location.lat) + "
longitude = " + JSON.stringify(obj.data.location.lon); - }; -} - -function submitForm() { - var element = document.getElementById("command"); - var value = element.options[element.selectedIndex].value; - let msg = "{\"id\":\"poiCmd\", \"major\": 1, \"minor\": 0, \"seqNr\": " + seqnr++ + ", \"data\": {" + - "\"command\": \"" + value + "\" }}"; - - console.log("Sending message: " + msg); - sendSocketP1.send(msg); - alert("sending message: " + msg); - return false; -} \ No newline at end of file diff --git a/bundles/pubsub/examples/pubsub/subscriber/CMakeLists.txt b/bundles/pubsub/examples/pubsub/subscriber/CMakeLists.txt deleted file mode 100644 index 363833f26..000000000 --- a/bundles/pubsub/examples/pubsub/subscriber/CMakeLists.txt +++ /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. - -add_celix_bundle(celix_pubsub_poi_subscriber - SYMBOLIC_NAME "apache_celix_pubsub_poi_subscriber" - VERSION "1.0.0" - SOURCES - private/src/ps_sub_activator.c - private/src/pubsub_subscriber.c -) - -target_link_libraries(celix_pubsub_poi_subscriber PRIVATE Celix::pubsub_api) -target_include_directories(celix_pubsub_poi_subscriber PRIVATE private/include) -celix_deprecated_utils_headers(celix_pubsub_poi_subscriber) -celix_deprecated_framework_headers(celix_pubsub_poi_subscriber) - - -celix_bundle_files(celix_pubsub_poi_subscriber - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi1.descriptor - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/pubsub/msg_descriptors/msg_poi2.descriptor - DESTINATION "META-INF/descriptors" -) - -celix_bundle_files(celix_pubsub_poi_subscriber - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/pubsub/msg_descriptors/poi1.properties - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/pubsub/msg_descriptors/poi2.properties - DESTINATION "META-INF/topics/sub" -) - -celix_bundle_files(celix_pubsub_poi_subscriber - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/keys/subscriber - DESTINATION "META-INF/keys" -) - -celix_bundle_files(celix_pubsub_poi_subscriber - ${PROJECT_SOURCE_DIR}/bundles/pubsub/examples/keys/publisher/public - DESTINATION "META-INF/keys/publisher" -) diff --git a/bundles/pubsub/examples/pubsub/subscriber/private/include/pubsub_subscriber_private.h b/bundles/pubsub/examples/pubsub/subscriber/private/include/pubsub_subscriber_private.h deleted file mode 100644 index 8021517cb..000000000 --- a/bundles/pubsub/examples/pubsub/subscriber/private/include/pubsub_subscriber_private.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -/** - * pubsub_subscriber_private.h - * - * \date Sep 21, 2010 - * \author Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - -#ifndef PUBSUB_SUBSCRIBER_PRIVATE_H_ -#define PUBSUB_SUBSCRIBER_PRIVATE_H_ - - -#include -#include - -#include "pubsub/subscriber.h" - -struct pubsub_receiver { - char *name; -}; - -typedef struct pubsub_receiver pubsub_receiver_t; - -pubsub_receiver_t* subscriber_create(char* topics); -void subscriber_start(pubsub_receiver_t* client); -void subscriber_stop(pubsub_receiver_t* client); -void subscriber_destroy(pubsub_receiver_t* client); - -int pubsub_subscriber_recv(void* handle, const char* msgType, unsigned int msgTypeId, void* msg, const celix_properties_t *metadata, bool* release); - - -#endif /* PUBSUB_SUBSCRIBER_PRIVATE_H_ */ diff --git a/bundles/pubsub/examples/pubsub/subscriber/private/src/ps_sub_activator.c b/bundles/pubsub/examples/pubsub/subscriber/private/src/ps_sub_activator.c deleted file mode 100644 index 1e6385e16..000000000 --- a/bundles/pubsub/examples/pubsub/subscriber/private/src/ps_sub_activator.c +++ /dev/null @@ -1,113 +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. - */ -/** - * ps_sub_activator.c - * - * \date Sep 21, 2010 - * \author Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - -#include -#include - -#include "celix_bundle_activator.h" -#include "bundle_context.h" - -#include "pubsub_subscriber_private.h" - -#define SUB_NAME "poi1;poi2" -static const char * SUB_TOPICS[] = { - "poi1", - "poi2", - NULL -}; - -struct subscriberActivator { - celix_array_list_t* registrationList; //List - pubsub_subscriber_t *subsvc; -}; - -celix_status_t bundleActivator_create(celix_bundle_context_t *context, void **userData) { - struct subscriberActivator * act = calloc(1,sizeof(struct subscriberActivator)); - *userData = act; - act->registrationList = celix_arrayList_create(); - return CELIX_SUCCESS; -} - -celix_status_t bundleActivator_start(void * userData, celix_bundle_context_t *context) { - struct subscriberActivator * act = (struct subscriberActivator *) userData; - - pubsub_subscriber_t *subsvc = calloc(1,sizeof(*subsvc)); - pubsub_receiver_t *sub = subscriber_create(SUB_NAME); - subsvc->handle = sub; - subsvc->receive = pubsub_subscriber_recv; - - act->subsvc = subsvc; - - int i; - for (i = 0; SUB_TOPICS[i] != NULL; i++) { - const char* topic = SUB_TOPICS[i]; - celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, PUBSUB_SUBSCRIBER_TOPIC, topic); -#ifdef USE_SCOPE - char *scope; - asprintf(&scope, "my_scope_%d", i); - celix_properties_set(props, PUBSUB_SUBSCRIBER_SCOPE, scope); - free(scope); -#endif - service_registration_pt reg = NULL; - bundleContext_registerService(context, PUBSUB_SUBSCRIBER_SERVICE_NAME, subsvc, props, ®); - celix_arrayList_add(act->registrationList,reg); - } - - subscriber_start((pubsub_receiver_t *) act->subsvc->handle); - - return CELIX_SUCCESS; -} - -celix_status_t bundleActivator_stop(void * userData, celix_bundle_context_t *context) { - struct subscriberActivator * act = (struct subscriberActivator *) userData; - - int i; - for (i = 0; i < celix_arrayList_size(act->registrationList); i++) { - service_registration_pt reg = celix_arrayList_get(act->registrationList, i); - serviceRegistration_unregister(reg); - - } - - subscriber_stop((pubsub_receiver_t *) act->subsvc->handle); - - return CELIX_SUCCESS; -} - -celix_status_t bundleActivator_destroy(void * userData, celix_bundle_context_t *context) { - - struct subscriberActivator * act = (struct subscriberActivator *) userData; - - act->subsvc->receive = NULL; - subscriber_destroy((pubsub_receiver_t *) act->subsvc->handle); - act->subsvc->handle = NULL; - free(act->subsvc); - act->subsvc = NULL; - celix_arrayList_destroy(act->registrationList); - free(act); - - return CELIX_SUCCESS; -} diff --git a/bundles/pubsub/examples/pubsub/subscriber/private/src/pubsub_subscriber.c b/bundles/pubsub/examples/pubsub/subscriber/private/src/pubsub_subscriber.c deleted file mode 100644 index c05df1ee0..000000000 --- a/bundles/pubsub/examples/pubsub/subscriber/private/src/pubsub_subscriber.c +++ /dev/null @@ -1,71 +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_subscriber.c - * - * \date Sep 21, 2010 - * \author Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - -#include -#include -#include -#include - -#include "poi.h" -#include "pubsub_subscriber_private.h" - -pubsub_receiver_t* subscriber_create(char* topics) { - pubsub_receiver_t *sub = calloc(1,sizeof(*sub)); - sub->name = strdup(topics); - return sub; -} - - -void subscriber_start(pubsub_receiver_t *subscriber) { - printf("Subscriber started...\n"); -} - -void subscriber_stop(pubsub_receiver_t *subscriber) { - printf("Subscriber stopped...\n"); -} - -void subscriber_destroy(pubsub_receiver_t *subscriber) { - if (subscriber->name != NULL) { - free(subscriber->name); - } - subscriber->name=NULL; - free(subscriber); -} - -int pubsub_subscriber_recv(void* handle, const char* msgType, unsigned int msgTypeId, void* msg, const celix_properties_t *metadata, bool* release) { - location_t place = (location_t)msg; - printf("Recv (%s): [%f, %f] (%s, %s, %s, len data %li)\n", msgType, place->position.lat, place->position.lon, place->name, place->description, place->extra, (long)(strlen(place->data) + 1)); - - if (metadata == NULL || celix_properties_size(metadata) == 0) { - printf("No metadata\n"); - } else { - CELIX_PROPERTIES_ITERATE(metadata, iter) { - printf("%s=%s\n", iter.key, iter.entry.value); - } - } - - return 0; -} diff --git a/bundles/pubsub/integration/CMakeLists.txt b/bundles/pubsub/integration/CMakeLists.txt deleted file mode 100644 index 64ce44142..000000000 --- a/bundles/pubsub/integration/CMakeLists.txt +++ /dev/null @@ -1,505 +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. - -celix_subproject(PUBSUB_INTEGRATION "Option to build the pubsub integration" ON) -if (PUBSUB_INTEGRATION) - add_celix_bundle(pubsub_endpoint_sut - #"Vanilla" bundle which is under test - SOURCES - gtest/sut_endpoint_activator.c - VERSION 1.0.0 - ) - target_include_directories(pubsub_endpoint_sut PRIVATE gtest) - target_link_libraries(pubsub_endpoint_sut PRIVATE Celix::pubsub_api) - celix_deprecated_utils_headers(pubsub_endpoint_sut) - celix_bundle_files(pubsub_endpoint_sut - meta_data/msg.descriptor - DESTINATION "META-INF/descriptors" - ) - celix_bundle_files(pubsub_endpoint_sut - meta_data/ping2.properties - DESTINATION "META-INF/topics/pub" - ) - - add_celix_bundle(pubsub_endpoint_tst - #Test bundle containing cpputests and uses celix_test_runner launcher instead of the celix launcher - SOURCES - gtest/tst_endpoint_activator.c - VERSION 1.0.0 - ) - target_link_libraries(pubsub_endpoint_tst PRIVATE Celix::pubsub_api) - celix_deprecated_utils_headers(pubsub_endpoint_tst) - celix_bundle_files(pubsub_endpoint_tst - meta_data/msg.descriptor - DESTINATION "META-INF/descriptors" - ) - celix_bundle_files(pubsub_endpoint_tst - meta_data/pong3.properties - DESTINATION "META-INF/topics/sub" - ) - - - add_celix_bundle(pubsub_loopback - #"Vanilla" bundle which is under test - SOURCES - gtest/loopback_activator.c - VERSION 1.0.0 - ) - celix_deprecated_utils_headers(pubsub_loopback) - target_include_directories(pubsub_loopback PRIVATE gtest) - target_link_libraries(pubsub_loopback PRIVATE Celix::pubsub_api) - celix_bundle_files(pubsub_loopback - meta_data/msg.descriptor - DESTINATION "META-INF/descriptors" - ) - celix_bundle_files(pubsub_loopback - meta_data/ping3.properties - DESTINATION "META-INF/topics/pub" - ) - celix_bundle_files(pubsub_loopback - meta_data/pong2.properties - DESTINATION "META-INF/topics/sub" - ) - - add_celix_bundle(pubsub_sut - #"Vanilla" bundle which is under test - SOURCES - gtest/sut_activator.c - VERSION 1.0.0 - ) - celix_deprecated_utils_headers(pubsub_sut) - target_include_directories(pubsub_sut PRIVATE gtest) - target_link_libraries(pubsub_sut PRIVATE Celix::pubsub_api) - celix_bundle_files(pubsub_sut - meta_data/msg.descriptor - DESTINATION "META-INF/descriptors" - ) - celix_bundle_files(pubsub_sut - meta_data/ping.properties - DESTINATION "META-INF/topics/pub" - ) - - add_celix_bundle(pubsub_tst - #Test bundle containing cpputests and uses celix_test_runner launcher instead of the celix launcher - SOURCES - gtest/tst_activator.c - VERSION 1.0.0 - ) - celix_deprecated_utils_headers(pubsub_tst) - target_link_libraries(pubsub_tst PRIVATE Celix::pubsub_api) - celix_bundle_files(pubsub_tst - meta_data/msg.descriptor - DESTINATION "META-INF/descriptors" - ) - celix_bundle_files(pubsub_tst - meta_data/ping.properties - DESTINATION "META-INF/topics/sub" - ) - - add_celix_bundle(pubsub_deadlock_sut - #"Vanilla" bundle which is used to trigger a publisher added call - SOURCES - gtest/sut_activator.c - VERSION 1.0.0 - ) - celix_deprecated_utils_headers(pubsub_deadlock_sut) - celix_bundle_files(pubsub_deadlock_sut - meta_data/msg.descriptor - DESTINATION "META-INF/descriptors" - ) - celix_bundle_files(pubsub_deadlock_sut - meta_data/deadlock.scope.properties - DESTINATION "META-INF/topics/pub" - ) - celix_bundle_files(pubsub_deadlock_sut - meta_data/deadlock.scope2.properties - DESTINATION "META-INF/topics/pub" - ) - target_link_libraries(pubsub_deadlock_sut PRIVATE Celix::pubsub_api) - - celix_get_bundle_file(pubsub_deadlock_sut DEADLOCK_SUT_BUNDLE_FILE) - - add_celix_bundle(pubsub_serializer - #serializer bundle - SOURCES - gtest/serializer_activator.cc - VERSION 1.0.0 - ) - celix_deprecated_utils_headers(pubsub_serializer) - target_include_directories(pubsub_serializer PRIVATE gtest) - target_link_libraries(pubsub_serializer PRIVATE Celix::pubsub_api Celix::pubsub_spi) - - if (BUILD_PUBSUB_PSA_TCP) - # TCP v2 tests - - add_celix_container(pubsub_tcp_v2_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 - pubsub_serializer - ) - target_link_libraries(pubsub_tcp_v2_wire_v1_tests PRIVATE Celix::pubsub_api GTest::gtest GTest::gtest_main) - target_include_directories(pubsub_tcp_v2_wire_v1_tests SYSTEM PRIVATE gtest) - add_test(NAME pubsub_tcp_v2_wire_v1_tests COMMAND pubsub_tcp_v2_wire_v1_tests WORKING_DIRECTORY $) - setup_target_for_coverage(pubsub_tcp_v2_wire_v1_tests SCAN_DIR ..) - - add_celix_container(pubsub_tcp_v2_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 - pubsub_serializer - ) - target_link_libraries(pubsub_tcp_v2_wire_v2_tests PRIVATE Celix::pubsub_api GTest::gtest GTest::gtest_main) - target_include_directories(pubsub_tcp_v2_wire_v2_tests SYSTEM PRIVATE gtest) - add_test(NAME pubsub_tcp_v2_wire_v2_tests COMMAND pubsub_tcp_v2_wire_v2_tests WORKING_DIRECTORY $) - setup_target_for_coverage(pubsub_tcp_v2_wire_v2_tests SCAN_DIR ..) - - add_celix_container(pubsub_tcp_v2_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 - pubsub_serializer - ) - target_link_libraries(pubsub_tcp_v2_wire_v2_with_no_scope_tests PRIVATE Celix::pubsub_api GTest::gtest GTest::gtest_main) - target_include_directories(pubsub_tcp_v2_wire_v2_with_no_scope_tests SYSTEM PRIVATE gtest) - add_test(NAME pubsub_tcp_v2_wire_v2_with_no_scope_tests COMMAND pubsub_tcp_v2_wire_v2_with_no_scope_tests WORKING_DIRECTORY $) - setup_target_for_coverage(pubsub_tcp_v2_wire_v2_with_no_scope_tests SCAN_DIR ..) - - add_celix_container(pubsub_tcp_v2_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 - pubsub_serializer - ) - target_link_libraries(pubsub_tcp_v2_endpoint_tests PRIVATE Celix::pubsub_api GTest::gtest GTest::gtest_main) - target_include_directories(pubsub_tcp_v2_endpoint_tests SYSTEM PRIVATE gtest) - - add_celix_container(pstm_deadlock_tcp_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 - 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 - pubsub_serializer - ) - target_compile_definitions(pstm_deadlock_tcp_v2_test PRIVATE -DDEADLOCK_SUT_BUNDLE_FILE=\"${DEADLOCK_SUT_BUNDLE_FILE}\") - target_link_libraries(pstm_deadlock_tcp_v2_test PRIVATE Celix::pubsub_api GTest::gtest GTest::gtest_main) - target_include_directories(pstm_deadlock_tcp_v2_test SYSTEM PRIVATE pstm_deadlock_tcp_v2_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_celix_bundle_dependencies(pstm_deadlock_tcp_v2_test pubsub_deadlock_sut) - - #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_v2_test COMMAND pstm_deadlock_tcp_v2_test WORKING_DIRECTORY $) - setup_target_for_coverage(pstm_deadlock_tcp_v2_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_v2_endpoint_tests COMMAND pubsub_tcp_v2_endpoint_tests WORKING_DIRECTORY $) - setup_target_for_coverage(pubsub_tcp_v2_endpoint_tests SCAN_DIR ..) - endif() - endif() - - if (BUILD_PUBSUB_PSA_WS) - find_package(civetweb REQUIRED) - add_celix_container(pubsub_websocket_v2_tests - USE_CONFIG - LAUNCHER_SRC ${CMAKE_CURRENT_LIST_DIR}/gtest/PubSubWebsocketTestMain.cc - DIR ${CMAKE_CURRENT_BINARY_DIR} - PROPERTIES - LOGHELPER_STDOUT_FALLBACK_INCLUDE_DEBUG=true - CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=trace - CELIX_HTTP_ADMIN_LISTENING_PORTS=58080 - BUNDLES - Celix::celix_pubsub_serializer_json - Celix::http_admin - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_websocket - pubsub_sut - pubsub_tst - pubsub_serializer - ) - target_link_libraries(pubsub_websocket_v2_tests PRIVATE Celix::pubsub_api GTest::gtest civetweb::civetweb) - target_include_directories(pubsub_websocket_v2_tests SYSTEM PRIVATE gtest) - add_test(NAME pubsub_websocket_v2_tests COMMAND pubsub_websocket_v2_tests WORKING_DIRECTORY $) - setup_target_for_coverage(pubsub_websocket_v2_tests SCAN_DIR ..) - - add_celix_container(pstm_deadlock_websocket_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 - DIR ${CMAKE_CURRENT_BINARY_DIR} - PROPERTIES - LOGHELPER_STDOUT_FALLBACK_INCLUDE_DEBUG=true - CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=trace - CELIX_HTTP_ADMIN_LISTENING_PORTS=58080 - BUNDLES - Celix::celix_pubsub_serializer_json - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_websocket - Celix::shell - Celix::shell_tui - pubsub_serializer - ) - target_compile_definitions(pstm_deadlock_websocket_v2_test PRIVATE -DDEADLOCK_SUT_BUNDLE_FILE=\"${DEADLOCK_SUT_BUNDLE_FILE}\") - target_link_libraries(pstm_deadlock_websocket_v2_test PRIVATE Celix::pubsub_api GTest::gtest GTest::gtest_main) - target_include_directories(pstm_deadlock_websocket_v2_test SYSTEM PRIVATE pstm_deadlock_websocket_v2_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_celix_bundle_dependencies(pstm_deadlock_websocket_v2_test pubsub_deadlock_sut) - - #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_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 $) - setup_target_for_coverage(pstm_deadlock_websocket_v2_test SCAN_DIR ..) - endif() - - if (BUILD_PUBSUB_PSA_ZMQ) - 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 - 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_topology_manager - Celix::celix_pubsub_admin_zmq - Celix::celix_pubsub_protocol_wire_v2 - pubsub_sut - pubsub_tst - pubsub_serializer - ) - - target_link_libraries(pubsub_zmq_v2_tests PRIVATE Celix::pubsub_api 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 $) - setup_target_for_coverage(pubsub_zmq_v2_tests SCAN_DIR ..) - - 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 - 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_topology_manager - Celix::celix_pubsub_admin_zmq - Celix::celix_pubsub_protocol_wire_v2 - Celix::shell - Celix::shell_tui - pubsub_sut - pubsub_tst - pubsub_serializer - ) - - target_link_libraries(pubsub_zmq_v2_zerocopy_tests PRIVATE Celix::pubsub_api GTest::gtest GTest::gtest_main) - target_include_directories(pubsub_zmq_v2_zerocopy_tests SYSTEM PRIVATE gtest) - - add_test(NAME pubsub_zmq_v2_zerocopy_tests COMMAND pubsub_zmq_v2_zerocopy_tests WORKING_DIRECTORY $) - setup_target_for_coverage(pubsub_zmq_v2_zerocopy_tests SCAN_DIR ..) - - 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 - 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_topology_manager - Celix::celix_pubsub_admin_zmq - Celix::celix_pubsub_protocol_wire_v2 - ) - - 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) - target_include_directories(pstm_deadlock_zmq_v2_test SYSTEM PRIVATE pstm_deadlock_zmq_v2_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_celix_bundle_dependencies(pstm_deadlock_zmq_v2_test pubsub_deadlock_sut) - - #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_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 $) - setup_target_for_coverage(pstm_deadlock_zmq_v2_test SCAN_DIR ..) - endif () - - if (BUILD_PUBSUB_PSA_ZMQ) - #Test suite to test if component with same topic and different scope combinations work - add_executable(test_pubsub_topic_and_scope_integration - gtest/PubSubTopicAndScopeIntegrationTestSuite.cc - ) - target_link_libraries(test_pubsub_topic_and_scope_integration PRIVATE Celix::framework Celix::pubsub_api GTest::gtest GTest::gtest_main) - add_test(NAME test_pubsub_topic_and_scope_integration COMMAND test_pubsub_topic_and_scope_integration) - setup_target_for_coverage(test_pubsub_topic_and_scope_integration SCAN_DIR ..) - - #configure topology manager and pubsub zmq, json serializer and wire protocol v2 bundles - celix_get_bundle_file(Celix::celix_pubsub_serializer_json PUBSUB_JSON_BUNDLE_FILE) - celix_get_bundle_file(Celix::celix_pubsub_topology_manager PUBSUB_TOPMAN_BUNDLE_FILE) - celix_get_bundle_file(Celix::celix_pubsub_admin_zmq PUBSUB_ZMQ_BUNDLE_FILE) - celix_get_bundle_file(Celix::celix_pubsub_protocol_wire_v2 PUBSUB_WIRE_BUNDLE_FILE) - add_celix_bundle_dependencies(test_pubsub_topic_and_scope_integration - celix_pubsub_serializer_json - celix_pubsub_topology_manager - celix_pubsub_admin_zmq - celix_pubsub_protocol_wire_v2 - ) - target_compile_definitions(test_pubsub_topic_and_scope_integration PRIVATE - PUBSUB_JSON_BUNDLE_FILE="${PUBSUB_JSON_BUNDLE_FILE}" - PUBSUB_TOPMAN_BUNDLE_FILE="${PUBSUB_TOPMAN_BUNDLE_FILE}" - PUBSUB_ZMQ_BUNDLE_FILE="${PUBSUB_ZMQ_BUNDLE_FILE}" - PUBSUB_WIRE_BUNDLE_FILE="${PUBSUB_WIRE_BUNDLE_FILE}" - ) - endif () - - #[[ - Add a integration test with use interceptors for a configurable PSA and wire protocol - - ARGV0 is test target name - ARGV1 is PSA target name - ARGV2 is wire protocol target name - ARGV3 is option boolean whether http admin bundle should be used - - ]] - function(add_celix_interceptors_test_for_psa_and_wire) - set(TEST_TARGET_NAME ${ARGV0}) - set(PSA ${ARGV1}) - set(WIRE ${ARGV2}) - set(USE_HTTP_ADMIN ${ARGV3}) - - #Test suite to test if pusbub interceptors - add_executable(${TEST_TARGET_NAME} - gtest/PubSubInterceptorTestSuite.cc - ) - target_link_libraries(${TEST_TARGET_NAME} PRIVATE Celix::framework Celix::pubsub_api GTest::gtest GTest::gtest_main Celix::pubsub_spi) - target_include_directories(${TEST_TARGET_NAME} PRIVATE gtest) - add_test(NAME ${TEST_TARGET_NAME} COMMAND ${TEST_TARGET_NAME}) - setup_target_for_coverage(${TEST_TARGET_NAME} SCAN_DIR ..) - - #configure topology manager and pubsub admin, json serializer and wire protocol bundles - celix_get_bundle_file(Celix::celix_pubsub_serializer_json PUBSUB_JSON_BUNDLE_FILE) - celix_get_bundle_file(Celix::celix_pubsub_topology_manager PUBSUB_TOPMAN_BUNDLE_FILE) - celix_get_bundle_file(${PSA} PUBSUB_PSA_BUNDLE_FILE) - celix_get_bundle_file(${WIRE} PUBSUB_WIRE_BUNDLE_FILE) - - celix_get_bundle_file(pubsub_sut PUBSUB_PUBLISHER_BUNDLE_FILE) - celix_get_bundle_file(pubsub_tst PUBSUB_SUBSCRIBER_BUNDLE_FILE) - add_celix_bundle_dependencies(${TEST_TARGET_NAME} Celix::celix_pubsub_serializer_json Celix::celix_pubsub_topology_manager ${PSA} ${WIRE} pubsub_sut pubsub_tst) - target_compile_definitions(${TEST_TARGET_NAME} PRIVATE - PUBSUB_JSON_BUNDLE_FILE="${PUBSUB_JSON_BUNDLE_FILE}" - PUBSUB_TOPMAN_BUNDLE_FILE="${PUBSUB_TOPMAN_BUNDLE_FILE}" - PUBSUB_PSA_BUNDLE_FILE="${PUBSUB_PSA_BUNDLE_FILE}" - PUBSUB_WIRE_BUNDLE_FILE="${PUBSUB_WIRE_BUNDLE_FILE}" - PUBSUB_PUBLISHER_BUNDLE_FILE="${PUBSUB_PUBLISHER_BUNDLE_FILE}" - PUBSUB_SUBSCRIBER_BUNDLE_FILE="${PUBSUB_SUBSCRIBER_BUNDLE_FILE}" - ) - - #if PSA websocket is enabled add http_admin bundle - if (USE_HTTP_ADMIN) - target_link_libraries(${TEST_TARGET_NAME} PRIVATE Celix::http_admin_api) - celix_get_bundle_file(Celix::http_admin HTTP_ADMIN_BUNDLE_FILE) - add_celix_bundle_dependencies(${TEST_TARGET_NAME} Celix::http_admin) - target_compile_definitions(${TEST_TARGET_NAME} PRIVATE HTTP_ADMIN_BUNDLE_FILE="${HTTP_ADMIN_BUNDLE_FILE}") - endif () - endfunction() - - - if (BUILD_PUBSUB_PSA_WS) - add_celix_interceptors_test_for_psa_and_wire(test_pubsub_interceptors_ws_and_wire_v1_integration Celix::celix_pubsub_admin_websocket Celix::celix_pubsub_protocol_wire_v1 true) - add_celix_interceptors_test_for_psa_and_wire(test_pubsub_interceptors_ws_and_wire_v2_integration Celix::celix_pubsub_admin_websocket Celix::celix_pubsub_protocol_wire_v2 true) - endif () - - if (BUILD_PUBSUB_PSA_TCP) - add_celix_interceptors_test_for_psa_and_wire(test_pubsub_interceptors_tcp_and_wire_v1_integration Celix::celix_pubsub_admin_tcp Celix::celix_pubsub_protocol_wire_v1) - add_celix_interceptors_test_for_psa_and_wire(test_pubsub_interceptors_tcp_and_wire_v2_integration Celix::celix_pubsub_admin_tcp Celix::celix_pubsub_protocol_wire_v2) - endif () - - if (BUILD_PUBSUB_PSA_ZMQ) - add_celix_interceptors_test_for_psa_and_wire(test_pubsub_interceptors_zmq_and_wire_v1_integration Celix::celix_pubsub_admin_zmq Celix::celix_pubsub_protocol_wire_v1) - add_celix_interceptors_test_for_psa_and_wire(test_pubsub_interceptors_zmq_and_wire_v2_integration Celix::celix_pubsub_admin_zmq Celix::celix_pubsub_protocol_wire_v2) - endif () -endif () diff --git a/bundles/pubsub/integration/gtest/PubSubEndpointIntegrationTestSuite.cc b/bundles/pubsub/integration/gtest/PubSubEndpointIntegrationTestSuite.cc deleted file mode 100644 index af05e27af..000000000 --- a/bundles/pubsub/integration/gtest/PubSubEndpointIntegrationTestSuite.cc +++ /dev/null @@ -1,70 +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 - -#include "celix_launcher.h" -#include "celix_bundle_context.h" -#include -#include "receive_count_service.h" - -class PubSubIntegrationTestSuite : public ::testing::Test { -public: - PubSubIntegrationTestSuite() { - celixLauncher_launch("config.properties", &fw); - ctx = celix_framework_getFrameworkContext(fw); - } - - ~PubSubIntegrationTestSuite() override { - celixLauncher_stop(fw); - celixLauncher_waitForShutdown(fw); - celixLauncher_destroy(fw); - } - - PubSubIntegrationTestSuite(const PubSubIntegrationTestSuite&) = delete; - PubSubIntegrationTestSuite(PubSubIntegrationTestSuite&&) = delete; - PubSubIntegrationTestSuite& operator=(const PubSubIntegrationTestSuite&) = delete; - PubSubIntegrationTestSuite& operator=(PubSubIntegrationTestSuite&&) = delete; - - celix_framework_t* fw = nullptr; - celix_bundle_context_t* ctx = nullptr; -}; - -TEST_F(PubSubIntegrationTestSuite, recvTest) { - constexpr int TRIES = 50; - constexpr int TIMEOUT = 250000; - constexpr int MSG_COUNT = 100; - - int count = 0; - - for (int i = 0; i < TRIES; ++i) { - count = 0; - celix_bundleContext_useService(ctx, CELIX_RECEIVE_COUNT_SERVICE_NAME, &count, [](void *handle, void *svc) { - auto* count_ptr = static_cast(handle); - auto* count = static_cast(svc); - *count_ptr = count->receiveCount(count->handle); - }); - printf("Current msg count is %i, waiting for at least %i\n", count, MSG_COUNT); - if (count >= MSG_COUNT) { - break; - } - usleep(TIMEOUT); - } - EXPECT_GE(count, MSG_COUNT); -} diff --git a/bundles/pubsub/integration/gtest/PubSubIntegrationTestSuite.cc b/bundles/pubsub/integration/gtest/PubSubIntegrationTestSuite.cc deleted file mode 100644 index 8f420dbf8..000000000 --- a/bundles/pubsub/integration/gtest/PubSubIntegrationTestSuite.cc +++ /dev/null @@ -1,119 +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 - -#include "celix_launcher.h" -#include "celix_bundle_context.h" -#include -#include "receive_count_service.h" - -class PubSubIntegrationTestSuite : public ::testing::Test { -public: - PubSubIntegrationTestSuite() { - celixLauncher_launch("config.properties", &fw); - ctx = celix_framework_getFrameworkContext(fw); - } - - ~PubSubIntegrationTestSuite() override { - celixLauncher_stop(fw); - celixLauncher_waitForShutdown(fw); - celixLauncher_destroy(fw); - } - - PubSubIntegrationTestSuite(const PubSubIntegrationTestSuite&) = delete; - PubSubIntegrationTestSuite(PubSubIntegrationTestSuite&&) = delete; - PubSubIntegrationTestSuite& operator=(const PubSubIntegrationTestSuite&) = delete; - PubSubIntegrationTestSuite& operator=(PubSubIntegrationTestSuite&&) = delete; - - celix_framework_t* fw = nullptr; - celix_bundle_context_t* ctx = nullptr; -}; - -class PubSubIntegrationWithEnvironmentTestSuite : public ::testing::Test { -public: - PubSubIntegrationWithEnvironmentTestSuite() { - setenv("PSA_TCP_STATIC_BIND_URL_FOR_ping", "tcp://localhost:9001", 1); - setenv("PSA_TCP_STATIC_CONNECT_URL_FOR_ping", "tcp://localhost:9001", 1); - setenv("PSA_UDPMC_STATIC_BIND_PORT_FOR_ping", "9001", 1); - setenv("PSA_UDPMC_STATIC_CONNECT_URLS_FOR_ping", "224.100.0.1:9001", 1); - setenv("PUBSUB_WEBSOCKET_STATIC_CONNECT_SOCKET_ADDRESSES_FOR_ping", "127.0.0.1:9001", 1); - setenv("CELIX_HTTP_ADMIN_LISTENING_PORTS", "9001", 1); - setenv("PSA_ZMQ_STATIC_BIND_URL_FOR_ping", "ipc:///tmp/pubsub-envtest", 1); - setenv("PSA_ZMQ_STATIC_CONNECT_URL_FOR_ping", "ipc:///tmp/pubsub-envtest", 1); - - celixLauncher_launch("config.properties", &fw); - ctx = celix_framework_getFrameworkContext(fw); - } - - ~PubSubIntegrationWithEnvironmentTestSuite() override { - celixLauncher_stop(fw); - celixLauncher_waitForShutdown(fw); - celixLauncher_destroy(fw); - - unsetenv("PSA_TCP_STATIC_BIND_URL_FOR_ping"); - unsetenv("PSA_TCP_STATIC_CONNECT_URL_FOR_ping"); - unsetenv("PSA_UDPMC_STATIC_BIND_PORT_FOR_ping"); - unsetenv("PSA_UDPMC_STATIC_CONNECT_URLS_FOR_ping"); - unsetenv("PUBSUB_WEBSOCKET_STATIC_CONNECT_SOCKET_ADDRESSES_FOR_ping"); - unsetenv("CELIX_HTTP_ADMIN_LISTENING_PORTS"); - unsetenv("PSA_ZMQ_STATIC_BIND_URL_FOR_ping"); - unsetenv("PSA_ZMQ_STATIC_CONNECT_URL_FOR_ping"); - } - - PubSubIntegrationWithEnvironmentTestSuite(const PubSubIntegrationWithEnvironmentTestSuite&) = delete; - PubSubIntegrationWithEnvironmentTestSuite(PubSubIntegrationWithEnvironmentTestSuite&&) = delete; - PubSubIntegrationWithEnvironmentTestSuite& operator=(const PubSubIntegrationWithEnvironmentTestSuite&) = delete; - PubSubIntegrationWithEnvironmentTestSuite& operator=(PubSubIntegrationWithEnvironmentTestSuite&&) = delete; - - celix_framework_t* fw = nullptr; - celix_bundle_context_t* ctx = nullptr; -}; - -void receiveTest(celix_bundle_context_t *ctx) { - constexpr int TRIES = 50; - constexpr int TIMEOUT = 250000; - constexpr int MSG_COUNT = 100; - - int count = 0; - - for (int i = 0; i < TRIES; ++i) { - count = 0; - celix_bundleContext_useService(ctx, CELIX_RECEIVE_COUNT_SERVICE_NAME, &count, [](void *handle, void *svc) { - auto *count_ptr = static_cast(handle); - auto *count = static_cast(svc); - *count_ptr = count->receiveCount(count->handle); - }); - printf("Current msg count is %i, waiting for at least %i\n", count, MSG_COUNT); - if (count >= MSG_COUNT) { - break; - } - usleep(TIMEOUT); - } - EXPECT_GE(count, MSG_COUNT); -} - -TEST_F(PubSubIntegrationTestSuite, recvTest) { - receiveTest(ctx); -} - - -TEST_F(PubSubIntegrationWithEnvironmentTestSuite, recvTest) { - receiveTest(ctx); -} diff --git a/bundles/pubsub/integration/gtest/PubSubInterceptorTestSuite.cc b/bundles/pubsub/integration/gtest/PubSubInterceptorTestSuite.cc deleted file mode 100644 index 0c4c7c0b3..000000000 --- a/bundles/pubsub/integration/gtest/PubSubInterceptorTestSuite.cc +++ /dev/null @@ -1,235 +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 - -#include -#include -#include -#include - -#include "pubsub_serializer_handler.h" -#include "celix/FrameworkFactory.h" -#include "msg.h" -#include "pubsub_interceptor.h" - -struct TestData { - TestData(const std::shared_ptr& ctx) { - serHandler = std::shared_ptr{pubsub_serializerHandler_create(ctx->getCBundleContext(), "json", true), [](pubsub_serializer_handler_t* h) { - pubsub_serializerHandler_destroy(h); - }}; - } - - std::shared_ptr serHandler{}; - - std::mutex mutex{}; //protects below - int preSendCount{0}; - int postSendCount{0}; - int preReceiveCount{0}; - int postReceiveCount{0}; - std::condition_variable cond{}; -}; - -static void serializeAndPrint(TestData* testData, uint32_t msgId, const void *msg) { - struct iovec* vec = nullptr; - size_t vecLen = 0; - pubsub_serializerHandler_serialize(testData->serHandler.get(), msgId, msg, &vec, &vecLen); - if (vecLen > 0) { - for (size_t i = 0; i < vecLen; ++i) { - fwrite(vec[i].iov_base, sizeof(char), vec[i].iov_len, stdout); - } - } - fputc('\n', stdout); - pubsub_serializerHandler_freeSerializedMsg(testData->serHandler.get(), msgId, vec, vecLen); -} - -class PubSubInterceptorTestSuite : public ::testing::Test { -public: - PubSubInterceptorTestSuite() { - fw = celix::createFramework({ - {"CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL", "info"}, - {"CELIX_HTTP_ADMIN_LISTENING_PORTS", "58080"}, - {"CELIX_PUBSUB_TEST_ADD_METADATA", "true"} - }); - ctx = fw->getFrameworkBundleContext(); - testData = std::make_shared(ctx); - - EXPECT_GE(ctx->installBundle(PUBSUB_JSON_BUNDLE_FILE), 0); - EXPECT_GE(ctx->installBundle(PUBSUB_TOPMAN_BUNDLE_FILE), 0); - EXPECT_GE(ctx->installBundle(PUBSUB_PSA_BUNDLE_FILE), 0); - EXPECT_GE(ctx->installBundle(PUBSUB_WIRE_BUNDLE_FILE), 0); -#ifdef HTTP_ADMIN_BUNDLE_FILE - EXPECT_GE(ctx->installBundle(HTTP_ADMIN_BUNDLE_FILE), 0); -#endif - } - - std::shared_ptr createInterceptor(bool cancelSend, bool cancelReceive) { - auto interceptor = std::make_shared(pubsub_interceptor{}); - interceptor->handle = (void*)testData.get(); - interceptor->preSend = [](void* handle, const pubsub_interceptor_properties_t *, const char *, const uint32_t, - const void *, celix_properties_t* metadata) { - auto* td = (TestData*)handle; - celix_properties_set(metadata, "test", "preSend"); - - std::lock_guard lck{td->mutex}; - td->preSendCount += 1; - td->cond.notify_all(); - return true; - }; - if (cancelSend) { - interceptor->preSend = [](void* handle, const pubsub_interceptor_properties_t *, const char *, const uint32_t, - const void *, celix_properties_t*) { - auto* td = (TestData*)handle; - std::lock_guard lck{td->mutex}; - td->preSendCount += 1; - td->cond.notify_all(); - return false; - }; - } - interceptor->postSend = [](void *handle, const pubsub_interceptor_properties_t* intProps, const char *msgType, uint32_t msgId, const void *rawMsg, - celix_properties_t* metadata) { - auto* td = (TestData*)handle; - serializeAndPrint(td, msgId, rawMsg); - EXPECT_STREQ(msgType, "msg"); - const auto *msg = static_cast(rawMsg); - EXPECT_GE(msg->seqNr, 0); - EXPECT_STREQ(celix_properties_get(metadata, "test", nullptr), "preSend"); - CELIX_PROPERTIES_ITERATE(metadata, iter) { - printf("got property %s=%s\n", iter.key, iter.entry.value); - } - fprintf(stdout, "Got message in postSend interceptor %s/%s for type %s and ser %s with seq nr %i\n", intProps->scope, intProps->topic, intProps->psaType, intProps->serializationType, msg->seqNr); - - std::lock_guard lck{td->mutex}; - td->postSendCount += 1; - td->cond.notify_all(); - }; - interceptor->preReceive = [](void* handle, const pubsub_interceptor_properties_t *, const char *, uint32_t, - const void *, celix_properties_t* metadata) { - auto* td = (TestData*)handle; - celix_properties_set(metadata, "test", "preReceive"); - - std::lock_guard lck{td->mutex}; - td->preReceiveCount += 1; - td->cond.notify_all(); - return true; - }; - if (cancelReceive) { - interceptor->preReceive = [](void* handle, const pubsub_interceptor_properties_t *, const char *, uint32_t, - const void *, celix_properties_t*) { - auto* td = (TestData*)handle; - std::lock_guard lck{td->mutex}; - td->preReceiveCount += 1; - td->cond.notify_all(); - return false; - }; - } - interceptor->postReceive = [](void *handle, const pubsub_interceptor_properties_t* intProps, const char *msgType, uint32_t msgId, const void *rawMsg, - celix_properties_t* metadata) { - auto* td = (TestData*)handle; - serializeAndPrint(td, msgId, rawMsg); - EXPECT_STREQ(msgType, "msg"); - const auto *msg = static_cast(rawMsg); - EXPECT_GE(msg->seqNr, 0); - EXPECT_STREQ(celix_properties_get(metadata, "test", nullptr), "preReceive"); - fprintf(stdout, "Got message in postReceive interceptor %s/%s for type %s and ser %s with seq nr %i\n", intProps->scope, intProps->topic, intProps->psaType, intProps-> serializationType, msg->seqNr); - - std::lock_guard lck{td->mutex}; - td->postReceiveCount += 1; - td->cond.notify_all(); - }; - //note registering identical services to validate multiple interceptors - return ctx->registerService(std::move(interceptor), PUBSUB_INTERCEPTOR_SERVICE_NAME) - .setUnregisterAsync(false) //note to ensure test data is still valid when service is registered - .build(); - } - - std::shared_ptr fw{}; - std::shared_ptr ctx{}; - std::shared_ptr testData{}; -}; - -TEST_F(PubSubInterceptorTestSuite, InterceptorWithSinglePublishersAndMultipleReceivers) { - //Given a publisher (PUBSUB_PUBLISHER_BUNDLE_FILE) and 2 receivers (PUBSUB_SUBSCRIBER_BUNDLE_FILE) - //And several registered interceptors - //Then the interceptor receives a correct msg type. - - auto reg1 = createInterceptor(false, false); - auto reg2 = createInterceptor(false, false); - auto reg3 = createInterceptor(false, false); - ctx->waitForEvents(); - - EXPECT_GE(ctx->installBundle(PUBSUB_PUBLISHER_BUNDLE_FILE), 0); - EXPECT_GE(ctx->installBundle(PUBSUB_SUBSCRIBER_BUNDLE_FILE), 0); - - std::unique_lock lck{testData->mutex}; - auto isTestDone = testData->cond.wait_for(lck, std::chrono::seconds{5}, [this]{ - return testData->preSendCount > 10 && - testData->postSendCount > 10 && - testData->preReceiveCount > 10 && - testData->postReceiveCount > 10; - }); - - EXPECT_TRUE(isTestDone); -} - -TEST_F(PubSubInterceptorTestSuite, InterceptorWithPreSendCancelWillPreventSends) { - //Given a publisher (PUBSUB_PUBLISHER_BUNDLE_FILE) and 2 receivers (PUBSUB_SUBSCRIBER_BUNDLE_FILE) - //And a interceptor which cancel a send - //Then only the preSend count will be increased, but the rest of the count will be 0 - - auto reg1 = createInterceptor(true, false); - ctx->waitForEvents(); - - EXPECT_GE(ctx->installBundle(PUBSUB_PUBLISHER_BUNDLE_FILE), 0); - EXPECT_GE(ctx->installBundle(PUBSUB_SUBSCRIBER_BUNDLE_FILE), 0); - - std::unique_lock lck{testData->mutex}; - auto isTestDone = testData->cond.wait_for(lck, std::chrono::seconds{5}, [this]{ - return testData->preSendCount > 10 ; - }); - - EXPECT_EQ(testData->postSendCount, 0); - EXPECT_EQ(testData->preReceiveCount, 0); - EXPECT_EQ(testData->postReceiveCount, 0); - - EXPECT_TRUE(isTestDone); -} - -TEST_F(PubSubInterceptorTestSuite, InterceptorWithPreRedeiveCancelWillPreventPostReceive) { - //Given a publisher (PUBSUB_PUBLISHER_BUNDLE_FILE) and 2 receivers (PUBSUB_SUBSCRIBER_BUNDLE_FILE) - //And a interceptor which cancel a receive - //Then the preSend, postSend and preReceive count will be increased, but the postReceive count will be 0 - - auto reg1 = createInterceptor(false, true); - ctx->waitForEvents(); - - EXPECT_GE(ctx->installBundle(PUBSUB_PUBLISHER_BUNDLE_FILE), 0); - EXPECT_GE(ctx->installBundle(PUBSUB_SUBSCRIBER_BUNDLE_FILE), 0); - - std::unique_lock lck{testData->mutex}; - auto isTestDone = testData->cond.wait_for(lck, std::chrono::seconds{5}, [this]{ - return testData->preSendCount > 10 && - testData->postSendCount > 10 && - testData->preReceiveCount > 10; - }); - - EXPECT_EQ(testData->postReceiveCount, 0); - - EXPECT_TRUE(isTestDone); -} \ No newline at end of file diff --git a/bundles/pubsub/integration/gtest/PubSubTopicAndScopeIntegrationTestSuite.cc b/bundles/pubsub/integration/gtest/PubSubTopicAndScopeIntegrationTestSuite.cc deleted file mode 100644 index f900b4a45..000000000 --- a/bundles/pubsub/integration/gtest/PubSubTopicAndScopeIntegrationTestSuite.cc +++ /dev/null @@ -1,69 +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 -#include - -#include "celix/FrameworkFactory.h" -#include "pubsub/publisher.h" - -class PubSubTopicAndScopeIntegrationTestSuite : public ::testing::Test { -public: - - PubSubTopicAndScopeIntegrationTestSuite() { - celix::Properties config {{"CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL", "trace"}}; - fw = celix::createFramework(config); - ctx = fw->getFrameworkBundleContext(); - - EXPECT_GE(ctx->installBundle(PUBSUB_JSON_BUNDLE_FILE), 0); - EXPECT_GE(ctx->installBundle(PUBSUB_TOPMAN_BUNDLE_FILE), 0); - EXPECT_GE(ctx->installBundle(PUBSUB_ZMQ_BUNDLE_FILE), 0); - EXPECT_GE(ctx->installBundle(PUBSUB_WIRE_BUNDLE_FILE), 0); - } - - - std::shared_ptr fw{}; - std::shared_ptr ctx{}; -}; - -class TestComponent{}; - -TEST_F(PubSubTopicAndScopeIntegrationTestSuite, ComponentsWithSameTopicAndDifferentScope) { - //When I create publisher with the same topic, but different scope - //I expect the pubsub topology manager and a PSA can handle this and the - //publisher components will become active. - - auto& cmp1 = ctx->getDependencyManager()->createComponent(); - cmp1.createServiceDependency(PUBSUB_PUBLISHER_SERVICE_NAME) - .setFilter("(topic=foo)"); - cmp1.build(); - EXPECT_EQ(cmp1.getState(), celix::dm::ComponentState::TRACKING_OPTIONAL); - - auto& cmp2 = ctx->getDependencyManager()->createComponent(); - cmp2.createServiceDependency(PUBSUB_PUBLISHER_SERVICE_NAME) - .setFilter("(&(topic=foo)(scope=bar))"); - cmp2.build(); - EXPECT_EQ(cmp2.getState(), celix::dm::ComponentState::TRACKING_OPTIONAL); - - auto& cmp3 = ctx->getDependencyManager()->createComponent(); - cmp3.createServiceDependency(PUBSUB_PUBLISHER_SERVICE_NAME) - .setFilter("(&(topic=foo)(scope=default))"); - cmp3.build(); - EXPECT_EQ(cmp3.getState(), celix::dm::ComponentState::TRACKING_OPTIONAL); -} \ No newline at end of file diff --git a/bundles/pubsub/integration/gtest/PubSubWebsocketTestMain.cc b/bundles/pubsub/integration/gtest/PubSubWebsocketTestMain.cc deleted file mode 100644 index ee3774e00..000000000 --- a/bundles/pubsub/integration/gtest/PubSubWebsocketTestMain.cc +++ /dev/null @@ -1,28 +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 -#include "PubSubIntegrationTestSuite.cc" - -int main(int argc, char **argv) { - mg_init_library(MG_FEATURES_ALL); - ::testing::InitGoogleTest(&argc, argv); - int rc = RUN_ALL_TESTS(); - mg_exit_library(); - return rc; -} diff --git a/bundles/pubsub/integration/gtest/loopback_activator.c b/bundles/pubsub/integration/gtest/loopback_activator.c deleted file mode 100644 index c718c4a71..000000000 --- a/bundles/pubsub/integration/gtest/loopback_activator.c +++ /dev/null @@ -1,99 +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 -#include -#include "celix_constants.h" -#include - -#include "celix_bundle_activator.h" -#include "pubsub/api.h" -#include "msg.h" - -static int tst_receive(void *handle, const char *msgType, unsigned int msgTypeId, void *msg, const celix_properties_t *metadata, bool *release); -static void sut_pubSet(void *handle, void *service); - -struct activator { - long pubTrkId; - long subSvcId; - pubsub_publisher_t* pubSvc; - pubsub_subscriber_t subSvc; - pthread_mutex_t mutex; - unsigned int count; - unsigned int msgId; -}; - -celix_status_t bnd_start(struct activator *act, celix_bundle_context_t *ctx) { - - char filter[512]; - snprintf(filter, 512, "(%s=%s)", PUBSUB_PUBLISHER_TOPIC, "ping3"); - celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; - opts.set = sut_pubSet; - opts.callbackHandle = act; - opts.filter.serviceName = PUBSUB_PUBLISHER_SERVICE_NAME; - opts.filter.filter = filter; - act->pubTrkId = celix_bundleContext_trackServicesWithOptions(ctx, &opts); - act->count = 0; - act->msgId = 0; - - pthread_mutex_init(&act->mutex, NULL); - - celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, PUBSUB_SUBSCRIBER_TOPIC, "pong2"); - act->subSvc.handle = act; - act->subSvc.receive = tst_receive; - act->subSvcId = celix_bundleContext_registerService(ctx, &act->subSvc, PUBSUB_SUBSCRIBER_SERVICE_NAME, props); - - - return CELIX_SUCCESS; -} - -celix_status_t bnd_stop(struct activator *act, celix_bundle_context_t *ctx) { - celix_bundleContext_stopTracker(ctx, act->pubTrkId); - celix_bundleContext_unregisterService(ctx, act->subSvcId); - pthread_mutex_destroy(&act->mutex); - return CELIX_SUCCESS; -} - -CELIX_GEN_BUNDLE_ACTIVATOR(struct activator, bnd_start, bnd_stop); - -static void sut_pubSet(void *handle, void *service) { - struct activator* act = handle; - pthread_mutex_lock(&act->mutex); - act->pubSvc = service; - pthread_mutex_unlock(&act->mutex); -} - - -static int tst_receive(void *handle, const char *msgType, unsigned int msgTypeId, void * voidMsg, const celix_properties_t *metadata, bool *release) { - struct activator *act =handle; - msg_t *msg = voidMsg; - msg_t send_msg = *msg; - pthread_mutex_lock(&act->mutex); - - if (act->pubSvc != NULL) { - if (act->count == 0) { - act->pubSvc->localMsgTypeIdForMsgType(act->pubSvc->handle, MSG_NAME, &act->msgId); - } - act->pubSvc->send(act->pubSvc->handle, act->msgId, &send_msg, (celix_properties_t *) metadata); - act->count += 1; - } - pthread_mutex_unlock(&act->mutex); - return CELIX_SUCCESS; -} diff --git a/bundles/pubsub/integration/gtest/msg.h b/bundles/pubsub/integration/gtest/msg.h deleted file mode 100644 index 81cf4b817..000000000 --- a/bundles/pubsub/integration/gtest/msg.h +++ /dev/null @@ -1,31 +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 MSG_H -#define MSG_H - -#include - -#define MSG_NAME "msg" - -typedef struct msg { - uint32_t seqNr; -} msg_t; - -#endif //MSG_H diff --git a/bundles/pubsub/integration/gtest/receive_count_service.h b/bundles/pubsub/integration/gtest/receive_count_service.h deleted file mode 100644 index d1eca004f..000000000 --- a/bundles/pubsub/integration/gtest/receive_count_service.h +++ /dev/null @@ -1,30 +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_RECEIVE_COUNT_SERVICE_H -#define CELIX_RECEIVE_COUNT_SERVICE_H - -#define CELIX_RECEIVE_COUNT_SERVICE_NAME "celix_receive_count_service" - -typedef struct celix_receive_count_service { - void *handle; - size_t (*receiveCount)(void *handle); -} celix_receive_count_service_t; - -#endif //CELIX_RECEIVE_COUNT_SERVICE_H diff --git a/bundles/pubsub/integration/gtest/serializer_activator.cc b/bundles/pubsub/integration/gtest/serializer_activator.cc deleted file mode 100644 index cecf90fb1..000000000 --- a/bundles/pubsub/integration/gtest/serializer_activator.cc +++ /dev/null @@ -1,87 +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 "celix_constants.h" -#include -#include -#include - -#include "celix_bundle_activator.h" -#include "msg.h" - -struct activator { - long serId; - pubsub_message_serialization_service_t svc; -}; - -celix_status_t bnd_start(struct activator *act, celix_bundle_context_t *ctx) { - -#pragma GCC diagnostic ignored "-Wunused-parameter" - act->svc.serialize = [](void* handle, const void* input, struct iovec** output, size_t* outputIovLen) { - if (*output == nullptr) { - *output = static_cast(calloc(1, sizeof(struct iovec))); - *outputIovLen = 1; - auto *val = new uint32_t; - *val = ((msg_t *) input)->seqNr; - (*output)->iov_base = val; - (*output)->iov_len = sizeof(uint32_t); - } - - return CELIX_SUCCESS; - }; - - act->svc.deserialize = [](void* handle, const struct iovec* input, size_t inputIovLen, void** out) { - auto *msg = new msg_t; - msg->seqNr = *(uint32_t*)(uintptr_t)input->iov_base; - *out = msg; - return CELIX_SUCCESS; - }; - - act->svc.freeSerializedMsg = [](void* handle, struct iovec* input, size_t inputIovLen) { - delete (uint32_t*)input->iov_base; - free(input); - }; - - act->svc.freeDeserializedMsg = [](void* handle, void* msg) { - delete (msg_t*)msg; - }; - - auto* p = celix_properties_create(); - celix_properties_set(p, PUBSUB_SERIALIZER_TYPE_KEY, "json"); - celix_properties_set(p, PUBSUB_MESSAGE_SERIALIZATION_SERVICE_SERIALIZATION_TYPE_PROPERTY, "msg_serializer"); - celix_properties_set(p, PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_ID_PROPERTY, "20"); - celix_properties_set(p, PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_FQN_PROPERTY, MSG_NAME); - celix_properties_set(p, PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_VERSION_PROPERTY, "1.0.0"); - celix_properties_setLong(p, CELIX_FRAMEWORK_SERVICE_RANKING, 20); - celix_service_registration_options_t opts; - opts.svc = &act->svc; - opts.properties = p; - opts.serviceName = PUBSUB_MESSAGE_SERIALIZATION_SERVICE_NAME; - opts.serviceVersion = PUBSUB_MESSAGE_SERIALIZATION_SERVICE_VERSION; - act->serId = celix_bundleContext_registerServiceWithOptions(ctx, &opts); - - return CELIX_SUCCESS; -} - -celix_status_t bnd_stop(struct activator *act, celix_bundle_context_t *ctx) { - celix_bundleContext_unregisterService(ctx, act->serId); - return CELIX_SUCCESS; -} - -CELIX_GEN_BUNDLE_ACTIVATOR(activator, bnd_start, bnd_stop) diff --git a/bundles/pubsub/integration/gtest/sut_activator.c b/bundles/pubsub/integration/gtest/sut_activator.c deleted file mode 100644 index 27ad18a65..000000000 --- a/bundles/pubsub/integration/gtest/sut_activator.c +++ /dev/null @@ -1,118 +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 -#include -#include "celix_constants.h" -#include - -#include "celix_bundle_activator.h" -#include "pubsub/api.h" -#include "msg.h" - -static void sut_pubSet(void *handle, void *service); -static void* sut_sendThread(void *data); - -struct activator { - bool addMetadata; - - long pubTrkId; - - pthread_t sendThread; - - pthread_mutex_t mutex; - bool running; - pubsub_publisher_t* pubSvc; -}; - -celix_status_t bnd_start(struct activator *act, celix_bundle_context_t *ctx) { - - act->addMetadata = celix_bundleContext_getPropertyAsBool(ctx, "CELIX_PUBSUB_TEST_ADD_METADATA", false); - - char filter[512]; - bool useNegativeScopeFilter = celix_bundleContext_getPropertyAsBool(ctx, "CELIX_PUBSUB_TEST_USE_NEGATIVE_SCOPE_FILTER", true); - if (useNegativeScopeFilter) { - snprintf(filter, 512, "(%s=%s)(!(scope=*))", PUBSUB_PUBLISHER_TOPIC, "ping"); - } else { - snprintf(filter, 512, "(%s=%s)", PUBSUB_PUBLISHER_TOPIC, "ping"); - } - celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; - opts.set = sut_pubSet; - opts.callbackHandle = act; - opts.filter.serviceName = PUBSUB_PUBLISHER_SERVICE_NAME; - opts.filter.filter = filter; - act->pubTrkId = celix_bundleContext_trackServicesWithOptions(ctx, &opts); - - __atomic_store_n(&act->running, true, __ATOMIC_RELEASE); - pthread_create(&act->sendThread, NULL, sut_sendThread, act); - - return CELIX_SUCCESS; -} - -celix_status_t bnd_stop(struct activator *act, celix_bundle_context_t *ctx) { - __atomic_store_n(&act->running, false, __ATOMIC_RELEASE); - pthread_join(act->sendThread, NULL); - celix_bundleContext_stopTracker(ctx, act->pubTrkId); - pthread_mutex_destroy(&act->mutex); - return CELIX_SUCCESS; -} - -CELIX_GEN_BUNDLE_ACTIVATOR(struct activator, bnd_start, bnd_stop) - -static void sut_pubSet(void *handle, void *service) { - struct activator* act = handle; - pthread_mutex_lock(&act->mutex); - act->pubSvc = service; - pthread_mutex_unlock(&act->mutex); -} - -static void* sut_sendThread(void *data) { - struct activator *act = data; - - unsigned int msgId = 0; - msg_t msg; - msg.seqNr = 1; - - while (__atomic_load_n(&act->running, __ATOMIC_ACQUIRE)) { - pthread_mutex_lock(&act->mutex); - if (act->pubSvc != NULL) { - if (msgId == 0) { - act->pubSvc->localMsgTypeIdForMsgType(act->pubSvc->handle, MSG_NAME, &msgId); - } - celix_properties_t* metadata = NULL; - if (act->addMetadata) { - metadata = celix_properties_create(); - celix_properties_setLong(metadata, "seqNr", (long)msgId); - } - act->pubSvc->send(act->pubSvc->handle, msgId, &msg, metadata); - if (msg.seqNr % 1000 == 0) { - printf("Send %i messages\n", msg.seqNr); - } - - msg.seqNr += 1; - - } - pthread_mutex_unlock(&act->mutex); - - usleep(10000); - } - printf("Send %i messages\n", msg.seqNr); - - return NULL; -} diff --git a/bundles/pubsub/integration/gtest/sut_endpoint_activator.c b/bundles/pubsub/integration/gtest/sut_endpoint_activator.c deleted file mode 100644 index 3b97ab73d..000000000 --- a/bundles/pubsub/integration/gtest/sut_endpoint_activator.c +++ /dev/null @@ -1,120 +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 -#include -#include "celix_constants.h" -#include - -#include "celix_bundle_activator.h" -#include "pubsub/api.h" -#include "msg.h" - -static void sut_pubSet(void *handle, void *service); -static void* sut_sendThread(void *data); - -struct activator { - long pubTrkId; - - pthread_t sendThread; - - pthread_mutex_t mutex; - bool running; - pubsub_publisher_t* pubSvc; -}; - -celix_status_t bnd_start(struct activator *act, celix_bundle_context_t *ctx) { - - char filter[512]; - bool useNegativeScopeFilter = celix_bundleContext_getPropertyAsBool(ctx, "CELIX_PUBSUB_TEST_USE_NEGATIVE_SCOPE_FILTER", true); - if (useNegativeScopeFilter) { - snprintf(filter, 512, "(%s=%s)(!(scope=*))", PUBSUB_PUBLISHER_TOPIC, "ping"); - } else { - snprintf(filter, 512, "(%s=%s)", PUBSUB_PUBLISHER_TOPIC, "ping"); - } - celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; - opts.set = sut_pubSet; - opts.callbackHandle = act; - opts.filter.serviceName = PUBSUB_PUBLISHER_SERVICE_NAME; - opts.filter.filter = filter; - act->pubTrkId = celix_bundleContext_trackServicesWithOptions(ctx, &opts); - - act->running = true; - pthread_create(&act->sendThread, NULL, sut_sendThread, act); - - return CELIX_SUCCESS; -} - -celix_status_t bnd_stop(struct activator *act, celix_bundle_context_t *ctx) { - pthread_mutex_lock(&act->mutex); - act->running = false; - pthread_mutex_unlock(&act->mutex); - pthread_join(act->sendThread, NULL); - pthread_mutex_destroy(&act->mutex); - - celix_bundleContext_stopTracker(ctx, act->pubTrkId); - return CELIX_SUCCESS; -} - -CELIX_GEN_BUNDLE_ACTIVATOR(struct activator, bnd_start, bnd_stop); - -static void sut_pubSet(void *handle, void *service) { - struct activator* act = handle; - pthread_mutex_lock(&act->mutex); - act->pubSvc = service; - pthread_mutex_unlock(&act->mutex); -} - -static void* sut_sendThread(void *data) { - struct activator *act = data; - - pthread_mutex_lock(&act->mutex); - bool running = act->running; - pthread_mutex_unlock(&act->mutex); - - unsigned int msgId = 0; - msg_t msg; - msg.seqNr = 1; - - while (running) { - pthread_mutex_lock(&act->mutex); - if (act->pubSvc != NULL) { - if (msgId == 0) { - act->pubSvc->localMsgTypeIdForMsgType(act->pubSvc->handle, MSG_NAME, &msgId); - } - act->pubSvc->send(act->pubSvc->handle, msgId, &msg, NULL); - if (msg.seqNr % 1000 == 0) { - printf("Send %i messages\n", msg.seqNr); - } - - msg.seqNr += 1; - - } - pthread_mutex_unlock(&act->mutex); - - usleep(10000); - - pthread_mutex_lock(&act->mutex); - running = act->running; - pthread_mutex_unlock(&act->mutex); - } - printf("Send %i messages\n", msg.seqNr); - - return NULL; -} diff --git a/bundles/pubsub/integration/gtest/tst_activator.c b/bundles/pubsub/integration/gtest/tst_activator.c deleted file mode 100644 index 811c8d4d0..000000000 --- a/bundles/pubsub/integration/gtest/tst_activator.c +++ /dev/null @@ -1,138 +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 -#include -#include -#include - -#include "celix_bundle_activator.h" -#include "celix_compiler.h" -#include "pubsub/api.h" - -#include "msg.h" -#include "receive_count_service.h" - -static int tst_receive(void *handle, const char *msgType, unsigned int msgTypeId, void *msg, const celix_properties_t *metadata, bool *release); -static int tst_receive2(void *handle, const char *msgType, unsigned int msgTypeId, void *msg, const celix_properties_t *metadata, bool *release); -static size_t tst_count(void *handle); - -struct activator { - pubsub_subscriber_t subSvc1; - long subSvcId1; - - pubsub_subscriber_t subSvc2; - long subSvcId2; - - celix_receive_count_service_t countSvc; - long countSvcId; - - pthread_mutex_t mutex; - unsigned int count1; - unsigned int count2; -}; - -celix_status_t bnd_start(struct activator *act, celix_bundle_context_t *ctx) { - pthread_mutex_init(&act->mutex, NULL); - - { - celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, PUBSUB_SUBSCRIBER_TOPIC, "ping"); - act->subSvc1.handle = act; - act->subSvc1.receive = tst_receive; - act->subSvcId1 = celix_bundleContext_registerService(ctx, &act->subSvc1, PUBSUB_SUBSCRIBER_SERVICE_NAME, props); - } - - { - celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, PUBSUB_SUBSCRIBER_TOPIC, "ping"); - act->subSvc2.handle = act; - act->subSvc2.receive = tst_receive2; - act->subSvcId2 = celix_bundleContext_registerService(ctx, &act->subSvc2, PUBSUB_SUBSCRIBER_SERVICE_NAME, props); - } - - { - act->countSvc.handle = act; - act->countSvc.receiveCount = tst_count; - act->countSvcId = celix_bundleContext_registerService(ctx, &act->countSvc, CELIX_RECEIVE_COUNT_SERVICE_NAME, NULL); - } - - return CELIX_SUCCESS; -} - -celix_status_t bnd_stop(struct activator *act, celix_bundle_context_t *ctx) { - celix_bundleContext_unregisterService(ctx, act->subSvcId1); - celix_bundleContext_unregisterService(ctx, act->subSvcId2); - celix_bundleContext_unregisterService(ctx, act->countSvcId); - pthread_mutex_destroy(&act->mutex); - return CELIX_SUCCESS; -} - -CELIX_GEN_BUNDLE_ACTIVATOR(struct activator, bnd_start, bnd_stop) ; - - -static int tst_receive(void *handle, const char * msgType CELIX_UNUSED, unsigned int msgTypeId CELIX_UNUSED, void * voidMsg, const celix_properties_t *metadata CELIX_UNUSED, bool *release) { - struct activator *act = handle; - - msg_t *msg = voidMsg; - static uint32_t prevSeqNr = 0; - long delta = msg->seqNr - prevSeqNr; - if (delta != 1 && msg->seqNr > 1 && prevSeqNr < msg->seqNr) { - fprintf(stderr, "Warning: missing messages. seq jumped from %i to %i\n", prevSeqNr, msg->seqNr); - } - prevSeqNr = msg->seqNr; - - pthread_mutex_lock(&act->mutex); - act->count1 += 1; - pthread_mutex_unlock(&act->mutex); - - *release = false; - free(voidMsg); - - return CELIX_SUCCESS; -} - -static int tst_receive2(void *handle, const char * msgType CELIX_UNUSED, unsigned int msgTypeId CELIX_UNUSED, void * voidMsg, const celix_properties_t *metadata CELIX_UNUSED, bool *release CELIX_UNUSED) { - struct activator *act = handle; - - msg_t *msg = voidMsg; - static int prevSeqNr = 0; - int delta = msg->seqNr - prevSeqNr; - if (delta != 1) { - fprintf(stderr, "Warning: missing messages. seq jumped from %i to %i\n", prevSeqNr, msg->seqNr); - } - prevSeqNr = msg->seqNr; - - pthread_mutex_lock(&act->mutex); - act->count2 += 1; - pthread_mutex_unlock(&act->mutex); - return CELIX_SUCCESS; -} - -static size_t tst_count(void *handle) { - struct activator *act = handle; - size_t count1; - size_t count2; - pthread_mutex_lock(&act->mutex); - count1 = act->count1; - count2 = act->count2; - pthread_mutex_unlock(&act->mutex); - printf("msg count1 is %lu and msg count 2 is %lu\n", (long unsigned int) count1, (long unsigned int) count2); - return count1 >= count2 ? count1 : count2; -} diff --git a/bundles/pubsub/integration/gtest/tst_endpoint_activator.c b/bundles/pubsub/integration/gtest/tst_endpoint_activator.c deleted file mode 100644 index b9198650e..000000000 --- a/bundles/pubsub/integration/gtest/tst_endpoint_activator.c +++ /dev/null @@ -1,103 +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 -#include -#include -#include - -#include "celix_bundle_activator.h" -#include "celix_compiler.h" -#include "pubsub/api.h" - -#include "msg.h" -#include "receive_count_service.h" - - -static int tst_receive(void *handle, const char *msgType, unsigned int msgTypeId, void *msg, const celix_properties_t *metadata, bool *release); -static size_t tst_count(void *handle); - -struct activator { - pubsub_subscriber_t subSvc; - long subSvcId; - - celix_receive_count_service_t countSvc; - long countSvcId; - - pthread_mutex_t mutex; - unsigned int count; -}; - -celix_status_t bnd_start(struct activator *act, celix_bundle_context_t *ctx) { - pthread_mutex_init(&act->mutex, NULL); - - { - celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, PUBSUB_SUBSCRIBER_TOPIC, "pong3"); - act->subSvc.handle = act; - act->subSvc.receive = tst_receive; - act->subSvcId = celix_bundleContext_registerService(ctx, &act->subSvc, PUBSUB_SUBSCRIBER_SERVICE_NAME, props); - } - - - { - act->countSvc.handle = act; - act->countSvc.receiveCount = tst_count; - act->countSvcId = celix_bundleContext_registerService(ctx, &act->countSvc, CELIX_RECEIVE_COUNT_SERVICE_NAME, NULL); - } - - - return CELIX_SUCCESS; -} - -celix_status_t bnd_stop(struct activator *act, celix_bundle_context_t *ctx) { - celix_bundleContext_unregisterService(ctx, act->subSvcId); - celix_bundleContext_unregisterService(ctx, act->countSvcId); - pthread_mutex_destroy(&act->mutex); - return CELIX_SUCCESS; -} - -CELIX_GEN_BUNDLE_ACTIVATOR(struct activator, bnd_start, bnd_stop) ; - - -static int tst_receive(void *handle, const char * msgType CELIX_UNUSED, unsigned int msgTypeId CELIX_UNUSED, void * voidMsg, const celix_properties_t *metadata CELIX_UNUSED, bool *release CELIX_UNUSED) { - struct activator *act = handle; - - msg_t *msg = voidMsg; - static uint32_t prevSeqNr = 0; - long delta = msg->seqNr - prevSeqNr; - if (delta != 1 && msg->seqNr > 1 && prevSeqNr < msg->seqNr) { - fprintf(stderr, "Warning: missing messages. seq jumped from %i to %i\n", prevSeqNr, msg->seqNr); - } - prevSeqNr = msg->seqNr; - - pthread_mutex_lock(&act->mutex); - act->count += 1; - pthread_mutex_unlock(&act->mutex); - return CELIX_SUCCESS; -} - -static size_t tst_count(void *handle) { - struct activator *act = handle; - size_t count; - pthread_mutex_lock(&act->mutex); - count = act->count; - pthread_mutex_unlock(&act->mutex); - return count; -} diff --git a/bundles/pubsub/integration/meta_data/deadlock.scope.properties b/bundles/pubsub/integration/meta_data/deadlock.scope.properties deleted file mode 100644 index 29985104e..000000000 --- a/bundles/pubsub/integration/meta_data/deadlock.scope.properties +++ /dev/null @@ -1,28 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -zmq.static.bind.url=ipc:///tmp/pubsub-deadlock -zmq.static.connect.urls=ipc:///tmp/pubsub-deadlock -tcp.static.bind.url=tcp://localhost:9000 -tcp.static.connect.urls=tcp://localhost:9000 -udpmc.static.bind.port=50678 -udpmc.static.connect.socket_addresses=224.100.0.1:50678 -websocket.static.connect.socket_addresses=127.0.0.1:58080 - -#note only effective if run as root -thread.realtime.sched=SCHED_FIFO -thread.realtime.prio=50 - diff --git a/bundles/pubsub/integration/meta_data/deadlock.scope2.properties b/bundles/pubsub/integration/meta_data/deadlock.scope2.properties deleted file mode 100644 index 29985104e..000000000 --- a/bundles/pubsub/integration/meta_data/deadlock.scope2.properties +++ /dev/null @@ -1,28 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -zmq.static.bind.url=ipc:///tmp/pubsub-deadlock -zmq.static.connect.urls=ipc:///tmp/pubsub-deadlock -tcp.static.bind.url=tcp://localhost:9000 -tcp.static.connect.urls=tcp://localhost:9000 -udpmc.static.bind.port=50678 -udpmc.static.connect.socket_addresses=224.100.0.1:50678 -websocket.static.connect.socket_addresses=127.0.0.1:58080 - -#note only effective if run as root -thread.realtime.sched=SCHED_FIFO -thread.realtime.prio=50 - diff --git a/bundles/pubsub/integration/meta_data/msg.descriptor b/bundles/pubsub/integration/meta_data/msg.descriptor deleted file mode 100644 index da774ae02..000000000 --- a/bundles/pubsub/integration/meta_data/msg.descriptor +++ /dev/null @@ -1,9 +0,0 @@ -:header -type=message -name=msg -version=1.0.0 -:annotations -classname=org.example.Msg -:types -:message -{i seqNr} diff --git a/bundles/pubsub/integration/meta_data/ping.properties b/bundles/pubsub/integration/meta_data/ping.properties deleted file mode 100644 index 811441373..000000000 --- a/bundles/pubsub/integration/meta_data/ping.properties +++ /dev/null @@ -1,29 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -zmq.static.bind.url=ipc:///tmp/pubsub-pingtest -zmq.static.connect.urls=ipc:///tmp/pubsub-pingtest -tcp.static.bind.url=tcp://localhost:9000 -tcp.static.connect.urls=tcp://localhost:9000 -udpmc.static.bind.port=50678 -udpmc.static.connect.socket_addresses=224.100.0.1:50678 -websocket.static.connect.socket_addresses=127.0.0.1:58080 - -#note only effective if run as root -thread.realtime.sched=SCHED_FIFO -thread.realtime.prio=50 - -pubsub.serializer=json \ No newline at end of file diff --git a/bundles/pubsub/integration/meta_data/ping2.properties b/bundles/pubsub/integration/meta_data/ping2.properties deleted file mode 100644 index ff0dbed31..000000000 --- a/bundles/pubsub/integration/meta_data/ping2.properties +++ /dev/null @@ -1,23 +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. -tcp.static.bind.url=tcp://localhost:9500 -tcp.passive.key=tcp://localhost:9500 - -#note only effective if run as root -thread.realtime.sched=SCHED_FIFO -thread.realtime.prio=50 - diff --git a/bundles/pubsub/integration/meta_data/ping3.properties b/bundles/pubsub/integration/meta_data/ping3.properties deleted file mode 100644 index 557170542..000000000 --- a/bundles/pubsub/integration/meta_data/ping3.properties +++ /dev/null @@ -1,22 +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. -tcp.passive.key=tcp://localhost -tcp.passive.configured=true -#note only effective if run as root -thread.realtime.sched=SCHED_FIFO -thread.realtime.prio=50 - diff --git a/bundles/pubsub/integration/meta_data/pong2.properties b/bundles/pubsub/integration/meta_data/pong2.properties deleted file mode 100644 index b95f3bc53..000000000 --- a/bundles/pubsub/integration/meta_data/pong2.properties +++ /dev/null @@ -1,23 +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. -tcp.static.connect.urls=tcp://localhost:9500 -tcp.passive.key=tcp://localhost - -#note only effective if run as root -thread.realtime.sched=SCHED_FIFO -thread.realtime.prio=50 - diff --git a/bundles/pubsub/integration/meta_data/pong3.properties b/bundles/pubsub/integration/meta_data/pong3.properties deleted file mode 100644 index cb64543dc..000000000 --- a/bundles/pubsub/integration/meta_data/pong3.properties +++ /dev/null @@ -1,22 +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. -tcp.passive.key=tcp://localhost:9500 -tcp.passive.configured=true -#note only effective if run as root -thread.realtime.sched=SCHED_FIFO -thread.realtime.prio=50 - diff --git a/bundles/pubsub/integration/pstm_deadlock_test/test_runner.cc b/bundles/pubsub/integration/pstm_deadlock_test/test_runner.cc deleted file mode 100644 index b4e10e7cc..000000000 --- a/bundles/pubsub/integration/pstm_deadlock_test/test_runner.cc +++ /dev/null @@ -1,161 +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 "celix_launcher.h" -#include -#include -#include "pubsub/api.h" -#include -#include -#include -#include "celix_bundle_context.h" -#include "celix_constants.h" - -#include -#include - -constexpr const char *deadlockSutBundleFile = DEADLOCK_SUT_BUNDLE_FILE; - -struct DeadlockTestSuite : public ::testing::Test { - celix_framework_t *fw = NULL; - celix_bundle_context_t *ctx = NULL; - std::shared_ptr mng = NULL; - long sutBundleId = 0; - - DeadlockTestSuite() { - celixLauncher_launch("config.properties", &fw); - ctx = celix_framework_getFrameworkContext(fw); - mng = std::shared_ptr(new DependencyManager(ctx)); - sutBundleId = celix_bundleContext_installBundle(ctx, deadlockSutBundleFile, false); - } - - ~DeadlockTestSuite() override { - celix_bundleContext_uninstallBundle(ctx, sutBundleId); - mng = nullptr; - celixLauncher_stop(fw); - celixLauncher_waitForShutdown(fw); - celixLauncher_destroy(fw); - ctx = NULL; - fw = NULL; - } - - DeadlockTestSuite(const DeadlockTestSuite&) = delete; - DeadlockTestSuite& operator=(const DeadlockTestSuite&) = delete; -}; - -class DependencyCmp; - -struct activator { - std::string cmpUUID{}; - celix_bundle_context_t *ctx{}; - std::promise promise{}; - std::shared_ptr mng{}; -}; - -class IDependency { -protected: - IDependency() = default; - ~IDependency() = default; -public: - virtual double getData() = 0; -}; - -class DependencyCmp : public IDependency { -public: - DependencyCmp() { - std::cout << "Creating DependencyCmp\n"; - } - virtual ~DependencyCmp() { std::cout << "Destroying DependencyCmp\n"; }; - - DependencyCmp(DependencyCmp&& other) noexcept = default; - DependencyCmp& operator=(DependencyCmp&&) = default; - - DependencyCmp(const DependencyCmp& other) = delete; - DependencyCmp operator=(const DependencyCmp&) = delete; - - double getData() override { - return 1.0; - } - - void setPublisher(const pubsub_publisher_t *pub) { - if (pub == nullptr) { - return; //nothing on "unsetting" svc - } - auto cmp = act->mng->findComponent(act->cmpUUID); - EXPECT_TRUE(cmp); - if (cmp) { - cmp->createCServiceDependency(PUBSUB_PUBLISHER_SERVICE_NAME) - .setVersionRange("[3.0.0,4)") - .setFilter("(topic=deadlock)(scope=scope2)") - .setStrategy(celix::dm::DependencyUpdateStrategy::suspend) - .setCallbacks([](const pubsub_publisher_t *, Properties&&) { std::cout << "success\n"; }) - .setRequired(true) - .build(); - } - act->promise.set_value(); - } - - int init() { - return CELIX_SUCCESS; - } - - int start() { - return CELIX_SUCCESS; - } - - int stop() { - return CELIX_SUCCESS; - } - - int deinit() { - return CELIX_SUCCESS; - } - - activator *act{nullptr}; -}; - -TEST_F(DeadlockTestSuite, test) { - - Component& cmp = mng->createComponent() - .addInterface("1.0.0", {}); - - cmp.setCallbacks(&DependencyCmp::init, &DependencyCmp::start, &DependencyCmp::stop, &DependencyCmp::deinit); - - activator act{}; - act.ctx = ctx; - act.mng = mng; - act.cmpUUID = cmp.getUUID(); - cmp.getInstance().act = &act; - - cmp.createCServiceDependency(PUBSUB_PUBLISHER_SERVICE_NAME) - .setVersionRange("[3.0.0,4)") - .setFilter("(topic=deadlock)(scope=scope)") - .setStrategy(celix::dm::DependencyUpdateStrategy::suspend) - .setCallbacks([&cmp](const pubsub_publisher_t *pub, Properties&&) { cmp.getInstance().setPublisher(pub); }) - .setRequired(true); - - ASSERT_TRUE(cmp.isValid()); - mng->start(); - - celix_bundleContext_startBundle(ctx, sutBundleId); - - //wait till setPublisher has added an service dependency. If not the findComponent can return NULL - act.promise.get_future().wait(); - mng->stop(); -} diff --git a/bundles/pubsub/keygen/CMakeLists.txt b/bundles/pubsub/keygen/CMakeLists.txt deleted file mode 100644 index 0f8ecc893..000000000 --- a/bundles/pubsub/keygen/CMakeLists.txt +++ /dev/null @@ -1,30 +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. - -if (BUILD_ZMQ_SECURITY) - - find_package(ZeroMQ REQUIRED) - find_package(czmq REQUIRED) - find_package(OpenSSL 1.1.0 REQUIRED) - - add_executable(makecert makecert.c) - target_link_libraries(makecert czmq::czmq) - - add_executable(ed_file ed_file.c) - target_link_libraries(ed_file PUBLIC ZeroMQ::ZeroMQ czmq::czmq OpenSSL::SSL) - -endif() diff --git a/bundles/pubsub/keygen/ed_file.c b/bundles/pubsub/keygen/ed_file.c deleted file mode 100644 index aabb8f1ae..000000000 --- a/bundles/pubsub/keygen/ed_file.c +++ /dev/null @@ -1,309 +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. - */ -/** - * ed_file.c - * - * \date Dec 2, 2016 - * \author Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - -#include -#include - -#include -#include -#include - -#define MAX_KEY_FILE_LENGTH 256 -#define MAX_LINE_LENGTH 64 -#define AES_KEY_LENGTH 32 -#define AES_IV_LENGTH 16 - -#define KEY_TO_GET "aes_key" -#define IV_TO_GET "aes_iv" - -int generate_sha256_hash(char* text, unsigned char* digest); -int encrypt_aes(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext); -int decrypt_aes(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext); - -static char* read_keys_file_content(const char *filePath); -static void parse_key_lines(char *keysBuffer, char **key, char **iv); -static void parse_key_line(char *line, char **key, char **iv); - -int main(int argc, const char* argv[]) -{ - if (argc < 4) { - printf("Usage: %s [options]\n", argv[0]); - printf("Default behavior: encrypting a file\n"); - printf("Options:\n"); - printf("\t-d\tSpecify to decrypt a file\n"); - printf("\n"); - return EXIT_FAILURE; - } - - int rc = 0; - - const char* keys_file_path = argv[1]; - const char* input_file_path = argv[2]; - const char* output_file_path = argv[3]; - - bool decryptParam = false; - if (argc > 4 && strcmp(argv[4], "-d") == 0) { - decryptParam = true; - } - - if (!zsys_file_exists(keys_file_path)) { - printf("Keys file '%s' doesn't exist!\n", keys_file_path); - return EXIT_FAILURE; - } - - if (!zsys_file_exists(input_file_path)) { - printf("Input file does not exist!\n"); - return EXIT_FAILURE; - } - - char* keys_data = read_keys_file_content(keys_file_path); - if (keys_data == NULL) { - return EXIT_FAILURE; - } - - char* key = NULL; - char* iv = NULL; - parse_key_lines(keys_data, &key, &iv); - free(keys_data); - - if (key == NULL || iv == NULL) { - printf("Loading AES key and/or AES iv failed!\n"); - free(key); - free(iv); - return EXIT_FAILURE; - } - - printf("Using AES Key \t\t'%s'\n", key); - printf("Using AES IV \t\t'%s'\n", iv); - printf("Input file path \t'%s'\n", input_file_path); - printf("Output file path \t'%s'\n", output_file_path); - printf("Decrypting \t\t'%s'\n\n", (decryptParam) ? "true" : "false"); - - unsigned char key_digest[EVP_MAX_MD_SIZE]; - unsigned char iv_digest[EVP_MAX_MD_SIZE]; - generate_sha256_hash((char*) key, key_digest); - generate_sha256_hash((char*) iv, iv_digest); - - zchunk_t* input_chunk = zchunk_slurp (input_file_path, 0); - if (input_chunk == NULL) { - printf("Input file not correct!\n"); - free(key); - free(iv); - return EXIT_FAILURE; - } - - //Load input data from file - int input_file_size = (int) zchunk_size (input_chunk); - char* input_file_data = zchunk_strdup(input_chunk); - zchunk_destroy (&input_chunk); - - int output_len; - unsigned char output[input_file_size]; - if (decryptParam) { - output_len = decrypt_aes((unsigned char*) input_file_data, input_file_size, key_digest, iv_digest, output); - output[output_len] = '\0'; - }else{ - output_len = encrypt_aes((unsigned char*) input_file_data, input_file_size, key_digest, iv_digest, output); - } - - //Write output data to file - zfile_t* output_file = zfile_new (".", output_file_path); - zchunk_t* output_chunk = zchunk_new(output, output_len); - rc = zfile_output (output_file); - if (rc != 0) { - printf("Problem with opening file for writing!\n"); - zchunk_destroy (&output_chunk); - zfile_close (output_file); - zfile_destroy (&output_file); - free(input_file_data); - free(key); - free(iv); - - return EXIT_FAILURE; - } - - rc = zfile_write (output_file, output_chunk, 0); - if (rc != 0) { - printf("Problem with writing output to file!\n"); - } - printf("Output written to file:\n"); - if (decryptParam) { - printf("%s\n", output); - }else{ - BIO_dump_fp (stdout, (const char *) output, output_len); - } - - zchunk_destroy (&output_chunk); - zfile_close (output_file); - zfile_destroy (&output_file); - free(input_file_data); - free(key); - free(iv); - - return EXIT_SUCCESS; -} - -int generate_sha256_hash(char* text, unsigned char* digest) -{ - unsigned int digest_len; - - EVP_MD_CTX * mdctx = EVP_MD_CTX_new(); - EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL); - EVP_DigestUpdate(mdctx, text, strlen(text)); - EVP_DigestFinal_ex(mdctx, digest, &digest_len); - EVP_MD_CTX_free(mdctx); - - return digest_len; -} - -int encrypt_aes(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext) -{ - int len; - int ciphertext_len; - - EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); - - EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv); - EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len); - ciphertext_len = len; - EVP_EncryptFinal_ex(ctx, ciphertext + len, &len); - ciphertext_len += len; - - EVP_CIPHER_CTX_free(ctx); - - return ciphertext_len; -} - -int decrypt_aes(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext) -{ - int len; - int plaintext_len; - - EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); - - EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv); - EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len); - plaintext_len = len; - EVP_DecryptFinal_ex(ctx, plaintext + len, &len); - plaintext_len += len; - - EVP_CIPHER_CTX_free(ctx); - - return plaintext_len; -} - -static char* read_keys_file_content(const char *keys_file_path) { - char* keys_file_full_path = strndup(keys_file_path, MAX_KEY_FILE_LENGTH); - char* keys_file_name = NULL; - - char* sep_kf_at = strrchr(keys_file_path, '/'); - if (sep_kf_at != NULL) { - *sep_kf_at = '\0'; - keys_file_name = sep_kf_at + 1; - }else{ - keys_file_name = (char*) keys_file_path; - keys_file_path = (const char*) "."; - } - - printf("Keys file path: %s\n", keys_file_full_path); - - int rc = 0; - - zfile_t* keys_file = zfile_new (keys_file_path, keys_file_name); - rc = zfile_input (keys_file); - if (rc != 0) { - printf("Keys file '%s' not readable!\n", keys_file_full_path); - zfile_destroy(&keys_file); - free(keys_file_full_path); - return NULL; - } - - ssize_t keys_file_size = zsys_file_size (keys_file_full_path); - zchunk_t* keys_chunk = zfile_read (keys_file, keys_file_size, 0); - if (keys_chunk == NULL) { - printf("Can't read file '%s'!\n", keys_file_full_path); - zfile_close(keys_file); - zfile_destroy(&keys_file); - free(keys_file_full_path); - return NULL; - } - - char* keys_data = zchunk_strdup(keys_chunk); - zchunk_destroy(&keys_chunk); - zfile_close(keys_file); - zfile_destroy (&keys_file); - - return keys_data; -} - -static void parse_key_lines(char *keysBuffer, char **key, char **iv) { - char *line = NULL, *saveLinePointer = NULL; - - bool firstTime = true; - do { - if (firstTime) { - line = strtok_r(keysBuffer, "\n", &saveLinePointer); - firstTime = false; - }else { - line = strtok_r(NULL, "\n", &saveLinePointer); - } - - if (line == NULL) { - break; - } - - parse_key_line(line, key, iv); - - } while ((*key == NULL || *iv == NULL) && line != NULL); - -} - -static void parse_key_line(char *line, char **key, char **iv) { - char *detectedKey = NULL, *detectedValue= NULL; - - char* sep_at = strchr(line, ':'); - if (sep_at == NULL) { - return; - } - - *sep_at = '\0'; // overwrite first separator, creating two strings. - detectedKey = line; - detectedValue = sep_at + 1; - - if (detectedKey == NULL || detectedValue == NULL) { - return; - } - if (detectedKey[0] == '\0' || detectedValue[0] == '\0') { - return; - } - - if (*key == NULL && strcmp(detectedKey, KEY_TO_GET) == 0) { - *key = strndup(detectedValue, AES_KEY_LENGTH); - } else if (*iv == NULL && strcmp(detectedKey, IV_TO_GET) == 0) { - *iv = strndup(detectedValue, AES_IV_LENGTH); - } -} - diff --git a/bundles/pubsub/keygen/makecert.c b/bundles/pubsub/keygen/makecert.c deleted file mode 100644 index 4999397ac..000000000 --- a/bundles/pubsub/keygen/makecert.c +++ /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. - */ -/** - * makecert.c - * - * \date Dec 2, 2016 - * \author Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - -#include - -#include "czmq.h" - -int main (int argc, const char * argv[]) { - - const char * cert_name_public = "certificate.pub"; - const char * cert_name_secret = "certificate.key"; - if (argc == 3 && strcmp(argv[1], argv[2]) != 0) { - cert_name_public = argv[1]; - cert_name_secret = argv[2]; - } - - zcert_t * cert = zcert_new(); - - char *timestr = zclock_timestr (); - zcert_set_meta (cert, "date-created", timestr); - free (timestr); - - zcert_save_public(cert, cert_name_public); - zcert_save_secret(cert, cert_name_secret); - zcert_print (cert); - printf("\n"); - printf("I: CURVE certificate created in %s and %s\n", cert_name_public, cert_name_secret); - zcert_destroy (&cert); - - return 0; -} diff --git a/bundles/pubsub/pubsub_admin_tcp/CMakeLists.txt b/bundles/pubsub/pubsub_admin_tcp/CMakeLists.txt deleted file mode 100644 index 421f4afa2..000000000 --- a/bundles/pubsub/pubsub_admin_tcp/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -celix_subproject(PUBSUB_PSA_TCP "Build TCP PubSub Admin" ON) -if (PUBSUB_PSA_TCP) - find_package(libuuid REQUIRED) - - add_celix_bundle(celix_pubsub_admin_tcp - BUNDLE_SYMBOLICNAME "apache_celix_pubsub_admin_tcp" - VERSION "2.1.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 - ) - - target_link_libraries(celix_pubsub_admin_tcp PRIVATE Celix::pubsub_spi Celix::pubsub_utils) - target_link_libraries(celix_pubsub_admin_tcp PRIVATE Celix::log_helper) - target_link_libraries(celix_pubsub_admin_tcp PRIVATE Celix::shell_api) - target_include_directories(celix_pubsub_admin_tcp PRIVATE src) - target_link_libraries(celix_pubsub_admin_tcp PRIVATE libuuid::libuuid) - celix_deprecated_utils_headers(celix_pubsub_admin_tcp) - celix_deprecated_framework_headers(celix_pubsub_admin_tcp) - - install_celix_bundle(celix_pubsub_admin_tcp EXPORT celix COMPONENT pubsub) - add_library(Celix::celix_pubsub_admin_tcp ALIAS celix_pubsub_admin_tcp) -endif (PUBSUB_PSA_TCP) diff --git a/bundles/pubsub/pubsub_admin_tcp/src/psa_activator.c b/bundles/pubsub/pubsub_admin_tcp/src/psa_activator.c deleted file mode 100644 index d8b5f13a6..000000000 --- a/bundles/pubsub/pubsub_admin_tcp/src/psa_activator.c +++ /dev/null @@ -1,128 +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 - -#include "celix_bundle_activator.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 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->protocolsTrackerId = -1L; - - act->logHelper = celix_logHelper_create(ctx, "celix_psa_admin_tcp_v2"); - - act->admin = pubsub_tcpAdmin_create(ctx, act->logHelper); - celix_status_t status = act->admin != NULL ? CELIX_SUCCESS : CELIX_BUNDLE_EXCEPTION; - - //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.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->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/src/pubsub_psa_tcp_constants.h b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_psa_tcp_constants.h deleted file mode 100644 index d493eaacb..000000000 --- a/bundles/pubsub/pubsub_admin_tcp/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/src/pubsub_tcp_admin.c b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_admin.c deleted file mode 100644 index bdca02cb9..000000000 --- a/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_admin.c +++ /dev/null @@ -1,710 +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 -#include -#include - -#include -#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" -#include "celix_compiler.h" -#include "celix_constants.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_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; - - struct { - celix_thread_mutex_t mutex; - hash_map_t *map; //key = pubsub message serialization marker svc id (long), pubsub_serialization_handler_t*. - } serializationHandlers; - - pubsub_tcp_endPointStore_t endpointStore; -}; - -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, CELIX_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->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); - - celixThreadMutex_create(&psa->serializationHandlers.mutex, NULL); - psa->serializationHandlers.map = hashMap_create(NULL, NULL, NULL, 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->serializationHandlers.mutex); - iter = hashMapIterator_construct(psa->serializationHandlers.map); - while (hashMapIterator_hasNext(&iter)) { - pubsub_serializer_handler_t* entry = hashMapIterator_nextValue(&iter); - pubsub_serializerHandler_destroy(entry); - } - celixThreadMutex_unlock(&psa->serializationHandlers.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->serializationHandlers.mutex); - hashMap_destroy(psa->serializationHandlers.map, false, false); - - celixThreadMutex_destroy(&psa->protocols.mutex); - hashMap_destroy(psa->protocols.map, false, false); - - free(psa->ipAddress); - - free(psa); -} - -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, CELIX_FRAMEWORK_SERVICE_ID, -1L); - - if (protType == NULL) { - L_INFO("[PSA_tcp] 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, CELIX_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_V2] pubsub_tcpAdmin_matchPublisher"); - celix_status_t status = CELIX_SUCCESS; - double score = pubsub_utils_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_V2] pubsub_tcpAdmin_matchSubscriber"); - celix_status_t status = CELIX_SUCCESS; - double score = pubsub_utils_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_V2] pubsub_tcpAdmin_matchEndpoint"); - celix_status_t status = CELIX_SUCCESS; - bool match = pubsub_utils_matchEndpoint(psa->ctx, psa->log, endpoint, PUBSUB_TCP_ADMIN_TYPE, true, NULL, NULL); - if (outMatch != NULL) { - *outMatch = match; - } - return status; -} - -static pubsub_serializer_handler_t* pubsub_tcpAdmin_getSerializationHandler(pubsub_tcp_admin_t* psa, long msgSerializationMarkerSvcId) { - pubsub_serializer_handler_t* handler = NULL; - celixThreadMutex_lock(&psa->serializationHandlers.mutex); - handler = hashMap_get(psa->serializationHandlers.map, (void*)msgSerializationMarkerSvcId); - if (handler == NULL) { - handler = pubsub_serializerHandler_createForMarkerService(psa->ctx, msgSerializationMarkerSvcId, psa->log); - if (handler != NULL) { - hashMap_put(psa->serializationHandlers.map, (void*)msgSerializationMarkerSvcId, handler); - } - } - celixThreadMutex_unlock(&psa->serializationHandlers.mutex); - return handler; -} - -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) Get serialization handler - //2) Create TopicSender - //3) Store TopicSender - //4) Connect existing endpoints - //5) set outPublisherEndpoint - - pubsub_serializer_handler_t* handler = pubsub_tcpAdmin_getSerializationHandler(psa, serializerSvcId); - if (handler == NULL) { - L_ERROR("Cannot create topic sender without serialization handler"); - return CELIX_ILLEGAL_STATE; - } - - celix_properties_t *newEndpoint = NULL; - char *key = pubsubEndpoint_createScopeTopicKey(scope, topic); - - celixThreadMutex_lock(&psa->protocols.mutex); - celixThreadMutex_lock(&psa->topicSenders.mutex); - pubsub_tcp_topic_sender_t *sender = hashMap_get(psa->topicSenders.map, key); - celixThreadMutex_unlock(&psa->topicSenders.mutex); - if (sender == NULL) { - psa_tcp_protocol_entry_t *protEntry = hashMap_get(psa->protocols.map, (void *) protocolSvcId); - if (protEntry != NULL) { - sender = pubsub_tcpTopicSender_create(psa->ctx, psa->log, scope, topic, handler, handle, topicProperties, - &psa->endpointStore, protocolSvcId, - protEntry->svc); - } - if (sender != NULL) { - const char *psaType = PUBSUB_TCP_ADMIN_TYPE; - const char *protType = protEntry->protType; - newEndpoint = pubsubEndpoint_create(psa->fwUUID, scope, topic, PUBSUB_PUBLISHER_ENDPOINT_TYPE, psaType, - pubsub_serializerHandler_getSerializationType(handler), 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); - celixThreadMutex_lock(&psa->topicSenders.mutex); - hashMap_put(psa->topicSenders.map, key, sender); - celixThreadMutex_unlock(&psa->topicSenders.mutex); - } else { - L_ERROR("[PSA_TCP_V2] Error creating a TopicSender"); - free(key); - } - } else { - free(key); - L_ERROR("[PSA_TCP_V2] Cannot setup already existing TopicSender for scope/topic %s/%s!", scope, topic); - } - celixThreadMutex_unlock(&psa->protocols.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); - celixThreadMutex_unlock(&psa->topicSenders.mutex); - free(mapKey); - pubsub_tcpTopicSender_destroy(sender); - } else { - celixThreadMutex_unlock(&psa->topicSenders.mutex); - L_ERROR("[PSA_TCP_V2] Cannot teardown TopicSender with scope/topic %s/%s. Does not exists", - scope == NULL ? "(null)" : scope, - topic); - } - 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; - - pubsub_serializer_handler_t* handler = pubsub_tcpAdmin_getSerializationHandler(psa, serializerSvcId); - if (handler == NULL) { - L_ERROR("Cannot create topic receiver without serialization handler"); - return CELIX_ILLEGAL_STATE; - } - - celix_properties_t *newEndpoint = NULL; - char *key = pubsubEndpoint_createScopeTopicKey(scope, topic); - - celixThreadMutex_lock(&psa->protocols.mutex); - celixThreadMutex_lock(&psa->topicReceivers.mutex); - pubsub_tcp_topic_receiver_t *receiver = hashMap_get(psa->topicReceivers.map, key); - celixThreadMutex_unlock(&psa->topicReceivers.mutex); - if (receiver == NULL) { - psa_tcp_protocol_entry_t *protEntry = hashMap_get(psa->protocols.map, (void *) protocolSvcId); - if (protEntry != NULL) { - receiver = pubsub_tcpTopicReceiver_create(psa->ctx, psa->log, scope, topic, - handler, handle, topicProperties, - &psa->endpointStore, protocolSvcId, protEntry->svc); - } else { - L_ERROR("[PSA_TCP_V2] 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 *protType = protEntry->protType; - newEndpoint = pubsubEndpoint_create(psa->fwUUID, scope, topic, - PUBSUB_SUBSCRIBER_ENDPOINT_TYPE, psaType, pubsub_serializerHandler_getSerializationType(handler), 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); - } - celixThreadMutex_lock(&psa->topicReceivers.mutex); - hashMap_put(psa->topicReceivers.map, key, receiver); - celixThreadMutex_unlock(&psa->topicReceivers.mutex); - } else { - L_ERROR("[PSA_TCP_V2] Error creating a TopicReceiver."); - free(key); - } - } else { - free(key); - L_ERROR("[PSA_TCP_V2] Cannot setup already existing TopicReceiver for scope/topic %s/%s!", - scope == NULL ? "(null)" : scope, - topic); - } - celixThreadMutex_unlock(&psa->protocols.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); - celixThreadMutex_unlock(&psa->topicReceivers.mutex); - - free(receiverKey); - pubsub_tcpTopicReceiver_destroy(receiver); - } else { - 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_V2] 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); - } - - celix_properties_t *cpy = celix_properties_copy(endpoint); - const char *uuid = celix_properties_get(cpy, PUBSUB_ENDPOINT_UUID, NULL); - - celixThreadMutex_lock(&psa->discoveredEndpoints.mutex); - 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_V2] 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 CELIX_UNUSED, FILE *out, - FILE *errStream CELIX_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->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 protSvcId = pubsub_tcpTopicSender_protocolSvcId(sender); - psa_tcp_protocol_entry_t *protEntry = hashMap_get(psa->protocols.map, (void *) protSvcId); - const char *serType = pubsub_tcpTopicSender_serializerType(sender); - 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); - - fprintf(out, "\n"); - fprintf(out, "\nTopic Receivers:\n"); - 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 protSvcId = pubsub_tcpTopicReceiver_protocolSvcId(receiver); - psa_tcp_protocol_entry_t *protEntry = hashMap_get(psa->protocols.map, (void *) protSvcId); - const char *serType = pubsub_tcpTopicReceiver_serializerType(receiver); - 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); - fprintf(out, "\n"); - - free(line); - return status; -} - -pubsub_admin_metrics_t *pubsub_tcpAdmin_metrics(void *handle) { - return NULL; -} diff --git a/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_admin.h b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_admin.h deleted file mode 100644 index fe8d97a53..000000000 --- a/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_admin.h +++ /dev/null @@ -1,87 +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 -#include -#include -#include "celix_log_helper.h" -#include "pubsub_psa_tcp_constants.h" - -typedef struct pubsub_tcp_admin pubsub_tcp_admin_t; - -typedef struct psa_tcp_serializer_entry { - const char *fqn; - const char *version; - pubsub_message_serialization_service_t *svc; -} psa_tcp_serializer_entry_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/src/pubsub_tcp_common.c b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_common.c deleted file mode 100644 index b46e39c6c..000000000 --- a/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_common.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -#include -#include -#include "pubsub_tcp_common.h" -#include "celix_utils.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 = celix_utils_trimInPlace(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/src/pubsub_tcp_common.h b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_common.h deleted file mode 100644 index 9ea31dba7..000000000 --- a/bundles/pubsub/pubsub_admin_tcp/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 -#include - -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/src/pubsub_tcp_handler.c b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_handler.c deleted file mode 100644 index 464e60192..000000000 --- a/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_handler.c +++ /dev/null @@ -1,1451 +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 Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - -#include -#include -#include -#include -#include -#include -#include -#if defined(__APPLE__) -#include -#include -#include -#else -#include -#endif -#include -#include -#include -#include -#include "hash_map.h" -#include "utils.h" -#include "pubsub_tcp_handler.h" -#include "celix_compiler.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)\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 CELIX_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) { - // already exist - return rc; - } - char protocol[] = "tcp"; - int fd = pubsub_tcpHandler_open(handle, url); - rc = fd; - if (rc < 0) { - return rc; - } - struct sockaddr_in *sin = pubsub_utils_url_from_fd(fd); - // Make handler fd entry - char *pUrl = pubsub_utils_url_get_url(sin, protocol); - if (sin != NULL && pUrl != NULL) { - entry = pubsub_tcpHandler_createEntry(handle, fd, pUrl, NULL, sin); - } - free(pUrl); - free(sin); - if (entry != NULL) { - __atomic_store_n(&entry->connected, true, __ATOMIC_RELEASE); - if (rc >= 0) { - rc = listen(fd, SOMAXCONN); - if (rc != 0) { - L_ERROR("[TCP Socket] Error listen: %s\n", strerror(errno)); - } - } - if (rc >= 0) { - rc = pubsub_tcpHandler_makeNonBlocking(handle, fd); - } - 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_INFO("[TCP Socket] Using %s for service annunciation", entry->url); - celixThreadRwlock_writeLock(&handle->dbLock); - 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); - entry = NULL; - } else { - L_ERROR("[TCP Socket] Cannot create poll: %s\n", strerror(errno)); - } - } - if (entry) { - pubsub_tcpHandler_freeEntry(entry); - entry = NULL; - } - } else { - L_ERROR("[TCP Socket] Error listen socket cannot bind to %s: %s\n", url ? url : "", strerror(errno)); - close(fd); - } - 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); - } - } - celix_properties_destroy(entry->header.metadata.metadata); - entry->header.metadata.metadata = NULL; -} - -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 (!__atomic_load_n(&entry->connected, __ATOMIC_ACQUIRE)) { - 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)+1]; // +1 to ensure a size of 0 never occurs. - 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 (!__atomic_load_n(&entry->connected, __ATOMIC_ACQUIRE)) { - 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; - - size_t metadataSize = 0; - if (message->metadata.metadata) { - handle->protocol->encodeMetadata(handle->protocol->handle, message, &entry->writeMetaBuffer, &entry->writeMetaBufferSize, &metadataSize); - // When maxMsgSize is smaller then meta data is disabled - if (metadataSize > entry->maxMsgSize) { - metadataSize = 0; - } - } - - 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 && entry->writeMetaBuffer) && - (msgPartSize < maxMsgSize) && - (msg.msg_iovlen-1 < max_msg_iov_len)) { // header is already included - msg.msg_iov[msg.msg_iovlen].iov_base = entry->writeMetaBuffer; - 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: %zu != %ld (%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); - 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 (!__atomic_exchange_n(&entry->connected, true, __ATOMIC_ACQ_REL)) { - // tell sender that an receiver is connected - if (handle->receiverConnectMessageCallback) - handle->receiverConnectMessageCallback(handle->receiverConnectPayload, entry->url, false); - } - 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/src/pubsub_tcp_handler.h b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_handler.h deleted file mode 100644 index 2d97634e2..000000000 --- a/bundles/pubsub/pubsub_admin_tcp/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 Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - -#ifndef _PUBSUB_TCP_BUFFER_HANDLER_H_ -#define _PUBSUB_TCP_BUFFER_HANDLER_H_ - -#include -#include -#include -#include -#include -#include -#include "celix_threads.h" -#include "pubsub_utils_url.h" -#include - -#ifndef MIN -#define MIN(a, b) ((ab) ? (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/src/pubsub_tcp_topic_receiver.c b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_receiver.c deleted file mode 100644 index b533b8aee..000000000 --- a/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_receiver.c +++ /dev/null @@ -1,674 +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 -#include -#include -#include -#include -#include -#include -#include "pubsub_tcp_handler.h" -#include "pubsub_tcp_topic_receiver.h" -#include "pubsub_psa_tcp_constants.h" -#include "pubsub_tcp_common.h" -#include "pubsub_tcp_admin.h" - -#include -#include -#include "pubsub_interceptors_handler.h" -#include -#include "celix_compiler.h" -#include "celix_string_hash_map.h" -#include "celix_long_hash_map.h" - -#ifndef UUID_STR_LEN -#define UUID_STR_LEN 37 -#endif - -#define L_TRACE(...) \ - celix_logHelper_log(receiver->logHelper, CELIX_LOG_LEVEL_TRACE, __VA_ARGS__) -#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 protocolSvcId; - pubsub_protocol_service_t *protocol; - char *scope; - char *topic; - pubsub_serializer_handler_t* serializerHandler; - void *admin; - size_t timeout; - bool isPassive; - pubsub_tcpHandler_t *socketHandler; - pubsub_tcpHandler_t *sharedSocketHandler; - pubsub_interceptors_handler_t *interceptorsHandler; - - struct { - celix_thread_t thread; - celix_thread_mutex_t mutex; - bool running; - } thread; - - struct { - celix_thread_mutex_t mutex; - celix_string_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; - celix_long_hash_map_t *map; //key = long svc 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_entry { - pubsub_subscriber_t* subscriberSvc; - 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); -static void pubsub_tcpTopicReceiver_removeSubscriber(void *handle, void *svc, const celix_properties_t *props); -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 *message, 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); - -pubsub_tcp_topic_receiver_t *pubsub_tcpTopicReceiver_create(celix_bundle_context_t *ctx, - celix_log_helper_t *logHelper, - const char *scope, - const char *topic, - pubsub_serializer_handler_t* serializerHandler, - void *admin, - const celix_properties_t *topicProperties, - pubsub_tcp_endPointStore_t *handlerStore, - long protocolSvcId, - pubsub_protocol_service_t *protocol) { - pubsub_tcp_topic_receiver_t *receiver = calloc(1, sizeof(*receiver)); - receiver->ctx = ctx; - receiver->logHelper = logHelper; - receiver->serializerHandler = serializerHandler; - receiver->admin = admin; - receiver->protocolSvcId = protocolSvcId; - receiver->protocol = protocol; - receiver->scope = celix_utils_strdup(scope); - receiver->topic = celix_utils_strdup(topic); - receiver->interceptorsHandler = pubsubInterceptorsHandler_create(ctx, scope, topic, PUBSUB_TCP_ADMIN_TYPE, - pubsub_serializerHandler_getSerializationType(serializerHandler)); - 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; - - celixThreadMutex_create(&receiver->thread.mutex, NULL); - - //receiver->socketHandler depend on belows, we should initialize them first. - celixThreadMutex_create(&receiver->requestedConnections.mutex, NULL); - celixThreadMutex_create(&receiver->subscribers.mutex, NULL); - celix_string_hash_map_create_options_t reqConsMapOpts = CELIX_EMPTY_STRING_HASH_MAP_CREATE_OPTIONS; - reqConsMapOpts.storeKeysWeakly = true; - receiver->requestedConnections.map = celix_stringHashMap_createWithOptions(&reqConsMapOpts); - receiver->subscribers.map = celix_longHashMap_create(); - - /* 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); - } - - if ((staticConnectUrls != NULL) && (receiver->socketHandler != NULL) && (!receiver->isPassive)) { - char *urlsCopy = celix_utils_strdup(staticConnectUrls); - 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 = celix_utils_strdup(url); - entry->parent = receiver; - celix_stringHashMap_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.serviceName = PUBSUB_SUBSCRIBER_SERVICE_NAME; - opts.filter.filter = buf; - opts.callbackHandle = receiver; - opts.addWithProperties = pubsub_tcpTopicReceiver_addSubscriber; - opts.removeWithProperties = pubsub_tcpTopicReceiver_removeSubscriber; - receiver->subscriberTrackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts); - } - - if (receiver->socketHandler == NULL) { - celix_longHashMap_destroy(receiver->subscribers.map); - celix_stringHashMap_destroy(receiver->requestedConnections.map); - celixThreadMutex_destroy(&receiver->subscribers.mutex); - celixThreadMutex_destroy(&receiver->requestedConnections.mutex); - celixThreadMutex_destroy(&receiver->thread.mutex); - pubsubInterceptorsHandler_destroy(receiver->interceptorsHandler); - 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) { - - celix_bundleContext_stopTracker(receiver->ctx, receiver->subscriberTrackerId); - - celixThreadMutex_lock(&receiver->thread.mutex); - if (receiver->thread.running) { - receiver->thread.running = false; - celixThreadMutex_unlock(&receiver->thread.mutex); - celixThread_join(receiver->thread.thread, NULL); - } - - 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; - } - - celixThreadMutex_lock(&receiver->subscribers.mutex); - CELIX_LONG_HASH_MAP_ITERATE(receiver->subscribers.map, iter) { - free(iter.value.ptrValue); - } - celix_longHashMap_destroy(receiver->subscribers.map); - celixThreadMutex_unlock(&receiver->subscribers.mutex); - - celixThreadMutex_lock(&receiver->requestedConnections.mutex); - - CELIX_STRING_HASH_MAP_ITERATE(receiver->requestedConnections.map, iter) { - psa_tcp_requested_connection_entry_t *entry = iter.value.ptrValue; - if (entry != NULL) { - free(entry->url); - free(entry); - } - } - celix_stringHashMap_destroy(receiver->requestedConnections.map); - celixThreadMutex_unlock(&receiver->requestedConnections.mutex); - - celixThreadMutex_destroy(&receiver->subscribers.mutex); - celixThreadMutex_destroy(&receiver->requestedConnections.mutex); - celixThreadMutex_destroy(&receiver->thread.mutex); - - pubsubInterceptorsHandler_destroy(receiver->interceptorsHandler); - 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; -} - -const char *pubsub_tcpTopicReceiver_serializerType(pubsub_tcp_topic_receiver_t *receiver) { - return pubsub_serializerHandler_getSerializationType(receiver->serializerHandler); -} - -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 { - CELIX_STRING_HASH_MAP_ITERATE(receiver->requestedConnections.map, iter) { - psa_tcp_requested_connection_entry_t *entry = iter.value.ptrValue; - 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 = celix_stringHashMap_get(receiver->requestedConnections.map, url); - if (entry == NULL) { - entry = calloc(1, sizeof(*entry)); - entry->url = celix_utils_strdup(url); - entry->connected = false; - entry->statically = false; - entry->parent = receiver; - celix_stringHashMap_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 = celix_stringHashMap_get(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) { - celix_stringHashMap_remove(receiver->requestedConnections.map, url); - free(entry->url); - free(entry); - } - celixThreadMutex_unlock(&receiver->requestedConnections.mutex); -} - -static void pubsub_tcpTopicReceiver_addSubscriber(void *handle, void *svc, const celix_properties_t *props) { - pubsub_tcp_topic_receiver_t *receiver = handle; - - long svcId = celix_properties_getAsLong(props, CELIX_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; - } - - psa_tcp_subscriber_entry_t *entry = calloc(1, sizeof(*entry)); - entry->subscriberSvc = svc; - entry->initialized = false; - - celixThreadMutex_lock(&receiver->subscribers.mutex); - celix_longHashMap_put(receiver->subscribers.map, svcId, entry); - receiver->subscribers.allInitialized = false; - celixThreadMutex_unlock(&receiver->subscribers.mutex); -} - -static void pubsub_tcpTopicReceiver_removeSubscriber(void *handle, void *svc CELIX_UNUSED, const celix_properties_t *props) { - pubsub_tcp_topic_receiver_t *receiver = handle; - - long svcId = celix_properties_getAsLong(props, CELIX_FRAMEWORK_SERVICE_ID, -1); - - celixThreadMutex_lock(&receiver->subscribers.mutex); - psa_tcp_subscriber_entry_t *entry = celix_longHashMap_get(receiver->subscribers.map, svcId); - celix_longHashMap_remove(receiver->subscribers.map, svcId); - free(entry); - celixThreadMutex_unlock(&receiver->subscribers.mutex); -} - -static void callReceivers(pubsub_tcp_topic_receiver_t *receiver, const char* msgFqn, const pubsub_protocol_message_t *message, void** msg, bool* release, const celix_properties_t* metadata) { - *release = true; - celixThreadMutex_lock(&receiver->subscribers.mutex); - celix_long_hash_map_iterator_t iter = celix_longHashMap_begin(receiver->subscribers.map); - while(!celix_longHashMapIterator_isEnd(&iter)) { - psa_tcp_subscriber_entry_t* entry = iter.value.ptrValue; - celix_longHashMapIterator_next(&iter); - if (entry != NULL && entry->subscriberSvc->receive != NULL) { - entry->subscriberSvc->receive(entry->subscriberSvc->handle, msgFqn, message->header.msgId, *msg, metadata, release); - if (!(*release) && !celix_longHashMapIterator_isEnd(&iter)) { //receive function has taken ownership, deserialize again for new message - struct iovec deSerializeBuffer; - deSerializeBuffer.iov_base = message->payload.payload; - deSerializeBuffer.iov_len = message->payload.length; - celix_status_t status = pubsub_serializerHandler_deserialize(receiver->serializerHandler, - message->header.msgId, - message->header.msgMajorVersion, - message->header.msgMinorVersion, - &deSerializeBuffer, 0, msg); - if (status != CELIX_SUCCESS) { - L_WARN("[PSA_TCP_TR] Cannot deserialize msg type %s for scope/topic %s/%s", msgFqn, - receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic); - break; - } - } else if (!(*release)) { //receive function has taken ownership, but no receive left anymore. set msg to null - *msg = NULL; - } - *release = true; - } - } - celixThreadMutex_unlock(&receiver->subscribers.mutex); -} - -static inline void processMsg(void* handle, const pubsub_protocol_message_t *message, bool* releaseMsg, struct timespec *receiveTime) { - pubsub_tcp_topic_receiver_t *receiver = handle; - - const char *msgFqn = pubsub_serializerHandler_getMsgFqn(receiver->serializerHandler, message->header.msgId); - if (msgFqn == NULL) { - L_WARN("Cannot find msg fqn for msg id %u", message->header.msgId); - return; - } - void *deSerializedMsg = NULL; - bool validVersion = pubsub_serializerHandler_isMessageSupported(receiver->serializerHandler, message->header.msgId, - message->header.msgMajorVersion, - message->header.msgMinorVersion); - if (validVersion) { - struct iovec deSerializeBuffer; - deSerializeBuffer.iov_base = message->payload.payload; - deSerializeBuffer.iov_len = message->payload.length; - celix_status_t status = pubsub_serializerHandler_deserialize(receiver->serializerHandler, message->header.msgId, - message->header.msgMajorVersion, - message->header.msgMinorVersion, - &deSerializeBuffer, 0, &deSerializedMsg); - - // 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) { - celix_properties_t *metadata = message->metadata.metadata; - bool metadataWasNull = metadata == NULL; - bool cont = pubsubInterceptorHandler_invokePreReceive(receiver->interceptorsHandler, msgFqn, message->header.msgId, deSerializedMsg, &metadata); - bool release = true; - if (cont) { - callReceivers(receiver, msgFqn, message, &deSerializedMsg, &release, metadata); - if (pubsubInterceptorHandler_nrOfInterceptors(receiver->interceptorsHandler) > 0) { - if (deSerializedMsg == NULL) { //message deleted, but still need to call interceptors -> deserialize new message - release = true; - status = pubsub_serializerHandler_deserialize(receiver->serializerHandler, message->header.msgId, - message->header.msgMajorVersion, - message->header.msgMinorVersion, - &deSerializeBuffer, 0, &deSerializedMsg); - if (status != CELIX_SUCCESS) { - L_WARN("[PSA_TCP_TR] Cannot deserialize msg type %s for scope/topic %s/%s", msgFqn, - receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic); - } else { - pubsubInterceptorHandler_invokePostReceive(receiver->interceptorsHandler, msgFqn, message->header.msgId, deSerializedMsg, metadata); - } - } else { - pubsubInterceptorHandler_invokePostReceive(receiver->interceptorsHandler, msgFqn, message->header.msgId, deSerializedMsg, metadata); - } - } - } else { - L_TRACE("Skipping receive for msg type %s, based on pre receive interceptor result", msgFqn); - } - if (release) { - pubsub_serializerHandler_freeDeserializedMsg(receiver->serializerHandler, message->header.msgId, deSerializedMsg); - } - if (metadataWasNull) { - //note that if the metadata was created by the pubsubInterceptorHandler_invokePreReceive, this needs to be deallocated - celix_properties_destroy(metadata); - } - } else { - L_WARN("[PSA_TCP_TR] Cannot deserialize msg type %s for scope/topic %s/%s", msgFqn, - receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic); - } - } else { - L_WARN("[PSA_TCP_TR] Cannot deserialize message '%s' using %s, version mismatch. Version received: %i.%i.x, version local: %i.%i.x", - msgFqn, - pubsub_serializerHandler_getSerializationType(receiver->serializerHandler), - (int) message->header.msgMajorVersion, - (int) message->header.msgMinorVersion, - pubsub_serializerHandler_getMsgMajorVersion(receiver->serializerHandler, message->header.msgId), - pubsub_serializerHandler_getMsgMinorVersion(receiver->serializerHandler, message->header.msgId)); - } -} - -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; -} - -static void psa_tcp_connectToAllRequestedConnections(pubsub_tcp_topic_receiver_t *receiver) { - celixThreadMutex_lock(&receiver->requestedConnections.mutex); - if (!receiver->requestedConnections.allConnected) { - bool allConnected = true; - CELIX_STRING_HASH_MAP_ITERATE(receiver->requestedConnections.map, iter) { - psa_tcp_requested_connection_entry_t *entry = iter.value.ptrValue; - 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 = celix_stringHashMap_get(receiver->requestedConnections.map, url); - if (entry == NULL) { - entry = calloc(1, sizeof(*entry)); - entry->parent = receiver; - entry->url = celix_utils_strdup(url); - entry->statically = true; - celix_stringHashMap_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 = celix_stringHashMap_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; - CELIX_LONG_HASH_MAP_ITERATE(receiver->subscribers.map, iter) { - psa_tcp_subscriber_entry_t *entry = iter.value.ptrValue; - if (!entry->initialized) { - int rc = 0; - if (entry->subscriberSvc->init != NULL) { - rc = entry->subscriberSvc->init(entry->subscriberSvc->handle); - } - if (rc == 0) { - 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_tcp/src/pubsub_tcp_topic_receiver.h b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_receiver.h deleted file mode 100644 index 35c14c603..000000000 --- a/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_receiver.h +++ /dev/null @@ -1,56 +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" -#include "pubsub_serializer_handler.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, - pubsub_serializer_handler_t* serializerHandler, - void *admin, - const celix_properties_t *topicProperties, - pubsub_tcp_endPointStore_t *handlerStore, - 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); -const char *pubsub_tcpTopicReceiver_serializerType(pubsub_tcp_topic_receiver_t *sender); - -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); - -#endif //CELIX_PUBSUB_TCP_TOPIC_RECEIVER_H diff --git a/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_sender.c b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_sender.c deleted file mode 100644 index 7272af284..000000000 --- a/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_sender.c +++ /dev/null @@ -1,435 +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 -#include -#include -#include -#include -#include -#include -#include -#include "pubsub_psa_tcp_constants.h" -#include "pubsub_tcp_topic_sender.h" -#include "pubsub_tcp_handler.h" -#include "pubsub_tcp_common.h" -#include -#include "celix_compiler.h" -#include "celix_constants.h" -#include -#include "pubsub_interceptors_handler.h" -#include "pubsub_tcp_admin.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 protocolSvcId; - pubsub_protocol_service_t *protocol; - uuid_t fwUUID; - pubsub_tcpHandler_t *socketHandler; - pubsub_tcpHandler_t *sharedSocketHandler; - pubsub_interceptors_handler_t *interceptorsHandler; - pubsub_serializer_handler_t* serializerHandler; - - void *admin; - char *scope; - char *topic; - char *url; - bool isStatic; - bool isPassive; - bool verbose; - unsigned long send_delay; - int seqNr; //atomic - - 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_bounded_service_entry { - pubsub_tcp_topic_sender_t *parent; - pubsub_publisher_t service; - long bndId; - 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 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, - pubsub_serializer_handler_t* serializerHandler, - void *admin, - const celix_properties_t *topicProperties, - pubsub_tcp_endPointStore_t *handlerStore, - long protocolSvcId, - pubsub_protocol_service_t *protocol) { - pubsub_tcp_topic_sender_t *sender = calloc(1, sizeof(*sender)); - sender->ctx = ctx; - sender->logHelper = logHelper; - sender->serializerHandler = serializerHandler; - sender->admin = admin; - sender->protocolSvcId = protocolSvcId; - sender->protocol = protocol; - const char *uuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, NULL); - if (uuid != NULL) { - uuid_parse(uuid, sender->fwUUID); - } - sender->interceptorsHandler = pubsubInterceptorsHandler_create(ctx, scope, topic, PUBSUB_TCP_ADMIN_TYPE, - pubsub_serializerHandler_getSerializationType(serializerHandler)); - sender->isPassive = false; - 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); - // When 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); - free(entry); - } - hashMap_destroy(sender->boundedServices.map, false, false); - celixThreadMutex_unlock(&sender->boundedServices.mutex); - celixThreadMutex_destroy(&sender->boundedServices.mutex); - - pubsubInterceptorsHandler_destroy(sender->interceptorsHandler); - 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_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_serializerType(pubsub_tcp_topic_sender_t *sender) { - return pubsub_serializerHandler_getSerializationType(sender->serializerHandler); -} - -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; -} - -static void *psa_tcp_getPublisherService(void *handle, const celix_bundle_t *requestingBundle, - const celix_properties_t *svcProperties CELIX_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->service.handle = entry; - entry->service.localMsgTypeIdForMsgType = psa_tcp_localMsgTypeIdForMsgType; - entry->service.send = psa_tcp_topicPublicationSend; - hashMap_put(sender->boundedServices.map, (void *) bndId, entry); - } - 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 CELIX_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); - free(entry); - } - celixThreadMutex_unlock(&sender->boundedServices.mutex); - -} - -static int -psa_tcp_topicPublicationSend(void *handle, unsigned int msgTypeId, const void *inMsg, celix_properties_t *metadata) { - psa_tcp_bounded_service_entry_t *bound = handle; - pubsub_tcp_topic_sender_t *sender = bound->parent; - const char* msgFqn; - int majorVersion; - int minorVersion; - celix_status_t status = pubsub_serializerHandler_getMsgInfo(sender->serializerHandler, msgTypeId, &msgFqn, &majorVersion, &minorVersion); - - if (status != CELIX_SUCCESS) { - L_WARN("Cannot find serializer for msg id %u for serializer %s", msgTypeId, - pubsub_serializerHandler_getSerializationType(sender->serializerHandler)); - celix_properties_destroy(metadata); - return status; - } - - bool cont = pubsubInterceptorHandler_invokePreSend(sender->interceptorsHandler, msgFqn, msgTypeId, inMsg, &metadata); - if (!cont) { - L_DEBUG("Cancel send based on pubsub interceptor cancel return"); - celix_properties_destroy(metadata); - return status; - } - - size_t serializedIoVecOutputLen = 0; //entry->serializedIoVecOutputLen; - struct iovec *serializedIoVecOutput = NULL; - status = pubsub_serializerHandler_serialize(sender->serializerHandler, msgTypeId, inMsg, &serializedIoVecOutput, &serializedIoVecOutputLen); - if (status != CELIX_SUCCESS) { - L_WARN("[PSA_TCP_V2_TS] Error serialize message of type %s for scope/topic %s/%s", msgFqn, - sender->scope == NULL ? "(null)" : sender->scope, sender->topic); - celix_properties_destroy(metadata); - return status; - } - - 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 = __atomic_fetch_add(&sender->seqNr, 1, __ATOMIC_RELAXED); - message.header.msgMajorVersion = (uint16_t)majorVersion; - message.header.msgMinorVersion = (uint16_t)minorVersion; - message.header.payloadSize = 0; - message.header.payloadPartSize = 0; - message.header.payloadOffset = 0; - message.header.metadataSize = 0; - if (metadata != NULL) { - message.metadata.metadata = metadata; - } - bool sendOk = true; - { - int rc = pubsub_tcpHandler_write(sender->socketHandler, &message, serializedIoVecOutput, serializedIoVecOutputLen, 0); - if (rc < 0) { - status = -1; - sendOk = false; - } - pubsubInterceptorHandler_invokePostSend(sender->interceptorsHandler, msgFqn, msgTypeId, inMsg, metadata); - if (serializedIoVecOutput) { - pubsub_serializerHandler_freeSerializedMsg(sender->serializerHandler, msgTypeId, serializedIoVecOutput, serializedIoVecOutputLen); - serializedIoVecOutput = NULL; - } - } - - if (!sendOk) { - L_WARN("[PSA_TCP_V2_TS] Error sending msg. %s", strerror(errno)); - } - - celix_properties_destroy(metadata); - return status; -} - -static int psa_tcp_localMsgTypeIdForMsgType(void *handle, const char *msgType, unsigned int *msgTypeId) { - psa_tcp_bounded_service_entry_t* entry = handle; - uint32_t msgId = pubsub_serializerHandler_getMsgId(entry->parent->serializerHandler, msgType); - *msgTypeId = (unsigned int)msgId; - return 0; -} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_sender.h b/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_sender.h deleted file mode 100644 index 57b13a68f..000000000 --- a/bundles/pubsub/pubsub_admin_tcp/src/pubsub_tcp_topic_sender.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_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" -#include "pubsub_serializer_handler.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, - pubsub_serializer_handler_t* serializerHandler, - void *admin, - const celix_properties_t *topicProperties, - pubsub_tcp_endPointStore_t *handlerStore, - 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); -const char* pubsub_tcpTopicSender_serializerType(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); - -#endif //CELIX_PUBSUB_TCP_TOPIC_SENDER_H diff --git a/bundles/pubsub/pubsub_admin_websocket/CMakeLists.txt b/bundles/pubsub/pubsub_admin_websocket/CMakeLists.txt deleted file mode 100644 index 99a851254..000000000 --- a/bundles/pubsub/pubsub_admin_websocket/CMakeLists.txt +++ /dev/null @@ -1,44 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -celix_subproject(PUBSUB_PSA_WS "Build WebSocket PubSub Admin" ON) -if (PUBSUB_PSA_WS) - find_package(jansson REQUIRED) - find_package(libuuid REQUIRED) - - add_celix_bundle(celix_pubsub_admin_websocket - BUNDLE_SYMBOLICNAME "apache_celix_pubsub_admin_websocket" - VERSION "2.1.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 - ) - - target_link_libraries(celix_pubsub_admin_websocket PRIVATE Celix::log_helper Celix::http_admin_api) - target_link_libraries(celix_pubsub_admin_websocket PRIVATE Celix::pubsub_spi Celix::pubsub_utils) - target_link_libraries(celix_pubsub_admin_websocket PRIVATE Celix::shell_api libuuid::libuuid jansson::jansson) - target_include_directories(celix_pubsub_admin_websocket PRIVATE src) - celix_deprecated_utils_headers(celix_pubsub_admin_websocket) - celix_deprecated_framework_headers(celix_pubsub_admin_websocket) - - install_celix_bundle(celix_pubsub_admin_websocket EXPORT celix COMPONENT pubsub) - add_library(Celix::celix_pubsub_admin_websocket ALIAS celix_pubsub_admin_websocket) -endif (PUBSUB_PSA_WS) diff --git a/bundles/pubsub/pubsub_admin_websocket/src/psa_activator.c b/bundles/pubsub/pubsub_admin_websocket/src/psa_activator.c deleted file mode 100644 index 1d4c7ab20..000000000 --- a/bundles/pubsub/pubsub_admin_websocket/src/psa_activator.c +++ /dev/null @@ -1,100 +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 -#include - -#include "celix_api.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_v2"); - - act->admin = pubsub_websocketAdmin_create(ctx, act->logHelper); - celix_status_t status = act->admin != NULL ? CELIX_SUCCESS : CELIX_BUNDLE_EXCEPTION; - - //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/src/pubsub_psa_websocket_constants.h b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_psa_websocket_constants.h deleted file mode 100644 index 39870c148..000000000 --- a/bundles/pubsub/pubsub_admin_websocket/src/pubsub_psa_websocket_constants.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#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" - - -/* With this interval new connections and receivers are polled and registred. Similar to the TCP admin */ -#define PSA_WEBSOCKET_SUBSCRIBER_CONNECTION_TIMEOUT "PSA_WEBSOCKET_SUBSCRIBER_CONNECTION_TIMEOUT" -#define PSA_WEBSOCKET_SUBSCRIBER_CONNECTION_DEFAULT_TIMEOUT 250 // 250 ms -#define PSA_WEBSOCKET_SUBSCRIBER_CONNECTION_MIN_TIMEOUT 0 -#define PSA_WEBSOCKET_SUBSCRIBER_CONNECTION_MAX_TIMEOUT (UINT_MAX / 1000) - -/** - * 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/src/pubsub_websocket_admin.c b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_admin.c deleted file mode 100644 index 41b970461..000000000 --- a/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_admin.c +++ /dev/null @@ -1,533 +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 -#include - -#include "celix_compiler.h" -#include "pubsub_endpoint.h" -#include "pubsub_matching.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" -#include "pubsub_serializer_handler.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 = 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; - - struct { - celix_thread_mutex_t mutex; - hash_map_t *map; //key = pubsub message serialization marker svc id (long), pubsub_serialization_handler_t*. - } serializationHandlers; -}; - -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, CELIX_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->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->serializationHandlers.mutex, NULL); - psa->serializationHandlers.map = hashMap_create(NULL, NULL, NULL, NULL); - - return psa; -} - -void pubsub_websocketAdmin_destroy(pubsub_websocket_admin_t *psa) { - if (psa == NULL) { - return; - } - - //note assuming all 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->serializationHandlers.mutex); - iter = hashMapIterator_construct(psa->serializationHandlers.map); - while (hashMapIterator_hasNext(&iter)) { - pubsub_serializer_handler_t* entry = hashMapIterator_nextValue(&iter); - pubsub_serializerHandler_destroy(entry); - } - celixThreadMutex_unlock(&psa->serializationHandlers.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->serializationHandlers.mutex); - hashMap_destroy(psa->serializationHandlers.map, false, false); - - free(psa); -} - -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_V2] pubsub_websocketAdmin_matchPublisher"); - celix_status_t status = CELIX_SUCCESS; - double score = pubsub_utils_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_V2] pubsub_websocketAdmin_matchSubscriber"); - celix_status_t status = CELIX_SUCCESS; - double score = pubsub_utils_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_V2] pubsub_websocketAdmin_matchEndpoint"); - celix_status_t status = CELIX_SUCCESS; - bool match = pubsub_utils_matchEndpoint(psa->ctx, psa->log, endpoint, PUBSUB_WEBSOCKET_ADMIN_TYPE, false, NULL, NULL); - if (outMatch != NULL) { - *outMatch = match; - } - return status; -} - -static pubsub_serializer_handler_t* pubsub_websocketAdmin_getSerializationHandler(pubsub_websocket_admin_t* psa, long msgSerializationMarkerSvcId) { - pubsub_serializer_handler_t* handler = NULL; - celixThreadMutex_lock(&psa->serializationHandlers.mutex); - handler = hashMap_get(psa->serializationHandlers.map, (void*)msgSerializationMarkerSvcId); - if (handler == NULL) { - handler = pubsub_serializerHandler_createForMarkerService(psa->ctx, msgSerializationMarkerSvcId, psa->log); - if (handler != NULL) { - hashMap_put(psa->serializationHandlers.map, (void*)msgSerializationMarkerSvcId, handler); - } - } - celixThreadMutex_unlock(&psa->serializationHandlers.mutex); - return handler; -} - - -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) Get serialization handler - //2) Create TopicSender - //3) Store TopicSender - //4) Connect existing endpoints - //5) set outPublisherEndpoint - - pubsub_serializer_handler_t* handler = pubsub_websocketAdmin_getSerializationHandler(psa, serializerSvcId); - if (handler == NULL) { - L_ERROR("Cannot create topic sender without serialization handler"); - return CELIX_ILLEGAL_STATE; - } - - celix_properties_t *newEndpoint = NULL; - - char *key = pubsubEndpoint_createScopeTopicKey(scope, topic); - - celixThreadMutex_lock(&psa->topicSenders.mutex); - pubsub_websocket_topic_sender_t *sender = hashMap_get(psa->topicSenders.map, key); - if (sender == NULL) { - sender = pubsub_websocketTopicSender_create(psa->ctx, psa->log, scope, topic, handler, psa); - if (sender != NULL) { - const char *psaType = PUBSUB_WEBSOCKET_ADMIN_TYPE; - newEndpoint = pubsubEndpoint_create(psa->fwUUID, scope, topic, PUBSUB_PUBLISHER_ENDPOINT_TYPE, psaType, - pubsub_serializerHandler_getSerializationType(handler), 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_V2] Error creating a TopicSender"); - free(key); - } - } else { - free(key); - L_ERROR("[PSA_WEBSOCKET_V2] Cannot setup already existing TopicSender for scope/topic %s/%s!", scope == NULL ? "(null)" : scope, topic); - } - celixThreadMutex_unlock(&psa->topicSenders.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_V2] 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; - - pubsub_serializer_handler_t* handler = pubsub_websocketAdmin_getSerializationHandler(psa, serializerSvcId); - if (handler == NULL) { - L_ERROR("Cannot create topic receiver without serialization handler"); - return CELIX_ILLEGAL_STATE; - } - - - char *key = pubsubEndpoint_createScopeTopicKey(scope, topic); - celixThreadMutex_lock(&psa->topicReceivers.mutex); - pubsub_websocket_topic_receiver_t *receiver = hashMap_get(psa->topicReceivers.map, key); - if (receiver == NULL) { - receiver = pubsub_websocketTopicReceiver_create(psa->ctx, psa->log, scope, topic, topicProperties, handler, psa); - if (receiver != NULL) { - const char *psaType = PUBSUB_WEBSOCKET_ADMIN_TYPE; - newEndpoint = pubsubEndpoint_create(psa->fwUUID, scope, topic, - PUBSUB_SUBSCRIBER_ENDPOINT_TYPE, psaType, - pubsub_serializerHandler_getSerializationType(handler), 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_V2] Error creating a TopicReceiver."); - free(key); - } - } else { - free(key); - L_ERROR("[PSA_WEBSOCKET_V2] Cannot setup already existing TopicReceiver for scope/topic %s/%s!", scope == NULL ? "(null)" : scope, topic); - } - celixThreadMutex_unlock(&psa->topicReceivers.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:"); - CELIX_PROPERTIES_ITERATE(endpoint, iter) { - L_WARN("[PSA WEBSOCKET] |- %s=%s\n", iter.key, iter.entry.value); - } - 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:"); - CELIX_PROPERTIES_ITERATE(endpoint, iter) { - L_WARN("[PSA WEBSOCKET] |- %s=%s\n", iter.key, iter.entry.value); - } - 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 CELIX_UNUSED, FILE *out, FILE *errStream CELIX_UNUSED) { - pubsub_websocket_admin_t *psa = handle; - - fprintf(out, "\n"); - fprintf(out, "Topic Senders:\n"); - 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); - const char *serType = pubsub_websocketTopicSender_serializerType(sender); - 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); - - fprintf(out, "\n"); - fprintf(out, "\nTopic Receivers:\n"); - celixThreadMutex_lock(&psa->topicReceivers.mutex); - iter = hashMapIterator_construct(psa->topicReceivers.map); - while (hashMapIterator_hasNext(&iter)) { - pubsub_websocket_topic_receiver_t *receiver = hashMapIterator_nextValue(&iter); - const char *serType = pubsub_websocketTopicReceiver_serializerType(receiver); - 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); - fprintf(out, "\n"); - - return true; -} diff --git a/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_admin.h b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_admin.h deleted file mode 100644 index 960c26676..000000000 --- a/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_admin.h +++ /dev/null @@ -1,64 +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 -#include -#include "celix_api.h" -#include "celix_log_helper.h" -#include "pubsub_psa_websocket_constants.h" -#include - -typedef struct pubsub_websocket_admin pubsub_websocket_admin_t; - -typedef struct psa_websocket_serializer_entry { - const char *fqn; - const char *version; - pubsub_message_serialization_service_t *svc; -} psa_websocket_serializer_entry_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); - -psa_websocket_serializer_entry_t* pubsub_websocketAdmin_acquireSerializerForMessageId(void *handle, const char *serializationType, uint32_t msgId); -void pubsub_websocketAdmin_releaseSerializer(void *handle, psa_websocket_serializer_entry_t* serializer); -int64_t pubsub_websocketAdmin_getMessageIdForMessageFqn(void *handle, const char *serializationType, const char *fqn); - -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/src/pubsub_websocket_common.c b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_common.c deleted file mode 100644 index fe389bc31..000000000 --- a/bundles/pubsub/pubsub_admin_websocket/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 -#include -#include -#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/src/pubsub_websocket_common.h b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_common.h deleted file mode 100644 index 8a764d126..000000000 --- a/bundles/pubsub/pubsub_admin_websocket/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 -#include - -#include "version.h" - - -struct pubsub_websocket_msg_header { - const char *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/src/pubsub_websocket_topic_receiver.c b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_receiver.c deleted file mode 100644 index 93bfe3a43..000000000 --- a/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_receiver.c +++ /dev/null @@ -1,733 +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 -#include -#include -#include -#include -#include -#include -#include -#include "celix_compiler.h" -#include -#include -#include -#include "pubsub_websocket_topic_receiver.h" -#include "pubsub_psa_websocket_constants.h" -#include "pubsub_websocket_common.h" -#include "pubsub_websocket_admin.h" - -#include -#include -#include -#include -#include -#include "pubsub_interceptors_handler.h" - -#ifndef UUID_STR_LEN -#define UUID_STR_LEN 37 -#endif - -#define L_TRACE(...) \ - celix_logHelper_log(receiver->logHelper, CELIX_LOG_LEVEL_DEBUG, __VA_ARGS__) -#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_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; - void *admin; - useconds_t timeoutUs; - - char *scope; - char *topic; - char scopeAndTopicFilter[5]; - char *uri; - - pubsub_serializer_handler_t* serializerHandler; - pubsub_interceptors_handler_t *interceptorsHandler; - - celix_websocket_service_t sockSvc; - long svcId; - - 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 = long svc 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 { - pubsub_subscriber_t* subscriberSvc; - 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); -static void pubsub_websocketTopicReceiver_removeSubscriber(void *handle, void *svc, const celix_properties_t *props); -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_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, - pubsub_serializer_handler_t* serializerHandler, - void *admin) { - pubsub_websocket_topic_receiver_t *receiver = calloc(1, sizeof(*receiver)); - receiver->ctx = ctx; - receiver->logHelper = logHelper; - receiver->serializerHandler = serializerHandler; - receiver->interceptorsHandler = pubsubInterceptorsHandler_create(ctx, scope, topic, PUBSUB_WEBSOCKET_ADMIN_TYPE, - pubsub_serializerHandler_getSerializationType(serializerHandler)); - receiver->scope = scope == NULL ? NULL : strndup(scope, 1024 * 1024); - receiver->topic = strndup(topic, 1024 * 1024); - receiver->admin = admin; - psa_websocket_setScopeAndTopicFilter(scope, topic, receiver->scopeAndTopicFilter); - - receiver->uri = psa_websocket_createURI(scope, topic); - - long timeoutMs = celix_bundleContext_getPropertyAsLong(ctx, PSA_WEBSOCKET_SUBSCRIBER_CONNECTION_TIMEOUT, - PSA_WEBSOCKET_SUBSCRIBER_CONNECTION_DEFAULT_TIMEOUT); - receiver->timeoutUs = (useconds_t)(( - ( - (timeoutMs < PSA_WEBSOCKET_SUBSCRIBER_CONNECTION_MIN_TIMEOUT) - || (timeoutMs > PSA_WEBSOCKET_SUBSCRIBER_CONNECTION_MAX_TIMEOUT) - ) // Protect against under and overflow - ? PSA_WEBSOCKET_SUBSCRIBER_CONNECTION_DEFAULT_TIMEOUT // Use default for excessive values - : timeoutMs) - * 1000); - - if (receiver->uri != 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); - } - - //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.serviceName = PUBSUB_SUBSCRIBER_SERVICE_NAME; - opts.filter.filter = buf; - opts.callbackHandle = receiver; - opts.addWithProperties = pubsub_websocketTopicReceiver_addSubscriber; - opts.removeWithProperties = 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); - hashMap_destroy(receiver->subscribers.map, false, true); - - - celixThreadMutex_unlock(&receiver->subscribers.mutex); - - 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); - 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); - - pubsubInterceptorsHandler_destroy(receiver->interceptorsHandler); - - 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; -} - -const char *pubsub_websocketTopicReceiver_serializerType(pubsub_websocket_topic_receiver_t *receiver) { - return pubsub_serializerHandler_getSerializationType(receiver->serializerHandler); -} - -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:%ld", 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) { - pubsub_websocket_topic_receiver_t *receiver = handle; - - long svcId = celix_properties_getAsLong(props, CELIX_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; - } - - psa_websocket_subscriber_entry_t* entry = calloc(1, sizeof(*entry)); - entry->subscriberSvc = svc; - entry->initialized = false; - - celixThreadMutex_lock(&receiver->subscribers.mutex); - hashMap_put(receiver->subscribers.map, (void*)svcId, entry); - receiver->subscribers.allInitialized = false; - celixThreadMutex_unlock(&receiver->subscribers.mutex); -} - -static void pubsub_websocketTopicReceiver_removeSubscriber(void *handle, void *svc CELIX_UNUSED, const celix_properties_t *props) { - pubsub_websocket_topic_receiver_t *receiver = handle; - - long svcId = celix_properties_getAsLong(props, CELIX_FRAMEWORK_SERVICE_ID, -1); - - celixThreadMutex_lock(&receiver->subscribers.mutex); - psa_websocket_subscriber_entry_t *entry = hashMap_remove(receiver->subscribers.map, (void*)svcId); - free(entry); - celixThreadMutex_unlock(&receiver->subscribers.mutex); -} - -static void callReceivers( - pubsub_websocket_topic_receiver_t *receiver, - uint32_t msgId, - const pubsub_websocket_msg_header_t* header, - const char *payload, - size_t payloadSize, - void** msg, - bool* release, - const celix_properties_t* metadata) { - *release = true; - 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 && entry->subscriberSvc->receive != NULL) { - entry->subscriberSvc->receive(entry->subscriberSvc->handle, header->fqn, msgId, *msg, metadata, release); - if (!(*release)) { - //receive function has taken ownership, deserialize again for new message - struct iovec deSerializeBuffer; - deSerializeBuffer.iov_base = (void*) payload; - deSerializeBuffer.iov_len = payloadSize; - celix_status_t status = pubsub_serializerHandler_deserialize(receiver->serializerHandler, - msgId, - header->major, - header->minor, - &deSerializeBuffer, 0, msg); - if (status != CELIX_SUCCESS) { - L_WARN("[PSA_WEBSOCKET_TR] Cannot deserialize msg type %s for scope/topic %s/%s", header->fqn, - receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic); - break; - } - } - *release = true; - } - } - celixThreadMutex_unlock(&receiver->subscribers.mutex); -} - -static void processJsonMsg(pubsub_websocket_topic_receiver_t *receiver, const pubsub_websocket_msg_header_t* header, const char *payload, size_t payloadSize) { - uint32_t msgId = pubsub_serializerHandler_getMsgId(receiver->serializerHandler, header->fqn); - if (msgId == 0) { - L_WARN("Cannot find msg id for msg fqn %s", header->fqn); - return; - } - - void *deserializedMsg = NULL; - bool validVersion = pubsub_serializerHandler_isMessageSupported(receiver->serializerHandler, msgId, header->major, header->minor); - if (validVersion) { - struct iovec deSerializeBuffer; - deSerializeBuffer.iov_base = (void*)payload; - deSerializeBuffer.iov_len = payloadSize; - celix_status_t status = pubsub_serializerHandler_deserialize(receiver->serializerHandler, msgId, - header->major, - header->minor, - &deSerializeBuffer, 0, &deserializedMsg); - if (status == CELIX_SUCCESS) { - celix_properties_t *metadata = NULL; //NOTE metadata not supported for websocket - bool cont = pubsubInterceptorHandler_invokePreReceive(receiver->interceptorsHandler, header->fqn, msgId, - deserializedMsg, &metadata); - bool release = true; - if (cont) { - callReceivers(receiver, msgId, header, payload, payloadSize, &deserializedMsg, &release, metadata); - pubsubInterceptorHandler_invokePostReceive(receiver->interceptorsHandler, header->fqn, msgId, deserializedMsg, metadata); - } else { - L_TRACE("Skipping receive for msg type %s, based on pre receive interceptor result", header->fqn); - } - if (release) { - pubsub_serializerHandler_freeDeserializedMsg(receiver->serializerHandler, msgId, deserializedMsg); - } - celix_properties_destroy(metadata); - } else { - L_WARN("[PSA_WEBSOCKET_TR] Cannot deserialize msg type %s for scope/topic %s/%s", header->fqn, receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic); - } - } else { - L_WARN("[PSA_WEBSOCKET_TR] Cannot deserialize message '%s' using %s, version mismatch. Version received: %i.%i.x, version local: %i.%i.x", - header->fqn, - pubsub_serializerHandler_getSerializationType(receiver->serializerHandler), - (int) header->major, - (int) header->minor, - pubsub_serializerHandler_getMsgMajorVersion(receiver->serializerHandler, msgId), - pubsub_serializerHandler_getMsgMinorVersion(receiver->serializerHandler, msgId)); - } -} - -static 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"); //NOTE called id, but is the msgFqn - 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.fqn = 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); - char *payload = json_dumps(jsData, 0); - size_t payloadSize = strlen(payload); - L_TRACE("Received msg: fqn %s\tmajor %u\tminor %u\tseqNr %u\tdata %s\n", hdr.fqn, hdr.major, hdr.minor, hdr.seqNr, payload); - processJsonMsg(receiver, &hdr, payload, payloadSize); - free(payload); - } else { - L_WARN("[PSA_WEBSOCKET_TR] Received unsupported message: " - "ID = %s, major = %"JSON_INTEGER_FORMAT", minor = %"JSON_INTEGER_FORMAT", seqNr = %"JSON_INTEGER_FORMAT", 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); - } -} - -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); - } - usleep(receiver->timeoutUs); - - - 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, 48); - 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 CELIX_UNUSED, - int op_code CELIX_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; - processMsg(receiver, data, length); - } - - 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) { - int rc = 0; - if (entry->subscriberSvc != NULL && entry->subscriberSvc->init != NULL) { - rc = entry->subscriberSvc->init(entry->subscriberSvc->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/src/pubsub_websocket_topic_receiver.h b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_receiver.h deleted file mode 100644 index f5edda564..000000000 --- a/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_receiver.h +++ /dev/null @@ -1,48 +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" -#include "pubsub_serializer_handler.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, - pubsub_serializer_handler_t* serializerHandler, - void *admin); -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); -const char *pubsub_websocketTopicReceiver_serializerType(pubsub_websocket_topic_receiver_t *sender); - -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/src/pubsub_websocket_topic_sender.c b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_sender.c deleted file mode 100644 index f8fe5a5e9..000000000 --- a/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_sender.c +++ /dev/null @@ -1,330 +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 -#include -#include -#include -#include -#include -#include "pubsub_websocket_topic_sender.h" -#include "pubsub_psa_websocket_constants.h" -#include "pubsub_websocket_common.h" -#include -#include "celix_compiler.h" -#include "celix_constants.h" -#include "http_admin/api.h" -#include "civetweb.h" -#include "pubsub_websocket_admin.h" -#include "pubsub_interceptors_handler.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; - - void *admin; - char *scope; - char *topic; - char scopeAndTopicFilter[5]; - char *uri; - - pubsub_serializer_handler_t* serializerHandler; - pubsub_interceptors_handler_t *interceptorsHandler; - - int seqNr; //atomic - - 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_bounded_service_entry { - pubsub_websocket_topic_sender_t *parent; - pubsub_publisher_t service; - long bndId; - int getCount; -} psa_websocket_bounded_service_entry_t; - -static int psa_websocket_localMsgTypeIdForMsgType(void* handle CELIX_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 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, - pubsub_serializer_handler_t* serializerHandler, - void *admin) { - pubsub_websocket_topic_sender_t *sender = calloc(1, sizeof(*sender)); - sender->ctx = ctx; - sender->logHelper = logHelper; - sender->serializerHandler = serializerHandler; - sender->interceptorsHandler = pubsubInterceptorsHandler_create(ctx, scope, topic, PUBSUB_WEBSOCKET_ADMIN_TYPE, pubsub_serializerHandler_getSerializationType(serializerHandler)); - - psa_websocket_setScopeAndTopicFilter(scope, topic, sender->scopeAndTopicFilter); - sender->uri = psa_websocket_createURI(scope, topic); - sender->admin = admin; - - 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); - 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); - } - pubsubInterceptorsHandler_destroy(sender->interceptorsHandler); - free(sender->topic); - free(sender->uri); - free(sender); - } -} - -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; -} - -const char* pubsub_websocketTopicSender_serializerType(pubsub_websocket_topic_sender_t *sender) { - return pubsub_serializerHandler_getSerializationType(sender->serializerHandler); -} - -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; - uint32_t msgId = pubsub_serializerHandler_getMsgId(entry->parent->serializerHandler, msgType); - if (msgId != 0) { - *msgTypeId = msgId; - return 0; - } - return -1; -} - -static void* psa_websocket_getPublisherService(void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties CELIX_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->service.handle = entry; - entry->service.localMsgTypeIdForMsgType = psa_websocket_localMsgTypeIdForMsgType; - entry->service.send = psa_websocket_topicPublicationSend; - hashMap_put(sender->boundedServices.map, (void *) bndId, entry); - } - 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 CELIX_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); - free(entry); - } - celixThreadMutex_unlock(&sender->boundedServices.mutex); -} - -static int psa_websocket_topicPublicationSend(void* handle, unsigned int msgTypeId, const void *inMsg, celix_properties_t *metadata) { - psa_websocket_bounded_service_entry_t *bound = handle; - pubsub_websocket_topic_sender_t *sender = bound->parent; - - const char* msgFqn; - int majorVersion; - int minorVersion; - celix_status_t status = pubsub_serializerHandler_getMsgInfo(sender->serializerHandler, msgTypeId, &msgFqn, &majorVersion, &minorVersion); - if (status != CELIX_SUCCESS) { - L_WARN("Cannot find serializer for msg id %u for serializer %s", msgTypeId, pubsub_serializerHandler_getSerializationType(sender->serializerHandler)); - celix_properties_destroy(metadata); - return status; - } - - bool cont = pubsubInterceptorHandler_invokePreSend(sender->interceptorsHandler, msgFqn, msgTypeId, inMsg, &metadata); - if (!cont) { - L_DEBUG("Cancel send based on pubsub interceptor cancel return"); - celix_properties_destroy(metadata); - return status; - } - - if (sender->sockConnection != NULL) { - size_t serializedOutputLen = 0; - struct iovec* serializedOutput = NULL; - status = pubsub_serializerHandler_serialize(sender->serializerHandler, msgTypeId, inMsg, &serializedOutput, &serializedOutputLen); - if (status == CELIX_SUCCESS /*ser ok*/) { - json_error_t jsError; - - json_t *jsMsg = json_object(); - json_object_set_new_nocheck(jsMsg, "id", json_string(msgFqn)); - json_object_set_new_nocheck(jsMsg, "major", json_integer(majorVersion)); - json_object_set_new_nocheck(jsMsg, "minor", json_integer(minorVersion)); - uint32_t seqNr = __atomic_fetch_add(&sender->seqNr, 1, __ATOMIC_RELAXED); - json_object_set_new_nocheck(jsMsg, "seqNr", json_integer(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 %zu 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); - } - - json_decref(jsMsg); //Decrease ref count means freeing the object - pubsub_serializerHandler_freeSerializedMsg(sender->serializerHandler, msgTypeId, serializedOutput, serializedOutputLen); - } else { - L_WARN("[PSA_WEBSOCKET_TS] Error serialize message of type %u 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 - } - - pubsubInterceptorHandler_invokePostSend(sender->interceptorsHandler, msgFqn, msgTypeId, inMsg, metadata); - celix_properties_destroy(metadata); - 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 CELIX_UNUSED, void *handle) { - //Connection closed so reset connection - pubsub_websocket_topic_sender_t *sender = (pubsub_websocket_topic_sender_t *) handle; - sender->sockConnection = NULL; -} diff --git a/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_sender.h b/bundles/pubsub/pubsub_admin_websocket/src/pubsub_websocket_topic_sender.h deleted file mode 100644 index 6b42500f9..000000000 --- a/bundles/pubsub/pubsub_admin_websocket/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" -#include "pubsub_serializer_handler.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, - pubsub_serializer_handler_t* serializerHandler, - void *admin); -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); -const char *pubsub_websocketTopicSender_serializerType(pubsub_websocket_topic_sender_t *sender); - -#endif //CELIX_PUBSUB_WEBSOCKET_TOPIC_SENDER_H diff --git a/bundles/pubsub/pubsub_admin_zmq/CMakeLists.txt b/bundles/pubsub/pubsub_admin_zmq/CMakeLists.txt deleted file mode 100644 index f14f38bc6..000000000 --- a/bundles/pubsub/pubsub_admin_zmq/CMakeLists.txt +++ /dev/null @@ -1,58 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -celix_subproject(PUBSUB_PSA_ZMQ "Build ZeroMQ PubSub Admin (LGPL License)" ON) -if (PUBSUB_PSA_ZMQ) - find_package(ZeroMQ REQUIRED) - find_package(czmq REQUIRED) - find_package(libuuid REQUIRED) - - set(OPTIONAL_OPENSSL_LIB ) - # FIXME: ZMQ_SECURITY doesn't compile now - option(BUILD_ZMQ_SECURITY "Build with security for ZeroMQ." OFF) - 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 "2.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} - ) - - target_link_libraries(celix_pubsub_admin_zmq PRIVATE - Celix::log_helper libzmq czmq libuuid::libuuid ${OPTIONAL_OPENSSL_LIB}) - target_link_libraries(celix_pubsub_admin_zmq PRIVATE Celix::shell_api) - target_link_libraries(celix_pubsub_admin_zmq PRIVATE Celix::pubsub_spi Celix::pubsub_utils) - target_include_directories(celix_pubsub_admin_zmq PRIVATE src) - celix_deprecated_utils_headers(celix_pubsub_admin_zmq) - celix_deprecated_framework_headers(celix_pubsub_admin_zmq) - install_celix_bundle(celix_pubsub_admin_zmq EXPORT celix COMPONENT pubsub) - add_library(Celix::celix_pubsub_admin_zmq ALIAS celix_pubsub_admin_zmq) -endif (PUBSUB_PSA_ZMQ) diff --git a/bundles/pubsub/pubsub_admin_zmq/src/psa_activator.c b/bundles/pubsub/pubsub_admin_zmq/src/psa_activator.c deleted file mode 100644 index dfd9429eb..000000000 --- a/bundles/pubsub/pubsub_admin_zmq/src/psa_activator.c +++ /dev/null @@ -1,115 +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 -#include - -#include "celix_bundle_activator.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; - - 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_v2"); - - act->admin = pubsub_zmqAdmin_create(ctx, act->logHelper); - celix_status_t status = act->admin != NULL ? CELIX_SUCCESS : CELIX_BUNDLE_EXCEPTION; - - //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.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); - } - - //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_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/src/pubsub_psa_zmq_constants.h b/bundles/pubsub/pubsub_admin_zmq/src/pubsub_psa_zmq_constants.h deleted file mode 100644 index 7f1d89188..000000000 --- a/bundles/pubsub/pubsub_admin_zmq/src/pubsub_psa_zmq_constants.h +++ /dev/null @@ -1,108 +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_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/src/pubsub_zmq_admin.c b/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_admin.c deleted file mode 100644 index 7b101b80c..000000000 --- a/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_admin.c +++ /dev/null @@ -1,799 +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 -#include -#include -#include -#include -#include -#include -#include - -#include "celix_compiler.h" -#include "pubsub_serializer_handler.h" -#include "pubsub_endpoint.h" -#include "pubsub_protocol.h" -#include "pubsub_matching.h" -#include "pubsub_utils.h" -#include "pubsub_message_serialization_service.h" -#include "pubsub_message_serialization_marker.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_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; - - struct { - celix_thread_mutex_t mutex; - hash_map_t *map; //key = pubsub message serialization marker svc id (long), pubsub_serialization_handler_t*. - } serializationHandlers; -}; - -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 pubsub_serializer_handler_t* pubsub_zmqAdmin_getSerializationHandler(pubsub_zmq_admin_t* psa, long msgSerializationMarkerSvcId); - -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, CELIX_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 = strdup(PUBSUB_ZMQ_DEFAULT_IP); - } - - 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 %ld threads for ZMQ", 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->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->serializationHandlers.mutex, NULL); - psa->serializationHandlers.map = hashMap_create(NULL, NULL, NULL, 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->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_lock(&psa->serializationHandlers.mutex); - iter = hashMapIterator_construct(psa->serializationHandlers.map); - while (hashMapIterator_hasNext(&iter)) { - pubsub_serializer_handler_t* entry = hashMapIterator_nextValue(&iter); - pubsub_serializerHandler_destroy(entry); - } - celixThreadMutex_unlock(&psa->serializationHandlers.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->protocols.mutex); - hashMap_destroy(psa->protocols.map, false, false); - - celixThreadMutex_destroy(&psa->serializationHandlers.mutex); - hashMap_destroy(psa->serializationHandlers.map, false, false); - - if (psa->zmq_auth != NULL) { - zactor_destroy(&psa->zmq_auth); - } - - free(psa->ipAddress); - - free(psa); -} - -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, CELIX_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, CELIX_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 *receiverEntry = hashMapIterator_nextEntry(&iter); - pubsub_zmq_topic_receiver_t *receiver = hashMapEntry_getValue(receiverEntry); - if (receiver != NULL && entry->svcId == pubsub_zmqTopicReceiver_protocolSvcId(receiver)) { - char *key = hashMapEntry_getKey(receiverEntry); - 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 = pubsub_utils_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 = pubsub_utils_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 = pubsub_utils_matchEndpoint(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) Get serialization handler - //2) Create TopicSender - //3) Store TopicSender - //4) Connect existing endpoints - //5) set outPublisherEndpoint - - pubsub_serializer_handler_t* handler = pubsub_zmqAdmin_getSerializationHandler(psa, serializerSvcId); - if (handler == NULL) { - L_ERROR("Cannot create topic sender without serialization handler"); - return CELIX_ILLEGAL_STATE; - } - - 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->protocols.mutex); - celixThreadMutex_lock(&psa->topicSenders.mutex); - pubsub_zmq_topic_sender_t *sender = hashMap_get(psa->topicSenders.map, key); - celixThreadMutex_unlock(&psa->topicSenders.mutex); - if (sender == NULL) { - psa_zmq_protocol_entry_t *protEntry = hashMap_get(psa->protocols.map, (void*)protocolSvcId); - if (protEntry != NULL) { - sender = pubsub_zmqTopicSender_create(psa->ctx, psa->log, scope, topic, handler, handle, - protocolSvcId, protEntry->svc, psa->ipAddress, staticBindUrl, psa->basePort, psa->maxPort); - } - if (sender != NULL) { - const char *psaType = PUBSUB_ZMQ_ADMIN_TYPE; - const char *protType = protEntry->protType; - newEndpoint = pubsubEndpoint_create(psa->fwUUID, scope, topic, PUBSUB_PUBLISHER_ENDPOINT_TYPE, psaType, - pubsub_zmqTopicSender_serializerType(sender), 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); - } - celixThreadMutex_lock(&psa->topicSenders.mutex); - hashMap_put(psa->topicSenders.map, key, sender); - celixThreadMutex_unlock(&psa->topicSenders.mutex); - } 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->protocols.mutex); - - 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); - celixThreadMutex_unlock(&psa->topicSenders.mutex); - free(mapKey); - pubsub_zmqTopicSender_destroy(sender); - } else { - celixThreadMutex_unlock(&psa->topicSenders.mutex); - L_ERROR("[PSA ZMQ] Cannot teardown TopicSender with scope/topic %s/%s. Does not exists", scope == NULL ? "(null)" : scope, topic); - } - 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 CELIX_UNUSED, long protocolSvcId, celix_properties_t **outSubscriberEndpoint) { - pubsub_zmq_admin_t *psa = handle; - celix_properties_t *newEndpoint = NULL; - - pubsub_serializer_handler_t* handler = pubsub_zmqAdmin_getSerializationHandler(psa, serializerSvcId); - if (handler == NULL) { - L_ERROR("Cannot create topic receiver without serialization handler"); - return CELIX_ILLEGAL_STATE; - } - - char *key = pubsubEndpoint_createScopeTopicKey(scope, topic); - - celixThreadMutex_lock(&psa->protocols.mutex); - celixThreadMutex_lock(&psa->topicReceivers.mutex); - pubsub_zmq_topic_receiver_t *receiver = hashMap_get(psa->topicReceivers.map, key); - celixThreadMutex_unlock(&psa->topicReceivers.mutex); - if (receiver == NULL) { - psa_zmq_protocol_entry_t *protEntry = hashMap_get(psa->protocols.map, (void*)protocolSvcId); - if (protEntry != NULL) { - receiver = pubsub_zmqTopicReceiver_create(psa->ctx, psa->log, scope, topic, topicProperties, handler, handle, 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 *protType = protEntry->protType; - newEndpoint = pubsubEndpoint_create(psa->fwUUID, scope, topic, - PUBSUB_SUBSCRIBER_ENDPOINT_TYPE, psaType, - pubsub_zmqTopicReceiver_serializerType(receiver), 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); - } - celixThreadMutex_lock(&psa->topicReceivers.mutex); - hashMap_put(psa->topicReceivers.map, key, receiver); - celixThreadMutex_unlock(&psa->topicReceivers.mutex); - } 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->protocols.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); - if (entry != NULL) { - char *receiverKey = hashMapEntry_getKey(entry); - pubsub_zmq_topic_receiver_t *receiver = hashMapEntry_getValue(entry); - hashMap_remove(psa->topicReceivers.map, receiverKey); - celixThreadMutex_unlock(&psa->topicReceivers.mutex); - - free(receiverKey); - pubsub_zmqTopicReceiver_destroy(receiver); - } else { - celixThreadMutex_unlock(&psa->topicReceivers.mutex); - } - free(key); - - 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); - } - - celix_properties_t *cpy = celix_properties_copy(endpoint); - const char *uuid = celix_properties_get(cpy, PUBSUB_ENDPOINT_UUID, NULL); - - celixThreadMutex_lock(&psa->discoveredEndpoints.mutex); - 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 CELIX_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->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); - - const char *serType = pubsub_zmqTopicSender_serializerType(sender); - - long protSvcId = pubsub_zmqTopicSender_protocolSvcId(sender); - psa_zmq_protocol_entry_t *protEntry = hashMap_get(psa->protocols.map, (void*)protSvcId); - - 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); - - fprintf(out, "\n"); - fprintf(out, "\nTopic Receivers:\n"); - 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); - const char *serType = pubsub_zmqTopicReceiver_serializerType(receiver); - - long protSvcId = pubsub_zmqTopicReceiver_protocolSvcId(receiver); - psa_zmq_protocol_entry_t *protEntry = hashMap_get(psa->protocols.map, (void*)protSvcId); - - 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); - fprintf(out, "\n"); - free(line); - - return status; -} - -static pubsub_serializer_handler_t* pubsub_zmqAdmin_getSerializationHandler(pubsub_zmq_admin_t* psa, long msgSerializationMarkerSvcId) { - pubsub_serializer_handler_t* handler = NULL; - celixThreadMutex_lock(&psa->serializationHandlers.mutex); - handler = hashMap_get(psa->serializationHandlers.map, (void*)msgSerializationMarkerSvcId); - if (handler == NULL) { - handler = pubsub_serializerHandler_createForMarkerService(psa->ctx, msgSerializationMarkerSvcId, psa->log); - if (handler != NULL) { - hashMap_put(psa->serializationHandlers.map, (void*)msgSerializationMarkerSvcId, handler); - } - } - celixThreadMutex_unlock(&psa->serializationHandlers.mutex); - return handler; -} - -#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 diff --git a/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_admin.h b/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_admin.h deleted file mode 100644 index 6a8ba9742..000000000 --- a/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_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_ZMQ_ADMIN_H -#define CELIX_PUBSUB_ZMQ_ADMIN_H - -#include -#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_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); - -#endif //CELIX_PUBSUB_ZMQ_ADMIN_H - diff --git a/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_receiver.c b/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_receiver.c deleted file mode 100644 index 97debaaea..000000000 --- a/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_receiver.c +++ /dev/null @@ -1,710 +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 -#include -#include -#include -#include -#if !defined(__APPLE__) - #include -#endif - -#include -#include -#include -#include - -#include "pubsub_endpoint.h" -#include "celix_log_helper.h" -#include "pubsub_zmq_topic_receiver.h" -#include "pubsub_psa_zmq_constants.h" -#include "pubsub_admin_metrics.h" -#include "pubsub_utils.h" -#include "celix_api.h" -#include "celix_version.h" -#include "pubsub_serializer_handler.h" -#include "pubsub_interceptors_handler.h" -#include "celix_utils_api.h" -#include "pubsub_zmq_admin.h" - -#define PSA_ZMQ_RECV_TIMEOUT 1000 - -#ifndef UUID_STR_LEN -#define UUID_STR_LEN 37 -#endif - -#define L_TRACE(...) \ - celix_logHelper_log(receiver->logHelper, CELIX_LOG_LEVEL_TRACE, __VA_ARGS__) -#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; - void *admin; - long protocolSvcId; - pubsub_protocol_service_t *protocol; - char *scope; - char *topic; - - pubsub_serializer_handler_t* serializerHandler; - pubsub_interceptors_handler_t *interceptorsHandler; - - 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 = long svc 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_entry { - pubsub_subscriber_t* subscriberSvc; - 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); -static void pubsub_zmqTopicReceiver_removeSubscriber(void *handle, void *svc, const celix_properties_t *props); -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); - - -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, - pubsub_serializer_handler_t* serHandler, - void *admin, - long protocolSvcId, - pubsub_protocol_service_t *protocol) { - pubsub_zmq_topic_receiver_t *receiver = calloc(1, sizeof(*receiver)); - receiver->ctx = ctx; - receiver->logHelper = logHelper; - receiver->serializerHandler = serHandler; - receiver->admin = admin; - receiver->protocolSvcId = protocolSvcId; - receiver->protocol = protocol; - receiver->scope = scope == NULL ? NULL : celix_utils_strdup(scope); - receiver->topic = celix_utils_strdup(topic); - - receiver->interceptorsHandler = pubsubInterceptorsHandler_create(ctx, scope, topic, PUBSUB_ZMQ_ADMIN_TYPE, - pubsub_serializerHandler_getSerializationType(serHandler)); - -#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 = celix_utils_strdup(staticConnectUrls); - 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 = celix_utils_strdup(url); - 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.serviceName = PUBSUB_SUBSCRIBER_SERVICE_NAME; - opts.filter.filter = buf; - opts.callbackHandle = receiver; - opts.addWithProperties = pubsub_zmqTopicReceiver_addSubscriber; - opts.removeWithProperties = 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); - hashMap_destroy(receiver->subscribers.map, false, true); - celixThreadMutex_unlock(&receiver->subscribers.mutex); - - 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); - 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); - - pubsubInterceptorsHandler_destroy(receiver->interceptorsHandler); - - 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; -} - -const char* pubsub_zmqTopicReceiver_serializerType(pubsub_zmq_topic_receiver_t *receiver) { - return pubsub_serializerHandler_getSerializationType(receiver->serializerHandler); -} - -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 = celix_utils_strdup(url); - 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) { - pubsub_zmq_topic_receiver_t *receiver = handle; - - long svcId = celix_properties_getAsLong(props, CELIX_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; - } - - psa_zmq_subscriber_entry_t *entry = calloc(1, sizeof(*entry)); - entry->subscriberSvc = svc; - entry->initialized = false; - - celixThreadMutex_lock(&receiver->subscribers.mutex); - hashMap_put(receiver->subscribers.map, (void*)svcId, entry); - receiver->subscribers.allInitialized = false; - celixThreadMutex_unlock(&receiver->subscribers.mutex); -} - -static void pubsub_zmqTopicReceiver_removeSubscriber(void *handle, void *svc, const celix_properties_t *props) { - pubsub_zmq_topic_receiver_t *receiver = handle; - - long svcId = celix_properties_getAsLong(props, CELIX_FRAMEWORK_SERVICE_ID, -1); - - celixThreadMutex_lock(&receiver->subscribers.mutex); - psa_zmq_subscriber_entry_t *entry = hashMap_remove(receiver->subscribers.map, (void*)svcId); - free(entry); - celixThreadMutex_unlock(&receiver->subscribers.mutex); -} - -static void callReceivers(pubsub_zmq_topic_receiver_t *receiver, const char* msgFqn, const pubsub_protocol_message_t *message, void** msg, bool* release, const celix_properties_t* metadata) { - *release = true; - 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 && entry->subscriberSvc->receive != NULL) { - entry->subscriberSvc->receive(entry->subscriberSvc->handle, msgFqn, message->header.msgId, *msg, metadata, release); - if (!(*release)) { - //receive function has taken ownership, deserialize again for new message - struct iovec deSerializeBuffer; - deSerializeBuffer.iov_base = message->payload.payload; - deSerializeBuffer.iov_len = message->payload.length; - celix_status_t status = pubsub_serializerHandler_deserialize(receiver->serializerHandler, - message->header.msgId, - message->header.msgMajorVersion, - message->header.msgMinorVersion, - &deSerializeBuffer, 0, msg); - if (status != CELIX_SUCCESS) { - L_WARN("[PSA_ZMQ_TR] Cannot deserialize msg type %s for scope/topic %s/%s", msgFqn, - receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic); - break; - } - } - *release = true; - } - } - celixThreadMutex_unlock(&receiver->subscribers.mutex); -} - -static inline void processMsg(pubsub_zmq_topic_receiver_t *receiver, pubsub_protocol_message_t *message, struct timespec *receiveTime) { - const char *msgFqn = pubsub_serializerHandler_getMsgFqn(receiver->serializerHandler, message->header.msgId); - if (msgFqn == NULL) { - L_WARN("Cannot find msg fqn for msg id %u", message->header.msgId); - return; - } - void *deserializedMsg = NULL; - bool validVersion = pubsub_serializerHandler_isMessageSupported(receiver->serializerHandler, message->header.msgId, - message->header.msgMajorVersion, - message->header.msgMinorVersion); - if (validVersion) { - struct iovec deSerializeBuffer; - deSerializeBuffer.iov_base = message->payload.payload; - deSerializeBuffer.iov_len = message->payload.length; - celix_status_t status = pubsub_serializerHandler_deserialize(receiver->serializerHandler, message->header.msgId, - message->header.msgMajorVersion, - message->header.msgMinorVersion, - &deSerializeBuffer, 0, &deserializedMsg); - if (status == CELIX_SUCCESS) { - celix_properties_t *metadata = message->metadata.metadata; - bool metadataWasNull = metadata == NULL; - bool cont = pubsubInterceptorHandler_invokePreReceive(receiver->interceptorsHandler, msgFqn, message->header.msgId, deserializedMsg, &metadata); - bool release = true; - if (cont) { - callReceivers(receiver, msgFqn, message, &deserializedMsg, &release, metadata); - pubsubInterceptorHandler_invokePostReceive(receiver->interceptorsHandler, msgFqn, message->header.msgId, deserializedMsg, metadata); - } else { - L_TRACE("Skipping receive for msg type %s, based on pre receive interceptor result", msgFqn); - } - if (release) { - pubsub_serializerHandler_freeDeserializedMsg(receiver->serializerHandler, message->header.msgId, deserializedMsg); - } - if (metadataWasNull) { - //note that if the metadata was created by the pubsubInterceptorHandler_invokePreReceive, this needs to be deallocated - celix_properties_destroy(metadata); - } - } else { - L_WARN("[PSA_ZMQ_TR] Cannot deserialize msg type %s for scope/topic %s/%s", msgFqn, - receiver->scope == NULL ? "(null)" : receiver->scope, receiver->topic); - } - } else { - L_WARN("[PSA_ZMQ_TR] Cannot deserialize message '%s' using %s, version mismatch. Version received: %i.%i.x, version local: %i.%i.x", - msgFqn, - pubsub_serializerHandler_getSerializationType(receiver->serializerHandler), - (int) message->header.msgMajorVersion, - (int) message->header.msgMinorVersion, - pubsub_serializerHandler_getMsgMajorVersion(receiver->serializerHandler, message->header.msgId), - pubsub_serializerHandler_getMsgMinorVersion(receiver->serializerHandler, message->header.msgId)); - } -} - -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; -} - - -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) { - int rc = 0; - if (entry->subscriberSvc != NULL && entry->subscriberSvc->init != NULL) { - rc = entry->subscriberSvc->init(entry->subscriberSvc->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 -} diff --git a/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_receiver.h b/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_receiver.h deleted file mode 100644 index f47ce3702..000000000 --- a/bundles/pubsub/pubsub_admin_zmq/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 "pubsub_message_serialization_service.h" -#include "celix_bundle_context.h" -#include "pubsub_serializer_handler.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, - pubsub_serializer_handler_t* serializerHandler, - void *admin, - 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); - -const char* pubsub_zmqTopicReceiver_serializerType(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); - - - -#endif //CELIX_PUBSUB_ZMQ_TOPIC_RECEIVER_H diff --git a/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_sender.c b/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_sender.c deleted file mode 100644 index a8ff08f3f..000000000 --- a/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_sender.c +++ /dev/null @@ -1,559 +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 -#include -#include -#include -#include -#include - -#include "celix_compiler.h" -#include "celix_utils.h" -#include "pubsub_constants.h" -#include "pubsub/publisher.h" -#include "celix_log_helper.h" -#include "pubsub_zmq_topic_sender.h" -#include "pubsub_psa_zmq_constants.h" -#include "celix_version.h" -#include "pubsub_serializer_handler.h" -#include "celix_constants.h" -#include "pubsub_interceptors_handler.h" -#include "pubsub_zmq_admin.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; - void *admin; - long protocolSvcId; - pubsub_protocol_service_t *protocol; - uuid_t fwUUID; - bool zeroCopyEnabled; - - pubsub_serializer_handler_t* serializerHandler; - pubsub_interceptors_handler_t *interceptorsHandler; - - char *scope; - char *topic; - char *url; - bool isStatic; - - long seqNr; //atomic - - struct { - bool dataLock; //atomic, protects below and protect zmq internal data - void *headerBuffer; - size_t headerBufferSize; - void *metadataBuffer; - size_t metadataBufferSize; - void *footerBuffer; - size_t footerBufferSize; - } zmqBuffers; - - 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_bounded_service_entry { - pubsub_zmq_topic_sender_t *parent; - pubsub_publisher_t service; - long bndId; - int getCount; -} psa_zmq_bounded_service_entry_t; - -typedef struct psa_zmq_zerocopy_free_entry { - uint32_t msgId; - pubsub_serializer_handler_t *serHandler; - 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 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, - pubsub_serializer_handler_t* serializerHandler, - void *admin, - 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->serializerHandler = serializerHandler; - sender->admin = admin; - sender->protocolSvcId = protocolSvcId; - sender->protocol = prot; - const char* uuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, NULL); - if (uuid != NULL) { - uuid_parse(uuid, sender->fwUUID); - } - sender->zeroCopyEnabled = celix_bundleContext_getPropertyAsBool(ctx, PSA_ZMQ_ZEROCOPY_ENABLED, PSA_ZMQ_DEFAULT_ZEROCOPY_ENABLED); - - sender->interceptorsHandler = pubsubInterceptorsHandler_create(ctx, scope, topic, PUBSUB_ZMQ_ADMIN_TYPE, - pubsub_serializerHandler_getSerializationType(serializerHandler)); - - //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 = celix_utils_strdup(staticBindUrl); - 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 : celix_utils_strdup(scope); - sender->topic = celix_utils_strdup(topic); - - 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; -} - -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); - hashMap_destroy(sender->boundedServices.map, false, true); - celixThreadMutex_unlock(&sender->boundedServices.mutex); - - celixThreadMutex_destroy(&sender->boundedServices.mutex); - - pubsubInterceptorsHandler_destroy(sender->interceptorsHandler); - - if (sender->scope != NULL) { - free(sender->scope); - } - free(sender->topic); - free(sender->url); - free(sender->zmqBuffers.headerBuffer); - free(sender->zmqBuffers.metadataBuffer); - free(sender->zmqBuffers.footerBuffer); - free(sender); - } -} - -const char* pubsub_zmqTopicSender_serializerType(pubsub_zmq_topic_sender_t *sender) { - return pubsub_serializerHandler_getSerializationType(sender->serializerHandler); -} - -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; -} - -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 = pubsub_serializerHandler_getMsgId(entry->parent->serializerHandler, msgType); - return 0; -} - -static void* psa_zmq_getPublisherService(void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties CELIX_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->service.handle = entry; - entry->service.localMsgTypeIdForMsgType = psa_zmq_localMsgTypeIdForMsgType; - entry->service.send = psa_zmq_topicPublicationSend; - hashMap_put(sender->boundedServices.map, (void*)bndId, entry); - } - 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 CELIX_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); - free(entry); - } - celixThreadMutex_unlock(&sender->boundedServices.mutex); -} - -static void psa_zmq_freeMsg(void *msg, void *hint) { - psa_zmq_zerocopy_free_entry *entry = hint; - pubsub_serializerHandler_freeSerializedMsg(entry->serHandler, entry->msgId, entry->serializedOutput, entry->serializedOutputLen); - free(entry); -} - -static int psa_zmq_topicPublicationSend(void* handle, unsigned int msgTypeId, const void *inMsg, celix_properties_t *metadata) { - psa_zmq_bounded_service_entry_t *bound = handle; - pubsub_zmq_topic_sender_t *sender = bound->parent; - - const char* msgFqn; - int majorVersion; - int minorversion; - celix_status_t status = pubsub_serializerHandler_getMsgInfo(sender->serializerHandler, msgTypeId, &msgFqn, &majorVersion, &minorversion); - if (status != CELIX_SUCCESS) { - L_WARN("Cannot find serializer for msg id %u for serializer %s", msgTypeId, pubsub_serializerHandler_getSerializationType(sender->serializerHandler)); - celix_properties_destroy(metadata); - return status; - } - - bool cont = pubsubInterceptorHandler_invokePreSend(sender->interceptorsHandler, msgFqn, msgTypeId, inMsg, &metadata); - if (!cont) { - L_DEBUG("Cancel send based on pubsub interceptor cancel return"); - celix_properties_destroy(metadata); - return status; - } - - size_t serializedIoVecOutputLen = 0; //entry->serializedIoVecOutputLen; - struct iovec *serializedIoVecOutput = NULL; - status = pubsub_serializerHandler_serialize(sender->serializerHandler, msgTypeId, inMsg, &serializedIoVecOutput, &serializedIoVecOutputLen); - - if (status != CELIX_SUCCESS /*serialization not ok*/) { - L_WARN("[PSA_ZMQ_TS] Error serialize message of type %s for scope/topic %s/%s", msgFqn, sender->scope == NULL ? "(null)" : sender->scope, sender->topic); - celix_properties_destroy(metadata); - return status; - } - - // Some ZMQ functions are not thread-safe, but this atomic compare exchange ensures one access at a time. - // Also protect sender->zmqBuffers (header, meta and footer) - bool expected = false; - while(!__atomic_compare_exchange_n(&sender->zmqBuffers.dataLock, &expected, true, false, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) { - expected = false; - usleep(5); - } - - pubsub_protocol_message_t message; - message.payload.payload = serializedIoVecOutput->iov_base; - message.payload.length = serializedIoVecOutput->iov_len; - message.header.convertEndianess = 0; - - void *payloadData = NULL; - size_t payloadLength = 0; - sender->protocol->encodePayload(sender->protocol->handle, &message, &payloadData, &payloadLength); - - size_t metadataSize = 0; - if (metadata != NULL) { - message.metadata.metadata = metadata; - sender->protocol->encodeMetadata(sender->protocol->handle, &message, &sender->zmqBuffers.metadataBuffer, &sender->zmqBuffers.metadataBufferSize, &metadataSize); - } else { - message.metadata.metadata = NULL; - } - - sender->protocol->encodeFooter(sender->protocol->handle, &message, &sender->zmqBuffers.footerBuffer, &sender->zmqBuffers.footerBufferSize); - - message.header.msgId = msgTypeId; - message.header.seqNr = __atomic_fetch_add(&sender->seqNr, 1, __ATOMIC_RELAXED); - message.header.msgMajorVersion = majorVersion; - message.header.msgMinorVersion = minorversion; - message.header.payloadSize = payloadLength; - message.header.metadataSize = metadataSize; - message.header.payloadPartSize = payloadLength; - message.header.payloadOffset = 0; - message.header.isLastSegment = 1; - - sender->protocol->encodeHeader(sender->protocol->handle, &message, &sender->zmqBuffers.headerBuffer, &sender->zmqBuffers.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)); //NOTE should be improved. Not really zero copy - freeMsgEntry->serHandler = sender->serializerHandler; - freeMsgEntry->msgId = msgTypeId; - freeMsgEntry->serializedOutput = serializedIoVecOutput; - freeMsgEntry->serializedOutputLen = serializedIoVecOutputLen; - - zmq_msg_init_data(&msg1, sender->zmqBuffers.headerBuffer, sender->zmqBuffers.headerBufferSize, NULL, NULL); - //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 = ((metadataSize > 0) || (sender->zmqBuffers.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 && metadataSize > 0) { - int flag = (sender->zmqBuffers.footerBufferSize > 0 ) ? ZMQ_SNDMORE : 0; - zmq_msg_init_data(&msg3, sender->zmqBuffers.metadataBuffer, metadataSize, 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 && sender->zmqBuffers.footerBufferSize > 0) { - zmq_msg_init_data(&msg4, sender->zmqBuffers.footerBuffer, sender->zmqBuffers.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, sender->zmqBuffers.headerBuffer, sender->zmqBuffers.headerBufferSize); - zmsg_addmem(msg, payloadData, payloadLength); - if (metadataSize > 0) { - zmsg_addmem(msg, sender->zmqBuffers.metadataBuffer, metadataSize); - } - if (sender->zmqBuffers.footerBufferSize > 0) { - zmsg_addmem(msg, sender->zmqBuffers.footerBuffer, sender->zmqBuffers.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(&sender->zmqBuffers.dataLock, false, __ATOMIC_RELEASE); - pubsubInterceptorHandler_invokePostSend(sender->interceptorsHandler, msgFqn, msgTypeId, inMsg, metadata); - - if (!bound->parent->zeroCopyEnabled && serializedIoVecOutput) { - pubsub_serializerHandler_freeSerializedMsg(sender->serializerHandler, msgTypeId, serializedIoVecOutput, serializedIoVecOutputLen); - } - - if (!sendOk) { - L_WARN("[PSA_ZMQ_TS] Error sending zmg. %s", strerror(errno)); - } - - celix_properties_destroy(metadata); - return status; -} - -static unsigned int rand_range(unsigned int min, unsigned int max) { - double scaled = ((double)random())/((double)RAND_MAX); - return (unsigned int)((max-min+1)*scaled + min); -} diff --git a/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_sender.h b/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_sender.h deleted file mode 100644 index bb49a2aad..000000000 --- a/bundles/pubsub/pubsub_admin_zmq/src/pubsub_zmq_topic_sender.h +++ /dev/null @@ -1,55 +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_SENDER_H -#define CELIX_PUBSUB_ZMQ_TOPIC_SENDER_H - -#include "pubsub_serializer_handler.h" -#include "celix_bundle_context.h" -#include "pubsub_admin_metrics.h" -#include "celix_log_helper.h" - -typedef struct pubsub_zmq_topic_sender pubsub_zmq_topic_sender_t; - -pubsub_zmq_topic_sender_t* pubsub_zmqTopicSender_create( - celix_bundle_context_t *ctx, - celix_log_helper_t *logHelper, - const char *scope, - const char *topic, - pubsub_serializer_handler_t* serializerHandler, - void *admin, - long protocolSvcId, - pubsub_protocol_service_t *prot, - const char *bindIP, - const char *staticBindUrl, - unsigned int basePort, - unsigned int maxPort); - -void pubsub_zmqTopicSender_destroy(pubsub_zmq_topic_sender_t *sender); - -const char* pubsub_zmqTopicSender_scope(pubsub_zmq_topic_sender_t *sender); -const char* pubsub_zmqTopicSender_topic(pubsub_zmq_topic_sender_t *sender); -const char* pubsub_zmqTopicSender_url(pubsub_zmq_topic_sender_t *sender); -bool pubsub_zmqTopicSender_isStatic(pubsub_zmq_topic_sender_t *sender); - -const char* pubsub_zmqTopicSender_serializerType(pubsub_zmq_topic_sender_t *sender); -long pubsub_zmqTopicSender_protocolSvcId(pubsub_zmq_topic_sender_t *sender); - - -#endif //CELIX_PUBSUB_ZMQ_TOPIC_SENDER_H diff --git a/bundles/pubsub/pubsub_admin_zmq/src/zmq_crypto.c b/bundles/pubsub/pubsub_admin_zmq/src/zmq_crypto.c deleted file mode 100644 index a28501f94..000000000 --- a/bundles/pubsub/pubsub_admin_zmq/src/zmq_crypto.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -/** - * zmq_crypto.c - * - * \date Dec 2, 2016 - * \author Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - -#include "zmq_crypto.h" - -#include -#include -#include -#include - -#include - -#define MAX_FILE_PATH_LENGTH 512 -#define ZMQ_KEY_LENGTH 40 -#define AES_KEY_LENGTH 32 -#define AES_IV_LENGTH 16 - -#define KEY_TO_GET "aes_key" -#define IV_TO_GET "aes_iv" - -static char* read_file_content(char* filePath, char* fileName); -static void parse_key_lines(char *keysBuffer, char **key, char **iv); -static void parse_key_line(char *line, char **key, char **iv); -static void extract_keys_from_buffer(unsigned char *input, int inputlen, char **publicKey, char **secretKey); - -/** - * Return a valid zcert_t from an encoded file - * Caller is responsible for freeing by calling zcert_destroy(zcert** cert); - */ -zcert_t* get_zcert_from_encoded_file(char* keysFilePath, char* keysFileName, char* file_path) { - - if (keysFilePath == NULL) { - keysFilePath = DEFAULT_KEYS_FILE_PATH; - } - - if (keysFileName == NULL) { - keysFileName = DEFAULT_KEYS_FILE_NAME; - } - - char* keys_data = read_file_content(keysFilePath, keysFileName); - if (keys_data == NULL) { - return NULL; - } - - char *key = NULL; - char *iv = NULL; - parse_key_lines(keys_data, &key, &iv); - free(keys_data); - - if (key == NULL || iv == NULL) { - free(key); - free(iv); - - printf("CRYPTO: Loading AES key and/or AES iv failed!\n"); - return NULL; - } - - //At this point, we know an aes key and iv are stored and loaded - - // generate sha256 hashes - unsigned char key_digest[EVP_MAX_MD_SIZE]; - unsigned char iv_digest[EVP_MAX_MD_SIZE]; - generate_sha256_hash((char*) key, key_digest); - generate_sha256_hash((char*) iv, iv_digest); - - zchunk_t *encoded_secret = zchunk_slurp(file_path, 0); - if (encoded_secret == NULL) { - free(key); - free(iv); - - return NULL; - } - - int encoded_secret_size = (int) zchunk_size(encoded_secret); - char *encoded_secret_data = zchunk_strdup(encoded_secret); - zchunk_destroy(&encoded_secret); - - // Decryption of data - int decryptedtext_len; - unsigned char decryptedtext[encoded_secret_size]; - decryptedtext_len = decrypt((unsigned char *) encoded_secret_data, encoded_secret_size, key_digest, iv_digest, decryptedtext); - decryptedtext[decryptedtext_len] = '\0'; - - EVP_cleanup(); - - free(encoded_secret_data); - free(key); - free(iv); - - // The public and private keys are retrieved - char *public_text = NULL; - char *secret_text = NULL; - - extract_keys_from_buffer(decryptedtext, decryptedtext_len, &public_text, &secret_text); - - byte public_key [32] = { 0 }; - byte secret_key [32] = { 0 }; - - zmq_z85_decode(public_key, public_text); - zmq_z85_decode(secret_key, secret_text); - - zcert_t *cert_loaded = zcert_new_from(public_key, secret_key); - - free(public_text); - free(secret_text); - - return cert_loaded; -} - -int generate_sha256_hash(char* text, unsigned char* digest) { - unsigned int digest_len; - - EVP_MD_CTX *mdctx = EVP_MD_CTX_new(); - EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL); - EVP_DigestUpdate(mdctx, text, strlen(text)); - EVP_DigestFinal_ex(mdctx, digest, &digest_len); - EVP_MD_CTX_free(mdctx); - - return digest_len; -} - -int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext) { - int len; - int plaintext_len; - - EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); - - EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv); - EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len); - plaintext_len = len; - EVP_DecryptFinal_ex(ctx, plaintext + len, &len); - plaintext_len += len; - - EVP_CIPHER_CTX_free(ctx); - - return plaintext_len; -} - -/** - * Caller is responsible for freeing the returned value - */ -static char* read_file_content(char* filePath, char* fileName) { - - char fileNameWithPath[MAX_FILE_PATH_LENGTH]; - snprintf(fileNameWithPath, MAX_FILE_PATH_LENGTH, "%s/%s", filePath, fileName); - int rc = 0; - - if (!zsys_file_exists(fileNameWithPath)) { - printf("CRYPTO: Keys file '%s' doesn't exist!\n", fileNameWithPath); - return NULL; - } - - zfile_t *keys_file = zfile_new (filePath, fileName); - rc = zfile_input (keys_file); - if (rc != 0) { - zfile_destroy(&keys_file); - printf("CRYPTO: Keys file '%s' not readable!\n", fileNameWithPath); - return NULL; - } - - ssize_t keys_file_size = zsys_file_size (fileNameWithPath); - zchunk_t *keys_chunk = zfile_read (keys_file, keys_file_size, 0); - if (keys_chunk == NULL) { - zfile_close(keys_file); - zfile_destroy(&keys_file); - printf("CRYPTO: Can't read file '%s'!\n", fileNameWithPath); - return NULL; - } - - char *keys_data = zchunk_strdup(keys_chunk); - zchunk_destroy(&keys_chunk); - zfile_close(keys_file); - zfile_destroy (&keys_file); - - return keys_data; -} - -static void parse_key_lines(char *keysBuffer, char **key, char **iv) { - char *line = NULL, *saveLinePointer = NULL; - - bool firstTime = true; - do { - if (firstTime) { - line = strtok_r(keysBuffer, "\n", &saveLinePointer); - firstTime = false; - } else { - line = strtok_r(NULL, "\n", &saveLinePointer); - } - - if (line == NULL) { - break; - } - - parse_key_line(line, key, iv); - - } while ((*key == NULL || *iv == NULL) && line != NULL); - -} - -static void parse_key_line(char *line, char **key, char **iv) { - char *detectedKey = NULL, *detectedValue= NULL; - - char *sep_at = strchr(line, ':'); - if (sep_at == NULL) { - return; - } - - *sep_at = '\0'; // overwrite first separator, creating two strings. - detectedKey = line; - detectedValue = sep_at + 1; - - if (detectedKey == NULL || detectedValue == NULL) { - return; - } - if (detectedKey[0] == '\0' || detectedValue[0] == '\0') { - return; - } - - if (*key == NULL && strcmp(detectedKey, KEY_TO_GET) == 0) { - *key = strndup(detectedValue, AES_KEY_LENGTH); - } else if (*iv == NULL && strcmp(detectedKey, IV_TO_GET) == 0) { - *iv = strndup(detectedValue, AES_IV_LENGTH); - } -} - -static void extract_keys_from_buffer(unsigned char *input, int inputlen, char **publicKey, char **secretKey) { - // Load decrypted text buffer - zchunk_t *secret_decrypted = zchunk_new(input, inputlen); - if (secret_decrypted == NULL) { - printf("CRYPTO: Failed to create zchunk\n"); - return; - } - - zconfig_t *secret_config = zconfig_chunk_load(secret_decrypted); - zchunk_destroy (&secret_decrypted); - if (secret_config == NULL) { - printf("CRYPTO: Failed to create zconfig\n"); - return; - } - - // Extract public and secret key from text buffer - char *public_text = zconfig_get(secret_config, "/curve/public-key", NULL); - char *secret_text = zconfig_get(secret_config, "/curve/secret-key", NULL); - - if (public_text == NULL || secret_text == NULL) { - zconfig_destroy(&secret_config); - printf("CRYPTO: Loading public / secret key from text-buffer failed!\n"); - return; - } - - *publicKey = strndup(public_text, ZMQ_KEY_LENGTH + 1); - *secretKey = strndup(secret_text, ZMQ_KEY_LENGTH + 1); - - zconfig_destroy(&secret_config); -} diff --git a/bundles/pubsub/pubsub_admin_zmq/src/zmq_crypto.h b/bundles/pubsub/pubsub_admin_zmq/src/zmq_crypto.h deleted file mode 100644 index 03527cbf8..000000000 --- a/bundles/pubsub/pubsub_admin_zmq/src/zmq_crypto.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -/** - * zmq_crypto.h - * - * \date Dec 2, 2016 - * \author Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - -#ifndef ZMQ_CRYPTO_H_ -#define ZMQ_CRYPTO_H_ - -#include - -#define PROPERTY_KEYS_FILE_PATH "keys.file.path" -#define PROPERTY_KEYS_FILE_NAME "keys.file.name" -#define DEFAULT_KEYS_FILE_PATH "/etc/" -#define DEFAULT_KEYS_FILE_NAME "pubsub.keys" - -zcert_t* get_zcert_from_encoded_file(char* keysFilePath, char* keysFileName, char* file_path); -int generate_sha256_hash(char* text, unsigned char* digest); -int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext); - -#endif diff --git a/bundles/pubsub/pubsub_api/CMakeLists.txt b/bundles/pubsub/pubsub_api/CMakeLists.txt deleted file mode 100644 index 14facae8f..000000000 --- a/bundles/pubsub/pubsub_api/CMakeLists.txt +++ /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. - -#api target -add_library(pubsub_api INTERFACE) - -target_include_directories(pubsub_api INTERFACE - $ -) -target_link_libraries(pubsub_api INTERFACE Celix::utils) - -#install api -install(TARGETS pubsub_api EXPORT celix DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT pubsub - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/celix/pubsub) -install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/celix/pubsub COMPONENT pubsub) - -#Setup target aliases to match external usage -add_library(Celix::pubsub_api ALIAS pubsub_api) - diff --git a/bundles/pubsub/pubsub_api/include/pubsub/api.h b/bundles/pubsub/pubsub_api/include/pubsub/api.h deleted file mode 100644 index 08a2a9d06..000000000 --- a/bundles/pubsub/pubsub_api/include/pubsub/api.h +++ /dev/null @@ -1,28 +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_API_H_ -#define __PUBSUB_API_H_ - - -#include "pubsub/publisher.h" -#include "pubsub/subscriber.h" - - -#endif // __PUBSUB_API_H_ diff --git a/bundles/pubsub/pubsub_api/include/pubsub/publisher.h b/bundles/pubsub/pubsub_api/include/pubsub/publisher.h deleted file mode 100644 index 68eb839d5..000000000 --- a/bundles/pubsub/pubsub_api/include/pubsub/publisher.h +++ /dev/null @@ -1,78 +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_PUBLISHER_H_ -#define __PUBSUB_PUBLISHER_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include "celix_properties.h" - -#define PUBSUB_PUBLISHER_SERVICE_NAME "pubsub.publisher" -#define PUBSUB_PUBLISHER_SERVICE_VERSION "3.0.0" - -//properties -#define PUBSUB_PUBLISHER_TOPIC "topic" -#define PUBSUB_PUBLISHER_SCOPE "scope" -#define PUBSUB_PUBLISHER_CONFIG "pubsub.config" - -struct pubsub_publisher { - void *handle; - - /** - * Every msg is identifiable by msg type string. Because msg type string are performance wise not preferable (string compares), - * a "local" (int / platform dependent) unique id will be generated runtime - * with use of a distributed key/value store or communication between participation parties. - * this is called the local message type id. This local message type id can be requested with the localMsgIdForMsgType method. - * When return is successful the msgTypeId is always greater than 0. (Note this can be used to specify/detect uninitialized msg type ids in the consumer code). - * - * @param handle The publisher handle. - * @param msgType The fully qualified type name. - * @param msgTypeId Output argument for the local type id, how this is calculated/created is up to the pubsub admin. - * @return Returns 0 on success. - */ - int (*localMsgTypeIdForMsgType)(void *handle, const char *msgType, unsigned int *msgTypeId); - - /** - * send block until the message is either copied or serialized. - * Whether the message is already provided to the network layer or whether send through the network is up to the pubsubadmins. - * If and how meta data is handled can be different between pubsubadmins. - * - * Caller keeps ownership of the provided msg and can safely free the msg when the send function returns. - * Callee will take ownership of the metadata. - * - * @param handle The publisher handle. - * @param msgTypeId The local type id. Is used to find the correct message serializer and to identify the message on the wire. - * @param msg The message to send. - * @param metadata The meta data to send along with this message. Can be NULL. - * @return Returns 0 on success. - */ - int (*send)(void *handle, unsigned int msgTypeId, const void *msg, celix_properties_t *metadata); - -}; -typedef struct pubsub_publisher pubsub_publisher_t; - -#ifdef __cplusplus -} -#endif -#endif // __PUBSUB_PUBLISHER_H_ diff --git a/bundles/pubsub/pubsub_api/include/pubsub/subscriber.h b/bundles/pubsub/pubsub_api/include/pubsub/subscriber.h deleted file mode 100644 index ccc62e4fc..000000000 --- a/bundles/pubsub/pubsub_api/include/pubsub/subscriber.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 __PUBSUB_SUBSCRIBER_H_ -#define __PUBSUB_SUBSCRIBER_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include "celix_properties.h" - -#define PUBSUB_SUBSCRIBER_SERVICE_NAME "pubsub.subscriber" -#define PUBSUB_SUBSCRIBER_SERVICE_VERSION "3.0.0" - -//properties -#define PUBSUB_SUBSCRIBER_TOPIC "topic" -#define PUBSUB_SUBSCRIBER_SCOPE "scope" -#define PUBSUB_SUBSCRIBER_CONFIG "pubsub.config" - -struct pubsub_subscriber_struct { - void *handle; - - /** - * Called to initialize the subscriber with the receiver thread. - * Can be used to tweak the receiver thread attributes - * - * this method can be NULL. - */ - int (*init)(void *handle); - - - /** - * When a new message for a topic is available the receive will be called. - * - * msgType contains fully qualified name of the type and msgTypeId is a local id which presents the type for performance reasons. - * Release can be used to instruct the pubsubadmin to release (free) the message when receive function returns. Set it to false to take - * over ownership of the msg (e.g. take the responsibility to free it). - * - * The callbacks argument is only valid inside the receive function, use the getMultipart callback, with retain=true, to keep multipart messages in memory. - * results of the localMsgTypeIdForMsgType callback are valid during the complete lifecycle of the component, not just a single receive call. - * - * - * this method can be NULL. - * - * @param handle The subscriber handle - * @param msgType The fully qualified type name - * @param msgTypeId The local type id of the type, how this is calculated/created is up to the pubsub admin. (can be cached for improved performance) - * @param msg The pointer to the message - * @param metadata The meta data provided with the data. Can be NULL and is only valid during the callback. - * @param release Pointer to the release boolean, default is release is true. - * @return Return 0 implies a successful handling. If return is not 0, the msg will always be released by the pubsubadmin. - */ - int (*receive)(void *handle, const char *msgType, unsigned int msgTypeId, void *msg, const celix_properties_t *metadata, bool *release); - -}; -typedef struct pubsub_subscriber_struct pubsub_subscriber_t; - -#ifdef __cplusplus -} -#endif -#endif // __PUBSUB_SUBSCRIBER_H_ diff --git a/bundles/pubsub/pubsub_discovery/CMakeLists.txt b/bundles/pubsub/pubsub_discovery/CMakeLists.txt deleted file mode 100644 index ca73cae8a..000000000 --- a/bundles/pubsub/pubsub_discovery/CMakeLists.txt +++ /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. - -celix_subproject(PUBSUB_DISCOVERY_ETCD "Option to enable building the PubSub Discovery (ETCD) bundle" ON) -if (PUBSUB_DISCOVERY_ETCD) - find_package(jansson REQUIRED) - - add_celix_bundle(celix_pubsub_discovery_etcd - BUNDLE_SYMBOLICNAME "apache_celix_pubsub_discovery_etcd" - VERSION "1.1.0" - GROUP "Celix/PubSub" - SOURCES - src/psd_activator.c - src/pubsub_discovery_impl.c - ) - target_include_directories(celix_pubsub_discovery_etcd PRIVATE src) - target_link_libraries(celix_pubsub_discovery_etcd PRIVATE - Celix::etcdlib_static - Celix::shell_api Celix::log_helper - jansson::jansson - ) - target_link_libraries(celix_pubsub_discovery_etcd PRIVATE Celix::pubsub_spi Celix::pubsub_utils) - celix_deprecated_utils_headers(celix_pubsub_discovery_etcd) - celix_deprecated_framework_headers(celix_pubsub_discovery_etcd) - - install_celix_bundle(celix_pubsub_discovery_etcd EXPORT celix COMPONENT pubsub) - - add_library(Celix::celix_pubsub_discovery_etcd ALIAS celix_pubsub_discovery_etcd) -endif () diff --git a/bundles/pubsub/pubsub_discovery/src/psd_activator.c b/bundles/pubsub/pubsub_discovery/src/psd_activator.c deleted file mode 100644 index d19cb0f1d..000000000 --- a/bundles/pubsub/pubsub_discovery/src/psd_activator.c +++ /dev/null @@ -1,105 +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 -#include -#include - -#include "celix_log_helper.h" -#include "celix_shell_command.h" - -#include "celix_bundle_context.h" -#include "celix_bundle_activator.h" -#include "celix_constants.h" -#include "celix_log.h" - -#include "pubsub_listeners.h" -#include "pubsub_discovery_impl.h" - -typedef struct psd_activator { - pubsub_discovery_t *pubsub_discovery; - - long publishAnnounceSvcTrackerId; - //service_tracker_pt pstmPublishersTracker; - - pubsub_announce_endpoint_listener_t listenerSvc; - long listenerSvcId; - - celix_shell_command_t cmdSvc; - long cmdSvcId; - - celix_log_helper_t *loghelper; -} psd_activator_t; - -static celix_status_t psd_start(psd_activator_t *act, celix_bundle_context_t *ctx) { - celix_status_t status; - - act->loghelper = celix_logHelper_create(ctx, "celix_psa_discovery_etcd"); - - act->pubsub_discovery = pubsub_discovery_create(ctx, act->loghelper); - // pubsub_discovery_start needs to be first to initialize - status = pubsub_discovery_start(act->pubsub_discovery); - - celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; - opts.filter.serviceName = PUBSUB_DISCOVERED_ENDPOINT_LISTENER_SERVICE; - opts.callbackHandle = act->pubsub_discovery; - opts.addWithOwner = pubsub_discovery_discoveredEndpointsListenerAdded; - opts.removeWithOwner = pubsub_discovery_discoveredEndpointsListenerRemoved; - act->publishAnnounceSvcTrackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts); - - act->listenerSvc.handle = act->pubsub_discovery; - act->listenerSvc.announceEndpoint = pubsub_discovery_announceEndpoint; - act->listenerSvc.revokeEndpoint = pubsub_discovery_revokeEndpoint; - - //register shell command service - //register shell command - if (status == CELIX_SUCCESS) { - act->cmdSvc.handle = act->pubsub_discovery; - act->cmdSvc.executeCommand = pubsub_discovery_executeCommand; - celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, CELIX_SHELL_COMMAND_NAME, "celix::psd_etcd"); - celix_properties_set(props, CELIX_SHELL_COMMAND_USAGE, "psd_etcd"); - celix_properties_set(props, CELIX_SHELL_COMMAND_DESCRIPTION, "Overview of discovered/announced endpoints from/to ETCD"); - act->cmdSvcId = celix_bundleContext_registerService(ctx, &act->cmdSvc, CELIX_SHELL_COMMAND_SERVICE_NAME, props); - } - - if (status == CELIX_SUCCESS) { - act->listenerSvcId = celix_bundleContext_registerService(ctx, &act->listenerSvc, PUBSUB_ANNOUNCE_ENDPOINT_LISTENER_SERVICE, NULL); - } else { - act->listenerSvcId = -1L; - } - - return status; -} - -static celix_status_t psd_stop(psd_activator_t *act, celix_bundle_context_t *ctx) { - celix_bundleContext_stopTracker(ctx, act->publishAnnounceSvcTrackerId); - celix_bundleContext_unregisterService(ctx, act->listenerSvcId); - celix_bundleContext_unregisterService(ctx, act->cmdSvcId); - - celix_status_t status = pubsub_discovery_stop(act->pubsub_discovery); - pubsub_discovery_destroy(act->pubsub_discovery); - - celix_logHelper_destroy(act->loghelper); - - return status; -} - - -CELIX_GEN_BUNDLE_ACTIVATOR(psd_activator_t, psd_start, psd_stop); diff --git a/bundles/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c b/bundles/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c deleted file mode 100644 index f4730a8a9..000000000 --- a/bundles/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c +++ /dev/null @@ -1,639 +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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "celix_compiler.h" -#include "celix_bundle_context.h" -#include "celix_properties.h" -#include "celix_constants.h" -#include "celix_threads.h" -#include "array_list.h" -#include "utils.h" -#include "celix_errno.h" -#include "filter.h" - -#include "pubsub_listeners.h" -#include "pubsub_endpoint.h" -#include "pubsub_discovery_impl.h" - -#define L_DEBUG(...) \ - celix_logHelper_log(disc->logHelper, CELIX_LOG_LEVEL_DEBUG, __VA_ARGS__) -#define L_INFO(...) \ - celix_logHelper_log(disc->logHelper, CELIX_LOG_LEVEL_INFO, __VA_ARGS__) -#define L_WARN(...) \ - celix_logHelper_log(disc->logHelper, CELIX_LOG_LEVEL_WARNING, __VA_ARGS__) -#define L_ERROR(...) \ - celix_logHelper_log(disc->logHelper, CELIX_LOG_LEVEL_ERROR, __VA_ARGS__) - -static celix_properties_t* pubsub_discovery_parseEndpoint(pubsub_discovery_t *disc, const char *key, const char *value); -static char* pubsub_discovery_createJsonEndpoint(const celix_properties_t *props); -static void pubsub_discovery_addDiscoveredEndpoint(pubsub_discovery_t *disc, celix_properties_t *endpoint); -static void pubsub_discovery_removeDiscoveredEndpoint(pubsub_discovery_t *disc, const char *uuid); - -/* Discovery activator functions */ -pubsub_discovery_t* pubsub_discovery_create(celix_bundle_context_t *context, celix_log_helper_t *logHelper) { - pubsub_discovery_t *disc = calloc(1, sizeof(*disc)); - disc->logHelper = logHelper; - disc->context = context; - disc->discoveredEndpoints = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL); - disc->announcedEndpoints = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL); - disc->discoveredEndpointsListeners = hashMap_create(NULL, NULL, NULL, NULL); - celixThreadMutex_create(&disc->discoveredEndpointsListenersMutex, NULL); - celixThreadMutex_create(&disc->announcedEndpointsMutex, NULL); - celixThreadMutex_create(&disc->discoveredEndpointsMutex, NULL); - - celixThreadCondition_init(&disc->waitCond, NULL); - celixThreadMutex_create(&disc->runningMutex, NULL); - disc->running = true; - - - disc->verbose = celix_bundleContext_getPropertyAsBool(context, PUBSUB_ETCD_DISCOVERY_VERBOSE_KEY, PUBSUB_ETCD_DISCOVERY_DEFAULT_VERBOSE); - - const char* etcdIp = celix_bundleContext_getProperty(context, PUBSUB_DISCOVERY_SERVER_IP_KEY, PUBSUB_DISCOVERY_SERVER_IP_DEFAULT); - long etcdPort = celix_bundleContext_getPropertyAsLong(context, PUBSUB_DISCOVERY_SERVER_PORT_KEY, PUBSUB_DISCOVERY_SERVER_PORT_DEFAULT); - long ttl = celix_bundleContext_getPropertyAsLong(context, PUBSUB_DISCOVERY_ETCD_TTL_KEY, PUBSUB_DISCOVERY_ETCD_TTL_DEFAULT); - - disc->etcdlib = etcdlib_create(etcdIp, etcdPort, ETCDLIB_NO_CURL_INITIALIZATION); - disc->ttlForEntries = (int)ttl; - disc->sleepInsecBetweenTTLRefresh = (int)(((float)ttl)/2.0); - disc->pubsubPath = celix_bundleContext_getProperty(context, PUBSUB_DISCOVERY_SERVER_PATH_KEY, PUBSUB_DISCOVERY_SERVER_PATH_DEFAULT); - disc->fwUUID = celix_bundleContext_getProperty(context, CELIX_FRAMEWORK_UUID, NULL); - - return disc; -} - -celix_status_t pubsub_discovery_destroy(pubsub_discovery_t *ps_discovery) { - celix_status_t status = CELIX_SUCCESS; - - //note cleanup done in stop - celixThreadMutex_lock(&ps_discovery->discoveredEndpointsMutex); - hash_map_iterator_t iter = hashMapIterator_construct(ps_discovery->discoveredEndpoints); - while (hashMapIterator_hasNext(&iter)) { - celix_properties_t *props = hashMapIterator_nextValue(&iter); - celix_properties_destroy(props); - } - hashMap_destroy(ps_discovery->discoveredEndpoints, false, false); - celixThreadMutex_unlock(&ps_discovery->discoveredEndpointsMutex); - celixThreadMutex_destroy(&ps_discovery->discoveredEndpointsMutex); - - celixThreadMutex_lock(&ps_discovery->discoveredEndpointsListenersMutex); - hashMap_destroy(ps_discovery->discoveredEndpointsListeners, false, false); - celixThreadMutex_unlock(&ps_discovery->discoveredEndpointsListenersMutex); - celixThreadMutex_destroy(&ps_discovery->discoveredEndpointsListenersMutex); - - //note cleanup done in stop - celixThreadMutex_lock(&ps_discovery->announcedEndpointsMutex); - hashMap_destroy(ps_discovery->announcedEndpoints, false, false); - celixThreadMutex_unlock(&ps_discovery->announcedEndpointsMutex); - celixThreadMutex_destroy(&ps_discovery->announcedEndpointsMutex); - celixThreadCondition_destroy(&ps_discovery->waitCond); - - celixThreadMutex_destroy(&ps_discovery->runningMutex); - - if (ps_discovery->etcdlib != NULL) { - etcdlib_destroy(ps_discovery->etcdlib); - ps_discovery->etcdlib = NULL; - } - - free(ps_discovery); - - return status; -} - - -static void psd_etcdReadCallback(const char *key, const char *value, void* arg) { - pubsub_discovery_t *disc = arg; - celix_properties_t *props = pubsub_discovery_parseEndpoint(disc, key, value); - if (props != NULL) { - pubsub_discovery_addDiscoveredEndpoint(disc, props); - } -} - -static void psd_watchSetupConnection(pubsub_discovery_t *disc, bool *connectedPtr, long long *mIndex) { - bool connected = *connectedPtr; - if (!connected) { - if (disc->verbose) { - printf("[PSD] Reading etcd directory at %s\n", disc->pubsubPath); - } - int rc = etcdlib_get_directory(disc->etcdlib, disc->pubsubPath, psd_etcdReadCallback, disc, mIndex); - if (rc == ETCDLIB_RC_OK) { - *connectedPtr = true; - } else { - *connectedPtr = false; - } - } -} - -static void psd_watchForChange(pubsub_discovery_t *disc, bool *connectedPtr, long long *mIndex) { - bool connected = *connectedPtr; - if (connected) { - long long watchIndex = *mIndex + 1; - - char *action = NULL; - char *value = NULL; - char *readKey = NULL; - //TODO add interruptable etcdlib_watch -> which returns a handle to interrupt and a can be used for a wait call - int rc = etcdlib_watch(disc->etcdlib, disc->pubsubPath, watchIndex, &action, NULL, &value, &readKey, mIndex); - if (rc == ETCDLIB_RC_ERROR) { - L_ERROR("[PSD] Communicating with etcd. rc is %i, action value is %s\n", rc, action); - *connectedPtr = false; - } else if (rc == ETCDLIB_RC_TIMEOUT || action == NULL) { - //nop - } else { - if (strncmp(ETCDLIB_ACTION_CREATE, action, strlen(ETCDLIB_ACTION_CREATE)) == 0 || - strncmp(ETCDLIB_ACTION_SET, action, strlen(ETCDLIB_ACTION_SET)) == 0 || - strncmp(ETCDLIB_ACTION_UPDATE, action, strlen(ETCDLIB_ACTION_UPDATE)) == 0) { - celix_properties_t *props = pubsub_discovery_parseEndpoint(disc, readKey, value); - if (props != NULL) { - pubsub_discovery_addDiscoveredEndpoint(disc, props); - } - } else if (strncmp(ETCDLIB_ACTION_DELETE, action, strlen(ETCDLIB_ACTION_DELETE)) == 0 || - strncmp(ETCDLIB_ACTION_EXPIRE, action, strlen(ETCDLIB_ACTION_EXPIRE)) == 0) { - char *uuid = strrchr(readKey, '/'); - if (uuid != NULL) { - uuid = uuid + 1; - pubsub_discovery_removeDiscoveredEndpoint(disc, uuid); - } - } else { - //ETCDLIB_ACTION_GET -> nop - } - - free(action); - free(value); - free(readKey); - } - } else { - if (disc->verbose) { - printf("[PSD] Skipping etcd watch -> not connected\n"); - } - } -} - -static void psd_cleanupIfDisconnected(pubsub_discovery_t *disc, bool *connectedPtr) { - bool connected = *connectedPtr; - if (!connected) { - - celixThreadMutex_lock(&disc->discoveredEndpointsMutex); - int size = hashMap_size(disc->discoveredEndpoints); - if (disc->verbose) { - printf("[PSD] Removing all discovered entries (%i) -> not connected\n", size); - } - - hash_map_iterator_t iter = hashMapIterator_construct(disc->discoveredEndpoints); - while (hashMapIterator_hasNext(&iter)) { - celix_properties_t *endpoint = hashMapIterator_nextValue(&iter); - - celixThreadMutex_lock(&disc->discoveredEndpointsListenersMutex); - hash_map_iterator_t iter2 = hashMapIterator_construct(disc->discoveredEndpointsListeners); - while (hashMapIterator_hasNext(&iter2)) { - pubsub_discovered_endpoint_listener_t *listener = hashMapIterator_nextValue(&iter2); - listener->removeDiscoveredEndpoint(listener->handle, endpoint); - } - celixThreadMutex_unlock(&disc->discoveredEndpointsListenersMutex); - - celix_properties_destroy(endpoint); - } - hashMap_clear(disc->discoveredEndpoints, false, false); - celixThreadMutex_unlock(&disc->discoveredEndpointsMutex); - } -} - -void* psd_watch(void *data) { - pubsub_discovery_t *disc = data; - - long long mIndex = 0L; - bool connected = false; - - celixThreadMutex_lock(&disc->runningMutex); - bool running = disc->running; - celixThreadMutex_unlock(&disc->runningMutex); - - while (running) { - psd_watchSetupConnection(disc, &connected, &mIndex); - psd_watchForChange(disc, &connected, &mIndex); - psd_cleanupIfDisconnected(disc, &connected); - - celixThreadMutex_lock(&disc->runningMutex); - if (!connected && disc->running) { - celixThreadCondition_timedwaitRelative(&disc->waitCond, &disc->runningMutex, 5, 0); //if not connected wait a few seconds - } - running = disc->running; - celixThreadMutex_unlock(&disc->runningMutex); - } - - return NULL; -} - -void* psd_refresh(void *data) { - pubsub_discovery_t *disc = data; - - celixThreadMutex_lock(&disc->runningMutex); - bool running = disc->running; - celixThreadMutex_unlock(&disc->runningMutex); - - while (running) { - struct timespec start; - clock_gettime(CLOCK_MONOTONIC, &start); - - celixThreadMutex_lock(&disc->announcedEndpointsMutex); - hash_map_iterator_t iter = hashMapIterator_construct(disc->announcedEndpoints); - while (hashMapIterator_hasNext(&iter)) { - pubsub_announce_entry_t *entry = hashMapIterator_nextValue(&iter); - if (entry->isSet) { - //only refresh ttl -> no index update -> no watch trigger - int rc = etcdlib_refresh(disc->etcdlib, entry->key, disc->ttlForEntries); - if (rc != ETCDLIB_RC_OK) { - L_WARN("[PSD] Warning: Cannot refresh etcd key %s\n", entry->key); - entry->isSet = false; - entry->errorCount += 1; - } else { - entry->refreshCount += 1; - } - } else { - char *str = pubsub_discovery_createJsonEndpoint(entry->properties); - int rc = etcdlib_set(disc->etcdlib, entry->key, str, disc->ttlForEntries, false); - if (rc == ETCDLIB_RC_OK) { - entry->isSet = true; - entry->setCount += 1; - } else { - L_WARN("[PSD] Warning: Cannot set endpoint in etcd for key %s\n", entry->key); - entry->errorCount += 1; - } - free(str); - } - } - celixThreadMutex_unlock(&disc->announcedEndpointsMutex); - - celixThreadMutex_lock(&disc->runningMutex); - celixThreadCondition_timedwaitRelative(&disc->waitCond, &disc->runningMutex, disc->sleepInsecBetweenTTLRefresh, 0); - running = disc->running; - celixThreadMutex_unlock(&disc->runningMutex); - } - return NULL; -} - -celix_status_t pubsub_discovery_start(pubsub_discovery_t *ps_discovery) { - celix_status_t status = CELIX_SUCCESS; - - celixThread_create(&ps_discovery->watchThread, NULL, psd_watch, ps_discovery); - celixThread_setName(&ps_discovery->watchThread, "PubSub ETCD Watch"); - celixThread_create(&ps_discovery->refreshTTLThread, NULL, psd_refresh, ps_discovery); - celixThread_setName(&ps_discovery->refreshTTLThread, "PubSub ETCD Refresh TTL"); - - return status; -} - -celix_status_t pubsub_discovery_stop(pubsub_discovery_t *disc) { - celix_status_t status = CELIX_SUCCESS; - - celixThreadMutex_lock(&disc->runningMutex); - disc->running = false; - celixThreadCondition_broadcast(&disc->waitCond); - celixThreadMutex_unlock(&disc->runningMutex); - - celixThread_join(disc->watchThread, NULL); - celixThread_join(disc->refreshTTLThread, NULL); - - celixThreadMutex_lock(&disc->discoveredEndpointsMutex); - hash_map_iterator_t iter = hashMapIterator_construct(disc->discoveredEndpoints); - while (hashMapIterator_hasNext(&iter)) { - celix_properties_t *props = hashMapIterator_nextValue(&iter); - - celixThreadMutex_lock(&disc->discoveredEndpointsListenersMutex); - hash_map_iterator_t iter2 = hashMapIterator_construct(disc->discoveredEndpointsListeners); - while (hashMapIterator_hasNext(&iter2)) { - pubsub_discovered_endpoint_listener_t *listener = hashMapIterator_nextValue(&iter2); - listener->removeDiscoveredEndpoint(listener->handle, props); - } - celixThreadMutex_unlock(&disc->discoveredEndpointsListenersMutex); - - celix_properties_destroy(props); - } - hashMap_clear(disc->discoveredEndpoints, false, false); - celixThreadMutex_unlock(&disc->discoveredEndpointsMutex); - - celixThreadMutex_lock(&disc->announcedEndpointsMutex); - iter = hashMapIterator_construct(disc->announcedEndpoints); - while (hashMapIterator_hasNext(&iter)) { - pubsub_announce_entry_t *entry = hashMapIterator_nextValue(&iter); - if (entry->isSet) { - etcdlib_del(disc->etcdlib, entry->key); - } - free(entry->key); - celix_properties_destroy(entry->properties); - free(entry); - } - hashMap_clear(disc->announcedEndpoints, false, false); - celixThreadMutex_unlock(&disc->announcedEndpointsMutex); - - return status; -} - -void pubsub_discovery_discoveredEndpointsListenerAdded(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *bnd) { - pubsub_discovery_t *disc = handle; - pubsub_discovered_endpoint_listener_t *listener = svc; - - long svcId = celix_properties_getAsLong(props, CELIX_FRAMEWORK_SERVICE_ID, -1L); - celixThreadMutex_lock(&disc->discoveredEndpointsListenersMutex); - hashMap_put(disc->discoveredEndpointsListeners, (void*)svcId, listener); - celixThreadMutex_unlock(&disc->discoveredEndpointsListenersMutex); - - celixThreadMutex_lock(&disc->discoveredEndpointsMutex); - hash_map_iterator_t iter = hashMapIterator_construct(disc->discoveredEndpoints); - while (hashMapIterator_hasNext(&iter)) { - celix_properties_t *props = hashMapIterator_nextValue(&iter); - listener->addDiscoveredEndpoint(listener->handle, props); - } - celixThreadMutex_unlock(&disc->discoveredEndpointsMutex); -} - -void pubsub_discovery_discoveredEndpointsListenerRemoved(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *bnd) { - pubsub_discovery_t *disc = handle; - - long svcId = celix_properties_getAsLong(props, CELIX_FRAMEWORK_SERVICE_ID, -1L); - celixThreadMutex_lock(&disc->discoveredEndpointsListenersMutex); - hashMap_remove(disc->discoveredEndpointsListeners, (void*)svcId); - celixThreadMutex_unlock(&disc->discoveredEndpointsListenersMutex); -} - -celix_status_t pubsub_discovery_announceEndpoint(void *handle, const celix_properties_t *endpoint) { - pubsub_discovery_t *disc = handle; - celix_status_t status = CELIX_SUCCESS; - - bool valid = pubsubEndpoint_isValid(endpoint, true, true); - const char *config = celix_properties_get(endpoint, PUBSUB_ENDPOINT_ADMIN_TYPE, NULL); - const char *scope = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TOPIC_SCOPE, NULL); - const char *topic = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TOPIC_NAME, NULL); - const char *uuid = celix_properties_get(endpoint, PUBSUB_ENDPOINT_UUID, NULL); - - const char *visibility = celix_properties_get(endpoint, PUBSUB_ENDPOINT_VISIBILITY, PUBSUB_ENDPOINT_VISIBILITY_DEFAULT); - - if (valid && strncmp(visibility, PUBSUB_ENDPOINT_SYSTEM_VISIBILITY, strlen(PUBSUB_ENDPOINT_SYSTEM_VISIBILITY)) == 0) { - pubsub_announce_entry_t *entry = calloc(1, sizeof(*entry)); - clock_gettime(CLOCK_MONOTONIC, &entry->createTime); - entry->isSet = false; - entry->properties = celix_properties_copy(endpoint); - asprintf(&entry->key, "/pubsub/%s/%s/%s/%s", config, scope == NULL ? PUBSUB_DEFAULT_ENDPOINT_SCOPE : scope, topic, uuid); - - const char *hashKey = celix_properties_get(entry->properties, PUBSUB_ENDPOINT_UUID, NULL); - celixThreadMutex_lock(&disc->announcedEndpointsMutex); - hashMap_put(disc->announcedEndpoints, (void*)hashKey, entry); - celixThreadMutex_unlock(&disc->announcedEndpointsMutex); - - celixThreadMutex_lock(&disc->runningMutex); - celixThreadCondition_broadcast(&disc->waitCond); - celixThreadMutex_unlock(&disc->runningMutex); - } else if (valid) { - L_DEBUG("[PSD] Ignoring endpoint %s/%s because the visibility is not %s. Configured visibility is %s\n", scope == NULL ? "(null)" : scope, topic, PUBSUB_ENDPOINT_SYSTEM_VISIBILITY, visibility); - } - - if (!valid) { - L_ERROR("[PSD] Error cannot announce endpoint. missing some mandatory properties\n"); - } - - return status; -} -celix_status_t pubsub_discovery_revokeEndpoint(void *handle, const celix_properties_t *endpoint) { - pubsub_discovery_t *disc = handle; - celix_status_t status = CELIX_SUCCESS; - - const char *uuid = celix_properties_get(endpoint, PUBSUB_ENDPOINT_UUID, NULL); - pubsub_announce_entry_t *entry = NULL; - - if (uuid != NULL) { - celixThreadMutex_lock(&disc->announcedEndpointsMutex); - entry = hashMap_remove(disc->announcedEndpoints, uuid); - celixThreadMutex_unlock(&disc->announcedEndpointsMutex); - } else { - L_WARN("[PSD] Cannot remove announced endpoint. missing endpoint uuid property\n"); - } - - if (entry != NULL) { - if (entry->isSet) { - etcdlib_del(disc->etcdlib, entry->key); - } - free(entry->key); - celix_properties_destroy(entry->properties); - free(entry); - } - - return status; -} - - -static void pubsub_discovery_addDiscoveredEndpoint(pubsub_discovery_t *disc, celix_properties_t *endpoint) { - const char *uuid = celix_properties_get(endpoint, PUBSUB_ENDPOINT_UUID, NULL); - assert(uuid != NULL); - - celixThreadMutex_lock(&disc->discoveredEndpointsMutex); - bool exists = hashMap_containsKey(disc->discoveredEndpoints, (void*)uuid); - if (exists) { - //if exists -> keep old and free properties - celix_properties_destroy(endpoint); - } else { - hashMap_put(disc->discoveredEndpoints, (void*)uuid, endpoint); - } - celixThreadMutex_unlock(&disc->discoveredEndpointsMutex); - - if (!exists) { - if (disc->verbose) { - const char *type = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TYPE, "!Error!"); - const char *admin = celix_properties_get(endpoint, PUBSUB_ENDPOINT_ADMIN_TYPE, "!Error!"); - const char *ser = celix_properties_get(endpoint, PUBSUB_SERIALIZER_TYPE_KEY, "!Error!"); - const char *prot = celix_properties_get(endpoint, PUBSUB_PROTOCOL_TYPE_KEY, "!Error!"); - L_INFO("[PSD] Adding discovered endpoint %s. type is %s, admin is %s, serializer is %s, protocol is %s.\n", - uuid, type, admin, ser, prot); - } - - celixThreadMutex_lock(&disc->discoveredEndpointsListenersMutex); - hash_map_iterator_t iter = hashMapIterator_construct(disc->discoveredEndpointsListeners); - while (hashMapIterator_hasNext(&iter)) { - pubsub_discovered_endpoint_listener_t *listener = hashMapIterator_nextValue(&iter); - listener->addDiscoveredEndpoint(listener->handle, endpoint); - } - celixThreadMutex_unlock(&disc->discoveredEndpointsListenersMutex); - } else { - //assuming this is the same endpoint -> ignore - } -} - -static void pubsub_discovery_removeDiscoveredEndpoint(pubsub_discovery_t *disc, const char *uuid) { - celixThreadMutex_lock(&disc->discoveredEndpointsMutex); - celix_properties_t *endpoint = hashMap_remove(disc->discoveredEndpoints, (void*)uuid); - celixThreadMutex_unlock(&disc->discoveredEndpointsMutex); - - if (endpoint == NULL) { - L_WARN("Cannot find endpoint with uuid %s\n", uuid); - return; - } - - if (disc->verbose) { - const char *type = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TYPE, "!Error!"); - const char *admin = celix_properties_get(endpoint, PUBSUB_ENDPOINT_ADMIN_TYPE, "!Error!"); - const char *ser = celix_properties_get(endpoint, PUBSUB_SERIALIZER_TYPE_KEY, "!Error!"); - const char *prot = celix_properties_get(endpoint, PUBSUB_PROTOCOL_TYPE_KEY, "!Error!"); - L_INFO("[PSD] Removing discovered endpoint %s. type is %s, admin is %s, serializer is %s, protocol = %s.\n", - uuid, type, admin, ser, prot); - } - - if (endpoint != NULL) { - celixThreadMutex_lock(&disc->discoveredEndpointsListenersMutex); - hash_map_iterator_t iter = hashMapIterator_construct(disc->discoveredEndpointsListeners); - while (hashMapIterator_hasNext(&iter)) { - pubsub_discovered_endpoint_listener_t *listener = hashMapIterator_nextValue(&iter); - listener->removeDiscoveredEndpoint(listener->handle, endpoint); - } - celixThreadMutex_unlock(&disc->discoveredEndpointsListenersMutex); - - celix_properties_destroy(endpoint); - } else { - L_WARN("[PSD] Warning unexpected remove from non existing endpoint (uuid is %s)\n", uuid); - } -} - -celix_properties_t* pubsub_discovery_parseEndpoint(pubsub_discovery_t *disc, const char *key, const char* etcdValue) { - celix_properties_t *props = celix_properties_create(); - - // etcdValue contains the json formatted string - json_error_t error; - json_t* jsonRoot = json_loads(etcdValue, JSON_DECODE_ANY, &error); - - if (json_is_object(jsonRoot)) { - - void *iter = json_object_iter(jsonRoot); - - const char *key; - json_t *value; - - while (iter) { - key = json_object_iter_key(iter); - value = json_object_iter_value(iter); - celix_properties_set(props, key, json_string_value(value)); - iter = json_object_iter_next(jsonRoot, iter); - } - } - - if (jsonRoot != NULL) { - json_decref(jsonRoot); - } - - bool valid = pubsubEndpoint_isValid(props, true, true); - if (!valid) { - L_WARN("[PSD] Retrieved endpoint '%s' is not valid\n", key); - L_DEBUG("[PSD] Key %s: %s\n", key, etcdValue); - celix_properties_destroy(props); - props = NULL; - } - - return props; -} - -static char* pubsub_discovery_createJsonEndpoint(const celix_properties_t *props) { - //note props is already check for validity (pubsubEndpoint_isValid) - - json_t *jsEndpoint = json_object(); - CELIX_PROPERTIES_ITERATE(props, iter) { - json_object_set_new(jsEndpoint, iter.key, json_string(iter.entry.value)); - } - char* str = json_dumps(jsEndpoint, JSON_COMPACT); - json_decref(jsEndpoint); - return str; -} - -bool pubsub_discovery_executeCommand(void *handle, const char * commandLine CELIX_UNUSED, FILE *os, FILE *errorStream CELIX_UNUSED) { - pubsub_discovery_t *disc = handle; - - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - //TODO add support for query (scope / topic) - - fprintf(os, "\n"); - fprintf(os, "Discovery configuration:\n"); - fprintf(os, " |- etcd host = %s\n", etcdlib_host(disc->etcdlib)); - fprintf(os, " |- etcd port = %i\n", etcdlib_port(disc->etcdlib)); - fprintf(os, " |- entries ttl = %i seconds\n", disc->ttlForEntries); - fprintf(os, " |- entries refresh time = %i seconds\n", disc->sleepInsecBetweenTTLRefresh); - fprintf(os, " |- pubsub discovery path = %s\n", disc->pubsubPath); - - fprintf(os, "\n"); - fprintf(os, "Discovered Endpoints:\n"); - celixThreadMutex_lock(&disc->discoveredEndpointsMutex); - hash_map_iterator_t iter = hashMapIterator_construct(disc->discoveredEndpoints); - while (hashMapIterator_hasNext(&iter)) { - celix_properties_t *ep = hashMapIterator_nextValue(&iter); - const char *uuid = celix_properties_get(ep, PUBSUB_ENDPOINT_UUID, "!Error!"); - const char *scope = celix_properties_get(ep, PUBSUB_ENDPOINT_TOPIC_SCOPE, "!Error!"); - const char *topic = celix_properties_get(ep, PUBSUB_ENDPOINT_TOPIC_NAME, "!Error!"); - const char *adminType = celix_properties_get(ep, PUBSUB_ENDPOINT_ADMIN_TYPE, "!Error!"); - const char *serType = celix_properties_get(ep, PUBSUB_ENDPOINT_SERIALIZER, "!Error!"); - const char *protType = celix_properties_get(ep, PUBSUB_ENDPOINT_PROTOCOL, "!Error!"); - const char *type = celix_properties_get(ep, PUBSUB_ENDPOINT_TYPE, "!Error!"); - fprintf(os, "Endpoint %s:\n", uuid); - fprintf(os, " |- type = %s\n", type); - fprintf(os, " |- scope = %s\n", scope); - fprintf(os, " |- topic = %s\n", topic); - fprintf(os, " |- admin type = %s\n", adminType); - fprintf(os, " |- serializer = %s\n", serType); - fprintf(os, " |- protocol = %s\n", protType); - } - celixThreadMutex_unlock(&disc->discoveredEndpointsMutex); - - fprintf(os, "\n"); - fprintf(os, "Announced Endpoints:\n"); - celixThreadMutex_lock(&disc->announcedEndpointsMutex); - iter = hashMapIterator_construct(disc->announcedEndpoints); - while (hashMapIterator_hasNext(&iter)) { - pubsub_announce_entry_t *entry = hashMapIterator_nextValue(&iter); - const char *uuid = celix_properties_get(entry->properties, PUBSUB_ENDPOINT_UUID, "!Error!"); - const char *scope = celix_properties_get(entry->properties, PUBSUB_ENDPOINT_TOPIC_SCOPE, "!Error!"); - const char *topic = celix_properties_get(entry->properties, PUBSUB_ENDPOINT_TOPIC_NAME, "!Error!"); - const char *adminType = celix_properties_get(entry->properties, PUBSUB_ENDPOINT_ADMIN_TYPE, "!Error!"); - const char *serType = celix_properties_get(entry->properties, PUBSUB_ENDPOINT_SERIALIZER, "!Error!"); - const char *protType = celix_properties_get(entry->properties, PUBSUB_ENDPOINT_PROTOCOL, "!Error!"); - const char *type = celix_properties_get(entry->properties, PUBSUB_ENDPOINT_TYPE, "!Error!"); - int age = (int)(now.tv_sec - entry->createTime.tv_sec); - fprintf(os, "Endpoint %s:\n", uuid); - fprintf(os, " |- type = %s\n", type); - fprintf(os, " |- scope = %s\n", scope); - fprintf(os, " |- topic = %s\n", topic); - fprintf(os, " |- admin type = %s\n", adminType); - fprintf(os, " |- serializer = %s\n", serType); - fprintf(os, " |- protocol = %s\n", protType); - fprintf(os, " |- age = %ds\n", age); - fprintf(os, " |- is set = %s\n", entry->isSet ? "true" : "false"); - if (disc->verbose) { - fprintf(os, " |- set count = %d\n", entry->setCount); - fprintf(os, " |- refresh count = %d\n", entry->refreshCount); - fprintf(os, " |- error count = %d\n", entry->errorCount); - } - } - celixThreadMutex_unlock(&disc->announcedEndpointsMutex); - - return true; -} diff --git a/bundles/pubsub/pubsub_discovery/src/pubsub_discovery_impl.h b/bundles/pubsub/pubsub_discovery/src/pubsub_discovery_impl.h deleted file mode 100644 index 6fcdb3cdc..000000000 --- a/bundles/pubsub/pubsub_discovery/src/pubsub_discovery_impl.h +++ /dev/null @@ -1,100 +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_DISCOVERY_IMPL_H_ -#define PUBSUB_DISCOVERY_IMPL_H_ - -#include -#include "bundle_context.h" -#include "service_reference.h" - -#include "pubsub_endpoint.h" -#include "etcd.h" - -#define FREE_MEM(ptr) if(ptr) {free(ptr); ptr = NULL;} - -#define PUBSUB_ETCD_DISCOVERY_VERBOSE_KEY "PUBSUB_ETCD_DISCOVERY_VERBOSE" -#define PUBSUB_ETCD_DISCOVERY_DEFAULT_VERBOSE false - - -#define PUBSUB_DISCOVERY_SERVER_IP_KEY "PUBSUB_DISCOVERY_ETCD_SERVER_IP" -#define PUBSUB_DISCOVERY_SERVER_PORT_KEY "PUBSUB_DISCOVERY_ETCD_SERVER_PORT" -#define PUBSUB_DISCOVERY_SERVER_PATH_KEY "PUBSUB_DISCOVERY_ETCD_ROOT_PATH" -#define PUBSUB_DISCOVERY_ETCD_TTL_KEY "PUBSUB_DISCOVERY_ETCD_TTL" - - -#define PUBSUB_DISCOVERY_SERVER_IP_DEFAULT "127.0.0.1" -#define PUBSUB_DISCOVERY_SERVER_PORT_DEFAULT 2379 -#define PUBSUB_DISCOVERY_SERVER_PATH_DEFAULT "pubsub/" -#define PUBSUB_DISCOVERY_ETCD_TTL_DEFAULT 30 - -typedef struct pubsub_discovery { - celix_bundle_context_t *context; - celix_log_helper_t *logHelper; - - celix_thread_mutex_t discoveredEndpointsMutex; //when locked with EndpointsListenersMutex -> first lock this - hash_map_pt discoveredEndpoints; //> - - celix_thread_mutex_t announcedEndpointsMutex; - hash_map_pt announcedEndpoints; //> - - celix_thread_mutex_t discoveredEndpointsListenersMutex; - hash_map_pt discoveredEndpointsListeners; //key=svcId, value=pubsub_discovered_endpoint_listener_t - - celix_thread_mutex_t runningMutex; - bool running; - celix_thread_cond_t waitCond; - celix_thread_t watchThread; - celix_thread_t refreshTTLThread; - - //configurable by config/env. - const char *pubsubPath; - bool verbose; - etcdlib_t *etcdlib; - int ttlForEntries; - int sleepInsecBetweenTTLRefresh; - const char *fwUUID; -} pubsub_discovery_t; - -typedef struct pubsub_announce_entry { - char *key; //etcd key - bool isSet; //whether the value is already set (in case of unavailable etcd server this can linger) - int refreshCount; - int setCount; - int errorCount; - celix_properties_t *properties; //the endpoint properties - struct timespec createTime; //from MONOTONIC clock -} pubsub_announce_entry_t; - - -pubsub_discovery_t* pubsub_discovery_create(celix_bundle_context_t *context, celix_log_helper_t *logHelper); -celix_status_t pubsub_discovery_destroy(pubsub_discovery_t *node_discovery); -celix_status_t pubsub_discovery_start(pubsub_discovery_t *node_discovery); -celix_status_t pubsub_discovery_stop(pubsub_discovery_t *node_discovery); - -void pubsub_discovery_discoveredEndpointsListenerAdded(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *bnd); -void pubsub_discovery_discoveredEndpointsListenerRemoved(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *bnd); - -celix_status_t pubsub_discovery_announceEndpoint(void *handle, const celix_properties_t *endpoint); -celix_status_t pubsub_discovery_revokeEndpoint(void *handle, const celix_properties_t *endpoint); - -bool pubsub_discovery_executeCommand(void *handle, const char * commandLine, FILE *os, FILE *errorStream); - - -#endif /* PUBSUB_DISCOVERY_IMPL_H_ */ diff --git a/bundles/pubsub/pubsub_protocol/CMakeLists.txt b/bundles/pubsub/pubsub_protocol/CMakeLists.txt deleted file mode 100644 index ad935dfea..000000000 --- a/bundles/pubsub/pubsub_protocol/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - - -add_subdirectory(pubsub_protocol_lib) -add_subdirectory(pubsub_protocol_wire_v1) -add_subdirectory(pubsub_protocol_wire_v2) diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/CMakeLists.txt b/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/CMakeLists.txt deleted file mode 100644 index e2ffe2382..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -add_library(celix_pubsub_protocol_lib STATIC - src/pubsub_wire_protocol_common.c - ) -target_link_libraries(celix_pubsub_protocol_lib PUBLIC Celix::pubsub_spi) -target_include_directories(celix_pubsub_protocol_lib PUBLIC include) - -if (ENABLE_TESTING) - add_subdirectory(gtest) -endif() diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/gtest/CMakeLists.txt b/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/gtest/CMakeLists.txt deleted file mode 100644 index cb84dca04..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/gtest/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -add_executable(celix_pswp_common_tests src/PS_WP_common_tests.cc) -target_include_directories(celix_pswp_common_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../src) -target_link_libraries(celix_pswp_common_tests PRIVATE celix_pubsub_protocol_lib GTest::gtest Celix::pubsub_spi GTest::gtest_main) - -add_test(NAME celix_pswp_common_tests COMMAND celix_pswp_common_tests) -setup_target_for_coverage(celix_pswp_common_tests SCAN_DIR ..) - -if (EI_TESTS) - add_executable(celix_pswp_common_ei_tests src/PS_WP_common_ei_tests.cc) - target_include_directories(celix_pswp_common_ei_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../src) - target_link_libraries(celix_pswp_common_ei_tests PRIVATE celix_pubsub_protocol_lib GTest::gtest Celix::pubsub_spi GTest::gtest_main Celix::malloc_ei Celix::properties_ei) - - add_test(NAME celix_pswp_common_ei_tests COMMAND celix_pswp_common_ei_tests) - setup_target_for_coverage(celix_pswp_common_ei_tests SCAN_DIR ..) -endif () \ No newline at end of file diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/gtest/src/PS_WP_common_ei_tests.cc b/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/gtest/src/PS_WP_common_ei_tests.cc deleted file mode 100644 index aeccfc2ad..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/gtest/src/PS_WP_common_ei_tests.cc +++ /dev/null @@ -1,233 +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 -#include -#include -#include "celix_properties_ei.h" -#include "malloc_ei.h" - -#include "pubsub_wire_protocol_common.h" - -class WireProtocolCommonEiTest : public ::testing::Test { -public: - WireProtocolCommonEiTest() = default; - ~WireProtocolCommonEiTest() override { - celix_ei_expect_realloc(nullptr, 0, nullptr); - celix_ei_expect_calloc(nullptr, 0, nullptr); - celix_ei_expect_celix_properties_create(nullptr, 0, nullptr); - }; -}; - -TEST_F(WireProtocolCommonEiTest, WireProtocolCommonTest_EncodeMetadataWithNoMemoryLeft) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 0; - message.metadata.metadata = celix_properties_create(); - celix_properties_set(message.metadata.metadata, "key1", "value1"); - - //Scenario: No mem with no pre-allocated data - //Given (mocked) realloc is forced to return NULL - celix_ei_expect_realloc((void *)pubsubProtocol_encodeMetadata, 0, nullptr); - - //When I try to encode a metadata - char *data = nullptr; - size_t length = 0; - size_t contentLength = 0; - auto status = pubsubProtocol_encodeMetadata(&message, &data, &length, &contentLength); - //Then I expect a failure - EXPECT_NE(status, CELIX_SUCCESS); - - //Scenario: No mem with some pre-allocated data - //Given a data set with some space - data = (char*)malloc(16); - length = 16; - - //And (mocked) realloc is forced to return NULL - celix_ei_expect_realloc((void *)pubsubProtocol_encodeMetadata, 0, nullptr); - - //When I try to encode a metadata - status = pubsubProtocol_encodeMetadata(&message, &data, &length, &contentLength); - - //Then I expect a failure - EXPECT_NE(status, CELIX_SUCCESS); - - free(data); - celix_properties_destroy(message.metadata.metadata); -} - -TEST_F(WireProtocolCommonEiTest, WireProtocolCommonTest_DecodeMetadataWithSingleEntries) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 0; - message.metadata.metadata = nullptr; - - char* data = strdup("ABCD4:key1,6:value1,"); //note 1 entry - auto len = strlen(data); - pubsubProtocol_writeInt((unsigned char*)data, 0, message.header.convertEndianess, 1); - auto status = pubsubProtocol_decodeMetadata((void*)data, len, &message); - - EXPECT_EQ(status, CELIX_SUCCESS); - EXPECT_EQ(1, celix_properties_size(message.metadata.metadata)); - EXPECT_STREQ("value1", celix_properties_get(message.metadata.metadata, "key1", "not-found")); - - free(data); - celix_properties_destroy(message.metadata.metadata); -} - -TEST_F(WireProtocolCommonEiTest, WireProtocolCommonTest_DencodeMetadataWithMultipleEntries) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 1; - message.metadata.metadata = nullptr; - - char* data = strdup("ABCD4:key1,6:value1,4:key2,6:value2,6:key111,8:value111,"); //note 3 entries - auto len = strlen(data); - pubsubProtocol_writeInt((unsigned char*)data, 0, message.header.convertEndianess, 3); - auto status = pubsubProtocol_decodeMetadata((void*)data, len, &message); - - EXPECT_EQ(status, CELIX_SUCCESS); - EXPECT_EQ(3, celix_properties_size(message.metadata.metadata)); - EXPECT_STREQ("value1", celix_properties_get(message.metadata.metadata, "key1", "not-found")); - EXPECT_STREQ("value2", celix_properties_get(message.metadata.metadata, "key2", "not-found")); - EXPECT_STREQ("value111", celix_properties_get(message.metadata.metadata, "key111", "not-found")); - - free(data); - celix_properties_destroy(message.metadata.metadata); -} - -TEST_F(WireProtocolCommonEiTest, WireProtocolCommonTest_DencodeMetadataWithExtraEntries) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 1; - message.metadata.metadata = nullptr; - - char* data = strdup("ABCD4:key1,6:value1,4:key2,6:value2,6:key111,8:value111,"); //note 3 entries - auto len = strlen(data); - pubsubProtocol_writeInt((unsigned char*)data, 0, message.header.convertEndianess, 2); - auto status = pubsubProtocol_decodeMetadata((void*)data, len, &message); - // the 3rd entry should be ignored - EXPECT_EQ(status, CELIX_SUCCESS); - EXPECT_EQ(2, celix_properties_size(message.metadata.metadata)); - EXPECT_STREQ("value1", celix_properties_get(message.metadata.metadata, "key1", "not-found")); - EXPECT_STREQ("value2", celix_properties_get(message.metadata.metadata, "key2", "not-found")); - EXPECT_STREQ("not-found", celix_properties_get(message.metadata.metadata, "key111", "not-found")); - - free(data); - celix_properties_destroy(message.metadata.metadata); -} - -TEST_F(WireProtocolCommonEiTest, WireProtocolCommonTest_DencodeMetadataMissingEntries) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 1; - message.metadata.metadata = nullptr; - - char* data = strdup("ABCD4:key1,6:value1,4:key2,6:value2,6:key111,8:value111,"); //note 3 entries - auto len = strlen(data); - pubsubProtocol_writeInt((unsigned char*)data, 0, message.header.convertEndianess, 4); - auto status = pubsubProtocol_decodeMetadata((void*)data, len, &message); - - EXPECT_EQ(status, CELIX_INVALID_SYNTAX); - EXPECT_EQ(nullptr, message.metadata.metadata); - - free(data); -} - -TEST_F(WireProtocolCommonEiTest, WireProtocolCommonTest_DecodeMetadataWithSingleEntryWithIncompleteValue) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 0; - message.metadata.metadata = nullptr; - - char* data = strdup("ABCD4:key1,6:val,"); //note 1 entry with short value - auto len = strlen(data); - pubsubProtocol_writeInt((unsigned char*)data, 0, message.header.convertEndianess, 1); - auto status = pubsubProtocol_decodeMetadata((void*)data, len, &message); - - EXPECT_EQ(status, CELIX_INVALID_SYNTAX); - EXPECT_EQ(nullptr, message.metadata.metadata); - - free(data); -} - -TEST_F(WireProtocolCommonEiTest, WireProtocolCommonTest_DecodeMetadataTooShort) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 0; - message.metadata.metadata = nullptr; - - char* data = strdup("ABCD4:key1,6:value1,"); //note 1 entry - pubsubProtocol_writeInt((unsigned char*)data, 0, message.header.convertEndianess, 1); - auto status = pubsubProtocol_decodeMetadata((void*)data, 3, &message); // not enough data for `nOfElements` - - EXPECT_EQ(status, CELIX_INVALID_SYNTAX); - EXPECT_EQ(nullptr, message.metadata.metadata); - - free(data); -} - -TEST_F(WireProtocolCommonEiTest, WireProtocolCommonTest_DecodeEmptyMetadata) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 0; - message.metadata.metadata = nullptr; - - uint32_t data = 0; - auto status = pubsubProtocol_decodeMetadata((void*)&data, 4, &message); - - EXPECT_EQ(status, CELIX_SUCCESS); - EXPECT_EQ(nullptr, message.metadata.metadata); - - // incorrect `nOfElements` - data = 4; - status = pubsubProtocol_decodeMetadata((void*)&data, 4, &message); - - EXPECT_EQ(status, CELIX_INVALID_SYNTAX); - EXPECT_EQ(nullptr, message.metadata.metadata); -} - -TEST_F(WireProtocolCommonEiTest, WireProtocolCommonTest_NotEnoughMemoryForMultipleEntries) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 1; - message.metadata.metadata = nullptr; - - char* data = strdup("ABCD4:key1,6:value1,4:key2,6:value2,6:key111,8:value111,"); //note 3 entries - auto len = strlen(data); - pubsubProtocol_writeInt((unsigned char*)data, 0, message.header.convertEndianess, 3); - for (int i = 0; i < 6; ++i) { - celix_ei_expect_calloc((void *)pubsubProtocol_decodeMetadata, 0, nullptr, i+1); - auto status = pubsubProtocol_decodeMetadata((void*)data, len, &message); - - EXPECT_EQ(status, CELIX_ENOMEM); - EXPECT_EQ(nullptr, message.metadata.metadata); - } - free(data); -} - -TEST_F(WireProtocolCommonEiTest, WireProtocolCommonTest_PropertiesAllocFailureWhenDecodingMetadata) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 0; - message.metadata.metadata = nullptr; - - char* data = strdup("ABCD4:key1,6:value1,"); //note 1 entry - auto len = strlen(data); - pubsubProtocol_writeInt((unsigned char*)data, 0, message.header.convertEndianess, 1); - celix_ei_expect_celix_properties_create((void*)pubsubProtocol_decodeMetadata, 0, nullptr); - auto status = pubsubProtocol_decodeMetadata((void*)data, len, &message); - - EXPECT_EQ(status, CELIX_ENOMEM); - EXPECT_EQ(nullptr, message.metadata.metadata); - - free(data); -} diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/gtest/src/PS_WP_common_tests.cc b/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/gtest/src/PS_WP_common_tests.cc deleted file mode 100644 index 54c64b353..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/gtest/src/PS_WP_common_tests.cc +++ /dev/null @@ -1,311 +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 -#include -#include - -#include "pubsub_wire_protocol_common.h" - -class WireProtocolCommonTest : public ::testing::Test { -public: - WireProtocolCommonTest() = default; - ~WireProtocolCommonTest() = default; -}; - -TEST_F(WireProtocolCommonTest, WireProtocolCommonTest_EncodeMetadataWithSingleEntries) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 0; - message.metadata.metadata = celix_properties_create(); - celix_properties_set(message.metadata.metadata, "key1", "value1"); - size_t neededNetstringLength = 16; //4:key1,6:value1, (16 chars) - - char *data = nullptr; - size_t length = 0; - size_t contentLength = 0; - celix_status_t status = pubsubProtocol_encodeMetadata(&message, &data, &length, &contentLength); - EXPECT_TRUE(status == CELIX_SUCCESS); - EXPECT_EQ(contentLength, neededNetstringLength + 4); - - //note first 4 bytes are an int with the nr of metadata entries (6); - uint32_t nrOfMetadataEntries; - pubsubProtocol_readInt((unsigned char*)data, 0, message.header.convertEndianess, &nrOfMetadataEntries); - EXPECT_EQ(1, nrOfMetadataEntries); - EXPECT_GE(length, neededNetstringLength + 4 /*sizeof(nrOfMetadataEntries)*/); - - //create null terminated string from netstring entries in the data buffer (- first 4 bytes + null terminating entry) - char checkStr[32]; - ASSERT_GE(sizeof(checkStr), neededNetstringLength); - strncpy(checkStr, data+4, neededNetstringLength); - checkStr[neededNetstringLength] = '\0'; - EXPECT_STREQ("4:key1,6:value1,", checkStr); - - free(data); - celix_properties_destroy(message.metadata.metadata); -} - -TEST_F(WireProtocolCommonTest, WireProtocolCommonTest_EncodeMetadataWithMultipleEntries) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 1; - message.metadata.metadata = celix_properties_create(); - celix_properties_set(message.metadata.metadata, "key1", "value1"); //4:key1,6:value1, (16 chars) - celix_properties_set(message.metadata.metadata, "key2", "value2"); //4:key2,6:value2, (16 chars) - celix_properties_set(message.metadata.metadata, "key3", "value3"); //4:key3,6:value3, (16 chars) - celix_properties_set(message.metadata.metadata, "key4", "value4"); //4:key4,6:value4, (16 chars) - celix_properties_set(message.metadata.metadata, "key5", "value5"); //4:key5,6:value5, (16 chars) - celix_properties_set(message.metadata.metadata, "key111", "value111"); //6:key111,8:value111, (20 chars) - size_t neededNetstringLength = 100; //Total: 5 * 16 + 20 = 100 - - - char *data = nullptr; - size_t length = 0; - size_t contentLength = 0; - celix_status_t status = pubsubProtocol_encodeMetadata(&message, &data, &length, &contentLength); - EXPECT_TRUE(status == CELIX_SUCCESS); - EXPECT_EQ(contentLength, neededNetstringLength + 4); - - //note first 4 bytes are a int with the nr of metadata entries (6); - uint32_t nrOfMetadataEntries; - pubsubProtocol_readInt((unsigned char*)data, 0, message.header.convertEndianess, &nrOfMetadataEntries); - EXPECT_EQ(6, nrOfMetadataEntries); - - - //create null terminated string from netstring entries in the data buffer (- first 4 bytes + null terminating entry) - char checkStr[128]; - ASSERT_GE(sizeof(checkStr), neededNetstringLength); - strncpy(checkStr, data+4, neededNetstringLength); - checkStr[neededNetstringLength] = '\0'; - - //NOTE because celix properties can reorder entries (hashmap), check if the expected str parts are in the data. - EXPECT_NE(nullptr, strstr(checkStr, "4:key1,6:value1,")); //entry 1 - EXPECT_NE(nullptr, strstr(checkStr, "4:key2,6:value2,")); //entry 2 - EXPECT_NE(nullptr, strstr(checkStr, "4:key3,6:value3,")); //entry 3 - EXPECT_NE(nullptr, strstr(checkStr, "4:key4,6:value4,")); //entry 4 - EXPECT_NE(nullptr, strstr(checkStr, "4:key5,6:value5,")); //entry 5 - EXPECT_NE(nullptr, strstr(checkStr, "6:key111,8:value111,")); //entry 6 (with value 111) - - free(data); - celix_properties_destroy(message.metadata.metadata); -} - -TEST_F(WireProtocolCommonTest, WireProtocolCommonTest_EncodeMetadataWithNullOrEmptyArguments) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 0; - message.metadata.metadata = nullptr; - - char *data = nullptr; - size_t length = 0; - size_t contentLength = 0; - celix_status_t status = pubsubProtocol_encodeMetadata(&message, &data, &length, &contentLength); - - EXPECT_EQ(status, CELIX_SUCCESS); - EXPECT_EQ(contentLength, 4); - - //note first 4 bytes are a int with the nr of metadata entries (0); - uint32_t nrOfMetadataEntries; - pubsubProtocol_readInt((unsigned char*)data, 0, message.header.convertEndianess, &nrOfMetadataEntries); - EXPECT_EQ(0, nrOfMetadataEntries); - free(data); - - data = nullptr; - length = 0; - message.metadata.metadata = celix_properties_create(); //note empty - - status = pubsubProtocol_encodeMetadata(&message, &data, &length, &contentLength); - EXPECT_EQ(status, CELIX_SUCCESS); - EXPECT_EQ(contentLength, 4); - - //note first 4 bytes are a int with the nr of metadata entries (0); - pubsubProtocol_readInt((unsigned char*)data, 0, message.header.convertEndianess, &nrOfMetadataEntries); - EXPECT_EQ(0, nrOfMetadataEntries); - free(data); - celix_properties_destroy(message.metadata.metadata); -} - -TEST_F(WireProtocolCommonTest, WireProtocolCommonTest_EncodeWithExistinBufferWhichAlsoNeedsSomeRealloc) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 0; - message.metadata.metadata = nullptr; - - char *data = (char*)malloc(2); - size_t length = 2; - size_t contentLength = 0; - celix_status_t status = pubsubProtocol_encodeMetadata(&message, &data, &length, &contentLength); - EXPECT_EQ(status, CELIX_SUCCESS); - EXPECT_GT(length, 2); - - message.metadata.metadata = celix_properties_create(); - char key[32]; - //create a lot of metadata entries - for (int i = 0; i < 1000; ++i) { - snprintf(key, sizeof(key), "key%i", i); - celix_properties_set(message.metadata.metadata, key, "abcdefghijklmnop"); - } - //note reusing data - status = pubsubProtocol_encodeMetadata(&message, &data, &length, &contentLength); - EXPECT_EQ(status, CELIX_SUCCESS); - - free(data); - celix_properties_destroy(message.metadata.metadata); -} - -TEST_F(WireProtocolCommonTest, WireProtocolCommonTest_DecodeMetadataWithSingleEntries) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 0; - message.metadata.metadata = nullptr; - - char* data = strdup("ABCD4:key1,6:value1,"); //note 1 entry - auto len = strlen(data); - pubsubProtocol_writeInt((unsigned char*)data, 0, message.header.convertEndianess, 1); - auto status = pubsubProtocol_decodeMetadata((void*)data, len, &message); - - EXPECT_EQ(status, CELIX_SUCCESS); - EXPECT_EQ(1, celix_properties_size(message.metadata.metadata)); - EXPECT_STREQ("value1", celix_properties_get(message.metadata.metadata, "key1", "not-found")); - - free(data); - celix_properties_destroy(message.metadata.metadata); -} - -TEST_F(WireProtocolCommonTest, WireProtocolCommonTest_DencodeMetadataWithMultipleEntries) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 1; - message.metadata.metadata = nullptr; - - char* data = strdup("ABCD4:key1,6:value1,4:key2,6:value2,6:key111,8:value111,"); //note 3 entries - auto len = strlen(data); - pubsubProtocol_writeInt((unsigned char*)data, 0, message.header.convertEndianess, 3); - auto status = pubsubProtocol_decodeMetadata((void*)data, len, &message); - - EXPECT_EQ(status, CELIX_SUCCESS); - EXPECT_EQ(3, celix_properties_size(message.metadata.metadata)); - EXPECT_STREQ("value1", celix_properties_get(message.metadata.metadata, "key1", "not-found")); - EXPECT_STREQ("value2", celix_properties_get(message.metadata.metadata, "key2", "not-found")); - EXPECT_STREQ("value111", celix_properties_get(message.metadata.metadata, "key111", "not-found")); - - free(data); - celix_properties_destroy(message.metadata.metadata); -} - -TEST_F(WireProtocolCommonTest, WireProtocolCommonTest_DencodeMetadataWithExtraEntries) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 1; - message.metadata.metadata = nullptr; - - char* data = strdup("ABCD4:key1,6:value1,4:key2,6:value2,6:key111,8:value111,"); //note 3 entries - auto len = strlen(data); - pubsubProtocol_writeInt((unsigned char*)data, 0, message.header.convertEndianess, 2); - auto status = pubsubProtocol_decodeMetadata((void*)data, len, &message); - // the 3rd entry should be ignored - EXPECT_EQ(status, CELIX_SUCCESS); - EXPECT_EQ(2, celix_properties_size(message.metadata.metadata)); - EXPECT_STREQ("value1", celix_properties_get(message.metadata.metadata, "key1", "not-found")); - EXPECT_STREQ("value2", celix_properties_get(message.metadata.metadata, "key2", "not-found")); - EXPECT_STREQ("not-found", celix_properties_get(message.metadata.metadata, "key111", "not-found")); - - free(data); - celix_properties_destroy(message.metadata.metadata); -} - -TEST_F(WireProtocolCommonTest, WireProtocolCommonTest_DencodeMetadataMissingEntries) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 1; - message.metadata.metadata = nullptr; - - char* data = strdup("ABCD4:key1,6:value1,4:key2,6:value2,6:key111,8:value111,"); //note 3 entries - auto len = strlen(data); - pubsubProtocol_writeInt((unsigned char*)data, 0, message.header.convertEndianess, 4); - auto status = pubsubProtocol_decodeMetadata((void*)data, len, &message); - - EXPECT_EQ(status, CELIX_INVALID_SYNTAX); - EXPECT_EQ(nullptr, message.metadata.metadata); - - free(data); -} - -TEST_F(WireProtocolCommonTest, WireProtocolCommonTest_DecodeMetadataWithSingleEntryWithIncompleteValue) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 0; - message.metadata.metadata = nullptr; - - char* data = strdup("ABCD4:key1,6:val,"); //note 1 entry with short value - auto len = strlen(data); - pubsubProtocol_writeInt((unsigned char*)data, 0, message.header.convertEndianess, 1); - auto status = pubsubProtocol_decodeMetadata((void*)data, len, &message); - - EXPECT_EQ(status, CELIX_INVALID_SYNTAX); - EXPECT_EQ(nullptr, message.metadata.metadata); - - free(data); -} - -TEST_F(WireProtocolCommonTest, WireProtocolCommonTest_DecodeMetadataTooShort) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 0; - message.metadata.metadata = nullptr; - - char* data = strdup("ABCD4:key1,6:value1,"); //note 1 entry - pubsubProtocol_writeInt((unsigned char*)data, 0, message.header.convertEndianess, 1); - auto status = pubsubProtocol_decodeMetadata((void*)data, 3, &message); // not enough data for `nOfElements` - - EXPECT_EQ(status, CELIX_INVALID_SYNTAX); - EXPECT_EQ(nullptr, message.metadata.metadata); - - free(data); -} - -TEST_F(WireProtocolCommonTest, WireProtocolCommonTest_DecodeEmptyMetadata) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 0; - message.metadata.metadata = nullptr; - - uint32_t data = 0; - auto status = pubsubProtocol_decodeMetadata((void*)&data, 4, &message); - - EXPECT_EQ(status, CELIX_SUCCESS); - EXPECT_EQ(nullptr, message.metadata.metadata); - - // incorrect `nOfElements` - data = 4; - status = pubsubProtocol_decodeMetadata((void*)&data, 4, &message); - - EXPECT_EQ(status, CELIX_INVALID_SYNTAX); - EXPECT_EQ(nullptr, message.metadata.metadata); -} - -TEST_F(WireProtocolCommonTest, WireProtocolCommonTest_DencodeMetadataWithDuplicateEntries) { - pubsub_protocol_message_t message; - message.header.convertEndianess = 1; - message.metadata.metadata = nullptr; - - char* data = strdup("ABCD4:key1,6:value1,4:key1,6:value2,6:key111,8:value111,"); //note 3 entries with duplicate key1 - auto len = strlen(data); - pubsubProtocol_writeInt((unsigned char*)data, 0, message.header.convertEndianess, 3); - auto status = pubsubProtocol_decodeMetadata((void*)data, len, &message); - - EXPECT_EQ(status, CELIX_SUCCESS); - EXPECT_EQ(2, celix_properties_size(message.metadata.metadata)); - EXPECT_STREQ("value2", celix_properties_get(message.metadata.metadata, "key1", "not-found")); - EXPECT_STREQ("value111", celix_properties_get(message.metadata.metadata, "key111", "not-found")); - - free(data); - celix_properties_destroy(message.metadata.metadata); -} diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/include/pubsub_wire_protocol_common.h b/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/include/pubsub_wire_protocol_common.h deleted file mode 100644 index f6f1b8abc..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/include/pubsub_wire_protocol_common.h +++ /dev/null @@ -1,86 +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_PROTOCOL_COMMON_H -#define CELIX_PUBSUB_PROTOCOL_COMMON_H - -#include - -#include "celix_errno.h" -#include "pubsub_protocol.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define NETSTRING_ERROR_TOO_LONG -1 -#define NETSTRING_ERROR_NO_COLON -2 -#define NETSTRING_ERROR_TOO_SHORT -3 -#define NETSTRING_ERROR_NO_COMMA -4 -#define NETSTRING_ERROR_LEADING_ZERO -5 -#define NETSTRING_ERROR_NO_LENGTH -6 - -static const unsigned int PROTOCOL_WIRE_V1_SYNC_HEADER = 0xABBABAAB; -static const unsigned int PROTOCOL_WIRE_V1_ENVELOPE_VERSION = 1; - -static const unsigned int PROTOCOL_WIRE_V2_SYNC_HEADER = 0xABBADEAF; -static const unsigned int PROTOCOL_WIRE_V2_SYNC_FOOTER = 0xDEAFABBA; -static const unsigned int PROTOCOL_WIRE_V2_ENVELOPE_VERSION = 2; - -int pubsubProtocol_readChar(const unsigned char *data, int offset, uint8_t *val); -int pubsubProtocol_readShort(const unsigned char *data, int offset, uint32_t convert, uint16_t *val); -int pubsubProtocol_readInt(const unsigned char *data, int offset, uint32_t convert, uint32_t *val); -int pubsubProtocol_readLong(const unsigned char *data, int offset, uint32_t convert, uint64_t *val); - -int pubsubProtocol_writeChar(unsigned char *data, int offset, uint8_t val); -int pubsubProtocol_writeShort(unsigned char *data, int offset, uint32_t convert, uint16_t val); -int pubsubProtocol_writeInt(unsigned char *data, int offset, uint32_t convert, uint32_t val); -int pubsubProtocol_writeLong(unsigned char *data, int offset, uint32_t convert, uint64_t val); - -celix_status_t pubsubProtocol_encodePayload(pubsub_protocol_message_t *message, void **outBuffer, size_t *outLength); -celix_status_t pubsubProtocol_decodePayload(void *data, size_t length, pubsub_protocol_message_t *message); -celix_status_t pubsubProtocol_decodeMetadata(void *data, size_t length, pubsub_protocol_message_t *message); - -/** - * @brief Encode metadata to bufferInOut. - * - * The metadata is encoded as a bytebuffer where the first 4 bytes is used to specify how many metadata (key,value) - * entries there are and then every metadata entry is encoded as a netstring key followed by a netstring value. - * - * If *bufferInOut is NULL, a new buffer will be allocated. If *bufferInOut is not NULL, the buffer is reused and the - * provided *bufferLengthInOut must indicate the length of the provided buffer. - * If a provided *bufferInOut is not large enough to fit the encoded metadata, the buffer will be reallocated. - * - * If this calls return with an error, the caller is still owner of a possible returned output buffer. - * - * @param message The message containing the metadata to encode - * @param bufferInOut Input/output argument for the buffer, if call is successful will contain the metadata header - * @param bufferLengthInOut Input/output arguments for the length of the bufferInOut argument. - * @param bufferContentLengthOut Output argument for the actual content size of the bufferInOut. Note that the - * bufferContentLengthOut can be smaller than the buffer length. - * @return CELIX_SUCCESS if encoding was successful. - */ -celix_status_t pubsubProtocol_encodeMetadata(pubsub_protocol_message_t* message, char** bufferInOut, size_t* bufferLengthInOut, size_t* bufferContentLengthOut); - - -#ifdef __cplusplus -} -#endif - -#endif //CELIX_PUBSUB_PROTOCOL_COMMON_H diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/src/pubsub_wire_protocol_common.c b/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/src/pubsub_wire_protocol_common.c deleted file mode 100644 index 5010919c7..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_lib/src/pubsub_wire_protocol_common.c +++ /dev/null @@ -1,313 +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_wire_protocol_common.h" - -#include -#include -#include -#include "celix_byteswap.h" -#include "celix_utils.h" - -#define PUBSUB_METADATA_INITIAL_BUFFER_SIZE 1024 -#define PUBSUB_METADATA_MAX_BUFFER_SIZE (1024 * 1024 * 1024) //max 1gb -#define PUBSUB_METADATA_BUFFER_INCREASE_FACTOR 2.0 - -/** - * @brief Add - as netstring formatted - str to the provided buffer. - * - * The provided offset will be updated to point to the next unused byte for the provided buffer. - * - * @return CELIX_FILE_IO_EXCEPTION if the provided buffer is not big enough. - */ -static celix_status_t pubsubProtocol_addNetstringEntryToBuffer(char* buffer, size_t bufferSize, size_t* offsetInOut, const char* str) { - size_t offset = *offsetInOut; - - size_t strLen = celix_utils_strlen(str); - - char strLenString[32]; //note the str needed to print the strLen of str. - int written = snprintf(strLenString, sizeof(strLenString), "%zu", strLen); - if (written >= sizeof(strLenString) || written < 0) { - return CELIX_ILLEGAL_ARGUMENT; //str too large to capture in 31 characters. - } - size_t strLenStringLen = written; - - if (strLen == 0) { - if ((bufferSize - offset) < 3) { - return CELIX_FILE_IO_EXCEPTION; - } else { - memcpy(buffer + offset, "0:,", 3); - offset += 3; - } - } else { - size_t sizeNeeded = strLenStringLen + 1 /*:*/ + strLen + 1 /*,*/; //e.g "5:hello," - if (sizeNeeded > bufferSize - offset) { - return CELIX_FILE_IO_EXCEPTION; - } - memcpy(buffer + offset, strLenString, strLenStringLen); //e.g "5" - offset += strLenStringLen; - buffer[offset++] = ':'; - memcpy(buffer + offset, str, strLen); //e.g. "hello" - offset += strLen; - buffer[offset++] = ','; - } - - *offsetInOut = offset; - return CELIX_SUCCESS; -} - -celix_status_t pubsubProtocol_encodeMetadata(pubsub_protocol_message_t* message, char** bufferInOut, size_t* bufferLengthInOut, size_t* bufferContentLengthOut) { - size_t metadataSize = message->metadata.metadata == NULL ? 0 : celix_properties_size(message->metadata.metadata); - bool reallocBuffer = false; - bool encoded = false; - - if (*bufferInOut == NULL || *bufferLengthInOut < 4 /*note buffer needs to fit int for nr of metadata entries*/) { - reallocBuffer = true; - } - - size_t offset = 4; //note starting at index 4, to keep the first 4 bytes free for the nr metadata elements entry - while (!encoded) { - if (reallocBuffer) { - size_t newLength = *bufferInOut == NULL ? - PUBSUB_METADATA_INITIAL_BUFFER_SIZE : - (size_t)((double)*bufferLengthInOut * PUBSUB_METADATA_BUFFER_INCREASE_FACTOR); - if (newLength > PUBSUB_METADATA_MAX_BUFFER_SIZE) { - //max buffer size reached - return CELIX_ILLEGAL_ARGUMENT; - } - char* newBuffer = realloc(*bufferInOut, newLength); - if (newBuffer == NULL) { - return CELIX_ENOMEM; - } - *bufferInOut = newBuffer; - *bufferLengthInOut = newLength; - } - if (metadataSize == 0) { - encoded = true; - continue; - } - celix_status_t status = CELIX_SUCCESS; - CELIX_PROPERTIES_ITERATE(message->metadata.metadata, iter) { - if (status == CELIX_SUCCESS) { - status = pubsubProtocol_addNetstringEntryToBuffer(*bufferInOut, *bufferLengthInOut, &offset, iter.key); - } - if (status == CELIX_SUCCESS) { - status = pubsubProtocol_addNetstringEntryToBuffer(*bufferInOut, *bufferLengthInOut, &offset, iter.entry.value); - } - } - if (status == CELIX_FILE_IO_EXCEPTION) { - reallocBuffer = true; - continue; - } else if (status != CELIX_SUCCESS) { - return status; - } - encoded =true; - } - - //write nr of meta elements at the beginning of the pubsub protocol metadata entry - pubsubProtocol_writeInt((unsigned char *)*bufferInOut, 0, message->header.convertEndianess, metadataSize); - *bufferContentLengthOut = offset; - return CELIX_SUCCESS; -} - -/* Reads a netstring from a `buffer` of length `buffer_length`. Writes - to `netstring_start` a pointer to the beginning of the string in - the buffer, and to `netstring_length` the length of the - string. Does not allocate any memory. If it reads successfully, - then it returns 0. If there is an error, then the return value will - be negative. The error values are: - NETSTRING_ERROR_TOO_LONG More than 999999999 bytes in a field - NETSTRING_ERROR_NO_COLON No colon was found after the number - NETSTRING_ERROR_TOO_SHORT Number of bytes greater than buffer length - NETSTRING_ERROR_NO_COMMA No comma was found at the end - NETSTRING_ERROR_LEADING_ZERO Leading zeros are not allowed - NETSTRING_ERROR_NO_LENGTH Length not given at start of netstring - If you're sending messages with more than 999999999 bytes -- about - 2 GB -- then you probably should not be doing so in the form of a - single netstring. This restriction is in place partially to protect - from malicious or erroneous input, and partly to be compatible with - D. J. Bernstein's reference implementation. - Example: - if (netstring_read("3:foo,", 6, &str, &len) < 0) explode_and_die(); - */ -static int pubsubProtocol_parseNetstring(unsigned char *buffer, size_t buffer_length, - unsigned char **netstring_start, size_t *netstring_length) { - int i; - size_t len = 0; - - /* Write default values for outputs */ - *netstring_start = NULL; *netstring_length = 0; - - /* Make sure buffer is big enough. Minimum size is 3. */ - if (buffer_length < 3) return NETSTRING_ERROR_TOO_SHORT; - - /* No leading zeros allowed! */ - if (buffer[0] == '0' && isdigit(buffer[1])) - return NETSTRING_ERROR_LEADING_ZERO; - - /* The netstring must start with a number */ - if (!isdigit(buffer[0])) return NETSTRING_ERROR_NO_LENGTH; - - /* Read the number of bytes */ - for (i = 0; i < buffer_length && isdigit(buffer[i]); i++) { - /* Error if more than 9 digits */ - if (i >= 9) return NETSTRING_ERROR_TOO_LONG; - /* Accumulate each digit, assuming ASCII. */ - len = len*10 + (buffer[i] - '0'); - } - - /* Check buffer length once and for all. Specifically, we make sure - that the buffer is longer than the number we've read, the length - of the string itself, and the colon and comma. */ - if (i + len + 1 >= buffer_length) return NETSTRING_ERROR_TOO_SHORT; - - /* Read the colon */ - if (buffer[i++] != ':') return NETSTRING_ERROR_NO_COLON; - - /* Test for the trailing comma, and set the return values */ - if (buffer[i + len] != ',') return NETSTRING_ERROR_NO_COMMA; - *netstring_start = &buffer[i]; *netstring_length = len; - - return 0; -} - -int pubsubProtocol_readChar(const unsigned char *data, int offset, uint8_t *val) { - memcpy(val, data + offset, sizeof(uint8_t)); - *val = *val; - return offset + sizeof(uint16_t); -} - -int pubsubProtocol_readShort(const unsigned char *data, int offset, uint32_t convert, uint16_t *val) { - memcpy(val, data + offset, sizeof(uint16_t)); - if (convert) { - *val = bswap_16(*val); - } - return offset + sizeof(uint16_t); -} - -int pubsubProtocol_readInt(const unsigned char *data, int offset, uint32_t convert, uint32_t *val) { - memcpy(val, data + offset, sizeof(uint32_t)); - if (convert) { - *val = bswap_32(*val); - } - return offset + sizeof(uint32_t); -} - -int pubsubProtocol_readLong(const unsigned char *data, int offset, uint32_t convert, uint64_t *val) { - memcpy(val, data + offset, sizeof(uint64_t)); - if (convert) { - *val = bswap_64(*val); - } - return offset + sizeof(uint64_t); -} - -int pubsubProtocol_writeChar(unsigned char *data, int offset, uint8_t val) { - memcpy(data + offset, &val, sizeof(uint8_t)); - return offset + sizeof(uint8_t); -} - -int pubsubProtocol_writeShort(unsigned char *data, int offset, uint32_t convert, uint16_t val) { - uint16_t nVal = (convert) ? bswap_16(val) : val; - memcpy(data + offset, &nVal, sizeof(uint16_t)); - return offset + sizeof(uint16_t); -} - -int pubsubProtocol_writeInt(unsigned char *data, int offset, uint32_t convert, uint32_t val) { - uint32_t nVal = (convert) ? bswap_32(val) : val; - memcpy(data + offset, &nVal, sizeof(uint32_t)); - return offset + sizeof(uint32_t); -} - -int pubsubProtocol_writeLong(unsigned char *data, int offset, uint32_t convert, uint64_t val) { - uint64_t nVal = (convert) ? bswap_64(val) : val; - memcpy(data + offset, &nVal, sizeof(uint64_t)); - return offset + sizeof(uint64_t); -} - -celix_status_t pubsubProtocol_encodePayload(pubsub_protocol_message_t *message, void **outBuffer, size_t *outLength) { - *outBuffer = message->payload.payload; - *outLength = message->payload.length; - - return CELIX_SUCCESS; -} - -celix_status_t pubsubProtocol_decodePayload(void *data, size_t length, pubsub_protocol_message_t *message){ - message->payload.payload = data; - message->payload.length = length; - - return CELIX_SUCCESS; -} - -celix_status_t pubsubProtocol_decodeMetadata(void *data, size_t length, pubsub_protocol_message_t *message) { - celix_status_t status = CELIX_SUCCESS; - message->metadata.metadata = NULL; - if (length < sizeof(uint32_t)) { - return CELIX_INVALID_SYNTAX; - } - uint32_t nOfElements; - size_t idx = pubsubProtocol_readInt(data, 0, message->header.convertEndianess, &nOfElements); - if (nOfElements == 0) { - return CELIX_SUCCESS; - } - unsigned char *netstring = data + idx; - size_t netstringLen = length - idx; - - message->metadata.metadata = celix_properties_create(); - if (message->metadata.metadata == NULL) { - return CELIX_ENOMEM; - } - for (; nOfElements > 0 && netstringLen > 0; nOfElements--) { - int i; - char *strs[2] = {NULL, NULL}; - for (i = 0; i < 2; ++i) { - unsigned char *outstring = NULL; - size_t outlen; - status = pubsubProtocol_parseNetstring(netstring, netstringLen, &outstring, &outlen); - if (status != CELIX_SUCCESS) { - status = CELIX_INVALID_SYNTAX; - break; - } - strs[i] = calloc(outlen + 1, sizeof(char)); - if (strs[i] == NULL) { - status = CELIX_ENOMEM; - break; - } - memcpy(strs[i], outstring, outlen); - strs[i][outlen] = '\0'; - netstringLen -= (outstring - netstring + outlen + 1); - netstring = outstring + (outlen + 1); - } - if (i == 2) { - // if metadata has duplicate keys, the last one takes effect - celix_properties_unset(message->metadata.metadata, strs[0]); - celix_properties_setWithoutCopy(message->metadata.metadata, strs[0], strs[1]); - } else { - for (int j = 0; j < i; ++j) { - free(strs[j]); - } - break; - } - } - if (nOfElements > 0) { - celix_properties_destroy(message->metadata.metadata); - message->metadata.metadata = NULL; - status = (status != CELIX_SUCCESS) ? status : CELIX_INVALID_SYNTAX; - } - return status; -} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/CMakeLists.txt b/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/CMakeLists.txt deleted file mode 100644 index 950590d45..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/CMakeLists.txt +++ /dev/null @@ -1,48 +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. - -celix_subproject(PUBSUB_WIRE_PROTOCOL_V1 "Option to enable building the PubSub Wire Protocol v1 bundle" ON) -if (PUBSUB_WIRE_PROTOCOL_V1) - add_library(celix_wire_protocol_v1_impl STATIC - src/pubsub_wire_protocol_impl.c - ) - target_include_directories(celix_wire_protocol_v1_impl PRIVATE src) - target_link_libraries(celix_wire_protocol_v1_impl PUBLIC Celix::pubsub_spi) - target_link_libraries(celix_wire_protocol_v1_impl PUBLIC celix_pubsub_protocol_lib) - celix_deprecated_utils_headers(celix_wire_protocol_v1_impl) - - add_celix_bundle(celix_pubsub_protocol_wire_v1 - BUNDLE_SYMBOLICNAME "apache_celix_pubsub_protocol_wire_v1" - VERSION "1.0.1" - GROUP "Celix/PubSub" - SOURCES - src/ps_wire_protocol_activator.c - ) - target_include_directories(celix_pubsub_protocol_wire_v1 PRIVATE src) - target_link_libraries(celix_pubsub_protocol_wire_v1 PRIVATE Celix::pubsub_spi Celix::pubsub_utils) - target_link_libraries(celix_pubsub_protocol_wire_v1 PRIVATE celix_wire_protocol_v1_impl) - celix_deprecated_utils_headers(celix_pubsub_protocol_wire_v1) - celix_deprecated_framework_headers(celix_pubsub_protocol_wire_v1) - - install_celix_bundle(celix_pubsub_protocol_wire_v1 EXPORT celix COMPONENT pubsub) - - add_library(Celix::celix_pubsub_protocol_wire_v1 ALIAS celix_pubsub_protocol_wire_v1) - - if (ENABLE_TESTING) - add_subdirectory(gtest) - endif() -endif () \ No newline at end of file diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/gtest/CMakeLists.txt b/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/gtest/CMakeLists.txt deleted file mode 100644 index f86a18e1f..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/gtest/CMakeLists.txt +++ /dev/null @@ -1,28 +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. - -set(SOURCES - src/main.cc - src/PS_WP_tests.cc - ) -add_executable(celix_pswp_tests ${SOURCES}) -#target_include_directories(celix_cxx_pswp_tests SYSTEM PRIVATE gtest) -target_include_directories(celix_pswp_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../src) -target_link_libraries(celix_pswp_tests PRIVATE celix_wire_protocol_v1_impl GTest::gtest Celix::pubsub_spi) - -add_test(NAME celix_pswp_tests COMMAND celix_pswp_tests) -setup_target_for_coverage(celix_pswp_tests SCAN_DIR ..) \ No newline at end of file diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/gtest/src/PS_WP_tests.cc b/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/gtest/src/PS_WP_tests.cc deleted file mode 100644 index 346514af2..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/gtest/src/PS_WP_tests.cc +++ /dev/null @@ -1,323 +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 -#include - -#include - -#include "gtest/gtest.h" - -#include "pubsub_wire_protocol_impl.h" -#include - -class WireProtocolV1Test : public ::testing::Test { -public: - WireProtocolV1Test() = default; - ~WireProtocolV1Test() override = default; - -}; - - -TEST_F(WireProtocolV1Test, WireProtocolV1Test_EncodeHeader_Test) { // NOLINT(cert-err58-cpp) - pubsub_protocol_wire_v1_t *wireprotocol; - pubsubProtocol_create(&wireprotocol); - - pubsub_protocol_message_t message; - message.header.msgId = 1; - message.header.msgMajorVersion = 0; - message.header.msgMinorVersion = 0; - message.header.payloadSize = 2; - message.header.metadataSize = 3; - - void *headerData = nullptr; - size_t headerLength = 0; - celix_status_t status = pubsubProtocol_encodeHeader(nullptr, &message, &headerData, &headerLength); - - unsigned char exp[24]; - uint32_t s = 0xABBABAAB; - memcpy(exp, &s, sizeof(uint32_t)); - uint32_t e = 0x01000000; - memcpy(exp+4, &e, sizeof(uint32_t)); - uint32_t m = 0x01000000; - memcpy(exp+8, &m, sizeof(uint32_t)); - uint32_t v = 0x00000000; - memcpy(exp+12, &v, sizeof(uint32_t)); - uint32_t ps = 0x02000000; - memcpy(exp+16, &ps, sizeof(uint32_t)); - uint32_t ms = 0x03000000; - memcpy(exp+20, &ms, sizeof(uint32_t)); - - ASSERT_EQ(status, CELIX_SUCCESS); - ASSERT_EQ(24, headerLength); - for (int i = 0; i < 24; i++) { - ASSERT_EQ(((unsigned char*) headerData)[i], exp[i]); - } - - pubsubProtocol_destroy(wireprotocol); - free(headerData); -} - -TEST_F(WireProtocolV1Test, WireProtocolV1Test_EncodeHeader_TestWithExistingMemory) { - pubsub_protocol_wire_v1_t *wireprotocol; - pubsubProtocol_create(&wireprotocol); - - pubsub_protocol_message_t message; - message.header.msgId = 1; - message.header.msgMajorVersion = 0; - message.header.msgMinorVersion = 0; - message.header.payloadSize = 2; - message.header.metadataSize = 3; - - void* headerData = malloc(3); - size_t headerLength = 0; - - //calling with too small of a buffer (new buffer with new length should be created). - celix_status_t status = pubsubProtocol_encodeHeader(nullptr, &message, &headerData, &headerLength); - EXPECT_EQ(status, CELIX_SUCCESS); - EXPECT_EQ(24, headerLength); - EXPECT_NE(3, headerLength); - - void* orgHeaderDataPointer = headerData; - //calling with matching buffer, buffer will be re-used. - status = pubsubProtocol_encodeHeader(nullptr, &message, &headerData, &headerLength); - EXPECT_EQ(status, CELIX_SUCCESS); - EXPECT_EQ(24, headerLength); - EXPECT_EQ(headerData, orgHeaderDataPointer); - - - pubsubProtocol_destroy(wireprotocol); - free(headerData); -} - -TEST_F(WireProtocolV1Test, WireProtocolV1Test_DecodeHeader_Test) { // NOLINT(cert-err58-cpp) - pubsub_protocol_wire_v1_t *wireprotocol; - pubsubProtocol_create(&wireprotocol); - - unsigned char exp[24]; - uint32_t s = 0xABBABAAB; - memcpy(exp, &s, sizeof(uint32_t)); - uint32_t e = 0x01000000; - memcpy(exp+4, &e, sizeof(uint32_t)); - uint32_t m = 0x01000000; - memcpy(exp+8, &m, sizeof(uint32_t)); - uint32_t v = 0x00000000; - memcpy(exp+12, &v, sizeof(uint32_t)); - uint32_t ps = 0x02000000; - memcpy(exp+16, &ps, sizeof(uint32_t)); - uint32_t ms = 0x03000000; - memcpy(exp+20, &ms, sizeof(uint32_t)); - - pubsub_protocol_message_t message; - - celix_status_t status = pubsubProtocol_decodeHeader(nullptr, exp, 24, &message); - - ASSERT_EQ(CELIX_SUCCESS, status); - ASSERT_EQ(1, message.header.msgId); - ASSERT_EQ(0, message.header.msgMajorVersion); - ASSERT_EQ(0, message.header.msgMinorVersion); - ASSERT_EQ(2, message.header.payloadSize); - ASSERT_EQ(3, message.header.metadataSize); - - pubsubProtocol_destroy(wireprotocol); -} - -TEST_F(WireProtocolV1Test, WireProtocolV1Test_WireProtocolV1Test_DecodeHeader_IncorrectSync_Test) { // NOLINT(cert-err58-cpp) - pubsub_protocol_wire_v1_t *wireprotocol; - pubsubProtocol_create(&wireprotocol); - - unsigned char exp[24]; - uint32_t s = 0xBAABABBA; - memcpy(exp, &s, sizeof(uint32_t)); - uint32_t e = 0x01000000; - memcpy(exp+4, &e, sizeof(uint32_t)); - uint32_t m = 0x01000000; - memcpy(exp+8, &m, sizeof(uint32_t)); - uint32_t v = 0x00000000; - memcpy(exp+12, &v, sizeof(uint32_t)); - uint32_t ps = 0x02000000; - memcpy(exp+16, &ps, sizeof(uint32_t)); - uint32_t ms = 0x03000000; - memcpy(exp+20, &ms, sizeof(uint32_t)); - - pubsub_protocol_message_t message; - - celix_status_t status = pubsubProtocol_decodeHeader(nullptr, exp, 24, &message); - - ASSERT_EQ(CELIX_ILLEGAL_ARGUMENT, status); - - pubsubProtocol_destroy(wireprotocol); -} - -TEST_F(WireProtocolV1Test, WireProtocolV1Test_WireProtocolV1Test_DecodeHeader_IncorrectVersion_Test) { // NOLINT(cert-err58-cpp) - pubsub_protocol_wire_v1_t *wireprotocol; - pubsubProtocol_create(&wireprotocol); - - unsigned char exp[24]; - uint32_t s = 0xABBABAAB; - memcpy(exp, &s, sizeof(uint32_t)); - uint32_t e = 0x02000000; - memcpy(exp+4, &e, sizeof(uint32_t)); - uint32_t m = 0x01000000; - memcpy(exp+8, &m, sizeof(uint32_t)); - uint32_t v = 0x00000000; - memcpy(exp+12, &v, sizeof(uint32_t)); - uint32_t ps = 0x02000000; - memcpy(exp+16, &ps, sizeof(uint32_t)); - uint32_t ms = 0x03000000; - memcpy(exp+20, &ms, sizeof(uint32_t)); - - pubsub_protocol_message_t message; - - celix_status_t status = pubsubProtocol_decodeHeader(nullptr, exp, 24, &message); - - ASSERT_EQ(CELIX_ILLEGAL_ARGUMENT, status); - - pubsubProtocol_destroy(wireprotocol); -} - -TEST_F(WireProtocolV1Test, WireProtocolV1Test_EncodeMetadata_Test) { // NOLINT(cert-err58-cpp) - pubsub_protocol_wire_v1_t *wireprotocol; - pubsubProtocol_create(&wireprotocol); - - pubsub_protocol_message_t message; - - message.metadata.metadata = celix_properties_create(); - message.header.convertEndianess = 1; - celix_properties_set(message.metadata.metadata, "a", "b"); - - void *data = nullptr; - size_t dataLength = 0; - size_t length = 0; - celix_status_t status = pubsubProtocol_v1_encodeMetadata(nullptr, &message, &data, &dataLength, &length); - ASSERT_EQ(status, CELIX_SUCCESS); - - unsigned char exp[12]; - uint32_t s = htonl(1); - memcpy(exp, &s, sizeof(uint32_t)); - memcpy(exp + 4, "1:a,1:b,", 8); - - ASSERT_EQ(status, CELIX_SUCCESS); - ASSERT_EQ(12, length); - for (int i = 0; i < 12; i++) { - ASSERT_EQ(((unsigned char*) data)[i], exp[i]) << "Error at index " << i; - } - - celix_properties_destroy(message.metadata.metadata); - free(data); - pubsubProtocol_destroy(wireprotocol); -} - -TEST_F(WireProtocolV1Test, WireProtocolV1Test_DecodeMetadata_Test) { // NOLINT(cert-err58-cpp) - pubsub_protocol_wire_v1_t *wireprotocol; - pubsubProtocol_create(&wireprotocol); - - unsigned char exp[12]; - uint32_t s = htonl(1); - memcpy(exp, &s, sizeof(uint32_t)); - memcpy(exp + 4, "1:a,1:b,", 8); - - pubsub_protocol_message_t message; - message.header.convertEndianess = true; - celix_status_t status = pubsubProtocol_v1_decodeMetadata(nullptr, exp, 12, &message); - - ASSERT_EQ(status, CELIX_SUCCESS); - ASSERT_EQ(1, celix_properties_size(message.metadata.metadata)); - const char * value = celix_properties_get(message.metadata.metadata, "a", nullptr); - ASSERT_STREQ("b", value); - - celix_properties_destroy(message.metadata.metadata); - - pubsubProtocol_destroy(wireprotocol); -} - -TEST_F(WireProtocolV1Test, WireProtocolV1Test_DecodeMetadata_EmptyKey_Test) { // NOLINT(cert-err58-cpp) - pubsub_protocol_wire_v1_t *wireprotocol; - pubsubProtocol_create(&wireprotocol); - - unsigned char exp[11]; - uint32_t s = htonl(1); - memcpy(exp, &s, sizeof(uint32_t)); - memcpy(exp + 4, "0:,1:b,", 7); - - pubsub_protocol_message_t message; - message.header.convertEndianess = true; - celix_status_t status = pubsubProtocol_v1_decodeMetadata(nullptr, exp, 11, &message); - - ASSERT_EQ(status, CELIX_SUCCESS); - ASSERT_EQ(1, celix_properties_size(message.metadata.metadata)); - const char * value = celix_properties_get(message.metadata.metadata, "", nullptr); - ASSERT_STREQ("b", value); - - celix_properties_destroy(message.metadata.metadata); - pubsubProtocol_destroy(wireprotocol); -} - -TEST_F(WireProtocolV1Test, WireProtocolV1Test_DecodeMetadata_SpecialChars_Test) { // NOLINT(cert-err58-cpp) - pubsub_protocol_wire_v1_t *wireprotocol; - pubsubProtocol_create(&wireprotocol); - - unsigned char exp[15]; - uint32_t s = htonl(1); - memcpy(exp, &s, sizeof(uint32_t)); - memcpy(exp + 4, "4:a,:l,1:b,", 11); - - pubsub_protocol_message_t message; - message.header.convertEndianess = true; - celix_status_t status = pubsubProtocol_v1_decodeMetadata(nullptr, &exp, 15, &message); - - ASSERT_EQ(status, CELIX_SUCCESS); - ASSERT_EQ(1, celix_properties_size(message.metadata.metadata)); - const char * value = celix_properties_get(message.metadata.metadata, "a,:l", nullptr); - ASSERT_STREQ("b", value); - - celix_properties_destroy(message.metadata.metadata); - pubsubProtocol_destroy(wireprotocol); -} - -TEST_F(WireProtocolV1Test, WireProtocolV1Test_EncodeFooter_Test) { // NOLINT(cert-err58-cpp) - pubsub_protocol_wire_v1_t *wireprotocol; - pubsubProtocol_create(&wireprotocol); - - pubsub_protocol_message_t message; - - void *footerData = nullptr; - size_t footerLength = 0; - celix_status_t status = pubsubProtocol_encodeFooter(nullptr, &message, &footerData, &footerLength); - - ASSERT_EQ(status, CELIX_SUCCESS); - ASSERT_EQ(0, footerLength); - ASSERT_EQ(nullptr, footerData); - pubsubProtocol_destroy(wireprotocol); - free(footerData); -} - -TEST_F(WireProtocolV1Test, WireProtocolV1Test_DecodeFooter_Test) { // NOLINT(cert-err58-cpp) - pubsub_protocol_wire_v1_t *wireprotocol; - pubsubProtocol_create(&wireprotocol); - - unsigned char exp[4]; - uint32_t s = 0xBAABABBA; - memcpy(exp, &s, sizeof(uint32_t)); - pubsub_protocol_message_t message; - - celix_status_t status = pubsubProtocol_decodeFooter(nullptr, exp, 4, &message); - ASSERT_EQ(CELIX_SUCCESS, status); - pubsubProtocol_destroy(wireprotocol); -} diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/gtest/src/main.cc b/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/gtest/src/main.cc deleted file mode 100644 index 09731c411..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/gtest/src/main.cc +++ /dev/null @@ -1,26 +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 - -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - int rc = RUN_ALL_TESTS(); - return rc; -} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/src/ps_wire_protocol_activator.c b/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/src/ps_wire_protocol_activator.c deleted file mode 100644 index 32af5adda..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/src/ps_wire_protocol_activator.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include - -#include "celix_api.h" -#include "pubsub_wire_protocol_impl.h" - -typedef struct ps_wp_activator { - pubsub_protocol_wire_v1_t *wireprotocol; - - pubsub_protocol_service_t protocolSvc; - long wireProtocolSvcId; -} ps_wp_activator_t; - -static int ps_wp_start(ps_wp_activator_t *act, celix_bundle_context_t *ctx) { - act->wireProtocolSvcId = -1L; - - celix_status_t status = pubsubProtocol_create(&(act->wireprotocol)); - if (status == CELIX_SUCCESS) { - /* Set serializertype */ - celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, PUBSUB_PROTOCOL_TYPE_KEY, PUBSUB_WIRE_PROTOCOL_TYPE); - celix_properties_setLong(props, CELIX_FRAMEWORK_SERVICE_RANKING, 5); - - act->protocolSvc.getHeaderSize = pubsubProtocol_getHeaderSize; - act->protocolSvc.getHeaderBufferSize = pubsubProtocol_getHeaderBufferSize; - act->protocolSvc.getSyncHeaderSize = pubsubProtocol_getSyncHeaderSize; - act->protocolSvc.getSyncHeader = pubsubProtocol_getSyncHeader; - act->protocolSvc.getFooterSize = pubsubProtocol_getFooterSize; - act->protocolSvc.isMessageSegmentationSupported = pubsubProtocol_isMessageSegmentationSupported; - - act->protocolSvc.encodeHeader = pubsubProtocol_encodeHeader; - act->protocolSvc.encodePayload = pubsubProtocol_v1_encodePayload; - act->protocolSvc.encodeMetadata = pubsubProtocol_v1_encodeMetadata; - act->protocolSvc.encodeFooter = pubsubProtocol_encodeFooter; - - act->protocolSvc.decodeHeader = pubsubProtocol_decodeHeader; - act->protocolSvc.decodePayload = pubsubProtocol_v1_decodePayload; - act->protocolSvc.decodeMetadata = pubsubProtocol_v1_decodeMetadata; - act->protocolSvc.decodeFooter = pubsubProtocol_decodeFooter; - - act->wireProtocolSvcId = celix_bundleContext_registerService(ctx, &act->protocolSvc, PUBSUB_PROTOCOL_SERVICE_NAME, props); - } - return status; -} - -static int ps_wp_stop(ps_wp_activator_t *act, celix_bundle_context_t *ctx) { - celix_bundleContext_unregisterService(ctx, act->wireProtocolSvcId); - act->wireProtocolSvcId = -1L; - pubsubProtocol_destroy(act->wireprotocol); - return CELIX_SUCCESS; -} - -CELIX_GEN_BUNDLE_ACTIVATOR(ps_wp_activator_t, ps_wp_start, ps_wp_stop) \ No newline at end of file diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/src/pubsub_wire_protocol_impl.c b/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/src/pubsub_wire_protocol_impl.c deleted file mode 100644 index 7634315e0..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/src/pubsub_wire_protocol_impl.c +++ /dev/null @@ -1,177 +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 -#include -#include -#include - -#include "celix_compiler.h" -#include "celix_properties.h" - -#include "pubsub_wire_protocol_impl.h" -#include "pubsub_wire_protocol_common.h" - - -struct pubsub_protocol_wire_v1 { -}; - -celix_status_t pubsubProtocol_create(pubsub_protocol_wire_v1_t **protocol) { - celix_status_t status = CELIX_SUCCESS; - - *protocol = calloc(1, sizeof(**protocol)); - - if (!*protocol) { - status = CELIX_ENOMEM; - } - else { - // - } - - return status; -} - -celix_status_t pubsubProtocol_destroy(pubsub_protocol_wire_v1_t* protocol) { - celix_status_t status = CELIX_SUCCESS; - free(protocol); - return status; -} - -celix_status_t pubsubProtocol_getHeaderSize(void* handle CELIX_UNUSED, size_t *length) { - *length = sizeof(int) * 5 + sizeof(short) * 2; // header + sync + version = 24 - return CELIX_SUCCESS; -} - -celix_status_t pubsubProtocol_getHeaderBufferSize(void* handle, size_t *length) { - return pubsubProtocol_getHeaderSize(handle, length); -} - -celix_status_t pubsubProtocol_getSyncHeaderSize(void* handle CELIX_UNUSED, size_t *length) { - *length = sizeof(int); - return CELIX_SUCCESS; -} - -celix_status_t pubsubProtocol_getSyncHeader(void* handle CELIX_UNUSED, void *syncHeader) { - pubsubProtocol_writeInt(syncHeader, 0, true, PROTOCOL_WIRE_V1_SYNC_HEADER); - return CELIX_SUCCESS; -} - -celix_status_t pubsubProtocol_getFooterSize(void* handle CELIX_UNUSED, size_t *length) { - *length = 0; - return CELIX_SUCCESS; -} - -celix_status_t pubsubProtocol_isMessageSegmentationSupported(void* handle CELIX_UNUSED, bool *isSupported) { - *isSupported = false; - return CELIX_SUCCESS; -} -celix_status_t pubsubProtocol_encodeHeader(void *handle, pubsub_protocol_message_t *message, void **outBuffer, size_t *outLength) { - celix_status_t status = CELIX_SUCCESS; - // Get HeaderSize - size_t headerSize = 0; - pubsubProtocol_getHeaderSize(handle, &headerSize); - - if (*outBuffer == NULL || headerSize != *outLength) { - free(*outBuffer); - *outBuffer = calloc(1, headerSize); - *outLength = headerSize; - } - if (*outBuffer == NULL) { - status = CELIX_ENOMEM; - } else { - int idx = 0; - idx = pubsubProtocol_writeInt(*outBuffer, idx, true, PROTOCOL_WIRE_V1_SYNC_HEADER); - idx = pubsubProtocol_writeInt(*outBuffer, idx, true, PROTOCOL_WIRE_V1_ENVELOPE_VERSION); - idx = pubsubProtocol_writeInt(*outBuffer, idx, true, message->header.msgId); - idx = pubsubProtocol_writeShort(*outBuffer, idx, true, message->header.msgMajorVersion); - idx = pubsubProtocol_writeShort(*outBuffer, idx, true, message->header.msgMinorVersion); - idx = pubsubProtocol_writeInt(*outBuffer, idx, true, message->header.payloadSize); - idx = pubsubProtocol_writeInt(*outBuffer, idx, true, message->header.metadataSize); - - *outLength = idx; - } - - return status; -} - -celix_status_t pubsubProtocol_v1_encodePayload(void *handle CELIX_UNUSED, pubsub_protocol_message_t *message, void **outBuffer, size_t *outLength) { - message->header.convertEndianess = true; - return pubsubProtocol_encodePayload(message, outBuffer, outLength); -} - -celix_status_t pubsubProtocol_v1_encodeMetadata(void *handle CELIX_UNUSED, pubsub_protocol_message_t *message, void **bufferInOut, size_t *bufferLengthInOut, size_t *bufferContentLengthOut) { - message->header.convertEndianess = true; - return pubsubProtocol_encodeMetadata(message, (char**)bufferInOut, bufferLengthInOut, bufferContentLengthOut); -} - -celix_status_t pubsubProtocol_encodeFooter(void *handle, pubsub_protocol_message_t *message CELIX_UNUSED, void **outBuffer CELIX_UNUSED, size_t *outLength) { - message->header.convertEndianess = true; - return pubsubProtocol_getFooterSize(handle, outLength); -} - -celix_status_t pubsubProtocol_v1_decodePayload(void* handle CELIX_UNUSED, void *data, size_t length, pubsub_protocol_message_t *message){ - message->header.convertEndianess = true; - return pubsubProtocol_decodePayload(data, length, message); -} - -celix_status_t pubsubProtocol_v1_decodeMetadata(void* handle CELIX_UNUSED, void *data, size_t length, pubsub_protocol_message_t *message) { - message->header.convertEndianess = true; - return pubsubProtocol_decodeMetadata(data, length, message); -} - -celix_status_t pubsubProtocol_decodeFooter(void* handle CELIX_UNUSED, void *data CELIX_UNUSED, size_t length CELIX_UNUSED, pubsub_protocol_message_t *message CELIX_UNUSED) { - celix_status_t status = CELIX_SUCCESS; - return status; -} - -celix_status_t pubsubProtocol_decodeHeader(void *handle, void *data, size_t length, pubsub_protocol_message_t *message) { - celix_status_t status = CELIX_SUCCESS; - - int idx = 0; - size_t headerSize = 0; - pubsubProtocol_getHeaderSize(handle, &headerSize); - if (length == headerSize) { - unsigned int sync; - idx = pubsubProtocol_readInt(data, idx, true, &sync); - if (sync != PROTOCOL_WIRE_V1_SYNC_HEADER) { - status = CELIX_ILLEGAL_ARGUMENT; - } else { - unsigned int envelopeVersion; - idx = pubsubProtocol_readInt(data, idx, true, &envelopeVersion); - if (envelopeVersion != PROTOCOL_WIRE_V1_ENVELOPE_VERSION) { - status = CELIX_ILLEGAL_ARGUMENT; - } else { - idx = pubsubProtocol_readInt(data, idx, true, &message->header.msgId); - idx = pubsubProtocol_readShort(data, idx, true, &message->header.msgMajorVersion); - idx = pubsubProtocol_readShort(data, idx, true, &message->header.msgMinorVersion); - idx = pubsubProtocol_readInt(data, idx, true, &message->header.payloadSize); - pubsubProtocol_readInt(data, idx, true, &message->header.metadataSize); - message->header.convertEndianess = true; - // Set message segmentation parameters to defaults - message->header.seqNr = 0; - message->header.payloadPartSize = message->header.payloadSize; - message->header.payloadOffset = 0; - message->header.isLastSegment = 0x1; - } - } - } else { - status = CELIX_ILLEGAL_ARGUMENT; - } - return status; -} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/src/pubsub_wire_protocol_impl.h b/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/src/pubsub_wire_protocol_impl.h deleted file mode 100644 index f6c40f685..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v1/src/pubsub_wire_protocol_impl.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 PUBSUB_PROTOCOL_WIRE_H_ -#define PUBSUB_PROTOCOL_WIRE_H_ - -#include "pubsub_protocol.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define PUBSUB_WIRE_PROTOCOL_TYPE "envelope-v1" - -typedef struct pubsub_protocol_wire_v1 pubsub_protocol_wire_v1_t; - -celix_status_t pubsubProtocol_create(pubsub_protocol_wire_v1_t **protocol); -celix_status_t pubsubProtocol_destroy(pubsub_protocol_wire_v1_t* protocol); - -celix_status_t pubsubProtocol_getHeaderSize(void *handle, size_t *length); -celix_status_t pubsubProtocol_getHeaderBufferSize(void *handle, size_t *length); -celix_status_t pubsubProtocol_getSyncHeaderSize(void *handle, size_t *length); -celix_status_t pubsubProtocol_getSyncHeader(void* handle, void *syncHeader); -celix_status_t pubsubProtocol_getFooterSize(void* handle, size_t *length); -celix_status_t pubsubProtocol_isMessageSegmentationSupported(void* handle, bool *isSupported); - -celix_status_t pubsubProtocol_encodeHeader(void *handle, pubsub_protocol_message_t *message, void **outBuffer, size_t *outLength); -celix_status_t pubsubProtocol_v1_encodePayload(void *handle, pubsub_protocol_message_t *message, void **outBuffer, size_t *outLength); -celix_status_t pubsubProtocol_v1_encodeMetadata(void *handle, pubsub_protocol_message_t *message, void **bufferInOut, size_t *bufferLengthInOut, size_t *bufferContentLengthOut); -celix_status_t pubsubProtocol_encodeFooter(void *handle, pubsub_protocol_message_t *message, void **outBuffer, size_t *outLength); - -celix_status_t pubsubProtocol_decodeHeader(void* handle, void *data, size_t length, pubsub_protocol_message_t *message); -celix_status_t pubsubProtocol_v1_decodePayload(void* handle, void *data, size_t length, pubsub_protocol_message_t *message); -celix_status_t pubsubProtocol_v1_decodeMetadata(void* handle, void *data, size_t length, pubsub_protocol_message_t *message); -celix_status_t pubsubProtocol_decodeFooter(void* handle, void *data, size_t length, pubsub_protocol_message_t *message); - -#ifdef __cplusplus -} -#endif - -#endif /* PUBSUB_PROTOCOL_WIRE_H_ */ diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/CMakeLists.txt b/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/CMakeLists.txt deleted file mode 100644 index 87e8fefef..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -celix_subproject(PUBSUB_WIRE_PROTOCOL_V2 "Option to enable building the PubSub Wire Protocol v2 bundle" ON) -if (PUBSUB_WIRE_PROTOCOL_V2) - add_library(celix_wire_protocol_v2_impl STATIC - src/pubsub_wire_v2_protocol_impl.c - ) - target_include_directories(celix_wire_protocol_v2_impl PRIVATE src) - target_link_libraries(celix_wire_protocol_v2_impl PUBLIC Celix::pubsub_spi) - target_link_libraries(celix_wire_protocol_v2_impl PUBLIC celix_pubsub_protocol_lib) - - add_celix_bundle(celix_pubsub_protocol_wire_v2 - BUNDLE_SYMBOLICNAME "apache_celix_pubsub_protocol_wire_v2" - VERSION "1.0.1" - GROUP "Celix/PubSub" - SOURCES - src/ps_wire_v2_protocol_activator.c - ) - target_include_directories(celix_pubsub_protocol_wire_v2 PRIVATE src) - target_link_libraries(celix_pubsub_protocol_wire_v2 PRIVATE Celix::pubsub_utils) - target_link_libraries(celix_pubsub_protocol_wire_v2 PRIVATE celix_wire_protocol_v2_impl) - - install_celix_bundle(celix_pubsub_protocol_wire_v2 EXPORT celix COMPONENT pubsub) - - add_library(Celix::celix_pubsub_protocol_wire_v2 ALIAS celix_pubsub_protocol_wire_v2) - - if (ENABLE_TESTING) - add_subdirectory(gtest) - endif() -endif () \ No newline at end of file diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/gtest/CMakeLists.txt b/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/gtest/CMakeLists.txt deleted file mode 100644 index 4d557a0fe..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/gtest/CMakeLists.txt +++ /dev/null @@ -1,28 +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. - -set(SOURCES - src/main.cc - src/PS_WP_v2_tests.cc - ) -add_executable(celix_pswp_v2_tests ${SOURCES}) -#target_include_directories(celix_cxx_pswp_tests SYSTEM PRIVATE gtest) -target_include_directories(celix_pswp_v2_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../src) -target_link_libraries(celix_pswp_v2_tests PRIVATE celix_wire_protocol_v2_impl GTest::gtest Celix::pubsub_spi) - -add_test(NAME celix_pswp_v2_tests COMMAND celix_pswp_v2_tests) -setup_target_for_coverage(celix_pswp_v2_tests SCAN_DIR ..) \ No newline at end of file diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/gtest/src/PS_WP_v2_tests.cc b/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/gtest/src/PS_WP_v2_tests.cc deleted file mode 100644 index 3a1dbda0f..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/gtest/src/PS_WP_v2_tests.cc +++ /dev/null @@ -1,309 +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 -#include -#include - -#include - -#include "gtest/gtest.h" - -#include "pubsub_wire_v2_protocol_impl.h" -#include "celix_byteswap.h" -#include - -class WireProtocolV2Test : public ::testing::Test { -public: - WireProtocolV2Test() = default; - ~WireProtocolV2Test() override = default; - -}; - - -TEST_F(WireProtocolV2Test, WireProtocolV2Test_EncodeHeader_Test) { // NOLINT(cert-err58-cpp) - pubsub_protocol_wire_v2_t *wireprotocol; - pubsubProtocol_wire_v2_create(&wireprotocol); - - pubsub_protocol_message_t message; - message.header.msgId = 1; - message.header.seqNr = 4; - message.header.msgMajorVersion = 0; - message.header.msgMinorVersion = 0; - message.header.payloadSize = 2; - message.header.metadataSize = 3; - message.header.payloadPartSize = 4; - message.header.payloadOffset = 2; - message.header.isLastSegment = 1; - message.header.convertEndianess = 1; - - void *headerData = nullptr; - size_t headerLength = 0; - celix_status_t status = pubsubProtocol_wire_v2_encodeHeader(nullptr, &message, &headerData, &headerLength); - - unsigned char exp[40]; - uint32_t s = bswap_32(0xABBADEAF); - memcpy(exp, &s, sizeof(uint32_t)); - uint32_t e = 0x02000000; //envelope version - memcpy(exp+4, &e, sizeof(uint32_t)); - uint32_t m = 0x01000000; //msg id - memcpy(exp+8, &m, sizeof(uint32_t)); - uint32_t seq = 0x04000000; //seqnr - memcpy(exp+12, &seq, sizeof(uint32_t)); - uint32_t v = 0x00000000; - memcpy(exp+16, &v, sizeof(uint32_t)); - uint32_t ps = 0x02000000; - memcpy(exp+20, &ps, sizeof(uint32_t)); - uint32_t ms = 0x03000000; - memcpy(exp+24, &ms, sizeof(uint32_t)); - uint32_t pps = 0x04000000; - memcpy(exp+28, &pps, sizeof(uint32_t)); - uint32_t ppo = 0x02000000; - memcpy(exp+32, &ppo, sizeof(uint32_t)); - uint32_t ils = 0x01000000; - memcpy(exp+36, &ils, sizeof(uint32_t)); - - ASSERT_EQ(status, CELIX_SUCCESS); - ASSERT_EQ(40, headerLength); - for (int i = 0; i < 40; i++) { - ASSERT_EQ(((unsigned char*) headerData)[i], exp[i]); - } - - pubsubProtocol_wire_v2_destroy(wireprotocol); - free(headerData); -} - -TEST_F(WireProtocolV2Test, WireProtocolV2Test_EncodeHeader_TestWithExistingBuffer) { - pubsub_protocol_wire_v2_t *wireprotocol; - pubsubProtocol_wire_v2_create(&wireprotocol); - - pubsub_protocol_message_t message; - message.header.msgId = 1; - message.header.seqNr = 4; - message.header.msgMajorVersion = 0; - message.header.msgMinorVersion = 0; - message.header.payloadSize = 2; - message.header.metadataSize = 3; - message.header.payloadPartSize = 4; - message.header.payloadOffset = 2; - message.header.isLastSegment = 1; - message.header.convertEndianess = 1; - - void *headerData = malloc(3); - size_t headerLength = 3; - - //calling with too small of a buffer (new buffer with new length should be created). - celix_status_t status = pubsubProtocol_wire_v2_encodeHeader(nullptr, &message, &headerData, &headerLength); - EXPECT_EQ(status, CELIX_SUCCESS); - EXPECT_EQ(40, headerLength); - - void* orgHeaderDataPointer = headerData; - //calling with matching buffer, buffer will be re-used. - status = pubsubProtocol_wire_v2_encodeHeader(nullptr, &message, &headerData, &headerLength); - EXPECT_EQ(status, CELIX_SUCCESS); - EXPECT_EQ(40, headerLength); - EXPECT_EQ(headerData, orgHeaderDataPointer); - - pubsubProtocol_wire_v2_destroy(wireprotocol); - free(headerData); -} - -TEST_F(WireProtocolV2Test, WireProtocolV2Test_DecodeHeader_Test) { // NOLINT(cert-err58-cpp) - pubsub_protocol_wire_v2_t *wireprotocol; - pubsubProtocol_wire_v2_create(&wireprotocol); - - unsigned char exp[40]; - uint32_t s = bswap_32(0xABBADEAF); //sync - memcpy(exp, &s, sizeof(uint32_t)); - uint32_t e = 0x02000000; //envelope version - memcpy(exp+4, &e, sizeof(uint32_t)); - uint32_t m = 0x01000000; //msg id - memcpy(exp+8, &m, sizeof(uint32_t)); - uint32_t seq = 0x08000000; //seqnr - memcpy(exp+12, &seq, sizeof(uint32_t)); - uint32_t v = 0x00000000; - memcpy(exp+16, &v, sizeof(uint32_t)); - uint32_t ps = 0x02000000; - memcpy(exp+20, &ps, sizeof(uint32_t)); - uint32_t ms = 0x03000000; - memcpy(exp+24, &ms, sizeof(uint32_t)); - uint32_t pps = 0x04000000; - memcpy(exp+28, &pps, sizeof(uint32_t)); - uint32_t ppo = 0x02000000; - memcpy(exp+32, &ppo, sizeof(uint32_t)); - uint32_t ils = 0x01000000; - memcpy(exp+36, &ils, sizeof(uint32_t)); - - pubsub_protocol_message_t message; - - celix_status_t status = pubsubProtocol_wire_v2_decodeHeader(nullptr, exp, 40, &message); - - ASSERT_EQ(CELIX_SUCCESS, status); - ASSERT_EQ(1, message.header.msgId); - ASSERT_EQ(8, message.header.seqNr); - ASSERT_EQ(0, message.header.msgMajorVersion); - ASSERT_EQ(0, message.header.msgMinorVersion); - ASSERT_EQ(2, message.header.payloadSize); - ASSERT_EQ(3, message.header.metadataSize); - ASSERT_EQ(4, message.header.payloadPartSize); - ASSERT_EQ(2, message.header.payloadOffset); - ASSERT_EQ(1, message.header.isLastSegment); - ASSERT_EQ(1, message.header.convertEndianess); - - pubsubProtocol_wire_v2_destroy(wireprotocol); -} - -TEST_F(WireProtocolV2Test, WireProtocolV2Test_DecodeHeader_IncorrectSync_Test) { // NOLINT(cert-err58-cpp) - pubsub_protocol_wire_v2_t *wireprotocol; - pubsubProtocol_wire_v2_create(&wireprotocol); - - unsigned char exp[40]; - uint32_t s = 0xBAABABBA; - memcpy(exp, &s, sizeof(uint32_t)); - uint32_t e = 0x01000000; - memcpy(exp+4, &e, sizeof(uint32_t)); - uint32_t m = 0x01000000; - memcpy(exp+8, &m, sizeof(uint32_t)); - uint32_t seq = 0x08000000; - memcpy(exp+12, &seq, sizeof(uint32_t)); - uint32_t v = 0x00000000; - memcpy(exp+16, &v, sizeof(uint32_t)); - uint32_t ps = 0x02000000; - memcpy(exp+20, &ps, sizeof(uint32_t)); - uint32_t ms = 0x03000000; - memcpy(exp+24, &ms, sizeof(uint32_t)); - - pubsub_protocol_message_t message; - - celix_status_t status = pubsubProtocol_wire_v2_decodeHeader(nullptr, exp, 40, &message); - - ASSERT_EQ(CELIX_ILLEGAL_ARGUMENT, status); - - pubsubProtocol_wire_v2_destroy(wireprotocol); -} - -TEST_F(WireProtocolV2Test, WireProtocolV2Test_DecodeHeader_IncorrectVersion_Test) { // NOLINT(cert-err58-cpp) - pubsub_protocol_wire_v2_t *wireprotocol; - pubsubProtocol_wire_v2_create(&wireprotocol); - - unsigned char exp[40]; - uint32_t s = 0xABBADEAF; - memcpy(exp, &s, sizeof(uint32_t)); - uint32_t e = 0x02000000; - memcpy(exp+4, &e, sizeof(uint32_t)); - uint32_t m = 0x01000000; - memcpy(exp+8, &m, sizeof(uint32_t)); - uint32_t seq = 0x08000000; - memcpy(exp+12, &seq, sizeof(uint32_t)); - uint32_t v = 0x00000000; - memcpy(exp+16, &v, sizeof(uint32_t)); - uint32_t ps = 0x02000000; - memcpy(exp+20, &ps, sizeof(uint32_t)); - uint32_t ms = 0x03000000; - memcpy(exp+24, &ms, sizeof(uint32_t)); - - pubsub_protocol_message_t message; - - celix_status_t status = pubsubProtocol_wire_v2_decodeHeader(nullptr, exp, 40, &message); - - ASSERT_EQ(CELIX_ILLEGAL_ARGUMENT, status); - - pubsubProtocol_wire_v2_destroy(wireprotocol); -} - -TEST_F(WireProtocolV2Test, WireProtocolV2Test_EncodeFooter_Test) { // NOLINT(cert-err58-cpp) - pubsub_protocol_wire_v2_t *wireprotocol; - pubsubProtocol_wire_v2_create(&wireprotocol); - - pubsub_protocol_message_t message; - message.header.convertEndianess = 0; - - void *footerData = nullptr; - size_t footerLength = 0; - celix_status_t status = pubsubProtocol_wire_v2_encodeFooter(nullptr, &message, &footerData, &footerLength); - - unsigned char exp[4]; - uint32_t s = 0xDEAFABBA; - memcpy(exp, &s, sizeof(uint32_t)); - ASSERT_EQ(status, CELIX_SUCCESS); - ASSERT_EQ(4, footerLength); - for (int i = 0; i < 4; i++) { - if (((unsigned char*) footerData)[i] != exp[i]) { - std::cerr << "error at index " << std::to_string(i) << std::endl; - } - ASSERT_EQ(((unsigned char*) footerData)[i], exp[i]); - } - pubsubProtocol_wire_v2_destroy(wireprotocol); - free(footerData); -} - -TEST_F(WireProtocolV2Test, WireProtocolV2Test_EncodeFooter_TestWithExistingBuffer) { - pubsub_protocol_wire_v2_t *wireprotocol; - pubsubProtocol_wire_v2_create(&wireprotocol); - - pubsub_protocol_message_t message; - message.header.convertEndianess = 0; - - void *footerData = malloc(3); - size_t footerLength = 3; - //calling with too small of a buffer (new buffer with new length should be created). - celix_status_t status = pubsubProtocol_wire_v2_encodeFooter(nullptr, &message, &footerData, &footerLength); - EXPECT_EQ(status, CELIX_SUCCESS); - EXPECT_NE(3, footerLength); - - - void* orgFooterDataPointer = footerData; - //calling with matching buffer, buffer will be re-used. - status = pubsubProtocol_wire_v2_encodeFooter(nullptr, &message, &footerData, &footerLength); - EXPECT_EQ(status, CELIX_SUCCESS); - EXPECT_EQ(footerData, orgFooterDataPointer); - - pubsubProtocol_wire_v2_destroy(wireprotocol); - free(footerData); -} - -TEST_F(WireProtocolV2Test, WireProtocolV2Test_DecodeFooter_Test) { // NOLINT(cert-err58-cpp) - pubsub_protocol_wire_v2_t *wireprotocol; - pubsubProtocol_wire_v2_create(&wireprotocol); - - unsigned char exp[4]; - uint32_t s = 0xDEAFABBA; - memcpy(exp, &s, sizeof(uint32_t)); - pubsub_protocol_message_t message; - message.header.convertEndianess = 0; - celix_status_t status = pubsubProtocol_wire_v2_decodeFooter(nullptr, exp, 4, &message); - - ASSERT_EQ(CELIX_SUCCESS, status); - pubsubProtocol_wire_v2_destroy(wireprotocol); -} - -TEST_F(WireProtocolV2Test, WireProtocolV2Test_DecodeFooter_IncorrectSync_Test) { // NOLINT(cert-err58-cpp) - pubsub_protocol_wire_v2_t *wireprotocol; - pubsubProtocol_wire_v2_create(&wireprotocol); - - unsigned char exp[4]; - uint32_t s = 0xABBABAAB; - memcpy(exp, &s, sizeof(uint32_t)); - pubsub_protocol_message_t message; - - celix_status_t status = pubsubProtocol_wire_v2_decodeFooter(nullptr, exp, 4, &message); - ASSERT_EQ(CELIX_ILLEGAL_ARGUMENT, status); - - pubsubProtocol_wire_v2_destroy(wireprotocol); -} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/gtest/src/main.cc b/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/gtest/src/main.cc deleted file mode 100644 index 09731c411..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/gtest/src/main.cc +++ /dev/null @@ -1,26 +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 - -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - int rc = RUN_ALL_TESTS(); - return rc; -} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/src/ps_wire_v2_protocol_activator.c b/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/src/ps_wire_v2_protocol_activator.c deleted file mode 100644 index 000119afb..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/src/ps_wire_v2_protocol_activator.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include - -#include "celix_bundle_activator.h" -#include "celix_constants.h" -#include "pubsub_wire_v2_protocol_impl.h" - -typedef struct ps_wp_activator { - pubsub_protocol_wire_v2_t *wireprotocol; - - pubsub_protocol_service_t protocolSvc; - long wireProtocolSvcId; -} ps_wp_activator_t; - -static int ps_wp_start(ps_wp_activator_t *act, celix_bundle_context_t *ctx) { - act->wireProtocolSvcId = -1L; - - celix_status_t status = pubsubProtocol_wire_v2_create(&(act->wireprotocol)); - if (status == CELIX_SUCCESS) { - /* Set serializertype */ - celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, PUBSUB_PROTOCOL_TYPE_KEY, PUBSUB_WIRE_V2_PROTOCOL_TYPE); - celix_properties_setLong(props, CELIX_FRAMEWORK_SERVICE_RANKING, 10); - - act->protocolSvc.getHeaderSize = pubsubProtocol_wire_v2_getHeaderSize; - act->protocolSvc.getHeaderBufferSize = pubsubProtocol_wire_v2_getHeaderBufferSize; - act->protocolSvc.getSyncHeaderSize = pubsubProtocol_wire_v2_getSyncHeaderSize; - act->protocolSvc.getSyncHeader = pubsubProtocol_wire_v2_getSyncHeader; - act->protocolSvc.getFooterSize = pubsubProtocol_wire_v2_getFooterSize; - act->protocolSvc.isMessageSegmentationSupported = pubsubProtocol_wire_v2_isMessageSegmentationSupported; - - act->protocolSvc.encodeHeader = pubsubProtocol_wire_v2_encodeHeader; - act->protocolSvc.encodePayload = pubsubProtocol_wire_v2_encodePayload; - act->protocolSvc.encodeMetadata = pubsubProtocol_wire_v2_encodeMetadata; - act->protocolSvc.encodeFooter = pubsubProtocol_wire_v2_encodeFooter; - - act->protocolSvc.decodeHeader = pubsubProtocol_wire_v2_decodeHeader; - act->protocolSvc.decodePayload = pubsubProtocol_wire_v2_decodePayload; - act->protocolSvc.decodeMetadata = pubsubProtocol_wire_v2_decodeMetadata; - act->protocolSvc.decodeFooter = pubsubProtocol_wire_v2_decodeFooter; - - act->wireProtocolSvcId = celix_bundleContext_registerService(ctx, &act->protocolSvc, PUBSUB_PROTOCOL_SERVICE_NAME, props); - } - return status; -} - -static int ps_wp_stop(ps_wp_activator_t *act, celix_bundle_context_t *ctx) { - celix_bundleContext_unregisterService(ctx, act->wireProtocolSvcId); - act->wireProtocolSvcId = -1L; - pubsubProtocol_wire_v2_destroy(act->wireprotocol); - return CELIX_SUCCESS; -} - -CELIX_GEN_BUNDLE_ACTIVATOR(ps_wp_activator_t, ps_wp_start, ps_wp_stop) \ No newline at end of file diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/src/pubsub_wire_v2_protocol_impl.c b/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/src/pubsub_wire_v2_protocol_impl.c deleted file mode 100644 index 9539dc996..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/src/pubsub_wire_v2_protocol_impl.c +++ /dev/null @@ -1,210 +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 -#include - -#include "celix_compiler.h" -#include "celix_properties.h" - -#include "pubsub_wire_v2_protocol_impl.h" -#include "pubsub_wire_protocol_common.h" - -struct pubsub_protocol_wire_v2 { -}; -celix_status_t pubsubProtocol_wire_v2_create(pubsub_protocol_wire_v2_t **protocol) { - celix_status_t status = CELIX_SUCCESS; - - *protocol = calloc(1, sizeof(**protocol)); - - if (!*protocol) { - status = CELIX_ENOMEM; - } - else {} - return status; -} - -celix_status_t pubsubProtocol_wire_v2_destroy(pubsub_protocol_wire_v2_t* protocol) { - celix_status_t status = CELIX_SUCCESS; - free(protocol); - return status; -} - -celix_status_t pubsubProtocol_wire_v2_getHeaderSize(void* handle, size_t *length) { - *length = sizeof(int) * 9 + sizeof(short) * 2; // header + sync + version = 36 - return CELIX_SUCCESS; -} - -celix_status_t pubsubProtocol_wire_v2_getHeaderBufferSize(void* handle, size_t *length) { - return pubsubProtocol_wire_v2_getHeaderSize(handle, length); -} - -celix_status_t pubsubProtocol_wire_v2_getSyncHeaderSize(void* handle, size_t *length) { - *length = sizeof(int); - return CELIX_SUCCESS; -} - -celix_status_t pubsubProtocol_wire_v2_getSyncHeader(void* handle, void *syncHeader) { - pubsubProtocol_writeInt(syncHeader, 0, false, PROTOCOL_WIRE_V2_SYNC_HEADER); - return CELIX_SUCCESS; -} - -celix_status_t pubsubProtocol_wire_v2_getFooterSize(void* handle, size_t *length) { - *length = sizeof(int); - return CELIX_SUCCESS; -} - -celix_status_t pubsubProtocol_wire_v2_isMessageSegmentationSupported(void* handle, bool *isSupported) { - *isSupported = true; - return CELIX_SUCCESS; -} - -celix_status_t pubsubProtocol_wire_v2_encodeHeader(void *handle, pubsub_protocol_message_t *message, void **outBuffer, size_t *outLength) { - celix_status_t status = CELIX_SUCCESS; - // Get HeaderSize - size_t headerSize = 0; - pubsubProtocol_wire_v2_getHeaderSize(handle, &headerSize); - - if (*outBuffer == NULL || *outLength != headerSize) { - //allocated or reallocate memory for header - free(*outBuffer); - *outBuffer = malloc(headerSize); - *outLength = headerSize; - } - if (*outBuffer == NULL) { - status = CELIX_ENOMEM; - } else { - int idx = 0; - unsigned int convert = message->header.convertEndianess; - idx = pubsubProtocol_writeInt(*outBuffer, idx, convert, PROTOCOL_WIRE_V2_SYNC_HEADER); - idx = pubsubProtocol_writeInt(*outBuffer, idx, convert, PROTOCOL_WIRE_V2_ENVELOPE_VERSION); - idx = pubsubProtocol_writeInt(*outBuffer, idx, convert, message->header.msgId); - idx = pubsubProtocol_writeInt(*outBuffer, idx, convert, message->header.seqNr); - idx = pubsubProtocol_writeShort(*outBuffer, idx, convert, message->header.msgMajorVersion); - idx = pubsubProtocol_writeShort(*outBuffer, idx, convert, message->header.msgMinorVersion); - idx = pubsubProtocol_writeInt(*outBuffer, idx, convert, message->header.payloadSize); - idx = pubsubProtocol_writeInt(*outBuffer, idx, convert, message->header.metadataSize); - idx = pubsubProtocol_writeInt(*outBuffer, idx, convert, message->header.payloadPartSize); - idx = pubsubProtocol_writeInt(*outBuffer, idx, convert, message->header.payloadOffset); - idx = pubsubProtocol_writeInt(*outBuffer, idx, convert, message->header.isLastSegment); - *outLength = idx; - } - - return status; -} - -celix_status_t pubsubProtocol_wire_v2_encodeFooter(void *handle, pubsub_protocol_message_t *message, void **outBuffer, size_t *outLength) { - celix_status_t status = CELIX_SUCCESS; - // Get HeaderSize - size_t footerSize = 0; - pubsubProtocol_wire_v2_getFooterSize(handle, &footerSize); - - if (*outBuffer == NULL || *outLength != footerSize) { - //allocated or reallocate memory for footer - free(*outBuffer); - *outBuffer = malloc(footerSize); - *outLength = footerSize; - } - if (*outBuffer == NULL) { - status = CELIX_ENOMEM; - } else { - int idx = 0; - unsigned int convert = message->header.convertEndianess; - idx = pubsubProtocol_writeInt(*outBuffer, idx, convert, PROTOCOL_WIRE_V2_SYNC_FOOTER); - *outLength = idx; - } - - return status; -} - -celix_status_t pubsubProtocol_wire_v2_decodeHeader(void* handle, void *data, size_t length, pubsub_protocol_message_t *message) { - celix_status_t status = CELIX_SUCCESS; - - int idx = 0; - size_t headerSize = 0; - pubsubProtocol_wire_v2_getHeaderSize(handle, &headerSize); - if (length == headerSize) { - unsigned int sync = 0; - unsigned int sync_endianess = 0; - idx = pubsubProtocol_readInt(data, idx, false, &sync); - pubsubProtocol_readInt(data, 0, true, &sync_endianess); - message->header.convertEndianess = (sync_endianess == PROTOCOL_WIRE_V2_SYNC_HEADER) ? true : false; - if ((sync != PROTOCOL_WIRE_V2_SYNC_HEADER) && (sync_endianess != PROTOCOL_WIRE_V2_SYNC_HEADER)) { - status = CELIX_ILLEGAL_ARGUMENT; - } else { - unsigned int envelopeVersion; - unsigned int convert = message->header.convertEndianess; - idx = pubsubProtocol_readInt(data, idx, convert, &envelopeVersion); - if (envelopeVersion != PROTOCOL_WIRE_V2_ENVELOPE_VERSION) { - fprintf(stderr, "found sync %x and converted sync %x\n", sync, sync_endianess); - fprintf(stderr, "wrong envelop version\n"); - fprintf(stderr, "Got %i, need %i\n", envelopeVersion, PROTOCOL_WIRE_V2_ENVELOPE_VERSION); - status = CELIX_ILLEGAL_ARGUMENT; - } else { - idx = pubsubProtocol_readInt(data, idx, convert, &message->header.msgId); - idx = pubsubProtocol_readInt(data, idx, convert, &message->header.seqNr); - idx = pubsubProtocol_readShort(data, idx, convert, &message->header.msgMajorVersion); - idx = pubsubProtocol_readShort(data, idx, convert, &message->header.msgMinorVersion); - idx = pubsubProtocol_readInt(data, idx, convert, &message->header.payloadSize); - idx = pubsubProtocol_readInt(data, idx, convert, &message->header.metadataSize); - idx = pubsubProtocol_readInt(data, idx, convert, &message->header.payloadPartSize); - idx = pubsubProtocol_readInt(data, idx, convert, &message->header.payloadOffset); - pubsubProtocol_readInt(data, idx, convert, &message->header.isLastSegment); - } - } - } else { - status = CELIX_ILLEGAL_ARGUMENT; - } - return status; -} - -celix_status_t pubsubProtocol_wire_v2_decodeFooter(void* handle, void *data, size_t length, pubsub_protocol_message_t *message) { - celix_status_t status = CELIX_SUCCESS; - - int idx = 0; - size_t footerSize = 0; - pubsubProtocol_wire_v2_getFooterSize(handle, &footerSize); - if (length == footerSize) { - unsigned int footerSync; - unsigned int convert = message->header.convertEndianess; - idx = pubsubProtocol_readInt(data, idx, convert, &footerSync); - if (footerSync != PROTOCOL_WIRE_V2_SYNC_FOOTER) { - status = CELIX_ILLEGAL_ARGUMENT; - } - } else { - status = CELIX_ILLEGAL_ARGUMENT; - } - return status; -} - -celix_status_t pubsubProtocol_wire_v2_encodePayload(void* handle CELIX_UNUSED, pubsub_protocol_message_t *message, void **outBuffer, size_t *outLength) { - return pubsubProtocol_encodePayload(message, outBuffer, outLength); -} - -celix_status_t pubsubProtocol_wire_v2_encodeMetadata(void *handle, pubsub_protocol_message_t *message, void **bufferInOut, size_t *bufferLengthInOut, size_t* bufferContentLengthOut) { - return pubsubProtocol_encodeMetadata(message, (char**)bufferInOut, bufferLengthInOut, bufferContentLengthOut); -} - -celix_status_t pubsubProtocol_wire_v2_decodePayload(void* handle CELIX_UNUSED, void *data, size_t length, pubsub_protocol_message_t *message) { - return pubsubProtocol_decodePayload(data, length, message); -} - -celix_status_t pubsubProtocol_wire_v2_decodeMetadata(void* handle CELIX_UNUSED, void *data, size_t length, pubsub_protocol_message_t *message) { - return pubsubProtocol_decodeMetadata(data, length, message); -} diff --git a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/src/pubsub_wire_v2_protocol_impl.h b/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/src/pubsub_wire_v2_protocol_impl.h deleted file mode 100644 index 22df6ec9e..000000000 --- a/bundles/pubsub/pubsub_protocol/pubsub_protocol_wire_v2/src/pubsub_wire_v2_protocol_impl.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef PUBSUB_PROTOCOL_WIRE_V2_H_ -#define PUBSUB_PROTOCOL_WIRE_V2_H_ - -#include "pubsub_protocol.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define PUBSUB_WIRE_V2_PROTOCOL_TYPE "envelope-v2" - -typedef struct pubsub_protocol_wire_v2 pubsub_protocol_wire_v2_t; - -celix_status_t pubsubProtocol_wire_v2_create(pubsub_protocol_wire_v2_t **protocol); -celix_status_t pubsubProtocol_wire_v2_destroy(pubsub_protocol_wire_v2_t* protocol); - -celix_status_t pubsubProtocol_wire_v2_getHeaderSize(void *handle, size_t *length); -celix_status_t pubsubProtocol_wire_v2_getHeaderBufferSize(void *handle, size_t *length); -celix_status_t pubsubProtocol_wire_v2_getSyncHeaderSize(void *handle, size_t *length); -celix_status_t pubsubProtocol_wire_v2_getSyncHeader(void* handle, void *syncHeader); -celix_status_t pubsubProtocol_wire_v2_getFooterSize(void* handle, size_t *length); -celix_status_t pubsubProtocol_wire_v2_isMessageSegmentationSupported(void* handle, bool *isSupported); - -celix_status_t pubsubProtocol_wire_v2_encodeHeader(void *handle, pubsub_protocol_message_t *message, void **outBuffer, size_t *outLength); -celix_status_t pubsubProtocol_wire_v2_encodeFooter(void *handle, pubsub_protocol_message_t *message, void **outBuffer, size_t *outLength); - -celix_status_t pubsubProtocol_wire_v2_decodeHeader(void* handle, void *data, size_t length, pubsub_protocol_message_t *message); -celix_status_t pubsubProtocol_wire_v2_decodeFooter(void* handle, void *data, size_t length, pubsub_protocol_message_t *message); - -celix_status_t pubsubProtocol_wire_v2_encodePayload(void* handle, pubsub_protocol_message_t *message, void **outBuffer, size_t *outLength); -celix_status_t pubsubProtocol_wire_v2_encodeMetadata(void *handle, pubsub_protocol_message_t *message, void **bufferInOut, size_t *bufferLengthInOut, size_t* bufferContentLengthOut); -celix_status_t pubsubProtocol_wire_v2_decodePayload(void* handle, void *data, size_t length, pubsub_protocol_message_t *message); -celix_status_t pubsubProtocol_wire_v2_decodeMetadata(void* handle, void *data, size_t length, pubsub_protocol_message_t *message); - -#ifdef __cplusplus -} -#endif - -#endif /* PUBSUB_PROTOCOL_WIRE_V2_H_ */ diff --git a/bundles/pubsub/pubsub_serializer_avrobin/CMakeLists.txt b/bundles/pubsub/pubsub_serializer_avrobin/CMakeLists.txt deleted file mode 100644 index 57ca752ad..000000000 --- a/bundles/pubsub/pubsub_serializer_avrobin/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. - -celix_subproject(PUBSUB_AVROBIN_SERIALIZER "Option to enable building the Avro binary serializer bundle" ON) -if (PUBSUB_AVROBIN_SERIALIZER) - find_package(jansson REQUIRED) - - add_celix_bundle(celix_pubsub_serializer_avrobin - BUNDLE_SYMBOLICNAME "apache_celix_pubsub_serializer_avrobin" - VERSION "1.1.1" - GROUP "Celix/PubSub" - SOURCES - src/ps_avrobin_serializer_activator.c - src/pubsub_avrobin_serialization_provider.c - ) - target_include_directories(celix_pubsub_serializer_avrobin PRIVATE - src - ${JANSSON_INCLUDE_DIR} - ) - target_link_libraries(celix_pubsub_serializer_avrobin PRIVATE Celix::dfi jansson::jansson Celix::log_helper) - target_link_libraries(celix_pubsub_serializer_avrobin PRIVATE Celix::pubsub_spi Celix::pubsub_utils ) - celix_deprecated_utils_headers(celix_pubsub_serializer_avrobin) - celix_deprecated_framework_headers(celix_pubsub_serializer_avrobin) - - install_celix_bundle(celix_pubsub_serializer_avrobin EXPORT celix COMPONENT pubsub) - - add_library(Celix::celix_pubsub_serializer_avrobin ALIAS celix_pubsub_serializer_avrobin) - - if (ENABLE_TESTING) - add_subdirectory(gtest) - endif(ENABLE_TESTING) -endif () \ No newline at end of file diff --git a/bundles/pubsub/pubsub_serializer_avrobin/gtest/CMakeLists.txt b/bundles/pubsub/pubsub_serializer_avrobin/gtest/CMakeLists.txt deleted file mode 100644 index b28e01e4a..000000000 --- a/bundles/pubsub/pubsub_serializer_avrobin/gtest/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -add_celix_bundle(pubsub_avrobin_serialization_descriptor NO_ACTIVATOR VERSION 1.0.0) -celix_bundle_files(pubsub_avrobin_serialization_descriptor - ${CMAKE_CURRENT_SOURCE_DIR}/msg_descriptors/msg_poi1.descriptor - DESTINATION "META-INF/descriptors" -) - -add_executable(test_pubsub_serializer_avrobin - src/PubSubAvrobinSerializationProviderTestSuite.cc -) -celix_deprecated_utils_headers(test_pubsub_serializer_avrobin) -target_link_libraries(test_pubsub_serializer_avrobin PRIVATE Celix::framework Celix::dfi Celix::pubsub_utils GTest::gtest GTest::gtest_main Celix::pubsub_spi) - -add_celix_bundle_dependencies(test_pubsub_serializer_avrobin celix_pubsub_serializer_avrobin pubsub_avrobin_serialization_descriptor) -target_compile_definitions(test_pubsub_serializer_avrobin PRIVATE -DSERIALIZATION_BUNDLE=\"$\") -target_compile_definitions(test_pubsub_serializer_avrobin PRIVATE -DDESCRIPTOR_BUNDLE=\"$\") - -add_test(NAME test_pubsub_serializer_avrobin COMMAND test_pubsub_serializer_avrobin) -setup_target_for_coverage(test_pubsub_serializer_avrobin SCAN_DIR ..) - diff --git a/bundles/pubsub/pubsub_serializer_avrobin/gtest/msg_descriptors/msg_poi1.descriptor b/bundles/pubsub/pubsub_serializer_avrobin/gtest/msg_descriptors/msg_poi1.descriptor deleted file mode 100644 index 705cf2965..000000000 --- a/bundles/pubsub/pubsub_serializer_avrobin/gtest/msg_descriptors/msg_poi1.descriptor +++ /dev/null @@ -1,10 +0,0 @@ -:header -type=message -name=poi1 -version=1.0.0 -:annotations -classname=org.example.PointOfInterest -:types -location={DD lat lon} -:message -{llocation;t location name} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_serializer_avrobin/gtest/src/PubSubAvrobinSerializationProviderTestSuite.cc b/bundles/pubsub/pubsub_serializer_avrobin/gtest/src/PubSubAvrobinSerializationProviderTestSuite.cc deleted file mode 100644 index c52be9d80..000000000 --- a/bundles/pubsub/pubsub_serializer_avrobin/gtest/src/PubSubAvrobinSerializationProviderTestSuite.cc +++ /dev/null @@ -1,110 +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 "gtest/gtest.h" - -#include - -#include "celix_constants.h" -#include "celix_framework_factory.h" -#include "celix_bundle_context.h" -#include "pubsub_message_serialization_service.h" - -class PubSubAvrobinSerializationProviderTestSuite : public ::testing::Test { -public: - PubSubAvrobinSerializationProviderTestSuite() { - auto* props = celix_properties_create(); - celix_properties_set(props, CELIX_FRAMEWORK_CACHE_DIR, ".pubsub_avrobin_serializer_cache"); - auto* fwPtr = celix_frameworkFactory_createFramework(props); - auto* ctxPtr = celix_framework_getFrameworkContext(fwPtr); - fw = std::shared_ptr{fwPtr, [](auto* f) {celix_frameworkFactory_destroyFramework(f);}}; - ctx = std::shared_ptr{ctxPtr, [](auto*){/*nop*/}}; - - const char* descBundleFile = DESCRIPTOR_BUNDLE; - const char* serBundleFile = SERIALIZATION_BUNDLE; - long bndId; - - bndId = celix_bundleContext_installBundle(ctx.get(), descBundleFile, true); - EXPECT_TRUE(bndId >= 0); - - bndId = celix_bundleContext_installBundle(ctx.get(), serBundleFile, true); - EXPECT_TRUE(bndId >= 0); - } - - std::shared_ptr fw{}; - std::shared_ptr ctx{}; -}; - - -TEST_F(PubSubAvrobinSerializationProviderTestSuite, CreateDestroy) { - //checks if the bundles are started and stopped correctly (no mem leaks). -} - -TEST_F(PubSubAvrobinSerializationProviderTestSuite, FindSerializationServices) { - auto* services = celix_bundleContext_findServices(ctx.get(), PUBSUB_MESSAGE_SERIALIZATION_SERVICE_NAME); - EXPECT_EQ(1, celix_arrayList_size(services)); //3 valid, 5 invalid - celix_arrayList_destroy(services); -} - -TEST_F(PubSubAvrobinSerializationProviderTestSuite, SerializeAndDeserializeTest) { - struct poi1 { - struct { - double lat; - double lon; - } location; - const char *name; - }; - - struct data { - poi1* input; - poi1* output; - }; - - poi1 input; - input.location.lat = 42; - input.location.lon = 43; - input.name = "test"; - - poi1 output; - memset(&output, 0, sizeof(output)); - - data dataHandle; - dataHandle.input = &input; - dataHandle.output = &output; - - celix_service_use_options_t opts{}; - opts.filter.serviceName = PUBSUB_MESSAGE_SERIALIZATION_SERVICE_NAME; - opts.filter.filter = "(msg.fqn=poi1)"; - opts.callbackHandle = static_cast(&dataHandle); - opts.use = [](void *handle, void *svc) { - auto *dh = static_cast(handle); - auto* ser = static_cast(svc); - struct iovec* serVec; - size_t serSize; - ser->serialize(ser->handle, dh->input, &serVec, &serSize); - ser->deserialize(ser->handle, serVec, serSize, (void**)(&dh->output)); - - EXPECT_EQ(42, dh->output->location.lat); - - ser->freeSerializedMsg(ser->handle, serVec, serSize); - ser->freeDeserializedMsg(ser->handle, dh->output); - }; - bool called = celix_bundleContext_useServiceWithOptions(ctx.get(), &opts); - EXPECT_TRUE(called); -} diff --git a/bundles/pubsub/pubsub_serializer_avrobin/src/ps_avrobin_serializer_activator.c b/bundles/pubsub/pubsub_serializer_avrobin/src/ps_avrobin_serializer_activator.c deleted file mode 100644 index d60343503..000000000 --- a/bundles/pubsub/pubsub_serializer_avrobin/src/ps_avrobin_serializer_activator.c +++ /dev/null @@ -1,40 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ - -#include -#include - -#include "celix_api.h" -#include "pubsub_avrobin_serialization_provider.h" - -typedef struct psav_activator { - pubsub_serialization_provider_t* avrobinSerializationProvider; -} psav_activator_t; - -static int psav_start(psav_activator_t *act, celix_bundle_context_t *ctx) { - act->avrobinSerializationProvider = pubsub_avrobinSerializationProvider_create(ctx); - return act->avrobinSerializationProvider ? CELIX_SUCCESS : CELIX_BUNDLE_EXCEPTION; -} - -static int psav_stop(psav_activator_t *act, celix_bundle_context_t *ctx) { - pubsub_avrobinSerializationProvider_destroy(act->avrobinSerializationProvider); - return CELIX_SUCCESS; -} - -CELIX_GEN_BUNDLE_ACTIVATOR(psav_activator_t, psav_start, psav_stop) diff --git a/bundles/pubsub/pubsub_serializer_avrobin/src/pubsub_avrobin_serialization_provider.c b/bundles/pubsub/pubsub_serializer_avrobin/src/pubsub_avrobin_serialization_provider.c deleted file mode 100644 index 20086138b..000000000 --- a/bundles/pubsub/pubsub_serializer_avrobin/src/pubsub_avrobin_serialization_provider.c +++ /dev/null @@ -1,120 +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_avrobin_serialization_provider.h" - -#include -#include -#include -#include - -#include "avrobin_serializer.h" -#include "dyn_message.h" -#include "celix_log_helper.h" -#include "pubsub_message_serialization_service.h" - -static void dfi_log(void *handle, int level, const char *file, int line, const char *msg, ...) { - va_list ap; - celix_log_helper_t *log = handle; - char *logStr = NULL; - va_start(ap, msg); - vasprintf(&logStr, msg, ap); - va_end(ap); - celix_logHelper_log(log, level, "FILE:%s, LINE:%i, MSG:%s", file, line, logStr); - free(logStr); -} - - -static celix_status_t pubsub_avrobinSerializationProvider_serialize(pubsub_serialization_entry_t* entry, const void* msg, struct iovec** output, size_t* outputIovLen) { - celix_status_t status = CELIX_SUCCESS; - - if (output != NULL) { - *output = calloc(1, sizeof(struct iovec)); - *outputIovLen = 1; - } else { - return CELIX_ILLEGAL_ARGUMENT; - } - - uint8_t *serializedOutput = NULL; - size_t serializedOutputLen; - dyn_type* dynType; - dynMessage_getMessageType(entry->msgType, &dynType); - - if (avrobinSerializer_serialize(dynType, msg, &serializedOutput, &serializedOutputLen) != 0) { - status = CELIX_BUNDLE_EXCEPTION; - } - - if (status == CELIX_SUCCESS) { - (**output).iov_base = (void*)serializedOutput; - (**output).iov_len = serializedOutputLen; - } - - return status; -} - -void pubsub_avrobinSerializationProvider_freeSerializeMsg(pubsub_serialization_entry_t* entry, struct iovec* input, size_t inputIovLen) { - if (input != NULL) { - if (entry->msgType != NULL) { - for (int i = 0; i < inputIovLen; i++) { - if (input[i].iov_base) { - free(input[i].iov_base); - } - input[i].iov_base = NULL; - input[i].iov_len = 0; - } - } - free(input); - } -} - -celix_status_t pubsub_avrobinSerializationProvider_deserialize(pubsub_serialization_entry_t* entry, const struct iovec* input, size_t inputIovLen, void **out) { - celix_status_t status = CELIX_SUCCESS; - if (input == NULL) return CELIX_BUNDLE_EXCEPTION; - void *msg = NULL; - dyn_type* dynType; - dynMessage_getMessageType(entry->msgType, &dynType); - - assert(inputIovLen == 1); - - if (avrobinSerializer_deserialize(dynType, (uint8_t *)input->iov_base, input->iov_len, &msg) != 0) { - status = CELIX_BUNDLE_EXCEPTION; - } else{ - *out = msg; - } - - return status; -} - -void pubsub_avrobinSerializationProvider_freeDeserializeMsg(pubsub_serialization_entry_t* entry, void *msg) { - if (entry->msgType != NULL) { - dyn_type* dynType; - dynMessage_getMessageType(entry->msgType, &dynType); - dynType_free(dynType, msg); - } -} - -pubsub_serialization_provider_t* pubsub_avrobinSerializationProvider_create(celix_bundle_context_t* ctx) { - pubsub_serialization_provider_t* provider = pubsub_serializationProvider_create(ctx, "avrobin", false, 0, pubsub_avrobinSerializationProvider_serialize, pubsub_avrobinSerializationProvider_freeSerializeMsg, pubsub_avrobinSerializationProvider_deserialize, pubsub_avrobinSerializationProvider_freeDeserializeMsg); - avrobinSerializer_logSetup(dfi_log, pubsub_serializationProvider_getLogHelper(provider), 1); - return provider; -} - -void pubsub_avrobinSerializationProvider_destroy(pubsub_serialization_provider_t* provider) { - pubsub_serializationProvider_destroy(provider); -} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_serializer_avrobin/src/pubsub_avrobin_serialization_provider.h b/bundles/pubsub/pubsub_serializer_avrobin/src/pubsub_avrobin_serialization_provider.h deleted file mode 100644 index b8ed98aa3..000000000 --- a/bundles/pubsub/pubsub_serializer_avrobin/src/pubsub_avrobin_serialization_provider.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ - -#ifndef CELIX_PUBSUB_AVROBIN_SERIALIZATION_PROVIDER_H -#define CELIX_PUBSUB_AVROBIN_SERIALIZATION_PROVIDER_H - -#include "pubsub_serialization_provider.h" - -#ifdef __cplusplus -extern "C" { -#endif - -pubsub_serialization_provider_t* pubsub_avrobinSerializationProvider_create(celix_bundle_context_t *ctx); - -/** - * Destroys the provided AVRO-bin Serialization Provider. - */ -void pubsub_avrobinSerializationProvider_destroy(pubsub_serialization_provider_t *provider); - -#ifdef __cplusplus -}; -#endif - -#endif //CELIX_PUBSUB_AVROBIN_SERIALIZATION_PROVIDER_H diff --git a/bundles/pubsub/pubsub_serializer_json/CMakeLists.txt b/bundles/pubsub/pubsub_serializer_json/CMakeLists.txt deleted file mode 100644 index 94d8a7c60..000000000 --- a/bundles/pubsub/pubsub_serializer_json/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. - -celix_subproject(PUBSUB_JSON_SERIALIZER "Option to enable building the PubSub JSON serializer bundle" ON) -if (PUBSUB_JSON_SERIALIZER) - find_package(jansson REQUIRED) - - - add_celix_bundle(celix_pubsub_serializer_json - BUNDLE_SYMBOLICNAME "apache_celix_pubsub_serializer_json" - VERSION "1.1.1" - GROUP "Celix/PubSub" - SOURCES - src/ps_json_serializer_activator.c - src/pubsub_json_serialization_provider.c - ) - target_include_directories(celix_pubsub_serializer_json PRIVATE - src - ) - target_link_libraries(celix_pubsub_serializer_json PRIVATE Celix::dfi jansson::jansson Celix::log_helper) - target_link_libraries(celix_pubsub_serializer_json PRIVATE Celix::pubsub_spi Celix::pubsub_utils) - celix_deprecated_utils_headers(celix_pubsub_serializer_json) - celix_deprecated_framework_headers(celix_pubsub_serializer_json) - - install_celix_bundle(celix_pubsub_serializer_json EXPORT celix COMPONENT pubsub) - - add_library(Celix::celix_pubsub_serializer_json ALIAS celix_pubsub_serializer_json) - - - if (ENABLE_TESTING) - add_subdirectory(gtest) - endif(ENABLE_TESTING) -endif () \ No newline at end of file diff --git a/bundles/pubsub/pubsub_serializer_json/gtest/CMakeLists.txt b/bundles/pubsub/pubsub_serializer_json/gtest/CMakeLists.txt deleted file mode 100644 index b9a6d0a99..000000000 --- a/bundles/pubsub/pubsub_serializer_json/gtest/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -add_celix_bundle(pubsub_json_serialization_descriptor NO_ACTIVATOR VERSION 1.0.0) -celix_bundle_files(pubsub_json_serialization_descriptor - ${CMAKE_CURRENT_SOURCE_DIR}/msg_descriptors/msg_poi1.descriptor - DESTINATION "META-INF/descriptors" -) - -add_executable(test_pubsub_serializer_json - src/PubSubJsonSerializationProviderTestSuite.cc -) -celix_deprecated_utils_headers(test_pubsub_serializer_json) -target_link_libraries(test_pubsub_serializer_json PRIVATE Celix::framework Celix::dfi Celix::pubsub_utils GTest::gtest GTest::gtest_main Celix::pubsub_spi) - -add_celix_bundle_dependencies(test_pubsub_serializer_json celix_pubsub_serializer_json pubsub_json_serialization_descriptor) -target_compile_definitions(test_pubsub_serializer_json PRIVATE -DSERIALIZATION_BUNDLE=\"$\") -target_compile_definitions(test_pubsub_serializer_json PRIVATE -DDESCRIPTOR_BUNDLE=\"$\") - -add_test(NAME test_pubsub_serializer_json COMMAND test_pubsub_serializer_json) -setup_target_for_coverage(test_pubsub_serializer_json SCAN_DIR ..) - diff --git a/bundles/pubsub/pubsub_serializer_json/gtest/msg_descriptors/msg_poi1.descriptor b/bundles/pubsub/pubsub_serializer_json/gtest/msg_descriptors/msg_poi1.descriptor deleted file mode 100644 index 705cf2965..000000000 --- a/bundles/pubsub/pubsub_serializer_json/gtest/msg_descriptors/msg_poi1.descriptor +++ /dev/null @@ -1,10 +0,0 @@ -:header -type=message -name=poi1 -version=1.0.0 -:annotations -classname=org.example.PointOfInterest -:types -location={DD lat lon} -:message -{llocation;t location name} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_serializer_json/gtest/src/PubSubJsonSerializationProviderTestSuite.cc b/bundles/pubsub/pubsub_serializer_json/gtest/src/PubSubJsonSerializationProviderTestSuite.cc deleted file mode 100644 index b24c623ae..000000000 --- a/bundles/pubsub/pubsub_serializer_json/gtest/src/PubSubJsonSerializationProviderTestSuite.cc +++ /dev/null @@ -1,117 +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 "gtest/gtest.h" - -#include - -#include "celix_framework_factory.h" -#include "celix_constants.h" -#include "celix_bundle_context.h" -#include "pubsub_message_serialization_service.h" - -class PubSubJsonSerializationProviderTestSuite : public ::testing::Test { -public: - PubSubJsonSerializationProviderTestSuite() { - auto* props = celix_properties_create(); - celix_properties_set(props, CELIX_FRAMEWORK_CACHE_DIR, ".pubsub_json_serializer_cache"); - auto* fwPtr = celix_frameworkFactory_createFramework(props); - auto* ctxPtr = celix_framework_getFrameworkContext(fwPtr); - fw = std::shared_ptr{fwPtr, [](auto* f) {celix_frameworkFactory_destroyFramework(f);}}; - ctx = std::shared_ptr{ctxPtr, [](auto*){/*nop*/}}; - - const char* descBundleFile = DESCRIPTOR_BUNDLE; - const char* serBundleFile = SERIALIZATION_BUNDLE; - long bndId; - - bndId = celix_bundleContext_installBundle(ctx.get(), descBundleFile, true); - EXPECT_TRUE(bndId >= 0); - - bndId = celix_bundleContext_installBundle(ctx.get(), serBundleFile, true); - EXPECT_TRUE(bndId >= 0); - } - - std::shared_ptr fw{}; - std::shared_ptr ctx{}; -}; - - -TEST_F(PubSubJsonSerializationProviderTestSuite, CreateDestroy) { - //checks if the bundles are started and stopped correctly (no mem leaks). -} - -TEST_F(PubSubJsonSerializationProviderTestSuite, FindSerializationServices) { - auto* services = celix_bundleContext_findServices(ctx.get(), PUBSUB_MESSAGE_SERIALIZATION_SERVICE_NAME); - EXPECT_EQ(1, celix_arrayList_size(services)); - celix_arrayList_destroy(services); -} - -struct poi1 { - struct { - double lat; - double lon; - } location; - const char *name; -}; - -TEST_F(PubSubJsonSerializationProviderTestSuite, SerializeTest) { - poi1 p; - p.location.lat = 42; - p.location.lon = 43; - p.name = "test"; - - celix_service_use_options_t opts{}; - opts.filter.serviceName = PUBSUB_MESSAGE_SERIALIZATION_SERVICE_NAME; - opts.filter.filter = "(msg.fqn=poi1)"; - opts.callbackHandle = static_cast(&p); - opts.use = [](void *handle, void *svc) { - //auto *poi = static_cast(handle); - auto* ser = static_cast(svc); - struct iovec* outVec = NULL; - size_t outSize = 0; - int rc = ser->serialize(ser->handle, handle, &outVec, &outSize); - EXPECT_EQ(0, rc); - EXPECT_TRUE(strstr(static_cast(outVec->iov_base), "\"lat\":42") != NULL); - ser->freeSerializedMsg(ser->handle, outVec, outSize); - }; - bool called = celix_bundleContext_useServiceWithOptions(ctx.get(), &opts); - EXPECT_TRUE(called); -} - -TEST_F(PubSubJsonSerializationProviderTestSuite, DeserializeTest) { - celix_service_use_options_t opts{}; - opts.filter.serviceName = PUBSUB_MESSAGE_SERIALIZATION_SERVICE_NAME; - opts.filter.filter = "(msg.fqn=poi1)"; - opts.callbackHandle = nullptr; - opts.use = [](void *, void *svc) { - auto* ser = static_cast(svc); - const char* data = R"({"location":{"lat":42.0,"lon":43.0},"name":"test"})"; - poi1 *p = nullptr; - iovec inVec; - inVec.iov_base = static_cast(const_cast(data)); - inVec.iov_len = strlen(data); - ser->deserialize(ser->handle, &inVec, 1, (void**)(&p)); - EXPECT_EQ(42,p->location.lat); - EXPECT_EQ(43,p->location.lon); - EXPECT_STREQ("test", p->name); - ser->freeDeserializedMsg(ser->handle, p); - }; - bool called = celix_bundleContext_useServiceWithOptions(ctx.get(), &opts); - EXPECT_TRUE(called); -} diff --git a/bundles/pubsub/pubsub_serializer_json/src/ps_json_serializer_activator.c b/bundles/pubsub/pubsub_serializer_json/src/ps_json_serializer_activator.c deleted file mode 100644 index 6cea86a79..000000000 --- a/bundles/pubsub/pubsub_serializer_json/src/ps_json_serializer_activator.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include - -#include "pubsub_json_serialization_provider.h" -#include "celix_bundle_activator.h" - -typedef struct psjs_activator { - pubsub_serialization_provider_t *provider; - long serializerSvcId; -} psjs_activator_t; - -static int psjs_start(psjs_activator_t *act, celix_bundle_context_t *ctx) { - act->provider = pubsub_jsonSerializationProvider_create(ctx); - return act->provider ? CELIX_SUCCESS : CELIX_BUNDLE_EXCEPTION; -} - -static int psjs_stop(psjs_activator_t *act, celix_bundle_context_t *ctx __attribute__((unused))) { - pubsub_jsonSerializationProvider_destroy(act->provider); - return CELIX_SUCCESS; -} - -CELIX_GEN_BUNDLE_ACTIVATOR(psjs_activator_t, psjs_start, psjs_stop) \ No newline at end of file diff --git a/bundles/pubsub/pubsub_serializer_json/src/pubsub_json_serialization_provider.c b/bundles/pubsub/pubsub_serializer_json/src/pubsub_json_serialization_provider.c deleted file mode 100644 index 0e7874760..000000000 --- a/bundles/pubsub/pubsub_serializer_json/src/pubsub_json_serialization_provider.c +++ /dev/null @@ -1,117 +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_json_serialization_provider.h" - -#include -#include -#include - -#include "json_serializer.h" -#include "dyn_message.h" -#include "celix_compiler.h" -#include "celix_log_helper.h" -#include "pubsub_message_serialization_service.h" - -static void dfi_log(void *handle, int level, const char *file, int line, const char *msg, ...) { - va_list ap; - celix_log_helper_t *log = handle; - char *logStr = NULL; - va_start(ap, msg); - vasprintf(&logStr, msg, ap); - va_end(ap); - celix_logHelper_log(log, level, "FILE:%s, LINE:%i, MSG:%s", file, line, logStr); - free(logStr); -} - - -static celix_status_t pubsub_jsonSerializationProvider_serialize(pubsub_serialization_entry_t* entry, const void* msg, struct iovec** output, size_t* outputIovLen) { - celix_status_t status = CELIX_SUCCESS; - - if (*output == NULL) { - *output = calloc(1, sizeof(struct iovec)); - *outputIovLen = 1; - } else { - return CELIX_ILLEGAL_ARGUMENT; - } - - char *jsonOutput = NULL; - dyn_type* dynType; - dynMessage_getMessageType(entry->msgType, &dynType); - - if (jsonSerializer_serialize(dynType, msg, &jsonOutput) != 0) { - status = CELIX_BUNDLE_EXCEPTION; - } - - if (status == CELIX_SUCCESS) { - (**output).iov_base = (void*)jsonOutput; - (**output).iov_len = strlen(jsonOutput); - } - - return status; -} - -static void pubsub_jsonSerializationProvider_freeSerializeMsg(pubsub_serialization_entry_t* entry, struct iovec* input, size_t inputIovLen) { - if (input != NULL) { - if (entry->msgType != NULL) { - for (int i = 0; i < inputIovLen; i++) { - if (input[i].iov_base) { - free(input[i].iov_base); - } - input[i].iov_base = NULL; - input[i].iov_len = 0; - } - } - free(input); - } -} - -static celix_status_t pubsub_jsonSerializationProvider_deserialize(pubsub_serialization_entry_t* entry, const struct iovec* input, size_t inputIovLen CELIX_UNUSED, void **out) { - celix_status_t status = CELIX_SUCCESS; - if (input == NULL) return CELIX_BUNDLE_EXCEPTION; - void *msg = NULL; - dyn_type* dynType; - dynMessage_getMessageType(entry->msgType, &dynType); - - if (jsonSerializer_deserialize(dynType, (const char*)input->iov_base, input->iov_len, &msg) != 0) { - status = CELIX_BUNDLE_EXCEPTION; - } else{ - *out = msg; - } - - return status; -} - -static void pubsub_jsonSerializationProvider_freeDeserializeMsg(pubsub_serialization_entry_t* entry, void *msg) { - if (entry->msgType != NULL) { - dyn_type* dynType; - dynMessage_getMessageType(entry->msgType, &dynType); - dynType_free(dynType, msg); - } -} - -pubsub_serialization_provider_t* pubsub_jsonSerializationProvider_create(celix_bundle_context_t* ctx) { - pubsub_serialization_provider_t* provider = pubsub_serializationProvider_create(ctx, "json", true, 0, pubsub_jsonSerializationProvider_serialize, pubsub_jsonSerializationProvider_freeSerializeMsg, pubsub_jsonSerializationProvider_deserialize, pubsub_jsonSerializationProvider_freeDeserializeMsg); - jsonSerializer_logSetup(dfi_log, pubsub_serializationProvider_getLogHelper(provider), 1);; - return provider; -} - -void pubsub_jsonSerializationProvider_destroy(pubsub_serialization_provider_t* provider) { - pubsub_serializationProvider_destroy(provider); -} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_serializer_json/src/pubsub_json_serialization_provider.h b/bundles/pubsub/pubsub_serializer_json/src/pubsub_json_serialization_provider.h deleted file mode 100644 index a8b95c833..000000000 --- a/bundles/pubsub/pubsub_serializer_json/src/pubsub_json_serialization_provider.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_JSON_SERIALIZATION_PROVIDER_H -#define CELIX_PUBSUB_JSON_SERIALIZATION_PROVIDER_H - -#include "pubsub_serialization_provider.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** -* Creates a JSON Serialization Provider. -*/ -pubsub_serialization_provider_t* pubsub_jsonSerializationProvider_create(celix_bundle_context_t *ctx); - -/** - * Destroys the provided JSON Serialization Provider. - */ -void pubsub_jsonSerializationProvider_destroy(pubsub_serialization_provider_t *provider); - -#ifdef __cplusplus -}; -#endif - -#endif //CELIX_PUBSUB_JSON_SERIALIZATION_PROVIDER_H diff --git a/bundles/pubsub/pubsub_spi/CMakeLists.txt b/bundles/pubsub/pubsub_spi/CMakeLists.txt deleted file mode 100644 index b88c8f1b1..000000000 --- a/bundles/pubsub/pubsub_spi/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -find_package(libuuid REQUIRED) - -add_library(pubsub_spi STATIC - src/pubsub_endpoint.c - src/pubsub_endpoint_match.c - src/pubsub_admin_metrics.c - src/pubsub_interceptors_handler.c) - -set_target_properties(pubsub_spi PROPERTIES OUTPUT_NAME "celix_pubsub_spi") -target_include_directories(pubsub_spi PUBLIC - $) - -target_link_libraries(pubsub_spi PUBLIC Celix::framework Celix::pubsub_api) -target_link_libraries(pubsub_spi PUBLIC Celix::pubsub_utils libuuid::libuuid) -celix_deprecated_utils_headers(pubsub_spi) -celix_deprecated_framework_headers(pubsub_spi) -celix_target_hide_symbols(pubsub_spi) - -add_library(Celix::pubsub_spi ALIAS pubsub_spi) - -install(TARGETS pubsub_spi EXPORT celix DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT pubsub - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/celix/pubsub_spi) -install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/celix/pubsub_spi COMPONENT pubsub) - - -if (ENABLE_TESTING) - add_subdirectory(gtest) -endif(ENABLE_TESTING) \ No newline at end of file diff --git a/bundles/pubsub/pubsub_spi/gtest/CMakeLists.txt b/bundles/pubsub/pubsub_spi/gtest/CMakeLists.txt deleted file mode 100644 index 4c084bd6d..000000000 --- a/bundles/pubsub/pubsub_spi/gtest/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -add_executable(test_pubsub_spi - src/PubSubEndpointUtilsTestSuite.cc -) -target_link_libraries(test_pubsub_spi PRIVATE Celix::pubsub_spi GTest::gtest GTest::gtest_main) - -#Seems to be an issue with coverage setup, for now disabled -#setup_target_for_coverage(test_pubsub_spi SCAN_DIR ..) diff --git a/bundles/pubsub/pubsub_spi/gtest/src/PubSubEndpointUtilsTestSuite.cc b/bundles/pubsub/pubsub_spi/gtest/src/PubSubEndpointUtilsTestSuite.cc deleted file mode 100644 index 802e8f0e8..000000000 --- a/bundles/pubsub/pubsub_spi/gtest/src/PubSubEndpointUtilsTestSuite.cc +++ /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. - */ - -#include "gtest/gtest.h" - -#include "pubsub_endpoint.h" - -TEST(PubSubEndpointUtilsTestSuite, pubsubEndpoint_matchWithTopicAndScope) { - celix_properties_t* endpoint = celix_properties_create(); - celix_properties_set(endpoint, PUBSUB_ENDPOINT_TOPIC_NAME, "topic"); - - EXPECT_TRUE(pubsubEndpoint_matchWithTopicAndScope(endpoint, "topic", nullptr)); - EXPECT_FALSE(pubsubEndpoint_matchWithTopicAndScope(endpoint, "topicaa", nullptr)); - EXPECT_TRUE(pubsubEndpoint_matchWithTopicAndScope(endpoint, "topic", "default")); //Note "default" is the same as NULL scope - EXPECT_FALSE(pubsubEndpoint_matchWithTopicAndScope(endpoint, "topic", "scope")); - - celix_properties_set(endpoint, PUBSUB_ENDPOINT_TOPIC_SCOPE, "scope"); - EXPECT_FALSE(pubsubEndpoint_matchWithTopicAndScope(endpoint, "topic", nullptr)); - EXPECT_FALSE(pubsubEndpoint_matchWithTopicAndScope(endpoint, "topicaa", nullptr)); - EXPECT_FALSE(pubsubEndpoint_matchWithTopicAndScope(endpoint, "topic", "default")); - EXPECT_TRUE(pubsubEndpoint_matchWithTopicAndScope(endpoint, "topic", "scope")); - EXPECT_FALSE(pubsubEndpoint_matchWithTopicAndScope(endpoint, "topic", "scopeaa")); - - celix_properties_set(endpoint, PUBSUB_ENDPOINT_TOPIC_SCOPE, "default"); - EXPECT_TRUE(pubsubEndpoint_matchWithTopicAndScope(endpoint, "topic", nullptr)); //Note NULL is the same as "default" scope - EXPECT_FALSE(pubsubEndpoint_matchWithTopicAndScope(endpoint, "topicaa", nullptr)); - EXPECT_TRUE(pubsubEndpoint_matchWithTopicAndScope(endpoint, "topic", "default")); - EXPECT_FALSE(pubsubEndpoint_matchWithTopicAndScope(endpoint, "topic", "scope")); - - celix_properties_destroy(endpoint); -} diff --git a/bundles/pubsub/pubsub_spi/include/pubsub_admin.h b/bundles/pubsub/pubsub_spi/include/pubsub_admin.h deleted file mode 100644 index e142883bd..000000000 --- a/bundles/pubsub/pubsub_spi/include/pubsub_admin.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef PUBSUB_ADMIN_H_ -#define PUBSUB_ADMIN_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "celix_properties.h" -#include "celix_bundle.h" -#include "celix_filter.h" - -#define PUBSUB_ADMIN_SERVICE_NAME "pubsub_admin" -#define PUBSUB_ADMIN_SERVICE_VERSION "3.0.0" -#define PUBSUB_ADMIN_SERVICE_RANGE "[3,4)" - -//expected service properties -#define PUBSUB_ADMIN_SERVICE_TYPE "psa_type" - -#define PUBSUB_ADMIN_FULL_MATCH_SCORE 100.0F -#define PUBSUB_ADMIN_NO_MATCH_SCORE 0.0F - -struct pubsub_admin_service { - void *handle; - - celix_status_t (*matchPublisher)(void *handle, long svcRequesterBndId, const celix_filter_t *svcFilter, celix_properties_t **outTopicProperties, double *outScore, long *outSerializerSvcId, long *outProtocolSvcId); - celix_status_t (*matchSubscriber)(void *handle, long svcProviderBndId, const celix_properties_t *svcProperties, celix_properties_t **outTopicProperties, double *outScore, long *outSerializerSvcId, long *outProtocolSvcId); - celix_status_t (*matchDiscoveredEndpoint)(void *handle, const celix_properties_t *endpoint, bool *match); - - //note endpoint is owned by caller - celix_status_t (*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 (*teardownTopicSender)(void *handle, const char *scope, const char *topic); - - //note endpoint is owned by caller - celix_status_t (*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 (*teardownTopicReceiver)(void *handle, const char *scope, const char *topic); - - celix_status_t (*addDiscoveredEndpoint)(void *handle, const celix_properties_t *endpoint); - celix_status_t (*removeDiscoveredEndpoint)(void *handle, const celix_properties_t *endpoint); -}; - -typedef struct pubsub_admin_service pubsub_admin_service_t; - -#ifdef __cplusplus -} -#endif -#endif /* PUBSUB_ADMIN_H_ */ - - diff --git a/bundles/pubsub/pubsub_spi/include/pubsub_admin_metrics.h b/bundles/pubsub/pubsub_spi/include/pubsub_admin_metrics.h deleted file mode 100644 index 628eda0e4..000000000 --- a/bundles/pubsub/pubsub_spi/include/pubsub_admin_metrics.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef PUBSUB_ADMIN_METRICS_H_ -#define PUBSUB_ADMIN_METRICS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include "celix_array_list.h" - -#define PUBSUB_ADMIN_METRICS_SERVICE_NAME "pubsub_admin_metrics" - -#define PUBSUB_AMDIN_METRICS_NAME_MAX 1024 - -typedef struct pubsub_admin_sender_msg_type_metrics { - long bndId; - char typeFqn[PUBSUB_AMDIN_METRICS_NAME_MAX]; - unsigned int typeId; - unsigned long nrOfMessagesSend; - unsigned long nrOfMessagesSendFailed; - unsigned long nrOfSerializationErrors; - struct timespec lastMessageSend; - double averageTimeBetweenMessagesInSeconds; - double averageSerializationTimeInSeconds; -} pubsub_admin_sender_msg_type_metrics_t; - -typedef struct pubsub_admin_sender_metrics { - char scope[PUBSUB_AMDIN_METRICS_NAME_MAX]; - char topic[PUBSUB_AMDIN_METRICS_NAME_MAX]; - unsigned long nrOfUnknownMessagesRetrieved; - unsigned int nrOfmsgMetrics; - pubsub_admin_sender_msg_type_metrics_t *msgMetrics; //size = nrOfMessageTypes -} pubsub_admin_sender_metrics_t; - -typedef struct pubsub_admin_receiver_metrics { - char scope[PUBSUB_AMDIN_METRICS_NAME_MAX]; - char topic[PUBSUB_AMDIN_METRICS_NAME_MAX]; - unsigned long nrOfMsgTypes; - struct { - unsigned int typeId; - char typeFqn[PUBSUB_AMDIN_METRICS_NAME_MAX]; - int nrOfOrigins; - struct { - uuid_t originUUID; - unsigned long nrOfMessagesReceived; - unsigned long nrOfSerializationErrors; - unsigned long nrOfMissingSeqNumbers; - struct timespec lastMessageReceived; - double averageTimeBetweenMessagesInSeconds; - double averageSerializationTimeInSeconds; - double averageDelayInSeconds; - double minDelayInSeconds; - double maxDelayInSeconds; - } *origins; - } *msgTypes; -} pubsub_admin_receiver_metrics_t; - - -typedef struct pubsub_admin_metrics { - char psaType[PUBSUB_AMDIN_METRICS_NAME_MAX]; - - celix_array_list_t *senders; //entry type = pubsub_admin_sender_metrics_t - celix_array_list_t *receivers;//entry type = pubsub_admin_receiver_metrics_t - -} pubsub_admin_metrics_t; - -/** - * A metrics service for a PubSubAdmin. This is an optional service. - * - * Expected service properties: PUBSUB_ADMIN_SERVICE_TYPE - */ -struct pubsub_admin_metrics_service { - void *handle; - - /** - * Creates a metrics struct for the PSA. The caller is owner of the data and - * should use pubsub_freePubSubAdminMetrics (part of pubsub_spi) to release the data. - * @param handle - * @return The metrics or NULL if no metrics can be created. - */ - pubsub_admin_metrics_t* (*metrics)(void *handle); -}; - -void pubsub_freePubSubAdminMetrics(pubsub_admin_metrics_t *metrics); - -typedef struct pubsub_admin_metrics_service pubsub_admin_metrics_service_t; - -#ifdef __cplusplus -} -#endif -#endif /* PUBSUB_ADMIN_METRICS_H_ */ - - diff --git a/bundles/pubsub/pubsub_spi/include/pubsub_constants.h b/bundles/pubsub/pubsub_spi/include/pubsub_constants.h deleted file mode 100644 index 00ee6b406..000000000 --- a/bundles/pubsub/pubsub_spi/include/pubsub_constants.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 PUBSUB_CONSTANTS_H_ -#define PUBSUB_CONSTANTS_H_ - -#define PUBSUB_ADMIN_TYPE_KEY "pubsub.config" -#define PUBSUB_SERIALIZER_TYPE_KEY "pubsub.serializer" -#define PUBSUB_PROTOCOL_TYPE_KEY "pubsub.protocol" - -/** - * Endpoints with the system visibility should be discoverable through the complete system - */ -#define PUBSUB_ENDPOINT_SYSTEM_VISIBILITY "system" - -/** - * Endpoints with the system visibility are discoverable for a single host (i.e. IPC) - */ -#define PUBSUB_ENDPOINT_HOST_VISIBILITY "host" - -/** - * Endpoints which are only visible within a single process - */ -#define PUBSUB_ENDPOINT_LOCAL_VISIBILITY "local" - -/** - * Default scope, if not scope is specified endpoints are published using this scope - */ -#define PUBSUB_DEFAULT_ENDPOINT_SCOPE "default" - -#endif /* PUBSUB_CONSTANTS_H_ */ diff --git a/bundles/pubsub/pubsub_spi/include/pubsub_endpoint.h b/bundles/pubsub/pubsub_spi/include/pubsub_endpoint.h deleted file mode 100644 index 5fc818bcb..000000000 --- a/bundles/pubsub/pubsub_spi/include/pubsub_endpoint.h +++ /dev/null @@ -1,90 +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_ENDPOINT_H_ -#define PUBSUB_ENDPOINT_H_ - -#include "celix_log_helper.h" -#include "celix_bundle_context.h" -#include "celix_properties.h" - -#include "pubsub/publisher.h" -#include "pubsub/subscriber.h" - -#include "pubsub_constants.h" - -#ifdef __cplusplus -extern "C" { -#endif -//required for valid endpoint -#define PUBSUB_ENDPOINT_TOPIC_NAME "pubsub.topic.name" -#define PUBSUB_ENDPOINT_TOPIC_SCOPE "pubsub.topic.scope" - -#define PUBSUB_ENDPOINT_UUID "pubsub.endpoint.uuid" //required -#define PUBSUB_ENDPOINT_FRAMEWORK_UUID "pubsub.framework.uuid" //required -#define PUBSUB_ENDPOINT_TYPE "pubsub.endpoint.type" //PUBSUB_PUBLISHER_ENDPOINT_TYPE or PUBSUB_SUBSCRIBER_ENDPOINT_TYPE -#define PUBSUB_ENDPOINT_VISIBILITY "pubsub.endpoint.visibility" //local, host or system. e.g. for IPC host -#define PUBSUB_ENDPOINT_ADMIN_TYPE PUBSUB_ADMIN_TYPE_KEY -#define PUBSUB_ENDPOINT_SERIALIZER PUBSUB_SERIALIZER_TYPE_KEY -#define PUBSUB_ENDPOINT_PROTOCOL PUBSUB_PROTOCOL_TYPE_KEY - - -#define PUBSUB_PUBLISHER_ENDPOINT_TYPE "publisher" -#define PUBSUB_SUBSCRIBER_ENDPOINT_TYPE "subscriber" -#define PUBSUB_ENDPOINT_VISIBILITY_DEFAULT PUBSUB_ENDPOINT_SYSTEM_VISIBILITY - - -celix_properties_t * -pubsubEndpoint_create(const char *fwUUID, const char *scope, const char *topic, const char *pubsubType, - const char *adminType, const char *serType, const char *protType, celix_properties_t *topic_props); - -celix_properties_t * -pubsubEndpoint_createFromSubscriberSvc(bundle_context_t *ctx, long svcBndId, const celix_properties_t *svcProps); - -celix_properties_t * -pubsubEndpoint_createFromPublisherTrackerInfo(bundle_context_t *ctx, long bundleId, const char *filter); - -bool pubsubEndpoint_equals(const celix_properties_t *psEp1, const celix_properties_t *psEp2); - -//check if the required properties are available for the endpoint -bool -pubsubEndpoint_isValid(const celix_properties_t *endpointProperties, bool requireAdminType, bool requireSerializerType); - -/** - * Create a key based on scope an topic. - * Scope can be NULL. - * Note that NULL, "topic" and "default", "topic" will result in different keys - * @return a newly created key. caller is responsible for freeing the string array. - */ -char *pubsubEndpoint_createScopeTopicKey(const char *scope, const char *topic); - -/** - * Match an endpoint with a topic & scope. - * @param endpoint The endpoints (mandatory) - * @param topic The topic (mandatory) - * @param scope The scope (can be NULL) - * @return true if the endpoint is for the provide topic and scope); - */ -bool pubsubEndpoint_matchWithTopicAndScope(const celix_properties_t* endpoint, const char *topic, const char *scope); - - -#ifdef __cplusplus -} -#endif -#endif /* PUBSUB_ENDPOINT_H_ */ diff --git a/bundles/pubsub/pubsub_spi/include/pubsub_interceptor.h b/bundles/pubsub/pubsub_spi/include/pubsub_interceptor.h deleted file mode 100644 index 785c88ac6..000000000 --- a/bundles/pubsub/pubsub_spi/include/pubsub_interceptor.h +++ /dev/null @@ -1,116 +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_INTERCEPTOR_H -#define __PUBSUB_INTERCEPTOR_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -#include "celix_properties.h" - -#define PUBSUB_INTERCEPTOR_SERVICE_NAME "pubsub.interceptor" -#define PUBSUB_INTERCEPTOR_SERVICE_VERSION "2.0.0" - -typedef struct pubsub_interceptor_properties { - const char* psaType; //i.e. zmq, tcp, etc - const char* serializationType; //i.e. json, avrobin - const char* scope; - const char* topic; -} pubsub_interceptor_properties_t; - -/** - * @brief PubSub Interceptor which can be used to intercept pubsub publish/receive callbacks - * - */ -struct pubsub_interceptor { - /** - * Service handle. - */ - void *handle; - - /** - * @brief preSend will be called when a user called send on a pubsub/publisher, but before the message is "handed over" to the actual pubsub technology (i.e. TCP stack, shared memory, etc) - * - * This function can be NULL. - * - * @param handle The service handle - * @param properties The scope and topic of the sending publisher - * @param messageType The fqn of the message - * @param msgTypeId The (local) type id of the message - * @param message The actual message pointer - * @param metadata The metadata of the message - * @return True if the send should continue. - */ - bool (*preSend)(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, uint32_t msgTypeId, const void *message, celix_properties_t *metadata); - - /** - * @brief postSend will be called when a user called send on a pubsub/publisher, but after the message is "handed over" to the actual pubsub technology (i.e. TCP stack, shared memory, etc) - * - * This function can be NULL. - * - * @param handle The service handle - * @param properties The scope and topic of the sending publisher - * @param messageType The fqn of the message - * @param msgTypeId The (local) type id of the message - * @param message The actual message pointer - * @param metadata The metadata of the message - */ - void (*postSend)(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, uint32_t msgTypeId, const void *message, celix_properties_t *metadata); - - /** - * @brief preReceive will be called when is message is received in a pubsub admin, but before the pubsub/subscriber callback is called. - * - * This function can be NULL. - * - * @param handle The service handle - * @param properties The scope and topic of the sending publisher - * @param messageType The fqn of the message - * @param msgTypeId The (local) type id of the message - * @param message The actual message pointer - * @param metadata The metadata of the message - * @return True if the pubsub/subsciber callback should be called. - */ - bool (*preReceive)(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, uint32_t msgTypeId, const void *message, celix_properties_t *metadata); - - /** - * @brief postReceive will be called when is message is received in a pubsub admin and is called after the pubsub/subscriber callback is called. - * - * This function can be NULL. - * - * @param handle The service handle - * @param properties The scope and topic of the sending publisher - * @param messageType The fqn of the message - * @param msgTypeId The (local) type id of the message - * @param message The actual message pointer - * @param metadata The metadata of the message - */ - void (*postReceive)(void *handle, const pubsub_interceptor_properties_t *properties, const char *messageType, uint32_t msgTypeId, const void *message, celix_properties_t *metadata); -}; - -typedef struct pubsub_interceptor pubsub_interceptor_t; - -#ifdef __cplusplus -} -#endif -#endif //__PUBSUB_INTERCEPTOR_H diff --git a/bundles/pubsub/pubsub_spi/include/pubsub_interceptors_handler.h b/bundles/pubsub/pubsub_spi/include/pubsub_interceptors_handler.h deleted file mode 100644 index 88c0d09d9..000000000 --- a/bundles/pubsub/pubsub_spi/include/pubsub_interceptors_handler.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -#ifndef PUBSUB_INTERCEPTORS_HANDLER_H -#define PUBSUB_INTERCEPTORS_HANDLER_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include "celix_errno.h" -#include "celix_array_list.h" -#include "pubsub_interceptor.h" -#include "celix_properties.h" - -typedef struct pubsub_interceptors_handler pubsub_interceptors_handler_t; - -/** - * @brief Creates a pubsub interceptor handler for a specific scope, topic, psa type and serialization type. - * - * A interceptor handler will track pubsub interceptors and will call these interceptors when using the - * invokePreSend, invokePostSend, invokePreReceive and invokePostReceive functions. - * - * The interceptor handler will forward the topic, scope, psa type and serialization type info to every interceptor - * functions as pubsub_interceptor_properties_t. - * - */ -pubsub_interceptors_handler_t* pubsubInterceptorsHandler_create(celix_bundle_context_t* ctx, const char* scope, const char* topic, const char* psaType, const char* serializationType); - -/** - * @brief Destroy the interceptor handler - * @param handler - */ -void pubsubInterceptorsHandler_destroy(pubsub_interceptors_handler_t *handler); - -/** - * @brief Calls all the tracked interceptor service preSend functions. - */ -bool pubsubInterceptorHandler_invokePreSend(pubsub_interceptors_handler_t *handler, const char* messageType, uint32_t messageId, const void* message, celix_properties_t** metadata); - -/** - * @brief Calls all the tracked interceptor service postSend functions. - */ -void pubsubInterceptorHandler_invokePostSend(pubsub_interceptors_handler_t *handler, const char* messageType, uint32_t messageId, const void* message, celix_properties_t* metadata); - -/** - * @brief Calls all the tracked interceptor service preReceive functions. - */ -bool pubsubInterceptorHandler_invokePreReceive(pubsub_interceptors_handler_t *handler, const char* messageType, uint32_t messageId, const void* message, celix_properties_t** metadata); - -/** - * @brief Calls all the tracked interceptor service postReceive functions. - */ -void pubsubInterceptorHandler_invokePostReceive(pubsub_interceptors_handler_t *handler, const char* messageType, uint32_t messageId, const void* message, celix_properties_t* metadata); - -/** - * @brief Return the nr of interceptors currently tracked. - */ -size_t pubsubInterceptorHandler_nrOfInterceptors(pubsub_interceptors_handler_t *handler); - -#ifdef __cplusplus -} -#endif -#endif //PUBSUB_INTERCEPTORS_HANDLER_H diff --git a/bundles/pubsub/pubsub_spi/include/pubsub_listeners.h b/bundles/pubsub/pubsub_spi/include/pubsub_listeners.h deleted file mode 100644 index 67d149f32..000000000 --- a/bundles/pubsub/pubsub_spi/include/pubsub_listeners.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 PUBSUB_LISTENERS_H_ -#define PUBSUB_LISTENERS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "celix_properties.h" - -#define PUBSUB_DISCOVERED_ENDPOINT_LISTENER_SERVICE "pubsub_discovered_endpoint_listener" - -//Informs the topology manager that pub/sub endpoints are discovered in the network -struct pubsub_discovered_endpoint_listener { - void *handle; - - celix_status_t (*addDiscoveredEndpoint)(void *handle, const celix_properties_t *properties); - celix_status_t (*removeDiscoveredEndpoint)(void *handle, const celix_properties_t *properties); -}; -typedef struct pubsub_discovered_endpoint_listener pubsub_discovered_endpoint_listener_t; - - - -#define PUBSUB_ANNOUNCE_ENDPOINT_LISTENER_SERVICE "pubsub_announce_endpoint_listener" - -//Informs the pubsub discoveries to announce/revoke endpoint -struct pubsub_announce_endpoint_listener { - void *handle; - - celix_status_t (*announceEndpoint)(void *handle, const celix_properties_t *properties); - celix_status_t (*revokeEndpoint)(void *handle, const celix_properties_t *properties); -}; - -typedef struct pubsub_announce_endpoint_listener pubsub_announce_endpoint_listener_t; - -#ifdef __cplusplus -} -#endif -#endif /* PUBSUB_LISTENERS_H_ */ diff --git a/bundles/pubsub/pubsub_spi/include/pubsub_message_serialization_marker.h b/bundles/pubsub/pubsub_spi/include/pubsub_message_serialization_marker.h deleted file mode 100644 index 919b8f47b..000000000 --- a/bundles/pubsub/pubsub_spi/include/pubsub_message_serialization_marker.h +++ /dev/null @@ -1,67 +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_MESSAGE_SERIALIZATION_MARKER_H_ -#define PUBSUB_MESSAGE_SERIALIZATION_MARKER_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "hash_map.h" -#include "version.h" -#include "celix_bundle.h" -#include "sys/uio.h" - -#define PUBSUB_MESSAGE_SERIALIZATION_MARKER_NAME "pubsub_message_serialization_marker" -#define PUBSUB_MESSAGE_SERIALIZATION_MARKER_VERSION "1.0.0" -#define PUBSUB_MESSAGE_SERIALIZATION_MARKER_RANGE "[1,2)" - -/** - * @brief Service property (named "serialization.type") identifying the serialization type (e.g json, avrobin, etc) - */ -#define PUBSUB_MESSAGE_SERIALIZATION_MARKER_SERIALIZATION_TYPE_PROPERTY "serialization.type" - -/** - * @brief Service property (named "serialization.backwards.compatible") identifying whether the serialization is - * backwards compatible (i.e. for json a extra - new - field can be safely ignored and is thus backwards compatible. - * - * Type if boolean. If service property is not present, false will be used. - */ -#define PUBSUB_MESSAGE_SERIALIZATION_MARKER_SERIALIZATION_BACKWARDS_COMPATIBLE "serialization.backwards.compatible" - -/** - * @brief Marker interface - interface with no methods - to indicate that a serialization.type is available. - * - * This marker interface is used to indicate that a serialization type is available without the need to rely on - * pubsub message serialization service per msg type. - * The service.ranking of this marker interface must be used to select a serialization type if no serialization type is - * configured. The service.ranking of individual pubsub_messge_serization_service is used to override serializers per - * type. - * - * The properties serialization.type is mandatory - */ -typedef struct pubsub_message_serialization_marker { - void* handle; -} pubsub_message_serialization_marker_t; - -#ifdef __cplusplus -} -#endif -#endif /* PUBSUB_MESSAGE_SERIALIZATION_MARKER_H_ */ diff --git a/bundles/pubsub/pubsub_spi/include/pubsub_message_serialization_service.h b/bundles/pubsub/pubsub_spi/include/pubsub_message_serialization_service.h deleted file mode 100644 index c47d9eb52..000000000 --- a/bundles/pubsub/pubsub_spi/include/pubsub_message_serialization_service.h +++ /dev/null @@ -1,102 +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_MESSAGE_SERIALIZATION_SERVICE_H_ -#define PUBSUB_MESSAGE_SERIALIZATION_SERVICE_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "hash_map.h" -#include "version.h" -#include "celix_bundle.h" -#include "sys/uio.h" - -#define PUBSUB_MESSAGE_SERIALIZATION_SERVICE_NAME "pubsub_message_serialization_service" -#define PUBSUB_MESSAGE_SERIALIZATION_SERVICE_VERSION "1.0.0" -#define PUBSUB_MESSAGE_SERIALIZATION_SERVICE_RANGE "[1,2)" - -#define PUBSUB_MESSAGE_SERIALIZATION_SERVICE_SERIALIZATION_TYPE_PROPERTY "serialization.type" -#define PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_FQN_PROPERTY "msg.fqn" -#define PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_VERSION_PROPERTY "msg.version" -#define PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_ID_PROPERTY "msg.id" - -/** - * @brief A message serialization service for a serialization type (e.g. json) and - * for a specific msg type (based on the fully qualified name) and version. - * - * The properties serialization.type, msg,fqn, msg.version and msg.id are mandatory - */ -typedef struct pubsub_message_serialization_service { - void* handle; - - /** - * @brief Serialize a message into iovec structs (set of structures with buffer pointer and length) - * - * The correct message serialization services will be selected based on the provided msgId. - * - * @param handle The pubsub message serialization service handle. - * @param msgId The msg id for the message to be serialized. - * @param input A pointer to the message object - * @param output An output pointer to a array of iovec structs. - * @param outputIovLen The number of iovec struct created - * @return CELIX_SUCCESS on success, CELIX_ILLEGAL_ARGUMENT if the msg id is not known or serialization failed. - */ - celix_status_t (*serialize)(void* handle, const void* input, struct iovec** output, size_t* outputIovLen); - - /** - * @brief Free the memory of for the serialized msg. - */ - void (*freeSerializedMsg)(void* handle, struct iovec* input, size_t inputIovLen); - - /** - * @brief Deserialize a message using the provided iovec buffers. - * - * The deserialize function will also check if the target major/minor version of the message is valid with the version - * of the serialized data. - * - * For some serialization types (e.g. JSON) newer versions of the serialized data can be deserialized. - * E.g. JSON serialized data with version 1.2.0 can be deserialized to a target message with version 1.0.0 - * But JSON serialized data with a version 2.0.0 will not be deserialized to a target message with version 1.0.0 - * This assume correct use of semantic versioning. - * - * @param handle The pubsub message serialization service handle. - * @param msgId The msg id for the message to be deserialized. - * @param serializedMajorVersion The major version of the serialized data - * @param serializedMinorVersion The minor version of the serialized data. - * @param input Pointer to the first element in a array of iovecs. - * @param inputIovLen Then number of iovecs. - * @param out The newly allocated and deserialized message object - * @return CELIX_SUCCESS on success. CELIX_ILLEGAL_ARGUMENT if the msg id is not known, - * or if the version do no match or deserialization failed. - */ - celix_status_t (*deserialize)(void* handle, const struct iovec* input, size_t inputIovLen, void** out); //note inputLen can be 0 if predefined size is not needed - - /** - * @brief Free the memory for the deserialized message. - */ - void (*freeDeserializedMsg)(void* handle, void* msg); - -} pubsub_message_serialization_service_t; - -#ifdef __cplusplus -} -#endif -#endif /* PUBSUB_MESSAGE_SERIALIZATION_SERVICE_H_ */ diff --git a/bundles/pubsub/pubsub_spi/include/pubsub_protocol.h b/bundles/pubsub/pubsub_spi/include/pubsub_protocol.h deleted file mode 100644 index 7f5d62bdc..000000000 --- a/bundles/pubsub/pubsub_spi/include/pubsub_protocol.h +++ /dev/null @@ -1,270 +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_PROTOCOL_SERVICE_H_ -#define PUBSUB_PROTOCOL_SERVICE_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "celix_properties.h" - -#define PUBSUB_PROTOCOL_SERVICE_NAME "pubsub_protocol" -#define PUBSUB_PROTOCOL_SERVICE_VERSION "2.0.0" -#define PUBSUB_PROTOCOL_SERVICE_RANGE "[2,3)" - -typedef struct pubsub_protocol_header pubsub_protocol_header_t; - -/** - * The protocol header structure, contains the information about the message payload and metadata - */ -struct pubsub_protocol_header { - /** message payload identification attributes */ - uint32_t msgId; - uint16_t msgMajorVersion; - uint16_t msgMinorVersion; - - /** Payload and metadata sizes attributes */ - uint32_t payloadSize; - uint32_t metadataSize; - - /** optional convert Endianess attribute, this attribute is used to indicate the header needs to converted for endianess during encoding - * this attribute is used to indicate the payload needs to converted for endianess after header decoding. - * Note: this attribute is transmitted using the wire protocol, the sync word is used to determine endianess conversion */ - uint32_t convertEndianess; - - /** Optional message segmentation attributes, these attributes are only used/written by the protocol admin. - * When message segmentation is supported by the protocol admin */ - uint32_t seqNr; - uint32_t payloadPartSize; - uint32_t payloadOffset; - uint32_t isLastSegment; -}; - -typedef struct pubsub_protocol_payload pubsub_protocol_payload_t; - -struct pubsub_protocol_payload { - void *payload; - uint32_t length; -}; - -typedef struct pubsub_protocol_metadata pubsub_protocol_metadata_t; - -struct pubsub_protocol_metadata { - celix_properties_t *metadata; -}; - -typedef struct pubsub_protocol_message pubsub_protocol_message_t; - -struct pubsub_protocol_message { - pubsub_protocol_header_t header; - pubsub_protocol_payload_t payload; - pubsub_protocol_metadata_t metadata; -}; - -typedef struct pubsub_protocol_service { - void* handle; - /** - * @brief Returns the size of the header. - * - * Is used by the receiver to configure the expected size of the header. - * The receiver first reads the header to know if the receive is big enough - * to contain the complete payload. - * - * @param handle handle for service - * @param length output param for header size - * @return status code indicating failure or success - */ - celix_status_t (*getHeaderSize)(void *handle, size_t *length); - /** - * @brief Returns the size of the header buffer for the receiver. - * - * Is used by the receiver to configure the buffer size of the header. - * Note for a protocol with a header the headerBufferSize >= headerSize. - * Note for header-less protocol the headerBufferSize is zero - * because the header is part of the payload. - * - * @param handle handle for service - * @param length output param for header buffer size - * @return status code indicating failure or success - */ - celix_status_t (*getHeaderBufferSize)(void *handle, size_t *length); - /** - * @brief Returns the size of the sync word - * - * Is used by the receiver to skip the sync in the header buffer, - * to get in sync with data reception. - * - * @param handle handle for service - * @param length output param for sync size - * @return status code indicating failure or success - */ - celix_status_t (*getSyncHeaderSize)(void *handle, size_t *length); - /** - * @brief Returns the header (as byte array) that should be used by the underlying protocol as sync between - * messages. - * - * @param handle handle for service - * @param sync output param for byte array - * @return status code indicating failure or success - */ - celix_status_t (*getSyncHeader)(void *handle, void *sync); - - /** - * @brief Returns the size of the footer. - * - * Is used by the receiver to configure the expected size of the footer. - * The receiver reads the footer to know if the complete message including paylaod is received. - * - * @param handle handle for service - * @param length output param for footer size - * @return status code indicating failure or success - */ - celix_status_t (*getFooterSize)(void *handle, size_t *length); - - /** - * @brief Returns the if the protocol service supports the message segmentation attributes that is used by the - * underlying protocol. - * - * @param handle handle for service - * @param isSupported indicates that message segmentation is supported or not. - * @return status code indicating failure or success - */ - celix_status_t (*isMessageSegmentationSupported)(void *handle, bool *isSupported); - - /** - * @brief Encode the header using the supplied message.header. - * - * If *bufferInOut is NULL a new buffer will be allocated. - * If *bufferInOut is not NULL and *bufferLengthInOut matches the header size the buffer will be reused. - * If *bufferInOut is not NULL, but *bufferLengthInOut does not match the header size, the provided buffer will - * be freed and a new buffer (matching the header size) will be allocated. - * - * @param handle handle for service - * @param message message to use header from - * @param bufferInOut byte array containing the encoded header - * @param bufferLengthInOut length of the byte array - * @return status code indicating failure or success - */ - celix_status_t (*encodeHeader)(void *handle, pubsub_protocol_message_t *message, void **bufferInOut, size_t *bufferLengthInOut); - - /** - * @brief Encode the payload using the supplied message.header. Note, this encoding is for protocol specific tasks, - * and does not perform the needed message serialization. See the serialization service for that. - * In most cases this will simply use the known data and length from message.payload. - * - * @param handle handle for service - * @param message message to use header from - * @param outBuffer byte array containing the encoded payload - * @param outLength length of the byte array - * @return status code indicating failure or success - */ - celix_status_t (*encodePayload)(void *handle, pubsub_protocol_message_t *message, void **outBuffer, size_t *outLength); - - /** - * @brief Encode metadata to bufferInOut using the supplied message.metadata - * - * If *bufferInOut is NULL, a new buffer will be allocated. If *bufferInOut is not NULL, the buffer is reused and - * the provided *bufferLengthInOut must indicate the length of the provided buffer. - * If a provided *bufferInOut is not large enough to fit the encoded metadata, the buffer will be reallocated and - * enlarged. - * - * If this calls return with an error, the caller is still owner of a possible returned output buffer. - * - * @param handle handle for service - * @param message The message containing the metadata to encode - * @param bufferInOut Input/output argument for the buffer, if call is successful will contain the metadata header - * @param bufferLengthInOut Input/output arguments for the length of the bufferInOut argument. - * @param bufferContentLengthOut Output argument for the actual content size of the bufferInOut. Note that the - * bufferContentLengthOut can be smaller than the buffer length. - * @return CELIX_SUCCESS if encoding was successful. - */ - celix_status_t (*encodeMetadata)(void *handle, pubsub_protocol_message_t *message, void **bufferInOut, size_t *bufferLengthInOut, size_t* bufferContentLengthOut); - - /** - * @brief Encode the footer - * - * If *bufferInOut is NULL a new buffer will be allocated. - * If *bufferInOut is not NULL and *bufferLengthInOut matches the footer size the buffer will be reused. - * If *bufferInOut is not NULL, but *bufferLengthInOut does not match the footer size, the provided buffer will - * be freed and a new buffer (matching the footer size) will be allocated. - * - * @param handle handle for service - * @param message message to use footer from - * @param bufferInOut byte array containing the encoded footer - * @param bufferLengthInOut length of the byte array - * @return status code indicating failure or success - */ - celix_status_t (*encodeFooter)(void *handle, pubsub_protocol_message_t *message, void **bufferInOut, size_t *bufferLengthInOut); - - - /** - * @brief Decodes the given data into message.header. - * - * @param handle handle for service - * @param data incoming byte array to decode - * @param length length of the byte array - * @param message pointer to message to be filled in with decoded header - * @return status code indicating failure or success - */ - celix_status_t (*decodeHeader)(void* handle, void *data, size_t length, pubsub_protocol_message_t *message); - - /** - * @brief Decodes the given data into message.payload. Note, this decode is for protocol specific tasks, and - * does not performthe needed message serialization. See the serialization service for that. - * - * In most cases this will simply set the incoming data and length in message.payload. - * - * @param handle handle for service - * @param data incoming byte array to decode - * @param length length of the byte array - * @param message pointer to message to be filled in with decoded payload - * @return status code indicating failure or success - */ - celix_status_t (*decodePayload)(void* handle, void *data, size_t length, pubsub_protocol_message_t *message); - - /** - * @brief Decodes the given data into message.metadata. - * - * @param handle handle for service - * @param data incoming byte array to decode - * @param length length of the byte array - * @param message pointer to message to be filled in with decoded metadata - * @return status code indicating failure or success - */ - celix_status_t (*decodeMetadata)(void* handle, void *data, size_t length, pubsub_protocol_message_t *message); - - /** - * @brief Decodes the given data into message.header. - * - * @param handle handle for service - * @param data incoming byte array to decode - * @param length length of the byte array - * @param message pointer to message to be filled in with decoded footer - * @return status code indicating failure or success - */ - celix_status_t (*decodeFooter)(void* handle, void *data, size_t length, pubsub_protocol_message_t *message); -} pubsub_protocol_service_t; - -#ifdef __cplusplus -} -#endif -#endif /* PUBSUB_PROTOCOL_SERVICE_H_ */ diff --git a/bundles/pubsub/pubsub_spi/src/pubsub_admin_metrics.c b/bundles/pubsub/pubsub_spi/src/pubsub_admin_metrics.c deleted file mode 100644 index eec0c0257..000000000 --- a/bundles/pubsub/pubsub_spi/src/pubsub_admin_metrics.c +++ /dev/null @@ -1,51 +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. - */ - -#if defined(__MACH__) -#include -#else -#include -#endif -#include -#include "pubsub_admin_metrics.h" - -void pubsub_freePubSubAdminMetrics(pubsub_admin_metrics_t *metrics) { - if (metrics != NULL) { - if (metrics->receivers != NULL) { - for (int i = 0; i < celix_arrayList_size(metrics->receivers); ++i) { - pubsub_admin_receiver_metrics_t *m = celix_arrayList_get(metrics->receivers, i); - for (int k = 0; k < m->nrOfMsgTypes; ++k) { - free(m->msgTypes[k].origins); - } - free(m->msgTypes); - free(m); - } - celix_arrayList_destroy(metrics->receivers); - } - if (metrics->senders != NULL) { - for (int i = 0; i < celix_arrayList_size(metrics->senders); ++i) { - pubsub_admin_sender_metrics_t *m = celix_arrayList_get(metrics->senders, i); - free(m->msgMetrics); - free(m); - } - celix_arrayList_destroy(metrics->senders); - } - free(metrics); - } -} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_spi/src/pubsub_endpoint.c b/bundles/pubsub/pubsub_spi/src/pubsub_endpoint.c deleted file mode 100644 index 214eb1d8b..000000000 --- a/bundles/pubsub/pubsub_spi/src/pubsub_endpoint.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -/** - * endpoint_description.c - * - * \date 25 Jul 2014 - * \author Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - -#include -#include -#include -#include - -#include "celix_errno.h" -#include "celix_log.h" -#include "pubsub_endpoint.h" -#include "celix_constants.h" -#include "pubsub_utils.h" -#include "celix_bundle_context.h" - - -static void pubsubEndpoint_setFields(celix_properties_t *psEp, const char* fwUUID, const char* scope, const char* topic, const char *pubsubType, const char *adminType, const char *serType, const char *protType, const celix_properties_t *topic_props); - -static void pubsubEndpoint_setFields(celix_properties_t *ep, const char* fwUUID, const char* scope, const char* topic, const char *pubsubType, const char *adminType, const char *serType, const char *protType, const celix_properties_t *topic_props) { - assert(ep != NULL); - - //copy topic properties - if (topic_props != NULL) { - CELIX_PROPERTIES_ITERATE((celix_properties_t *) topic_props, iter) { - celix_properties_set(ep, iter.key, iter.entry.value); - } - } - - - char endpointUuid[37]; - uuid_t endpointUid; - uuid_generate(endpointUid); - uuid_unparse(endpointUid, endpointUuid); - celix_properties_set(ep, PUBSUB_ENDPOINT_UUID, endpointUuid); - - if (fwUUID != NULL) { - celix_properties_set(ep, PUBSUB_ENDPOINT_FRAMEWORK_UUID, fwUUID); - } - - if (scope != NULL) { - celix_properties_set(ep, PUBSUB_ENDPOINT_TOPIC_SCOPE, scope); - } else { - celix_properties_set(ep, PUBSUB_ENDPOINT_TOPIC_SCOPE, PUBSUB_DEFAULT_ENDPOINT_SCOPE); - } - - if (topic != NULL) { - celix_properties_set(ep, PUBSUB_ENDPOINT_TOPIC_NAME, topic); - } - - if (pubsubType != NULL) { - celix_properties_set(ep, PUBSUB_ENDPOINT_TYPE, pubsubType); - } - - if (adminType != NULL) { - celix_properties_set(ep, PUBSUB_ENDPOINT_ADMIN_TYPE, adminType); - } - - if (serType != NULL) { - celix_properties_set(ep, PUBSUB_ENDPOINT_SERIALIZER, serType); - } - - if (protType != NULL) { - celix_properties_set(ep, PUBSUB_ENDPOINT_PROTOCOL, protType); - } -} - -celix_properties_t* pubsubEndpoint_create( - const char* fwUUID, - const char* scope, - const char* topic, - const char* pubsubType, - const char* adminType, - const char *serType, - const char *protType, - celix_properties_t *topic_props) { - celix_properties_t *ep = celix_properties_create(); - pubsubEndpoint_setFields(ep, fwUUID, scope, topic, pubsubType, adminType, serType, protType, topic_props); - if (!pubsubEndpoint_isValid(ep, true, true)) { - celix_properties_destroy(ep); - ep = NULL; - } - return ep; -} - - -struct retrieve_topic_properties_data { - celix_properties_t *props; - const char *scope; - const char *topic; - bool isPublisher; -}; - -static void retrieveTopicProperties(void *handle, const celix_bundle_t *bnd) { - struct retrieve_topic_properties_data *data = handle; - data->props = pubsub_utils_getTopicProperties(bnd, data->scope, data->topic, data->isPublisher); -} - -celix_properties_t* pubsubEndpoint_createFromSubscriberSvc(bundle_context_t* ctx, long bundleId, const celix_properties_t *svcProps) { - celix_properties_t *ep = celix_properties_create(); - - const char* fwUUID = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, NULL); - const char* scope = celix_properties_get(svcProps, PUBSUB_SUBSCRIBER_SCOPE, NULL); - const char* topic = celix_properties_get(svcProps, PUBSUB_SUBSCRIBER_TOPIC, NULL); - - struct retrieve_topic_properties_data data; - data.props = NULL; - data.isPublisher = false; - data.scope = scope; - data.topic = topic; - celix_bundleContext_useBundle(ctx, bundleId, &data, retrieveTopicProperties); - - const char *pubsubType = PUBSUB_SUBSCRIBER_ENDPOINT_TYPE; - - pubsubEndpoint_setFields(ep, fwUUID, scope, topic, pubsubType, NULL, NULL, NULL, data.props); - - if (data.props != NULL) { - celix_properties_destroy(data.props); //Can be deleted since setFields invokes properties_copy - } - - if (!pubsubEndpoint_isValid(ep, false, false)) { - celix_properties_destroy(ep); - ep = NULL; - } - return ep; -} - - -celix_properties_t* pubsubEndpoint_createFromPublisherTrackerInfo(bundle_context_t *ctx, long bundleId, const char *filter) { - celix_properties_t *ep = celix_properties_create(); - - const char* fwUUID= celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, NULL); - assert(fwUUID != NULL); - - char* topic = NULL; - char* scopeFromFilter = NULL; - pubsub_getPubSubInfoFromFilter(filter, &scopeFromFilter, &topic); - const char *scope = scopeFromFilter; - - struct retrieve_topic_properties_data data; - data.props = NULL; - data.isPublisher = true; - data.scope = scope; - data.topic = topic; - celix_bundleContext_useBundle(ctx, bundleId, &data, retrieveTopicProperties); - - pubsubEndpoint_setFields(ep, fwUUID, scope, topic, PUBSUB_PUBLISHER_ENDPOINT_TYPE, NULL, NULL, NULL, data.props); - celix_properties_destroy(data.props); //safe to delete, properties are copied in pubsubEndpoint_setFields - - if (!pubsubEndpoint_isValid(ep, false, false)) { - celix_properties_destroy(ep); - ep = NULL; - } - - free(topic); - if (scope != NULL) { - free(scopeFromFilter); - } - - return ep; -} - - -bool pubsubEndpoint_equals(const celix_properties_t *psEp1, const celix_properties_t *psEp2) { - if (psEp1 && psEp2) { - const char *uuid1 = celix_properties_get(psEp1, PUBSUB_ENDPOINT_UUID, "entry1"); - const char *uuid2 = celix_properties_get(psEp1, PUBSUB_ENDPOINT_UUID, "entry1"); - return strcmp(uuid1, uuid2) == 0; - } else { - return false; - } -} - -char* pubsubEndpoint_createScopeTopicKey(const char* scope, const char* topic) { - char *result = NULL; - if (scope != NULL) { - asprintf(&result, "%s:%s", scope, topic); - } else { - //NOTE scope == NULL, equal to scope="default" - asprintf(&result, "%s", topic); - } - return result; -} - -static bool checkProp(const celix_properties_t *props, const char *key) { - const char *val = celix_properties_get(props, key, NULL); - if (val == NULL) { - fprintf(stderr, "[Error] Missing mandatory entry for endpoint. Missing key is '%s'\n", key); - } - return val != NULL; -} - - -bool pubsubEndpoint_isValid(const celix_properties_t *props, bool requireAdminType, bool requireSerializerType) { - bool p1 = checkProp(props, PUBSUB_ENDPOINT_UUID); - bool p2 = checkProp(props, PUBSUB_ENDPOINT_FRAMEWORK_UUID); - bool p3 = checkProp(props, PUBSUB_ENDPOINT_TYPE); - bool p4 = true; - if (requireAdminType) { - p4 = checkProp(props, PUBSUB_ENDPOINT_ADMIN_TYPE); - } - bool p5 = true; - if (requireSerializerType) { - p5 = checkProp(props, PUBSUB_ENDPOINT_SERIALIZER); - } - bool p6 = checkProp(props, PUBSUB_ENDPOINT_TOPIC_NAME); - return p1 && p2 && p3 && p4 && p5 && p6; -} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_spi/src/pubsub_endpoint_match.c b/bundles/pubsub/pubsub_spi/src/pubsub_endpoint_match.c deleted file mode 100644 index f141d7084..000000000 --- a/bundles/pubsub/pubsub_spi/src/pubsub_endpoint_match.c +++ /dev/null @@ -1,35 +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 - -#include "pubsub_endpoint.h" -#include "celix_utils.h" -#include "celix_constants.h" - - -bool pubsubEndpoint_matchWithTopicAndScope(const celix_properties_t* endpoint, const char *topic, const char *scope) { - const char *endpointScope = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TOPIC_SCOPE, PUBSUB_DEFAULT_ENDPOINT_SCOPE); - const char *endpointTopic = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TOPIC_NAME, NULL); - if (scope == NULL) { - scope = PUBSUB_DEFAULT_ENDPOINT_SCOPE; - } - - return celix_utils_stringEquals(topic, endpointTopic) && celix_utils_stringEquals(scope, endpointScope); -} diff --git a/bundles/pubsub/pubsub_spi/src/pubsub_interceptors_handler.c b/bundles/pubsub/pubsub_spi/src/pubsub_interceptors_handler.c deleted file mode 100644 index 239511e49..000000000 --- a/bundles/pubsub/pubsub_spi/src/pubsub_interceptors_handler.c +++ /dev/null @@ -1,216 +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 "celix_bundle_context.h" -#include "celix_compiler.h" -#include "celix_constants.h" -#include "celix_array_list.h" -#include "celix_utils.h" -#include "celix_threads.h" - -#include "pubsub_interceptors_handler.h" - -typedef struct entry { - const celix_properties_t *properties; - pubsub_interceptor_t *interceptor; -} entry_t; - -struct pubsub_interceptors_handler { - pubsub_interceptor_properties_t properties; - - celix_array_list_t *interceptors; - - long interceptorsTrackerId; - - celix_bundle_context_t *ctx; - - celix_thread_mutex_t lock; -}; - -static int referenceCompare(const void *a, const void *b); - -static void pubsubInterceptorsHandler_addInterceptor(void *handle, void *svc, const celix_properties_t *props); -static void pubsubInterceptorsHandler_removeInterceptor(void *handle, void *svc, const celix_properties_t *props); - -pubsub_interceptors_handler_t* pubsubInterceptorsHandler_create(celix_bundle_context_t *ctx, const char *scope, const char *topic, const char* psaType, const char* serType) { - pubsub_interceptors_handler_t* handler = calloc(1, sizeof(*handler)); - handler->ctx = ctx; - handler->properties.scope = celix_utils_strdup(scope); - handler->properties.topic = celix_utils_strdup(topic); - handler->properties.psaType = celix_utils_strdup(psaType); - handler->properties.serializationType = celix_utils_strdup(serType); - handler->interceptors = celix_arrayList_create(); - celixThreadMutex_create(&handler->lock, NULL); - - // Create service tracker here, and not in the activator - celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; - opts.filter.serviceName = PUBSUB_INTERCEPTOR_SERVICE_NAME; - opts.callbackHandle = handler; - opts.addWithProperties = pubsubInterceptorsHandler_addInterceptor; - opts.removeWithProperties = pubsubInterceptorsHandler_removeInterceptor; - handler->interceptorsTrackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts); - - return handler; -} - -void pubsubInterceptorsHandler_destroy(pubsub_interceptors_handler_t *handler) { - if (handler != NULL) { - celix_bundleContext_stopTracker(handler->ctx, handler->interceptorsTrackerId); - celix_arrayList_destroy(handler->interceptors); - celixThreadMutex_destroy(&handler->lock); - free((char*)handler->properties.scope); - free((char*)handler->properties.topic); - free((char*)handler->properties.psaType); - free((char*)handler->properties.serializationType); - free(handler); - } -} - -void pubsubInterceptorsHandler_addInterceptor(void *handle, void *svc, const celix_properties_t *props) { - pubsub_interceptors_handler_t *handler = handle; - - celixThreadMutex_lock(&handler->lock); - - bool exists = false; - for (uint32_t i = 0; i < celix_arrayList_size(handler->interceptors); i++) { - entry_t *entry = celix_arrayList_get(handler->interceptors, i); - if (entry->interceptor == svc) { - exists = true; - } - } - if (!exists) { - entry_t *entry = calloc(1, sizeof(*entry)); - entry->properties = props; - entry->interceptor = svc; - celix_arrayList_add(handler->interceptors, entry); - - celix_arrayList_sort(handler->interceptors, referenceCompare); - } - - celixThreadMutex_unlock(&handler->lock); -} - -void pubsubInterceptorsHandler_removeInterceptor(void *handle, void *svc, const celix_properties_t *props CELIX_UNUSED) { - pubsub_interceptors_handler_t *handler = handle; - - celixThreadMutex_lock(&handler->lock); - - for (uint32_t i = 0; i < celix_arrayList_size(handler->interceptors); i++) { - entry_t *entry = celix_arrayList_get(handler->interceptors, i); - if (entry->interceptor == svc) { - celix_arrayList_removeAt(handler->interceptors, i); - free(entry); - break; - } - } - - celixThreadMutex_unlock(&handler->lock); -} - -bool pubsubInterceptorHandler_invokePreSend(pubsub_interceptors_handler_t *handler, const char *messageType, uint32_t messageId, const void *message, celix_properties_t **metadata) { - bool cont = true; - - celixThreadMutex_lock(&handler->lock); - - if (*metadata == NULL && celix_arrayList_size(handler->interceptors) > 0) { - *metadata = celix_properties_create(); - } - - for (uint32_t i = celix_arrayList_size(handler->interceptors); i > 0; i--) { - entry_t *entry = celix_arrayList_get(handler->interceptors, i - 1); - if (entry->interceptor->preSend != NULL) { - cont = entry->interceptor->preSend(entry->interceptor->handle, &handler->properties, messageType, messageId, message, *metadata); - } - if (!cont) { - break; - } - } - - celixThreadMutex_unlock(&handler->lock); - - return cont; -} - -void pubsubInterceptorHandler_invokePostSend(pubsub_interceptors_handler_t *handler, const char *messageType, uint32_t messageId, const void *message, celix_properties_t *metadata) { - celixThreadMutex_lock(&handler->lock); - - for (uint32_t i = celix_arrayList_size(handler->interceptors); i > 0; i--) { - entry_t *entry = celix_arrayList_get(handler->interceptors, i - 1); - if (entry->interceptor->postSend != NULL) { - entry->interceptor->postSend(entry->interceptor->handle, &handler->properties, messageType, messageId, message, metadata); - } - } - - celixThreadMutex_unlock(&handler->lock); -} - -bool pubsubInterceptorHandler_invokePreReceive(pubsub_interceptors_handler_t *handler, const char *messageType, uint32_t messageId, const void *message, celix_properties_t **metadata) { - bool cont = true; - - celixThreadMutex_lock(&handler->lock); - if (*metadata == NULL && celix_arrayList_size(handler->interceptors) > 0) { - *metadata = celix_properties_create(); - } - for (uint32_t i = 0; i < celix_arrayList_size(handler->interceptors); i++) { - entry_t *entry = celix_arrayList_get(handler->interceptors, i); - if (entry->interceptor->preReceive != NULL) { - cont = entry->interceptor->preReceive(entry->interceptor->handle, &handler->properties, messageType, messageId, message, *metadata); - } - if (!cont) { - break; - } - } - - celixThreadMutex_unlock(&handler->lock); - - return cont; -} - -void pubsubInterceptorHandler_invokePostReceive(pubsub_interceptors_handler_t *handler, const char *messageType, uint32_t messageId, const void *message, celix_properties_t *metadata) { - celixThreadMutex_lock(&handler->lock); - - for (uint32_t i = 0; i < celix_arrayList_size(handler->interceptors); i++) { - entry_t *entry = celix_arrayList_get(handler->interceptors, i); - if (entry->interceptor->postReceive != NULL) { - entry->interceptor->postReceive(entry->interceptor->handle, &handler->properties, messageType, messageId, message, metadata); - } - } - - celixThreadMutex_unlock(&handler->lock); -} - -int referenceCompare(const void *a, const void *b) { - const entry_t *aEntry = a; - const entry_t *bEntry = b; - - long servIdA = celix_properties_getAsLong(aEntry->properties, CELIX_FRAMEWORK_SERVICE_ID, 0); - long servIdB = celix_properties_getAsLong(bEntry->properties, CELIX_FRAMEWORK_SERVICE_ID, 0); - - long servRankingA = celix_properties_getAsLong(aEntry->properties, CELIX_FRAMEWORK_SERVICE_RANKING, 0); - long servRankingB = celix_properties_getAsLong(bEntry->properties, CELIX_FRAMEWORK_SERVICE_RANKING, 0); - - return celix_utils_compareServiceIdsAndRanking(servIdA, servRankingA, servIdB, servRankingB); -} - -size_t pubsubInterceptorHandler_nrOfInterceptors(pubsub_interceptors_handler_t *handler) { - size_t nr = 0; - celixThreadMutex_lock(&handler->lock); - nr = (size_t)celix_arrayList_size(handler->interceptors); - celixThreadMutex_unlock(&handler->lock); - return nr; -} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_topology_manager/CMakeLists.txt b/bundles/pubsub/pubsub_topology_manager/CMakeLists.txt deleted file mode 100644 index 6ac4efdb3..000000000 --- a/bundles/pubsub/pubsub_topology_manager/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -find_package(libuuid REQUIRED) - -add_celix_bundle(celix_pubsub_topology_manager - BUNDLE_SYMBOLICNAME "apache_celix_pubsub_topology_manager" - VERSION "1.1.1" - GROUP "Celix/PubSub" - SOURCES - src/pstm_activator.c - src/pubsub_topology_manager.c - src/pubsub_topology_manager.h -) -target_link_libraries(celix_pubsub_topology_manager PRIVATE Celix::framework Celix::log_helper Celix::shell_api) -target_link_libraries(celix_pubsub_topology_manager PRIVATE Celix::pubsub_spi Celix::pubsub_utils ) -target_link_libraries(celix_pubsub_topology_manager PRIVATE libuuid::libuuid) -celix_deprecated_utils_headers(celix_pubsub_topology_manager) - -install_celix_bundle(celix_pubsub_topology_manager EXPORT celix COMPONENT pubsub) - -add_library(Celix::celix_pubsub_topology_manager ALIAS celix_pubsub_topology_manager) - diff --git a/bundles/pubsub/pubsub_topology_manager/src/pstm_activator.c b/bundles/pubsub/pubsub_topology_manager/src/pstm_activator.c deleted file mode 100644 index 6462a41c6..000000000 --- a/bundles/pubsub/pubsub_topology_manager/src/pstm_activator.c +++ /dev/null @@ -1,162 +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 -#include -#include -#include -#include -#include -#include "celix_log_helper.h" -#include "hash_map.h" -#include "pubsub_topology_manager.h" -#include "pubsub_listeners.h" - -typedef struct pstm_activator { - pubsub_topology_manager_t *manager; - - long pubsubDiscoveryTrackerId; - long pubsubAdminTrackerId; - long pubsubSubscribersTrackerId; - long pubsubPublishServiceTrackerId; - long pubsubPSAMetricsTrackerId; - - pubsub_discovered_endpoint_listener_t discListenerSvc; - long discListenerSvcId; - - celix_shell_command_t shellCmdSvc; - long shellCmdSvcId; - - celix_log_helper_t *loghelper; -} pstm_activator_t; - - -static int pstm_start(pstm_activator_t *act, celix_bundle_context_t *ctx) { - celix_status_t status; - - act->discListenerSvcId = -1L; - act->pubsubSubscribersTrackerId = -1L; - act->pubsubAdminTrackerId = -1L; - act->pubsubDiscoveryTrackerId = -1L; - act->pubsubPublishServiceTrackerId = -1L; - act->pubsubPSAMetricsTrackerId = -1L; - act->shellCmdSvcId = -1L; - - act->loghelper = celix_logHelper_create(ctx, "celix_psa_topology_manager"); - - status = pubsub_topologyManager_create(ctx, act->loghelper, &act->manager); - - //track pubsub announce endpoint listener services (pubsub discovery components) - if (status == CELIX_SUCCESS) { - celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; - opts.addWithProperties = pubsub_topologyManager_pubsubAnnounceEndpointListenerAdded; - opts.removeWithProperties = pubsub_topologyManager_pubsubAnnounceEndpointListenerRemoved; - opts.callbackHandle = act->manager; - opts.filter.serviceName = PUBSUB_ANNOUNCE_ENDPOINT_LISTENER_SERVICE; - act->pubsubDiscoveryTrackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts); - } - - //track pubsub admin service (psa components) - if (status == CELIX_SUCCESS) { - celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; - opts.addWithProperties = pubsub_topologyManager_psaAdded; - opts.removeWithProperties = pubsub_topologyManager_psaRemoved; - opts.callbackHandle = act->manager; - opts.filter.serviceName = PUBSUB_ADMIN_SERVICE_NAME; - act->pubsubAdminTrackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts); - } - - //track subscriber service - if (status == CELIX_SUCCESS) { - celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; - opts.addWithOwner = pubsub_topologyManager_subscriberAdded; - opts.removeWithOwner = pubsub_topologyManager_subscriberRemoved; - opts.callbackHandle = act->manager; - opts.filter.serviceName = PUBSUB_SUBSCRIBER_SERVICE_NAME; - act->pubsubSubscribersTrackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts); - } - - - //track requests for publisher services - if (status == CELIX_SUCCESS) { - act->pubsubPublishServiceTrackerId = celix_bundleContext_trackServiceTrackers(ctx, - PUBSUB_PUBLISHER_SERVICE_NAME, - act->manager, - pubsub_topologyManager_publisherTrackerAdded, - pubsub_topologyManager_publisherTrackerRemoved); - } - - if (status == CELIX_SUCCESS) { - celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; - opts.callbackHandle = act->manager; - opts.addWithProperties = pubsub_topologyManager_addMetricsService; - opts.removeWithProperties = pubsub_topologyManager_removeMetricsService; - opts.filter.serviceName = PUBSUB_ADMIN_METRICS_SERVICE_NAME; - act->pubsubPSAMetricsTrackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts); - } - - //register discovered endpoints listener service (called by pubsub discovery components) - if (status == CELIX_SUCCESS) { - act->discListenerSvc.handle = act->manager; - act->discListenerSvc.addDiscoveredEndpoint = pubsub_topologyManager_addDiscoveredEndpoint; - act->discListenerSvc.removeDiscoveredEndpoint = pubsub_topologyManager_removeDiscoveredEndpoint; - act->discListenerSvcId = celix_bundleContext_registerService(ctx, &act->discListenerSvc, PUBSUB_DISCOVERED_ENDPOINT_LISTENER_SERVICE, NULL); - } - - //register shell command - if (status == CELIX_SUCCESS) { - act->shellCmdSvc.handle = act->manager; - act->shellCmdSvc.executeCommand = pubsub_topologyManager_shellCommand; - celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, CELIX_SHELL_COMMAND_NAME, "celix::pstm"); - celix_properties_set(props, CELIX_SHELL_COMMAND_USAGE, "pstm [topology|metrics]"); //TODO add search topic/scope option - celix_properties_set(props, CELIX_SHELL_COMMAND_DESCRIPTION, "pubsub_topology_info: Overview of Topology information for PubSub"); - act->shellCmdSvcId = celix_bundleContext_registerService(ctx, &act->shellCmdSvc, CELIX_SHELL_COMMAND_SERVICE_NAME, props); - } - - //TODO add tracker for pubsub_serializer and - //1) on remove reset sender/receivers entries - //2) on add indicate that topic/senders should be reevaluated. - - /* NOTE: Enable those line in order to remotely expose the topic_info service - celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, PUBSUB_TOPIC_INFO_SERVICE); - status += bundleContext_registerService(context, (char *) PUBSUB_TOPIC_INFO_SERVICE, activator->topicInfo, props, &activator->topicInfoService); - */ - - return 0; -} - -static int pstm_stop(pstm_activator_t *act, celix_bundle_context_t *ctx) { - celix_bundleContext_stopTracker(ctx, act->pubsubSubscribersTrackerId); - celix_bundleContext_stopTracker(ctx, act->pubsubDiscoveryTrackerId); - celix_bundleContext_stopTracker(ctx, act->pubsubAdminTrackerId); - celix_bundleContext_stopTracker(ctx, act->pubsubPublishServiceTrackerId); - celix_bundleContext_stopTracker(ctx, act->pubsubPSAMetricsTrackerId); - celix_bundleContext_unregisterService(ctx, act->discListenerSvcId); - celix_bundleContext_unregisterService(ctx, act->shellCmdSvcId); - - pubsub_topologyManager_destroy(act->manager); - - celix_logHelper_destroy(act->loghelper); - - return 0; -} - -CELIX_GEN_BUNDLE_ACTIVATOR(pstm_activator_t, pstm_start, pstm_stop); diff --git a/bundles/pubsub/pubsub_topology_manager/src/pubsub_topology_manager.c b/bundles/pubsub/pubsub_topology_manager/src/pubsub_topology_manager.c deleted file mode 100644 index 1e84515c4..000000000 --- a/bundles/pubsub/pubsub_topology_manager/src/pubsub_topology_manager.c +++ /dev/null @@ -1,1406 +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 -#include -#include -#include -#include -#include -#include -#include - -#include "hash_map.h" -#include "celix_array_list.h" -#include "celix_bundle_context.h" -#include "celix_compiler.h" -#include "celix_constants.h" -#include "utils.h" -#include "celix_log_helper.h" - -#include "pubsub_listeners.h" -#include "pubsub_topology_manager.h" -#include "pubsub_admin.h" - -#define PSTM_PSA_HANDLING_SLEEPTIME_IN_SECONDS 30L - -#ifndef UUID_STR_LEN -#define UUID_STR_LEN 37 -#endif - -static void *pstm_psaHandlingThread(void *data); - -celix_status_t pubsub_topologyManager_create(celix_bundle_context_t *context, celix_log_helper_t *logHelper, pubsub_topology_manager_t **out) { - celix_status_t status = CELIX_SUCCESS; - - pubsub_topology_manager_t *manager = calloc(1, sizeof(*manager)); - if (manager == NULL) { - *out = NULL; - return CELIX_ENOMEM; - } else { - *out = manager; - } - - manager->context = context; - - status |= celixThreadMutex_create(&manager->pubsubadmins.mutex, NULL); - status |= celixThreadMutex_create(&manager->discoveredEndpoints.mutex, NULL); - status |= celixThreadMutex_create(&manager->announceEndpointListeners.mutex, NULL); - status |= celixThreadMutex_create(&manager->topicReceivers.mutex, NULL); - status |= celixThreadMutex_create(&manager->topicSenders.mutex, NULL); - status |= celixThreadMutex_create(&manager->psaMetrics.mutex, NULL); - status |= celixThreadMutex_create(&manager->psaHandling.mutex, NULL); - - status |= celixThreadCondition_init(&manager->psaHandling.cond, NULL); - - manager->discoveredEndpoints.map = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL); - manager->announceEndpointListeners.list = celix_arrayList_create(); - manager->pubsubadmins.map = hashMap_create(NULL, NULL, NULL, NULL); - manager->topicReceivers.map = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL); - manager->psaMetrics.map = hashMap_create(NULL, NULL, NULL, NULL); - manager->topicSenders.map = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL); - - manager->loghelper = logHelper; - manager->verbose = celix_bundleContext_getPropertyAsBool(context, PUBSUB_TOPOLOGY_MANAGER_VERBOSE_KEY, PUBSUB_TOPOLOGY_MANAGER_DEFAULT_VERBOSE); - unsigned handlingThreadSleepTime = celix_bundleContext_getPropertyAsLong(context, PUBSUB_TOPOLOGY_MANAGER_HANDLING_THREAD_SLEEPTIME_SECONDS_KEY, PSTM_PSA_HANDLING_SLEEPTIME_IN_SECONDS); - if ( handlingThreadSleepTime >= 0 ) { - manager->handlingThreadSleepTime = handlingThreadSleepTime * 1000L; - } - manager->handlingThreadSleepTime = celix_bundleContext_getPropertyAsLong(context, PUBSUB_TOPOLOGY_MANAGER_HANDLING_THREAD_SLEEPTIME_MS_KEY, manager->handlingThreadSleepTime); - manager->psaHandling.running = true; - celixThread_create(&manager->psaHandling.thread, NULL, pstm_psaHandlingThread, manager); - celixThread_setName(&manager->psaHandling.thread, "PubSub TopologyManager"); - - return status; -} - -celix_status_t pubsub_topologyManager_destroy(pubsub_topology_manager_t *manager) { - celix_status_t status = CELIX_SUCCESS; - - celixThreadMutex_lock(&manager->psaHandling.mutex); - manager->psaHandling.running = false; - celixThreadCondition_broadcast(&manager->psaHandling.cond); - celixThreadMutex_unlock(&manager->psaHandling.mutex); - celixThread_join(manager->psaHandling.thread, NULL); - - celixThreadMutex_lock(&manager->pubsubadmins.mutex); - hashMap_destroy(manager->pubsubadmins.map, false, false); - celixThreadMutex_unlock(&manager->pubsubadmins.mutex); - celixThreadMutex_destroy(&manager->pubsubadmins.mutex); - - celixThreadMutex_lock(&manager->discoveredEndpoints.mutex); - hash_map_iterator_t iter = hashMapIterator_construct(manager->discoveredEndpoints.map); - while (hashMapIterator_hasNext(&iter)) { - pstm_discovered_endpoint_entry_t *entry = hashMapIterator_nextValue(&iter); - if (entry != NULL) { - celix_properties_destroy(entry->endpoint); - free(entry); - } - } - hashMap_destroy(manager->discoveredEndpoints.map, false, false); - celixThreadMutex_unlock(&manager->discoveredEndpoints.mutex); - celixThreadMutex_destroy(&manager->discoveredEndpoints.mutex); - - celixThreadMutex_lock(&manager->topicReceivers.mutex); - iter = hashMapIterator_construct(manager->topicReceivers.map); - while (hashMapIterator_hasNext(&iter)) { - pstm_topic_receiver_or_sender_entry_t *entry = hashMapIterator_nextValue(&iter); - if (entry != NULL) { - free(entry->scopeAndTopicKey); - if (entry->scope != NULL) { - free(entry->scope); - } - free(entry->topic); - if (entry->topicProperties != NULL) { - celix_properties_destroy(entry->topicProperties); - } - if (entry->endpoint != NULL) { - celix_properties_destroy(entry->endpoint); - } - celix_properties_destroy(entry->subscriberProperties); - free(entry); - } - } - hashMap_destroy(manager->topicReceivers.map, false, false); - celixThreadMutex_unlock(&manager->topicReceivers.mutex); - celixThreadMutex_destroy(&manager->topicReceivers.mutex); - - celixThreadMutex_lock(&manager->topicSenders.mutex); - iter = hashMapIterator_construct(manager->topicSenders.map); - while (hashMapIterator_hasNext(&iter)) { - pstm_topic_receiver_or_sender_entry_t *entry = hashMapIterator_nextValue(&iter); - if (entry != NULL) { - free(entry->scopeAndTopicKey); - if (entry->scope != NULL) { - free(entry->scope); - } - free(entry->topic); - if (entry->topicProperties != NULL) { - celix_properties_destroy(entry->topicProperties); - } - if (entry->endpoint != NULL) { - celix_properties_destroy(entry->endpoint); - } - celix_filter_destroy(entry->publisherFilter); - free(entry); - } - } - hashMap_destroy(manager->topicSenders.map, false, false); - celixThreadMutex_unlock(&manager->topicSenders.mutex); - celixThreadMutex_destroy(&manager->topicSenders.mutex); - - celixThreadMutex_destroy(&manager->announceEndpointListeners.mutex); - celix_arrayList_destroy(manager->announceEndpointListeners.list); - - celixThreadMutex_destroy(&manager->psaMetrics.mutex); - hashMap_destroy(manager->psaMetrics.map, false, false); - - free(manager); - - return status; -} - -void pubsub_topologyManager_psaAdded(void *handle, void *svc, const celix_properties_t *props CELIX_UNUSED) { - pubsub_topology_manager_t *manager = handle; - pubsub_admin_service_t *psa = (pubsub_admin_service_t *) svc; - - - long svcId = celix_properties_getAsLong(props, CELIX_FRAMEWORK_SERVICE_ID, -1L); - const char* psaType = celix_properties_get(props, PUBSUB_ADMIN_SERVICE_TYPE, "!Error!"); - celix_logHelper_debug(manager->loghelper, "Added %s PSA", psaType); - - if (svcId >= 0) { - celixThreadMutex_lock(&manager->pubsubadmins.mutex); - hashMap_put(manager->pubsubadmins.map, (void *) svcId, psa); - celixThreadMutex_unlock(&manager->pubsubadmins.mutex); - } - - //NOTE new psa, so no endpoints announce yet - - //Because this is a new PSA every topic sender/receiver entry needs a rematch. - //This is needed because the new PSA can be a better match than currently used. - int needsRematchCount = 0; - - celixThreadMutex_lock(&manager->topicSenders.mutex); - hash_map_iterator_t iter = hashMapIterator_construct(manager->topicSenders.map); - while (hashMapIterator_hasNext(&iter)) { - pstm_topic_receiver_or_sender_entry_t *entry = hashMapIterator_nextValue(&iter); - entry->matching.needsMatch = true; - ++needsRematchCount; - } - celixThreadMutex_unlock(&manager->topicSenders.mutex); - celixThreadMutex_lock(&manager->topicReceivers.mutex); - iter = hashMapIterator_construct(manager->topicReceivers.map); - while (hashMapIterator_hasNext(&iter)) { - pstm_topic_receiver_or_sender_entry_t *entry = hashMapIterator_nextValue(&iter); - entry->matching.needsMatch = true; - ++needsRematchCount; - } - celixThreadMutex_unlock(&manager->topicReceivers.mutex); - - if (needsRematchCount > 0) { - celix_logHelper_info(manager->loghelper, - "A new PSA is added after at least one active publisher/provided. \ - It is preferred that all PSA are started before publiser/subscriber are started!\n\ - Current topic/sender count is %i", needsRematchCount); - celixThreadMutex_lock(&manager->psaHandling.mutex); - celixThreadCondition_broadcast(&manager->psaHandling.cond); - celixThreadMutex_unlock(&manager->psaHandling.mutex); - } - -} - -void pubsub_topologyManager_psaRemoved(void *handle, void *svc CELIX_UNUSED, const celix_properties_t *props) { - pubsub_topology_manager_t *manager = handle; - //pubsub_admin_service_t *psa = (pubsub_admin_service_t*) svc; - long svcId = celix_properties_getAsLong(props, CELIX_FRAMEWORK_SERVICE_ID, -1L); - const char* psaType = celix_properties_get(props, PUBSUB_ADMIN_SERVICE_TYPE, "!Error!"); - celix_logHelper_debug(manager->loghelper, "Removing %s PSA", psaType); - - // Remove the svcId from the hashmap, because the service is not available - celixThreadMutex_lock(&manager->pubsubadmins.mutex); - hashMap_remove(manager->pubsubadmins.map, (void *)svcId); - celixThreadMutex_unlock(&manager->pubsubadmins.mutex); - - // Remove the svcId from the discovered endpoint, because the service is not available - celixThreadMutex_lock(&manager->discoveredEndpoints.mutex); - hash_map_iterator_t iter_endpoint = hashMapIterator_construct(manager->discoveredEndpoints.map); - while (hashMapIterator_hasNext(&iter_endpoint)) { - pstm_discovered_endpoint_entry_t *entry = hashMapIterator_nextValue(&iter_endpoint); - if (entry != NULL && entry->selectedPsaSvcId > 0 && entry->selectedPsaSvcId == svcId) { - entry->selectedPsaSvcId = -1L; //NOTE not selected a psa anymore - } - } - celixThreadMutex_unlock(&manager->discoveredEndpoints.mutex); - - //NOTE psa shutdown will teardown topic receivers / topic senders - //de-setup all topic receivers/senders for the removed psa. - //the next psaHandling run will try to find new psa. - - celix_array_list_t* revokedEndpoints = celix_arrayList_create(); - celixThreadMutex_lock(&manager->topicSenders.mutex); - hash_map_iterator_t iter = hashMapIterator_construct(manager->topicSenders.map); - while (hashMapIterator_hasNext(&iter)) { - pstm_topic_receiver_or_sender_entry_t *entry = hashMapIterator_nextValue(&iter); - if (entry->matching.selectedPsaSvcId == svcId) { - if (entry->endpoint != NULL) { - celix_arrayList_add(revokedEndpoints, entry->endpoint); - } - - entry->matching.needsMatch = true; - entry->matching.selectedSerializerSvcId = -1L; - entry->matching.selectedProtocolSvcId = -1L; - entry->matching.selectedPsaSvcId = -1L; - entry->endpoint = NULL; - } - } - celixThreadMutex_unlock(&manager->topicSenders.mutex); - - celixThreadMutex_lock(&manager->topicReceivers.mutex); - iter = hashMapIterator_construct(manager->topicReceivers.map); - while (hashMapIterator_hasNext(&iter)) { - pstm_topic_receiver_or_sender_entry_t *entry = hashMapIterator_nextValue(&iter); - if (entry->matching.selectedPsaSvcId == svcId) { - if (entry->endpoint != NULL) { - celix_arrayList_add(revokedEndpoints, entry->endpoint); - } - - entry->matching.needsMatch = true; - entry->matching.selectedSerializerSvcId = -1L; - entry->matching.selectedProtocolSvcId = -1L; - entry->matching.selectedPsaSvcId = -1L; - entry->endpoint = NULL; - } - } - celixThreadMutex_unlock(&manager->topicReceivers.mutex); - - /* de-announce all senders & receiver endpoints */ - for (int i = 0; i < celix_arrayList_size(revokedEndpoints); ++i) { - celix_properties_t* endpoint = celix_arrayList_get(revokedEndpoints, i); - celixThreadMutex_lock(&manager->announceEndpointListeners.mutex); - for (int j = 0; j < celix_arrayList_size(manager->announceEndpointListeners.list); ++j) { - pubsub_announce_endpoint_listener_t *listener; - listener = celix_arrayList_get(manager->announceEndpointListeners.list, j); - listener->revokeEndpoint(listener->handle, endpoint); - } - celixThreadMutex_unlock(&manager->announceEndpointListeners.mutex); - celix_properties_destroy(endpoint); - } - celix_arrayList_destroy(revokedEndpoints); - - celixThreadMutex_lock(&manager->psaHandling.mutex); - celixThreadCondition_broadcast(&manager->psaHandling.cond); - celixThreadMutex_unlock(&manager->psaHandling.mutex); -} - -void pubsub_topologyManager_subscriberAdded(void *handle, void *svc CELIX_UNUSED, const celix_properties_t *props, const celix_bundle_t *bnd) { - pubsub_topology_manager_t *manager = handle; - - //NOTE new local subscriber service register - //1) First trying to see if a TopicReceiver already exists for this subscriber, if found - //2) update the usage count. if not found - //3) signal psaHandling thread to setup topic receiver - - const char *topic = celix_properties_get(props, PUBSUB_SUBSCRIBER_TOPIC, NULL); - const char *scope = celix_properties_get(props, PUBSUB_SUBSCRIBER_SCOPE, NULL); - if (topic == NULL) { - celix_logHelper_warning(manager->loghelper, - "Warning found subscriber service without mandatory '%s' property.", - PUBSUB_SUBSCRIBER_TOPIC); - return; - } - celix_logHelper_trace(manager->loghelper, "Adding subscriber %s/%s", scope, topic); - - long bndId = celix_bundle_getId(bnd); - char *scopeAndTopicKey = NULL; - scopeAndTopicKey = pubsubEndpoint_createScopeTopicKey(scope, topic); - - celixThreadMutex_lock(&manager->topicReceivers.mutex); - pstm_topic_receiver_or_sender_entry_t *entry = hashMap_get(manager->topicReceivers.map, scopeAndTopicKey); - if (entry != NULL) { - entry->usageCount += 1; - free(scopeAndTopicKey); - } else { - entry = calloc(1, sizeof(*entry)); - entry->scopeAndTopicKey = scopeAndTopicKey; //note taking ownership - entry->scope = scope == NULL ? NULL : celix_utils_strdup(scope); - entry->topic = celix_utils_strdup(topic); - entry->usageCount = 1; - entry->matching.selectedPsaSvcId = -1L; - entry->matching.selectedSerializerSvcId = -1L; - entry->matching.needsMatch = true; - entry->bndId = bndId; - entry->subscriberProperties = celix_properties_copy(props); - hashMap_put(manager->topicReceivers.map, entry->scopeAndTopicKey, entry); - celix_logHelper_trace(manager->loghelper, "Created new topic receiver entry %s", entry->scopeAndTopicKey); - } - //signal psa handling thread - bool triggerCondition = (entry->usageCount == 1); - celixThreadMutex_unlock(&manager->topicReceivers.mutex); - - if (triggerCondition) { - celixThreadMutex_lock(&manager->psaHandling.mutex); - celixThreadCondition_broadcast(&manager->psaHandling.cond); - celixThreadMutex_unlock(&manager->psaHandling.mutex); - } -} - -void pubsub_topologyManager_subscriberRemoved(void *handle, void *svc CELIX_UNUSED, const celix_properties_t *props, const celix_bundle_t *bnd) { - pubsub_topology_manager_t *manager = handle; - - //NOTE local subscriber service unregister - //1) Find topic receiver and decrease count - - const char *topic = celix_properties_get(props, PUBSUB_SUBSCRIBER_TOPIC, NULL); - const char *scope = celix_properties_get(props, PUBSUB_SUBSCRIBER_SCOPE, NULL); - - if (topic == NULL) { - return; - } - celix_logHelper_trace(manager->loghelper, "Removing subscriber %s/%s", scope, topic); - - char *scopeAndTopicKey = pubsubEndpoint_createScopeTopicKey(scope, topic); - celixThreadMutex_lock(&manager->topicReceivers.mutex); - pstm_topic_receiver_or_sender_entry_t *entry = hashMap_get(manager->topicReceivers.map, scopeAndTopicKey); - if (entry != NULL) { - entry->usageCount -= 1; - } - celixThreadMutex_unlock(&manager->topicReceivers.mutex); - free(scopeAndTopicKey); - - //NOTE not waking up psaHandling thread, topic receiver does not need to be removed immediately. -} - -void pubsub_topologyManager_pubsubAnnounceEndpointListenerAdded(void *handle, void *svc, const celix_properties_t *props CELIX_UNUSED) { - pubsub_topology_manager_t *manager = (pubsub_topology_manager_t *) handle; - pubsub_announce_endpoint_listener_t *listener = svc; - - celix_logHelper_trace(manager->loghelper, "Added EndpointListener"); - - - //1) retroactively call announceEndpoint for already existing endpoints (manager->announcedEndpoints) - //2) Add listener to manager->announceEndpointListeners - - celix_array_list_t* announceEndpoints = celix_arrayList_create(); - - celixThreadMutex_lock(&manager->announceEndpointListeners.mutex); - - celixThreadMutex_lock(&manager->topicSenders.mutex); - hash_map_iterator_t iter = hashMapIterator_construct(manager->topicSenders.map); - while (hashMapIterator_hasNext(&iter)) { - pstm_topic_receiver_or_sender_entry_t *entry = hashMapIterator_nextValue(&iter); - if (entry != NULL && entry->endpoint != NULL) { - celix_arrayList_add(announceEndpoints, celix_properties_copy(entry->endpoint)); - } - } - celixThreadMutex_unlock(&manager->topicSenders.mutex); - - celixThreadMutex_lock(&manager->topicReceivers.mutex); - iter = hashMapIterator_construct(manager->topicReceivers.map); - while (hashMapIterator_hasNext(&iter)) { - pstm_topic_receiver_or_sender_entry_t *entry = hashMapIterator_nextValue(&iter); - if (entry != NULL && entry->endpoint != NULL) { - celix_arrayList_add(announceEndpoints, celix_properties_copy(entry->endpoint)); - } - } - celixThreadMutex_unlock(&manager->topicReceivers.mutex); - - celix_arrayList_add(manager->announceEndpointListeners.list, listener); - celixThreadMutex_unlock(&manager->announceEndpointListeners.mutex); - - for (int i = 0; i < celix_arrayList_size(announceEndpoints); ++i) { - celix_properties_t* endpoint = celix_arrayList_get(announceEndpoints, i); - listener->announceEndpoint(listener->handle, endpoint); - celix_properties_destroy(endpoint); - } - celix_arrayList_destroy(announceEndpoints); -} - - -void pubsub_topologyManager_pubsubAnnounceEndpointListenerRemoved(void *handle, void *svc, const celix_properties_t *props CELIX_UNUSED) { - pubsub_topology_manager_t *manager = (pubsub_topology_manager_t *) handle; - pubsub_announce_endpoint_listener_t *listener = svc; - - celix_logHelper_trace(manager->loghelper, "Removing EndpointListener"); - - celixThreadMutex_lock(&manager->announceEndpointListeners.mutex); - celix_arrayList_remove(manager->announceEndpointListeners.list, listener); - celixThreadMutex_unlock(&manager->announceEndpointListeners.mutex); -} - -void pubsub_topologyManager_publisherTrackerAdded(void *handle, const celix_service_tracker_info_t *info) { - pubsub_topology_manager_t *manager = handle; - - //NOTE new local subscriber service register - //1) First trying to see if a TopicReceiver already exists for this subscriber, if found - //2) update the usage count. if not found - //3) signal psaHandling thread to find a psa and setup TopicSender - - - char *topicFromFilter = NULL; - char *scopeFromFilter = NULL; - pubsub_getPubSubInfoFromFilter(info->filter->filterStr, &scopeFromFilter, &topicFromFilter); - char *scope = scopeFromFilter; - char *topic = topicFromFilter; - - char *scopeAndTopicKey = NULL; - if (topic == NULL) { - celix_logHelper_log(manager->loghelper, CELIX_LOG_LEVEL_WARNING, - "[PSTM] Warning found publisher service request without mandatory '%s' filter attribute.", - PUBSUB_SUBSCRIBER_TOPIC); - return; - } - celix_logHelper_trace(manager->loghelper, "Adding new request for publisher %s/%s", scope, topic); - - - scopeAndTopicKey = pubsubEndpoint_createScopeTopicKey(scope, topic); - celixThreadMutex_lock(&manager->topicSenders.mutex); - pstm_topic_receiver_or_sender_entry_t *entry = hashMap_get(manager->topicSenders.map, scopeAndTopicKey); - if (entry != NULL) { - entry->usageCount += 1; - if (scope != NULL) { - free(scope); - } - free(topic); - free(scopeAndTopicKey); - } else { - entry = calloc(1, sizeof(*entry)); - entry->usageCount = 1; - entry->matching.needsMatch = true; - entry->matching.selectedSerializerSvcId = -1L; - entry->matching.selectedProtocolSvcId = -1L; - entry->matching.selectedPsaSvcId = -1L; - entry->scope = scope; //taking ownership - entry->topic = topic; //taking ownership - entry->scopeAndTopicKey = scopeAndTopicKey; //taking ownership - entry->publisherFilter = celix_filter_create(info->filter->filterStr); - entry->bndId = info->bundleId; - hashMap_put(manager->topicSenders.map, entry->scopeAndTopicKey, entry); - celix_logHelper_trace(manager->loghelper, "Created new topic sender entry %s", entry->scopeAndTopicKey); - } - //new entry -> wakeup psaHandling thread - bool triggerCondition = (entry->usageCount == 1); - - celixThreadMutex_unlock(&manager->topicSenders.mutex); - - if (triggerCondition) { - celixThreadMutex_lock(&manager->psaHandling.mutex); - celixThreadCondition_broadcast(&manager->psaHandling.cond); - celixThreadMutex_unlock(&manager->psaHandling.mutex); - } -} - -void pubsub_topologyManager_publisherTrackerRemoved(void *handle, const celix_service_tracker_info_t *info) { - pubsub_topology_manager_t *manager = handle; - - //NOTE local subscriber service unregister - //1) Find topic sender and decrease count - - char *topic = NULL; - char *scopeFromFilter = NULL; - pubsub_getPubSubInfoFromFilter(info->filter->filterStr, &scopeFromFilter, &topic); - const char *scope = scopeFromFilter; - - if (topic == NULL) { - if (scopeFromFilter != NULL) { - free(scopeFromFilter); - } - return; - } - celix_logHelper_trace(manager->loghelper, "Removing request for publisher %s/%s", scope, topic); - - - char *scopeAndTopicKey = pubsubEndpoint_createScopeTopicKey(scope, topic); - celixThreadMutex_lock(&manager->topicSenders.mutex); - pstm_topic_receiver_or_sender_entry_t *entry = hashMap_get(manager->topicSenders.map, scopeAndTopicKey); - if (entry != NULL) { - entry->usageCount -= 1; - } - celixThreadMutex_unlock(&manager->topicSenders.mutex); - - free(scopeAndTopicKey); - free(topic); - if (scopeFromFilter != NULL) { - free(scopeFromFilter); - } - - //NOTE not waking up psaHandling thread, topic sender does not need to be removed immediately. -} - -celix_status_t pubsub_topologyManager_addDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint) { - celix_status_t status = CELIX_SUCCESS; - pubsub_topology_manager_t *manager = handle; - - const char *uuid = celix_properties_get(endpoint, PUBSUB_ENDPOINT_UUID, NULL); - assert(uuid != NULL); //discovery should check if endpoint is valid -> pubsubEndpoint_isValid. - - // 1) See if endpoint is already discovered, if so increase usage count. - // 1) If not, find matching psa using the matchEndpoint - // 2) if found call addEndpoint of the matching psa - bool triggerCondition = false; - - if (manager->verbose) { - celix_logHelper_trace(manager->loghelper, - "Adding discovered endpoint for topic %s with scope %s [fwUUID=%s, epUUID=%s]\n", - celix_properties_get(endpoint, PUBSUB_ENDPOINT_TOPIC_NAME, NULL), - celix_properties_get(endpoint, PUBSUB_ENDPOINT_TOPIC_SCOPE, "(null)"), - celix_properties_get(endpoint, PUBSUB_ENDPOINT_FRAMEWORK_UUID, NULL), - uuid); - } - - - celixThreadMutex_lock(&manager->discoveredEndpoints.mutex); - pstm_discovered_endpoint_entry_t *entry = hashMap_get(manager->discoveredEndpoints.map, uuid); - if (entry != NULL) { - //already existing endpoint -> increase usage - entry->usageCount += 1; - } else { - //new endpoint -> new entry - entry = calloc(1, sizeof(*entry)); - entry->usageCount = 1; - entry->endpoint = celix_properties_copy(endpoint); - entry->uuid = celix_properties_get(entry->endpoint, PUBSUB_ENDPOINT_UUID, NULL); - entry->selectedPsaSvcId = -1L; //NOTE not selected a psa yet - hashMap_put(manager->discoveredEndpoints.map, (void *) entry->uuid, entry); - celix_logHelper_trace(manager->loghelper, "Created new discovered endpoint entry %s", uuid); - - //waking up psa handling thread to select psa - triggerCondition = true; - - } - celixThreadMutex_unlock(&manager->discoveredEndpoints.mutex); - - if (triggerCondition) { - celixThreadMutex_lock(&manager->psaHandling.mutex); - celixThreadCondition_broadcast(&manager->psaHandling.cond); - celixThreadMutex_unlock(&manager->psaHandling.mutex); - } - - return status; -} - -static void pstm_removeEndpointCallback(void *handle, void *svc) { - celix_properties_t *endpoint = handle; - pubsub_admin_service_t *psa = svc; - psa->removeDiscoveredEndpoint(psa->handle, endpoint); -} - -celix_status_t pubsub_topologyManager_removeDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint) { - pubsub_topology_manager_t *manager = handle; - - // 1) See if endpoint is already discovered, if so decrease usage count. - // 1) If usage count becomes 0, find matching psa using the matchEndpoint - // 2) if found call disconnectEndpoint of the matching psa - - const char *uuid = celix_properties_get(endpoint, PUBSUB_ENDPOINT_UUID, NULL); - assert(uuid != NULL); //discovery should check if endpoint is valid -> pubsubEndoint_isValid. - - if (manager->verbose) { - celix_logHelper_trace(manager->loghelper, - "Removing discovered endpoint for topic %s with scope %s [fwUUID=%s, epUUID=%s]\n", - celix_properties_get(endpoint, PUBSUB_ENDPOINT_TOPIC_NAME, "(null)"), - celix_properties_get(endpoint, PUBSUB_ENDPOINT_TOPIC_SCOPE, "(null)"), - celix_properties_get(endpoint, PUBSUB_ENDPOINT_FRAMEWORK_UUID, "(null)"), - uuid); - } - - celixThreadMutex_lock(&manager->discoveredEndpoints.mutex); - pstm_discovered_endpoint_entry_t *entry = hashMap_get(manager->discoveredEndpoints.map, uuid); - if (entry != NULL) { - //already existing endpoint -> decrease usage - entry->usageCount -= 1; - if (entry->usageCount <= 0) { - hashMap_remove(manager->discoveredEndpoints.map, entry->uuid); - } else { - entry = NULL; //still used (usage count > 0) -> do nothing - } - } - celixThreadMutex_unlock(&manager->discoveredEndpoints.mutex); - - if (entry != NULL) { - //note entry is removed from manager->discoveredEndpoints, also inform used psa - if (entry->selectedPsaSvcId >= 0) { - //note that it is possible that the psa is already gone, in that case the call is also not needed anymore. - celix_bundleContext_useServiceWithId(manager->context, entry->selectedPsaSvcId, PUBSUB_ADMIN_SERVICE_NAME, - (void *) endpoint, pstm_removeEndpointCallback); - } else { - celix_logHelper_log(manager->loghelper, CELIX_LOG_LEVEL_DEBUG, "No selected psa for endpoint %s\n", entry->uuid); - } - celix_logHelper_trace(manager->loghelper, "Destroying discovered endpoint entry %s", uuid); - celix_properties_destroy(entry->endpoint); - free(entry); - } - - - return CELIX_SUCCESS; -} - -struct pstm_teardown_entry { - char* scope; - char* topic; - long psaSvcId; -}; - -static void pstm_teardownTopicSenderCallback(void *handle, void *svc) { - struct pstm_teardown_entry* entry = handle; - pubsub_admin_service_t *psa = svc; - psa->teardownTopicSender(psa->handle, entry->scope, entry->topic); -} - -//Note called on pstm update thread -static void pstm_teardownTopicSenders(pubsub_topology_manager_t *manager) { - celix_array_list_t* revokeEndpoints = celix_arrayList_create(); - celix_array_list_t* teardownEntries = celix_arrayList_create(); - - celixThreadMutex_lock(&manager->topicSenders.mutex); - hash_map_iterator_t iter = hashMapIterator_construct(manager->topicSenders.map); - while (hashMapIterator_hasNext(&iter)) { - pstm_topic_receiver_or_sender_entry_t *entry = hashMapIterator_nextValue(&iter); - - if (entry != NULL && (entry->usageCount <= 0 || entry->matching.needsMatch)) { - if (manager->verbose && entry->endpoint != NULL) { - celix_logHelper_log(manager->loghelper, CELIX_LOG_LEVEL_DEBUG, - "Tearing down TopicSender for scope/topic %s/%s\n", entry->scope == NULL ? "(null)" : entry->scope, entry->topic); - } - if (entry->endpoint != NULL) { - celix_arrayList_add(revokeEndpoints, celix_properties_copy(entry->endpoint)); - struct pstm_teardown_entry* teardownEntry = malloc(sizeof(*teardownEntry)); - teardownEntry->scope = celix_utils_strdup(entry->scope); - teardownEntry->topic = celix_utils_strdup(entry->topic); - teardownEntry->psaSvcId = entry->matching.selectedPsaSvcId; - celix_arrayList_add(teardownEntries, teardownEntry); - } - - //cleanup entry - if (entry->usageCount <= 0) { - //no usage -> remove - hashMapIterator_remove(&iter); - free(entry->scopeAndTopicKey); - if (entry->scope != NULL) { - free(entry->scope); - } - free(entry->topic); - if (entry->topicProperties != NULL) { - celix_properties_destroy(entry->topicProperties); - } - if (entry->publisherFilter != NULL) { - celix_filter_destroy(entry->publisherFilter); - } - if (entry->endpoint != NULL) { - celix_properties_destroy(entry->endpoint); - } - free(entry); - } else { - //still usage, setup for new match - if (entry->endpoint != NULL) { - celix_properties_destroy(entry->endpoint); - } - entry->endpoint = NULL; - entry->matching.selectedPsaSvcId = -1L; - entry->matching.selectedSerializerSvcId = -1L; - entry->matching.selectedProtocolSvcId = -1L; - } - } - } - celixThreadMutex_unlock(&manager->topicSenders.mutex); - - - - celixThreadMutex_lock(&manager->announceEndpointListeners.mutex); - for (int i = 0; i < celix_arrayList_size(manager->announceEndpointListeners.list); ++i) { - pubsub_announce_endpoint_listener_t *listener; - listener = celix_arrayList_get(manager->announceEndpointListeners.list, i); - for (int k = 0; k < celix_arrayList_size(revokeEndpoints); ++k) { - celix_properties_t* endpoint = celix_arrayList_get(revokeEndpoints, k); - listener->revokeEndpoint(listener->handle, endpoint); - } - } - for (int k = 0; k < celix_arrayList_size(revokeEndpoints); ++k) { - celix_properties_t* endpoint = celix_arrayList_get(revokeEndpoints, k); - celix_properties_destroy(endpoint); - } - celixThreadMutex_unlock(&manager->announceEndpointListeners.mutex); - celix_arrayList_destroy(revokeEndpoints); - - for (int i = 0; i < celix_arrayList_size(teardownEntries); ++i) { - struct pstm_teardown_entry* entry = celix_arrayList_get(teardownEntries, i); - celix_bundleContext_useServiceWithId(manager->context, entry->psaSvcId, - PUBSUB_ADMIN_SERVICE_NAME, - entry, pstm_teardownTopicSenderCallback); - free(entry->scope); - free(entry->topic); - free(entry); - } - celix_arrayList_destroy(teardownEntries); -} - -static void pstm_teardownTopicReceiverCallback(void *handle, void *svc) { - struct pstm_teardown_entry* entry = handle; - pubsub_admin_service_t *psa = svc; - psa->teardownTopicReceiver(psa->handle, entry->scope, entry->topic); -} - -static void pstm_teardownTopicReceivers(pubsub_topology_manager_t *manager) { - celix_array_list_t* revokeEndpoints = celix_arrayList_create(); - celix_array_list_t* teardownEntries = celix_arrayList_create(); - - celixThreadMutex_lock(&manager->topicReceivers.mutex); - hash_map_iterator_t iter = hashMapIterator_construct(manager->topicReceivers.map); - while (hashMapIterator_hasNext(&iter)) { - pstm_topic_receiver_or_sender_entry_t *entry = hashMapIterator_nextValue(&iter); - if (entry != NULL && (entry->usageCount <= 0 || entry->matching.needsMatch)) { - if (manager->verbose && entry->endpoint != NULL) { - const char *adminType = celix_properties_get(entry->endpoint, PUBSUB_ENDPOINT_ADMIN_TYPE, "!Error!"); - const char *serType = celix_properties_get(entry->endpoint, PUBSUB_ENDPOINT_SERIALIZER, "!Error!"); - celix_logHelper_log(manager->loghelper, CELIX_LOG_LEVEL_DEBUG, - "Tearing down TopicReceiver for scope/topic %s/%s with psa admin type %s and serializer %s\n", - entry->scope == NULL ? "(null)" : entry->scope, entry->topic, adminType, serType); - } - if (entry->endpoint != NULL) { - celix_arrayList_add(revokeEndpoints, celix_properties_copy(entry->endpoint)); - struct pstm_teardown_entry* teardownEntry = malloc(sizeof(*teardownEntry)); - teardownEntry->scope = celix_utils_strdup(entry->scope); - teardownEntry->topic = celix_utils_strdup(entry->topic); - teardownEntry->psaSvcId = entry->matching.selectedPsaSvcId; - celix_arrayList_add(teardownEntries, teardownEntry); - } - - if (entry->usageCount <= 0) { - //no usage -> remove - hashMapIterator_remove(&iter); - //cleanup entry - free(entry->scopeAndTopicKey); - if (entry->scope != NULL) { - free(entry->scope); - } - free(entry->topic); - if (entry->topicProperties != NULL) { - celix_properties_destroy(entry->topicProperties); - } - if (entry->subscriberProperties != NULL) { - celix_properties_destroy(entry->subscriberProperties); - } - if (entry->endpoint != NULL) { - celix_properties_destroy(entry->endpoint); - } - free(entry); - } else { - //still usage -> setup for rematch - if (entry->endpoint != NULL) { - celix_properties_destroy(entry->endpoint); - } - entry->endpoint = NULL; - entry->matching.selectedPsaSvcId = -1L; - entry->matching.selectedSerializerSvcId = -1L; - entry->matching.selectedProtocolSvcId = -1L; - } - } - } - celixThreadMutex_unlock(&manager->topicReceivers.mutex); - - celixThreadMutex_lock(&manager->announceEndpointListeners.mutex); - for (int i = 0; i < celix_arrayList_size(manager->announceEndpointListeners.list); ++i) { - pubsub_announce_endpoint_listener_t *listener; - listener = celix_arrayList_get(manager->announceEndpointListeners.list, i); - for (int k = 0; k < celix_arrayList_size(revokeEndpoints); ++k) { - celix_properties_t* endpoint = celix_arrayList_get(revokeEndpoints, k); - listener->revokeEndpoint(listener->handle, endpoint); - } - } - // Clean-up properties - for (int k = 0; k < celix_arrayList_size(revokeEndpoints); ++k) { - celix_properties_t* endpoint = celix_arrayList_get(revokeEndpoints, k); - celix_properties_destroy(endpoint); - } - celixThreadMutex_unlock(&manager->announceEndpointListeners.mutex); - celix_arrayList_destroy(revokeEndpoints); - - for (int i = 0; i < celix_arrayList_size(teardownEntries); ++i) { - struct pstm_teardown_entry* entry = celix_arrayList_get(teardownEntries, i); - celix_bundleContext_useServiceWithId(manager->context, entry->psaSvcId, - PUBSUB_ADMIN_SERVICE_NAME, - entry, pstm_teardownTopicReceiverCallback); - free(entry->scope); - free(entry->topic); - free(entry); - } - celix_arrayList_destroy(teardownEntries); -} - -static void pstm_addEndpointCallback(void *handle, void *svc) { - celix_properties_t *endpoint = handle; - pubsub_admin_service_t *psa = svc; - psa->addDiscoveredEndpoint(psa->handle, endpoint); -} - -static void pstm_findPsaForEndpoints(pubsub_topology_manager_t *manager) { - celixThreadMutex_lock(&manager->discoveredEndpoints.mutex); - hash_map_iterator_t iter = hashMapIterator_construct(manager->discoveredEndpoints.map); - while (hashMapIterator_hasNext(&iter)) { - pstm_discovered_endpoint_entry_t *entry = hashMapIterator_nextValue(&iter); - if (entry != NULL && entry->selectedPsaSvcId < 0) { - long psaSvcId = -1L; - - celixThreadMutex_lock(&manager->pubsubadmins.mutex); - hash_map_iterator_t iter2 = hashMapIterator_construct(manager->pubsubadmins.map); - while (hashMapIterator_hasNext(&iter2)) { - hash_map_entry_t *mapEntry = hashMapIterator_nextEntry(&iter2); - pubsub_admin_service_t *psa = hashMapEntry_getValue(mapEntry); - long svcId = (long) hashMapEntry_getKey(mapEntry); - bool match = false; - //NOTE assuming match is safe to call within a lock - psa->matchDiscoveredEndpoint(psa->handle, entry->endpoint, &match); - if (match) { - psaSvcId = svcId; - break; - } - } - celixThreadMutex_unlock(&manager->pubsubadmins.mutex); - - if (psaSvcId >= 0) { - //NOTE assuming adding discovered endpoint is safe to call within a lock - celix_bundleContext_useServiceWithId(manager->context, psaSvcId, PUBSUB_ADMIN_SERVICE_NAME, - (void *) entry->endpoint, pstm_addEndpointCallback); - } else { - celix_logHelper_log(manager->loghelper, CELIX_LOG_LEVEL_DEBUG, "Cannot find psa for endpoint %s\n", entry->uuid); - } - - entry->selectedPsaSvcId = psaSvcId; - } - } - celixThreadMutex_unlock(&manager->discoveredEndpoints.mutex); -} - -struct pstm_setup_entry { - char* scope; - char* topic; - char* key; - celix_properties_t* topicProperties; - long selectedSerializerSvcId; - long selectedProtocolSvcId; - long psaSvcId; - celix_properties_t* endpointResult; -}; - -static void pstm_setupTopicSenderCallback(void *handle, void *svc) { - struct pstm_setup_entry *entry = handle; - pubsub_admin_service_t *psa = svc; - psa->setupTopicSender(psa->handle, entry->scope, entry->topic, entry->topicProperties, entry->selectedSerializerSvcId, entry->selectedProtocolSvcId, &entry->endpointResult); -} - -static void pstm_setupTopicSenders(pubsub_topology_manager_t *manager) { - celix_array_list_t* setupEntries = celix_arrayList_create(); - - celixThreadMutex_lock(&manager->topicSenders.mutex); - hash_map_iterator_t iter = hashMapIterator_construct(manager->topicSenders.map); - while (hashMapIterator_hasNext(&iter)) { - pstm_topic_receiver_or_sender_entry_t *entry = hashMapIterator_nextValue(&iter); - if (entry != NULL && entry->matching.needsMatch && entry->usageCount > 0) { - //new topic sender needed, requesting match with current psa - double highestScore = PUBSUB_ADMIN_NO_MATCH_SCORE; - long serializerSvcId = -1L; - long protocolSvcId = -1L; - long selectedPsaSvcId = -1L; - celix_properties_t *topicPropertiesForHighestMatch = NULL; - - celixThreadMutex_lock(&manager->pubsubadmins.mutex); - hash_map_iterator_t iter2 = hashMapIterator_construct(manager->pubsubadmins.map); - while (hashMapIterator_hasNext(&iter2)) { - hash_map_entry_t *mapEntry = hashMapIterator_nextEntry(&iter2); - long svcId = (long) hashMapEntry_getKey(mapEntry); - pubsub_admin_service_t *psa = hashMapEntry_getValue(mapEntry); - double score = PUBSUB_ADMIN_NO_MATCH_SCORE; - long serSvcId = -1L; - long protSvcId = -1L; - celix_properties_t *topicProps = NULL; - //NOTE assuming matchPublisher is safe to call within lock - psa->matchPublisher(psa->handle, entry->bndId, entry->publisherFilter, &topicProps, &score, &serSvcId, - &protSvcId); - if (score > highestScore) { - celix_properties_destroy(topicPropertiesForHighestMatch); - highestScore = score; - serializerSvcId = serSvcId; - protocolSvcId = protSvcId; - selectedPsaSvcId = svcId; - topicPropertiesForHighestMatch = topicProps; - } else { - celix_properties_destroy(topicProps); - } - } - celixThreadMutex_unlock(&manager->pubsubadmins.mutex); - - if (highestScore > PUBSUB_ADMIN_NO_MATCH_SCORE) { - entry->matching.needsMatch = false; - //NOTE the needsMatch can be updated as soon as the lock manager->topicSenders.mutex is released. - //This is ok, because the next pstm update loop will then do a new teardown/setup - - struct pstm_setup_entry *setupEntry = malloc(sizeof(*setupEntry)); - setupEntry->endpointResult = NULL; - setupEntry->scope = celix_utils_strdup(entry->scope); - setupEntry->topic = celix_utils_strdup(entry->topic); - setupEntry->key = pubsubEndpoint_createScopeTopicKey(entry->scope, entry->topic); - setupEntry->topicProperties = topicPropertiesForHighestMatch; - setupEntry->psaSvcId = selectedPsaSvcId; - setupEntry->selectedSerializerSvcId = serializerSvcId; - setupEntry->selectedProtocolSvcId = protocolSvcId; - celix_arrayList_add(setupEntries, setupEntry); - celix_logHelper_debug(manager->loghelper, "Found PSA match for publisher with scope/topic %s/%s. PSA svc id is %li", entry->scope, entry->topic, selectedPsaSvcId); - } else { - celix_logHelper_trace(manager->loghelper, - "No PSA match for publisher with scope/topic %s/%s. Provided filter %s", - entry->scope, - entry->topic, - celix_filter_getFilterString(entry->publisherFilter)); - celix_properties_destroy(topicPropertiesForHighestMatch); - } - } - } - celixThreadMutex_unlock(&manager->topicSenders.mutex); - - for (int i = 0; i < celix_arrayList_size(setupEntries); ++i) { - struct pstm_setup_entry* setupEntry = celix_arrayList_get(setupEntries, i); - bool called = celix_bundleContext_useServiceWithId(manager->context, setupEntry->psaSvcId, PUBSUB_ADMIN_SERVICE_NAME, setupEntry, pstm_setupTopicSenderCallback); - if (called && setupEntry->endpointResult != NULL) { - celixThreadMutex_lock(&manager->announceEndpointListeners.mutex); - for (int k = 0; k < celix_arrayList_size(manager->announceEndpointListeners.list); ++k) { - pubsub_announce_endpoint_listener_t *listener = celix_arrayList_get(manager->announceEndpointListeners.list, k); - listener->announceEndpoint(listener->handle, setupEntry->endpointResult); - } - celixThreadMutex_unlock(&manager->announceEndpointListeners.mutex); - - celixThreadMutex_lock(&manager->topicSenders.mutex); - pstm_topic_receiver_or_sender_entry_t* entry = hashMap_get(manager->topicSenders.map, setupEntry->key); - if (entry->endpoint != NULL) { - celix_properties_destroy(entry->endpoint); - } - entry->endpoint = setupEntry->endpointResult; - entry->topicProperties = setupEntry->topicProperties; - entry->matching.selectedPsaSvcId = setupEntry->psaSvcId; - entry->matching.selectedSerializerSvcId = setupEntry->selectedSerializerSvcId; - entry->matching.selectedProtocolSvcId = setupEntry->selectedProtocolSvcId; - celixThreadMutex_unlock(&manager->topicSenders.mutex); - } else { - celix_logHelper_warning(manager->loghelper, "Cannot setup TopicSender for %s/%s\n", setupEntry->scope == NULL ? "(null)" : setupEntry->scope, setupEntry->topic); - celixThreadMutex_lock(&manager->topicSenders.mutex); - pstm_topic_receiver_or_sender_entry_t* entry = hashMap_get(manager->topicSenders.map, setupEntry->key); - entry->matching.needsMatch = true; - celixThreadMutex_unlock(&manager->topicSenders.mutex); - celix_properties_destroy(setupEntry->topicProperties); - celix_properties_destroy(setupEntry->endpointResult); - } - free(setupEntry->scope); - free(setupEntry->topic); - free(setupEntry->key); - free(setupEntry); - } - - celix_arrayList_destroy(setupEntries); -} - -static void pstm_setupTopicReceiverCallback(void *handle, void *svc) { - struct pstm_setup_entry *entry = handle; - pubsub_admin_service_t *psa = svc; - psa->setupTopicReceiver(psa->handle, entry->scope, entry->topic, entry->topicProperties, entry->selectedSerializerSvcId, entry->selectedProtocolSvcId, &entry->endpointResult); -} - -static void pstm_setupTopicReceivers(pubsub_topology_manager_t *manager) { - celix_array_list_t* setupEntries = celix_arrayList_create(); - - celixThreadMutex_lock(&manager->topicReceivers.mutex); - hash_map_iterator_t iter = hashMapIterator_construct(manager->topicReceivers.map); - while (hashMapIterator_hasNext(&iter)) { - pstm_topic_receiver_or_sender_entry_t *entry = hashMapIterator_nextValue(&iter); - if (entry != NULL && entry->matching.needsMatch && entry->usageCount > 0) { - - double highestScore = PUBSUB_ADMIN_NO_MATCH_SCORE; - long serializerSvcId = -1L; - long protocolSvcId = -1L; - long selectedPsaSvcId = -1L; - celix_properties_t *highestMatchTopicProperties = NULL; - - celixThreadMutex_lock(&manager->pubsubadmins.mutex); - hash_map_iterator_t iter2 = hashMapIterator_construct(manager->pubsubadmins.map); - while (hashMapIterator_hasNext(&iter2)) { - hash_map_entry_t *mapEntry = hashMapIterator_nextEntry(&iter2); - long svcId = (long) hashMapEntry_getKey(mapEntry); - pubsub_admin_service_t *psa = hashMapEntry_getValue(mapEntry); - double score = PUBSUB_ADMIN_NO_MATCH_SCORE; - long serSvcId = -1L; - long protSvcId = -1L; - celix_properties_t *topicProps = NULL; - - psa->matchSubscriber(psa->handle, entry->bndId, entry->subscriberProperties, &topicProps, &score, - &serSvcId, &protSvcId); - if (score > highestScore) { - if (highestMatchTopicProperties != NULL) { - celix_properties_destroy(highestMatchTopicProperties); - } - highestScore = score; - serializerSvcId = serSvcId; - protocolSvcId = protSvcId; - selectedPsaSvcId = svcId; - highestMatchTopicProperties = topicProps; - } else if (topicProps != NULL) { - celix_properties_destroy(topicProps); - } - } - celixThreadMutex_unlock(&manager->pubsubadmins.mutex); - - if (highestScore > PUBSUB_ADMIN_NO_MATCH_SCORE) { - entry->matching.needsMatch = false; - //NOTE the needsMatch can be updated as soon as the lock manager->topicSenders.mutex is released. - //This is ok, because the next pstm update loop will then do a new teardown/setup - - struct pstm_setup_entry *setupEntry = malloc(sizeof(*setupEntry)); - setupEntry->endpointResult = NULL; - setupEntry->scope = celix_utils_strdup(entry->scope); - setupEntry->topic = celix_utils_strdup(entry->topic); - setupEntry->key = pubsubEndpoint_createScopeTopicKey(entry->scope, entry->topic); - setupEntry->topicProperties = highestMatchTopicProperties; - setupEntry->psaSvcId = selectedPsaSvcId; - setupEntry->selectedSerializerSvcId = serializerSvcId; - setupEntry->selectedProtocolSvcId = protocolSvcId; - celix_arrayList_add(setupEntries, setupEntry); - celix_logHelper_debug(manager->loghelper, "Found PSA match for subscriber with scope/topic %s/%s. PSA svc id is %li", entry->scope, entry->topic, selectedPsaSvcId); - } else { - celix_logHelper_trace(manager->loghelper, - "No PSA match for subscriber with scope/topic %s/%s.", - entry->scope, - entry->topic); - } - } - } - celixThreadMutex_unlock(&manager->topicReceivers.mutex); - - - - for (int i = 0; i < celix_arrayList_size(setupEntries); ++i) { - struct pstm_setup_entry* setupEntry = celix_arrayList_get(setupEntries, i); - bool called = celix_bundleContext_useServiceWithId(manager->context, setupEntry->psaSvcId, PUBSUB_ADMIN_SERVICE_NAME, setupEntry, pstm_setupTopicReceiverCallback); - if (called && setupEntry->endpointResult != NULL) { - celixThreadMutex_lock(&manager->announceEndpointListeners.mutex); - for (int k = 0; k < celix_arrayList_size(manager->announceEndpointListeners.list); ++k) { - pubsub_announce_endpoint_listener_t *listener = celix_arrayList_get(manager->announceEndpointListeners.list, k); - listener->announceEndpoint(listener->handle, setupEntry->endpointResult); - } - celixThreadMutex_unlock(&manager->announceEndpointListeners.mutex); - - celixThreadMutex_lock(&manager->topicReceivers.mutex); - pstm_topic_receiver_or_sender_entry_t* entry = hashMap_get(manager->topicReceivers.map, setupEntry->key); - if (entry->endpoint != NULL) { - celix_properties_destroy(entry->endpoint); - } - entry->endpoint = setupEntry->endpointResult; - entry->topicProperties = setupEntry->topicProperties; - entry->matching.selectedPsaSvcId = setupEntry->psaSvcId; - entry->matching.selectedSerializerSvcId = setupEntry->selectedSerializerSvcId; - entry->matching.selectedProtocolSvcId = setupEntry->selectedProtocolSvcId; - celixThreadMutex_unlock(&manager->topicReceivers.mutex); - } else { - celix_logHelper_warning(manager->loghelper, "Cannot setup TopicReceiver for %s/%s\n", setupEntry->scope == NULL ? "(null)" : setupEntry->scope, setupEntry->topic); - celixThreadMutex_lock(&manager->topicReceivers.mutex); - pstm_topic_receiver_or_sender_entry_t* entry = hashMap_get(manager->topicReceivers.map, setupEntry->key); - entry->matching.needsMatch = true; - celixThreadMutex_unlock(&manager->topicReceivers.mutex); - } - free(setupEntry->scope); - free(setupEntry->topic); - free(setupEntry->key); - free(setupEntry); - } - - celix_arrayList_destroy(setupEntries); -} - -static void *pstm_psaHandlingThread(void *data) { - pubsub_topology_manager_t *manager = data; - - celixThreadMutex_lock(&manager->psaHandling.mutex); - bool running = manager->psaHandling.running; - celixThreadMutex_unlock(&manager->psaHandling.mutex); - - while (running) { - //first teardown -> also if rematch is needed - pstm_teardownTopicSenders(manager); - pstm_teardownTopicReceivers(manager); - - //then see if any topic sender/receiver are needed - pstm_setupTopicSenders(manager); - pstm_setupTopicReceivers(manager); - - pstm_findPsaForEndpoints(manager); //trying to find psa and possible set for endpoints with no psa - - celixThreadMutex_lock(&manager->psaHandling.mutex); - celixThreadCondition_timedwaitRelative(&manager->psaHandling.cond, &manager->psaHandling.mutex, manager->handlingThreadSleepTime / 1000, (manager->handlingThreadSleepTime % 1000) * 1000000); - running = manager->psaHandling.running; - celixThreadMutex_unlock(&manager->psaHandling.mutex); - } - return NULL; -} - -void pubsub_topologyManager_addMetricsService(void * handle, void *svc, const celix_properties_t *props) { - pubsub_topology_manager_t *manager = handle; - long svcId = celix_properties_getAsLong(props, CELIX_FRAMEWORK_SERVICE_ID, -1L); - celixThreadMutex_lock(&manager->psaMetrics.mutex); - hashMap_put(manager->psaMetrics.map, (void*)svcId, svc); - celixThreadMutex_unlock(&manager->psaMetrics.mutex); -} - -void pubsub_topologyManager_removeMetricsService(void * handle, void *svc, const celix_properties_t *props) { - pubsub_topology_manager_t *manager = handle; - long svcId = celix_properties_getAsLong(props, CELIX_FRAMEWORK_SERVICE_ID, -1L); - celixThreadMutex_lock(&manager->psaMetrics.mutex); - hashMap_remove(manager->psaMetrics.map, (void*)svcId); - celixThreadMutex_unlock(&manager->psaMetrics.mutex); -} - -static celix_status_t pubsub_topologyManager_topology(pubsub_topology_manager_t *manager, const char *commandLine CELIX_UNUSED, FILE *os, FILE *errorStream CELIX_UNUSED) { - fprintf(os, "\n"); - - fprintf(os, "Discovered Endpoints: \n"); - celixThreadMutex_lock(&manager->discoveredEndpoints.mutex); - hash_map_iterator_t iter = hashMapIterator_construct(manager->discoveredEndpoints.map); - while (hashMapIterator_hasNext(&iter)) { - pstm_discovered_endpoint_entry_t *discovered = hashMapIterator_nextValue(&iter); - const char *cn = celix_properties_get(discovered->endpoint, "container_name", "!Error!"); - const char *fwuuid = celix_properties_get(discovered->endpoint, PUBSUB_ENDPOINT_FRAMEWORK_UUID, "!Error!"); - const char *type = celix_properties_get(discovered->endpoint, PUBSUB_ENDPOINT_TYPE, "!Error!"); - const char *scope = celix_properties_get(discovered->endpoint, PUBSUB_ENDPOINT_TOPIC_SCOPE, "(null)"); - const char *topic = celix_properties_get(discovered->endpoint, PUBSUB_ENDPOINT_TOPIC_NAME, "!Error!"); - const char *adminType = celix_properties_get(discovered->endpoint, PUBSUB_ENDPOINT_ADMIN_TYPE, "!Error!"); - const char *serType = celix_properties_get(discovered->endpoint, PUBSUB_ENDPOINT_SERIALIZER, "!Error!"); - const char *protType = celix_properties_get(discovered->endpoint, PUBSUB_ENDPOINT_PROTOCOL, "!Error!"); - fprintf(os, "|- Discovered Endpoint %s:\n", discovered->uuid); - fprintf(os, " |- container name = %s\n", cn); - fprintf(os, " |- fw uuid = %s\n", fwuuid); - fprintf(os, " |- type = %s\n", type); - fprintf(os, " |- scope = %s\n", scope); - fprintf(os, " |- topic = %s\n", topic); - fprintf(os, " |- admin type = %s\n", adminType); - fprintf(os, " |- serializer = %s\n", serType); - fprintf(os, " |- protocol = %s\n", protType); - if (manager->verbose) { - fprintf(os, " |- psa svc id = %li\n", discovered->selectedPsaSvcId); - fprintf(os, " |- usage count = %i\n", discovered->usageCount); - } - } - celixThreadMutex_unlock(&manager->discoveredEndpoints.mutex); - fprintf(os, "\n"); - - - fprintf(os, "Active Topic Senders:\n"); - int countPendingSenders = 0; - celixThreadMutex_lock(&manager->topicSenders.mutex); - iter = hashMapIterator_construct(manager->topicSenders.map); - while (hashMapIterator_hasNext(&iter)) { - pstm_topic_receiver_or_sender_entry_t *entry = hashMapIterator_nextValue(&iter); - if (entry->endpoint == NULL) { - ++countPendingSenders; - continue; - } - const char *uuid = celix_properties_get(entry->endpoint, PUBSUB_ENDPOINT_UUID, "!Error!"); - const char *adminType = celix_properties_get(entry->endpoint, PUBSUB_ENDPOINT_ADMIN_TYPE, "!Error!"); - const char *serType = celix_properties_get(entry->endpoint, PUBSUB_ENDPOINT_SERIALIZER, "!Error!"); - const char *protType = celix_properties_get(entry->endpoint, PUBSUB_ENDPOINT_PROTOCOL, "!Error!"); - fprintf(os, "|- Topic Sender for endpoint %s:\n", uuid); - fprintf(os, " |- scope = %s\n", entry->scope == NULL ? "(null)" : entry->scope); - fprintf(os, " |- topic = %s\n", entry->topic); - fprintf(os, " |- admin type = %s\n", adminType); - fprintf(os, " |- serializer = %s\n", serType); - fprintf(os, " |- protocol = %s\n", protType); - if (manager->verbose) { - fprintf(os, " |- psa svc id = %li\n", entry->matching.selectedPsaSvcId); - fprintf(os, " |- ser svc id = %li\n", entry->matching.selectedSerializerSvcId); - fprintf(os, " |- prot svc id = %li\n", entry->matching.selectedProtocolSvcId); - fprintf(os, " |- usage count = %i\n", entry->usageCount); - } - } - celixThreadMutex_unlock(&manager->topicSenders.mutex); - fprintf(os, "\n"); - - fprintf(os, "Active Topic Receivers:\n"); - int countPendingReceivers = 0; - celixThreadMutex_lock(&manager->topicReceivers.mutex); - iter = hashMapIterator_construct(manager->topicReceivers.map); - while (hashMapIterator_hasNext(&iter)) { - pstm_topic_receiver_or_sender_entry_t *entry = hashMapIterator_nextValue(&iter); - if (entry->endpoint == NULL) { - ++countPendingReceivers; - continue; - } - const char *uuid = celix_properties_get(entry->endpoint, PUBSUB_ENDPOINT_UUID, "!Error!"); - const char *adminType = celix_properties_get(entry->endpoint, PUBSUB_ENDPOINT_ADMIN_TYPE, "!Error!"); - const char *serType = celix_properties_get(entry->endpoint, PUBSUB_ENDPOINT_SERIALIZER, "!Error!"); - const char *protType = celix_properties_get(entry->endpoint, PUBSUB_ENDPOINT_PROTOCOL, "!Error!"); - fprintf(os, "|- Topic Receiver for endpoint %s:\n", uuid); - fprintf(os, " |- scope = %s\n", entry->scope == NULL ? "(null)" : entry->scope); - fprintf(os, " |- topic = %s\n", entry->topic); - fprintf(os, " |- admin type = %s\n", adminType); - fprintf(os, " |- serializer = %s\n", serType); - fprintf(os, " |- protocol = %s\n", protType); - if (manager->verbose) { - fprintf(os, " |- psa svc id = %li\n", entry->matching.selectedPsaSvcId); - fprintf(os, " |- ser svc id = %li\n", entry->matching.selectedSerializerSvcId); - fprintf(os, " |- prot svc id = %li\n", entry->matching.selectedProtocolSvcId); - fprintf(os, " |- usage count = %i\n", entry->usageCount); - } - } - celixThreadMutex_unlock(&manager->topicReceivers.mutex); - fprintf(os, "\n"); - - if (countPendingSenders > 0) { - fprintf(os, "Pending Topic Senders:\n"); - celixThreadMutex_lock(&manager->topicSenders.mutex); - iter = hashMapIterator_construct(manager->topicSenders.map); - while (hashMapIterator_hasNext(&iter)) { - pstm_topic_receiver_or_sender_entry_t *entry = hashMapIterator_nextValue(&iter); - if (entry->endpoint == NULL) { - fprintf(os, "|- Pending Topic Sender for %s/%s:\n", entry->scope == NULL ? "(null)" : entry->scope, entry->topic); - const char *requestedQos = celix_properties_get(entry->topicProperties, PUBSUB_UTILS_QOS_ATTRIBUTE_KEY, "(None)"); - const char *requestedConfig = celix_properties_get(entry->topicProperties, PUBSUB_ADMIN_TYPE_KEY, "(None)"); - const char *requestedSer = celix_properties_get(entry->topicProperties, PUBSUB_SERIALIZER_TYPE_KEY, "(None)"); - const char *requestedProt = celix_properties_get(entry->topicProperties, PUBSUB_PROTOCOL_TYPE_KEY, "(None)"); - fprintf(os, " |- requested qos = %s\n", requestedQos); - fprintf(os, " |- requested config = %s\n", requestedConfig); - fprintf(os, " |- requested serializer = %s\n", requestedSer); - fprintf(os, " |- requested protocol = %s\n", requestedProt); - if (manager->verbose) { - fprintf(os, " |- usage count = %i\n", entry->usageCount); - } - } - } - celixThreadMutex_unlock(&manager->topicSenders.mutex); - fprintf(os, "\n"); - } - - if (countPendingReceivers > 0) { - fprintf(os, "Pending Topic Receivers:\n"); - celixThreadMutex_lock(&manager->topicReceivers.mutex); - iter = hashMapIterator_construct(manager->topicReceivers.map); - while (hashMapIterator_hasNext(&iter)) { - pstm_topic_receiver_or_sender_entry_t *entry = hashMapIterator_nextValue(&iter); - if (entry->endpoint == NULL) { - fprintf(os, "|- Topic Receiver for %s/%s:\n", entry->scope == NULL ? "(null)" : entry->scope, entry->topic); - const char *requestedQos = celix_properties_get(entry->topicProperties, PUBSUB_UTILS_QOS_ATTRIBUTE_KEY, "(None)"); - const char *requestedConfig = celix_properties_get(entry->topicProperties, PUBSUB_ADMIN_TYPE_KEY, "(None)"); - const char *requestedSer = celix_properties_get(entry->topicProperties, PUBSUB_SERIALIZER_TYPE_KEY, "(None)"); - const char *requestedProt = celix_properties_get(entry->topicProperties, PUBSUB_PROTOCOL_TYPE_KEY, "(None)"); - fprintf(os, " |- requested qos = %s\n", requestedQos); - fprintf(os, " |- requested config = %s\n", requestedConfig); - fprintf(os, " |- requested serializer = %s\n", requestedSer); - fprintf(os, " |- requested protocol = %s\n", requestedProt); - if (manager->verbose) { - fprintf(os, " |- usage count = %i\n", entry->usageCount); - } - } - } - celixThreadMutex_unlock(&manager->topicReceivers.mutex); - fprintf(os, "\n"); - } - - - return CELIX_SUCCESS; -} - -static void fetchBundleName(void *handle, const bundle_t *bundle) { - const char **out = handle; - *out = celix_bundle_getSymbolicName(bundle); -} - -static celix_status_t pubsub_topologyManager_metrics(pubsub_topology_manager_t *manager, const char *commandLine CELIX_UNUSED, FILE *os, FILE *errorStream CELIX_UNUSED) { - celix_array_list_t *psaMetrics = celix_arrayList_create(); - celixThreadMutex_lock(&manager->psaMetrics.mutex); - hash_map_iterator_t iter = hashMapIterator_construct(manager->psaMetrics.map); - while (hashMapIterator_hasNext(&iter)) { - pubsub_admin_metrics_service_t *svc = hashMapIterator_nextValue(&iter); - pubsub_admin_metrics_t *m = svc->metrics(svc->handle); - celix_arrayList_add(psaMetrics, m); - } - celixThreadMutex_unlock(&manager->psaMetrics.mutex); - - for (int i = 0; i < celix_arrayList_size(psaMetrics); ++i) { - pubsub_admin_metrics_t *metrics = celix_arrayList_get(psaMetrics, i); - fprintf(os, "Metric for PSA %s:\n", metrics->psaType); - for (int k = 0; k < celix_arrayList_size(metrics->senders); ++k) { - pubsub_admin_sender_metrics_t *sm = celix_arrayList_get(metrics->senders, k); - fprintf(os, "|- Topic Sender %s/%s\n", sm->scope, sm->topic); - for (int j = 0; j < sm->nrOfmsgMetrics; ++j) { - if (sm->msgMetrics[j].nrOfMessagesSend == 0 && sm->msgMetrics[j].nrOfMessagesSendFailed == 0 && sm->msgMetrics[j].nrOfSerializationErrors == 0) { - continue; - } - const char *bndName = "inactive"; - celix_bundleContext_useBundle(manager->context, sm->msgMetrics->bndId, &bndName, fetchBundleName); - fprintf(os, " |- Message '%s' from bundle '%s' (%li):\n", sm->msgMetrics[j].typeFqn, bndName, sm->msgMetrics->bndId); - fprintf(os, " |- msg type = 0x%X\n", sm->msgMetrics[j].typeId); - fprintf(os, " |- send count = %li\n", sm->msgMetrics[j].nrOfMessagesSend); - fprintf(os, " |- fail count = %li\n", sm->msgMetrics[j].nrOfMessagesSendFailed); - fprintf(os, " |- serialization failed = %li\n", sm->msgMetrics[j].nrOfSerializationErrors); - fprintf(os, " |- average serialization time = %f s\n", sm->msgMetrics[j].averageSerializationTimeInSeconds); - fprintf(os, " |- average time between messages = %f s\n", sm->msgMetrics[j].averageTimeBetweenMessagesInSeconds); - } - } - for (int k = 0; k < celix_arrayList_size(metrics->receivers); ++k) { - pubsub_admin_receiver_metrics_t *rm = celix_arrayList_get(metrics->receivers, k); - fprintf(os, "|- Topic Receiver %s/%s:\n", rm->scope, rm->topic); - for (int j = 0; j < rm->nrOfMsgTypes; ++j) { - int nrOfOrigins = rm->msgTypes[j].nrOfOrigins; - for (int m = 0; m < nrOfOrigins; ++m) { - long nrOfMessageReceived = rm->msgTypes[j].origins[m].nrOfMessagesReceived; - if (nrOfMessageReceived == 0) { - continue; - } - char uuidStr[UUID_STR_LEN+1]; - uuid_unparse(rm->msgTypes[j].origins[m].originUUID, uuidStr); - fprintf(os, " |- Message '%s' from framework UUID %s:\n", rm->msgTypes[j].typeFqn, uuidStr); - fprintf(os, " |- msg type = 0x%X\n", rm->msgTypes[j].typeId); - fprintf(os, " |- receive count = %li\n", rm->msgTypes[j].origins[m].nrOfMessagesReceived); - fprintf(os, " |- serialization error = %li\n", rm->msgTypes[j].origins[m].nrOfSerializationErrors); - fprintf(os, " |- missing seq numbers = %li\n", rm->msgTypes[j].origins[m].nrOfMissingSeqNumbers); - fprintf(os, " |- average delay = %fs\n", rm->msgTypes[j].origins[m].averageDelayInSeconds); - fprintf(os, " |- max delay = %fs\n", rm->msgTypes[j].origins[m].maxDelayInSeconds); - fprintf(os, " |- min delay = %fs\n", rm->msgTypes[j].origins[m].minDelayInSeconds); - fprintf(os, " |- average serialization time = %fs\n", rm->msgTypes[j].origins[m].averageSerializationTimeInSeconds); - fprintf(os, " |- average time between messages time = %fs\n", rm->msgTypes[j].origins[m].averageTimeBetweenMessagesInSeconds); - } - } - } - pubsub_freePubSubAdminMetrics(metrics); - } - celix_arrayList_destroy(psaMetrics); - return CELIX_SUCCESS; -} - -bool pubsub_topologyManager_shellCommand(void *handle, const char *commandLine, FILE *os, FILE *errorStream) { - pubsub_topology_manager_t *manager = handle; - - static const char * topCmd = "pstm t"; //"topology"; - static const char * metricsCmd = "pstm m"; //"metrics" - - celix_status_t status; - - if (strncmp(commandLine, topCmd, strlen(topCmd)) == 0) { - status = pubsub_topologyManager_topology(manager, commandLine, os, errorStream); - } else if (strncmp(commandLine, metricsCmd, strlen(metricsCmd)) == 0) { - status = pubsub_topologyManager_metrics(manager, commandLine, os, errorStream); - } else { //default - status = pubsub_topologyManager_topology(manager, commandLine, os, errorStream); - } - - return status == CELIX_SUCCESS; -} diff --git a/bundles/pubsub/pubsub_topology_manager/src/pubsub_topology_manager.h b/bundles/pubsub/pubsub_topology_manager/src/pubsub_topology_manager.h deleted file mode 100644 index 93df5144e..000000000 --- a/bundles/pubsub/pubsub_topology_manager/src/pubsub_topology_manager.h +++ /dev/null @@ -1,136 +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_TOPOLOGY_MANAGER_H_ -#define PUBSUB_TOPOLOGY_MANAGER_H_ - -#include "celix_log_helper.h" -#include "celix_shell_command.h" -#include "celix_bundle_context.h" - -#include "pubsub_endpoint.h" -#include "pubsub/publisher.h" -#include "pubsub/subscriber.h" - -#define PUBSUB_TOPOLOGY_MANAGER_VERBOSE_KEY "PUBSUB_TOPOLOGY_MANAGER_VERBOSE" -#define PUBSUB_TOPOLOGY_MANAGER_HANDLING_THREAD_SLEEPTIME_SECONDS_KEY "PUBSUB_TOPOLOGY_MANAGER_HANDLING_THREAD_SLEEPTIME_SECONDS" -#define PUBSUB_TOPOLOGY_MANAGER_HANDLING_THREAD_SLEEPTIME_MS_KEY "PUBSUB_TOPOLOGY_MANAGER_HANDLING_THREAD_SLEEPTIME_MS" -#define PUBSUB_TOPOLOGY_MANAGER_DEFAULT_VERBOSE false - - -typedef struct pubsub_topology_manager { - celix_bundle_context_t *context; - - struct { - celix_thread_mutex_t mutex; - hash_map_t *map; //key = svcId, value = pubsub_admin_t* - } pubsubadmins; - - struct { - celix_thread_mutex_t mutex; - hash_map_t *map; //key = uuid , value = pstm_discovered_endpoint_entry_t - } discoveredEndpoints; - - struct { - celix_thread_mutex_t mutex; - hash_map_t *map; //key = scope/topic key, value = pstm_topic_receiver_or_sender_entry_t* - } topicReceivers; - - struct { - celix_thread_mutex_t mutex; - hash_map_t *map; //key = scope/topic key, value = pstm_topic_receiver_or_sender_entry_t* - } topicSenders; - - struct { - celix_thread_mutex_t mutex; - celix_array_list_t *list; // - } announceEndpointListeners; - - struct { - celix_thread_mutex_t mutex; - hash_map_t *map; //key = svcId, value = pubsub_admin_metrics_service_t* - } psaMetrics; - - struct { - celix_thread_t thread; - celix_thread_mutex_t mutex; //protect running and condition - celix_thread_cond_t cond; - bool running; - } psaHandling; - - celix_log_helper_t *loghelper; - - unsigned handlingThreadSleepTime; - bool verbose; -} pubsub_topology_manager_t; - -typedef struct pstm_discovered_endpoint_entry { - const char *uuid; - long selectedPsaSvcId; // -1L, indicates no selected psa - int usageCount; //note that discovered endpoints can be found multiple times by different pubsub discovery components - celix_properties_t *endpoint; -} pstm_discovered_endpoint_entry_t; - -typedef struct pstm_topic_receiver_or_sender_entry { - char *scopeAndTopicKey; //key of the combined value of the scope and topic - celix_properties_t *endpoint; - char *topic; - char *scope; - int usageCount; //nr of provided subscriber services for the topic receiver (matching scope & topic) or nr of publisher requested for matching scope & topic. - long bndId; - celix_properties_t *topicProperties; //found in META-INF/(pub|sub)/(topic).properties - - //for sender entry - celix_filter_t *publisherFilter; - - //for receiver entry - celix_properties_t *subscriberProperties; - - struct { - bool needsMatch; //true if a psa needs to be selected or if a new psa has to be considered. - long selectedPsaSvcId; - long selectedSerializerSvcId; - long selectedProtocolSvcId; - } matching; -} pstm_topic_receiver_or_sender_entry_t; - -celix_status_t pubsub_topologyManager_create(celix_bundle_context_t *context, celix_log_helper_t *logHelper, pubsub_topology_manager_t **manager); -celix_status_t pubsub_topologyManager_destroy(pubsub_topology_manager_t *manager); - -void pubsub_topologyManager_psaAdded(void *handle, void *svc, const celix_properties_t *props); -void pubsub_topologyManager_psaRemoved(void *handle, void *svc, const celix_properties_t *props); - -void pubsub_topologyManager_pubsubAnnounceEndpointListenerAdded(void* handle, void *svc, const celix_properties_t *props); -void pubsub_topologyManager_pubsubAnnounceEndpointListenerRemoved(void * handle, void *svc, const celix_properties_t *props); - -void pubsub_topologyManager_subscriberAdded(void * handle, void *svc, const celix_properties_t *props, const celix_bundle_t *bnd); -void pubsub_topologyManager_subscriberRemoved(void * handle, void *svc, const celix_properties_t *props, const celix_bundle_t *bnd); - -void pubsub_topologyManager_publisherTrackerAdded(void *handle, const celix_service_tracker_info_t *info); -void pubsub_topologyManager_publisherTrackerRemoved(void *handle, const celix_service_tracker_info_t *info); - -celix_status_t pubsub_topologyManager_addDiscoveredEndpoint(void *handle, const celix_properties_t *properties); -celix_status_t pubsub_topologyManager_removeDiscoveredEndpoint(void *handle, const celix_properties_t *properties); - -bool pubsub_topologyManager_shellCommand(void *handle, const char * commandLine, FILE *outStream, FILE *errorStream); - -void pubsub_topologyManager_addMetricsService(void * handle, void *svc, const celix_properties_t *props); -void pubsub_topologyManager_removeMetricsService(void * handle, void *svc, const celix_properties_t *props); - -#endif /* PUBSUB_TOPOLOGY_MANAGER_H_ */ diff --git a/bundles/pubsub/pubsub_utils/CMakeLists.txt b/bundles/pubsub/pubsub_utils/CMakeLists.txt deleted file mode 100644 index 5cf9c90f2..000000000 --- a/bundles/pubsub/pubsub_utils/CMakeLists.txt +++ /dev/null @@ -1,44 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -add_library(pubsub_utils STATIC - src/pubsub_utils.c - src/pubsub_utils_url.c - src/pubsub_serializer_handler.c - src/pubsub_serialization_provider.c - src/pubsub_matching.c -) - -set_target_properties(pubsub_utils PROPERTIES OUTPUT_NAME "celix_pubsub_utils") -target_include_directories(pubsub_utils PUBLIC - $ -) -target_link_libraries(pubsub_utils PUBLIC Celix::framework Celix::dfi Celix::pubsub_api Celix::log_helper Celix::shell_api) -target_link_libraries(pubsub_utils PRIVATE Celix::pubsub_spi) -celix_deprecated_utils_headers(pubsub_utils) -celix_deprecated_framework_headers(pubsub_utils) -celix_target_hide_symbols(pubsub_utils) - -add_library(Celix::pubsub_utils ALIAS pubsub_utils) - -install(TARGETS pubsub_utils EXPORT celix DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT pubsub - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/celix/pubsub_utils) -install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/celix/pubsub_utils COMPONENT pubsub) - -if (ENABLE_TESTING) - add_subdirectory(gtest) -endif(ENABLE_TESTING) \ No newline at end of file diff --git a/bundles/pubsub/pubsub_utils/gtest/CMakeLists.txt b/bundles/pubsub/pubsub_utils/gtest/CMakeLists.txt deleted file mode 100644 index e395f5e0c..000000000 --- a/bundles/pubsub/pubsub_utils/gtest/CMakeLists.txt +++ /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. - -add_celix_bundle(pubsub_serialization_matching_descriptors NO_ACTIVATOR VERSION 1.0.0) -celix_bundle_files(pubsub_serialization_matching_descriptors - ${CMAKE_CURRENT_SOURCE_DIR}/msg_descriptors/msg_poi1.descriptor - DESTINATION "META-INF/descriptors" - ) - -celix_bundle_files(pubsub_serialization_matching_descriptors - ${CMAKE_CURRENT_SOURCE_DIR}/msg_descriptors/fiets.properties - DESTINATION "META-INF/topics/pub" - ) - -celix_bundle_files(pubsub_serialization_matching_descriptors - ${CMAKE_CURRENT_SOURCE_DIR}/msg_descriptors/fiets.properties - DESTINATION "META-INF/topics/sub" - ) - -add_celix_bundle(pubsub_serialization_provider_descriptors NO_ACTIVATOR VERSION 1.0.0) -celix_bundle_files(pubsub_serialization_provider_descriptors - ${CMAKE_CURRENT_SOURCE_DIR}/msg_descriptors/garbage.descriptor - ${CMAKE_CURRENT_SOURCE_DIR}/msg_descriptors/msg_poi1.descriptor - ${CMAKE_CURRENT_SOURCE_DIR}/msg_descriptors/msg_poiCmd.descriptor - ${CMAKE_CURRENT_SOURCE_DIR}/msg_descriptors/msg_poi2_variant1.descriptor - ${CMAKE_CURRENT_SOURCE_DIR}/msg_descriptors/msg_poi2_variant2.descriptor - ${CMAKE_CURRENT_SOURCE_DIR}/msg_descriptors/msg_poi3_variant1.descriptor - ${CMAKE_CURRENT_SOURCE_DIR}/msg_descriptors/msg_poi3_variant2.descriptor - ${CMAKE_CURRENT_SOURCE_DIR}/msg_descriptors/msg_poi4_variant1.descriptor - ${CMAKE_CURRENT_SOURCE_DIR}/msg_descriptors/msg_poi4_variant2.descriptor - ${CMAKE_CURRENT_SOURCE_DIR}/msg_descriptors/int_calc.descriptor - DESTINATION "META-INF/descriptors" -) - -add_executable(test_pubsub_utils - src/PubSubSerializationHandlerTestSuite.cc - src/PubSubSerializationProviderTestSuite.cc - src/PubSubMatchingTestSuite.cpp -) -target_link_libraries(test_pubsub_utils PRIVATE Celix::framework Celix::pubsub_utils GTest::gtest GTest::gtest_main Celix::pubsub_spi) -celix_deprecated_utils_headers(test_pubsub_utils) -add_test(NAME test_pubsub_utils COMMAND test_pubsub_utils) -setup_target_for_coverage(test_pubsub_utils SCAN_DIR ..) -add_celix_bundle_dependencies(test_pubsub_utils pubsub_serialization_matching_descriptors pubsub_serialization_provider_descriptors) -target_compile_definitions(test_pubsub_utils PRIVATE -DDESCRIPTOR_BUNDLE=\"$\") -target_compile_definitions(test_pubsub_utils PRIVATE -DMATCHING_BUNDLE=\"$\") \ No newline at end of file diff --git a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/fiets.properties b/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/fiets.properties deleted file mode 100644 index 4cf390806..000000000 --- a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/fiets.properties +++ /dev/null @@ -1,39 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# -# included in the bundle at location META-INF/topics/[pub|sub]/fiets.properties -# - -#topic info -topic.name=fiets -topic.id=fiets - -#Interface info -interface.name=org.example.unknown -interface.version=1.0.0 -interface.messages=poi1 - -# Version info -interface.message.consumer.range@poi1=[0.0.0,1.0.0) -interface.message.provider.version@poi1=0.0.0 -interface.message.consumer.range@poi2=[0.0.0,1.0.0) -interface.message.provider.version@poi2=0.0.0 - - -qos=sample -pubsub.serializer=fiets diff --git a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/garbage.descriptor b/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/garbage.descriptor deleted file mode 100644 index 88c65efb1..000000000 --- a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/garbage.descriptor +++ /dev/null @@ -1 +0,0 @@ -this is garbage diff --git a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/int_calc.descriptor b/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/int_calc.descriptor deleted file mode 100644 index 771dc5e10..000000000 --- a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/int_calc.descriptor +++ /dev/null @@ -1,13 +0,0 @@ -:header -type=interface -name=calculator -version=1.0.0 -:annotations -classname=org.example.Calculator -:types -StatsResult={DDD[D average min max input} -:methods -add(DD)D=add(#am=handle;PDD#am=pre;*D)N -sub(DD)D=sub(#am=handle;PDD*#am=pre;D)N -sqrt(D)D=sqrt(#am=handle;PD*#am=pre;D)N -stats([D)LStatsResult;=stats(#am=handle;P[D#am=out;*LStatsResult;)N diff --git a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi1.descriptor b/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi1.descriptor deleted file mode 100644 index 705cf2965..000000000 --- a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi1.descriptor +++ /dev/null @@ -1,10 +0,0 @@ -:header -type=message -name=poi1 -version=1.0.0 -:annotations -classname=org.example.PointOfInterest -:types -location={DD lat lon} -:message -{llocation;t location name} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi2_variant1.descriptor b/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi2_variant1.descriptor deleted file mode 100644 index 03664568a..000000000 --- a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi2_variant1.descriptor +++ /dev/null @@ -1,11 +0,0 @@ -:header -type=message -name=poi2 -version=1.0.0 -:annotations -classname=org.example.PointOfInterest -invalid_reason=same_msg_diff_version -:types -location={DD lat lon} -:message -{llocation;t location name} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi2_variant2.descriptor b/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi2_variant2.descriptor deleted file mode 100644 index 61b3ddd48..000000000 --- a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi2_variant2.descriptor +++ /dev/null @@ -1,11 +0,0 @@ -:header -type=message -name=poi2 -version=1.1.0 -:annotations -classname=org.example.PointOfInterest -invalid_reason=same_msg_diff_version -:types -location={DD lat lon} -:message -{llocation;t location name} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi3_variant1.descriptor b/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi3_variant1.descriptor deleted file mode 100644 index a603cc438..000000000 --- a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi3_variant1.descriptor +++ /dev/null @@ -1,11 +0,0 @@ -:header -type=message -name=poi3 -version=1.0.0 -:annotations -classname=org.example.PointOfInterest -invalid_reason=same_msg_diff_msg_id -:types -location={DD lat lon} -:message -{llocation;t location name} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi3_variant2.descriptor b/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi3_variant2.descriptor deleted file mode 100644 index 895930c03..000000000 --- a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi3_variant2.descriptor +++ /dev/null @@ -1,12 +0,0 @@ -:header -type=message -name=poi3 -version=1.0.0 -:annotations -classname=org.example.PointOfInterest -msgId=5555 -invalid_reason=same_msg_diff_msg_id -:types -location={DD lat lon} -:message -{llocation;t location name} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi4_variant1.descriptor b/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi4_variant1.descriptor deleted file mode 100644 index 00c6558d8..000000000 --- a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi4_variant1.descriptor +++ /dev/null @@ -1,12 +0,0 @@ -:header -type=message -name=poi4a -version=1.0.0 -:annotations -classname=org.example.PointOfInterest -msgId=5 -invalid_reason=same_msg_id_different_msg_fqn -:types -location={DD lat lon} -:message -{llocation;t location name} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi4_variant2.descriptor b/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi4_variant2.descriptor deleted file mode 100644 index 469923c5f..000000000 --- a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poi4_variant2.descriptor +++ /dev/null @@ -1,12 +0,0 @@ -:header -type=message -name=poi4b -version=1.0.0 -:annotations -classname=org.example.PointOfInterest -msgId=5 -invalid_reason=same_msg_id_different_msg_fqn -:types -location={DD lat lon} -:message -{llocation;t location name} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poiCmd.descriptor b/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poiCmd.descriptor deleted file mode 100644 index 5b674f292..000000000 --- a/bundles/pubsub/pubsub_utils/gtest/msg_descriptors/msg_poiCmd.descriptor +++ /dev/null @@ -1,8 +0,0 @@ -:header -type=message -name=poiCmd -version=1.0.0 -:annotations -classname=org.example.PointOfInterestCommand -:message -{t command} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_utils/gtest/src/PubSubMatchingTestSuite.cpp b/bundles/pubsub/pubsub_utils/gtest/src/PubSubMatchingTestSuite.cpp deleted file mode 100644 index a3b2bb82d..000000000 --- a/bundles/pubsub/pubsub_utils/gtest/src/PubSubMatchingTestSuite.cpp +++ /dev/null @@ -1,183 +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 "gtest/gtest.h" - -#include -#include - -#include "celix_constants.h" -#include "celix_framework_factory.h" -#include "pubsub_message_serialization_service.h" -#include "dyn_message.h" -#include "pubsub_protocol.h" -#include "pubsub_constants.h" -#include "pubsub_matching.h" -#include "pubsub/api.h" -#include "pubsub_endpoint.h" -#include "pubsub_message_serialization_marker.h" - -static void stdLog(void*, int level, const char *file, int line, const char *msg, ...) { - va_list ap; - const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"}; - fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line); - va_start(ap, msg); - vfprintf(stderr, msg, ap); - fprintf(stderr, "\n"); - va_end(ap); -} - -class PubSubMatchingTestSuite : public ::testing::Test { -public: - PubSubMatchingTestSuite() { - auto* props = celix_properties_create(); - celix_properties_set(props, CELIX_FRAMEWORK_CACHE_DIR, ".pubsub_utils_cache"); - auto* fwPtr = celix_frameworkFactory_createFramework(props); - auto* ctxPtr = celix_framework_getFrameworkContext(fwPtr); - fw = std::shared_ptr{fwPtr, [](auto* f) {celix_frameworkFactory_destroyFramework(f);}}; - ctx = std::shared_ptr{ctxPtr, [](auto*){/*nop*/}}; - - bndId = celix_bundleContext_installBundle(ctx.get(), MATCHING_BUNDLE, true); - - dynMessage_logSetup(stdLog, NULL, 1); - } - - ~PubSubMatchingTestSuite() override { - celix_bundleContext_uninstallBundle(ctx.get(), bndId); - } - - long registerMarkerSerSvc(const char* type) { - auto* p = celix_properties_create(); - celix_properties_set(p, PUBSUB_MESSAGE_SERIALIZATION_MARKER_SERIALIZATION_TYPE_PROPERTY, type); - celix_service_registration_options_t opts{}; - opts.svc = static_cast(&serMarkerSvc); - opts.properties = p; - opts.serviceName = PUBSUB_MESSAGE_SERIALIZATION_MARKER_NAME; - opts.serviceVersion = PUBSUB_MESSAGE_SERIALIZATION_MARKER_VERSION; - return celix_bundleContext_registerServiceWithOptions(ctx.get(), &opts); - } - - std::shared_ptr fw{}; - std::shared_ptr ctx{}; - pubsub_message_serialization_marker_t serMarkerSvc{}; - pubsub_protocol_service_t protocolSvc{}; - long bndId{}; -}; - -TEST_F(PubSubMatchingTestSuite, MatchPublisherSimple) { - auto serMarkerId = registerMarkerSerSvc("fiets"); - long foundSvcId = -1; - pubsub_utils_matchPublisher(ctx.get(), bndId, "(&(objectClass=pubsub.publisher)(service.lang=C)(topic=fiets))", "admin?", 0, 0, 0, false, NULL, &foundSvcId, NULL); - EXPECT_EQ(foundSvcId, serMarkerId); - celix_bundleContext_unregisterService(ctx.get(), serMarkerId); -} - -TEST_F(PubSubMatchingTestSuite, MatchPublisherMultiple) { - auto serFietsId = registerMarkerSerSvc("fiets"); - auto serFiets2Id = registerMarkerSerSvc("fiets"); - auto serAutoId = registerMarkerSerSvc("auto"); - auto serBelId = registerMarkerSerSvc("bel"); - long foundSvcId = -1; - pubsub_utils_matchPublisher(ctx.get(), bndId, "(&(objectClass=pubsub.publisher)(service.lang=C)(topic=fiets))", "admin?", 0, 0, 0, false, NULL, &foundSvcId, NULL); - EXPECT_EQ(foundSvcId, serFietsId); //older service are ranked higher - celix_bundleContext_unregisterService(ctx.get(), serFietsId); - celix_bundleContext_unregisterService(ctx.get(), serFiets2Id); - celix_bundleContext_unregisterService(ctx.get(), serAutoId); - celix_bundleContext_unregisterService(ctx.get(), serBelId); -} - -TEST_F(PubSubMatchingTestSuite, MatchSubscriberSimple) { - auto serId = registerMarkerSerSvc("fiets"); - - long foundSvcId = -1; - auto* p = celix_properties_create(); - celix_properties_set(p, PUBSUB_SUBSCRIBER_SCOPE, "scope"); - celix_properties_set(p, PUBSUB_SUBSCRIBER_TOPIC, "fiets"); - pubsub_utils_matchSubscriber(ctx.get(), bndId, p, "admin?", 0, 0, 0, false, NULL, &foundSvcId, NULL); - EXPECT_EQ(foundSvcId, serId); - celix_properties_destroy(p); - celix_bundleContext_unregisterService(ctx.get(), serId); -} - -TEST_F(PubSubMatchingTestSuite, MatchSubscriberMultiple) { - auto serFietsId = registerMarkerSerSvc("fiets"); - auto serFiets2Id = registerMarkerSerSvc("fiets"); - auto serAutoId = registerMarkerSerSvc("auto"); - auto serBelId = registerMarkerSerSvc("bel"); - - long foundSvcId = -1; - - auto* p = celix_properties_create(); - celix_properties_set(p, PUBSUB_SUBSCRIBER_SCOPE, "scope"); - celix_properties_set(p, PUBSUB_SUBSCRIBER_TOPIC, "fiets"); - - pubsub_utils_matchSubscriber(ctx.get(), bndId, p, "admin?", 0, 0, 0, false, NULL, &foundSvcId, NULL); - - EXPECT_EQ(foundSvcId, serFietsId); - - celix_properties_destroy(p); - celix_bundleContext_unregisterService(ctx.get(), serFietsId); - celix_bundleContext_unregisterService(ctx.get(), serFiets2Id); - celix_bundleContext_unregisterService(ctx.get(), serAutoId); - celix_bundleContext_unregisterService(ctx.get(), serBelId); -} - -TEST_F(PubSubMatchingTestSuite, MatchEndpointSimple) { - auto serId = registerMarkerSerSvc("fiets"); - - long foundSvcId = -1; - - auto logHelper = celix_logHelper_create(ctx.get(), "logger"); - auto* ep = celix_properties_create(); - celix_properties_set(ep, PUBSUB_ENDPOINT_ADMIN_TYPE, "admin?"); - celix_properties_set(ep, PUBSUB_ENDPOINT_SERIALIZER, "fiets"); - - pubsub_utils_matchEndpoint(ctx.get(), logHelper, ep, "admin?", false, &foundSvcId, NULL); - - EXPECT_EQ(foundSvcId, serId); - - celix_properties_destroy(ep); - celix_logHelper_destroy(logHelper); - celix_bundleContext_unregisterService(ctx.get(), serId); -} - -TEST_F(PubSubMatchingTestSuite, MatchEndpointMultiple) { - auto serFietsId = registerMarkerSerSvc("fiets"); - auto serFiets2Id = registerMarkerSerSvc("fiets"); - auto serAutoId = registerMarkerSerSvc("auto"); - auto serBelId = registerMarkerSerSvc("bel"); - - long foundSvcId = -1; - - auto logHelper = celix_logHelper_create(ctx.get(), "logger"); - auto* ep = celix_properties_create(); - celix_properties_set(ep, PUBSUB_ENDPOINT_ADMIN_TYPE, "admin?"); - celix_properties_set(ep, PUBSUB_ENDPOINT_SERIALIZER, "fiets"); - - pubsub_utils_matchEndpoint(ctx.get(), logHelper, ep, "admin?", false, &foundSvcId, NULL); - - EXPECT_EQ(foundSvcId, serFietsId); - - celix_properties_destroy(ep); - celix_logHelper_destroy(logHelper); - celix_bundleContext_unregisterService(ctx.get(), serFietsId); - celix_bundleContext_unregisterService(ctx.get(), serFiets2Id); - celix_bundleContext_unregisterService(ctx.get(), serAutoId); - celix_bundleContext_unregisterService(ctx.get(), serBelId); -} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_utils/gtest/src/PubSubSerializationHandlerTestSuite.cc b/bundles/pubsub/pubsub_utils/gtest/src/PubSubSerializationHandlerTestSuite.cc deleted file mode 100644 index 2522fcbdd..000000000 --- a/bundles/pubsub/pubsub_utils/gtest/src/PubSubSerializationHandlerTestSuite.cc +++ /dev/null @@ -1,339 +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 "gtest/gtest.h" - -#include -#include - -#include "celix_bundle_context.h" -#include "pubsub_message_serialization_service.h" -#include "pubsub_serializer_handler.h" -#include "dyn_message.h" -#include "pubsub_message_serialization_marker.h" -#include "celix_framework_factory.h" -#include "celix_constants.h" - -static void stdLog(void*, int level, const char *file, int line, const char *msg, ...) { - va_list ap; - const char *levels[5] = {"NIL", "ERROR", "WARNING", "INFO", "DEBUG"}; - fprintf(stderr, "%s: FILE:%s, LINE:%i, MSG:",levels[level], file, line); - va_start(ap, msg); - vfprintf(stderr, msg, ap); - fprintf(stderr, "\n"); - va_end(ap); -} - -class PubSubSerializationHandlerTestSuite : public ::testing::Test { -public: - PubSubSerializationHandlerTestSuite() { - auto* props = celix_properties_create(); - celix_properties_set(props, CELIX_FRAMEWORK_CACHE_DIR, ".pubsub_utils_cache"); - auto* fwPtr = celix_frameworkFactory_createFramework(props); - auto* ctxPtr = celix_framework_getFrameworkContext(fwPtr); - fw = std::shared_ptr{fwPtr, [](auto* f) {celix_frameworkFactory_destroyFramework(f);}}; - ctx = std::shared_ptr{ctxPtr, [](auto*){/*nop*/}}; - - dynMessage_logSetup(stdLog, NULL, 1); - - msgSerSvc.handle = this; - msgSerSvc.serialize = [](void* handle, const void*, struct iovec**, size_t*) -> celix_status_t { - auto* suite = static_cast(handle); - suite->serializeCallCount += 1; - return CELIX_SUCCESS; - }; - msgSerSvc.freeSerializedMsg = [](void* handle, struct iovec* , size_t) { - auto* suite = static_cast(handle); - suite->freeSerializedMsgCallCount += 1; - }; - msgSerSvc.deserialize = [](void* handle, const struct iovec*, size_t, void**) -> celix_status_t { - auto* suite = static_cast(handle); - suite->deserializeCallCount += 1; - return CELIX_SUCCESS; - }; - msgSerSvc.freeDeserializedMsg = [](void* handle, void*) { - auto* suite = static_cast(handle); - suite->freeDeserializedMsgCallCount += 1; - }; - } - - long registerSerSvc(const char* type, uint32_t msgId, const char* msgFqn, const char* msgVersion) { - auto* p = celix_properties_create(); - celix_properties_set(p, PUBSUB_MESSAGE_SERIALIZATION_SERVICE_SERIALIZATION_TYPE_PROPERTY, type); - celix_properties_set(p, PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_ID_PROPERTY, std::to_string(msgId).c_str()); - celix_properties_set(p, PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_FQN_PROPERTY, msgFqn); - celix_properties_set(p, PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_VERSION_PROPERTY, msgVersion); - celix_service_registration_options_t opts{}; - opts.svc = static_cast(&msgSerSvc); - opts.properties = p; - opts.serviceName = PUBSUB_MESSAGE_SERIALIZATION_SERVICE_NAME; - opts.serviceVersion = PUBSUB_MESSAGE_SERIALIZATION_SERVICE_VERSION; - return celix_bundleContext_registerServiceWithOptions(ctx.get(), &opts); - } - - std::shared_ptr fw{}; - std::shared_ptr ctx{}; - pubsub_message_serialization_service_t msgSerSvc{}; - - size_t serializeCallCount = 0; - size_t freeSerializedMsgCallCount = 0; - size_t deserializeCallCount = 0; - size_t freeDeserializedMsgCallCount = 0; -}; - - -TEST_F(PubSubSerializationHandlerTestSuite, CreateDestroy) { - auto *handler = pubsub_serializerHandler_create(ctx.get(), "json", true); - ASSERT_TRUE(handler != nullptr); - ASSERT_STREQ("json", pubsub_serializerHandler_getSerializationType(handler)); - pubsub_serializerHandler_destroy(handler); -} - -TEST_F(PubSubSerializationHandlerTestSuite, SerializationServiceFound) { - auto *handler = pubsub_serializerHandler_create(ctx.get(), "json", true); - long svcId = registerSerSvc("json", 42, "example::Msg", "1.0.0"); - - EXPECT_EQ(1, pubsub_serializerHandler_messageSerializationServiceCount(handler)); - EXPECT_EQ(42, pubsub_serializerHandler_getMsgId(handler, "example::Msg")); - auto *fqn = pubsub_serializerHandler_getMsgFqn(handler, 42); - EXPECT_STREQ("example::Msg", fqn); - EXPECT_TRUE(pubsub_serializerHandler_isMessageSupported(handler, 42, 1, 0)); - EXPECT_FALSE(pubsub_serializerHandler_isMessageSupported(handler, 42, 2, 0)); - - celix_bundleContext_unregisterService(ctx.get(), svcId); - EXPECT_EQ(0, pubsub_serializerHandler_messageSerializationServiceCount(handler)); - - pubsub_serializerHandler_destroy(handler); -} - -TEST_F(PubSubSerializationHandlerTestSuite, DifferentTypeOfSerializationService) { - auto *handler = pubsub_serializerHandler_create(ctx.get(), "json", true); - long svcId = registerSerSvc("avrobin", 42, "example::Msg", "1.0.0"); - EXPECT_EQ(0, pubsub_serializerHandler_messageSerializationServiceCount(handler)); - celix_bundleContext_unregisterService(ctx.get(), svcId); - pubsub_serializerHandler_destroy(handler); -} - -TEST_F(PubSubSerializationHandlerTestSuite, MutipleSerializationServices) { - auto *handler = pubsub_serializerHandler_create(ctx.get(), "json", true); - long svcId1 = registerSerSvc("json", 43, "example::Msg1", "1.0.0"); - long svcId2 = registerSerSvc("json", 44, "example::Msg2", "1.0.0"); - long svcId3 = registerSerSvc("json", 45, "example::Msg3", "1.0.0"); - long svcId4 = registerSerSvc("json", 46, "example::Msg4", "1.0.0"); - long svcId5 = registerSerSvc("json", 47, "example::Msg5", "1.0.0"); - long svcId6 = registerSerSvc("json", 48, "example::Msg6", "1.0.0"); - EXPECT_EQ(6, pubsub_serializerHandler_messageSerializationServiceCount(handler)); - celix_bundleContext_unregisterService(ctx.get(), svcId1); - celix_bundleContext_unregisterService(ctx.get(), svcId2); - celix_bundleContext_unregisterService(ctx.get(), svcId3); - celix_bundleContext_unregisterService(ctx.get(), svcId4); - celix_bundleContext_unregisterService(ctx.get(), svcId5); - celix_bundleContext_unregisterService(ctx.get(), svcId6); - pubsub_serializerHandler_destroy(handler); -} - -TEST_F(PubSubSerializationHandlerTestSuite, ClashingId) { - auto *handler = pubsub_serializerHandler_create(ctx.get(), "json", true); - - testing::internal::CaptureStderr(); - long svcId1 = registerSerSvc("json", 42, "example::Msg1", "1.0.0"); - long svcId2 = registerSerSvc("json", 42, "example::Msg2", "1.0.0"); - std::string output = testing::internal::GetCapturedStderr(); - - EXPECT_TRUE(strstr(output.c_str(), "error") != nullptr); - EXPECT_EQ(1, pubsub_serializerHandler_messageSerializationServiceCount(handler)); - celix_bundleContext_unregisterService(ctx.get(), svcId1); - celix_bundleContext_unregisterService(ctx.get(), svcId2); - pubsub_serializerHandler_destroy(handler); -} - -TEST_F(PubSubSerializationHandlerTestSuite, MultipleVersions) { - auto *handler = pubsub_serializerHandler_create(ctx.get(), "json", true); - - testing::internal::CaptureStderr(); - long svcId1 = registerSerSvc("json", 42, "example::Msg1", "1.0.0"); //successful - long svcId2 = registerSerSvc("json", 42, "example::Msg1", "1.1.0"); //ERROR - long svcId3 = registerSerSvc("json", 42, "example::Msg1", "2.1.0"); //ERROR - std::string output = testing::internal::GetCapturedStderr(); - - EXPECT_EQ(1, pubsub_serializerHandler_messageSerializationServiceCount(handler)); - EXPECT_TRUE(strstr(output.c_str(), "error") != nullptr); - EXPECT_TRUE(pubsub_serializerHandler_isMessageSupported(handler, 42, 1, 0)); - EXPECT_TRUE(pubsub_serializerHandler_isMessageSupported(handler, 42, 1, 1)); - EXPECT_TRUE(pubsub_serializerHandler_isMessageSupported(handler, 42, 1, 14)); - EXPECT_FALSE(pubsub_serializerHandler_isMessageSupported(handler, 42, 2, 1)); - EXPECT_FALSE(pubsub_serializerHandler_isMessageSupported(handler, 42, 2, 0)); - EXPECT_EQ(pubsub_serializerHandler_getMsgMajorVersion(handler, 42), 1); - EXPECT_EQ(pubsub_serializerHandler_getMsgMinorVersion(handler, 42), 0); - - celix_bundleContext_unregisterService(ctx.get(), svcId1); - celix_bundleContext_unregisterService(ctx.get(), svcId2); - celix_bundleContext_unregisterService(ctx.get(), svcId3); - pubsub_serializerHandler_destroy(handler); -} - -TEST_F(PubSubSerializationHandlerTestSuite, NoBackwardsCompatbile) { - auto *handler = pubsub_serializerHandler_create(ctx.get(), "json", false); - - long svcId1 = registerSerSvc("json", 42, "example::Msg1", "1.0.0"); - - EXPECT_EQ(1, pubsub_serializerHandler_messageSerializationServiceCount(handler)); - EXPECT_TRUE(pubsub_serializerHandler_isMessageSupported(handler, 42, 1, 0)); //NOTE only exact is supported - EXPECT_FALSE(pubsub_serializerHandler_isMessageSupported(handler, 42, 1, 1)); - EXPECT_FALSE(pubsub_serializerHandler_isMessageSupported(handler, 42, 1, 14)); - EXPECT_FALSE(pubsub_serializerHandler_isMessageSupported(handler, 42, 2, 1)); - EXPECT_FALSE(pubsub_serializerHandler_isMessageSupported(handler, 42, 2, 0)); - EXPECT_EQ(pubsub_serializerHandler_getMsgMajorVersion(handler, 42), 1); - EXPECT_EQ(pubsub_serializerHandler_getMsgMinorVersion(handler, 42), 0); - - celix_bundleContext_unregisterService(ctx.get(), svcId1); - pubsub_serializerHandler_destroy(handler); -} - -TEST_F(PubSubSerializationHandlerTestSuite, CallServiceMethods) { - auto *handler = pubsub_serializerHandler_create(ctx.get(), "json", false); - long svcId1 = registerSerSvc("json", 42, "example::Msg1", "1.0.0"); - - void* dummyMsg = (void*)0x42; - iovec* dummyBuffer = (iovec*)0x43; - size_t dummyBufferSize = 0; - - EXPECT_EQ(1, pubsub_serializerHandler_messageSerializationServiceCount(handler)); - EXPECT_EQ(0, serializeCallCount); - EXPECT_EQ(0, freeSerializedMsgCallCount); - EXPECT_EQ(0, deserializeCallCount); - EXPECT_EQ(0, freeDeserializedMsgCallCount); - pubsub_serializerHandler_serialize(handler, 42, dummyMsg, &dummyBuffer, &dummyBufferSize); - pubsub_serializerHandler_freeSerializedMsg(handler, 42, dummyBuffer, dummyBufferSize); - pubsub_serializerHandler_deserialize(handler, 42, 1, 0, dummyBuffer, dummyBufferSize, &dummyMsg); - pubsub_serializerHandler_freeDeserializedMsg(handler, 42, dummyMsg); - EXPECT_EQ(1, serializeCallCount); - EXPECT_EQ(1, freeSerializedMsgCallCount); - EXPECT_EQ(1, deserializeCallCount); - EXPECT_EQ(1, freeDeserializedMsgCallCount); - - celix_bundleContext_unregisterService(ctx.get(), svcId1); - pubsub_serializerHandler_destroy(handler); -} - -TEST_F(PubSubSerializationHandlerTestSuite, MismatchedCallServiceMethods) { - auto *handler = pubsub_serializerHandler_create(ctx.get(), "json", false); - - long svcId1 = registerSerSvc("json", 42, "example::Msg1", "1.0.0"); - - void* dummyMsg = (void*)0x42; - iovec* dummyBuffer = (iovec*)0x43; - size_t dummyBufferSize = 0; - - EXPECT_EQ(1, pubsub_serializerHandler_messageSerializationServiceCount(handler)); - EXPECT_EQ(0, serializeCallCount); - EXPECT_EQ(0, freeSerializedMsgCallCount); - EXPECT_EQ(0, deserializeCallCount); - EXPECT_EQ(0, freeDeserializedMsgCallCount); - pubsub_serializerHandler_serialize(handler, 43, dummyMsg, &dummyBuffer, &dummyBufferSize); - pubsub_serializerHandler_freeSerializedMsg(handler, 43, dummyBuffer, dummyBufferSize); - pubsub_serializerHandler_deserialize(handler, 43, 1, 0, dummyBuffer, dummyBufferSize, &dummyMsg); - pubsub_serializerHandler_deserialize(handler, 42, 1, 1, dummyBuffer, dummyBufferSize, &dummyMsg); //note wrong version - pubsub_serializerHandler_freeDeserializedMsg(handler, 43, dummyMsg); - EXPECT_EQ(0, serializeCallCount); - EXPECT_EQ(0, freeSerializedMsgCallCount); - EXPECT_EQ(0, deserializeCallCount); - EXPECT_EQ(0, freeDeserializedMsgCallCount); - - celix_bundleContext_unregisterService(ctx.get(), svcId1); - pubsub_serializerHandler_destroy(handler); -} - -TEST_F(PubSubSerializationHandlerTestSuite, BackwardsCompatibleCall) { - auto *handler = pubsub_serializerHandler_create(ctx.get(), "json", true); - long svcId1 = registerSerSvc("json", 42, "example::Msg1", "1.0.0"); - - void* dummyMsg = (void*)0x42; - iovec* dummyBuffer = (iovec*)0x43; - size_t dummyBufferSize = 0; - - EXPECT_EQ(1, pubsub_serializerHandler_messageSerializationServiceCount(handler)); - EXPECT_EQ(0, deserializeCallCount); - pubsub_serializerHandler_deserialize(handler, 42, 1, 0, dummyBuffer, dummyBufferSize, &dummyMsg); - pubsub_serializerHandler_deserialize(handler, 42, 1, 1, dummyBuffer, dummyBufferSize, &dummyMsg); //note compatible - pubsub_serializerHandler_deserialize(handler, 42, 1, 15, dummyBuffer, dummyBufferSize, &dummyMsg); //note compatible - pubsub_serializerHandler_deserialize(handler, 42, 2, 9, dummyBuffer, dummyBufferSize, &dummyMsg); //note not compatible - EXPECT_EQ(3, deserializeCallCount); - - celix_bundleContext_unregisterService(ctx.get(), svcId1); - pubsub_serializerHandler_destroy(handler); -} - -TEST_F(PubSubSerializationHandlerTestSuite, CreateHandlerFromMarker) { - auto* logHelper = celix_logHelper_create(ctx.get(), "test"); - auto* marker = pubsub_serializerHandler_createForMarkerService(ctx.get(), 1032 /*invalid*/, logHelper); - EXPECT_FALSE(marker); //non existing svc - - pubsub_message_serialization_marker_t markerSvc; - long svcId = celix_bundleContext_registerService(ctx.get(), &markerSvc, PUBSUB_MESSAGE_SERIALIZATION_MARKER_NAME, NULL); - EXPECT_GE(svcId, 0); - marker = pubsub_serializerHandler_createForMarkerService(ctx.get(), svcId, logHelper); - EXPECT_FALSE(marker); //missing ser type service property - celix_bundleContext_unregisterService(ctx.get(), svcId); - - auto* props = celix_properties_create(); - celix_properties_set(props, PUBSUB_MESSAGE_SERIALIZATION_MARKER_SERIALIZATION_TYPE_PROPERTY, "test"); - svcId = celix_bundleContext_registerService(ctx.get(), &markerSvc, PUBSUB_MESSAGE_SERIALIZATION_MARKER_NAME, props); - EXPECT_GE(svcId, 0); - marker = pubsub_serializerHandler_createForMarkerService(ctx.get(), svcId, logHelper); - EXPECT_TRUE(marker); - EXPECT_STREQ("test", pubsub_serializerHandler_getSerializationType(marker)); - celix_bundleContext_unregisterService(ctx.get(), svcId); - pubsub_serializerHandler_destroy(marker); - - celix_logHelper_destroy(logHelper); -} - -TEST_F(PubSubSerializationHandlerTestSuite, GetMsgInfo) { - auto *handler = pubsub_serializerHandler_create(ctx.get(), "json", true); - EXPECT_FALSE(pubsub_serializerHandler_isMessageSerializationServiceAvailable(handler, 42)); - EXPECT_EQ(CELIX_ILLEGAL_ARGUMENT, pubsub_serializerHandler_getMsgInfo(handler, 42, nullptr, nullptr, nullptr)); - - - long svcId1 = registerSerSvc("json", 42, "example::Msg1", "1.0.0"); - EXPECT_TRUE(pubsub_serializerHandler_isMessageSerializationServiceAvailable(handler, 42)); - EXPECT_EQ(CELIX_SUCCESS, pubsub_serializerHandler_getMsgInfo(handler, 42, nullptr, nullptr, nullptr)); - - const char* msgFqn; - int major; - int minor; - EXPECT_EQ(CELIX_SUCCESS, pubsub_serializerHandler_getMsgInfo(handler, 42, &msgFqn, &major, &minor)); - EXPECT_STREQ("example::Msg1", msgFqn); - EXPECT_EQ(1, major); - EXPECT_EQ(0, minor); - - celix_bundleContext_unregisterService(ctx.get(), svcId1); - pubsub_serializerHandler_destroy(handler); -} - -TEST_F(PubSubSerializationHandlerTestSuite, CallingFreeWithNULLWillBeSilentlyIgnored) { - auto *handler = pubsub_serializerHandler_create(ctx.get(), "json", true); - long svcId1 = registerSerSvc("json", 42, "example::Msg1", "1.0.0"); - - EXPECT_EQ(pubsub_serializerHandler_freeDeserializedMsg(handler, 42, nullptr), CELIX_SUCCESS); - EXPECT_EQ(pubsub_serializerHandler_freeSerializedMsg(handler, 42, nullptr, 10), CELIX_SUCCESS); - - celix_bundleContext_unregisterService(ctx.get(), svcId1); - pubsub_serializerHandler_destroy(handler); -} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_utils/gtest/src/PubSubSerializationProviderTestSuite.cc b/bundles/pubsub/pubsub_utils/gtest/src/PubSubSerializationProviderTestSuite.cc deleted file mode 100644 index 9735611a1..000000000 --- a/bundles/pubsub/pubsub_utils/gtest/src/PubSubSerializationProviderTestSuite.cc +++ /dev/null @@ -1,71 +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 "gtest/gtest.h" - -#include - -#include "celix_framework_factory.h" -#include "celix_constants.h" -#include "pubsub_message_serialization_marker.h" -#include "pubsub_serialization_provider.h" - -class PubSubSerializationProviderTestSuite : public ::testing::Test { -public: - PubSubSerializationProviderTestSuite() { - auto* props = celix_properties_create(); - celix_properties_set(props, CELIX_FRAMEWORK_CACHE_DIR, ".pubsub_serialization_provider_cache"); - auto* fwPtr = celix_frameworkFactory_createFramework(props); - auto* ctxPtr = celix_framework_getFrameworkContext(fwPtr); - fw = std::shared_ptr{fwPtr, [](auto* f) {celix_frameworkFactory_destroyFramework(f);}}; - ctx = std::shared_ptr{ctxPtr, [](auto*){/*nop*/}}; - - long bndId; - - bndId = celix_bundleContext_installBundle(ctx.get(), DESCRIPTOR_BUNDLE, true); - EXPECT_TRUE(bndId >= 0); - } - - std::shared_ptr fw{}; - std::shared_ptr ctx{}; -}; - - -TEST_F(PubSubSerializationProviderTestSuite, CreateDestroy) { - //checks if the bundles are started and stopped correctly (no mem leaks). - auto* provider = pubsub_serializationProvider_create(ctx.get(), "test", false, 0, nullptr, nullptr, nullptr, nullptr); - auto count = celix_bundleContext_useService(ctx.get(), PUBSUB_MESSAGE_SERIALIZATION_MARKER_NAME, nullptr, nullptr); - EXPECT_EQ(1, count); - pubsub_serializationProvider_destroy(provider); -} - -TEST_F(PubSubSerializationProviderTestSuite, FindSerializationServices) { - auto* provider = pubsub_serializationProvider_create(ctx.get(), "test", false, 0, nullptr, nullptr, nullptr, nullptr); - - size_t nrEntries = pubsub_serializationProvider_nrOfEntries(provider); - EXPECT_EQ(5, nrEntries); - size_t nrOfInvalidEntries = pubsub_serializationProvider_nrOfInvalidEntries(provider); - EXPECT_EQ(3, nrOfInvalidEntries); //note 3 invalid, because garbage.descriptor is never added (cannot extract msgFqn) - - auto* services = celix_bundleContext_findServices(ctx.get(), PUBSUB_MESSAGE_SERIALIZATION_SERVICE_NAME); - EXPECT_EQ(5, celix_arrayList_size(services)); //3 valid, 5 invalid - celix_arrayList_destroy(services); - - pubsub_serializationProvider_destroy(provider); -} diff --git a/bundles/pubsub/pubsub_utils/include/pubsub_matching.h b/bundles/pubsub/pubsub_utils/include/pubsub_matching.h deleted file mode 100644 index 0417769af..000000000 --- a/bundles/pubsub/pubsub_utils/include/pubsub_matching.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_MATCHING_H_ -#define PUBSUB_MATCHING_H_ - -#include -#include "celix_array_list.h" -#include "celix_bundle_context.h" -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Match a publisher for a provided bnd (using the bundleId) and service filter. - * - * The match function will try to find a topic properties for the requesting bundle (bundleId) using the topic - * from the filter at META-INF/topics/pub/.properties - * - * If the topic properties is configured for the provided adminType (i.e. pubsub.config=ZMQ) a full match will - * be returned. If no specific admin is configured in the topic properties the sampleScore will be returned if sample - * qos is configured (i.e. qos=sample), the controlScore will be returned if control qos is configured - * (i.e. qos=control) and otherwise the defaultScore will be returned. - * - * The match function will also search for a valid serializer. If a serializer is configured in the topic properties - * (i.e. pubsub.serializer=json) that specific serializer will be searched. If no serializer is configured the - * highest ranking serializer service will be returned. If no serializer can be found, the outSerializerSvcId will - * be -1. - * - * The function will also returned the found topic properties and the matching serialized. - * The caller is owner of the outTopicProperties. - * - * @param ctx The bundle context. - * @param bundleId The requesting bundle id. - * @param filter The filter of the publisher (i.e. "(&(topic=example)(scope=subsystem))") - * @param adminType The admin type used for the match. - * @param sampleScore The sample score used for the match. - * @param controlScore The control score used for the match. - * @param defaultScore The default score used for the match. - * @param outTopicProperties Output pointer for the read topic properties. Return can be NULL. - * @param outSerializerSvcId Output svc id for the matching serializer. If not found will be -1L. - * @return The matching score. - */ -double pubsub_utils_matchPublisher( - celix_bundle_context_t *ctx, - long bundleId, - const char *filter, - const char *adminType, - double sampleScore, - double controlScore, - double defaultScore, - bool matchProtocol, - celix_properties_t **outTopicProperties, - long *outSerializerSvcId, - long *outProtocolSvcId); - -/** - * Match a subscriber for a provided bnd (using the bundleId) and provided service properties. - * - * The match function will try to find a topic properties for the requesting bundle (bundleId) - using topic in the - * provided service properties - at META-INF/topics/sub/.properties - * - * If the topic properties is configured for the provided adminType (i.e. pubsub.config=ZMQ) a full match will - * be returned. If no specific admin is configured in the topic properties the sampleScore will be returned if sample - * qos is configured (i.e. qos=sample), the controlScore will be returned if control qos is configured - * (i.e. qos=control) and otherwise the defaultScore will be returned. - * - * The match function will also search for a valid serializer. If a serializer is configured in the topic properties - * (i.e. pubsub.serializer=json) that specific serializer will be searched. If no serializer is configured the - * highest ranking serializer service will be returned. If no serializer can be found, the outSerializerSvcId will - * be -1. - * - * The function will also returned the found topic properties and the matching serialized. - * The caller is owner of the outTopicProperties. - * - * @param ctx The bundle context. - * @param bundleId The requesting bundle id. - * @param svcProperties The service properties of the registered subscriber service. - * @param adminType The admin type used for the match. - * @param sampleScore The sample score used for the match. - * @param controlScore The control score used for the match. - * @param defaultScore The default score used for the match. - * @param outTopicProperties Output pointer for the read topic properties. Return can be NULL. - * @param outSerializerSvcId Output svc id for the matching serializer. If not found will be -1L. - * @return The matching score. - */ -double pubsub_utils_matchSubscriber( - celix_bundle_context_t *ctx, - const long svcProviderBundleId, - const celix_properties_t *svcProperties, - const char *adminType, - double sampleScore, - double controlScore, - double defaultScore, - bool matchProtocol, - celix_properties_t **outTopicProperties, - long *outSerializerSvcId, - long *outProtocolSvcId); - -/** - * Match an endpoint (subscriber or publisher endpoint) for the provided admin type. - * - * Also tries to found the matching serializer configured in the endpoint. - * - * @param ctx The bundle context. - * @param endpoint The endpoint to match. - * @param adminType The admin type (i.e. UDPMC) - * @param outSerializerSvcId The found serialized svc id based on the endpoint or -1 if no serializer is - * configured/found. - * @return true if there is a match. - */ -bool pubsub_utils_matchEndpoint( - celix_bundle_context_t *ctx, - celix_log_helper_t *logHelper, - const celix_properties_t *ep, - const char *adminType, - bool matchProtocol, - long *outSerializerSvcId, - long *outProtocolSvcId); -#ifdef __cplusplus -} -#endif - -#endif /* PUBSUB_MATCHING_H_ */ diff --git a/bundles/pubsub/pubsub_utils/include/pubsub_serialization_provider.h b/bundles/pubsub/pubsub_utils/include/pubsub_serialization_provider.h deleted file mode 100644 index a01b4c500..000000000 --- a/bundles/pubsub/pubsub_utils/include/pubsub_serialization_provider.h +++ /dev/null @@ -1,127 +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_SERIALIZATION_PROVIDER_H -#define CELIX_PUBSUB_SERIALIZATION_PROVIDER_H - -#include "celix_compiler.h" -#include "celix_log_helper.h" -#include "celix_bundle_context.h" -#include "pubsub_message_serialization_service.h" -#include "dyn_message.h" -#include "celix_version.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct pubsub_serialization_provider pubsub_serialization_provider_t; //opaque - -typedef struct { - celix_log_helper_t *log; - long svcId; - pubsub_message_serialization_service_t svc; - char* descriptorContent; - dyn_message_type *msgType; - unsigned int msgId; - const char* msgFqn; - celix_version_t *msgVersion; - char *msgVersionStr; - - long readFromBndId; - char* readFromEntryPath; - size_t nrOfTimesRead; //nr of times read from different bundles. - - bool valid; - const char* invalidReason; - - //custom user data, will initialized to NULL. If freeUserData is set during destruction of the entry, this will be called. - void* userData; - void (*freeUserData)(void* userData); -} pubsub_serialization_entry_t; - -/** - * @brief Creates A (descriptor based) Serialization Provider. - * - * The provider monitors bundles and creates pubsub message serialization services for every unique descriptor found. - * - * Descriptors can be DFI descriptors or AVPR descriptors (FIXME #158). - * - * The provider will look for descriptors in META-INF/descriptors directory of every installed bundle. - * If a framework config CELIX_FRAMEWORK_EXTENDER_PATH is set, this path will also be used to search for descriptor files. - * - * For every unique and valid descriptor found a pubsub_message_serialization_service will be registered for the serialization type (e.g. 'json') - * The provider will also register a single pubsub_serialization_marker service which 'marks' the existing of the a serialization type serialization support. - * - * Lastly a celix command shell will be register with the command name 'celix::_message_serialization' which can be used to interactively - * query the provided serialization services. - * - * If no specific serialization is configured or builtin by the PubSubAdmin, serialization is chosen by the - * highest ranking serialization marker service. - * - * - * @param ctx The bundle context - * @param serializationType The serialization type (e.g. 'json') - * @param backwardsCompatible Whether the serializer can deserialize data if the minor version is higher. (note true for JSON) - * Will be used to set the 'serialization.backwards.compatible' service property for the pusbub_message_serialization_marker - * @param serializationServiceRanking The service raking used for the serialization marker service. - * @param serialize The serialize function to use - * @param freeSerializeMsg The freeSerializeMsg function to use - * @param deserialize The deserialize function to use - * @param freeDeserializeMsg The freeDesrializeMsg function to use - * @return A pubsub serialization provided for the requested serialization type using the - * provided serialization functions. - */ -pubsub_serialization_provider_t *pubsub_serializationProvider_create( - celix_bundle_context_t *ctx, - const char* serializationType, - bool backwardsCompatible, - long serializationServiceRanking, - celix_status_t (*serialize)(pubsub_serialization_entry_t* entry, const void* msg, struct iovec** output, size_t* outputIovLen), - void (*freeSerializeMsg)(pubsub_serialization_entry_t* entry, struct iovec* input, size_t inputIovLen), - celix_status_t (*deserialize)(pubsub_serialization_entry_t* entry, const struct iovec* input, size_t inputIovLen CELIX_UNUSED, void **out), - void (*freeDeserializeMsg)(pubsub_serialization_entry_t* entry, void *msg)); - -/** - * Destroys the provided JSON Serialization Provider. - */ -void pubsub_serializationProvider_destroy(pubsub_serialization_provider_t *provider); - - -/** - * @brief Returns the number of valid entries. - */ -size_t pubsub_serializationProvider_nrOfEntries(pubsub_serialization_provider_t *provider); - -/** - * @brief Returns the number of invalid entries. - */ -size_t pubsub_serializationProvider_nrOfInvalidEntries(pubsub_serialization_provider_t *provider); - -/** - * @brief Returns the log helper of the serialization provider. - */ -celix_log_helper_t* pubsub_serializationProvider_getLogHelper(pubsub_serialization_provider_t *provider); - - -#ifdef __cplusplus -}; -#endif - -#endif //CELIX_PUBSUB_SERIALIZATION_PROVIDER_H diff --git a/bundles/pubsub/pubsub_utils/include/pubsub_serializer_handler.h b/bundles/pubsub/pubsub_utils/include/pubsub_serializer_handler.h deleted file mode 100644 index 47b41d455..000000000 --- a/bundles/pubsub/pubsub_utils/include/pubsub_serializer_handler.h +++ /dev/null @@ -1,206 +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_SERIALIZER_HANDLER_H -#define CELIX_PUBSUB_SERIALIZER_HANDLER_H - -#include -#include - -#include "celix_log_helper.h" -#include "celix_bundle_context.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct pubsub_serializer_handler pubsub_serializer_handler_t; //opaque type - - -/** - * @brief Creates a pubsub serializer handler which tracks pubsub_custom_msg_serialization_service services using the provided serialization type. - * - * If there are multiple pubsub_message_serialization_service services for the same msg fqn - * (targeted.msg.fqn property) the highest ranking service will be used. - * - * The message handler assumes (and checks) that all provided serialization services do not clash in message ids (so every msgId should have its own msgFqn) - * and that only one version for a message serialization is registered. - * This means that all bundles in a single celix container (a single process) should all use the same version of messages. - * - * If backwards compatibility is supported, when serialized message with a higher minor version when available in the serializer handler are used to - * deserialize. This could be supported for serialization like json. - * So when a json message of version 1.1.x with content {"field1":"value1", "field2":"value2"} is deserialized to a version 1.0 (which only has field1), - * the message can and will be deserialized - * - * @param ctx The bundle contest. - * @param serializerType type of serialization services to handle (e.g. json, avrobin, etc) - * @param backwardCompatible Whether backwards compatible serialization is supported. - * @return A newly created pubsub serializer handler. - */ -pubsub_serializer_handler_t* pubsub_serializerHandler_create(celix_bundle_context_t* ctx, const char* serializerType, bool backwardCompatible); - -/** - * @brief Creates a pubsub serializer handler which tracks pubsub_custom_msg_serialization_service services using the serialization type of the provided - * marker service.id - * - * If there are multiple pubsub_message_serialization_service services for the same msg fqn - * (targeted.msg.fqn property) the highest ranking service will be used. - * - * The message handler assumes (and checks) that all provided serialization services do not clash in message ids (so every msgId should have its own msgFqn) - * and that only one version for a message serialization is registered. - * This means that all bundles in a single celix container (a single process) should all use the same version of messages. - * - * If backwards compatibility is supported, when serialized message with a higher minor version when available in the serializer handler are used to - * deserialize. This could be supported for serialization like json. - * So when a json message of version 1.1.x with content {"field1":"value1", "field2":"value2"} is deserialized to a version 1.0 (which only has field1), - * the message can and will be deserialized - * - * @param ctx The bundle contest. - * @param pubsubSerializerMarkerSvcId The service.id of the pubsub_serialization_marker to use for deferring serializationType and backwardsCompatible. - * @param logHelper Optional log helper. If provided will be used to log issues whit creating a serializer handler for the provided marker svc id. - * @return A newly created pubsub serializer handler. - */ -pubsub_serializer_handler_t* pubsub_serializerHandler_createForMarkerService(celix_bundle_context_t* ctx, long pubsubSerializerMarkerSvcId, celix_log_helper_t* logHelper); - -/** - * @brief destroy the pubsub_serializer_handler and free the used memory. - */ -void pubsub_serializerHandler_destroy(pubsub_serializer_handler_t* handler); - -/** - * @brief Serialize a message into iovec structs (set of structures with buffer pointer and length) - * - * The correct message serialization services will be selected based on the provided msgId. - * - * @param handler The pubsub serialization handler. - * @param msgId The msg id for the message to be serialized. - * @param input A pointer to the message object - * @param output An output pointer to a array of iovec structs. - * @param outputIovLen The number of iovec struct created - * @return CELIX_SUCCESS on success, CELIX_ILLEGAL_ARGUMENT if the msg id is not known or serialization failed. - */ -celix_status_t pubsub_serializerHandler_serialize(pubsub_serializer_handler_t* handler, uint32_t msgId, const void* input, struct iovec** output, size_t* outputIovLen); - -/** - * @brief Free the memory of for the serialized msg. - */ -celix_status_t pubsub_serializerHandler_freeSerializedMsg(pubsub_serializer_handler_t* handler, uint32_t msgId, struct iovec* input, size_t inputIovLen); - -/** - * @brief Deserialize a message using the provided iovec buffers. - * - * The deserialize function will also check if the target major/minor version of the message is valid with the version - * of the serialized data. - * - * For some serialization types (e.g. JSON) newer versions of the serialized data can be deserialized. - * E.g. JSON serialized data with version 1.2.0 can be deserialized to a target message with version 1.0.0 - * But JSON serialized data with a version 2.0.0 will not be deserialized to a target message with version 1.0.0 - * This assume correct use of semantic versioning. - * - * @param handler The pubsub serialization handler. - * @param msgId The msg id for the message to be deserialized. - * @param serializedMajorVersion The major version of the serialized data - * @param serializedMinorVersion The minor version of the serialized data. - * @param input Pointer to the first element in a array of iovecs. - * @param inputIovLen Then number of iovecs. - * @param out The newly allocated and deserialized message object - * @return CELIX_SUCCESS on success. CELIX_ILLEGAL_ARGUMENT if the msg id is not known, - * or if the version do no match or deserialization failed. - */ -celix_status_t pubsub_serializerHandler_deserialize(pubsub_serializer_handler_t* handler, uint32_t msgId, int serializedMajorVersion, int serializedMinorVersion, const struct iovec* input, size_t inputIovLen, void** out); - -/** - * @brief Free the memory for the deserialized message. - */ -celix_status_t pubsub_serializerHandler_freeDeserializedMsg(pubsub_serializer_handler_t* handler, uint32_t msgId, void* msg); - -/** - * @brief Whether the msg is support. More specifically: - * - msg id is known and - * - a serialized msg with the provided major and minor version can be deserialized. - */ -bool pubsub_serializerHandler_isMessageSupported(pubsub_serializer_handler_t* handler, uint32_t msgId, int majorVersion, int minorVersion); - -/** - * @brief Whether the serializer handler has found 1 or more pubsub_message_serialization_service for the provided msg id. - */ -bool pubsub_serializerHandler_isMessageSerializationServiceAvailable(pubsub_serializer_handler_t* handler, uint32_t msgId); - -/** - * @brief Get msg fqn from a msg id. - * @return msg fqn or NULL if msg id is not known. msg fqn is valid as long as the handler exists. - */ -const char* pubsub_serializerHandler_getMsgFqn(pubsub_serializer_handler_t* handler, uint32_t msgId); - -/** - * @brief Get a msg id from a msgFqn. - * @return msg id or 0 if msg fqn is not known. - */ -uint32_t pubsub_serializerHandler_getMsgId(pubsub_serializer_handler_t* handler, const char* msgFqn); - -/** - * @brief nr of serialization services found. - */ -size_t pubsub_serializerHandler_messageSerializationServiceCount(pubsub_serializer_handler_t* handler); - - -/** - * @brief Get the serializer type for this hanlder. - * - * Valid as long as the handler exists. - */ -const char* pubsub_serializerHandler_getSerializationType(pubsub_serializer_handler_t* handler); - -/** - * @brief Returns the major version part of a message version. - * - * Returns -1 if message cannot be found. - */ -int pubsub_serializerHandler_getMsgMinorVersion(pubsub_serializer_handler_t* handler, uint32_t msgId); - -/** - * @brief Returns the minor version part of a message version. - * - * Returns -1 if message cannot be found. - */ -int pubsub_serializerHandler_getMsgMajorVersion(pubsub_serializer_handler_t* handler, uint32_t msgId); - - -/** - * @brief Returns msg info (fqn, major version, minor version) in 1 call. - * - * @param handler The serializer handler - * @param msgId The msg id where to get the info for - * @param msgFqnOut If not NULL will be set to the msgFqn (valid as long as the serializer handler is valid) - * @param msgMajorVersionOut If not NULL will be set to the msg major version - * @param msgMinorVersionOut If not NULL will be set to the msg minor version - * @return CELIX_SUCCESS on success, CELIX_ILLEGAL_ARGUMENT if the message for the provided msg id cannot be found. - */ -celix_status_t pubsub_serializerHandler_getMsgInfo( - pubsub_serializer_handler_t* handler, - uint32_t msgId, - const char** msgFqnOut, - int* msgMajorVersionOut, - int* msgMinorVersionOut); - -#ifdef __cplusplus -} -#endif - -#endif //CELIX_PUBSUB_SERIALIZER_HANDLER_H diff --git a/bundles/pubsub/pubsub_utils/include/pubsub_utils.h b/bundles/pubsub/pubsub_utils/include/pubsub_utils.h deleted file mode 100644 index 261f403dc..000000000 --- a/bundles/pubsub/pubsub_utils/include/pubsub_utils.h +++ /dev/null @@ -1,99 +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_UTILS_H_ -#define PUBSUB_UTILS_H_ - -#include "celix_array_list.h" -#include "celix_bundle_context.h" -#ifdef __cplusplus -extern "C" { -#endif -#define PUBSUB_UTILS_QOS_ATTRIBUTE_KEY "qos" -#define PUBSUB_UTILS_QOS_TYPE_SAMPLE "sample" /* A.k.a. unreliable connection */ -#define PUBSUB_UTILS_QOS_TYPE_CONTROL "control" /* A.k.a. reliable connection */ -#define PUBSUB_UTILS_PSA_SEND_DELAY "PSA_SEND_DELAY" -#define PUBSUB_UTILS_PSA_DEFAULT_SEND_DELAY 250 // 250 ms - -/** - * Returns the pubsub info from the provided filter. A pubsub filter should have a topic and can - * have a scope. If no topic is present the topic and scope output will be NULL. - * If a topic is present the topic output will contain an allocated topic string and if a scope was - * present an allocated scope string. - * The caller is owner of the topic and scope output string. - */ -celix_status_t pubsub_getPubSubInfoFromFilter(const char* filterstr, char **scope, char **topic); - -/** - * Loop through all bundles and look for the bundle with the keys inside. - * If no key bundle found, return NULL - * - * Caller is responsible for freeing the object - */ -char* pubsub_getKeysBundleDir(celix_bundle_context_t *ctx); - -/** - * Tries to find and read the topic properties for the provided bundle. - * - * Will look at META-INF/topics/pub/.properties for publisher and - * META-INF/topics/sub/.properties for subscribers. - * - * The caller is owner of the returned topic properties. - * - * @param bundle The bundle where the properties reside. - * @param scope The scope name. - * @param topic The topic name. - * @param isPublisher true if the topic properties for a publisher should be found. - * @return The topic properties if found or NULL. - */ -celix_properties_t* pubsub_utils_getTopicProperties(const celix_bundle_t *bundle, const char *scope, const char *topic, bool isPublisher); - -/** - * Returns a msg id from the provided fully qualified name. - * - * - * @param fqn fully qualified name - * @return msg id - */ -unsigned int pubsub_msgIdHashFromFqn(const char* fqn); - -/** - * Returns the directory where the descriptor for messages can be found. - * - * @param ctx The bundle context. - * @param bnd The bundle to get descriptor root dir from. - * @return NULL if the directory does not exists. Caller is owner of the data. - */ -char* pubsub_getMessageDescriptorsDir(celix_bundle_context_t*ctx, const celix_bundle_t *bnd); - -/** - * Combines the name of key with topic and optionally scope and retrieves the value of that environment variable or framework property - * @param ctx The bundle context - * @param key start of the key name, e.g. PUBSUB_TCP_STATIC_BIND_URL_FOR - * @param topic Name of topic. NULL NOT allowed - * @param scope Name of scope. NULL allowed - * @return Value of environment variable name, NULL if variable not defined/found. - */ -const char* pubsub_getEnvironmentVariableWithScopeTopic(celix_bundle_context_t* ctx, const char *key, const char *topic, const char *scope); - -#ifdef __cplusplus -} -#endif - -#endif /* PUBSUB_UTILS_H_ */ diff --git a/bundles/pubsub/pubsub_utils/include/pubsub_utils_url.h b/bundles/pubsub/pubsub_utils/include/pubsub_utils_url.h deleted file mode 100644 index 212b575b7..000000000 --- a/bundles/pubsub/pubsub_utils/include/pubsub_utils_url.h +++ /dev/null @@ -1,55 +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_UTILS_URL_H_ -#define PUBSUB_UTILS_URL_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -typedef struct pubsub_utils_url { - char *url; - char *protocol; - char *hostname; - unsigned int port_nr; - char *uri; - char *interface; - unsigned int interface_port_nr; - char *interface_url; -} pubsub_utils_url_t; - -struct sockaddr_in *pubsub_utils_url_from_fd(int fd); -struct sockaddr_in *pubsub_utils_url_getInAddr(const char *hostname, unsigned int port); -char *pubsub_utils_url_generate_url(char *hostname, unsigned int port_nr, char *protocol); -char *pubsub_utils_url_get_url(struct sockaddr_in *inp, char *protocol); -bool pubsub_utils_url_is_multicast(char *hostname); -char *pubsub_utils_url_get_multicast_ip(char *hostname); -char *pubsub_utils_url_get_ip(char *hostname); -void pubsub_utils_url_parse_url(char *_url, pubsub_utils_url_t *url_info); -pubsub_utils_url_t *pubsub_utils_url_parse(char *url); -void pubsub_utils_url_free(pubsub_utils_url_t *url_info); - -#ifdef __cplusplus -} -#endif - -#endif /* //#include "pubsub_utils_url.h" */ diff --git a/bundles/pubsub/pubsub_utils/src/pubsub_matching.c b/bundles/pubsub/pubsub_utils/src/pubsub_matching.c deleted file mode 100644 index 64855922c..000000000 --- a/bundles/pubsub/pubsub_utils/src/pubsub_matching.c +++ /dev/null @@ -1,302 +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 - -#include "celix_constants.h" -#include "celix_filter.h" - -#include "pubsub_utils.h" - -#include "celix_bundle.h" - -#include "pubsub_endpoint.h" -#include "pubsub_protocol.h" -#include "pubsub_admin.h" -#include "pubsub_message_serialization_marker.h" - - -struct ps_utils_serializer_selection_data { - const char *requested_serializer; - long matchingSvcId; - long matchingRanking; -}; - - -struct ps_utils_protocol_selection_data { - const char *requested_protocol; - long matchingSvcId; -}; - -typedef struct ps_utils_retrieve_topic_properties_data { - const char *topic; - const char *scope; - bool isPublisher; - - celix_properties_t *outEndpoint; -} ps_utils_retrieve_topic_properties_data_t; - -static long getPSSerializer(celix_bundle_context_t *ctx, const char *requested_serializer) { - long svcId = -1L; - - celix_service_filter_options_t opts = CELIX_EMPTY_SERVICE_FILTER_OPTIONS; - opts.serviceName = PUBSUB_MESSAGE_SERIALIZATION_MARKER_NAME; - - if (requested_serializer != NULL) { - char filter[512]; - int written = snprintf(filter, 512, "(%s=%s)", PUBSUB_MESSAGE_SERIALIZATION_MARKER_SERIALIZATION_TYPE_PROPERTY, requested_serializer); - if (written > 512) { - fprintf(stderr, "Cannot create serializer filter. need more than 512 char array\n"); - } else { - opts.filter = filter; - svcId = celix_bundleContext_findServiceWithOptions(ctx, &opts); - } - } else { - //note findService will automatically return the highest ranking service id - svcId = celix_bundleContext_findServiceWithOptions(ctx, &opts); - } - - return svcId; -} - - - -static double getPSScore(const char *requested_admin, const char *request_qos, const char *adminType, double sampleScore, double controlScore, double defaultScore) { - double score; - if (requested_admin != NULL && strncmp(requested_admin, adminType, strlen(adminType)) == 0) { - /* We got precise specification on the pubsub_admin we want */ - //Full match - score = PUBSUB_ADMIN_FULL_MATCH_SCORE; - } else if (requested_admin != NULL) { - //admin type requested, but no match -> do not select this psa - score = PUBSUB_ADMIN_NO_MATCH_SCORE; - } else if (request_qos != NULL && strncmp(request_qos, PUBSUB_UTILS_QOS_TYPE_SAMPLE, strlen(PUBSUB_UTILS_QOS_TYPE_SAMPLE)) == 0) { - //qos match - score = sampleScore; - } else if (request_qos != NULL && strncmp(request_qos, PUBSUB_UTILS_QOS_TYPE_CONTROL, strlen(PUBSUB_UTILS_QOS_TYPE_CONTROL)) == 0) { - //qos match - score = controlScore; - } else if (request_qos != NULL) { - //note unsupported qos -> defaultScore - score = defaultScore; - } else { - //default match - score = defaultScore; - } - return score; -} - -static long getPSProtocol(celix_bundle_context_t *ctx, const char *requested_protocol) { - long svcId = -1L; - - if (requested_protocol != NULL) { - char filter[512]; - int written = snprintf(filter, 512, "(%s=%s)", PUBSUB_PROTOCOL_TYPE_KEY, requested_protocol); - if (written > 512) { - fprintf(stderr, "Cannot create protocol filter. need more than 512 char array\n"); - } else { - celix_service_filter_options_t opts = CELIX_EMPTY_SERVICE_FILTER_OPTIONS; - opts.serviceName = PUBSUB_PROTOCOL_SERVICE_NAME; - opts.filter = filter; - svcId = celix_bundleContext_findServiceWithOptions(ctx, &opts); - } - } else { - celix_service_filter_options_t opts = CELIX_EMPTY_SERVICE_FILTER_OPTIONS; - opts.serviceName = PUBSUB_PROTOCOL_SERVICE_NAME; - - //note findService will automatically return the highest ranking service id - svcId = celix_bundleContext_findServiceWithOptions(ctx, &opts); - } - - return svcId; -} - -static void getTopicPropertiesCallback(void *handle, const celix_bundle_t *bnd) { - ps_utils_retrieve_topic_properties_data_t *data = handle; - data->outEndpoint = pubsub_utils_getTopicProperties(bnd, data->scope, data->topic, data->isPublisher); -} - -double pubsub_utils_matchPublisher( - celix_bundle_context_t *ctx, - long bundleId, - const char *filter, - const char *adminType, - double sampleScore, - double controlScore, - double defaultScore, - bool matchProtocol, - celix_properties_t **outTopicProperties, - long *outSerializerSvcId, - long *outProtocolSvcId) { - - celix_properties_t *ep = pubsubEndpoint_createFromPublisherTrackerInfo(ctx, bundleId, filter); - const char *requested_admin = NULL; - const char *requested_qos = NULL; - requested_admin = celix_properties_get(ep, PUBSUB_ENDPOINT_ADMIN_TYPE, NULL); - requested_qos = celix_properties_get(ep, PUBSUB_UTILS_QOS_ATTRIBUTE_KEY, NULL); - - double score = getPSScore(requested_admin, requested_qos, adminType, sampleScore, controlScore, defaultScore); - - const char *requested_serializer = celix_properties_get(ep, PUBSUB_ENDPOINT_SERIALIZER, NULL); - long serializerSvcId = getPSSerializer(ctx, requested_serializer); - - if (outSerializerSvcId != NULL) { - *outSerializerSvcId = serializerSvcId; - } - - long protocolSvcId = -1; - if (matchProtocol) { - const char *requested_protocol = celix_properties_get(ep, PUBSUB_ENDPOINT_PROTOCOL, NULL); - protocolSvcId = getPSProtocol(ctx, requested_protocol); - if (outProtocolSvcId != NULL) { - *outProtocolSvcId = protocolSvcId; - } - } - - if (serializerSvcId < 0) { - score = PUBSUB_ADMIN_NO_MATCH_SCORE; - } else if (matchProtocol && protocolSvcId < 0) { - score = PUBSUB_ADMIN_NO_MATCH_SCORE; - } - - if (outTopicProperties != NULL) { - *outTopicProperties = ep; - } else { - celix_properties_destroy(ep); - } - - return score; -} - -double pubsub_utils_matchSubscriber( - celix_bundle_context_t *ctx, - const long svcProviderBundleId, - const celix_properties_t *svcProperties, - const char *adminType, - double sampleScore, - double controlScore, - double defaultScore, - bool matchProtocol, - celix_properties_t **outTopicProperties, - long *outSerializerSvcId, - long *outProtocolSvcId) { - - ps_utils_retrieve_topic_properties_data_t data; - data.isPublisher = false; - data.scope = celix_properties_get(svcProperties, PUBSUB_SUBSCRIBER_SCOPE, NULL); - data.topic = celix_properties_get(svcProperties, PUBSUB_SUBSCRIBER_TOPIC, NULL); - data.outEndpoint = NULL; - celix_bundleContext_useBundle(ctx, svcProviderBundleId, &data, getTopicPropertiesCallback); - - celix_properties_t *ep = data.outEndpoint; - const char *requested_admin = NULL; - const char *requested_qos = NULL; - const char *requested_serializer = NULL; - const char *requested_protocol = NULL; - requested_admin = celix_properties_get(ep, PUBSUB_ENDPOINT_ADMIN_TYPE, NULL); - requested_qos = celix_properties_get(ep, PUBSUB_UTILS_QOS_ATTRIBUTE_KEY, NULL); - requested_serializer = celix_properties_get(ep, PUBSUB_ENDPOINT_SERIALIZER, NULL); - if (matchProtocol) { - requested_protocol = celix_properties_get(ep, PUBSUB_ENDPOINT_PROTOCOL, NULL); - } - - double score = getPSScore(requested_admin, requested_qos, adminType, sampleScore, controlScore, defaultScore); - - long serializerSvcId = getPSSerializer(ctx, requested_serializer); - if (serializerSvcId < 0) { - score = PUBSUB_ADMIN_NO_MATCH_SCORE; //no serializer, no match - } - - if (outSerializerSvcId != NULL) { - *outSerializerSvcId = serializerSvcId; - } - - if (matchProtocol) { - long protocolSvcId = getPSProtocol(ctx, requested_protocol); - if (protocolSvcId < 0) { - score = PUBSUB_ADMIN_NO_MATCH_SCORE; //no protocol, no match - } - - if (outProtocolSvcId != NULL) { - *outProtocolSvcId = protocolSvcId; - } - } - - if (outTopicProperties != NULL) { - *outTopicProperties = ep; - } else { - celix_properties_destroy(ep); - } - - return score; -} - -bool pubsub_utils_matchEndpoint( - celix_bundle_context_t *ctx, - celix_log_helper_t *logHelper, - const celix_properties_t *ep, - const char *adminType, - bool matchProtocol, - long *outSerializerSvcId, - long *outProtocolSvcId) { - - bool psaMatch = false; - const char *configured_admin = celix_properties_get(ep, PUBSUB_ENDPOINT_ADMIN_TYPE, NULL); - if (configured_admin != NULL) { - psaMatch = strncmp(configured_admin, adminType, strlen(adminType)) == 0; - } - - bool serMatch = false; - long serializerSvcId = -1L; - if (psaMatch) { - const char *configured_serializer = celix_properties_get(ep, PUBSUB_ENDPOINT_SERIALIZER, NULL); - serializerSvcId = getPSSerializer(ctx, configured_serializer); - serMatch = serializerSvcId >= 0; - - if(!serMatch) { - celix_logHelper_log(logHelper, CELIX_LOG_LEVEL_ERROR, "Matching endpoint for technology %s but couldn't get serializer %s", configured_admin, configured_serializer); - } - } - - bool match = psaMatch && serMatch; - - if (matchProtocol) { - bool protMatch = false; - long protocolSvcId = -1L; - if (psaMatch) { - const char *configured_protocol = celix_properties_get(ep, PUBSUB_ENDPOINT_PROTOCOL, NULL); - protocolSvcId = getPSProtocol(ctx, configured_protocol); - protMatch = protocolSvcId >= 0; - - if(!protMatch) { - celix_logHelper_log(logHelper, CELIX_LOG_LEVEL_ERROR, "Matching endpoint for technology %s but couldn't get protocol %s", configured_admin, configured_protocol); - } - } - match = match && protMatch; - - if (outProtocolSvcId != NULL) { - *outProtocolSvcId = protocolSvcId; - } - } - - if (outSerializerSvcId != NULL) { - *outSerializerSvcId = serializerSvcId; - } - - return match; -} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_utils/src/pubsub_serialization_provider.c b/bundles/pubsub/pubsub_utils/src/pubsub_serialization_provider.c deleted file mode 100644 index 3243fde65..000000000 --- a/bundles/pubsub/pubsub_utils/src/pubsub_serialization_provider.c +++ /dev/null @@ -1,729 +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_serialization_provider.h" - -#include -#include -#include -#include - -#include "pubsub_message_serialization_marker.h" -#include "celix_compiler.h" -#include "celix_constants.h" -#include "dyn_function.h" -#include "celix_version.h" -#include "celix_utils.h" -#include "dyn_message.h" -#include "dyn_interface.h" -#include "pubsub_utils.h" -#include "celix_log_helper.h" -#include "pubsub_message_serialization_service.h" -#include "celix_shell_command.h" -#include "celix_threads.h" - -#define MAX_PATH_LEN 1024 - -typedef enum -{ - FIT_INVALID = 0, - FIT_DESCRIPTOR = 1, - FIT_AVPR = 2 -} descriptor_type_e; - -#define L_DEBUG(...) \ - celix_logHelper_debug(provider->logHelper, __VA_ARGS__) -#define L_INFO(...) \ - celix_logHelper_info(provider->logHelper, __VA_ARGS__) -#define L_WARN(...) \ - celix_logHelper_warning(provider->logHelper, __VA_ARGS__) -#define L_ERROR(...) \ - celix_logHelper_error(provider->logHelper, __VA_ARGS__) - - -struct pubsub_serialization_provider { - celix_bundle_context_t *ctx; - celix_log_helper_t *logHelper; - char* serializationType; - - //serialization callbacks - celix_status_t (*serialize)(pubsub_serialization_entry_t* entry, const void* msg, struct iovec** output, size_t* outputIovLen); - void (*freeSerializeMsg)(pubsub_serialization_entry_t* entry, struct iovec* input, size_t inputIovLen); - celix_status_t (*deserialize)(pubsub_serialization_entry_t* entry, const struct iovec* input, size_t inputIovLen CELIX_UNUSED, void **out); - void (*freeDeserializeMsg)(pubsub_serialization_entry_t* entry, void *msg); - - //updated serialization services - long bundleTrackerId; - - celix_shell_command_t cmdSvc; - long cmdSvcId; - - pubsub_message_serialization_marker_t markerSvc; - long markerSvcId; - - celix_thread_mutex_t mutex; //protects below - celix_array_list_t *serializationSvcEntries; //key = pubsub_serialization_entry; -}; - -static void dfi_log(void *handle, int level, const char *file, int line, const char *msg, ...) { - (void)level; - va_list ap; - pubsub_serialization_provider_t *provider = handle; - char *logStr = NULL; - va_start(ap, msg); - vasprintf(&logStr, msg, ap); - va_end(ap); - celix_logHelper_log(provider->logHelper, CELIX_LOG_LEVEL_WARNING, "FILE:%s, LINE:%i, MSG:%s", file, line, logStr); - free(logStr); -} - -static descriptor_type_e getDescriptorType(const char* filename) { - if (strstr(filename, ".descriptor")) { - return FIT_DESCRIPTOR; - } - else if (strstr(filename, ".properties")) { - return FIT_AVPR; - } - else { - return FIT_INVALID; - } -} - -/** - * Reads an avpr properties file. A properties file which revert to an avpr file and the usaged definition in the avpr. - */ -static bool readAvprPropertiesFile(pubsub_serialization_provider_t* provider, const char* properties_file_name, const char* root, char* avpr_fqn, char* path) { - snprintf(path, MAX_PATH_LEN, "%s/%s", root, properties_file_name); // use path to create path to properties file - FILE *properties = fopen(path, "r"); - if (!properties) { - L_WARN("Could not find or open %s as a properties file in %s\n", properties_file_name, root); - return false; - } - - *avpr_fqn = '\0'; - *path = '\0'; //re-use path to create path to avpr file - char *p_line = malloc(MAX_PATH_LEN); - size_t line_len = MAX_PATH_LEN; - while (getline(&p_line, &line_len, properties) >= 0) { - if (strncmp(p_line, "fqn=", strlen("fqn=")) == 0) { - snprintf(avpr_fqn, MAX_PATH_LEN, "%s", (p_line + strlen("fqn="))); - avpr_fqn[strcspn(avpr_fqn, "\n")] = 0; - } - else if (strncmp(p_line, "avpr=", strlen("avpr=")) == 0) { - snprintf(path, MAX_PATH_LEN, "%s/%s", root, (p_line + strlen("avpr="))); - path[strcspn(path, "\n")] = 0; - } - } - free(p_line); - fclose(properties); - - if (*avpr_fqn == '\0') { - L_WARN("File %s does not contain a fully qualified name for the parser\n", properties_file_name); - return false; - } - - if (*path == '\0') { - L_WARN("File %s does not contain a location for the avpr file\n", properties_file_name); - return false; - } - - return true; -} - -static FILE* openFileStream(pubsub_serialization_provider_t* provider, descriptor_type_e descriptorType, const char* filename, const char* root, char* avpr_fqn, char* pathOrError) { - FILE* result = NULL; - memset(pathOrError, 0, MAX_PATH_LEN); - switch (descriptorType) { - case FIT_INVALID: - snprintf(pathOrError, MAX_PATH_LEN, "Because %s is not a valid file", filename); - break; - case FIT_DESCRIPTOR: - snprintf(pathOrError, MAX_PATH_LEN, "%s/%s", root, filename); - result = fopen(pathOrError, "r"); - break; - case FIT_AVPR: - if (readAvprPropertiesFile(provider, filename, root, avpr_fqn, pathOrError)) { - result = fopen(pathOrError, "r"); - } - break; - default: - L_WARN("Unknown file input type, returning NULL!\n"); - break; - } - - return result; -} - -static unsigned int pubsub_serializationProvider_getMsgId(pubsub_serialization_provider_t* provider CELIX_UNUSED, dyn_message_type *msg) { - unsigned int msgId = 0; - - char *msgName = NULL; - dynMessage_getName(msg, &msgName); - - char *msgIdStr = NULL; - int rv = dynMessage_getAnnotationEntry(msg, "msgId", &msgIdStr); - if (rv == CELIX_SUCCESS && msgIdStr != NULL) { - // custom msg id passed, use it - long customMsgId = strtol(msgIdStr, NULL, 10); - if (customMsgId > 0) { - msgId = (unsigned int) customMsgId; - } - } - if (msgId == 0) { - msgId = celix_utils_stringHash(msgName); - } - - return msgId; -} - -static dyn_message_type* pubsub_serializationProvider_parseDfiDescriptor(pubsub_serialization_provider_t* provider, FILE* stream, const char* entryPath) { - dyn_message_type *msg = NULL; - int rc = dynMessage_parse(stream, &msg); - if (rc != 0 || msg == NULL) { - L_WARN("Cannot parse message from descriptor from entry %s.\n", entryPath); - return NULL; - } - - char *msgName = NULL; - rc += dynMessage_getName(msg, &msgName); - - version_pt msgVersion = NULL; - rc += dynMessage_getVersion(msg, &msgVersion); - - if (rc != 0 || msgName == NULL || msgVersion == NULL) { - L_WARN("Cannot retrieve name and/or version from msg, using entry %s.\n", entryPath); - dynMessage_destroy(msg); - return NULL; - } - - return msg; -} - -static bool pubsub_serializationProvider_isDescriptorInterface(pubsub_serialization_provider_t* provider, FILE* stream) { - dyn_interface_type *msg = NULL; - bool isInterface = false; - - int rc = dynInterface_parse(stream, &msg); - if (rc == 0 && msg != NULL) { - isInterface = true; - } - dynInterface_destroy(msg); - fseek(stream, 0, SEEK_SET); - - return isInterface; -} - -//TODO FIXME, see #158 -// -// static dyn_message_type* pubsub_serializationProvider_parseAvprDescriptor(pubsub_serialization_provider_t* provider, FILE* stream, const char *entryName, const char* fqn) { -// -// //dyn_message_type* msgType = dynMessage_parseAvpr(file_ptr, fqn); -// dyn_message_type* msgType = NULL; -// -// if (!msgType) { -// L_WARN("[json serializer] Cannot parse avpr file '%s'\n", fqn); -// return -1; -// } -// -// dyn_type* type; -// dynMessage_getMessageType(msgType, &type); -// -// const char *msgName = dynType_getName(type); -// -// version_pt msgVersion = NULL; -// celix_status_t s = version_createVersionFromString(dynType_getMetaInfo(type, "version"), &msgVersion); -// -// if (s != CELIX_SUCCESS || !msgName) { -// L_WARN("[json serializer] Cannot retrieve name and/or version from msg\n"); -// if (s == CELIX_SUCCESS) { -// version_destroy(msgVersion); -// } -// return -1; -// } -// -// unsigned int msgId = 0; -// const char *msgIdStr = dynType_getMetaInfo(type, "msgId"); -// if (msgIdStr != NULL) { -// // custom msg id passed, use it -// long customMsgId = strtol(msgIdStr, NULL, 10); -// if (customMsgId > 0) -// msgId = (unsigned int) customMsgId; -// } -// -// if (msgId == 0) { -// msgId = utils_stringHash(msgName); -// } -// -// -// -// return 0; -//} -//} - -/** - * Check if a pubsub serialization entry is already present (exact path) - * - * @return true if the entry is a already present - */ -static bool pubsub_serializationProvider_alreadyAddedEntry(pubsub_serialization_provider_t* provider, pubsub_serialization_entry_t* entry) { - for (int i = 0; i < celix_arrayList_size(provider->serializationSvcEntries); ++i) { - pubsub_serialization_entry_t *visit = celix_arrayList_get(provider->serializationSvcEntries, i); - if (celix_utils_stringEquals(visit->readFromEntryPath, entry->readFromEntryPath)) { - return true; - } - } - return false; -} - -/** - * Validates an pubsub serialization entry and check if this is a new unique entry. - * - * Checks whether the entry is valid. Specifically checks: - * - If there is not already an entry with the same msg fqn, but a different msg id. - * - If there is not already an entry with the same msg id, but a different msg fqn. - * - If there is not already an entry for the message with a different versions. (this is not supported). - * - If there is not already an entry for the message with a different descriptor content. - * - * Logs error if msg id clashes or versions are different. - * Logs warning if descriptors are different. - * - * @return true if the entry is a new (unique) entry. - */ -static bool pubsub_serializationProvider_validateEntry(pubsub_serialization_provider_t* provider, pubsub_serialization_entry_t* entry) { - bool unique = true; - - celixThreadMutex_lock(&provider->mutex); - for (int i = 0; i < celix_arrayList_size(provider->serializationSvcEntries); ++i) { - pubsub_serialization_entry_t* visit = celix_arrayList_get(provider->serializationSvcEntries, i); - if (visit->msgId == entry->msgId || strncmp(visit->msgFqn, entry->msgFqn, 1024*1024) == 0) { - unique = false; //already have a descriptor with the same id or fqn. check if valid - visit->nrOfTimesRead += 1; - if (visit->msgId == entry->msgId && strncmp(visit->msgFqn, entry->msgFqn, 1024*1024) != 0) { - L_ERROR("Error adding descriptor %s. Found msg types with same msg id, but different msg fqn. Msg id is %d, but found fully qualified names are '%s' and '%s'. Not adding descriptor with msg fqn %s.", - entry->readFromEntryPath, entry->msgId, entry->msgFqn, visit->msgFqn, entry->msgFqn); - entry->invalidReason = "msg id clash"; - entry->valid = false; - } else if (strncmp(visit->msgFqn, entry->msgFqn, 1024*1024) == 0 && entry->msgId != visit->msgId) { - L_ERROR("Error adding descriptor %s. Found msg types with same fqn, but different msg ids. Msg fqn is %s, but found msg ids are '%d' and '%d'. Not adding descriptor with msg id %d.", - entry->readFromEntryPath, entry->msgFqn, entry->msgId, visit->msgId, entry->msgId); - entry->invalidReason = "msg fqn clash"; - entry->valid = false; - } else if (celix_version_compareTo(visit->msgVersion, entry->msgVersion) != 0) { - L_ERROR("Error adding descriptor %s. Found two different version for msg %s. This is not supported, please align used versions between bundles!. Versions found %s and %s. Not adding descriptor with version %s.", - entry->readFromEntryPath, entry->msgFqn, entry->msgVersionStr, visit->msgVersionStr, entry->msgVersionStr); - entry->invalidReason = "different versions for the same msg type"; - entry->valid = false; - } else if (strncmp(visit->descriptorContent, entry->descriptorContent, 1024*1014*10) != 0) { - L_ERROR("Error adding descriptor %s. Added descriptor content is different than existing content. Existing: '%s', added: %s.", entry->readFromEntryPath, entry->descriptorContent, visit->descriptorContent); - entry->invalidReason = "different versions for the same msg type"; - entry->valid = false; - } - } - } - celixThreadMutex_unlock(&provider->mutex); - - return unique; -} - -static void pubsub_serializationProvider_registerSerializationEntry(pubsub_serialization_provider_t* provider, pubsub_serialization_entry_t* entry) { - if (entry->svcId == -1L) { - celix_properties_t* props = celix_properties_create(); - celix_properties_set(props, PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_FQN_PROPERTY, entry->msgFqn); - celix_properties_set(props, PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_VERSION_PROPERTY, entry->msgVersionStr); - celix_properties_setLong(props, PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_ID_PROPERTY, (long)entry->msgId); - celix_properties_set(props, PUBSUB_MESSAGE_SERIALIZATION_SERVICE_SERIALIZATION_TYPE_PROPERTY, provider->serializationType); - - celix_service_registration_options_t opts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS; - opts.svc = &entry->svc; - opts.serviceName = PUBSUB_MESSAGE_SERIALIZATION_SERVICE_NAME; - opts.serviceVersion = PUBSUB_MESSAGE_SERIALIZATION_SERVICE_VERSION; - opts.properties = props; - entry->svcId = celix_bundleContext_registerServiceWithOptions(provider->ctx, &opts); - } -} - -static void pubsub_serializationProvider_parseDescriptors(pubsub_serialization_provider_t* provider, const char *root, long bndId) { - char fqn[MAX_PATH_LEN]; - char pathOrError[MAX_PATH_LEN]; - const char* entry_name = NULL; - descriptor_type_e descriptorType; - - const struct dirent *entry = NULL; - DIR* dir = opendir(root); - if (dir) { - entry = readdir(dir); - } - - for (; entry != NULL; entry = readdir(dir)) { - FILE* stream = NULL; - entry_name = entry->d_name; - descriptorType = getDescriptorType(entry_name); - if (descriptorType != FIT_INVALID) { - L_DEBUG("Parsing entry '%s'\n", entry_name); - stream = openFileStream(provider, descriptorType, entry_name, root, /*out*/fqn, /*out*/pathOrError); - if (!stream) { - L_WARN("Cannot open descriptor file: '%s'\n", pathOrError); - } - } - - if (!stream) { - continue; // Go to next entry in directory - } - - char *entryPath = NULL; - asprintf(&entryPath, "%s/%s", root, entry_name); - - dyn_message_type *msgType = NULL; - if (descriptorType == FIT_DESCRIPTOR) { - if(!pubsub_serializationProvider_isDescriptorInterface(provider, stream)) { - msgType = pubsub_serializationProvider_parseDfiDescriptor(provider, stream, entry_name); - } else { - L_DEBUG("Ignoring interface file"); - } - } else if (descriptorType == FIT_AVPR) { - L_DEBUG("Ignoring avpr files for now, needs fixing!"); - //msgType = pubsub_serializationProvider_parseAvprDescriptor(provider, stream, entry_name, /*TODO FQN*/fqn); - } else { - L_ERROR("Unexpected descriptor type for entry %s.", entryPath); - } - - if (msgType == NULL) { - free(entryPath); - fclose(stream); - continue; - } - - fseek(stream, 0L, SEEK_END); - long streamSize = ftell(stream); - char *membuf = malloc(streamSize + 1); - rewind(stream); - fread(membuf, streamSize, 1, stream); - fclose(stream); - membuf[streamSize] = '\0'; - - - celix_version_t *msgVersion = NULL; - char *msgFqn = NULL; - dynMessage_getVersion(msgType, &msgVersion); - dynMessage_getName(msgType, &msgFqn); - unsigned int msgId = pubsub_serializationProvider_getMsgId(provider, msgType); - - pubsub_serialization_entry_t* serEntry = calloc(1, sizeof(*serEntry)); - serEntry->log = provider->logHelper; - serEntry->descriptorContent = membuf; - serEntry->msgFqn = msgFqn; - serEntry->msgVersion = msgVersion; - serEntry->msgVersionStr = celix_version_toString(msgVersion); - serEntry->msgId = msgId; - serEntry->msgType = msgType; - serEntry->readFromBndId = bndId; - serEntry->readFromEntryPath = entryPath; - serEntry->nrOfTimesRead = 1; - serEntry->valid = true; - serEntry->invalidReason = ""; - serEntry->svc.handle = serEntry; - serEntry->svc.serialize = (void*)provider->serialize; - serEntry->svc.freeSerializedMsg = (void*)provider->freeSerializeMsg; - serEntry->svc.deserialize = (void*)provider->deserialize; - serEntry->svc.freeDeserializedMsg = (void*)provider->freeDeserializeMsg; - serEntry->svcId = -1L; - - if (pubsub_serializationProvider_alreadyAddedEntry(provider, serEntry)) { - L_WARN("Skipping entry %s. Exact entry already present!. Double event triggered?", serEntry->readFromEntryPath); - free(serEntry->descriptorContent); - free(serEntry->readFromEntryPath); - free(serEntry->msgVersionStr); - dynMessage_destroy(serEntry->msgType); - free(serEntry); - continue; - } - - bool unique = pubsub_serializationProvider_validateEntry(provider, serEntry); - if (unique && serEntry->valid) { //note only register if unique and valid - L_DEBUG("Adding message serialization entry for msg %s with id %d and version %s", serEntry->msgFqn, serEntry->msgId, serEntry->msgVersionStr); - pubsub_serializationProvider_registerSerializationEntry(provider, serEntry); - } - - celixThreadMutex_lock(&provider->mutex); - if (unique || !serEntry->valid) { //add all unique entries and ! invalid entries. The invalid entries are added to support debugging. - celix_arrayList_add(provider->serializationSvcEntries, serEntry); - } else { - free(serEntry->descriptorContent); - free(serEntry->readFromEntryPath); - free(serEntry->msgVersionStr); - dynMessage_destroy(serEntry->msgType); - free(serEntry); - } - celixThreadMutex_unlock(&provider->mutex); - } - - if (dir) { - closedir(dir); - } -} - -static void pubsub_serializationProvider_printEntryDetails(pubsub_serialization_provider_t* provider, FILE *outStream, pubsub_serialization_entry_t *entry) { - char *bndName = celix_bundleContext_getBundleSymbolicName(provider->ctx, entry->readFromBndId); - fprintf(outStream, "|- %20s = %s\n", "msg fqn", entry->msgFqn); - fprintf(outStream, "|- %20s = %d (0x8%x)\n", "msg id", entry->msgId, entry->msgId); - fprintf(outStream, "|- %20s = %s\n", "msg vesion", entry->msgVersionStr); - fprintf(outStream, "|- %20s = %li\n", "svc id", entry->svcId); - fprintf(outStream, "|- %20s = %s (bundle id %li)\n", "read from bundle", bndName, entry->readFromBndId); - fprintf(outStream, "|- %20s = %s\n", "bundle entry name", entry->readFromEntryPath); - fprintf(outStream, "|- %20s = %lu\n", "nr of times found", (long unsigned int) entry->nrOfTimesRead); - fprintf(outStream, "|- %20s = %s\n", "valid", entry->valid ? "true" : "false"); - if (!entry->valid) { - fprintf(outStream, "|- %20s = %s\n", "invalid reason", entry->invalidReason); - } - fprintf(outStream, "|- %20s:\n", "descriptor"); - fprintf(outStream, "%s\n", entry->descriptorContent); - free(bndName); -} - -bool pubsub_serializationProvider_executeCommand(void *handle, const char *commandLine , FILE *outStream, FILE *errorStream CELIX_UNUSED) { - pubsub_serialization_provider_t* provider = handle; - - bool verbose = false; - bool invalids = false; - unsigned int msgId = 0; - const char *msgFqn = NULL; - - //parse command line - char *line = celix_utils_strdup(commandLine); - char *lasts = NULL; - // skip first argument since this is the command - strtok_r(line," ", &lasts); - char* tok = strtok_r(NULL, " ", &lasts); - - if (tok != NULL && strncmp("invalids", tok, 32) == 0) { - invalids = true; - } else if (tok != NULL && strncmp("verbose", tok, 32) == 0) { - verbose = true; - } else if (tok != NULL) { - errno = 0; - msgId = strtol(tok, NULL, 10); - if (errno == EINVAL) { - msgId = 0; - msgFqn = tok; - } - } - - if (msgId != 0 || msgFqn != NULL) { - celixThreadMutex_lock(&provider->mutex); - bool match = false; - for (int i = 0; i < celix_arrayList_size(provider->serializationSvcEntries); ++i) { - pubsub_serialization_entry_t *entry = celix_arrayList_get(provider->serializationSvcEntries, i); - if (msgId != 0 && msgId == entry->msgId) { - match = true; - } else if (msgFqn != NULL && strncmp(msgFqn, entry->msgFqn, 1024*1024) == 0) { - match = true; - } - if (match) { - fprintf(outStream, "%s message serialization service info:\n", provider->serializationType); - pubsub_serializationProvider_printEntryDetails(provider, outStream, entry); - break; - } - } - celixThreadMutex_unlock(&provider->mutex); - } else { - celixThreadMutex_lock(&provider->mutex); - if (celix_arrayList_size(provider->serializationSvcEntries) == 0) { - fprintf(outStream, "No %s message serialization services available.\n", provider->serializationType); - } else if (invalids) { - fprintf(outStream, "%s invalid message serialization services: \n", provider->serializationType); - size_t count = 0; - for (int i = 0; i < celix_arrayList_size(provider->serializationSvcEntries); ++i) { - pubsub_serialization_entry_t *entry = celix_arrayList_get(provider->serializationSvcEntries, i); - if (!entry->valid) { - fprintf(outStream, "|- entry nr : %d\n", i + 1); - pubsub_serializationProvider_printEntryDetails(provider, outStream, entry); - fprintf(outStream, "\n"); - count++; - } - } - if (count == 0) { - fprintf(outStream, "No invalid message serialization entries found!\n"); - } - } else { - fprintf(outStream, "%s message serialization services: \n", provider->serializationType); - for (int i = 0; i < celix_arrayList_size(provider->serializationSvcEntries); ++i) { - pubsub_serialization_entry_t *entry = celix_arrayList_get(provider->serializationSvcEntries, i); - if (verbose) { - fprintf(outStream, "|- entry nr : %d\n", i + 1); - pubsub_serializationProvider_printEntryDetails(provider, outStream, entry); - fprintf(outStream, "\n"); - } else { - fprintf(outStream, "|- entry nr %02d: msg id=%d, msg fqn=%s, msg version = %s, valid = %s\n", i + 1, entry->msgId, entry->msgFqn, entry->msgVersionStr, entry->valid ? "true" : "false"); - } - } - } - celixThreadMutex_unlock(&provider->mutex); - } - - free(line); - return true; -} - -void pubsub_serializationProvider_onInstalledBundle(void *handle, const celix_bundle_t *bnd) { - pubsub_serialization_provider_t* provider = handle; - char *descriptorsDir = pubsub_getMessageDescriptorsDir(provider->ctx, bnd); - if (descriptorsDir != NULL) { - pubsub_serializationProvider_parseDescriptors(provider, descriptorsDir, celix_bundle_getId(bnd)); - free(descriptorsDir); - } -} - -pubsub_serialization_provider_t *pubsub_serializationProvider_create( - celix_bundle_context_t *ctx, - const char* serializationType, - bool backwardsCompatible, - long serializationServiceRanking, - celix_status_t (*serialize)(pubsub_serialization_entry_t* entry, const void* msg, struct iovec** output, size_t* outputIovLen), - void (*freeSerializeMsg)(pubsub_serialization_entry_t* entry, struct iovec* input, size_t inputIovLen), - celix_status_t (*deserialize)(pubsub_serialization_entry_t* entry, const struct iovec* input, size_t inputIovLen CELIX_UNUSED, void **out), - void (*freeDeserializeMsg)(pubsub_serialization_entry_t* entry, void *msg)) { - pubsub_serialization_provider_t* provider = calloc(1, sizeof(*provider)); - provider->ctx = ctx; - celixThreadMutex_create(&provider->mutex, NULL); - provider->serializationSvcEntries = celix_arrayList_create(); - - provider->serializationType = celix_utils_strdup(serializationType); - provider->serialize = serialize; - provider->freeSerializeMsg = freeSerializeMsg; - provider->deserialize = deserialize; - provider->freeDeserializeMsg = freeDeserializeMsg; - provider->logHelper = celix_logHelper_create(ctx, "celix_pubsub_serialization_provider"); - - dynFunction_logSetup(dfi_log, provider, 1); - dynType_logSetup(dfi_log, provider, 1); - dynCommon_logSetup(dfi_log, provider, 1); - - { - //Start bundle tracker and register pubsub_message_serialization services - celix_bundle_tracking_options_t opts = CELIX_EMPTY_BUNDLE_TRACKING_OPTIONS; - opts.callbackHandle = provider; - opts.onInstalled = pubsub_serializationProvider_onInstalledBundle; - opts.includeFrameworkBundle = true; - provider->bundleTrackerId = celix_bundleContext_trackBundlesWithOptions(ctx, &opts); - } - - { - //Register shell command to query serializers - provider->cmdSvc.handle = provider; - provider->cmdSvc.executeCommand = pubsub_serializationProvider_executeCommand; - - char *name = NULL; - asprintf(&name,"celix::%s_message_serialization", provider->serializationType); - char *usage = NULL; - asprintf(&usage,"celix::%s_message_serialization [verbose | invalids | | ]", provider->serializationType); - - celix_properties_t* props = celix_properties_create(); - provider->cmdSvc.handle = provider; - celix_properties_set(props, CELIX_SHELL_COMMAND_NAME, name); - celix_properties_set(props, CELIX_SHELL_COMMAND_USAGE, usage); - celix_properties_set(props, CELIX_SHELL_COMMAND_DESCRIPTION, "list available json message serialization services or provide detailed information about a serialization service."); - celix_service_registration_options_t opts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS; - opts.svc = &provider->cmdSvc; - opts.serviceName = CELIX_SHELL_COMMAND_SERVICE_NAME; - opts.serviceVersion = CELIX_SHELL_COMMAND_SERVICE_VERSION; - opts.properties = props; - provider->cmdSvcId = celix_bundleContext_registerServiceWithOptions(ctx, &opts); - - free(name); - free(usage); - } - - { - //Register pubsub_message_serialization_marker service to indicate the availability of this message serialization type. - celix_properties_t* props = celix_properties_create(); - provider->markerSvc.handle = provider; - celix_properties_set(props, PUBSUB_MESSAGE_SERIALIZATION_MARKER_SERIALIZATION_TYPE_PROPERTY, provider->serializationType); - celix_properties_setBool(props, PUBSUB_MESSAGE_SERIALIZATION_MARKER_SERIALIZATION_BACKWARDS_COMPATIBLE, backwardsCompatible); - celix_service_registration_options_t opts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS; - opts.svc = &provider->markerSvc; - opts.serviceName = PUBSUB_MESSAGE_SERIALIZATION_MARKER_NAME; - opts.serviceVersion = PUBSUB_MESSAGE_SERIALIZATION_MARKER_VERSION; - opts.properties = props; - provider->markerSvcId = celix_bundleContext_registerServiceWithOptions(ctx, &opts); - } - - return provider; -} - -void pubsub_serializationProvider_destroy(pubsub_serialization_provider_t* provider) { - if (provider != NULL) { - celix_bundleContext_unregisterService(provider->ctx, provider->markerSvcId); - - celix_bundleContext_stopTracker(provider->ctx, provider->bundleTrackerId); - celix_bundleContext_unregisterService(provider->ctx, provider->cmdSvcId); - - celixThreadMutex_lock(&provider->mutex); - for (int i = 0; i < celix_arrayList_size(provider->serializationSvcEntries); ++i) { - pubsub_serialization_entry_t *entry = celix_arrayList_get(provider->serializationSvcEntries, i); - celix_bundleContext_unregisterService(provider->ctx, entry->svcId); - if (entry->freeUserData) { - entry->freeUserData(entry->userData); - } - free(entry->descriptorContent); - free(entry->readFromEntryPath); - free(entry->msgVersionStr); - dynMessage_destroy(entry->msgType); - free(entry); - } - celix_arrayList_destroy(provider->serializationSvcEntries); - celixThreadMutex_unlock(&provider->mutex); - - celixThreadMutex_destroy(&provider->mutex); - - celix_logHelper_destroy(provider->logHelper); - - free(provider->serializationType); - free(provider); - } -} - -size_t pubsub_serializationProvider_nrOfEntries(pubsub_serialization_provider_t* provider) { - size_t count = 0; - celixThreadMutex_lock(&provider->mutex); - for (int i = 0; i < celix_arrayList_size(provider->serializationSvcEntries); ++i) { - pubsub_serialization_entry_t *entry = celix_arrayList_get(provider->serializationSvcEntries, i); - if (entry->valid) { - ++count; - } - } - celixThreadMutex_unlock(&provider->mutex); - return count; -} - -size_t pubsub_serializationProvider_nrOfInvalidEntries(pubsub_serialization_provider_t* provider) { - size_t count = 0; - celixThreadMutex_lock(&provider->mutex); - for (int i = 0; i < celix_arrayList_size(provider->serializationSvcEntries); ++i) { - pubsub_serialization_entry_t *entry = celix_arrayList_get(provider->serializationSvcEntries, i); - if (!entry->valid) { - ++count; - } - } - celixThreadMutex_unlock(&provider->mutex); - return count; -} - -celix_log_helper_t* pubsub_serializationProvider_getLogHelper(pubsub_serialization_provider_t *provider) { - return provider->logHelper; -} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_utils/src/pubsub_serializer_handler.c b/bundles/pubsub/pubsub_utils/src/pubsub_serializer_handler.c deleted file mode 100644 index 2515eb990..000000000 --- a/bundles/pubsub/pubsub_utils/src/pubsub_serializer_handler.c +++ /dev/null @@ -1,482 +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_handler.h" - -#include -#include - -#include "pubsub_message_serialization_marker.h" -#include "celix_version.h" -#include "pubsub_message_serialization_service.h" -#include "celix_log_helper.h" -#include "celix_compiler.h" -#include "celix_constants.h" -#include "celix_threads.h" -#include "celix_utils.h" - -#define L_DEBUG(...) \ - celix_logHelper_debug(handler->logHelper, __VA_ARGS__) -#define L_INFO(...) \ - celix_logHelper_info(handler->logHelper, __VA_ARGS__) -#define L_WARN(...) \ - celix_logHelper_warning(handler->logHelper, __VA_ARGS__) -#define L_ERROR(...) \ - celix_logHelper_error(handler->logHelper, __VA_ARGS__) - -typedef struct pubsub_serialization_service_entry { - long svcId; - const celix_properties_t *properties; - uint32_t msgId; - celix_version_t* msgVersion; - const char* msgFqn; - pubsub_message_serialization_service_t* svc; -} pubsub_serialization_service_entry_t; - -struct pubsub_serializer_handler { - celix_bundle_context_t* ctx; - char* filter; - char* serType; - bool backwardCompatible; - long serializationSvcTrackerId; - celix_log_helper_t *logHelper; - - celix_thread_rwlock_t lock; - hash_map_t *serializationServices; //key = msg id, value = sorted array list with pubsub_serialization_service_entry_t* - hash_map_t *msgFullyQualifiedNames; //key = msg id, value = msg fqn. Non destructive map with msg fqn -}; - -static void pubsub_serializerHandler_addSerializationService(pubsub_serializer_handler_t* handler, pubsub_message_serialization_service_t* svc, const celix_properties_t* svcProperties); -static void pubsub_serializerHandler_removeSerializationService(pubsub_serializer_handler_t* handler, pubsub_message_serialization_service_t* svc, const celix_properties_t* svcProperties); - -static void addSerializationService(void *handle, void* svc, const celix_properties_t *props) { - pubsub_serializer_handler_t* handler = handle; - pubsub_message_serialization_service_t* serSvc = svc; - pubsub_serializerHandler_addSerializationService(handler, serSvc, props); -} - -static void removeSerializationService(void *handle, void* svc, const celix_properties_t *props) { - pubsub_serializer_handler_t* handler = handle; - pubsub_message_serialization_service_t* serSvc = svc; - pubsub_serializerHandler_removeSerializationService(handler, serSvc, props); -} - -static int compareEntries(const void *a, const void *b) { - const pubsub_serialization_service_entry_t* aEntry = a; - const pubsub_serialization_service_entry_t* bEntry = b; - - long servIdA = celix_properties_getAsLong(aEntry->properties, CELIX_FRAMEWORK_SERVICE_ID, 0); - long servIdB = celix_properties_getAsLong(bEntry->properties, CELIX_FRAMEWORK_SERVICE_ID, 0); - - long servRankingA = celix_properties_getAsLong(aEntry->properties, CELIX_FRAMEWORK_SERVICE_RANKING, 0); - long servRankingB = celix_properties_getAsLong(bEntry->properties, CELIX_FRAMEWORK_SERVICE_RANKING, 0); - - return celix_utils_compareServiceIdsAndRanking(servIdA, servRankingA, servIdB, servRankingB); -} - -static pubsub_serialization_service_entry_t* findEntry(pubsub_serializer_handler_t* handler, uint32_t msgId) { - //NOTE assumes mutex is locked - celix_array_list_t* entries = hashMap_get(handler->serializationServices, (void*)(uintptr_t)msgId); - if (entries != NULL) { - return celix_arrayList_get(entries, 0); //NOTE if entries not null, always at least 1 entry - } - return NULL; -} - -static bool isCompatible(pubsub_serializer_handler_t* handler, pubsub_serialization_service_entry_t* entry, int serializedMajorVersion, int serializedMinorVersion) { - bool compatible = false; - if (handler->backwardCompatible) { - compatible = celix_version_isUserCompatible(entry->msgVersion, serializedMajorVersion, serializedMinorVersion); - } else { - compatible = celix_version_compareToMajorMinor(entry->msgVersion, serializedMajorVersion, serializedMinorVersion) == 0; - } - return compatible; -} - -pubsub_serializer_handler_t* pubsub_serializerHandler_create(celix_bundle_context_t* ctx, const char* serializerType, bool backwardCompatible) { - pubsub_serializer_handler_t* handler = calloc(1, sizeof(*handler)); - handler->ctx = ctx; - handler->serType = celix_utils_strdup(serializerType); - handler->backwardCompatible = backwardCompatible; - - handler->logHelper = celix_logHelper_create(ctx, "celix_pubsub_serialization_handler"); - - celixThreadRwlock_create(&handler->lock, NULL); - handler->serializationServices = hashMap_create(NULL, NULL, NULL, NULL); - handler->msgFullyQualifiedNames = hashMap_create(NULL, NULL, NULL, NULL); - - asprintf(&handler->filter, "(%s=%s)", PUBSUB_MESSAGE_SERIALIZATION_SERVICE_SERIALIZATION_TYPE_PROPERTY, serializerType); - celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; - opts.filter.serviceName = PUBSUB_MESSAGE_SERIALIZATION_SERVICE_NAME; - opts.filter.versionRange = PUBSUB_MESSAGE_SERIALIZATION_SERVICE_RANGE; - opts.filter.filter = handler->filter; - opts.callbackHandle = handler; - opts.addWithProperties = addSerializationService; - opts.removeWithProperties = removeSerializationService; - handler->serializationSvcTrackerId = celix_bundleContext_trackServicesWithOptionsAsync(ctx, &opts); - - - return handler; -} - -struct pubsub_serializerHandler_callback_data { - celix_bundle_context_t* ctx; - celix_log_helper_t* logHelper; - pubsub_serializer_handler_t* handler; -}; - -static void pubsub_serializerHandler_useMarkerSvcCallback(void *handle, void* svc CELIX_UNUSED, const celix_properties_t* props) { - struct pubsub_serializerHandler_callback_data* data = handle; - const char* serType = celix_properties_get(props, PUBSUB_MESSAGE_SERIALIZATION_MARKER_SERIALIZATION_TYPE_PROPERTY, NULL); - bool backwardsCompatible = celix_properties_getAsBool(props, PUBSUB_MESSAGE_SERIALIZATION_MARKER_SERIALIZATION_BACKWARDS_COMPATIBLE, false); - if (serType != NULL) { - data->handler = pubsub_serializerHandler_create(data->ctx, serType, backwardsCompatible); - } else if (data->logHelper != NULL) { - celix_logHelper_error( - data->logHelper, - "Cannot create serializer handler because service %s does not have a %s service property", - PUBSUB_MESSAGE_SERIALIZATION_MARKER_NAME, - PUBSUB_MESSAGE_SERIALIZATION_MARKER_SERIALIZATION_TYPE_PROPERTY); - } -} - -pubsub_serializer_handler_t* pubsub_serializerHandler_createForMarkerService(celix_bundle_context_t* ctx, long pubsubSerializerMarkerSvcId, celix_log_helper_t* logHelper) { - struct pubsub_serializerHandler_callback_data data; - memset(&data, 0, sizeof(data)); - data.ctx = ctx; - data.logHelper = logHelper; - - char filter[32]; - snprintf(filter, 32, "(%s=%li)", CELIX_FRAMEWORK_SERVICE_ID, pubsubSerializerMarkerSvcId); - celix_service_use_options_t opts = CELIX_EMPTY_SERVICE_USE_OPTIONS; - opts.filter.serviceName = PUBSUB_MESSAGE_SERIALIZATION_MARKER_NAME; - opts.filter.filter = filter; - opts.callbackHandle = &data; - opts.useWithProperties = pubsub_serializerHandler_useMarkerSvcCallback; - bool called = celix_bundleContext_useServiceWithOptions(ctx, &opts); - if (!called && logHelper != NULL) { - celix_logHelper_error( - logHelper, - "Cannot find %s service for service id %li", - PUBSUB_MESSAGE_SERIALIZATION_MARKER_NAME, - pubsubSerializerMarkerSvcId); - } - return data.handler; -} - -static void pubsub_serializerHandler_destroyCallback(void* data) { - pubsub_serializer_handler_t* handler = data; - celixThreadRwlock_destroy(&handler->lock); - hash_map_iterator_t iter = hashMapIterator_construct(handler->serializationServices); - while (hashMapIterator_hasNext(&iter)) { - celix_array_list_t *entries = hashMapIterator_nextValue(&iter); - for (int i = 0; i < celix_arrayList_size(entries); ++i) { - pubsub_serialization_service_entry_t* entry = celix_arrayList_get(entries, i); - celix_version_destroy(entry->msgVersion); - free(entry); - } - celix_arrayList_destroy(entries); - } - hashMap_destroy(handler->serializationServices, false, false); - hashMap_destroy(handler->msgFullyQualifiedNames, false, true); - celix_logHelper_destroy(handler->logHelper); - free(handler->serType); - free(handler->filter); - free(handler); -} - -void pubsub_serializerHandler_destroy(pubsub_serializer_handler_t* handler) { - if (handler != NULL) { - celix_bundleContext_stopTrackerAsync(handler->ctx, handler->serializationSvcTrackerId, handler, pubsub_serializerHandler_destroyCallback); - } -} - -void pubsub_serializerHandler_addSerializationService(pubsub_serializer_handler_t* handler, pubsub_message_serialization_service_t* svc, const celix_properties_t* svcProperties) { - long svcId = celix_properties_getAsLong(svcProperties, CELIX_FRAMEWORK_SERVICE_ID, -1L); - const char *msgFqn = celix_properties_get(svcProperties, PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_FQN_PROPERTY, NULL); - const char *version = celix_properties_get(svcProperties, PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_VERSION_PROPERTY, "0.0.0"); - uint32_t msgId = (uint32_t)celix_properties_getAsLong(svcProperties, PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_ID_PROPERTY, 0L); - - if (msgId == 0) { - msgId = celix_utils_stringHash(msgFqn); - } - - celix_version_t* msgVersion = celix_version_createVersionFromString(version); - if (msgVersion == NULL) { - L_ERROR("%s service has an invalid %s property. value is '%s'", PUBSUB_MESSAGE_SERIALIZATION_SERVICE_NAME, PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_VERSION_PROPERTY, version); - return; - } - - celixThreadRwlock_writeLock(&handler->lock); - - pubsub_serialization_service_entry_t* existingEntry = findEntry(handler, msgId); - - bool valid = true; - if (existingEntry != NULL && strncmp(existingEntry->msgFqn, msgFqn, 1024*1024) != 0) { - L_ERROR("Msg id clash. Registered serialization service with msg id %d and msg fqn '%s' clashes with an existing serialization service using the same msg id and msg fqn '%s'. Ignoring serialization service.", msgId, msgFqn, existingEntry->msgFqn); - valid = false; - } - - if (existingEntry != NULL && celix_version_compareTo(existingEntry->msgVersion, msgVersion) != 0) { - char* existingVersion = celix_version_toString(existingEntry->msgVersion); - L_ERROR("Mismatched message versions. Registered serialization service with msg '%s' with version %s, has a different version than an existing serialization service with version '%s'. Ignoring serialization service.", msgFqn, version, existingVersion); - free(existingVersion); - valid = false; - } - - if (valid) { - char* fqn = hashMap_get(handler->msgFullyQualifiedNames, (void*)(uintptr_t)msgId); - if (fqn == NULL) { - fqn = celix_utils_strdup(msgFqn); - hashMap_put(handler->msgFullyQualifiedNames, (void*)(uintptr_t)msgId, fqn); - } - - celix_array_list_t *entries = hashMap_get(handler->serializationServices, (void *) (uintptr_t) msgId); - if (entries == NULL) { - entries = celix_arrayList_create(); - } - pubsub_serialization_service_entry_t *entry = calloc(1, sizeof(*entry)); - entry->svcId = svcId; - entry->properties = svcProperties; - entry->msgFqn = fqn; - entry->msgId = msgId; - entry->msgVersion = msgVersion; - entry->svc = svc; - celix_arrayList_add(entries, entry); - celix_arrayList_sort(entries, compareEntries); - - hashMap_put(handler->serializationServices, (void*)(uintptr_t)msgId, entries); - } else { - celix_version_destroy(msgVersion); - } - - celixThreadRwlock_unlock(&handler->lock); -} - -void pubsub_serializerHandler_removeSerializationService(pubsub_serializer_handler_t* handler, pubsub_message_serialization_service_t* svc, const celix_properties_t* svcProperties) { - long svcId = celix_properties_getAsLong(svcProperties, CELIX_FRAMEWORK_SERVICE_ID, -1L); - const char *msgFqn = celix_properties_get(svcProperties, PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_FQN_PROPERTY, NULL); - uint32_t msgId = (uint32_t)celix_properties_getAsLong(svcProperties, PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_ID_PROPERTY, 0L); - if (msgId == 0) { - msgId = celix_utils_stringHash(msgFqn); - } - - celixThreadRwlock_writeLock(&handler->lock); - celix_array_list_t* entries = hashMap_get(handler->serializationServices, (void*)(uintptr_t)msgId); - if (entries != NULL) { - pubsub_serialization_service_entry_t *found = NULL; - for (int i = 0; i < celix_arrayList_size(entries); ++i) { - pubsub_serialization_service_entry_t *entry = celix_arrayList_get(entries, i); - if (entry->svcId == svcId) { - found = entry; - celix_arrayList_removeAt(entries, i); - celix_arrayList_sort(entries, compareEntries); - break; - } - } - if (found != NULL) { - celix_version_destroy(found->msgVersion); - free(found); - } - if (celix_arrayList_size(entries) == 0) { - hashMap_remove(handler->serializationServices, (void*)(uintptr_t)msgId); - celix_arrayList_destroy(entries); - } - } - celixThreadRwlock_unlock(&handler->lock); -} - -celix_status_t pubsub_serializerHandler_serialize(pubsub_serializer_handler_t* handler, uint32_t msgId, const void* input, struct iovec** output, size_t* outputIovLen) { - celix_status_t status; - celixThreadRwlock_readLock(&handler->lock); - pubsub_serialization_service_entry_t* entry = findEntry(handler, msgId); - if (entry != NULL) { - status = entry->svc->serialize(entry->svc->handle, input, output, outputIovLen); - } else { - status = CELIX_ILLEGAL_ARGUMENT; - L_ERROR("Cannot find message serialization service for msg id %u.", msgId); - } - celixThreadRwlock_unlock(&handler->lock); - return status; -} - -celix_status_t pubsub_serializerHandler_freeSerializedMsg(pubsub_serializer_handler_t* handler, uint32_t msgId, struct iovec* input, size_t inputIovLen) { - celix_status_t status = CELIX_SUCCESS; - if (input == NULL) { - return status; //silently ignore - } - celixThreadRwlock_readLock(&handler->lock); - pubsub_serialization_service_entry_t* entry = findEntry(handler, msgId); - if (entry != NULL) { - entry->svc->freeSerializedMsg(entry->svc->handle, input, inputIovLen); - } else { - status = CELIX_ILLEGAL_ARGUMENT; - L_ERROR("Cannot find message serialization service for msg id %u.", msgId); - } - celixThreadRwlock_unlock(&handler->lock); - return status; - -} - -celix_status_t pubsub_serializerHandler_deserialize(pubsub_serializer_handler_t* handler, uint32_t msgId, int serializedMajorVersion, int serializedMinorVersion, const struct iovec* input, size_t inputIovLen, void** out) { - celix_status_t status; - celixThreadRwlock_readLock(&handler->lock); - pubsub_serialization_service_entry_t* entry = findEntry(handler, msgId); - bool compatible = false; - if (entry != NULL) { - compatible = isCompatible(handler, entry, serializedMajorVersion, serializedMinorVersion); - if (compatible) { - status = entry->svc->deserialize(entry->svc->handle, input, inputIovLen, out); - } else { - status = CELIX_ILLEGAL_ARGUMENT; - char *version = celix_version_toString(entry->msgVersion); - L_ERROR("Cannot deserialize for message %s version %s. The serialized input has a version of %d.%d.x and this is incompatible.", entry->msgFqn, version, serializedMajorVersion, serializedMinorVersion); - free(version); - } - } else { - status = CELIX_ILLEGAL_ARGUMENT; - L_ERROR("Cannot find message serialization service for msg id %u.", msgId); - } - celixThreadRwlock_unlock(&handler->lock); - return status; -} - -celix_status_t pubsub_serializerHandler_freeDeserializedMsg(pubsub_serializer_handler_t* handler, uint32_t msgId, void* msg) { - celix_status_t status = CELIX_SUCCESS; - if (msg == NULL) { - return status; //silently ignore - } - celixThreadRwlock_readLock(&handler->lock); - pubsub_serialization_service_entry_t* entry = findEntry(handler, msgId); - if (entry != NULL) { - entry->svc->freeDeserializedMsg(entry->svc->handle, msg); - } else { - status = CELIX_ILLEGAL_ARGUMENT; - L_ERROR("Cannot find message serialization service for msg id %u.", msgId); - } - celixThreadRwlock_unlock(&handler->lock); - return status; -} - -bool pubsub_serializerHandler_isMessageSupported(pubsub_serializer_handler_t* handler, uint32_t msgId, int majorVersion, int minorVersion) { - celixThreadRwlock_readLock(&handler->lock); - bool compatible = false; - pubsub_serialization_service_entry_t* entry = findEntry(handler, msgId); - if (entry != NULL) { - compatible = isCompatible(handler, entry, majorVersion, minorVersion); - } - celixThreadRwlock_unlock(&handler->lock); - return compatible; -} - -bool pubsub_serializerHandler_isMessageSerializationServiceAvailable(pubsub_serializer_handler_t* handler, uint32_t msgId) { - celixThreadRwlock_readLock(&handler->lock); - void* entries = hashMap_get(handler->serializationServices, (void*)(uintptr_t)msgId); - celixThreadRwlock_unlock(&handler->lock); - return entries != NULL; -} - -const char* pubsub_serializerHandler_getMsgFqn(pubsub_serializer_handler_t* handler, uint32_t msgId) { - celixThreadRwlock_readLock(&handler->lock); - char *msgFqn = hashMap_get(handler->msgFullyQualifiedNames, (void*)(uintptr_t)msgId); - celixThreadRwlock_unlock(&handler->lock); - return msgFqn; -} - -uint32_t pubsub_serializerHandler_getMsgId(pubsub_serializer_handler_t* handler, const char* msgFqn) { - uint32_t result = 0; - celixThreadRwlock_readLock(&handler->lock); - hash_map_iterator_t iter = hashMapIterator_construct(handler->serializationServices); - while (hashMapIterator_hasNext(&iter) && result == 0) { - celix_array_list_t *entries = hashMapIterator_nextValue(&iter); - pubsub_serialization_service_entry_t* entry = celix_arrayList_get(entries, 0); //NOTE if an entries exists, there is at least 1 entry. - if (strncmp(entry->msgFqn, msgFqn, 1024*1024) == 0) { - result = entry->msgId; - } - } - celixThreadRwlock_unlock(&handler->lock); - return result; -} -int pubsub_serializerHandler_getMsgMajorVersion(pubsub_serializer_handler_t* handler, uint32_t msgId) { - celixThreadRwlock_readLock(&handler->lock); - int major = -1; - celix_array_list_t* entries = hashMap_get(handler->serializationServices, (void*)(uintptr_t)msgId); - if (entries != NULL) { - pubsub_serialization_service_entry_t *entry = celix_arrayList_get(entries, 0); //NOTE if an entries exists, there is at least 1 entry. - major = celix_version_getMajor(entry->msgVersion); - } - celixThreadRwlock_unlock(&handler->lock); - return major; -} - -int pubsub_serializerHandler_getMsgMinorVersion(pubsub_serializer_handler_t* handler, uint32_t msgId) { - celixThreadRwlock_readLock(&handler->lock); - int major = -1; - celix_array_list_t* entries = hashMap_get(handler->serializationServices, (void*)(uintptr_t)msgId); - if (entries != NULL) { - pubsub_serialization_service_entry_t *entry = celix_arrayList_get(entries, 0); //NOTE if an entries exists, there is at least 1 entry. - major = celix_version_getMinor(entry->msgVersion); - } - celixThreadRwlock_unlock(&handler->lock); - return major; -} - -size_t pubsub_serializerHandler_messageSerializationServiceCount(pubsub_serializer_handler_t* handler) { - size_t count = 0; - celixThreadRwlock_readLock(&handler->lock); - hash_map_iterator_t iter = hashMapIterator_construct(handler->serializationServices); - while (hashMapIterator_hasNext(&iter)) { - celix_array_list_t *entries = hashMapIterator_nextValue(&iter); - count += celix_arrayList_size(entries); - } - celixThreadRwlock_unlock(&handler->lock); - return count; -} - -const char* pubsub_serializerHandler_getSerializationType(pubsub_serializer_handler_t* handler) { - return handler->serType; -} - -int pubsub_serializerHandler_getMsgInfo( - pubsub_serializer_handler_t* handler, - uint32_t msgId, - const char** msgFqnOut, - int* msgMajorVersionOut, - int* msgMinorVersionOut) { - int result = CELIX_SUCCESS; - celixThreadRwlock_readLock(&handler->lock); - celix_array_list_t* entries = hashMap_get(handler->serializationServices, (void*)(uintptr_t)msgId); - if (entries != NULL) { - pubsub_serialization_service_entry_t *entry = celix_arrayList_get(entries, 0); //NOTE if an entries exists, there is at least 1 entry. - if (msgFqnOut != NULL) { - *msgFqnOut = entry->msgFqn; - } - if (msgMajorVersionOut != NULL) { - *msgMajorVersionOut = celix_version_getMajor(entry->msgVersion); - } - if (msgMinorVersionOut != NULL) { - *msgMinorVersionOut = celix_version_getMinor(entry->msgVersion); - } - } else { - result = CELIX_ILLEGAL_ARGUMENT; - } - celixThreadRwlock_unlock(&handler->lock); - return result; -} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_utils/src/pubsub_utils.c b/bundles/pubsub/pubsub_utils/src/pubsub_utils.c deleted file mode 100644 index a2cc2a261..000000000 --- a/bundles/pubsub/pubsub_utils/src/pubsub_utils.c +++ /dev/null @@ -1,198 +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 -#include - -#include "celix_constants.h" -#include "celix_filter.h" -#include "filter.h" - -#include "pubsub/publisher.h" -#include "pubsub_utils.h" -#include "bundle_context.h" - -#include "array_list.h" -#include "celix_bundle.h" - -#include -#include -#include - -#include -#include "celix_utils.h" - -#define MAX_KEYBUNDLE_LENGTH 256 - -/** - * The config/env options to set the extender path which is used to find - * descriptors if the requesting bundle is the framework bundle. - */ -#define SYSTEM_BUNDLE_ARCHIVE_PATH "CELIX_FRAMEWORK_EXTENDER_PATH" - - -celix_status_t pubsub_getPubSubInfoFromFilter(const char* filterstr, char **scopeOut, char **topicOut) { - celix_status_t status = CELIX_SUCCESS; - const char *scope = NULL; - const char *topic = NULL; - const char *objectClass = NULL; - celix_autoptr(celix_filter_t) filter = celix_filter_create(filterstr); - scope = celix_filter_findAttribute(filter, PUBSUB_PUBLISHER_SCOPE); - topic = celix_filter_findAttribute(filter, PUBSUB_PUBLISHER_TOPIC); - objectClass = celix_filter_findAttribute(filter, CELIX_FRAMEWORK_SERVICE_NAME); - - if (topic != NULL && objectClass != NULL && strncmp(objectClass, PUBSUB_PUBLISHER_SERVICE_NAME, 128) == 0) { - //NOTE topic must be present, scope can be present in the filter - *topicOut = celix_utils_strdup(topic); - if (scope != NULL) { - if (strncmp("*", scope, 2) == 0) { - //if scope attribute is present with a *, assume this is a negative test e.g. (&(topic=foo)(!(scope=*))) - *scopeOut = NULL; - } else { - *scopeOut = celix_utils_strdup(scope); - } - } else { - *scopeOut = NULL; - } - } else { - *topicOut = NULL; - *scopeOut = NULL; - } - - return status; -} - - -/** - * Loop through all bundles and look for the bundle with the keys inside. - * If no key bundle found, return NULL - * - * Caller is responsible for freeing the object - */ -char* pubsub_getKeysBundleDir(celix_bundle_context_t *ctx) { - array_list_pt bundles = NULL; - bundleContext_getBundles(ctx, &bundles); - uint32_t nrOfBundles = arrayList_size(bundles); - long bundle_id = -1; - char* result = NULL; - - for (int i = 0; i < nrOfBundles; i++) { - celix_bundle_t *b = arrayList_get(bundles, i); - - /* Skip bundle 0 (framework bundle) since it has no path nor revisions */ - bundle_getBundleId(b, &bundle_id); - if (bundle_id == 0) { - continue; - } - - char* dir = NULL; - bundle_getEntry(b, ".", &dir); - - char cert_dir[MAX_KEYBUNDLE_LENGTH]; - snprintf(cert_dir, MAX_KEYBUNDLE_LENGTH, "%s/META-INF/keys", dir); - - struct stat s; - int err = stat(cert_dir, &s); - if (err != -1) { - if (S_ISDIR(s.st_mode)) { - result = dir; - break; - } - } - - free(dir); - } - - arrayList_destroy(bundles); - - return result; -} - -celix_properties_t *pubsub_utils_getTopicProperties(const celix_bundle_t *bundle, const char *scope, const char *topic, bool isPublisher) { - celix_properties_t *topic_props = NULL; - - bool isSystemBundle = false; - bundle_isSystemBundle((celix_bundle_t *)bundle, &isSystemBundle); - long bundleId = -1; - bundle_isSystemBundle((celix_bundle_t *)bundle, &isSystemBundle); - bundle_getBundleId((celix_bundle_t *)bundle,&bundleId); - - if (isSystemBundle == false) { - char *bundleRoot = NULL; - char *topicPropertiesPath = NULL; - bundle_getEntry((celix_bundle_t *)bundle, ".", &bundleRoot); - - if (bundleRoot != NULL) { - if (scope) { - asprintf(&topicPropertiesPath, "%s/META-INF/topics/%s/%s.%s.properties", bundleRoot, isPublisher? "pub":"sub", scope, topic); - topic_props = celix_properties_load(topicPropertiesPath); - } - - if (topic_props == NULL) { - free(topicPropertiesPath); - asprintf(&topicPropertiesPath, "%s/META-INF/topics/%s/%s.properties", bundleRoot, isPublisher ? "pub" : "sub", topic); - topic_props = celix_properties_load(topicPropertiesPath); - } - free(topicPropertiesPath); - free(bundleRoot); - } - } - - return topic_props; -} - -unsigned int pubsub_msgIdHashFromFqn(const char* fqn) { - return celix_utils_stringHash(fqn); -} - -char* pubsub_getMessageDescriptorsDir(celix_bundle_context_t* ctx, const celix_bundle_t *bnd) { - char *root = NULL; - - bool isSystemBundle = celix_bundle_isSystemBundle(bnd); - bundle_isSystemBundle(bnd, &isSystemBundle); - - if (isSystemBundle == true) { - - const char *dir = celix_bundleContext_getProperty(ctx, SYSTEM_BUNDLE_ARCHIVE_PATH, NULL); - //asprintf(&root, "%s/META-INF/descriptors", dir); - struct stat s; - if (dir && stat(dir, &s) == 0) { - //file does exist - root = celix_utils_strdup(dir); - } - } else { - root = celix_bundle_getEntry(bnd, "META-INF/descriptors"); - } - return root; -} - -const char* pubsub_getEnvironmentVariableWithScopeTopic(celix_bundle_context_t* ctx, const char *key, const char *topic, const char *scope) { - char *combinedKey = malloc(512 * 1024); - memset(combinedKey, 0, 512 * 1024); - strncpy(combinedKey, key, 512 * 1024); - strncat(combinedKey, topic, 256 * 1024 - 25); - if(scope != NULL) { - strncat(combinedKey, "_", 1); - strncat(combinedKey, scope, 256 * 1024 - 25); - } - - const char *ret = celix_bundleContext_getProperty(ctx, combinedKey, NULL); - free(combinedKey); - return ret; -} \ No newline at end of file diff --git a/bundles/pubsub/pubsub_utils/src/pubsub_utils_url.c b/bundles/pubsub/pubsub_utils/src/pubsub_utils_url.c deleted file mode 100644 index 65a1ff2ce..000000000 --- a/bundles/pubsub/pubsub_utils/src/pubsub_utils_url.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -/** - * pubsub_utils_url.c - * - * \date Jun 24, 2019 - * \author Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "pubsub_utils_url.h" -#include - -unsigned int pubsub_utils_url_rand_range(unsigned int min, unsigned int max) { - if (!min || !max) - return 0; - double scaled = ((double) random()) / ((double) RAND_MAX); - return (unsigned int) ((max - min + 1) * scaled + min); -} - -struct sockaddr_in *pubsub_utils_url_from_fd(int fd) { - socklen_t len = sizeof(struct sockaddr_in); - struct sockaddr_in *inp = malloc(sizeof(struct sockaddr_in)); - bzero(inp, len); // zero the struct - int rc = getsockname(fd, (struct sockaddr *) inp, &len); - if (rc < 0) { - free(inp); - inp = NULL; - } - return inp; -} - -struct sockaddr_in *pubsub_utils_url_getInAddr(const char *hostname, unsigned int port) { - struct hostent *hp; - struct sockaddr_in *inp = malloc(sizeof(struct sockaddr_in)); - bzero(inp, sizeof(struct sockaddr_in)); // zero the struct - if (hostname == 0 || hostname[0] == 0) { - inp->sin_addr.s_addr = INADDR_ANY; - } else { - if (!inet_aton(hostname, &inp->sin_addr)) { - hp = gethostbyname(hostname); - if (hp == NULL) { - fprintf(stderr, "pubsub_utils_url_getInAddr: Unknown host name %s, %s\n", hostname, strerror(errno)); - errno = 0; - free(inp); - return NULL; - } - inp->sin_addr = *(struct in_addr *) hp->h_addr; - } - } - inp->sin_family = AF_INET; - inp->sin_port = htons(port); - return inp; -} - -char *pubsub_utils_url_generate_url(char *hostname, unsigned int portnr, char *protocol) { - char *url = NULL; - if (protocol) { - if (portnr) { - asprintf(&url, "%s://%s:%u", protocol, hostname, portnr); - } else { - asprintf(&url, "%s://%s", protocol, hostname); - } - } else { - if (portnr) { - asprintf(&url, "%s:%u", hostname, portnr); - } else { - asprintf(&url, "%s", hostname); - } - } - return url; -} - -char *pubsub_utils_url_get_url(struct sockaddr_in *inp, char *protocol) { - char *url = NULL; - if (inp == NULL) - return url; - char host[NI_MAXHOST]; - char service[NI_MAXSERV]; - if ((getnameinfo((struct sockaddr *) inp, sizeof(struct sockaddr_in), host, NI_MAXHOST, service, NI_MAXSERV, - NI_NUMERICHOST) == 0) && (inp->sin_family == AF_INET)) { //NI_NUMERICSERV - unsigned int portnr = ntohs(inp->sin_port); - url = pubsub_utils_url_generate_url(host, portnr, protocol); - } - return url; -} - -bool pubsub_utils_url_is_multicast(char *hostname) { - return (ntohl(inet_addr(hostname)) >= ntohl(inet_addr("224.0.0.0"))) ? true : false; -} - -/** Finds an IP of the available network interfaces of the machine by specifying an CIDR subnet. - * - * @param ipWithPrefix IP with prefix, e.g. 192.168.1.0/24 - * @return ip In case a matching interface could be found, an allocated string containing the IP of the - * interface will be returned, e.g. 192.168.1.16. Memory for the new string can be freed with free(). - * When no matching interface is found NULL will be returned. - */ -char *pubsub_utils_url_get_multicast_ip(char *hostname) { - char *ip = NULL; - if (hostname) { - char *subNet = strchr(hostname, '/'); - if (subNet != NULL) { - unsigned int length = strlen(subNet); - if ((length <= 1) || isalpha(subNet[1])) - return ip; - char *input = strndup(hostname, 19); // Make a copy as otherwise strtok_r manipulates the input string - char *savePtr; - char *inputIp = strtok_r(input, "/", &savePtr); - char *inputPrefixStr = strtok_r(NULL, "\0", &savePtr); - unsigned int inputPrefix = (unsigned int) strtoul(inputPrefixStr, NULL, 10); - - struct sockaddr_in address; - address.sin_family = AF_INET; - address.sin_port = 0; - if (!inet_aton(inputIp, &address.sin_addr)) - return NULL; - unsigned int ipAsUint = ntohl(address.sin_addr.s_addr); - unsigned int bitmask = ipUtils_prefixToBitmask(inputPrefix); - unsigned int ipRangeStart = ipAsUint & bitmask; - unsigned int ipRangeStop = ipAsUint | ~bitmask; - unsigned int addr = pubsub_utils_url_rand_range(ipRangeStart, ipRangeStop); - address.sin_addr.s_addr = htonl(addr); - ip = pubsub_utils_url_get_url(&address, NULL); - } - } - return ip; -} - -char *pubsub_utils_url_get_ip(char *_hostname) { - char *ip = NULL; - if (_hostname) { - char *subNet = strstr(_hostname, "/"); - char *hostname = strtok(celix_utils_strdup(_hostname), "/"); - if (subNet != NULL) { - unsigned int length = strlen(subNet); - if ((length > 1) && isdigit(subNet[1])) { - bool is_multicast = pubsub_utils_url_is_multicast(hostname); - if (is_multicast) - ip = pubsub_utils_url_get_multicast_ip(_hostname); - else - ip = ipUtils_findIpBySubnet(_hostname); - if (ip == NULL) - fprintf(stderr, "Could not find interface for requested subnet %s\n", _hostname); - } - } - free(hostname); - } - return ip; -} - -void pubsub_utils_url_parse_url(char *_url, pubsub_utils_url_t *url_info) { - if (!_url || !url_info) - return; - char *url_copy = celix_utils_strdup(_url); - char *url = strstr(url_copy, "://"); - if (url) { - if (!url_info->protocol) - url_info->protocol = strtok(strdup(url_copy), "://"); - url += 3; - } else { - url = url_copy; - } - char *interface = NULL; - char *hostname = NULL; - unsigned int length = strlen(url); - if (url[0] == ';') { - *url++ = '\0'; - hostname = celix_utils_strdup(url); - } else if ((url[0] == '/') && ((length > 1) && (isalpha(url[1])))) { - if (!url_info->uri) - url_info->uri = celix_utils_strdup(url); - } else { - interface = strstr(url, ";"); - if (!interface) { - interface = strstr(url, "@"); - hostname = strtok(celix_utils_strdup(url), "@"); - } - if (!hostname) - hostname = strtok(celix_utils_strdup(url), ";"); - } - - if (hostname) { - // Get port number - char *port = strstr(hostname, ":"); - if (!url_info->hostname) - url_info->hostname = strtok(celix_utils_strdup(hostname), ":"); - char *uri = strstr(url_info->hostname, "/"); - if (port) { - port += 1; - char *portnr = strtok(celix_utils_strdup(port), "-"); - char *maxPortnr = strstr(port, "-"); - if (maxPortnr) { - maxPortnr += 1; - unsigned int minDigits = (unsigned int) atoi(portnr); - unsigned int maxDigits = (unsigned int) atoi(maxPortnr); - url_info->port_nr = pubsub_utils_url_rand_range(minDigits, maxDigits); - } else { - unsigned int portDigits = (unsigned int) atoi(portnr); - if (portDigits != 0) - url_info->port_nr = portDigits; - uri = strstr(port, "/"); - if ((uri) && (!url_info->uri)) - url_info->uri = celix_utils_strdup(uri); - } - if (portnr) - free(portnr); - } else if (uri) { - length = strlen(uri); - if ((length > 1) && isalpha(uri[1]) && (!url_info->uri)) { - url_info->uri = celix_utils_strdup(uri); - *uri = '\0'; - } - } - free(hostname); - } - - if (interface) { - *interface++ = '0'; - // Get port number - char *port = strstr(interface, ":"); - if (!url_info->interface) - url_info->interface = strtok(celix_utils_strdup(interface), ":"); - char *uri = strstr(url_info->interface, "/"); - if (port) { - port += 1; - char *portnr = strtok(celix_utils_strdup(port), "-"); - char *maxPortnr = strstr(port, "-"); - if (maxPortnr) { - maxPortnr += 1; - unsigned int minDigits = (unsigned int) atoi(portnr); - unsigned int maxDigits = (unsigned int) atoi(maxPortnr); - url_info->interface_port_nr = pubsub_utils_url_rand_range(minDigits, maxDigits); - } else { - unsigned int portDigits = (unsigned int) atoi(portnr); - if (portDigits != 0) - url_info->interface_port_nr = portDigits; - uri = strstr(port, "/"); - if ((uri) && (!url_info->uri)) - url_info->uri = celix_utils_strdup(uri); - } - if (portnr) - free(portnr); - } else if (uri) { - length = strlen(uri); - if ((length > 1) && isalpha(uri[1]) && (!url_info->uri)) { - url_info->uri = celix_utils_strdup(uri); - *uri = '\0'; - } - } - } - free(url_copy); -} - -pubsub_utils_url_t *pubsub_utils_url_parse(char *url) { - pubsub_utils_url_t *url_info = calloc(1, sizeof(pubsub_utils_url_t)); - pubsub_utils_url_parse_url(url, url_info); - if (url_info->interface) { - pubsub_utils_url_t interface_url_info; - bzero(&interface_url_info, sizeof(pubsub_utils_url_t)); - char *ip = pubsub_utils_url_get_ip(url_info->interface); - if (ip != NULL) { - free(url_info->interface); - url_info->interface = ip; - } - struct sockaddr_in *m_sin = pubsub_utils_url_getInAddr(url_info->interface, url_info->interface_port_nr); - url_info->interface_url = pubsub_utils_url_get_url(m_sin, NULL); - free(m_sin); - pubsub_utils_url_parse_url(url_info->interface_url, &interface_url_info); - free(url_info->interface); - url_info->interface = interface_url_info.hostname; - url_info->interface_port_nr = interface_url_info.port_nr; - } - - if (url_info->hostname) { - if (url_info->url) - free(url_info->url); - char *ip = pubsub_utils_url_get_ip(url_info->hostname); - if (ip != NULL) { - free(url_info->hostname); - url_info->hostname = ip; - } - struct sockaddr_in *sin = pubsub_utils_url_getInAddr(url_info->hostname, url_info->port_nr); - url_info->url = pubsub_utils_url_get_url(sin, url_info->protocol); - free(url_info->hostname); - free(sin); - url_info->port_nr = 0; - url_info->hostname = NULL; - pubsub_utils_url_parse_url(url_info->url, url_info); - } - return url_info; -} - -void pubsub_utils_url_free(pubsub_utils_url_t *url_info) { - if (!url_info) - return; - if (url_info->hostname) - free(url_info->hostname); - if (url_info->protocol) - free(url_info->protocol); - if (url_info->interface) - free(url_info->interface); - if (url_info->url) - free(url_info->url); - if (url_info->interface_url) - free(url_info->interface_url); - if (url_info->uri) - free(url_info->uri); - url_info->url = NULL; - url_info->interface_url = NULL; - url_info->uri = NULL; - url_info->hostname = NULL; - url_info->protocol = NULL; - url_info->interface = NULL; - url_info->port_nr = 0; - url_info->interface_port_nr = 0; - free(url_info); -} diff --git a/examples/conan_test_package/CMakeLists.txt b/examples/conan_test_package/CMakeLists.txt index 13132c31b..b2573b5cc 100644 --- a/examples/conan_test_package/CMakeLists.txt +++ b/examples/conan_test_package/CMakeLists.txt @@ -69,88 +69,6 @@ if (TEST_SYSLOG_WRITER) celix_container_bundles(use_syslog_writer LEVEL 2 hello) endif () -option(TEST_PUBSUB "Test PubSub" OFF) -if (TEST_PUBSUB) - add_celix_bundle(my_pubsub_admin - SOURCES - my_psa_activator.c - ) - target_link_libraries(my_pubsub_admin PRIVATE Celix::framework Celix::dfi Celix::log_helper Celix::utils) - target_link_libraries(my_pubsub_admin PRIVATE Celix::pubsub_spi Celix::pubsub_utils ) - add_celix_container(use_my_psa - BUNDLES - Celix::celix_pubsub_topology_manager - my_pubsub_admin - hello - PROPERTIES - PUBSUB_TOPOLOGY_MANAGER_VERBOSE=true - ) -endif () - -option(TEST_PSA_ZMQ "Test ZeroMQ PubSub Admin" OFF) -if (TEST_PSA_ZMQ) - add_celix_container(use_psa_zmq - BUNDLES - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_zmq - hello - PROPERTIES - PUBSUB_TOPOLOGY_MANAGER_VERBOSE=true - ) -endif () - -option(TEST_PSA_TCP "Test TCP PubSub Admin" OFF) -if (TEST_PSA_TCP) - add_celix_container(use_psa_tcp - BUNDLES - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_tcp - hello - PROPERTIES - PSA_TCP_VERBOSE=true - PUBSUB_TOPOLOGY_MANAGER_VERBOSE=true - ) -endif () - -option(TEST_PSA_WS "Test WebSocket PubSub Admin" OFF) -if (TEST_PSA_WS) - add_celix_container(use_psa_ws - BUNDLES - Celix::http_admin - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_websocket - hello - PROPERTIES - PUBSUB_TOPOLOGY_MANAGER_VERBOSE=true - ) -endif () - -option(TEST_PSA_DISCOVERY_ETCD "Test the PubSub Discovery (ETCD) bundle" OFF) -if (TEST_PSA_DISCOVERY_ETCD) - add_celix_container(build_psa_discovery_etcd - BUNDLES - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_discovery_etcd - my_pubsub_admin - hello - PROPERTIES - PUBSUB_TOPOLOGY_MANAGER_VERBOSE=true - ) - if (TEST_LAUNCHER) - add_celix_container(use_psa_discovery_etcd - LAUNCHER Celix::launcher - BUNDLES - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_discovery_etcd - my_pubsub_admin - hello - USE_CONFIG - PROPERTIES - PUBSUB_TOPOLOGY_MANAGER_VERBOSE=true - ) - endif () -endif () - option(TEST_RSA "Test Remote Service Admin" OFF) if (TEST_RSA) add_celix_bundle(my_rsa diff --git a/examples/conan_test_package/my_psa_activator.c b/examples/conan_test_package/my_psa_activator.c deleted file mode 100644 index abc44ec43..000000000 --- a/examples/conan_test_package/my_psa_activator.c +++ /dev/null @@ -1,154 +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 -#include -#include -#include -#include -#include - -typedef struct my_psa_activator { - celix_log_helper_t *logHelper; - pubsub_admin_service_t adminService; - long adminSvcId; -} my_psa_activator_t; - - -static celix_status_t matchPublisher(void *handle, long svcRequesterBndId, - const celix_filter_t *svcFilter, celix_properties_t **outTopicProperties, - double *outScore, long *outSerializerSvcId, long *outProtocolSvcId) { - (void)handle; - (void)svcRequesterBndId; - (void)svcFilter; - (void)outTopicProperties; - (void)outScore; - (void)outSerializerSvcId; - (void)outProtocolSvcId; - return CELIX_SUCCESS; -} - -static celix_status_t matchSubscriber(void *handle, long svcProviderBndId, - const celix_properties_t *svcProperties, celix_properties_t **outTopicProperties, - double *outScore, long *outSerializerSvcId, long *outProtocolSvcId) { - (void)handle; - (void)svcProviderBndId; - (void)svcProperties; - (void)outTopicProperties; - (void)outScore; - (void)outSerializerSvcId; - (void)outProtocolSvcId; - return CELIX_SUCCESS; - -} - -static celix_status_t matchDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint, bool *match) { - (void)handle; - (void)endpoint; - (void)match; - return CELIX_SUCCESS; -} - -static celix_status_t setupTopicSender(void *handle, const char *scope, const char *topic, - const celix_properties_t *topicProperties, long serializerSvcId, long protocolSvcId, - celix_properties_t **publisherEndpoint) { - (void)handle; - (void)scope; - (void)topic; - (void)topicProperties; - (void)serializerSvcId; - (void)protocolSvcId; - (void)publisherEndpoint; - return CELIX_SUCCESS; -} - -static celix_status_t teardownTopicSender(void *handle, const char *scope, const char *topic) { - (void)handle; - (void)scope; - (void)topic; - return CELIX_SUCCESS; -} - -static celix_status_t setupTopicReceiver(void *handle, const char *scope, const char *topic, - const celix_properties_t *topicProperties, long serializerSvcId, long protocolSvcId, - celix_properties_t **subscriberEndpoint) { - (void)handle; - (void)scope; - (void)topic; - (void)topicProperties; - (void)serializerSvcId; - (void)protocolSvcId; - (void)subscriberEndpoint; - return CELIX_SUCCESS; -} - -static celix_status_t teardownTopicReceiver(void *handle, const char *scope, const char *topic) { - (void)handle; - (void)scope; - (void)topic; - return CELIX_SUCCESS; -} - -static celix_status_t addDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint) { - (void)handle; - (void)endpoint; - return CELIX_SUCCESS; -} - -static celix_status_t removeDiscoveredEndpoint(void *handle, const celix_properties_t *endpoint) { - (void)handle; - (void)endpoint; - return CELIX_SUCCESS; -} - -int psa_udpmc_start(my_psa_activator_t *act, celix_bundle_context_t *ctx) { - act->adminSvcId = -1L; - act->logHelper = celix_logHelper_create(ctx, "my_psa_admin"); - celix_status_t status = CELIX_SUCCESS; - - //register pubsub admin service - if (status == CELIX_SUCCESS) { - pubsub_admin_service_t *psaSvc = &act->adminService; - psaSvc->handle = act; - psaSvc->matchPublisher = matchPublisher; - psaSvc->matchSubscriber = matchSubscriber; - psaSvc->matchDiscoveredEndpoint = matchDiscoveredEndpoint; - psaSvc->setupTopicSender = setupTopicSender; - psaSvc->teardownTopicSender = teardownTopicSender; - psaSvc->setupTopicReceiver = setupTopicReceiver; - psaSvc->teardownTopicReceiver = teardownTopicReceiver; - psaSvc->addDiscoveredEndpoint = addDiscoveredEndpoint; - psaSvc->removeDiscoveredEndpoint = removeDiscoveredEndpoint; - - celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, PUBSUB_ADMIN_SERVICE_TYPE, "my_psa"); - - act->adminSvcId = celix_bundleContext_registerService(ctx, psaSvc, PUBSUB_ADMIN_SERVICE_NAME, props); - } - - return status; -} - -int psa_udpmc_stop(my_psa_activator_t *act, celix_bundle_context_t *ctx) { - celix_bundleContext_unregisterService(ctx, act->adminSvcId); - celix_logHelper_destroy(act->logHelper); - return CELIX_SUCCESS; -} - -CELIX_GEN_BUNDLE_ACTIVATOR(my_psa_activator_t, psa_udpmc_start, psa_udpmc_stop); diff --git a/libs/pushstreams/api/celix/PushStream.h b/libs/pushstreams/api/celix/PushStream.h index cce54af16..15d3ab148 100644 --- a/libs/pushstreams/api/celix/PushStream.h +++ b/libs/pushstreams/api/celix/PushStream.h @@ -66,7 +66,7 @@ namespace celix { * @param func The action to perform * @return promise that is resolved when the channel closes */ - [[nodiscard]] Promise forEach(ForEachFunction func); + [[maybe_unused]] Promise forEach(ForEachFunction func); /** * @brief only pass events downstream when the predicate tests true. From 54e60db6e124402a2f6ec0aa6ae4a193551a97ca Mon Sep 17 00:00:00 2001 From: Pepijn Noltes Date: Sun, 3 Dec 2023 22:49:23 +0100 Subject: [PATCH 2/6] Re-enable cxx integration test, now using IPC MQ --- .../integration/CMakeLists.txt | 6 +++--- .../integration/gtest/CMakeLists.txt | 15 --------------- .../src/RemoteServicesIntegrationTestSuite.cc | 13 ------------- 3 files changed, 3 insertions(+), 31 deletions(-) diff --git a/bundles/cxx_remote_services/integration/CMakeLists.txt b/bundles/cxx_remote_services/integration/CMakeLists.txt index b19715fc2..bad01c2d0 100644 --- a/bundles/cxx_remote_services/integration/CMakeLists.txt +++ b/bundles/cxx_remote_services/integration/CMakeLists.txt @@ -36,9 +36,9 @@ if (CXX_RSA_INTEGRATION) target_link_libraries(CalculatorConsumer PRIVATE Celix::Promises Celix::PushStreams Celix::shell_api Celix::RsaConfiguredDiscovery_api) target_include_directories(CalculatorConsumer PRIVATE include) -# if (ENABLE_TESTING) -# add_subdirectory(gtest) -# endif() + if (ENABLE_TESTING) + add_subdirectory(gtest) + endif() ################# Integration examples ################################## diff --git a/bundles/cxx_remote_services/integration/gtest/CMakeLists.txt b/bundles/cxx_remote_services/integration/gtest/CMakeLists.txt index 25572ed58..aead02992 100644 --- a/bundles/cxx_remote_services/integration/gtest/CMakeLists.txt +++ b/bundles/cxx_remote_services/integration/gtest/CMakeLists.txt @@ -22,10 +22,6 @@ target_link_libraries(test_cxx_remote_services_integration PRIVATE Celix::framew target_include_directories(test_cxx_remote_services_integration PRIVATE ../include) #Add ICalculator add_celix_bundle_dependencies(test_cxx_remote_services_integration - Celix::celix_pubsub_serializer_json - Celix::celix_pubsub_topology_manager - Celix::celix_pubsub_admin_zmq - Celix::celix_pubsub_protocol_wire_v2 Celix::RsaConfiguredDiscovery Celix::RemoteServiceAdmin TestExportImportRemoteServiceFactory @@ -33,17 +29,6 @@ add_celix_bundle_dependencies(test_cxx_remote_services_integration CalculatorConsumer ) -celix_get_bundle_file(Celix::celix_pubsub_serializer_json PS_SER_BUNDLE_LOC) -target_compile_definitions(test_cxx_remote_services_integration PRIVATE PS_SER_BUNDLE_LOC="${PS_SER_BUNDLE_LOC}") - -celix_get_bundle_file(Celix::celix_pubsub_topology_manager PS_PSTM_BUNDLE_LOC) -target_compile_definitions(test_cxx_remote_services_integration PRIVATE PS_PSTM_BUNDLE_LOC="${PS_PSTM_BUNDLE_LOC}") - -celix_get_bundle_file(Celix::celix_pubsub_admin_zmq PS_PSA_BUNDLE_LOC) -target_compile_definitions(test_cxx_remote_services_integration PRIVATE PS_PSA_BUNDLE_LOC="${PS_PSA_BUNDLE_LOC}") - -celix_get_bundle_file(Celix::celix_pubsub_protocol_wire_v2 PS_WIRE_BUNDLE_LOC) -target_compile_definitions(test_cxx_remote_services_integration PRIVATE PS_WIRE_BUNDLE_LOC="${PS_WIRE_BUNDLE_LOC}") celix_get_bundle_file(Celix::RsaConfiguredDiscovery RS_DISCOVERY_BUNDLE_LOC) target_compile_definitions(test_cxx_remote_services_integration PRIVATE RS_DISCOVERY_BUNDLE_LOC="${RS_DISCOVERY_BUNDLE_LOC}") diff --git a/bundles/cxx_remote_services/integration/gtest/src/RemoteServicesIntegrationTestSuite.cc b/bundles/cxx_remote_services/integration/gtest/src/RemoteServicesIntegrationTestSuite.cc index f611d6666..007dd1f80 100644 --- a/bundles/cxx_remote_services/integration/gtest/src/RemoteServicesIntegrationTestSuite.cc +++ b/bundles/cxx_remote_services/integration/gtest/src/RemoteServicesIntegrationTestSuite.cc @@ -26,15 +26,9 @@ class RemoteServicesIntegrationTestSuite : public ::testing::Test { public: RemoteServicesIntegrationTestSuite() { - auto pubsubTestReturnIpc = std::string{"ipc:///tmp/pubsub-test-return"}; - auto pubsubTestInvokeIpc = std::string{"ipc:///tmp/pubsub-test-invoke"}; - celix::Properties clientConfig{ {"CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL", "info"}, {celix::FRAMEWORK_CACHE_DIR, ".clientCache"}, - //Static configuration to let the pubsub zmq operate without discovery - {"PSA_ZMQ_STATIC_BIND_URL_FOR_test_invoke_default", pubsubTestInvokeIpc}, - {"PSA_ZMQ_STATIC_CONNECT_URL_FOR_test_return_default", pubsubTestReturnIpc } }; clientFw = celix::createFramework(clientConfig); clientCtx = clientFw->getFrameworkBundleContext(); @@ -42,9 +36,6 @@ class RemoteServicesIntegrationTestSuite : public ::testing::Test { celix::Properties serverConfig{ {"CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL", "info"}, {celix::FRAMEWORK_CACHE_DIR, ".serverCache"}, - //Static configuration to let the pubsub zmq operate without discovery - {"PSA_ZMQ_STATIC_BIND_URL_FOR_test_return_default", pubsubTestReturnIpc }, - {"PSA_ZMQ_STATIC_CONNECT_URL_FOR_test_invoke_default", pubsubTestInvokeIpc } }; serverFw = celix::createFramework(serverConfig); serverCtx = serverFw->getFrameworkBundleContext(); @@ -52,10 +43,6 @@ class RemoteServicesIntegrationTestSuite : public ::testing::Test { static void installSharedBundles(std::shared_ptr& ctx) { auto sharedBundles = { - PS_SER_BUNDLE_LOC, - PS_PSTM_BUNDLE_LOC, - PS_PSA_BUNDLE_LOC, - PS_WIRE_BUNDLE_LOC, RS_DISCOVERY_BUNDLE_LOC, RS_FACTORY_BUNDLE_LOC , RS_RSA_BUNDLE_LOC}; From ee9024a5e9fdbb55e62f36c53fd61b2ad68538d1 Mon Sep 17 00:00:00 2001 From: Pepijn Noltes Date: Sun, 3 Dec 2023 23:13:12 +0100 Subject: [PATCH 3/6] Change MQ key algorithm for cxx rsa integration test suite --- .../TestExportImportRemoteServiceFactory.cc | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/bundles/cxx_remote_services/integration/src/TestExportImportRemoteServiceFactory.cc b/bundles/cxx_remote_services/integration/src/TestExportImportRemoteServiceFactory.cc index 428e8d650..f86ebdeb2 100644 --- a/bundles/cxx_remote_services/integration/src/TestExportImportRemoteServiceFactory.cc +++ b/bundles/cxx_remote_services/integration/src/TestExportImportRemoteServiceFactory.cc @@ -102,13 +102,25 @@ static void sendMsgWithIpc(const celix::LogHelper& logHelper, int qidSender, con } } +static int getConsumer2ProviderChannelId(std::string& scope, std::string& topic) { + auto c2pChannel = std::string{"c2p"} + "/" + scope + "/" + topic; //client 2 provider channel + auto c2pId = (int)celix_utils_stringHash(c2pChannel.c_str()); + return c2pId; +} + +static long getProvider2ConsumerChannelId(std::string& scope, std::string& topic) { + auto p2cChannel = std::string{"p2c"} + "/" + scope + "/" + topic; //provider 2 client channel + int p2cId = (int)celix_utils_stringHash(p2cChannel.c_str()); + return p2cId; +} + /** * A importedCalculater which acts as a pubsub proxy to a imported remote service. */ class ImportedCalculator final : public ICalculator { public: - explicit ImportedCalculator(celix::LogHelper _logHelper) : logHelper{std::move(_logHelper)} { - setupMsgIpc(); + explicit ImportedCalculator(celix::LogHelper _logHelper, int c2pChannelId, int p2cChannelId) : logHelper{std::move(_logHelper)} { + setupMsgIpc(c2pChannelId, p2cChannelId); } ~ImportedCalculator() noexcept override { @@ -185,9 +197,9 @@ class ImportedCalculator final : public ICalculator { } private: - void setupMsgIpc() { - int keySender = 1234; // TODO make configurable - int keyReceiver = 1235; // TODO make configurable + void setupMsgIpc(int c2pChannelId, int p2cChannelId) { + int keySender = (int)c2pChannelId; + int keyReceiver = (int)p2cChannelId; qidSender = msgget(keySender, 0666 | IPC_CREAT); qidReceiver = msgget(keyReceiver, 0666 | IPC_CREAT); @@ -306,13 +318,6 @@ class CalculatorImportServiceFactory final : public celix::rsa::IImportServiceFa ~CalculatorImportServiceFactory() noexcept override = default; std::unique_ptr importService(const celix::rsa::EndpointDescription& endpoint) override { - auto topic = endpoint.getProperties().get("endpoint.topic"); - auto scope = endpoint.getProperties().get("endpoint.topic"); - if (topic.empty() || scope.empty()) { - ctx->logError("Cannot import pubsub endpoint. Endpoint does not have a scope and/or topic"); - return nullptr; - } - auto componentId = createImportedCalculatorComponent(endpoint); return std::make_unique(ctx, std::move(componentId)); } @@ -327,11 +332,12 @@ class CalculatorImportServiceFactory final : public celix::rsa::IImportServiceFa private: std::string createImportedCalculatorComponent(const celix::rsa::EndpointDescription& endpoint) { - auto invokeTopic = endpoint.getProperties().get("endpoint.topic") + "_invoke"; - auto returnTopic = endpoint.getProperties().get("endpoint.topic") + "_return"; + auto topic = endpoint.getProperties().get("endpoint.topic"); auto scope = endpoint.getProperties().get("endpoint.scope"); + auto c2pChannelId = getConsumer2ProviderChannelId(scope, topic); + auto p2cChannelId = getProvider2ConsumerChannelId(scope, topic); - auto& cmp = ctx->getDependencyManager()->createComponent(std::make_unique(logHelper)); + auto& cmp = ctx->getDependencyManager()->createComponent(std::make_unique(logHelper, c2pChannelId, p2cChannelId)); cmp.createServiceDependency() .setRequired(true) .setStrategy(DependencyUpdateStrategy::suspend) @@ -372,8 +378,8 @@ class CalculatorImportServiceFactory final : public celix::rsa::IImportServiceFa */ class ExportedCalculator final { public: - explicit ExportedCalculator(celix::LogHelper _logHelper) : logHelper{std::move(_logHelper)} { - setupMsgIpc(); + explicit ExportedCalculator(celix::LogHelper _logHelper, int c2pChannelId, int p2cChannelId) : logHelper{std::move(_logHelper)} { + setupMsgIpc(c2pChannelId, p2cChannelId); } void setPromiseFactory(const std::shared_ptr& fac) { @@ -428,10 +434,10 @@ class ExportedCalculator final { calculator = calc; } private: - void setupMsgIpc() { + void setupMsgIpc(int c2pChannelId, int p2cChannelId) { //note reverse order of sender and receiver compared to ImportedCalculator - int keySender = 1235; // TODO make configurable - int keyReceiver = 1234; // TODO make configurable + int keySender = (int)p2cChannelId; + int keyReceiver = (int)c2pChannelId; qidSender = msgget(keySender, 0666 | IPC_CREAT); qidReceiver = msgget(keyReceiver, 0666 | IPC_CREAT); @@ -520,13 +526,6 @@ class CalculatorExportServiceFactory final : public celix::rsa::IExportServiceFa ~CalculatorExportServiceFactory() noexcept override = default; std::unique_ptr exportService(const celix::Properties& serviceProperties) override { - auto topic = serviceProperties.get("endpoint.topic"); - auto scope = serviceProperties.get("endpoint.topic"); - if (topic.empty() || scope.empty()) { - ctx->logError("Cannot export remote service pubsub without endpoint configuration. Endpoint does not have a scope and/or topic"); - return nullptr; - } - auto componentId = createExportedCalculatorComponent(serviceProperties); return std::make_unique(ctx, std::move(componentId)); } @@ -545,12 +544,13 @@ class CalculatorExportServiceFactory final : public celix::rsa::IExportServiceFa private: std::string createExportedCalculatorComponent(const celix::Properties& serviceProperties) { - auto invokeTopic = serviceProperties.get("endpoint.topic") + "_invoke"; - auto returnTopic = serviceProperties.get("endpoint.topic") + "_return"; + auto topic = serviceProperties.get("endpoint.topic"); auto scope = serviceProperties.get("endpoint.scope"); + auto c2pChannelId = getConsumer2ProviderChannelId(scope, topic); + auto p2cChannelId = getProvider2ConsumerChannelId(scope, topic); auto svcId = serviceProperties.get(celix::SERVICE_ID); - auto& cmp = ctx->getDependencyManager()->createComponent(std::make_unique(logHelper)); + auto& cmp = ctx->getDependencyManager()->createComponent(std::make_unique(logHelper, c2pChannelId, p2cChannelId)); cmp.createServiceDependency() .setRequired(true) From d2e10c5ac70aecab62e08620e616920bc7191bb6 Mon Sep 17 00:00:00 2001 From: Pepijn Noltes Date: Sun, 17 Dec 2023 16:52:20 +0100 Subject: [PATCH 4/6] Refactor cxx rsa integration to use ipc concepts --- .../integration/CMakeLists.txt | 57 ++++++------- .../cxx_remote_services/integration/README.md | 8 ++ .../src/RemoteServicesIntegrationTestSuite.cc | 9 +- .../resources/endpoint_discovery.json | 6 +- .../integration/src/CalculatorConsumer.cc | 13 --- .../integration/src/CalculatorProvider.cc | 4 +- .../TestExportImportRemoteServiceFactory.cc | 83 ++++++++++--------- 7 files changed, 89 insertions(+), 91 deletions(-) create mode 100644 bundles/cxx_remote_services/integration/README.md diff --git a/bundles/cxx_remote_services/integration/CMakeLists.txt b/bundles/cxx_remote_services/integration/CMakeLists.txt index bad01c2d0..9bb8d7e61 100644 --- a/bundles/cxx_remote_services/integration/CMakeLists.txt +++ b/bundles/cxx_remote_services/integration/CMakeLists.txt @@ -41,39 +41,36 @@ if (CXX_RSA_INTEGRATION) endif() ################# Integration examples ################################## + add_celix_container(RemoteCalculatorProvider + CXX + GROUP rsa + PROPERTIES + CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=debug + BUNDLES + Celix::ShellCxx + Celix::shell_tui - if (BUILD_LAUNCHER) - add_celix_container(RemoteCalculatorProvider - CXX - GROUP rsa - PROPERTIES - CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=debug - BUNDLES - Celix::ShellCxx - Celix::shell_tui + #Remote Services + Celix::RemoteServiceAdmin + TestExportImportRemoteServiceFactory #needed to be able to create a ExportedService for ICalculator - #Remote Services - Celix::RemoteServiceAdmin - TestExportImportRemoteServiceFactory #needed to be able to create a ExportedService for ICalculator + CalculatorProvider + ) - CalculatorProvider - ) + add_celix_container(RemoteCalculatorConsumer + CXX + GROUP rsa + PROPERTIES + CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=debug + BUNDLES + Celix::ShellCxx + Celix::shell_tui - add_celix_container(RemoteCalculatorConsumer - CXX - GROUP rsa - PROPERTIES - CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL=debug - BUNDLES - Celix::ShellCxx - Celix::shell_tui + #Remote Services + Celix::RsaConfiguredDiscovery + Celix::RemoteServiceAdmin + TestExportImportRemoteServiceFactory #needed to be able to create a ExportedService for ICalculator - #Remote Services - Celix::RsaConfiguredDiscovery - Celix::RemoteServiceAdmin - TestExportImportRemoteServiceFactory #needed to be able to create a ExportedService for ICalculator - - CalculatorConsumer - ) - endif () + CalculatorConsumer + ) endif() diff --git a/bundles/cxx_remote_services/integration/README.md b/bundles/cxx_remote_services/integration/README.md new file mode 100644 index 000000000..1a34dccbd --- /dev/null +++ b/bundles/cxx_remote_services/integration/README.md @@ -0,0 +1,8 @@ +# C++ Remote Service Amdatu Integration + +This project part tests the integration of the C++ Remote Service Admin implementation with the +C++ configuration-based remote service discovery. + +Because the C++ Remote Service Admin is based on export and import service factories and does not directly +implement a transportation or serializer technology, the integration tests are based on a simple implementation of +inter process communication message queue (IPC mq) for transportation and a simple memcpy for serialization. diff --git a/bundles/cxx_remote_services/integration/gtest/src/RemoteServicesIntegrationTestSuite.cc b/bundles/cxx_remote_services/integration/gtest/src/RemoteServicesIntegrationTestSuite.cc index 007dd1f80..73ef653dd 100644 --- a/bundles/cxx_remote_services/integration/gtest/src/RemoteServicesIntegrationTestSuite.cc +++ b/bundles/cxx_remote_services/integration/gtest/src/RemoteServicesIntegrationTestSuite.cc @@ -74,9 +74,6 @@ class RemoteServicesIntegrationTestSuite : public ::testing::Test { } void invokeRemoteCalcService() { - installProviderBundles(); - installConsumerBundles(); - //If a calculator provider bundle is installed I expect a exported calculator interface auto count = serverCtx->useService() .setFilter("(service.exported.interfaces=*)") @@ -98,8 +95,8 @@ class RemoteServicesIntegrationTestSuite : public ::testing::Test { /* * Testing the remote service in a while loop till it is successful or 10 seconds has passed. - * Note that because pubsub does not guarantee a connection when used, it is possible - and likely - - * that the first remote test iteration fails due to not yet completely connected pubsub. + * Note that because mq does not guarantee a connection when used, it is possible - and likely - + * that the first remote test iteration fails due to not yet completely connected mq. */ auto start = std::chrono::system_clock::now(); auto now = std::chrono::system_clock::now(); @@ -156,5 +153,7 @@ TEST_F(RemoteServicesIntegrationTestSuite, StartStopFrameworks) { } TEST_F(RemoteServicesIntegrationTestSuite, InvokeRemoteCalcService) { + installProviderBundles(); + installConsumerBundles(); invokeRemoteCalcService(); } diff --git a/bundles/cxx_remote_services/integration/resources/endpoint_discovery.json b/bundles/cxx_remote_services/integration/resources/endpoint_discovery.json index e7d04adf6..f086cd12b 100644 --- a/bundles/cxx_remote_services/integration/resources/endpoint_discovery.json +++ b/bundles/cxx_remote_services/integration/resources/endpoint_discovery.json @@ -4,12 +4,12 @@ "endpoint.id": "id-01", "service.imported": true, "service.imported.configs": [ - "pubsub" + "ipc-mq" ], "service.exported.interfaces": "ICalculator", "endpoint.objectClass": "ICalculator", - "endpoint.topic": "test", - "endpoint.scope": "default" + "endpoint.client.to.provider.channel.id": "1234", + "endpoint.provider.to.client.channel.id": "1235" } ] } \ No newline at end of file diff --git a/bundles/cxx_remote_services/integration/src/CalculatorConsumer.cc b/bundles/cxx_remote_services/integration/src/CalculatorConsumer.cc index 35ceac042..00e22ec6b 100644 --- a/bundles/cxx_remote_services/integration/src/CalculatorConsumer.cc +++ b/bundles/cxx_remote_services/integration/src/CalculatorConsumer.cc @@ -46,20 +46,8 @@ class CalculatorConsumer final : public celix::IShellCommand { }); counter++; } - - void start() { - stream = calculator->result(); - stream->forEach([](double val) { - fprintf(stdout, "calc result stream: %f\n", val); - }); - } - - void stop() { - stream.reset(); - } private: std::shared_ptr calculator{}; - std::shared_ptr> stream{}; }; class CalculatorConsumerActivator { @@ -71,7 +59,6 @@ class CalculatorConsumerActivator { .setCallbacks(&CalculatorConsumer::setCalculator); cmp.createProvidedService() .addProperty(celix::IShellCommand::COMMAND_NAME, "calc"); - cmp.setCallbacks(nullptr, &CalculatorConsumer::start, &CalculatorConsumer::stop, nullptr); cmp.build(); //bootstrap own configured import discovery to the configured discovery manager diff --git a/bundles/cxx_remote_services/integration/src/CalculatorProvider.cc b/bundles/cxx_remote_services/integration/src/CalculatorProvider.cc index 57e86b00d..f3a46099f 100644 --- a/bundles/cxx_remote_services/integration/src/CalculatorProvider.cc +++ b/bundles/cxx_remote_services/integration/src/CalculatorProvider.cc @@ -98,8 +98,8 @@ class CalculatorProviderActivator { .setCallbacks(&CalculatorImpl::setPushStreamProvider); cmp.createProvidedService() .addProperty("service.exported.interfaces", celix::typeName()) - .addProperty("endpoint.topic", "test") - .addProperty("endpoint.scope", "default") + .addProperty("endpoint.client.to.provider.channel.id", "1234") + .addProperty("endpoint.provider.to.client.channel.id", "1235") .addProperty("service.exported.intents", "osgi.async"); cmp.setCallbacks(&CalculatorImpl::init, &CalculatorImpl::start, &CalculatorImpl::stop, &CalculatorImpl::deinit); diff --git a/bundles/cxx_remote_services/integration/src/TestExportImportRemoteServiceFactory.cc b/bundles/cxx_remote_services/integration/src/TestExportImportRemoteServiceFactory.cc index f86ebdeb2..a711a81e3 100644 --- a/bundles/cxx_remote_services/integration/src/TestExportImportRemoteServiceFactory.cc +++ b/bundles/cxx_remote_services/integration/src/TestExportImportRemoteServiceFactory.cc @@ -102,38 +102,19 @@ static void sendMsgWithIpc(const celix::LogHelper& logHelper, int qidSender, con } } -static int getConsumer2ProviderChannelId(std::string& scope, std::string& topic) { - auto c2pChannel = std::string{"c2p"} + "/" + scope + "/" + topic; //client 2 provider channel - auto c2pId = (int)celix_utils_stringHash(c2pChannel.c_str()); - return c2pId; -} - -static long getProvider2ConsumerChannelId(std::string& scope, std::string& topic) { - auto p2cChannel = std::string{"p2c"} + "/" + scope + "/" + topic; //provider 2 client channel - int p2cId = (int)celix_utils_stringHash(p2cChannel.c_str()); - return p2cId; -} - /** * A importedCalculater which acts as a pubsub proxy to a imported remote service. */ class ImportedCalculator final : public ICalculator { public: - explicit ImportedCalculator(celix::LogHelper _logHelper, int c2pChannelId, int p2cChannelId) : logHelper{std::move(_logHelper)} { + explicit ImportedCalculator(celix::LogHelper _logHelper, long c2pChannelId, long p2cChannelId) : logHelper{std::move(_logHelper)} { setupMsgIpc(c2pChannelId, p2cChannelId); } - ~ImportedCalculator() noexcept override { - //failing al leftover deferreds - { - std::lock_guard lock{mutex}; - for (auto& pair : deferreds) { - pair.second.fail(celix::rsa::RemoteServicesException{"Shutting down proxy"}); - } - } - }; + ~ImportedCalculator() noexcept override = default; std::shared_ptr> result() override { + std::lock_guard lock{mutex}; return stream; } @@ -158,6 +139,7 @@ class ImportedCalculator final : public ICalculator { } int start() { + std::lock_guard lock{mutex}; ses = psp->createSynchronousEventSource(factory); stream = psp->createStream(ses, factory); running.store(true, std::memory_order::memory_order_release); @@ -176,6 +158,8 @@ class ImportedCalculator final : public ICalculator { running.store(false, std::memory_order::memory_order_release); receiveThread.join(); receiveThread = {}; + cleanupDeferreds(); + std::lock_guard lock{mutex}; ses->close(); ses.reset(); stream.reset(); @@ -197,7 +181,10 @@ class ImportedCalculator final : public ICalculator { } private: - void setupMsgIpc(int c2pChannelId, int p2cChannelId) { + void setupMsgIpc(long c2pChannelId, long p2cChannelId) { + logHelper.debug("Creating msg queue for ImportedCalculator with c2pChannelId=%li and p2cChannelId=%li", + c2pChannelId, + p2cChannelId); int keySender = (int)c2pChannelId; int keyReceiver = (int)p2cChannelId; qidSender = msgget(keySender, 0666 | IPC_CREAT); @@ -205,7 +192,19 @@ class ImportedCalculator final : public ICalculator { if (qidSender == -1 || qidReceiver == -1) { throw std::logic_error{"RsaShmClient: Error creating msg queue."}; + } else { + logHelper.info("Created msg queue for ImportedCalculator with qidSender=%i and qidReceiver=%i", + qidSender, + qidReceiver); + } + } + + void cleanupDeferreds() { + std::lock_guard lock{mutex}; + for (auto& pair : deferreds) { + pair.second.tryFail(celix::rsa::RemoteServicesException{"Shutting down proxy"}); } + deferreds.clear(); } void receiveMessages() { @@ -233,9 +232,9 @@ class ImportedCalculator final : public ICalculator { lock.unlock(); if (ret.hasError) { - deferred.fail(celix::rsa::RemoteServicesException{ret.errorMsg}); + deferred.tryFail(celix::rsa::RemoteServicesException{ret.errorMsg}); } else { - deferred.resolve(ret.result); + deferred.tryResolve(ret.result); } } catch (const IpcException& e) { logHelper.error("IpcException: %s", e.what()); @@ -249,6 +248,7 @@ class ImportedCalculator final : public ICalculator { return; // no message available (yet) } auto event = msg.value().mtext; + logHelper.trace("Received event %f", event.eventData); if (event.hasError) { logHelper.error("Received error event %s", event.errorMsg); @@ -312,7 +312,7 @@ class ComponentImportRegistration final : public celix::rsa::IImportRegistration */ class CalculatorImportServiceFactory final : public celix::rsa::IImportServiceFactory { public: - static constexpr const char * const CONFIGS = "pubsub"; + static constexpr const char * const CONFIGS = "ipc-mq"; explicit CalculatorImportServiceFactory(std::shared_ptr _ctx) : ctx{std::move(_ctx)}, logHelper{ctx, "celix::rsa::RemoteServiceFactory"} {} ~CalculatorImportServiceFactory() noexcept override = default; @@ -332,10 +332,11 @@ class CalculatorImportServiceFactory final : public celix::rsa::IImportServiceFa private: std::string createImportedCalculatorComponent(const celix::rsa::EndpointDescription& endpoint) { - auto topic = endpoint.getProperties().get("endpoint.topic"); - auto scope = endpoint.getProperties().get("endpoint.scope"); - auto c2pChannelId = getConsumer2ProviderChannelId(scope, topic); - auto p2cChannelId = getProvider2ConsumerChannelId(scope, topic); + for (auto it : endpoint.getProperties()) { + logHelper.info("Endpoint property %s=%s", it.first.c_str(), it.second.c_str()); + } + auto c2pChannelId = endpoint.getProperties().getAsLong("endpoint.client.to.provider.channel.id", -1); + auto p2cChannelId = endpoint.getProperties().getAsLong("endpoint.provider.to.client.channel.id", -1); auto& cmp = ctx->getDependencyManager()->createComponent(std::make_unique(logHelper, c2pChannelId, p2cChannelId)); cmp.createServiceDependency() @@ -378,7 +379,7 @@ class CalculatorImportServiceFactory final : public celix::rsa::IImportServiceFa */ class ExportedCalculator final { public: - explicit ExportedCalculator(celix::LogHelper _logHelper, int c2pChannelId, int p2cChannelId) : logHelper{std::move(_logHelper)} { + explicit ExportedCalculator(celix::LogHelper _logHelper, long c2pChannelId, long p2cChannelId) : logHelper{std::move(_logHelper)} { setupMsgIpc(c2pChannelId, p2cChannelId); } @@ -434,7 +435,10 @@ class ExportedCalculator final { calculator = calc; } private: - void setupMsgIpc(int c2pChannelId, int p2cChannelId) { + void setupMsgIpc(long c2pChannelId, long p2cChannelId) { + logHelper.debug("Creating msg queue for ExportCalculator with c2pChannelId=%li and p2cChannelId=%li", + c2pChannelId, + p2cChannelId); //note reverse order of sender and receiver compared to ImportedCalculator int keySender = (int)p2cChannelId; int keyReceiver = (int)c2pChannelId; @@ -443,6 +447,10 @@ class ExportedCalculator final { if (qidSender == -1 || qidReceiver == -1) { throw std::logic_error{"RsaShmClient: Error creating msg queue."}; + } else { + logHelper.info("Created msg queue for ExportCalculator with qidSender=%i and qidReceiver=%i", + qidSender, + qidReceiver); } } @@ -518,7 +526,7 @@ class ComponentExportRegistration final : public celix::rsa::IExportRegistration */ class CalculatorExportServiceFactory final : public celix::rsa::IExportServiceFactory { public: - static constexpr const char * const CONFIGS = "pubsub"; + static constexpr const char * const CONFIGS = "ipc-mq"; static constexpr const char * const INTENTS = "osgi.async"; explicit CalculatorExportServiceFactory(std::shared_ptr _ctx) : ctx{std::move(_ctx)}, @@ -544,13 +552,12 @@ class CalculatorExportServiceFactory final : public celix::rsa::IExportServiceFa private: std::string createExportedCalculatorComponent(const celix::Properties& serviceProperties) { - auto topic = serviceProperties.get("endpoint.topic"); - auto scope = serviceProperties.get("endpoint.scope"); - auto c2pChannelId = getConsumer2ProviderChannelId(scope, topic); - auto p2cChannelId = getProvider2ConsumerChannelId(scope, topic); + auto c2pChannelId = serviceProperties.getAsLong("endpoint.client.to.provider.channel.id", -1); + auto p2cChannelId = serviceProperties.getAsLong("endpoint.provider.to.client.channel.id", -1); auto svcId = serviceProperties.get(celix::SERVICE_ID); - auto& cmp = ctx->getDependencyManager()->createComponent(std::make_unique(logHelper, c2pChannelId, p2cChannelId)); + auto& cmp = ctx->getDependencyManager()->createComponent( + std::make_unique(logHelper, c2pChannelId, p2cChannelId)); cmp.createServiceDependency() .setRequired(true) From 675b8282bd59100cce5d54cbb5b1baba44a566f6 Mon Sep 17 00:00:00 2001 From: Pepijn Noltes Date: Sun, 17 Dec 2023 17:13:34 +0100 Subject: [PATCH 5/6] Remove pubsub from build config --- .github/workflows/coverity-scan.yml | 1 - .github/workflows/macos.yml | 2 +- conanfile.py | 70 +-------------------- documents/patterns.md | 5 -- examples/conan_test_package/CMakeLists.txt | 15 ----- examples/conan_test_package/conanfile.py | 28 --------- examples/conan_test_package_v2/conanfile.py | 28 --------- 7 files changed, 3 insertions(+), 146 deletions(-) diff --git a/.github/workflows/coverity-scan.yml b/.github/workflows/coverity-scan.yml index 6baceb7b5..c9d303d5e 100644 --- a/.github/workflows/coverity-scan.yml +++ b/.github/workflows/coverity-scan.yml @@ -26,7 +26,6 @@ jobs: cmake \ libffi-dev \ libxml2-dev \ - libczmq-dev \ libcpputest-dev \ rapidjson-dev \ libavahi-compat-libdnssd-dev \ diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 435aac818..65fff36fb 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -75,7 +75,7 @@ jobs: uses: actions/checkout@v3.3.0 - name: Install dependencies run: | - brew install lcov zeromq czmq cpputest jansson rapidjson libzip ccache + brew install lcov cpputest jansson rapidjson libzip ccache - name: Prepare ccache timestamp id: ccache_cache_timestamp run: | diff --git a/conanfile.py b/conanfile.py index 66a7c8f7f..c63da2ced 100644 --- a/conanfile.py +++ b/conanfile.py @@ -53,16 +53,6 @@ class CelixConan(ConanFile): "build_log_helper": False, "build_log_service_api": False, "build_syslog_writer": False, - "build_pubsub": False, - "build_pubsub_wire_protocol_v1": False, - "build_pubsub_wire_protocol_v2": False, - "build_pubsub_json_serializer": False, - "build_pubsub_psa_zmq": False, - "build_pubsub_examples": False, - "build_pubsub_integration": False, - "build_pubsub_psa_tcp": False, - "build_pubsub_psa_ws": False, - "build_pubsub_discovery_etcd": False, "build_cxx_remote_service_admin": False, "build_cxx_rsa_integration": False, "build_remote_service_admin": False, @@ -144,8 +134,6 @@ def validate(self): def package_id(self): del self.info.options.build_all # the followings are not installed - del self.info.options.build_pubsub_integration - del self.info.options.build_pubsub_examples del self.info.options.build_cxx_rsa_integration del self.info.options.build_examples del self.info.options.enable_cmake_warning_tests @@ -194,54 +182,6 @@ def configure(self): options["build_shell"] = True options["build_shell_tui"] = True options["build_shell_api"] = True - options["build_pubsub"] = True - options["build_pubsub_wire_protocol_v2"] = True - options["build_pubsub_json_serializer"] = True - options["build_pubsub_psa_zmq"] = True - options["build_pubsub_discovery_etcd"] = True - - if options["build_pubsub_integration"]: - options["build_pubsub"] = True - options["build_shell_tui"] = True - options["build_pubsub_json_serializer"] = True - options["build_pubsub_wire_protocol_v2"] = True - options["build_pubsub_wire_protocol_v1"] = True - options["enable_testing"] = True - - if options["build_pubsub_examples"]: - options["build_log_service"] = True - options["build_shell_tui"] = True - options["build_pubsub_json_serializer"] = True - options["build_pubsub_discovery_etcd"] = True - options["build_pubsub_wire_protocol_v2"] = True - options["build_pubsub_wire_protocol_v1"] = True - - if options["build_pubsub_discovery_etcd"]: - options["build_pubsub"] = True - options["build_celix_etcdlib"] = True - - if options["build_pubsub_psa_ws"]: - options["build_http_admin"] = True - options["build_pubsub"] = True - - if options["build_pubsub_psa_zmq"] or options["build_pubsub_psa_tcp"]: - options["build_pubsub"] = True - - if options["build_pubsub_wire_protocol_v1"]: - options["build_pubsub"] = True - - if options["build_pubsub_wire_protocol_v2"]: - options["build_pubsub"] = True - - if options["build_pubsub_json_serializer"]: - options["build_pubsub"] = True - - if options["build_pubsub"]: - options["build_framework"] = True - options["build_celix_dfi"] = True - options["build_shell_api"] = True - options["build_log_helper"] = True - options["celix_install_deprecated_api"] = True if options["build_cxx_remote_service_admin"]: options["build_framework"] = True @@ -337,7 +277,7 @@ def configure(self): # https://github.com/conan-io/conan/issues/14528#issuecomment-1685344080 if self.options.build_utils: self.options['libzip'].shared = True - if self.options.build_framework or self.options.build_pubsub: + if self.options.build_framework: self.options['util-linux-libuuid'].shared = True if ((self.options.build_framework and self.options.framework_curlinit) or self.options.build_celix_etcdlib @@ -352,9 +292,6 @@ def configure(self): if (self.options.build_rsa_discovery_common or (self.options.build_rsa_remote_service_admin_dfi and self.options.enable_testing)): self.options['libxml2'].shared = True - if self.options.build_pubsub_psa_zmq: - self.options['zeromq'].shared = True - self.options['czmq'].shared = True if self.options.build_http_admin or self.options.build_rsa_discovery_common \ or self.options.build_rsa_remote_service_admin_dfi: self.options['civetweb'].shared = True @@ -367,7 +304,7 @@ def configure(self): def requirements(self): if self.options.build_utils: self.requires("libzip/[>=1.7.3 <2.0.0]") - if self.options.build_framework or self.options.build_pubsub: + if self.options.build_framework: self.requires("util-linux-libuuid/[>=2.39 <3.0.0]") if ((self.options.build_framework and self.options.framework_curlinit) or self.options.build_celix_etcdlib @@ -379,9 +316,6 @@ def requirements(self): self.requires("libxml2/[>=2.9.9 <3.0.0]") if self.options.build_cxx_remote_service_admin: self.requires("rapidjson/[>=1.1.0 <2.0.0]") - if self.options.build_pubsub_psa_zmq: - self.requires("zeromq/[>=4.3.4 <5.0.0]") - self.requires("czmq/4.2.0") if self.options.build_http_admin or self.options.build_rsa_discovery_common \ or self.options.build_rsa_remote_service_admin_dfi: self.requires("civetweb/1.16") diff --git a/documents/patterns.md b/documents/patterns.md index fbb4bbc0e..39d16027b 100644 --- a/documents/patterns.md +++ b/documents/patterns.md @@ -135,11 +135,6 @@ Some Apache Celix bundles use the SOD pattern. For example: - The `Celix::log_admin` bundle creates and registers `celix_log_service_t` services already preconfigured for a requested logger name.
![Celix Log Admin](diagrams/sod_pattern_log_service.png) - - The Celix PubSub bundles uses SOD to create and register `pubsub_publisher_t` services when these are requested - with a valid "topic.name" and "topic.scope" filter attribute. For PubSub, the Celix PubSub Topology Manager monitors - the `pubsub_publisher_t` requests and instructs the available Celix PubSub Admins to create - `pubsub_publisher_t`.
- ![Celix PubSub](diagrams/sod_pattern_publisher_service.png) - The Apache Celix / OSGi remote services uses SOD, by ad hoc imported services only when they are discovered and requested. diff --git a/examples/conan_test_package/CMakeLists.txt b/examples/conan_test_package/CMakeLists.txt index a98fd093c..0a7ef06b6 100644 --- a/examples/conan_test_package/CMakeLists.txt +++ b/examples/conan_test_package/CMakeLists.txt @@ -262,21 +262,6 @@ if (TEST_LOG_SERVICE_API) target_link_libraries(use_log_service_api PRIVATE Celix::log_service_api) endif () -option(TEST_PUBSUB_WIRE_PROTOCOL_V1 "Test pubsub wire protocol v1" OFF) -if (TEST_PUBSUB_WIRE_PROTOCOL_V1) - add_celix_container("use_pubsub_wire_protocol_v1" BUNDLES Celix::celix_pubsub_protocol_wire_v1 hello) -endif () - -option(TEST_PUBSUB_WIRE_PROTOCOL_V2 "Test pubsub wire protocol v2" OFF) -if (TEST_PUBSUB_WIRE_PROTOCOL_V2) - add_celix_container("use_pubsub_wire_protocol_v2" BUNDLES Celix::celix_pubsub_protocol_wire_v2 hello) -endif () - -option(TEST_PUBSUB_JSON_SERIALIZER "Test pubsub json serializer" OFF) -if (TEST_PUBSUB_JSON_SERIALIZER) - add_celix_container("use_pubsub_json_serializer" BUNDLES Celix::celix_pubsub_serializer_json hello) -endif () - option(TEST_CXX_REMOTE_SERVICE_ADMIN "Test C++ remote service admin" OFF) if (TEST_CXX_REMOTE_SERVICE_ADMIN) add_celix_container("use_cxx_remote_service_admin" BUNDLES Celix::RemoteServiceAdmin hello) diff --git a/examples/conan_test_package/conanfile.py b/examples/conan_test_package/conanfile.py index 8cdca8a57..c80070e3d 100644 --- a/examples/conan_test_package/conanfile.py +++ b/examples/conan_test_package/conanfile.py @@ -30,11 +30,6 @@ def build(self): cmake.definitions["TEST_HTTP_ADMIN"] = self.options["celix"].build_http_admin cmake.definitions["TEST_LOG_SERVICE"] = self.options["celix"].build_log_service cmake.definitions["TEST_SYSLOG_WRITER"] = self.options["celix"].build_syslog_writer - cmake.definitions["TEST_PUBSUB"] = self.options["celix"].build_pubsub - cmake.definitions["TEST_PSA_ZMQ"] = self.options["celix"].build_pubsub_psa_zmq - cmake.definitions["TEST_PSA_TCP"] = self.options["celix"].build_pubsub_psa_tcp - cmake.definitions["TEST_PSA_WS"] = self.options["celix"].build_pubsub_psa_ws - cmake.definitions["TEST_PSA_DISCOVERY_ETCD"] = self.options["celix"].build_pubsub_discovery_etcd cmake.definitions["TEST_RSA"] = self.options["celix"].build_remote_service_admin cmake.definitions["TEST_RSA_DFI"] = self.options["celix"].build_rsa_remote_service_admin_dfi cmake.definitions["TEST_RSA_SHM_V2"] = self.options["celix"].build_rsa_remote_service_admin_shm_v2 @@ -54,9 +49,6 @@ def build(self): cmake.definitions["TEST_PUSHSTREAMS"] = self.options["celix"].build_pushstreams cmake.definitions["TEST_LOG_HELPER"] = self.options["celix"].build_log_helper cmake.definitions["TEST_LOG_SERVICE_API"] = self.options["celix"].build_log_service_api - cmake.definitions["TEST_PUBSUB_WIRE_PROTOCOL_V1"] = self.options["celix"].build_pubsub_wire_protocol_v1 - cmake.definitions["TEST_PUBSUB_WIRE_PROTOCOL_V2"] = self.options["celix"].build_pubsub_wire_protocol_v2 - cmake.definitions["TEST_PUBSUB_JSON_SERIALIZER"] = self.options["celix"].build_pubsub_json_serializer cmake.definitions["TEST_CXX_REMOTE_SERVICE_ADMIN"] = self.options["celix"].build_cxx_remote_service_admin cmake.definitions["TEST_SHELL_API"] = self.options["celix"].build_shell_api cmake.definitions["TEST_CELIX_DFI"] = self.options["celix"].build_celix_dfi @@ -81,17 +73,6 @@ def test(self): self.run("./use_log_writer", cwd=os.path.join("deploy", "use_log_writer"), run_environment=True) if self.options["celix"].build_syslog_writer: self.run("./use_syslog_writer", cwd=os.path.join("deploy", "use_syslog_writer"), run_environment=True) - if self.options["celix"].build_pubsub: - self.run("./use_my_psa", cwd=os.path.join("deploy", "use_my_psa"), run_environment=True) - if self.options["celix"].build_pubsub_psa_zmq: - self.run("./use_psa_zmq", cwd=os.path.join("deploy", "use_psa_zmq"), run_environment=True) - if self.options["celix"].build_pubsub_psa_tcp: - self.run("./use_psa_tcp", cwd=os.path.join("deploy", "use_psa_tcp"), run_environment=True) - if self.options["celix"].build_pubsub_psa_ws: - self.run("./use_psa_ws", cwd=os.path.join("deploy", "use_psa_ws"), run_environment=True) - if self.options["celix"].build_pubsub_discovery_etcd and self.options["celix"].build_launcher: - self.run("./use_psa_discovery_etcd", - cwd=os.path.join("deploy", "use_psa_discovery_etcd"), run_environment=True) if self.options["celix"].build_remote_service_admin: self.run("./use_my_rsa", cwd=os.path.join("deploy", "use_my_rsa"), run_environment=True) self.run("./use_c_rsa_spi", run_environment=True) @@ -130,15 +111,6 @@ def test(self): self.run("./use_log_helper", run_environment=True) if self.options["celix"].build_log_service_api: self.run("./use_log_service_api", run_environment=True) - if self.options["celix"].build_pubsub_wire_protocol_v1: - self.run("./use_pubsub_wire_protocol_v1", - cwd=os.path.join("deploy", "use_pubsub_wire_protocol_v1"), run_environment=True) - if self.options["celix"].build_pubsub_wire_protocol_v2: - self.run("./use_pubsub_wire_protocol_v2", - cwd=os.path.join("deploy", "use_pubsub_wire_protocol_v2"), run_environment=True) - if self.options["celix"].build_pubsub_json_serializer: - self.run("./use_pubsub_json_serializer", - cwd=os.path.join("deploy", "use_pubsub_json_serializer"), run_environment=True) if self.options["celix"].build_cxx_remote_service_admin: self.run("./use_cxx_remote_service_admin", cwd=os.path.join("deploy", "use_cxx_remote_service_admin"), run_environment=True) diff --git a/examples/conan_test_package_v2/conanfile.py b/examples/conan_test_package_v2/conanfile.py index e7e8a948a..3eaabd65b 100644 --- a/examples/conan_test_package_v2/conanfile.py +++ b/examples/conan_test_package_v2/conanfile.py @@ -40,11 +40,6 @@ def generate(self): tc.cache_variables["TEST_HTTP_ADMIN"] = celix_options.build_http_admin tc.cache_variables["TEST_LOG_SERVICE"] = celix_options.build_log_service tc.cache_variables["TEST_SYSLOG_WRITER"] = celix_options.build_syslog_writer - tc.cache_variables["TEST_PUBSUB"] = celix_options.build_pubsub - tc.cache_variables["TEST_PSA_ZMQ"] = celix_options.build_pubsub_psa_zmq - tc.cache_variables["TEST_PSA_TCP"] = celix_options.build_pubsub_psa_tcp - tc.cache_variables["TEST_PSA_WS"] = celix_options.build_pubsub_psa_ws - tc.cache_variables["TEST_PSA_DISCOVERY_ETCD"] = celix_options.build_pubsub_discovery_etcd tc.cache_variables["TEST_RSA"] = celix_options.build_remote_service_admin tc.cache_variables["TEST_RSA_DFI"] = celix_options.build_rsa_remote_service_admin_dfi tc.cache_variables["TEST_RSA_SHM_V2"] = celix_options.build_rsa_remote_service_admin_shm_v2 @@ -64,9 +59,6 @@ def generate(self): tc.cache_variables["TEST_PUSHSTREAMS"] = celix_options.build_pushstreams tc.cache_variables["TEST_LOG_HELPER"] = celix_options.build_log_helper tc.cache_variables["TEST_LOG_SERVICE_API"] = celix_options.build_log_service_api - tc.cache_variables["TEST_PUBSUB_WIRE_PROTOCOL_V1"] = celix_options.build_pubsub_wire_protocol_v1 - tc.cache_variables["TEST_PUBSUB_WIRE_PROTOCOL_V2"] = celix_options.build_pubsub_wire_protocol_v2 - tc.cache_variables["TEST_PUBSUB_JSON_SERIALIZER"] = celix_options.build_pubsub_json_serializer tc.cache_variables["TEST_CXX_REMOTE_SERVICE_ADMIN"] = celix_options.build_cxx_remote_service_admin tc.cache_variables["TEST_SHELL_API"] = celix_options.build_shell_api tc.cache_variables["TEST_CELIX_DFI"] = celix_options.build_celix_dfi @@ -97,17 +89,6 @@ def test(self): self.run("./use_log_writer", cwd=os.path.join("deploy", "use_log_writer"), env="conanrun") if celix_options.build_syslog_writer: self.run("./use_syslog_writer", cwd=os.path.join("deploy", "use_syslog_writer"), env="conanrun") - if celix_options.build_pubsub: - self.run("./use_my_psa", cwd=os.path.join("deploy", "use_my_psa"), env="conanrun") - if celix_options.build_pubsub_psa_zmq: - self.run("./use_psa_zmq", cwd=os.path.join("deploy", "use_psa_zmq"), env="conanrun") - if celix_options.build_pubsub_psa_tcp: - self.run("./use_psa_tcp", cwd=os.path.join("deploy", "use_psa_tcp"), env="conanrun") - if celix_options.build_pubsub_psa_ws: - self.run("./use_psa_ws", cwd=os.path.join("deploy", "use_psa_ws"), env="conanrun") - if celix_options.build_pubsub_discovery_etcd and celix_options.build_launcher: - self.run("./use_psa_discovery_etcd", - cwd=os.path.join("deploy", "use_psa_discovery_etcd"), env="conanrun") if celix_options.build_remote_service_admin: self.run("./use_my_rsa", cwd=os.path.join("deploy", "use_my_rsa"), env="conanrun") self.run("./conan_test_package/use_c_rsa_spi", env="conanrun") @@ -146,15 +127,6 @@ def test(self): self.run("./conan_test_package/use_log_helper", env="conanrun") if celix_options.build_log_service_api: self.run("./conan_test_package/use_log_service_api", env="conanrun") - if celix_options.build_pubsub_wire_protocol_v1: - self.run("./use_pubsub_wire_protocol_v1", - cwd=os.path.join("deploy", "use_pubsub_wire_protocol_v1"), env="conanrun") - if celix_options.build_pubsub_wire_protocol_v2: - self.run("./use_pubsub_wire_protocol_v2", - cwd=os.path.join("deploy", "use_pubsub_wire_protocol_v2"), env="conanrun") - if celix_options.build_pubsub_json_serializer: - self.run("./use_pubsub_json_serializer", - cwd=os.path.join("deploy", "use_pubsub_json_serializer"), env="conanrun") if celix_options.build_cxx_remote_service_admin: self.run("./use_cxx_remote_service_admin", cwd=os.path.join("deploy", "use_cxx_remote_service_admin"), env="conanrun") From efad168a5d2a501cf72e3734b0242fb95bdf406c Mon Sep 17 00:00:00 2001 From: Pepijn Noltes Date: Sun, 17 Dec 2023 17:14:33 +0100 Subject: [PATCH 6/6] Remove psa nanomsg from experimental --- .github/workflows/ubuntu.yml | 1 - documents/building/README.md | 4 +- misc/experimental/bundles/CMakeLists.txt | 1 - .../pubsub_admin_nanomsg/CMakeLists.txt | 46 -- .../pubsub_admin_nanomsg/src/LogHelper.h | 103 --- .../src/psa_nanomsg_activator.cc | 87 --- .../src/pubsub_nanomsg_admin.cc | 625 ------------------ .../src/pubsub_nanomsg_admin.h | 154 ----- .../src/pubsub_nanomsg_common.cc | 56 -- .../src/pubsub_nanomsg_common.h | 56 -- .../src/pubsub_nanomsg_topic_receiver.cc | 319 --------- .../src/pubsub_nanomsg_topic_receiver.h | 127 ---- .../src/pubsub_nanomsg_topic_sender.cc | 265 -------- .../src/pubsub_nanomsg_topic_sender.h | 114 ---- .../src/pubsub_psa_nanomsg_constants.h | 39 -- 15 files changed, 1 insertion(+), 1996 deletions(-) delete mode 100644 misc/experimental/bundles/pubsub_admin_nanomsg/CMakeLists.txt delete mode 100644 misc/experimental/bundles/pubsub_admin_nanomsg/src/LogHelper.h delete mode 100644 misc/experimental/bundles/pubsub_admin_nanomsg/src/psa_nanomsg_activator.cc delete mode 100644 misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_admin.cc delete mode 100644 misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_admin.h delete mode 100644 misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_common.cc delete mode 100644 misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_common.h delete mode 100644 misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_topic_receiver.cc delete mode 100644 misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_topic_receiver.h delete mode 100644 misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_topic_sender.cc delete mode 100644 misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_topic_sender.h delete mode 100644 misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_psa_nanomsg_constants.h diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index e1bd8ef01..df0d9f402 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -119,7 +119,6 @@ jobs: cmake \ libffi-dev \ libxml2-dev \ - libczmq-dev \ libcpputest-dev \ rapidjson-dev \ libavahi-compat-libdnssd-dev \ diff --git a/documents/building/README.md b/documents/building/README.md index 420150cb5..c64351003 100644 --- a/documents/building/README.md +++ b/documents/building/README.md @@ -137,7 +137,6 @@ The following packages (libraries + headers) should be installed on your system: * libffi (for libdfi) * libxml2 (for remote services and bonjour shell) * rapidjson (for C++ remote service discovery) - * libczmq (for PubSubAdmin ZMQ) For Ubuntu 22.04, use the following commands: @@ -155,7 +154,6 @@ sudo apt-get install -yq --no-install-recommends \ libffi-dev \ libzip-dev \ libxml2-dev \ - libczmq-dev \ libcpputest-dev \ rapidjson-dev ``` @@ -163,7 +161,7 @@ sudo apt-get install -yq --no-install-recommends \ For OSX systems with brew installed, use the following commands: ```bash brew update && \ -brew install lcov libffi libzip czmq rapidjson libxml2 cmake jansson && \ +brew install lcov libffi libzip rapidjson libxml2 cmake jansson && \ brew link --force libffi ``` diff --git a/misc/experimental/bundles/CMakeLists.txt b/misc/experimental/bundles/CMakeLists.txt index b96038d79..fdd442fbe 100644 --- a/misc/experimental/bundles/CMakeLists.txt +++ b/misc/experimental/bundles/CMakeLists.txt @@ -19,5 +19,4 @@ if (NOT APPLE) #Note note sure if these bundles build on OSX add_subdirectory(config_admin) add_subdirectory(event_admin) - add_subdirectory(pubsub_admin_nanomsg) endif () diff --git a/misc/experimental/bundles/pubsub_admin_nanomsg/CMakeLists.txt b/misc/experimental/bundles/pubsub_admin_nanomsg/CMakeLists.txt deleted file mode 100644 index 27e808304..000000000 --- a/misc/experimental/bundles/pubsub_admin_nanomsg/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. - -if (BUILD_PUBSUB_PSA_NANOMSG) - - find_package(NanoMsg REQUIRED) - - add_celix_bundle(celix_pubsub_admin_nanomsg - BUNDLE_SYMBOLICNAME "apache_celix_pubsub_admin_nanomsg" - VERSION "1.0.0" - GROUP "Celix/PubSub" - SOURCES - src/psa_nanomsg_activator.cc - src/pubsub_nanomsg_admin.cc - src/pubsub_nanomsg_topic_sender.cc - src/pubsub_nanomsg_topic_receiver.cc - src/pubsub_nanomsg_common.cc - ) - - target_link_libraries(celix_pubsub_admin_nanomsg PRIVATE - Celix::pubsub_spi - Celix::framework Celix::dfi Celix::log_helper - NANOMSG::lib - ) - target_include_directories(celix_pubsub_admin_nanomsg PRIVATE - src - ) - - install_celix_bundle(celix_pubsub_admin_nanomsg EXPORT celix COMPONENT pubsub) - target_link_libraries(celix_pubsub_admin_nanomsg PRIVATE Celix::shell_api) - add_library(Celix::pubsub_admin_nanomsg ALIAS celix_pubsub_admin_nanomsg) -endif() diff --git a/misc/experimental/bundles/pubsub_admin_nanomsg/src/LogHelper.h b/misc/experimental/bundles/pubsub_admin_nanomsg/src/LogHelper.h deleted file mode 100644 index d5d2f0b86..000000000 --- a/misc/experimental/bundles/pubsub_admin_nanomsg/src/LogHelper.h +++ /dev/null @@ -1,103 +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. - */ - -#pragma once -#include -#include "log_helper.h" -#include -namespace celix { - namespace pubsub { - namespace nanomsg { - /* - * Not that the loghelper is created in the firs log-call. This is because when a log-helper is started - * during registration of a service with a service-factory a dead-lock can occur - * This prevents it. - */ - class LogHelper { - public: - LogHelper(bundle_context_t *_ctx, const std::string& _componentName ) : ctx{_ctx}, helperCreated{true}, componentName{_componentName}{ - } - - LogHelper(const LogHelper& ) = delete; - LogHelper& operator=(const LogHelper&) = delete; - - - ~LogHelper() { - if (helperCreated && _logHelper) { - logHelper_stop(_logHelper); - logHelper_destroy(&_logHelper); - } - std::cerr << "Destroyed loghelper for " << componentName << std::endl; - } - template - void ERROR(Args... args) { - auto ss = LOG_STREAM(args...); - log_string(OSGI_LOGSERVICE_ERROR, ss.str()); - } - - template - void WARN(Args... args) { - auto ss = LOG_STREAM(args...); - log_string(OSGI_LOGSERVICE_WARNING, ss.str()); - } - - template - void INFO(Args... args) { - auto ss = LOG_STREAM(args...); - log_string(OSGI_LOGSERVICE_INFO, ss.str()); - } - - template - void DBG(Args... args) { - auto ss = LOG_STREAM(args...); - log_string(OSGI_LOGSERVICE_DEBUG, ss.str()); - } - - private: - bundle_context_t *ctx; - bool helperCreated{false}; - log_helper_t *_logHelper{}; - std::string componentName{}; - template - std::stringstream LOG_STREAM(T first) const { - std::stringstream ss; - ss << first; - return ss; - } - - template - std::stringstream LOG_STREAM(T first, Args... args) const { - std::stringstream ss; - ss << "[" << componentName << "] " << first << LOG_STREAM(args...).str(); - return ss; - } - - void log_string(log_level_t level, const std::string& msg) { - if (_logHelper == nullptr) { - helperCreated = true; - logHelper_create(ctx, &_logHelper); - logHelper_start(_logHelper); - } - logHelper_log(_logHelper, level, msg.c_str()); - } - }; - - } - } -} \ No newline at end of file diff --git a/misc/experimental/bundles/pubsub_admin_nanomsg/src/psa_nanomsg_activator.cc b/misc/experimental/bundles/pubsub_admin_nanomsg/src/psa_nanomsg_activator.cc deleted file mode 100644 index 20c23920e..000000000 --- a/misc/experimental/bundles/pubsub_admin_nanomsg/src/psa_nanomsg_activator.cc +++ /dev/null @@ -1,87 +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 -#include -#include -#include "celix_api.h" -#include "pubsub_serializer.h" -#include "LogHelper.h" -#include "pubsub_admin.h" -#include "pubsub_nanomsg_admin.h" - -namespace celix { namespace pubsub { namespace nanomsg { - class Activator { - public: - Activator(celix_bundle_context_t *ctx) : - context{ctx}, - L{context, std::string("PSA_NANOMSG_ACTIVATOR")}, - admin(context) - { - } - Activator(const Activator&) = delete; - Activator& operator=(const Activator&) = delete; - - ~Activator() = default; - - celix_status_t start() { - admin.start(); - return CELIX_SUCCESS; - } - - celix_status_t stop() { - admin.stop(); - return CELIX_SUCCESS; - }; - - private: - celix_bundle_context_t *context{}; - celix::pubsub::nanomsg::LogHelper L; - pubsub_nanomsg_admin admin; - - }; -}}} - -celix_status_t celix_bundleActivator_create(celix_bundle_context_t *ctx , void **userData) { - celix_status_t status = CELIX_SUCCESS; - auto data = new (std::nothrow) celix::pubsub::nanomsg::Activator{ctx}; - if (data != NULL) { - *userData = data; - } else { - status = CELIX_ENOMEM; - } - return status; -} - -celix_status_t celix_bundleActivator_start(void *userData, celix_bundle_context_t *) { - auto act = static_cast(userData); - return act->start(); -} - -celix_status_t celix_bundleActivator_stop(void *userData, celix_bundle_context_t *) { - auto act = static_cast(userData); - return act->stop(); -} - - -celix_status_t celix_bundleActivator_destroy(void *userData, celix_bundle_context_t *) { - auto act = static_cast(userData); - delete act; - return CELIX_SUCCESS; -} diff --git a/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_admin.cc b/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_admin.cc deleted file mode 100644 index 064f3e73d..000000000 --- a/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_admin.cc +++ /dev/null @@ -1,625 +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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pubsub_utils.h" -#include "pubsub_nanomsg_admin.h" -#include "pubsub_psa_nanomsg_constants.h" - -#include "celix_compiler.h" - - -static celix_status_t nanoMsg_getIpAddress(const char *interface, char **ip); - -pubsub_nanomsg_admin::pubsub_nanomsg_admin(celix_bundle_context_t *_ctx): - ctx{_ctx}, - L{ctx, "pubsub_nanomsg_admin"} { - verbose = celix_bundleContext_getPropertyAsBool(ctx, PUBSUB_NANOMSG_VERBOSE_KEY, PUBSUB_NANOMSG_VERBOSE_DEFAULT); - fwUUID = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, nullptr); - - char *ip = nullptr; - const char *confIp = celix_bundleContext_getProperty(ctx, PUBSUB_NANOMSG_PSA_IP_KEY , nullptr); - if (confIp != NULL) { - if (strchr(confIp, '/') != NULL) { - // IP with subnet prefix specified - ip = ipUtils_findIpBySubnet(confIp); - if (ip == NULL) { - L_WARN("[PSA_NANOMSG] Could not find interface for requested subnet %s", confIp); - } - } else { - // IP address specified - ip = strndup(confIp, 1024); - } - } - - if (ip == nullptr) { - //TODO try to get ip from subnet (CIDR) - } - - if (ip == nullptr) { - //try to get ip from itf - const char *interface = celix_bundleContext_getProperty(ctx, PUBSUB_NANOMSG_PSA_ITF_KEY, nullptr); - nanoMsg_getIpAddress(interface, &ip); - } - - if (ip == nullptr) { - L.WARN("[PSA_NANOMSG] Could not determine IP address for PSA, using default ip (", PUBSUB_NANOMSG_DEFAULT_IP, ")"); - ip = strndup(PUBSUB_NANOMSG_DEFAULT_IP, 1024); - } - - ipAddress = ip; - if (verbose) { - L.INFO("[PSA_NANOMSG] Using ", ip, " for service annunciation."); - } - - - long _basePort = celix_bundleContext_getPropertyAsLong(ctx, PSA_NANOMSG_BASE_PORT, PSA_NANOMSG_DEFAULT_BASE_PORT); - long _maxPort = celix_bundleContext_getPropertyAsLong(ctx, PSA_NANOMSG_MAX_PORT, PSA_NANOMSG_DEFAULT_MAX_PORT); - basePort = (unsigned int)_basePort; - maxPort = (unsigned int)_maxPort; - if (verbose) { - L.INFO("[PSA_NANOMSG] Using base till max port: ", _basePort, " till ", _maxPort); - } - - - defaultScore = celix_bundleContext_getPropertyAsDouble(ctx, PSA_NANOMSG_DEFAULT_SCORE_KEY, PSA_NANOMSG_DEFAULT_SCORE); - qosSampleScore = celix_bundleContext_getPropertyAsDouble(ctx, PSA_NANOMSG_QOS_SAMPLE_SCORE_KEY, PSA_NANOMSG_DEFAULT_QOS_SAMPLE_SCORE); - qosControlScore = celix_bundleContext_getPropertyAsDouble(ctx, PSA_NANOMSG_QOS_CONTROL_SCORE_KEY, PSA_NANOMSG_DEFAULT_QOS_CONTROL_SCORE); -} - -pubsub_nanomsg_admin::~pubsub_nanomsg_admin() { - //note assuming al psa register services and service tracker are removed. - { -// std::lock_guard lock(topicSenders.mutex); -// for (auto &kv : topicSenders.map) { -// auto &sender = kv.second; -// delete (sender); -// } - } - - { - std::lock_guard lock(topicReceivers.mutex); - for (auto &kv: topicReceivers.map) { - delete kv.second; - } - } - - { - std::lock_guard lock(discoveredEndpoints.mutex); - for (auto &entry : discoveredEndpoints.map) { - auto *ep = entry.second; - celix_properties_destroy(ep); - } - } - - { - std::lock_guard lock(serializers.mutex); - serializers.map.clear(); - } - - free(ipAddress); - -} - -void pubsub_nanomsg_admin::start() { - adminService.handle = this; - adminService.matchPublisher = [](void *handle, long svcRequesterBndId, const celix_filter_t *svcFilter, celix_properties_t **outTopicProperties, double *score, long *serializerSvcId) { - auto me = static_cast(handle); - return me->matchPublisher(svcRequesterBndId, svcFilter, outTopicProperties, score, serializerSvcId); - }; - adminService.matchSubscriber = [](void *handle, long svcProviderBndId, const celix_properties_t *svcProperties, celix_properties_t **outTopicProperties, double *score, long *serializerSvcId) { - auto me = static_cast(handle); - return me->matchSubscriber(svcProviderBndId, svcProperties, outTopicProperties, score, serializerSvcId); - }; - adminService.matchDiscoveredEndpoint = [](void *handle, const celix_properties_t *endpoint, bool *match) { - auto me = static_cast(handle); - return me->matchEndpoint(endpoint, match); - }; - adminService.setupTopicSender = [](void *handle, const char *scope, const char *topic, const celix_properties_t *topicProperties, long serializerSvcId, celix_properties_t **publisherEndpoint) { - auto me = static_cast(handle); - return me->setupTopicSender(scope, topic, topicProperties, serializerSvcId, publisherEndpoint); - }; - adminService.teardownTopicSender = [](void *handle, const char *scope, const char *topic) { - auto me = static_cast(handle); - return me->teardownTopicSender(scope, topic); - }; - adminService.setupTopicReceiver = [](void *handle, const char *scope, const char *topic, const celix_properties_t *topicProperties, long serializerSvcId, celix_properties_t **subscriberEndpoint) { - auto me = static_cast(handle); - return me->setupTopicReceiver(std::string(scope), std::string(topic), topicProperties, serializerSvcId, subscriberEndpoint); - }; - - adminService.teardownTopicReceiver = [] (void *handle, const char *scope, const char *topic) { - auto me = static_cast(handle); - return me->teardownTopicReceiver(scope, topic); - }; - adminService.addDiscoveredEndpoint = [](void *handle, const celix_properties_t *endpoint) { - auto me = static_cast(handle); - return me->addEndpoint(endpoint); - }; - adminService.removeDiscoveredEndpoint = [](void *handle, const celix_properties_t *endpoint) { - auto me = static_cast(handle); - return me->removeEndpoint(endpoint); - }; - - celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, PUBSUB_ADMIN_SERVICE_TYPE, PUBSUB_NANOMSG_ADMIN_TYPE); - - adminSvcId = celix_bundleContext_registerService(ctx, static_cast(&adminService), PUBSUB_ADMIN_SERVICE_NAME, props); - - - celix_service_tracking_options_t opts{}; - opts.filter.serviceName = PUBSUB_SERIALIZER_SERVICE_NAME; - opts.filter.ignoreServiceLanguage = true; - opts.callbackHandle = this; - opts.addWithProperties = [](void *handle, void *svc, const celix_properties_t *props) { - auto me = static_cast(handle); - me->addSerializerSvc(svc, props); - }; - opts.removeWithProperties = [](void *handle, void *svc, const celix_properties_t *props) { - auto me = static_cast(handle); - me->removeSerializerSvc(svc, props); - }; - serializersTrackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts); - - //register shell command service - cmdSvc.handle = this; - cmdSvc.executeCommand = [](void *handle, char * commandLine, FILE *outStream, FILE *errorStream) { - auto me = static_cast(handle); - return me->executeCommand(commandLine, outStream, errorStream); - }; - - celix_properties_t* shellProps = celix_properties_create(); - celix_properties_set(shellProps, OSGI_SHELL_COMMAND_NAME, "psa_nanomsg"); - celix_properties_set(shellProps, OSGI_SHELL_COMMAND_USAGE, "psa_nanomsg"); - celix_properties_set(shellProps, OSGI_SHELL_COMMAND_DESCRIPTION, "Print the information about the TopicSender and TopicReceivers for the nanomsg PSA"); - cmdSvcId = celix_bundleContext_registerService(ctx, &cmdSvc, OSGI_SHELL_COMMAND_SERVICE_NAME, shellProps); - -} - -void pubsub_nanomsg_admin::stop() { - celix_bundleContext_unregisterService(ctx, adminSvcId); - celix_bundleContext_unregisterService(ctx, cmdSvcId); - celix_bundleContext_stopTracker(ctx, serializersTrackerId); -} - -void pubsub_nanomsg_admin::addSerializerSvc(void *svc, const celix_properties_t *props) { - const char *serType = celix_properties_get(props, PUBSUB_SERIALIZER_TYPE_KEY, nullptr); - long svcId = celix_properties_getAsLong(props, CELIX_FRAMEWORK_SERVICE_ID, -1L); - - if (serType == nullptr) { - L.INFO("[PSA_NANOMSG] Ignoring serializer service without ", PUBSUB_SERIALIZER_TYPE_KEY, " property"); - return; - } - - { - std::lock_guard lock(serializers.mutex); - auto it = serializers.map.find(svcId); - if (it == serializers.map.end()) { - serializers.map.emplace(std::piecewise_construct, - std::forward_as_tuple(svcId), - std::forward_as_tuple(serType, svcId, static_cast(svc))); - } - } -} - - -void pubsub_nanomsg_admin::removeSerializerSvc(void */*svc*/, const celix_properties_t *props) { - long svcId = celix_properties_getAsLong(props, CELIX_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 - - std::lock_guard lock(serializers.mutex); - - auto kvsm = serializers.map.find(svcId); - if (kvsm != serializers.map.end()) { - auto &entry = kvsm->second; - { - std::lock_guard senderLock(topicSenders.mutex); - for (auto it = topicSenders.map.begin(); it != topicSenders.map.end(); /*nothing*/) { - auto &sender = it->second; - if (entry.svcId == sender.getSerializerSvcId()) { - it = topicSenders.map.erase(it); - } else { - ++it; - } - } - } - - { - std::lock_guard receiverLock(topicReceivers.mutex); - for (auto iter = topicReceivers.map.begin(); iter != topicReceivers.map.end();) { - auto *receiver = iter->second; - if (receiver != nullptr && entry.svcId == receiver->serializerSvcId()) { - auto key = iter->first; - topicReceivers.map.erase(iter++); - delete receiver; - } else { - ++iter; - } - } - } - - } -} - -celix_status_t pubsub_nanomsg_admin::matchPublisher(long svcRequesterBndId, const celix_filter_t *svcFilter, celix_properties_t **outTopicProperties, - double *outScore, long *outSerializerSvcId) { - L.DBG("[PSA_NANOMSG] pubsub_nanoMsgAdmin_matchPublisher"); - celix_status_t status = CELIX_SUCCESS; - double score = pubsub_utils_matchPublisher(ctx, svcRequesterBndId, svcFilter->filterStr, PUBSUB_NANOMSG_ADMIN_TYPE, - qosSampleScore, qosControlScore, defaultScore, outTopicProperties, outSerializerSvcId); - *outScore = score; - - return status; -} - -celix_status_t pubsub_nanomsg_admin::matchSubscriber( - long svcProviderBndId, - const celix_properties_t *svcProperties, - celix_properties_t **outTopicProperties, - double *outScore, - long *outSerializerSvcId) { - L.DBG("[PSA_NANOMSG] pubsub_nanoMsgAdmin_matchSubscriber"); - celix_status_t status = CELIX_SUCCESS; - double score = pubsub_utils_matchSubscriber(ctx, svcProviderBndId, svcProperties, PUBSUB_NANOMSG_ADMIN_TYPE, - qosSampleScore, qosControlScore, defaultScore, outTopicProperties, outSerializerSvcId); - if (outScore != nullptr) { - *outScore = score; - } - return status; -} - -celix_status_t pubsub_nanomsg_admin::matchEndpoint(const celix_properties_t *endpoint, bool *outMatch) { - L.DBG("[PSA_NANOMSG] pubsub_nanoMsgAdmin_matchEndpoint"); - celix_status_t status = CELIX_SUCCESS; - bool match = pubsub_utils_matchEndpoint(ctx, endpoint, PUBSUB_NANOMSG_ADMIN_TYPE, nullptr); - if (outMatch != nullptr) { - *outMatch = match; - } - return status; -} - -celix_status_t pubsub_nanomsg_admin::setupTopicSender(const char *scope, const char *topic, - const celix_properties_t */*topicProperties*/, - long serializerSvcId, celix_properties_t **outPublisherEndpoint) { - celix_status_t status = CELIX_SUCCESS; - - //1) Create TopicSender - //2) Store TopicSender - //3) Connect existing endpoints - //4) set outPublisherEndpoint - - char *key = pubsubEndpoint_createScopeTopicKey(scope, topic); - std::lock_guard serializerLock(serializers.mutex); - std::lock_guard topicSenderLock(topicSenders.mutex); - auto sender = topicSenders.map.find(key); - if (sender == topicSenders.map.end()) { - //psa_nanomsg_serializer_entry *serEntry = nullptr; - auto kv = serializers.map.find(serializerSvcId); - if (kv != serializers.map.end()) { - auto &serEntry = kv->second; - auto e = topicSenders.map.emplace(std::piecewise_construct, - std::forward_as_tuple(key), - std::forward_as_tuple(ctx, scope, topic, serializerSvcId, serEntry.svc, ipAddress, - basePort, maxPort)); - celix_properties_t *newEndpoint = pubsubEndpoint_create(fwUUID, scope, topic, PUBSUB_PUBLISHER_ENDPOINT_TYPE, - PUBSUB_NANOMSG_ADMIN_TYPE, serEntry.serType, nullptr); - celix_properties_set(newEndpoint, PUBSUB_NANOMSG_URL_KEY, e.first->second.getUrl().c_str()); - //if available also set container name - const char *cn = celix_bundleContext_getProperty(ctx, "CELIX_CONTAINER_NAME", nullptr); - if (cn != nullptr) { - celix_properties_set(newEndpoint, "container_name", cn); - } - if (newEndpoint != nullptr && outPublisherEndpoint != nullptr) { - *outPublisherEndpoint = newEndpoint; - } - } else { - L.ERROR("[PSA NANOMSG] Error creating a TopicSender"); - } - } else { - L.ERROR("[PSA_NANOMSG] Cannot setup already existing TopicSender for scope/topic ", scope,"/", topic); - } - free(key); - - return status; -} - -celix_status_t pubsub_nanomsg_admin::teardownTopicSender(const char *scope, const char *topic) { - celix_status_t status = CELIX_SUCCESS; - - //1) Find and remove TopicSender from map - //2) destroy topic sender - - char *key = pubsubEndpoint_createScopeTopicKey(scope, topic); - std::lock_guard topicSenderLock(topicSenders.mutex); - if (topicSenders.map.erase(key) == 0) { - L.ERROR("[PSA NANOMSG] Cannot teardown TopicSender with scope/topic ", scope, "/", topic, " Does not exists"); - } - free(key); - - return status; -} - -celix_status_t pubsub_nanomsg_admin::setupTopicReceiver(const std::string &scope, const std::string &topic, - const celix_properties_t */*topicProperties*/, - long serializerSvcId, celix_properties_t **outSubscriberEndpoint) { - - celix_properties_t *newEndpoint = nullptr; - - auto key = pubsubEndpoint_createScopeTopicKey(scope.c_str(), topic.c_str()); - pubsub::nanomsg::topic_receiver * receiver = nullptr; - { - std::lock_guard serializerLock(serializers.mutex); - std::lock_guard topicReceiverLock(topicReceivers.mutex); - auto trkv = topicReceivers.map.find(key); - if (trkv != topicReceivers.map.end()) { - receiver = trkv->second; - } - if (receiver == nullptr) { - auto kvs = serializers.map.find(serializerSvcId); - if (kvs != serializers.map.end()) { - auto serEntry = kvs->second; - receiver = new pubsub::nanomsg::topic_receiver(ctx, scope, topic, serializerSvcId, serEntry.svc); - } else { - L.ERROR("[PSA_NANOMSG] Cannot find serializer for TopicSender ", scope, "/", topic); - } - if (receiver != nullptr) { - const char *psaType = PUBSUB_NANOMSG_ADMIN_TYPE; - const char *serType = kvs->second.serType; - newEndpoint = pubsubEndpoint_create(fwUUID, scope.c_str(), topic.c_str(), PUBSUB_SUBSCRIBER_ENDPOINT_TYPE, psaType, - serType, nullptr); - //if available also set container name - const char *cn = celix_bundleContext_getProperty(ctx, "CELIX_CONTAINER_NAME", nullptr); - if (cn != nullptr) { - celix_properties_set(newEndpoint, "container_name", cn); - } - topicReceivers.map[key] = receiver; - } else { - L.ERROR("[PSA NANOMSG] Error creating a TopicReceiver."); - } - } else { - L.ERROR("[PSA_NANOMSG] Cannot setup already existing TopicReceiver for scope/topic ", scope, "/", topic); - } - } - if (receiver != nullptr && newEndpoint != nullptr) { - std::lock_guard discEpLock(discoveredEndpoints.mutex); - for (auto entry : discoveredEndpoints.map) { - auto *endpoint = entry.second; - const char *type = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TYPE, nullptr); - if (type != nullptr && strncmp(PUBSUB_PUBLISHER_ENDPOINT_TYPE, type, strlen(PUBSUB_PUBLISHER_ENDPOINT_TYPE)) == 0) { - connectEndpointToReceiver(receiver, endpoint); - } - } - } - - if (newEndpoint != nullptr && outSubscriberEndpoint != nullptr) { - *outSubscriberEndpoint = newEndpoint; - } - free(key); - celix_status_t status = CELIX_SUCCESS; - return status; -} - -celix_status_t pubsub_nanomsg_admin::teardownTopicReceiver(const char *scope, const char *topic) { - char *key = pubsubEndpoint_createScopeTopicKey(scope, topic); - std::lock_guard topicReceiverLock(topicReceivers.mutex); - auto entry = topicReceivers.map.find(key); - free(key); - if (entry != topicReceivers.map.end()) { - auto receiverKey = entry->first; - pubsub::nanomsg::topic_receiver *receiver = entry->second; - topicReceivers.map.erase(receiverKey); - - delete receiver; - } - - celix_status_t status = CELIX_SUCCESS; - return status; -} - -celix_status_t pubsub_nanomsg_admin::connectEndpointToReceiver(pubsub::nanomsg::topic_receiver *receiver, - const celix_properties_t *endpoint) { - //note can be called with discoveredEndpoint.mutex lock - celix_status_t status = CELIX_SUCCESS; - - auto scope = receiver->scope(); - auto topic = receiver->topic(); - - std::string eScope = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TOPIC_SCOPE, ""); - std::string eTopic = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TOPIC_NAME, ""); - const char *url = celix_properties_get(endpoint, PUBSUB_NANOMSG_URL_KEY, nullptr); - - if (url == nullptr) { -// L_WARN("[PSA NANOMSG] Error got endpoint without a nanomsg url (admin: %s, type: %s)", admin , type); - status = CELIX_BUNDLE_EXCEPTION; - } else { - if ((eScope == scope) && (eTopic == topic)) { - receiver->connectTo(url); - } - } - - return status; -} - -celix_status_t pubsub_nanomsg_admin::addEndpoint(const celix_properties_t *endpoint) { - const char *type = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TYPE, nullptr); - - if (type != nullptr && strncmp(PUBSUB_PUBLISHER_ENDPOINT_TYPE, type, strlen(PUBSUB_PUBLISHER_ENDPOINT_TYPE)) == 0) { - std::lock_guard threadLock(topicReceivers.mutex); - for (auto &entry: topicReceivers.map) { - pubsub::nanomsg::topic_receiver *receiver = entry.second; - connectEndpointToReceiver(receiver, endpoint); - } - } - - std::lock_guard discEpLock(discoveredEndpoints.mutex); - celix_properties_t *cpy = celix_properties_copy(endpoint); - //TODO : check if properties are never deleted before map. - const char *uuid = celix_properties_get(cpy, PUBSUB_ENDPOINT_UUID, nullptr); - discoveredEndpoints.map[uuid] = cpy; - - celix_status_t status = CELIX_SUCCESS; - return status; -} - - -celix_status_t pubsub_nanomsg_admin::disconnectEndpointFromReceiver(pubsub::nanomsg::topic_receiver *receiver, - const celix_properties_t *endpoint) { - //note can be called with discoveredEndpoint.mutex lock - celix_status_t status = CELIX_SUCCESS; - - auto scope = receiver->scope(); - auto topic = receiver->topic(); - - auto eScope = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TOPIC_SCOPE, ""); - auto eTopic = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TOPIC_NAME, ""); - const char *url = celix_properties_get(endpoint, PUBSUB_NANOMSG_URL_KEY, nullptr); - - if (url == nullptr) { - L.WARN("[PSA NANOMSG] Error got endpoint without nanomsg url"); - status = CELIX_BUNDLE_EXCEPTION; - } else { - if ((eScope == scope) && (eTopic == topic)) { - receiver->disconnectFrom(url); - } - } - - return status; -} - -celix_status_t pubsub_nanomsg_admin::removeEndpoint(const celix_properties_t *endpoint) { - const char *type = celix_properties_get(endpoint, PUBSUB_ENDPOINT_TYPE, nullptr); - - if (type != nullptr && strncmp(PUBSUB_PUBLISHER_ENDPOINT_TYPE, type, strlen(PUBSUB_PUBLISHER_ENDPOINT_TYPE)) == 0) { - std::lock_guard topicReceiverLock(topicReceivers.mutex); - for (auto &entry : topicReceivers.map) { - pubsub::nanomsg::topic_receiver *receiver = entry.second; - disconnectEndpointFromReceiver(receiver, endpoint); - } - } - { - std::lock_guard discEpLock(discoveredEndpoints.mutex); - const char *uuid = celix_properties_get(endpoint, PUBSUB_ENDPOINT_UUID, nullptr); - discoveredEndpoints.map.erase(uuid); - } - return CELIX_SUCCESS;; -} - -celix_status_t pubsub_nanomsg_admin::executeCommand(char *commandLine CELIX_UNUSED, FILE *out, - FILE *errStream CELIX_UNUSED) { - celix_status_t status = CELIX_SUCCESS; - fprintf(out, "\n"); - fprintf(out, "Topic Senders:\n"); - { - std::lock_guard serializerLock(serializers.mutex); - std::lock_guard topicSenderLock(topicSenders.mutex); - for (auto &senderEntry: topicSenders.map) { - auto &sender = senderEntry.second; - long serSvcId = sender.getSerializerSvcId(); - auto kvs = serializers.map.find(serSvcId); - const char* serType = ( kvs == serializers.map.end() ? "!Error" : kvs->second.serType); - const auto scope = sender.getScope(); - const auto topic = sender.getTopic(); - const auto url = sender.getUrl(); - fprintf(out, "|- Topic Sender %s/%s\n", scope.c_str(), topic.c_str()); - fprintf(out, " |- serializer type = %s\n", serType); - fprintf(out, " |- url = %s\n", url.c_str()); - } - } - - { - fprintf(out, "\n"); - fprintf(out, "\nTopic Receivers:\n"); - std::lock_guard serializerLock(serializers.mutex); - std::lock_guard topicReceiverLock(topicReceivers.mutex); - for (auto &entry : topicReceivers.map) { - pubsub::nanomsg::topic_receiver *receiver = entry.second; - long serSvcId = receiver->serializerSvcId(); - auto kv = serializers.map.find(serSvcId); - const char *serType = (kv == serializers.map.end() ? "!Error!" : kv->second.serType); - auto scope = receiver->scope(); - auto topic = receiver->topic(); - - std::vector connected{}; - std::vector unconnected{}; - receiver->listConnections(connected, unconnected); - - fprintf(out, "|- Topic Receiver %s/%s\n", scope.c_str(), topic.c_str()); - fprintf(out, " |- serializer type = %s\n", serType); - for (auto &url : connected) { - fprintf(out, " |- connected url = %s\n", url.c_str()); - } - for (auto &url : unconnected) { - fprintf(out, " |- unconnected url = %s\n", url.c_str()); - } - } - } - fprintf(out, "\n"); - - return status; -} - -#ifndef ANDROID -static celix_status_t nanoMsg_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 != nullptr && status != CELIX_SUCCESS; ifa = ifa->ifa_next) - { - if (ifa->ifa_addr == nullptr) - continue; - - if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, nullptr, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) { - if (interface == nullptr) { - *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/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_admin.h b/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_admin.h deleted file mode 100644 index 3785ce5e2..000000000 --- a/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_admin.h +++ /dev/null @@ -1,154 +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_NANOMSG_ADMIN_H -#define CELIX_PUBSUB_NANOMSG_ADMIN_H - -#include -#include -#include -#include "celix_api.h" -#include "celix_compiler.h" -#include "pubsub_nanomsg_topic_receiver.h" -#include -#include "LogHelper.h" -#include "command.h" -#include "pubsub_nanomsg_topic_sender.h" -#include "pubsub_nanomsg_topic_receiver.h" - -#define PUBSUB_NANOMSG_ADMIN_TYPE "nanomsg" -#define PUBSUB_NANOMSG_URL_KEY "nanomsg.url" - -#define PUBSUB_NANOMSG_VERBOSE_KEY "PSA_NANOMSG_VERBOSE" -#define PUBSUB_NANOMSG_VERBOSE_DEFAULT true - -#define PUBSUB_NANOMSG_PSA_IP_KEY "PSA_IP" -#define PUBSUB_NANOMSG_PSA_ITF_KEY "PSA_INTERFACE" - -#define PUBSUB_NANOMSG_DEFAULT_IP "127.0.0.1" - -template -struct ProtectedMap { - std::mutex mutex{}; - std::map map{}; -}; - -class pubsub_nanomsg_admin { -public: - pubsub_nanomsg_admin(celix_bundle_context_t *ctx); - pubsub_nanomsg_admin(const pubsub_nanomsg_admin&) = delete; - pubsub_nanomsg_admin& operator=(const pubsub_nanomsg_admin&) = delete; - ~pubsub_nanomsg_admin(); - void start(); - void stop(); - -private: - void addSerializerSvc(void *svc, const celix_properties_t *props); - void removeSerializerSvc(void */*svc*/, const celix_properties_t *props); - celix_status_t matchPublisher( - long svcRequesterBndId, - const celix_filter_t *svcFilter, - celix_properties_t **outTopicProperties, - double *outScore, - long *outsSerializerSvcId); - celix_status_t matchSubscriber( - long svcProviderBndId, - const celix_properties_t *svcProperties, - celix_properties_t **outTopicProperties, - double *outScope, - long *outSerializerSvcId); - celix_status_t matchEndpoint(const celix_properties_t *endpoint, bool *match); - - celix_status_t setupTopicSender( - const char *scope, - const char *topic, - const celix_properties_t *topicProperties, - long serializerSvcId, - celix_properties_t **outPublisherEndpoint); - - celix_status_t teardownTopicSender(const char *scope, const char *topic); - - celix_status_t setupTopicReceiver( - const std::string &scope, - const std::string &topic, - const celix_properties_t *topicProperties, - long serializerSvcId, - celix_properties_t **outSubscriberEndpoint); - - celix_status_t teardownTopicReceiver(const char *scope, const char *topic); - - celix_status_t addEndpoint(const celix_properties_t *endpoint); - celix_status_t removeEndpoint(const celix_properties_t *endpoint); - - celix_status_t executeCommand(char *commandLine CELIX_UNUSED, FILE *out, - FILE *errStream CELIX_UNUSED); - - celix_status_t connectEndpointToReceiver(pubsub::nanomsg::topic_receiver *receiver, - const celix_properties_t *endpoint); - - celix_status_t disconnectEndpointFromReceiver(pubsub::nanomsg::topic_receiver *receiver, - const celix_properties_t *endpoint); - celix_bundle_context_t *ctx; - celix::pubsub::nanomsg::LogHelper L; - pubsub_admin_service_t adminService{}; - long adminSvcId = -1L; - long cmdSvcId = -1L; - command_service_t cmdSvc{}; - long serializersTrackerId = -1L; - - const char *fwUUID{}; - - char* ipAddress{}; - - unsigned int basePort{}; - unsigned int maxPort{}; - - double qosSampleScore{}; - double qosControlScore{}; - double defaultScore{}; - - bool verbose{}; - - class psa_nanomsg_serializer_entry { - public: - psa_nanomsg_serializer_entry(const char*_serType, long _svcId, pubsub_serializer_service_t *_svc) : - serType{_serType}, svcId{_svcId}, svc{_svc} { - - } - - const char *serType; - long svcId; - pubsub_serializer_service_t *svc; - }; - ProtectedMap serializers{}; - ProtectedMap topicSenders{}; - ProtectedMap topicReceivers{}; - ProtectedMap discoveredEndpoints{}; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - - -#endif //CELIX_PUBSUB_NANOMSG_ADMIN_H diff --git a/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_common.cc b/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_common.cc deleted file mode 100644 index ccafd436b..000000000 --- a/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_common.cc +++ /dev/null @@ -1,56 +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 -#include "pubsub_nanomsg_common.h" -#include "celix_compiler.h" - -int celix::pubsub::nanomsg::localMsgTypeIdForMsgType(void *handle CELIX_UNUSED, const char *msgType, - unsigned int *msgTypeId) { - *msgTypeId = utils_stringHash(msgType); - return 0; -} - -bool celix::pubsub::nanomsg::checkVersion(version_pt msgVersion, const celix::pubsub::nanomsg::msg_header *hdr) { - bool check=false; - int major=0,minor=0; - - if (msgVersion!=NULL) { - version_getMajor(msgVersion,&major); - version_getMinor(msgVersion,&minor); - if (hdr->major==((unsigned char)major)) { /* Different major means incompatible */ - check = (hdr->minor>=((unsigned char)minor)); /* Compatible only if the provider has a minor equals or greater (means compatible update) */ - } - } - - return check; -} - -std::string celix::pubsub::nanomsg::setScopeAndTopicFilter(const std::string &scope, const std::string &topic) { - std::string result(""); - if (scope.size() >= 2) { //3 ?? - result += scope[0]; - result += scope[1]; - } - if (topic.size() >= 2) { //3 ?? - result += topic[0]; - result += topic[1]; - } - return result; -} \ No newline at end of file diff --git a/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_common.h b/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_common.h deleted file mode 100644 index 465669bfb..000000000 --- a/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_common.h +++ /dev/null @@ -1,56 +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_NANOMSG_COMMON_H -#define CELIX_PUBSUB_NANOMSG_COMMON_H - -#include -#include -#include - -#include "version.h" -#include "log_helper.h" - -/* - * NOTE zmq is used by first sending three frames: - * 1) A subscription filter. - * This is a 5 char string of the first two chars of scope and topic combined and terminated with a '\0'. - * - * 2) The pubsub_zmq_msg_header_t is send containing the type id and major/minor version - * - * 3) The actual payload - */ - -namespace celix { namespace pubsub { namespace nanomsg { - struct msg_header { - //header - unsigned int type; - unsigned char major; - unsigned char minor; - }; - int localMsgTypeIdForMsgType(void *handle, const char *msgType, unsigned int *msgTypeId); - std::string setScopeAndTopicFilter(const std::string &scope, const std::string &topic); - - bool checkVersion(version_pt msgVersion, const celix::pubsub::nanomsg::msg_header *hdr); - -}}} - - - -#endif //CELIX_PUBSUB_NANOMSG_COMMON_H diff --git a/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_topic_receiver.cc b/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_topic_receiver.cc deleted file mode 100644 index 443f2ceeb..000000000 --- a/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_topic_receiver.cc +++ /dev/null @@ -1,319 +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 -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include "pubsub_nanomsg_topic_receiver.h" -#include "pubsub_psa_nanomsg_constants.h" -#include "pubsub_nanomsg_common.h" -#include "pubsub_topology_manager.h" - -//TODO see if block and wakeup (reset) also works -#define PSA_NANOMSG_RECV_TIMEOUT 100 //100 msec timeout - -/* -#define L_DEBUG(...) \ - logHelper_log(receiver->logHelper, OSGI_LOGSERVICE_DEBUG, __VA_ARGS__) -#define L_INFO(...) \ - logHelper_log(receiver->logHelper, OSGI_LOGSERVICE_INFO, __VA_ARGS__) -#define L_WARN(...) \ - logHelper_log(receiver->logHelper, OSGI_LOGSERVICE_WARNING, __VA_ARGS__) -#define L_ERROR(...) \ - logHelper_log(receiver->logHelper, OSGI_LOGSERVICE_ERROR, __VA_ARGS__) -*/ -//#define L_DEBUG printf -//#define L_INFO printf -//#define L_WARN printf -//#define L_ERROR printf - - -pubsub::nanomsg::topic_receiver::topic_receiver(celix_bundle_context_t *_ctx, - const std::string &_scope, - const std::string &_topic, - long _serializerSvcId, - pubsub_serializer_service_t *_serializer) : L{_ctx, "NANOMSG_topic_receiver"}, m_serializerSvcId{_serializerSvcId}, m_scope{_scope}, m_topic{_topic} { - ctx = _ctx; - serializer = _serializer; - - m_nanoMsgSocket = nn_socket(AF_SP, NN_BUS); - if (m_nanoMsgSocket < 0) { - L.ERROR("[PSA_NANOMSG] Cannot create TopicReceiver for scope/topic: ", m_scope.c_str(), "/", m_topic.c_str()); - std::bad_alloc{}; - } else { - int timeout = PSA_NANOMSG_RECV_TIMEOUT; - if (nn_setsockopt(m_nanoMsgSocket , NN_SOL_SOCKET, NN_RCVTIMEO, &timeout, - sizeof (timeout)) < 0) { - L.ERROR("[PSA_NANOMSG] Cannot create TopicReceiver for ",m_scope, "/",m_topic, ", set sockopt RECV_TIMEO failed"); - std::bad_alloc{}; - } - - auto subscriberFilter = celix::pubsub::nanomsg::setScopeAndTopicFilter(m_scope, m_topic); - - auto opts = createOptions(); - - subscriberTrackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts); - recvThread.running = true; - free ((void*)opts.filter.filter); - recvThread.thread = std::thread([this]() {this->recvThread_exec();}); - } -} - -celix_service_tracking_options_t pubsub::nanomsg::topic_receiver::createOptions() { - std::stringstream filter_str; - - filter_str << "(" << PUBSUB_SUBSCRIBER_TOPIC << "=" << m_topic << ")"; - celix_service_tracking_options_t opts{}; - opts.filter.ignoreServiceLanguage = true; - opts.filter.serviceName = PUBSUB_SUBSCRIBER_SERVICE_NAME; - opts.filter.filter = strdup(filter_str.str().c_str()); // TODO : memory leak ?? - opts.callbackHandle = this; - opts.addWithOwner = [](void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner) { - static_cast(handle)->addSubscriber(svc, props, svcOwner); - }; - opts.removeWithOwner = [](void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner) { - static_cast(handle)->removeSubscriber(svc, props, svcOwner); - }; - return opts; -} - -pubsub::nanomsg::topic_receiver::~topic_receiver() { - - { - std::lock_guard _lock(recvThread.mutex); - recvThread.running = false; - } - recvThread.thread.join(); - - celix_bundleContext_stopTracker(ctx, subscriberTrackerId); - - { - std::lock_guard _lock(subscribers.mutex); - for (auto elem : subscribers.map) { - serializer->destroySerializerMap(serializer->handle, elem.second.msgTypes); - } - subscribers.map.clear(); - } - nn_close(m_nanoMsgSocket); - -} - -std::string pubsub::nanomsg::topic_receiver::scope() const { - return m_scope; -} - -std::string pubsub::nanomsg::topic_receiver::topic() const { - return m_topic; -} - -long pubsub::nanomsg::topic_receiver::serializerSvcId() const { - return m_serializerSvcId; -} - -void pubsub::nanomsg::topic_receiver::listConnections(std::vector &connectedUrls, - std::vector &unconnectedUrls) { - std::lock_guard _lock(requestedConnections.mutex); - for (auto entry : requestedConnections.map) { - if (entry.second.isConnected()) { - connectedUrls.emplace_back(entry.second.getUrl()); - } else { - unconnectedUrls.emplace_back(entry.second.getUrl()); - } - } -} - - -void pubsub::nanomsg::topic_receiver::connectTo(const char *url) { - L.DBG("[PSA_NANOMSG] TopicReceiver ", m_scope, "/", m_topic, " connecting to nanomsg url ", url); - - std::lock_guard _lock(requestedConnections.mutex); - auto entry = requestedConnections.map.find(url); - if (entry == requestedConnections.map.end()) { - requestedConnections.map.emplace( - std::piecewise_construct, - std::forward_as_tuple(std::string(url)), - std::forward_as_tuple(url, -1)); - entry = requestedConnections.map.find(url); - } - if (!entry->second.isConnected()) { - int connection_id = nn_connect(m_nanoMsgSocket, url); - if (connection_id >= 0) { - entry->second.setConnected(true); - entry->second.setId(connection_id); - } else { - L.WARN("[PSA_NANOMSG] Error connecting to NANOMSG url ", url, " (",strerror(errno), ")"); - } - } -} - -void pubsub::nanomsg::topic_receiver::disconnectFrom(const char *url) { - L.DBG("[PSA NANOMSG] TopicReceiver ", m_scope, "/", m_topic, " disconnect from nanomsg url ", url); - - std::lock_guard _lock(requestedConnections.mutex); - auto entry = requestedConnections.map.find(url); - if (entry != requestedConnections.map.end()) { - if (entry->second.isConnected()) { - if (nn_shutdown(m_nanoMsgSocket, entry->second.getId()) == 0) { - entry->second.setConnected(false); - } else { - L.WARN("[PSA_NANOMSG] Error disconnecting from nanomsg url ", url, ", id: ", entry->second.getId(), " (",strerror(errno),")"); - } - } - requestedConnections.map.erase(url); - std::cerr << "REMOVING connection " << url << std::endl; - } else { - std::cerr << "Disconnecting from unknown URL " << url << std::endl; - } -} - -void pubsub::nanomsg::topic_receiver::addSubscriber(void *svc, const celix_properties_t *props, - const celix_bundle_t *bnd) { - long bndId = celix_bundle_getId(bnd); - std::string subScope = celix_properties_get(props, PUBSUB_SUBSCRIBER_SCOPE, PUBSUB_DEFAULT_ENDPOINT_SCOPE); - if (subScope != m_scope) { - //not the same scope. ignore - return; - } - - std::lock_guard _lock(subscribers.mutex); - auto entry = subscribers.map.find(bndId); - if (entry != subscribers.map.end()) { - entry->second.usageCount += 1; - } else { - //new create entry - subscribers.map.emplace(std::piecewise_construct, - std::forward_as_tuple(bndId), - std::forward_as_tuple(static_cast(svc), 1)); - entry = subscribers.map.find(bndId); - - int rc = serializer->createSerializerMap(serializer->handle, (celix_bundle_t*)bnd, &entry->second.msgTypes); - if (rc != 0) { - L.ERROR("[PSA_NANOMSG] Cannot create msg serializer map for TopicReceiver ", m_scope.c_str(), "/", m_topic.c_str()); - subscribers.map.erase(bndId); - } - } -} - -void pubsub::nanomsg::topic_receiver::removeSubscriber(void */*svc*/, - const celix_properties_t */*props*/, const celix_bundle_t *bnd) { - long bndId = celix_bundle_getId(bnd); - - std::lock_guard _lock(subscribers.mutex); - auto entry = subscribers.map.find(bndId); - if (entry != subscribers.map.end()) { - entry->second.usageCount -= 1; - if (entry->second.usageCount <= 0) { - //remove entry - int rc = serializer->destroySerializerMap(serializer->handle, entry->second.msgTypes); - if (rc != 0) { - L.ERROR("[PSA_NANOMSG] Cannot destroy msg serializers map for TopicReceiver ", m_scope.c_str(), "/",m_topic.c_str(),"\n"); - } - subscribers.map.erase(bndId); - } - } -} - -void pubsub::nanomsg::topic_receiver::processMsgForSubscriberEntry(psa_nanomsg_subscriber_entry* entry, const celix::pubsub::nanomsg::msg_header *hdr, const char* payload, size_t payloadSize) { - pubsub_msg_serializer_t* msgSer = static_cast(hashMap_get(entry->msgTypes, (void*)(uintptr_t)(hdr->type))); - pubsub_subscriber_t *svc = entry->svc; - - if (msgSer!= NULL) { - void *deserializedMsg = NULL; - bool validVersion = celix::pubsub::nanomsg::checkVersion(msgSer->msgVersion, hdr); - if (validVersion) { - celix_status_t status = msgSer->deserialize(msgSer, payload, payloadSize, &deserializedMsg); - if (status == CELIX_SUCCESS) { - bool release = false; - svc->receive(svc->handle, msgSer->msgName, msgSer->msgId, deserializedMsg, &release); - if (release) { - msgSer->freeMsg(msgSer->handle, deserializedMsg); - } - } else { - L.WARN("[PSA_NANOMSG_TR] Cannot deserialize msg type ", msgSer->msgName , "for scope/topic ", scope(), "/", topic()); - } - } - } else { - L.WARN("[PSA_NANOMSG_TR] Cannot find serializer for type id ", hdr->type); - } -} - -void pubsub::nanomsg::topic_receiver::processMsg(const celix::pubsub::nanomsg::msg_header *hdr, const char *payload, size_t payloadSize) { - std::lock_guard _lock(subscribers.mutex); - for (auto entry : subscribers.map) { - processMsgForSubscriberEntry(&entry.second, hdr, payload, payloadSize); - } -} - -struct Message { - celix::pubsub::nanomsg::msg_header header; - char payload[]; -}; - -void pubsub::nanomsg::topic_receiver::recvThread_exec() { - while (recvThread.running) { - Message *msg = nullptr; - nn_iovec iov[2]; - iov[0].iov_base = &msg; - iov[0].iov_len = NN_MSG; - - nn_msghdr msgHdr; - memset(&msgHdr, 0, sizeof(msgHdr)); - - msgHdr.msg_iov = iov; - msgHdr.msg_iovlen = 1; - - msgHdr.msg_control = nullptr; - msgHdr.msg_controllen = 0; - - errno = 0; - int recvBytes = nn_recvmsg(m_nanoMsgSocket, &msgHdr, 0); - if (msg && static_cast(recvBytes) >= sizeof(celix::pubsub::nanomsg::msg_header)) { - processMsg(&msg->header, msg->payload, recvBytes-sizeof(msg->header)); - nn_freemsg(msg); - } else if (recvBytes >= 0) { - L.ERROR("[PSA_NANOMSG_TR] Error receiving nanomsg msg, size (", recvBytes,") smaller than header\n"); - } else if (errno == EAGAIN || errno == ETIMEDOUT) { - // no data: go to next cycle - } else if (errno == EINTR) { - L.DBG("[PSA_NANOMSG_TR] nn_recvmsg interrupted"); - } else { - L.WARN("[PSA_NANOMSG_TR] Error receiving nanomessage: errno ", errno, " : ", strerror(errno), "\n"); - } - } // while - -} diff --git a/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_topic_receiver.h b/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_topic_receiver.h deleted file mode 100644 index e93ea30f0..000000000 --- a/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_topic_receiver.h +++ /dev/null @@ -1,127 +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. - */ - -#pragma once - -#include -#include -#include -#include -#include -#include "pubsub_serializer.h" -#include "LogHelper.h" -#include "celix_bundle_context.h" -#include "pubsub_nanomsg_common.h" -#include "pubsub/subscriber.h" - -struct psa_nanomsg_subscriber_entry { - psa_nanomsg_subscriber_entry(pubsub_subscriber_t *_svc, int _usageCount) : - svc{_svc}, usageCount{_usageCount} { - } - pubsub_subscriber_t *svc{}; - int usageCount; - hash_map_t *msgTypes{nullptr}; //map from serializer svc -}; - -typedef struct psa_nanomsg_requested_connection_entry { -public: - psa_nanomsg_requested_connection_entry(std::string _url, int _id, bool _connected=false): - url{_url}, id{_id}, connected{_connected} { - } - bool isConnected() const { - return connected; - } - - int getId() const { - return id; - } - - void setId(int _id) { - id = _id; - } - void setConnected(bool c) { - connected = c; - } - - const std::string &getUrl() const { - return url; - } -private: - std::string url; - int id; - bool connected; -} psa_nanomsg_requested_connection_entry_t; - -namespace pubsub { - namespace nanomsg { - class topic_receiver { - public: - topic_receiver(celix_bundle_context_t - *ctx, - const std::string &scope, - const std::string &topic, - long serializerSvcId, pubsub_serializer_service_t - *serializer); - topic_receiver(const topic_receiver &) = delete; - topic_receiver & operator=(const topic_receiver &) = delete; - ~topic_receiver(); - - std::string scope() const; - std::string topic() const; - long serializerSvcId() const; - void listConnections(std::vector &connectedUrls, std::vector &unconnectedUrls); - void connectTo(const char *url); - void disconnectFrom(const char *url); - void recvThread_exec(); - void processMsg(const celix::pubsub::nanomsg::msg_header *hdr, const char *payload, size_t payloadSize); - void processMsgForSubscriberEntry(psa_nanomsg_subscriber_entry* entry, const celix::pubsub::nanomsg::msg_header *hdr, const char* payload, size_t payloadSize); - void addSubscriber(void *svc, const celix_properties_t *props, const celix_bundle_t *bnd); - void removeSubscriber(void */*svc*/, const celix_properties_t */*props*/, const celix_bundle_t *bnd); - celix_service_tracking_options_t createOptions(); - - private: - celix_bundle_context_t *ctx{nullptr}; - celix::pubsub::nanomsg::LogHelper L; - long m_serializerSvcId{0}; - pubsub_serializer_service_t *serializer{nullptr}; - const std::string m_scope{}; - const std::string m_topic{}; - - int m_nanoMsgSocket{0}; - - struct { - std::thread thread; - std::mutex mutex; - bool running; - } recvThread{}; - - struct { - std::mutex mutex; - std::map map; - } requestedConnections{}; - - long subscriberTrackerId{0}; - struct { - std::mutex mutex; - std::map map; - } subscribers{}; - }; - } -} - diff --git a/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_topic_sender.cc b/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_topic_sender.cc deleted file mode 100644 index 452ea7853..000000000 --- a/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_topic_sender.cc +++ /dev/null @@ -1,265 +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 -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include "pubsub_nanomsg_topic_sender.h" -#include "pubsub_psa_nanomsg_constants.h" -#include "pubsub_nanomsg_common.h" -#include "celix_compiler.h" - -#define FIRST_SEND_DELAY_IN_SECONDS 2 -#define NANOMSG_BIND_MAX_RETRY 10 - -static unsigned int rand_range(unsigned int min, unsigned int max); -static void delay_first_send_for_late_joiners(celix::pubsub::nanomsg::LogHelper& logHelper); - -pubsub::nanomsg::pubsub_nanomsg_topic_sender::pubsub_nanomsg_topic_sender(celix_bundle_context_t *_ctx, - const char *_scope, - const char *_topic, - long _serializerSvcId, - pubsub_serializer_service_t *_ser, - const char *_bindIp, - unsigned int _basePort, - unsigned int _maxPort) : - ctx{_ctx}, - L{ctx, "PSA_NANOMSG_TS"}, - serializerSvcId {_serializerSvcId}, - serializer{_ser}, - scope{_scope}, - topic{_topic}{ - - scopeAndTopicFilter = celix::pubsub::nanomsg::setScopeAndTopicFilter(_scope, _topic); - - //setting up nanomsg socket for nanomsg TopicSender - int nnSock = nn_socket(AF_SP, NN_BUS); - if (nnSock == -1) { - perror("Error for nanomsg_socket"); - } - - int rv = -1, retry=0; - while (rv == -1 && retry < NANOMSG_BIND_MAX_RETRY ) { - /* Randomized part due to same bundle publishing on different topics */ - unsigned int port = rand_range(_basePort,_maxPort); - std::stringstream _url; - _url << "tcp://" << _bindIp << ":" << port; - - std::stringstream bindUrl; - bindUrl << "tcp://0.0.0.0:" << port; - - rv = nn_bind (nnSock, bindUrl.str().c_str()); - if (rv == -1) { - perror("Error for nn_bind"); - } else { - this->url = _url.str(); - nanomsg.socket = nnSock; - } - retry++; - } - - if (!url.empty()) { - - //register publisher services using a service factory - publisher.factory.handle = this; - publisher.factory.getService = [](void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties) { - return static_cast(handle)->getPublisherService( - requestingBundle, - svcProperties); - }; - publisher.factory.ungetService = [](void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties) { - return static_cast(handle)->ungetPublisherService( - requestingBundle, - svcProperties); - }; - - celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, PUBSUB_PUBLISHER_TOPIC, topic.c_str()); - celix_properties_set(props, PUBSUB_PUBLISHER_SCOPE, scope.c_str()); - - celix_service_registration_options_t opts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS; - opts.factory = &publisher.factory; - opts.serviceName = PUBSUB_PUBLISHER_SERVICE_NAME; - opts.serviceVersion = PUBSUB_PUBLISHER_SERVICE_VERSION; - opts.properties = props; - - publisher.svcId = celix_bundleContext_registerServiceWithOptions(_ctx, &opts); - } - -} - -pubsub::nanomsg::pubsub_nanomsg_topic_sender::~pubsub_nanomsg_topic_sender() { - celix_bundleContext_unregisterService(ctx, publisher.svcId); - - nn_close(nanomsg.socket); - std::lock_guard lock(boundedServices.mutex); - for (auto &it: boundedServices.map) { - serializer->destroySerializerMap(serializer->handle, it.second.msgTypes); - } - boundedServices.map.clear(); - -} - -long pubsub::nanomsg::pubsub_nanomsg_topic_sender::getSerializerSvcId() const { - return serializerSvcId; -} - -const std::string &pubsub::nanomsg::pubsub_nanomsg_topic_sender::getScope() const { - return scope; -} - -const std::string &pubsub::nanomsg::pubsub_nanomsg_topic_sender::getTopic() const { - return topic; -} - -const std::string &pubsub::nanomsg::pubsub_nanomsg_topic_sender::getUrl() const { - return url; -} - - -void* pubsub::nanomsg::pubsub_nanomsg_topic_sender::getPublisherService(const celix_bundle_t *requestingBundle, - const celix_properties_t *svcProperties CELIX_UNUSED) { - long bndId = celix_bundle_getId(requestingBundle); - void *service{nullptr}; - std::lock_guard lock(boundedServices.mutex); - auto existingEntry = boundedServices.map.find(bndId); - if (existingEntry != boundedServices.map.end()) { - existingEntry->second.getCount += 1; - service = &existingEntry->second.service; - } else { - auto entry = boundedServices.map.emplace(std::piecewise_construct, - std::forward_as_tuple(bndId), - std::forward_as_tuple(scope, topic, bndId, nanomsg.socket, ctx)); - int rc = serializer->createSerializerMap(serializer->handle, (celix_bundle_t*)requestingBundle, &entry.first->second.msgTypes); - - if (rc == 0) { - entry.first->second.service.handle = &entry.first->second; - entry.first->second.service.localMsgTypeIdForMsgType = celix::pubsub::nanomsg::localMsgTypeIdForMsgType; - entry.first->second.service.send = [](void *handle, unsigned int msgTypeId, const void *msg) { - return static_cast(handle)->topicPublicationSend(msgTypeId, msg); - }; - service = &entry.first->second.service; - } else { - boundedServices.map.erase(bndId); - L.ERROR("Error creating serializer map for NanoMsg TopicSender. Scope: ", scope, ", Topic: ", topic); - } - } - - return service; -} - -void pubsub::nanomsg::pubsub_nanomsg_topic_sender::ungetPublisherService(const celix_bundle_t *requestingBundle, - const celix_properties_t */*svcProperties*/) { - long bndId = celix_bundle_getId(requestingBundle); - - std::lock_guard lock(boundedServices.mutex); - auto entry = boundedServices.map.find(bndId); - if (entry != boundedServices.map.end()) { - entry->second.getCount -= 1; - if (entry->second.getCount == 0) { - int rc = serializer->destroySerializerMap(serializer->handle, entry->second.msgTypes); - if (rc != 0) { - L.ERROR("Error destroying publisher service, serializer not available / cannot get msg serializer map\n"); - } - boundedServices.map.erase(bndId); - } - } -} - -int pubsub::nanomsg::bounded_service_entry::topicPublicationSend(unsigned int msgTypeId, const void *inMsg) { - int status; - auto msgSer = static_cast(hashMap_get(msgTypes, (void*)(uintptr_t)msgTypeId)); - - if (msgSer != nullptr) { - delay_first_send_for_late_joiners(L); - - int major = 0, minor = 0; - - celix::pubsub::nanomsg::msg_header msg_hdr{}; - msg_hdr.type = msgTypeId; - - if (msgSer->msgVersion != nullptr) { - version_getMajor(msgSer->msgVersion, &major); - version_getMinor(msgSer->msgVersion, &minor); - msg_hdr.major = (unsigned char) major; - msg_hdr.minor = (unsigned char) minor; - } - - void *serializedOutput = nullptr; - size_t serializedOutputLen = 0; - status = msgSer->serialize(msgSer, inMsg, &serializedOutput, &serializedOutputLen); - if (status == CELIX_SUCCESS) { - nn_iovec data[2]; - - nn_msghdr msg{}; - msg.msg_iov = data; - msg.msg_iovlen = 2; - msg.msg_iov[0].iov_base = static_cast(&msg_hdr); - msg.msg_iov[0].iov_len = sizeof(msg_hdr); - msg.msg_iov[1].iov_base = serializedOutput; - msg.msg_iov[1].iov_len = serializedOutputLen; - msg.msg_control = nullptr; - msg.msg_controllen = 0; - errno = 0; - int rc = nn_sendmsg(nanoMsgSocket, &msg, 0 ); - free(serializedOutput); - if (rc < 0) { - L.WARN("[PSA_NANOMSG_TS] Error sending zmsg, rc: ", rc, ", error: ", strerror(errno)); - } else { - L.INFO("[PSA_NANOMSG_TS] Send message with size ", rc, "\n"); - L.INFO("[PSA_NANOMSG_TS] Send message ID ", msg_hdr.type, - " major: ", (int)msg_hdr.major, - " minor: ", (int)msg_hdr.minor,"\n"); - } - } else { - L.WARN("[PSA_NANOMSG_TS] Error serialize message of type ", msgSer->msgName, - " for scope/topic ", scope.c_str(), "/", topic.c_str(),"\n"); - } - } else { - status = CELIX_SERVICE_EXCEPTION; - L.WARN("[PSA_NANOMSG_TS] Error cannot serialize message with msg type id ", msgTypeId, - " for scope/topic ", scope.c_str(), "/", topic.c_str(),"\n"); - } - return status; -} - -static void delay_first_send_for_late_joiners(celix::pubsub::nanomsg::LogHelper& logHelper) { - - static bool firstSend = true; - - if (firstSend) { - logHelper.INFO("PSA_UDP_MC_TP: Delaying first send for late joiners...\n"); - sleep(FIRST_SEND_DELAY_IN_SECONDS); - firstSend = false; - } -} - -static unsigned int rand_range(unsigned int min, unsigned int max) { - double scaled = ((double)random())/((double)RAND_MAX); - return (unsigned int)((max-min+1)*scaled + min); -} diff --git a/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_topic_sender.h b/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_topic_sender.h deleted file mode 100644 index 3a29ad4e1..000000000 --- a/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_nanomsg_topic_sender.h +++ /dev/null @@ -1,114 +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_NANOMSG_TOPIC_SENDER_H -#define CELIX_PUBSUB_NANOMSG_TOPIC_SENDER_H - -#include -#include -#include "celix_bundle_context.h" -#include "celix_compiler.h" -#include -#include -#include - -namespace pubsub { - namespace nanomsg { - - class bounded_service_entry { - public: - bounded_service_entry( - std::string &_scope, - std::string &_topic, - long _bndId, - int _nanoMsgSocket, - celix_bundle_context_t *_context) : scope{_scope}, topic{_topic}, bndId{_bndId}, nanoMsgSocket{_nanoMsgSocket}, L{_context, "nanomsg_bounded_service_entry"} { - - } - bounded_service_entry(const bounded_service_entry&) = delete; - bounded_service_entry &operator=(const bounded_service_entry&) = delete; - int topicPublicationSend(unsigned int msgTypeId, const void *inMsg); - - pubsub_publisher_t service{}; - std::string scope; - std::string topic; - long bndId{}; - hash_map_t *msgTypes{}; - int getCount{1}; - int nanoMsgSocket{}; - celix::pubsub::nanomsg::LogHelper L; - } ; - - - class pubsub_nanomsg_topic_sender { - public: - pubsub_nanomsg_topic_sender(celix_bundle_context_t *_ctx, - const char *_scope, - const char *_topic, long _serializerSvcId, pubsub_serializer_service_t *_ser, - const char *_bindIp, unsigned int _basePort, unsigned int _maxPort); - - ~pubsub_nanomsg_topic_sender(); - - pubsub_nanomsg_topic_sender(const pubsub_nanomsg_topic_sender &) = delete; - - const pubsub_nanomsg_topic_sender &operator=(const pubsub_nanomsg_topic_sender &) = delete; - - long getSerializerSvcId() const ; - const std::string &getScope() const ; - const std::string &getTopic() const ; - const std::string &getUrl() const; - - void* getPublisherService(const celix_bundle_t *requestingBundle, - const celix_properties_t *svcProperties CELIX_UNUSED); - void ungetPublisherService(const celix_bundle_t *requestingBundle, - const celix_properties_t *svcProperties CELIX_UNUSED); - int topicPublicationSend(unsigned int msgTypeId, const void *inMsg); - void delay_first_send_for_late_joiners() ; - - //private: - celix_bundle_context_t *ctx; - celix::pubsub::nanomsg::LogHelper L; - long serializerSvcId; - pubsub_serializer_service_t *serializer; - - std::string scope{}; - std::string topic{}; - std::string scopeAndTopicFilter{}; - std::string url{}; - - struct { - std::mutex mutex; - int socket; - } nanomsg{}; - - struct { - long svcId; - celix_service_factory_t factory; - } publisher{}; - - struct { - std::mutex mutex{}; - std::map map{}; - //hash_map_t *map{}; //key = bndId, value = psa_nanomsg_bounded_service_entry_t - } boundedServices{}; - }; - } -} - -#endif //CELIX_PUBSUB_NANOMSG_TOPIC_SENDER_H diff --git a/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_psa_nanomsg_constants.h b/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_psa_nanomsg_constants.h deleted file mode 100644 index 1700ee42d..000000000 --- a/misc/experimental/bundles/pubsub_admin_nanomsg/src/pubsub_psa_nanomsg_constants.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef PUBSUB_PSA_NANOMSG_CONSTANTS_H_ -#define PUBSUB_PSA_NANOMSG_CONSTANTS_H_ - - -#define PSA_NANOMSG_BASE_PORT "PSA_NANOMSG_BASE_PORT" -#define PSA_NANOMSG_MAX_PORT "PSA_NANOMSG_MAX_PORT" - -#define PSA_NANOMSG_DEFAULT_BASE_PORT 5501 -#define PSA_NANOMSG_DEFAULT_MAX_PORT 6000 - -#define PSA_NANOMSG_DEFAULT_QOS_SAMPLE_SCORE 30 -#define PSA_NANOMSG_DEFAULT_QOS_CONTROL_SCORE 70 -#define PSA_NANOMSG_DEFAULT_SCORE 30 - -#define PSA_NANOMSG_QOS_SAMPLE_SCORE_KEY "PSA_NANOMSG_QOS_SAMPLE_SCORE" -#define PSA_NANOMSG_QOS_CONTROL_SCORE_KEY "PSA_NANOMSG_QOS_CONTROL_SCORE" -#define PSA_NANOMSG_DEFAULT_SCORE_KEY "PSA_NANOMSG_DEFAULT_SCORE" - - -#endif /* PUBSUB_PSA_NANOMSG_CONSTANTS_H_ */