From ac4b5296ab01fc25d89cc4fc89b6407fb7254f1b Mon Sep 17 00:00:00 2001 From: "adheli.tavares" Date: Mon, 23 Sep 2024 15:13:36 +0100 Subject: Moving message bus configurations to its own module Issue-ID: POLICY-5131 Change-Id: Ibbcdc487300767e7b10d69e9b388c50f09e1adbc Signed-off-by: adheli.tavares --- common-parameters/pom.xml | 33 +- .../policy/common/parameters/ParameterGroup.java | 9 +- .../policy/common/parameters/ValidationResult.java | 36 +- .../parameters/rest/RestClientParameters.java | 57 +++ .../parameters/rest/RestServerParameters.java | 57 +++ .../common/parameters/topic/BusTopicParams.java | 338 ++++++++++++++ .../parameters/topic/TopicParameterGroup.java | 92 ++++ .../common/parameters/topic/TopicParameters.java | 47 ++ .../parameters/TestBeanValidationResult.java | 4 +- .../common/parameters/TestBeanValidator.java | 98 ++--- .../common/parameters/TestFieldValidator.java | 4 +- .../parameters/rest/RestClientParametersTest.java | 116 +++++ .../parameters/topic/BusTopicParamsTest.java | 201 +++++++++ gson/pom.xml | 16 +- .../common/gson/internal/ClassWalkerTest.java | 58 +-- message-bus/pom.xml | 142 ++++++ .../policy/common/message/bus/event/Topic.java | 90 ++++ .../common/message/bus/event/TopicEndpoint.java | 238 ++++++++++ .../message/bus/event/TopicEndpointManager.java | 36 ++ .../message/bus/event/TopicEndpointProxy.java | 485 +++++++++++++++++++++ .../common/message/bus/event/TopicListener.java | 37 ++ .../message/bus/event/TopicRegisterable.java | 41 ++ .../policy/common/message/bus/event/TopicSink.java | 38 ++ .../common/message/bus/event/TopicSource.java | 36 ++ .../message/bus/event/base/ApiKeyEnabled.java | 39 ++ .../common/message/bus/event/base/BusConsumer.java | 278 ++++++++++++ .../message/bus/event/base/BusPublisher.java | 43 ++ .../message/bus/event/base/BusTopicBase.java | 109 +++++ .../message/bus/event/base/BusTopicSink.java | 42 ++ .../message/bus/event/base/BusTopicSource.java | 57 +++ .../message/bus/event/base/InlineBusTopicSink.java | 165 +++++++ .../event/base/SingleThreadedBusTopicSource.java | 288 ++++++++++++ .../common/message/bus/event/base/TopicBase.java | 243 +++++++++++ .../message/bus/event/base/TopicBaseFactory.java | 87 ++++ .../bus/event/base/TopicBaseHashedFactory.java | 207 +++++++++ .../bus/event/client/BidirectionalTopicClient.java | 222 ++++++++++ .../client/BidirectionalTopicClientException.java | 53 +++ .../message/bus/event/client/TopicSinkClient.java | 114 +++++ .../bus/event/client/TopicSinkClientException.java | 54 +++ .../event/kafka/IndexedKafkaTopicSinkFactory.java | 201 +++++++++ .../kafka/IndexedKafkaTopicSourceFactory.java | 211 +++++++++ .../bus/event/kafka/InlineKafkaTopicSink.java | 83 ++++ .../bus/event/kafka/KafkaPublisherWrapper.java | 121 +++++ .../bus/event/kafka/KafkaTopicFactories.java | 39 ++ .../message/bus/event/kafka/KafkaTopicSink.java | 28 ++ .../bus/event/kafka/KafkaTopicSinkFactory.java | 89 ++++ .../message/bus/event/kafka/KafkaTopicSource.java | 28 ++ .../bus/event/kafka/KafkaTopicSourceFactory.java | 88 ++++ .../kafka/SingleThreadedKafkaTopicSource.java | 80 ++++ .../message/bus/event/noop/NoopTopicEndpoint.java | 141 ++++++ .../message/bus/event/noop/NoopTopicFactories.java | 42 ++ .../message/bus/event/noop/NoopTopicFactory.java | 117 +++++ .../message/bus/event/noop/NoopTopicSink.java | 56 +++ .../bus/event/noop/NoopTopicSinkFactory.java | 58 +++ .../message/bus/event/noop/NoopTopicSource.java | 56 +++ .../bus/event/noop/NoopTopicSourceFactory.java | 56 +++ .../message/bus/features/NetLoggerFeatureApi.java | 54 +++ .../bus/features/NetLoggerFeatureProviders.java | 41 ++ .../bus/properties/MessageBusProperties.java | 78 ++++ .../message/bus/utils/KafkaPropertyUtils.java | 80 ++++ .../common/message/bus/utils/NetLoggerUtil.java | 134 ++++++ .../common/message/bus/event/CommonTestData.java | 111 +++++ .../message/bus/event/TopicEndpointProxyTest.java | 400 +++++++++++++++++ .../message/bus/event/TopicParameterGroupTest.java | 147 +++++++ .../message/bus/event/base/BusConsumerTest.java | 282 ++++++++++++ .../message/bus/event/base/BusTopicBaseTest.java | 139 ++++++ .../bus/event/base/BusTopicFactoryTestBase.java | 238 ++++++++++ .../bus/event/base/InlineBusTopicSinkTest.java | 230 ++++++++++ .../base/SingleThreadedBusTopicSourceTest.java | 375 ++++++++++++++++ .../message/bus/event/base/TopicBaseTest.java | 355 +++++++++++++++ .../bus/event/base/TopicFactoryTestBase.java | 225 ++++++++++ .../bus/event/base/TopicPropertyBuilder.java | 121 +++++ .../message/bus/event/base/TopicTestBase.java | 159 +++++++ .../event/client/BidirectionalTopicClientTest.java | 454 +++++++++++++++++++ .../bus/event/client/TopicClientExceptionTest.java | 36 ++ .../bus/event/client/TopicSinkClientTest.java | 147 +++++++ .../kafka/IndexedKafkaTopicSourceFactoryTest.java | 63 +++ .../bus/event/kafka/InlineKafkaTopicSinkTest.java | 68 +++ .../bus/event/kafka/KafkaPublisherWrapperTest.java | 98 +++++ .../bus/event/kafka/KafkaTopicFactoryTestBase.java | 47 ++ .../bus/event/kafka/KafkaTopicPropertyBuilder.java | 94 ++++ .../bus/event/kafka/KafkaTopicSinkFactoryTest.java | 200 +++++++++ .../bus/event/kafka/KafkaTopicSinkTest.java | 34 ++ .../event/kafka/KafkaTopicSourceFactoryTest.java | 168 +++++++ .../bus/event/kafka/KafkaTopicSourceTest.java | 34 ++ .../kafka/SingleThreadedKafkaTopicSourceTest.java | 61 +++ .../bus/event/noop/NoopTopicEndpointTest.java | 121 +++++ .../bus/event/noop/NoopTopicFactoryTest.java | 257 +++++++++++ .../bus/event/noop/NoopTopicPropertyBuilder.java | 77 ++++ .../bus/event/noop/NoopTopicSinkFactoryTest.java | 39 ++ .../message/bus/event/noop/NoopTopicSinkTest.java | 58 +++ .../bus/event/noop/NoopTopicSourceFactoryTest.java | 39 ++ .../bus/event/noop/NoopTopicSourceTest.java | 56 +++ .../bus/features/NetLoggerFeatureApiTest.java | 86 ++++ .../message/bus/utils/KafkaPropertyUtilsTest.java | 54 +++ .../message/bus/utils/NetLoggerUtilTest.java | 269 ++++++++++++ ...common.message.bus.features.NetLoggerFeatureApi | 1 + message-bus/src/test/resources/logback-test.xml | 42 ++ .../message/bus/event/TopicEndpointProxyTest.json | 30 ++ .../message/bus/event/base/BusTopicBaseTest.json | 14 + .../bus/event/base/InlineBusTopicSinkTest.json | 15 + .../base/SingleThreadedBusTopicSourceTest.json | 18 + .../message/bus/event/base/TopicBaseTest.json | 9 + .../bus/parameters/TopicParameters_all_params.json | 62 +++ .../bus/parameters/TopicParameters_invalid.json | 6 + .../TopicParameters_missing_mandatory.json | 12 + .../bus/parameters/TopicParameters_valid.json | 30 ++ policy-endpoints/pom.xml | 119 +++-- .../policy/common/endpoints/event/comm/Topic.java | 90 ---- .../common/endpoints/event/comm/TopicEndpoint.java | 238 ---------- .../endpoints/event/comm/TopicEndpointManager.java | 35 -- .../endpoints/event/comm/TopicEndpointProxy.java | 485 --------------------- .../common/endpoints/event/comm/TopicListener.java | 38 -- .../endpoints/event/comm/TopicRegisterable.java | 42 -- .../common/endpoints/event/comm/TopicSink.java | 41 -- .../common/endpoints/event/comm/TopicSource.java | 37 -- .../endpoints/event/comm/bus/ApiKeyEnabled.java | 40 -- .../endpoints/event/comm/bus/BusTopicSink.java | 44 -- .../endpoints/event/comm/bus/BusTopicSource.java | 59 --- .../comm/bus/IndexedKafkaTopicSinkFactory.java | 199 --------- .../comm/bus/IndexedKafkaTopicSourceFactory.java | 204 --------- .../event/comm/bus/KafkaTopicFactories.java | 39 -- .../endpoints/event/comm/bus/KafkaTopicSink.java | 26 -- .../event/comm/bus/KafkaTopicSinkFactory.java | 89 ---- .../endpoints/event/comm/bus/KafkaTopicSource.java | 26 -- .../event/comm/bus/KafkaTopicSourceFactory.java | 88 ---- .../event/comm/bus/NoopTopicEndpoint.java | 140 ------ .../event/comm/bus/NoopTopicFactories.java | 41 -- .../endpoints/event/comm/bus/NoopTopicFactory.java | 114 ----- .../endpoints/event/comm/bus/NoopTopicSink.java | 55 --- .../event/comm/bus/NoopTopicSinkFactory.java | 56 --- .../endpoints/event/comm/bus/NoopTopicSource.java | 55 --- .../event/comm/bus/NoopTopicSourceFactory.java | 54 --- .../endpoints/event/comm/bus/TopicBaseFactory.java | 86 ---- .../event/comm/bus/TopicBaseHashedFactory.java | 206 --------- .../event/comm/bus/internal/BusConsumer.java | 278 ------------ .../event/comm/bus/internal/BusPublisher.java | 144 ------ .../event/comm/bus/internal/BusTopicBase.java | 107 ----- .../event/comm/bus/internal/BusTopicParams.java | 338 -------------- .../comm/bus/internal/InlineBusTopicSink.java | 167 ------- .../comm/bus/internal/InlineKafkaTopicSink.java | 82 ---- .../bus/internal/SingleThreadedBusTopicSource.java | 287 ------------ .../internal/SingleThreadedKafkaTopicSource.java | 79 ---- .../event/comm/bus/internal/TopicBase.java | 243 ----------- .../comm/client/BidirectionalTopicClient.java | 224 ---------- .../client/BidirectionalTopicClientException.java | 53 --- .../event/comm/client/TopicSinkClient.java | 114 ----- .../comm/client/TopicSinkClientException.java | 54 --- .../endpoints/features/NetLoggerFeatureApi.java | 55 --- .../features/NetLoggerFeatureProviders.java | 40 -- .../endpoints/http/client/HttpClientFactory.java | 3 +- .../http/client/IndexedHttpClientFactory.java | 6 +- .../http/client/internal/JerseyClient.java | 4 +- .../server/IndexedHttpServletServerFactory.java | 2 +- .../common/endpoints/http/server/RestServer.java | 2 +- .../common/endpoints/listeners/JsonListener.java | 5 +- .../endpoints/listeners/MessageTypeDispatcher.java | 3 +- .../endpoints/listeners/RequestIdDispatcher.java | 3 +- .../common/endpoints/listeners/ScoListener.java | 3 +- .../endpoints/listeners/TypedMessageListener.java | 3 +- .../endpoints/parameters/RestClientParameters.java | 57 --- .../endpoints/parameters/RestServerParameters.java | 57 --- .../endpoints/parameters/TopicParameterGroup.java | 92 ---- .../endpoints/parameters/TopicParameters.java | 48 -- .../properties/PolicyEndPointProperties.java | 54 --- .../common/endpoints/report/HealthCheckReport.java | 43 -- .../common/endpoints/utils/KafkaPropertyUtils.java | 80 ---- .../common/endpoints/utils/NetLoggerUtil.java | 135 ------ .../common/endpoints/utils/PropertyUtils.java | 123 ------ .../event/comm/TopicEndpointProxyTest.java | 400 ----------------- .../event/comm/bus/BusTopicFactoryTestBase.java | 241 ---------- .../bus/IndexedKafkaTopicSourceFactoryTest.java | 74 ---- .../event/comm/bus/KafkaTopicFactoryTestBase.java | 48 -- .../event/comm/bus/KafkaTopicPropertyBuilder.java | 93 ---- .../event/comm/bus/KafkaTopicSinkFactoryTest.java | 201 --------- .../event/comm/bus/KafkaTopicSinkTest.java | 34 -- .../comm/bus/KafkaTopicSourceFactoryTest.java | 167 ------- .../event/comm/bus/KafkaTopicSourceTest.java | 34 -- .../event/comm/bus/NoopTopicEndpointTest.java | 120 ----- .../event/comm/bus/NoopTopicFactoryTest.java | 255 ----------- .../event/comm/bus/NoopTopicPropertyBuilder.java | 76 ---- .../event/comm/bus/NoopTopicSinkFactoryTest.java | 39 -- .../event/comm/bus/NoopTopicSinkTest.java | 58 --- .../event/comm/bus/NoopTopicSourceFactoryTest.java | 39 -- .../event/comm/bus/NoopTopicSourceTest.java | 58 --- .../event/comm/bus/TopicFactoryTestBase.java | 227 ---------- .../event/comm/bus/TopicPropertyBuilder.java | 120 ----- .../endpoints/event/comm/bus/TopicTestBase.java | 164 ------- .../event/comm/bus/internal/BusConsumerTest.java | 284 ------------ .../event/comm/bus/internal/BusTopicBaseTest.java | 141 ------ .../comm/bus/internal/BusTopicParamsTest.java | 161 ------- .../comm/bus/internal/InlineBusTopicSinkTest.java | 232 ---------- .../bus/internal/InlineKafkaTopicSinkTest.java | 70 --- .../bus/internal/KafkaPublisherWrapperTest.java | 97 ----- .../internal/SingleThreadedBusTopicSourceTest.java | 377 ---------------- .../SingleThreadedKafkaTopicSourceTest.java | 70 --- .../event/comm/bus/internal/TopicBaseTest.java | 357 --------------- .../comm/client/BidirectionalTopicClientTest.java | 454 ------------------- .../comm/client/TopicClientExceptionTest.java | 36 -- .../event/comm/client/TopicSinkClientTest.java | 146 ------- .../features/NetLoggerFeatureApiTest.java | 86 ---- .../endpoints/http/server/test/HttpClientTest.java | 15 +- .../endpoints/http/server/test/HttpServerTest.java | 4 +- .../endpoints/http/server/test/RestServerTest.java | 2 +- .../endpoints/listeners/JsonListenerTest.java | 2 +- .../listeners/MessageTypeDispatcherTest.java | 2 +- .../listeners/RequestIdDispatcherTest.java | 2 +- .../endpoints/listeners/ScoListenerTest.java | 24 +- .../endpoints/parameters/CommonTestData.java | 142 ------ .../parameters/RestClientParametersTest.java | 116 ----- .../parameters/RestServerParametersTest.java | 87 ---- .../parameters/TopicParameterGroupTest.java | 144 ------ .../endpoints/report/TestHealthCheckReport.java | 50 --- .../common/endpoints/rest/CommonTestData.java | 99 +++++ .../endpoints/rest/RestServerParametersTest.java | 88 ++++ .../endpoints/utils/KafkaPropertyUtilsTest.java | 55 --- .../common/endpoints/utils/NetLoggerUtilTest.java | 271 ------------ .../common/endpoints/utils/PropertyUtilsTest.java | 110 ----- ...y.common.endpoints.features.NetLoggerFeatureApi | 1 - .../event/comm/TopicEndpointProxyTest.json | 30 -- .../event/comm/bus/internal/BusTopicBaseTest.json | 14 - .../comm/bus/internal/InlineBusTopicSinkTest.json | 15 - .../bus/internal/InlineKafkaTopicSinkTest.json | 20 - .../internal/SingleThreadedBusTopicSourceTest.json | 18 - .../SingleThreadedKafkaTopicSourceTest.json | 19 - .../event/comm/bus/internal/TopicBaseTest.json | 9 - .../parameters/RestServerParameters_invalid.json | 6 - .../parameters/RestServerParameters_valid.json | 7 - .../parameters/TopicParameters_all_params.json | 62 --- .../parameters/TopicParameters_invalid.json | 6 - .../TopicParameters_missing_mandatory.json | 12 - .../parameters/TopicParameters_valid.json | 30 -- .../rest/RestServerParameters_invalid.json | 6 + .../endpoints/rest/RestServerParameters_valid.json | 7 + .../endpoints/rest/TopicParameters_all_params.json | 62 +++ .../endpoints/rest/TopicParameters_invalid.json | 6 + .../rest/TopicParameters_missing_mandatory.json | 12 + .../endpoints/rest/TopicParameters_valid.json | 30 ++ pom.xml | 9 +- spring-utils/pom.xml | 10 +- utils-test/pom.xml | 75 +++- utils/pom.xml | 56 ++- .../common/utils/properties/PropertyUtils.java | 123 ++++++ .../common/utils/report/HealthCheckReport.java | 44 ++ .../common/utils/services/OrderedServiceImpl.java | 21 +- .../common/utils/properties/PropertyUtilsTest.java | 110 +++++ .../common/utils/report/TestHealthCheckReport.java | 78 ++++ .../common/utils/resources/ResourceUtilsTest.java | 2 +- 248 files changed, 12541 insertions(+), 12037 deletions(-) create mode 100644 common-parameters/src/main/java/org/onap/policy/common/parameters/rest/RestClientParameters.java create mode 100644 common-parameters/src/main/java/org/onap/policy/common/parameters/rest/RestServerParameters.java create mode 100644 common-parameters/src/main/java/org/onap/policy/common/parameters/topic/BusTopicParams.java create mode 100644 common-parameters/src/main/java/org/onap/policy/common/parameters/topic/TopicParameterGroup.java create mode 100644 common-parameters/src/main/java/org/onap/policy/common/parameters/topic/TopicParameters.java create mode 100644 common-parameters/src/test/java/org/onap/policy/common/parameters/rest/RestClientParametersTest.java create mode 100644 common-parameters/src/test/java/org/onap/policy/common/parameters/topic/BusTopicParamsTest.java create mode 100644 message-bus/pom.xml create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/Topic.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicEndpoint.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicEndpointManager.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicEndpointProxy.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicListener.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicRegisterable.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicSink.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicSource.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/ApiKeyEnabled.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusConsumer.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusPublisher.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusTopicBase.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusTopicSink.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusTopicSource.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/InlineBusTopicSink.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/SingleThreadedBusTopicSource.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/TopicBase.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/TopicBaseFactory.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/TopicBaseHashedFactory.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/client/BidirectionalTopicClient.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/client/BidirectionalTopicClientException.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/client/TopicSinkClient.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/client/TopicSinkClientException.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/IndexedKafkaTopicSinkFactory.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/IndexedKafkaTopicSourceFactory.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/InlineKafkaTopicSink.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaPublisherWrapper.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicFactories.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSink.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSinkFactory.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSource.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSourceFactory.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/SingleThreadedKafkaTopicSource.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicEndpoint.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicFactories.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicFactory.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSink.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSinkFactory.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSource.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSourceFactory.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/features/NetLoggerFeatureApi.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/features/NetLoggerFeatureProviders.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/properties/MessageBusProperties.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/utils/KafkaPropertyUtils.java create mode 100644 message-bus/src/main/java/org/onap/policy/common/message/bus/utils/NetLoggerUtil.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/CommonTestData.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/TopicEndpointProxyTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/TopicParameterGroupTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/BusConsumerTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/BusTopicBaseTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/BusTopicFactoryTestBase.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/InlineBusTopicSinkTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/SingleThreadedBusTopicSourceTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/TopicBaseTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/TopicFactoryTestBase.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/TopicPropertyBuilder.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/TopicTestBase.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/client/BidirectionalTopicClientTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/client/TopicClientExceptionTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/client/TopicSinkClientTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/IndexedKafkaTopicSourceFactoryTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/InlineKafkaTopicSinkTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaPublisherWrapperTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicFactoryTestBase.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicPropertyBuilder.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSinkFactoryTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSinkTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSourceFactoryTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSourceTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/SingleThreadedKafkaTopicSourceTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicEndpointTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicFactoryTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicPropertyBuilder.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSinkFactoryTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSinkTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSourceFactoryTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSourceTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/features/NetLoggerFeatureApiTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/utils/KafkaPropertyUtilsTest.java create mode 100644 message-bus/src/test/java/org/onap/policy/common/message/bus/utils/NetLoggerUtilTest.java create mode 100644 message-bus/src/test/resources/META-INF/services/org.onap.policy.common.message.bus.features.NetLoggerFeatureApi create mode 100644 message-bus/src/test/resources/logback-test.xml create mode 100644 message-bus/src/test/resources/org/onap/policy/common/message/bus/event/TopicEndpointProxyTest.json create mode 100644 message-bus/src/test/resources/org/onap/policy/common/message/bus/event/base/BusTopicBaseTest.json create mode 100644 message-bus/src/test/resources/org/onap/policy/common/message/bus/event/base/InlineBusTopicSinkTest.json create mode 100644 message-bus/src/test/resources/org/onap/policy/common/message/bus/event/base/SingleThreadedBusTopicSourceTest.json create mode 100644 message-bus/src/test/resources/org/onap/policy/common/message/bus/event/base/TopicBaseTest.json create mode 100644 message-bus/src/test/resources/org/onap/policy/common/message/bus/parameters/TopicParameters_all_params.json create mode 100644 message-bus/src/test/resources/org/onap/policy/common/message/bus/parameters/TopicParameters_invalid.json create mode 100644 message-bus/src/test/resources/org/onap/policy/common/message/bus/parameters/TopicParameters_missing_mandatory.json create mode 100644 message-bus/src/test/resources/org/onap/policy/common/message/bus/parameters/TopicParameters_valid.json delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/Topic.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicEndpoint.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicEndpointManager.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicEndpointProxy.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicListener.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicRegisterable.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicSink.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicSource.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/ApiKeyEnabled.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/BusTopicSink.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/BusTopicSource.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/IndexedKafkaTopicSinkFactory.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/IndexedKafkaTopicSourceFactory.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicFactories.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSink.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSinkFactory.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSource.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSourceFactory.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicEndpoint.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicFactories.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicFactory.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSink.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSinkFactory.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSource.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSourceFactory.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/TopicBaseFactory.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/TopicBaseHashedFactory.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusConsumer.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusPublisher.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicBase.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicParams.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineBusTopicSink.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineKafkaTopicSink.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedBusTopicSource.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedKafkaTopicSource.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/TopicBase.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/BidirectionalTopicClient.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/BidirectionalTopicClientException.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClient.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientException.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/features/NetLoggerFeatureApi.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/features/NetLoggerFeatureProviders.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/parameters/RestClientParameters.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/parameters/RestServerParameters.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/parameters/TopicParameterGroup.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/parameters/TopicParameters.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/report/HealthCheckReport.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/utils/KafkaPropertyUtils.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/utils/NetLoggerUtil.java delete mode 100644 policy-endpoints/src/main/java/org/onap/policy/common/endpoints/utils/PropertyUtils.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/TopicEndpointProxyTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/BusTopicFactoryTestBase.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/IndexedKafkaTopicSourceFactoryTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicFactoryTestBase.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicPropertyBuilder.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSinkFactoryTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSinkTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSourceFactoryTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSourceTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicEndpointTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicFactoryTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicPropertyBuilder.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSinkFactoryTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSinkTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSourceFactoryTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSourceTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/TopicFactoryTestBase.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/TopicPropertyBuilder.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/TopicTestBase.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusConsumerTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicBaseTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicParamsTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineBusTopicSinkTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineKafkaTopicSinkTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/KafkaPublisherWrapperTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedBusTopicSourceTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedKafkaTopicSourceTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/TopicBaseTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/BidirectionalTopicClientTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/TopicClientExceptionTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/features/NetLoggerFeatureApiTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/parameters/CommonTestData.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/parameters/RestClientParametersTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/parameters/RestServerParametersTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/parameters/TopicParameterGroupTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/report/TestHealthCheckReport.java create mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/rest/CommonTestData.java create mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/rest/RestServerParametersTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/utils/KafkaPropertyUtilsTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/utils/NetLoggerUtilTest.java delete mode 100644 policy-endpoints/src/test/java/org/onap/policy/common/endpoints/utils/PropertyUtilsTest.java delete mode 100644 policy-endpoints/src/test/resources/META-INF/services/org.onap.policy.common.endpoints.features.NetLoggerFeatureApi delete mode 100644 policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/TopicEndpointProxyTest.json delete mode 100644 policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicBaseTest.json delete mode 100644 policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineBusTopicSinkTest.json delete mode 100644 policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineKafkaTopicSinkTest.json delete mode 100644 policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedBusTopicSourceTest.json delete mode 100644 policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedKafkaTopicSourceTest.json delete mode 100644 policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/TopicBaseTest.json delete mode 100644 policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/RestServerParameters_invalid.json delete mode 100644 policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/RestServerParameters_valid.json delete mode 100644 policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_all_params.json delete mode 100644 policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_invalid.json delete mode 100644 policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_missing_mandatory.json delete mode 100644 policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_valid.json create mode 100644 policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/RestServerParameters_invalid.json create mode 100644 policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/RestServerParameters_valid.json create mode 100644 policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/TopicParameters_all_params.json create mode 100644 policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/TopicParameters_invalid.json create mode 100644 policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/TopicParameters_missing_mandatory.json create mode 100644 policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/TopicParameters_valid.json create mode 100644 utils/src/main/java/org/onap/policy/common/utils/properties/PropertyUtils.java create mode 100644 utils/src/main/java/org/onap/policy/common/utils/report/HealthCheckReport.java create mode 100644 utils/src/test/java/org/onap/policy/common/utils/properties/PropertyUtilsTest.java create mode 100644 utils/src/test/java/org/onap/policy/common/utils/report/TestHealthCheckReport.java diff --git a/common-parameters/pom.xml b/common-parameters/pom.xml index 3257d3b3..5c112a91 100644 --- a/common-parameters/pom.xml +++ b/common-parameters/pom.xml @@ -19,7 +19,8 @@ SPDX-License-Identifier: Apache-2.0 ============LICENSE_END========================================================= --> - + 4.0.0 org.onap.policy.common @@ -29,17 +30,18 @@ common-parameters ${project.artifactId} - [${project.parent.artifactId}] module provides common property and parameter handling the ONAP Policy Framework + [${project.parent.artifactId}] module provides common property and parameter handling the ONAP Policy + Framework + - org.slf4j - slf4j-api - provided + com.google.code.gson + gson - org.projectlombok - lombok + com.google.re2j + re2j jakarta.validation @@ -50,21 +52,22 @@ commons-lang3 - com.google.re2j - re2j + org.projectlombok + lombok - com.google.code.gson - gson + org.slf4j + slf4j-api - org.assertj - assertj-core + org.mockito + mockito-core test - org.mockito - mockito-core + org.assertj + assertj-core + test diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterGroup.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterGroup.java index ab610933..c26b7b44 100644 --- a/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterGroup.java +++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterGroup.java @@ -1,8 +1,9 @@ /*- - * ============LICENSE_START======================================================= + * ============LICENSE_START========================================================= * Copyright (C) 2018 Ericsson. All rights reserved. * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. - * ================================================================================ + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================== * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -33,14 +34,14 @@ public interface ParameterGroup { * * @return the group name */ - public String getName(); + String getName(); /** * Set the group name. * * @param name the group name */ - public void setName(final String name); + void setName(final String name); /** * Validate parameters. diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/ValidationResult.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/ValidationResult.java index 309fd001..e6017410 100644 --- a/common-parameters/src/main/java/org/onap/policy/common/parameters/ValidationResult.java +++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/ValidationResult.java @@ -1,19 +1,20 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2018 Ericsson. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ @@ -29,14 +30,14 @@ public interface ValidationResult { * * @return the name */ - public String getName(); + String getName(); /** * Gets the status of validation. * * @return the status */ - public ValidationStatus getStatus(); + ValidationStatus getStatus(); /** * Checks if the result is valid. @@ -44,7 +45,7 @@ public interface ValidationResult { * @return true, if is valid */ default boolean isValid() { - return getStatus().isValid(); + return getStatus().isValid(); } /** @@ -53,7 +54,7 @@ public interface ValidationResult { * @return true, if is clean */ default boolean isClean() { - return getStatus().isClean(); + return getStatus().isClean(); } /** @@ -63,25 +64,26 @@ public interface ValidationResult { */ default String getResult() { return getResult( - ParameterConstants.DEFAULT_INITIAL_RESULT_INDENTATION, - ParameterConstants.DEFAULT_RESULT_INDENTATION, - ParameterConstants.DO_NOT_SHOW_CLEAN_RESULTS); + ParameterConstants.DEFAULT_INITIAL_RESULT_INDENTATION, + ParameterConstants.DEFAULT_RESULT_INDENTATION, + ParameterConstants.DO_NOT_SHOW_CLEAN_RESULTS); } /** * Gets the validation result. * * @param initialIndentation the indentation to use on the main result output - * @param subIndentation the indentation to use on sub parts of the result output - * @param showClean output information on clean fields + * @param subIndentation the indentation to use on sub parts of the result output + * @param showClean output information on clean fields * @return the result */ - public String getResult(final String initialIndentation, final String subIndentation, final boolean showClean); - + String getResult(final String initialIndentation, final String subIndentation, final boolean showClean); + /** - * Set a validation result. - * @param status The validation status the field is receiving + * Set a validation result. + * + * @param status The validation status the field is receiving * @param message The validation message explaining the validation status */ - public void setResult(final ValidationStatus status, final String message); + void setResult(final ValidationStatus status, final String message); } \ No newline at end of file diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/rest/RestClientParameters.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/rest/RestClientParameters.java new file mode 100644 index 00000000..bb03c066 --- /dev/null +++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/rest/RestClientParameters.java @@ -0,0 +1,57 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021, 2024 Nordix Foundation. + * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.parameters.rest; + +import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.common.parameters.ParameterGroup; +import org.onap.policy.common.parameters.ValidationStatus; +import org.onap.policy.common.parameters.topic.BusTopicParams; + +public class RestClientParameters extends BusTopicParams implements ParameterGroup { + + private static final String MSG_IS_BLANK = "is blank"; + + @Override + public String getName() { + return getClientName(); + } + + @Override + public void setName(String name) { + setClientName(name); + } + + @Override + public BeanValidationResult validate() { + var result = new BeanValidationResult(getClientName(), this); + if (isHostnameInvalid()) { + result.addResult("hostname", getHostname(), ValidationStatus.INVALID, MSG_IS_BLANK); + } + if (isClientNameInvalid()) { + result.addResult("clientName", getClientName(), ValidationStatus.INVALID, MSG_IS_BLANK); + } + if (isPortInvalid()) { + result.addResult("port", getPort(), ValidationStatus.INVALID, "is not valid"); + } + return result; + } +} diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/rest/RestServerParameters.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/rest/RestServerParameters.java new file mode 100644 index 00000000..8684b163 --- /dev/null +++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/rest/RestServerParameters.java @@ -0,0 +1,57 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019, 2023-2024 Nordix Foundation. + * Modifications Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2021 Bell Canada. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.parameters.rest; + +import lombok.Getter; +import org.onap.policy.common.parameters.ParameterGroupImpl; +import org.onap.policy.common.parameters.annotations.Min; +import org.onap.policy.common.parameters.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; + +/** + * Class to hold all parameters needed for rest server. + * + * @author Ajith Sreekumar (ajith.sreekumar@est.tech) + */ +@NotBlank +@Getter +public class RestServerParameters extends ParameterGroupImpl { + @NotNull + private String host; + + @Min(value = 1) + private int port; + + private String userName; + private String password; + private boolean https; + private boolean sniHostCHeck; + private boolean aaf; + private boolean prometheus; + private String servletClass; + private String servletUriPath; + + public RestServerParameters() { + super(RestServerParameters.class.getSimpleName()); + } +} diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/topic/BusTopicParams.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/topic/BusTopicParams.java new file mode 100644 index 00000000..66ac57c5 --- /dev/null +++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/topic/BusTopicParams.java @@ -0,0 +1,338 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. + * Modifications Copyright (C) 2018-2019, 2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019, 2023-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.parameters.topic; + +import java.util.List; +import java.util.Map; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.apache.commons.lang3.StringUtils; + +/** + * Member variables of this Params class are as follows. + * + *

servers Kafka servers + * topic Kafka Topic to be monitored + * apiKey Kafka API Key (optional) + * apiSecret Kafka API Secret (optional) + * consumerGroup kafka Reader Consumer Group + * consumerInstance Kafka Reader Instance + * fetchTimeout kafka fetch timeout + * fetchLimit Kafka fetch limit + * environment DME2 Environment + * aftEnvironment DME2 AFT Environment + * partner DME2 Partner + * latitude DME2 Latitude + * longitude DME2 Longitude + * additionalProps Additional properties to pass to DME2 + * useHttps does connection use HTTPS? + * allowTracing is message tracing allowed? + * allowSelfSignedCerts are self-signed certificates allow + */ +@Getter +@Setter +public class BusTopicParams { + + private int port; + private List servers; + private Map additionalProps; + private String topic; + private String effectiveTopic; + private String apiKey; + private String apiSecret; + private String consumerGroup; + private String consumerInstance; + private int fetchTimeout; + private int fetchLimit; + private boolean useHttps; + private boolean allowTracing; + private boolean allowSelfSignedCerts; + private boolean managed; + + private String userName; + private String password; + private String environment; + private String aftEnvironment; + private String partner; + private String latitude; + private String longitude; + private String partitionId; + private String clientName; + private String hostname; + private String basePath; + @Getter + private String serializationProvider; + + public static TopicParamsBuilder builder() { + return new TopicParamsBuilder(); + } + + /** + * Methods to Check if the property is INVALID. + */ + + boolean isEnvironmentInvalid() { + return StringUtils.isBlank(environment); + } + + boolean isAftEnvironmentInvalid() { + return StringUtils.isBlank(aftEnvironment); + } + + boolean isLatitudeInvalid() { + return StringUtils.isBlank(latitude); + } + + boolean isLongitudeInvalid() { + return StringUtils.isBlank(longitude); + } + + public boolean isConsumerInstanceInvalid() { + return StringUtils.isBlank(consumerInstance); + } + + public boolean isConsumerGroupInvalid() { + return StringUtils.isBlank(consumerGroup); + } + + public boolean isClientNameInvalid() { + return StringUtils.isBlank(clientName); + } + + boolean isPartnerInvalid() { + return StringUtils.isBlank(partner); + } + + boolean isServersInvalid() { + return (servers == null || servers.isEmpty() + || (servers.size() == 1 && ("".equals(servers.get(0))))); + } + + public boolean isTopicInvalid() { + return StringUtils.isBlank(topic); + } + + public boolean isPartitionIdInvalid() { + return StringUtils.isBlank(partitionId); + } + + public boolean isHostnameInvalid() { + return StringUtils.isBlank(hostname); + } + + public boolean isPortInvalid() { + return (getPort() <= 0 || getPort() >= 65535); + } + + /** + * Methods to Check if the property is Valid. + */ + + boolean isApiKeyValid() { + return StringUtils.isNotBlank(apiKey); + } + + boolean isApiSecretValid() { + return StringUtils.isNotBlank(apiSecret); + } + + boolean isUserNameValid() { + return StringUtils.isNotBlank(userName); + } + + boolean isPasswordValid() { + return StringUtils.isNotBlank(password); + } + + public boolean isAdditionalPropsValid() { + return additionalProps != null; + } + + public void setEffectiveTopic(String effectiveTopic) { + this.effectiveTopic = topicToLowerCase(effectiveTopic); + } + + public void setTopic(String topic) { + this.topic = topicToLowerCase(topic); + } + + public String getEffectiveTopic() { + return topicToLowerCase(effectiveTopic); + } + + public String getTopic() { + return topicToLowerCase(topic); + } + + private String topicToLowerCase(String topic) { + return (topic == null || topic.isEmpty()) ? topic : topic.toLowerCase(); + } + + @NoArgsConstructor(access = AccessLevel.PRIVATE) + public static class TopicParamsBuilder { + + final BusTopicParams params = new BusTopicParams(); + + public TopicParamsBuilder servers(List servers) { + this.params.servers = servers; + return this; + } + + public TopicParamsBuilder topic(String topic) { + this.params.setTopic(topic); + return this; + } + + public TopicParamsBuilder effectiveTopic(String effectiveTopic) { + this.params.setEffectiveTopic(effectiveTopic); + return this; + } + + public TopicParamsBuilder apiKey(String apiKey) { + this.params.apiKey = apiKey; + return this; + } + + public TopicParamsBuilder apiSecret(String apiSecret) { + this.params.apiSecret = apiSecret; + return this; + } + + public TopicParamsBuilder consumerGroup(String consumerGroup) { + this.params.consumerGroup = consumerGroup; + return this; + } + + public TopicParamsBuilder consumerInstance(String consumerInstance) { + this.params.consumerInstance = consumerInstance; + return this; + } + + public TopicParamsBuilder fetchTimeout(int fetchTimeout) { + this.params.fetchTimeout = fetchTimeout; + return this; + } + + public TopicParamsBuilder fetchLimit(int fetchLimit) { + this.params.fetchLimit = fetchLimit; + return this; + } + + public TopicParamsBuilder useHttps(boolean useHttps) { + this.params.useHttps = useHttps; + return this; + } + + public TopicParamsBuilder allowTracing(boolean allowTracing) { + this.params.allowTracing = allowTracing; + return this; + } + + public TopicParamsBuilder allowSelfSignedCerts(boolean allowSelfSignedCerts) { + this.params.allowSelfSignedCerts = allowSelfSignedCerts; + return this; + } + + public TopicParamsBuilder userName(String userName) { + this.params.userName = userName; + return this; + } + + public TopicParamsBuilder password(String password) { + this.params.password = password; + return this; + } + + public TopicParamsBuilder environment(String environment) { + this.params.environment = environment; + return this; + } + + public TopicParamsBuilder aftEnvironment(String aftEnvironment) { + this.params.aftEnvironment = aftEnvironment; + return this; + } + + public TopicParamsBuilder partner(String partner) { + this.params.partner = partner; + return this; + } + + public TopicParamsBuilder latitude(String latitude) { + this.params.latitude = latitude; + return this; + } + + public TopicParamsBuilder longitude(String longitude) { + this.params.longitude = longitude; + return this; + } + + public TopicParamsBuilder additionalProps(Map additionalProps) { + this.params.additionalProps = additionalProps; + return this; + } + + public TopicParamsBuilder partitionId(String partitionId) { + this.params.partitionId = partitionId; + return this; + } + + public BusTopicParams build() { + return params; + } + + public TopicParamsBuilder managed(boolean managed) { + this.params.managed = managed; + return this; + } + + public TopicParamsBuilder hostname(String hostname) { + this.params.hostname = hostname; + return this; + } + + public TopicParamsBuilder clientName(String clientName) { + this.params.clientName = clientName; + return this; + } + + public TopicParamsBuilder port(int port) { + this.params.port = port; + return this; + } + + public TopicParamsBuilder basePath(String basePath) { + this.params.basePath = basePath; + return this; + } + + public TopicParamsBuilder serializationProvider(String serializationProvider) { + this.params.serializationProvider = serializationProvider; + return this; + } + } +} + diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/topic/TopicParameterGroup.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/topic/TopicParameterGroup.java new file mode 100644 index 00000000..c9d5e3e8 --- /dev/null +++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/topic/TopicParameterGroup.java @@ -0,0 +1,92 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019, 2024 Nordix Foundation. + * Modifications Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.parameters.topic; + +import java.util.List; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.StringUtils; +import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.common.parameters.ParameterGroupImpl; +import org.onap.policy.common.parameters.ValidationStatus; +import org.onap.policy.common.parameters.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; + +/** + * Class to hold all parameters needed for topic properties. + * + * @author Ajith Sreekumar (ajith.sreekumar@est.tech) + */ +@NotNull +@NotBlank +@Getter +@Setter +public class TopicParameterGroup extends ParameterGroupImpl { + + private List topicSources; + private List topicSinks; + + public TopicParameterGroup() { + super(TopicParameterGroup.class.getSimpleName()); + } + + /** + * {@inheritDoc}. + */ + @Override + public BeanValidationResult validate() { + BeanValidationResult result = super.validate(); + if (result.isValid()) { + var errorMsg = new StringBuilder(); + StringBuilder missingSourceParams = checkMissingMandatoryParams(topicSources); + if (!missingSourceParams.isEmpty()) { + errorMsg.append(missingSourceParams.append("missing in topicSources. ")); + } + StringBuilder missingSinkParams = checkMissingMandatoryParams(topicSinks); + if (!missingSinkParams.isEmpty()) { + errorMsg.append(missingSinkParams.append("missing in topicSinks.")); + } + + if (!errorMsg.isEmpty()) { + errorMsg.insert(0, "Mandatory parameters are missing. "); + result.setResult(ValidationStatus.INVALID, errorMsg.toString()); + } + } + return result; + } + + private StringBuilder checkMissingMandatoryParams(List topicParametersList) { + var missingParams = new StringBuilder(); + for (TopicParameters topicParameters : topicParametersList) { + if (StringUtils.isBlank(topicParameters.getTopic())) { + missingParams.append("topic, "); + } + if (StringUtils.isBlank(topicParameters.getTopicCommInfrastructure())) { + missingParams.append("topicCommInfrastructure, "); + } + if (null == topicParameters.getServers() || topicParameters.getServers().isEmpty()) { + missingParams.append("servers, "); + } + } + return missingParams; + } +} diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/topic/TopicParameters.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/topic/TopicParameters.java new file mode 100644 index 00000000..2b8bfbdb --- /dev/null +++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/topic/TopicParameters.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019, 2024 Nordix Foundation. + * Modifications Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.parameters.topic; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import org.onap.policy.common.parameters.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; + +/** + * Class to hold topic details such as name, server and topicCommInfrastructure. + * + * @author Ajith Sreekumar (ajith.sreekumar@est.tech) + */ +@NotNull +@NotBlank +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +public class TopicParameters extends BusTopicParams { + private String topicCommInfrastructure; + + public TopicParameters() { + // this defaults to true + setManaged(true); + } +} diff --git a/common-parameters/src/test/java/org/onap/policy/common/parameters/TestBeanValidationResult.java b/common-parameters/src/test/java/org/onap/policy/common/parameters/TestBeanValidationResult.java index 2fc09949..ab733aed 100644 --- a/common-parameters/src/test/java/org/onap/policy/common/parameters/TestBeanValidationResult.java +++ b/common-parameters/src/test/java/org/onap/policy/common/parameters/TestBeanValidationResult.java @@ -112,7 +112,7 @@ class TestBeanValidationResult { @Test void testValidateNotNullList() { - List list = Arrays.asList(clean); + List list = List.of(clean); assertTrue(bean.validateNotNullList(MY_LIST, list, item -> item)); assertTrue(bean.isValid()); assertNull(bean.getResult()); @@ -141,7 +141,7 @@ class TestBeanValidationResult { assertTrue(bean.isValid()); assertNull(bean.getResult()); - list = Arrays.asList(clean); + list = List.of(clean); bean = new BeanValidationResult(NAME, OBJECT); assertTrue(bean.validateList(MY_LIST, list, item -> item)); assertTrue(bean.isValid()); diff --git a/common-parameters/src/test/java/org/onap/policy/common/parameters/TestBeanValidator.java b/common-parameters/src/test/java/org/onap/policy/common/parameters/TestBeanValidator.java index 31c34209..c4211136 100644 --- a/common-parameters/src/test/java/org/onap/policy/common/parameters/TestBeanValidator.java +++ b/common-parameters/src/test/java/org/onap/policy/common/parameters/TestBeanValidator.java @@ -82,9 +82,6 @@ class TestBeanValidator { data.strValue = STRING_VALUE; assertTrue(validator.validateTop(TOP, data).isValid()); - /** - * Repeat with a subclass. - */ @Getter class Derived extends Data { @Min(10) @@ -119,8 +116,8 @@ class TestBeanValidator { @Test void testVerNotNull() { + @Getter class NotNullCheck { - @Getter @Min(1) @NotNull Integer intValue; @@ -138,8 +135,8 @@ class TestBeanValidator { @Test void testVerNotBlank() { + @Getter class NotBlankCheck { - @Getter @NotBlank String strValue; } @@ -164,8 +161,8 @@ class TestBeanValidator { /* * Class with "blank" annotation on an integer. */ + @Getter class NotBlankInt { - @Getter @NotBlank int intValue; } @@ -180,8 +177,8 @@ class TestBeanValidator { */ @Test void testVerSizeCollection() { + @Getter class CollectionSizeCheck { - @Getter @Size(min = 3) Collection items; } @@ -210,8 +207,8 @@ class TestBeanValidator { */ @Test void testVerSizeMap() { + @Getter class MapSizeCheck { - @Getter @Size(min = 3) Map items; } @@ -240,8 +237,8 @@ class TestBeanValidator { */ @Test void testVerSizeOther() { + @Getter class OtherSizeCheck { - @Getter @Size(min = 3) Integer items; } @@ -254,8 +251,8 @@ class TestBeanValidator { @Test void testVerRegex() { + @Getter class RegexCheck { - @Getter @Pattern(regexp = "[a-f]*") String strValue; } @@ -272,8 +269,8 @@ class TestBeanValidator { assertTrue(validator.validateTop(TOP, regexCheck).isValid()); // invalid regex + @Getter class InvalidRegexCheck { - @Getter @Pattern(regexp = "[a-f") String strValue; } @@ -292,8 +289,8 @@ class TestBeanValidator { /* * Class with "regex" annotation on an integer. */ + @Getter class RegexInt { - @Getter @Pattern(regexp = "[a-f]*") int intValue; } @@ -309,8 +306,8 @@ class TestBeanValidator { /* * Field is not a number. */ + @Getter class NonNumeric { - @Getter @Max(100) String strValue; } @@ -322,68 +319,68 @@ class TestBeanValidator { /* * Integer field. */ + @Getter class IntField { - @Getter @Max(100) Integer intValue; } // ok value IntField intField = new IntField(); - assertNumeric("testVerMax-integer", intField, value -> { + assertNumeric(intField, value -> { intField.intValue = value; - }, INT_FIELD, "maximum", INT_VALUE, 100, 101); + }, INT_FIELD, "maximum", 100, 101); /* * Long field. */ + @Getter class LongField { - @Getter @Max(100) Long numValue; } // ok value LongField longField = new LongField(); - assertNumeric("testVerMax-long", longField, value -> { + assertNumeric(longField, value -> { longField.numValue = (long) value; - }, NUM_FIELD, "maximum", INT_VALUE, 100, 101); + }, NUM_FIELD, "maximum", 100, 101); /* * Float field. */ + @Getter class FloatField { - @Getter @Max(100) Float numValue; } // ok value FloatField floatField = new FloatField(); - assertNumeric("testVerMax-float", floatField, value -> { + assertNumeric(floatField, value -> { floatField.numValue = (float) value; - }, NUM_FIELD, "maximum", INT_VALUE, 100, 101); + }, NUM_FIELD, "maximum", 100, 101); /* * Double field. */ + @Getter class DoubleField { - @Getter @Max(100) Double numValue; } // ok value DoubleField doubleField = new DoubleField(); - assertNumeric("testVerMax-double", doubleField, value -> { + assertNumeric(doubleField, value -> { doubleField.numValue = (double) value; - }, NUM_FIELD, "maximum", INT_VALUE, 100, 101); + }, NUM_FIELD, "maximum", 100, 101); /* * Atomic Integer field (which is a subclass of Number). */ + @Getter class AtomIntValue { - @Getter @Max(100) AtomicInteger numValue; } @@ -403,8 +400,8 @@ class TestBeanValidator { /* * Field is not a number. */ + @Getter class NonNumeric { - @Getter @Min(10) String strValue; } @@ -416,68 +413,68 @@ class TestBeanValidator { /* * Integer field. */ + @Getter class IntField { - @Getter @Min(10) Integer intValue; } // ok value IntField intField = new IntField(); - assertNumeric("testVerMin-integer", intField, value -> { + assertNumeric(intField, value -> { intField.intValue = value; - }, INT_FIELD, "minimum", INT_VALUE, 10, 1); + }, INT_FIELD, "minimum", 10, 1); /* * Long field. */ + @Getter class LongField { - @Getter @Min(10) Long numValue; } // ok value LongField longField = new LongField(); - assertNumeric("testVerMin-long", longField, value -> { + assertNumeric(longField, value -> { longField.numValue = (long) value; - }, NUM_FIELD, "minimum", INT_VALUE, 10, 1); + }, NUM_FIELD, "minimum", 10, 1); /* * Float field. */ + @Getter class FloatField { - @Getter @Min(10) Float numValue; } // ok value FloatField floatField = new FloatField(); - assertNumeric("testVerMin-float", floatField, value -> { + assertNumeric(floatField, value -> { floatField.numValue = (float) value; - }, NUM_FIELD, "minimum", INT_VALUE, 10, 1); + }, NUM_FIELD, "minimum", 10, 1); /* * Double field. */ + @Getter class DoubleField { - @Getter @Min(10) Double numValue; } // ok value DoubleField doubleField = new DoubleField(); - assertNumeric("testVerMin-double", doubleField, value -> { + assertNumeric(doubleField, value -> { doubleField.numValue = (double) value; - }, NUM_FIELD, "minimum", INT_VALUE, 10, 1); + }, NUM_FIELD, "minimum", 10, 1); /* * Atomic Integer field (which is a subclass of Number). */ + @Getter class AtomIntValue { - @Getter @Min(10) AtomicInteger numValue; } @@ -494,8 +491,8 @@ class TestBeanValidator { @Test void testVerClassName() { + @Getter class ClassNameCheck { - @Getter @ClassName String strValue; } @@ -518,8 +515,8 @@ class TestBeanValidator { @Test void testVerCascade() { + @Getter class Item { - @Getter @NotNull Integer intValue; } @@ -626,27 +623,26 @@ class TestBeanValidator { @Test void testGetEntryName() { - assertThat(validator.getEntryName(makeEntry(null, 0))).isEmpty(); - assertThat(validator.getEntryName(makeEntry("", 0))).isEmpty(); - assertThat(validator.getEntryName(makeEntry(STRING_VALUE, 0))).isEqualTo(STRING_VALUE); + assertThat(validator.getEntryName(makeEntry(null))).isEmpty(); + assertThat(validator.getEntryName(makeEntry(""))).isEmpty(); + assertThat(validator.getEntryName(makeEntry(STRING_VALUE))).isEqualTo(STRING_VALUE); } /** * Makes a Map entry with the given key and value. * * @param key desired key - * @param value desired value * @return a new Map entry */ - private Map.Entry makeEntry(String key, int value) { + private Map.Entry makeEntry(String key) { HashMap map = new HashMap<>(); - map.put(key, value); + map.put(key, 0); return map.entrySet().iterator().next(); } - private void assertNumeric(String testName, T object, Consumer setter, String fieldName, - String expectedText, int inside, int edge, int outside) { - setter.accept(inside); + private void assertNumeric(T object, Consumer setter, String fieldName, + String expectedText, int edge, int outside) { + setter.accept(TestBeanValidator.INT_VALUE); assertTrue(validator.validateTop(TOP, object).isValid()); // on the edge diff --git a/common-parameters/src/test/java/org/onap/policy/common/parameters/TestFieldValidator.java b/common-parameters/src/test/java/org/onap/policy/common/parameters/TestFieldValidator.java index 0fb39b0f..0659ad81 100644 --- a/common-parameters/src/test/java/org/onap/policy/common/parameters/TestFieldValidator.java +++ b/common-parameters/src/test/java/org/onap/policy/common/parameters/TestFieldValidator.java @@ -101,7 +101,7 @@ class TestFieldValidator extends ValidatorUtil { private int voidMethod; /** - * Accessor is {@link #getParameterizedMethod()}, which requires a parameter. + * Accessor is {@link #getParameterizedMethod(boolean)}, which requires a parameter. */ @Min(0) private int parameterizedMethod; @@ -357,7 +357,7 @@ class TestFieldValidator extends ValidatorUtil { } public int getParameterizedMethod(boolean flag) { - return 0; + return flag ? 0 : 1; } public int getExMethod() { diff --git a/common-parameters/src/test/java/org/onap/policy/common/parameters/rest/RestClientParametersTest.java b/common-parameters/src/test/java/org/onap/policy/common/parameters/rest/RestClientParametersTest.java new file mode 100644 index 00000000..0e5df570 --- /dev/null +++ b/common-parameters/src/test/java/org/onap/policy/common/parameters/rest/RestClientParametersTest.java @@ -0,0 +1,116 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.parameters.rest; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.common.parameters.ValidationStatus; + +class RestClientParametersTest { + + private RestClientParameters params; + + @BeforeEach + void setUp() { + params = new RestClientParameters(); + } + + @Test + void testValidate_ValidParameters() { + params.setHostname("localhost"); + params.setClientName("testClient"); + params.setPort(8080); + + BeanValidationResult result = params.validate(); + + assertEquals(ValidationStatus.CLEAN, result.getStatus(), "Expected the parameters to be valid"); + assertNull(result.getResult(), "Expected no validation errors"); + } + + @Test + void testValidate_InvalidHostname() { + params.setHostname(""); + params.setClientName("testClient"); + params.setPort(8080); + + BeanValidationResult result = params.validate(); + + assertEquals(ValidationStatus.INVALID, result.getStatus(), "Expected the parameters to be invalid"); + assertTrue(result.getResult().contains("hostname") && result.getResult().contains("is blank"), + "Expected invalid hostname error message"); + } + + @Test + void testValidate_InvalidClientName() { + params.setHostname("localhost"); + params.setClientName(""); + params.setPort(8080); + + BeanValidationResult result = params.validate(); + + assertEquals(ValidationStatus.INVALID, result.getStatus(), "Expected the parameters to be invalid"); + assertTrue(result.getResult().contains("clientName") && result.getResult().contains("is blank"), + "Expected invalid clientName error message"); + } + + @Test + void testValidate_InvalidPort() { + params.setHostname("localhost"); + params.setClientName("testClient"); + params.setPort(-1); + + BeanValidationResult result = params.validate(); + + assertEquals(ValidationStatus.INVALID, result.getStatus(), "Expected the parameters to be invalid"); + assertTrue(result.getResult().contains("port") && result.getResult().contains("is not valid"), + "Expected invalid port error message"); + } + + @Test + void testValidate_MultipleInvalidParameters() { + params.setHostname(""); + params.setClientName(""); + params.setPort(-1); + + BeanValidationResult result = params.validate(); + + assertEquals(ValidationStatus.INVALID, result.getStatus(), "Expected the parameters to be invalid"); + + assertTrue(result.getResult().contains("hostname") && result.getResult().contains("is blank"), + "Expected invalid hostname error message"); + + assertTrue(result.getResult().contains("clientName") && result.getResult().contains("is blank"), + "Expected invalid clientName error message"); + + assertTrue(result.getResult().contains("port") && result.getResult().contains("is not valid"), + "Expected invalid port error message"); + } + + @Test + void testGetAndSetName() { + String name = "testClient"; + params.setName(name); + assertEquals(name, params.getName(), "Expected the client name to be set and retrieved correctly"); + } +} diff --git a/common-parameters/src/test/java/org/onap/policy/common/parameters/topic/BusTopicParamsTest.java b/common-parameters/src/test/java/org/onap/policy/common/parameters/topic/BusTopicParamsTest.java new file mode 100644 index 00000000..c474e5fc --- /dev/null +++ b/common-parameters/src/test/java/org/onap/policy/common/parameters/topic/BusTopicParamsTest.java @@ -0,0 +1,201 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.parameters.topic; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.function.BiConsumer; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.policy.common.parameters.topic.BusTopicParams.TopicParamsBuilder; + +class BusTopicParamsTest { + + public static final String MY_AFT_ENV = "my-aft-env"; + public static final String MY_API_KEY = "my-api-key"; + public static final String MY_API_SECRET = "my-api-secret"; + public static final String MY_BASE_PATH = "my-base"; + public static final String MY_CLIENT_NAME = "my-client"; + public static final String MY_CONS_GROUP = "my-cons-group"; + public static final String MY_CONS_INST = "my-cons-inst"; + public static final String MY_ENV = "my-env"; + public static final int MY_FETCH_LIMIT = 100; + public static final int MY_FETCH_TIMEOUT = 101; + public static final String MY_HOST = "my-host"; + public static final String MY_LAT = "my-lat"; + public static final String MY_LONG = "my-long"; + public static final String MY_PARTNER = "my-partner"; + public static final String MY_PASS = "my-pass"; + public static final int MY_PORT = 102; + public static final String MY_TOPIC = "my-topic"; + public static final String MY_EFFECTIVE_TOPIC = "my-effective-topic"; + public static final String MY_USERNAME = "my-user"; + public static final String MY_PARTITION = "my-partition"; + public static final String MY_SERIALIZER = "org.apache.kafka.common.serialization.StringSerializer"; + + protected Map addProps; + protected TopicParamsBuilder builder; + + @BeforeEach + public void setUp() { + addProps = new TreeMap<>(); + addProps.put("my-key-A", "my-value-A"); + addProps.put("my-key-B", "my-value-B"); + + builder = makeBuilder(); + } + + @Test + void testGetters() { + BusTopicParams params = makeBuilder().build(); + + Assertions.assertEquals(addProps, params.getAdditionalProps()); + Assertions.assertEquals(MY_AFT_ENV, params.getAftEnvironment()); + assertTrue(params.isAllowSelfSignedCerts()); + Assertions.assertEquals(MY_API_KEY, params.getApiKey()); + Assertions.assertEquals(MY_API_SECRET, params.getApiSecret()); + Assertions.assertEquals(MY_BASE_PATH, params.getBasePath()); + Assertions.assertEquals(MY_CLIENT_NAME, params.getClientName()); + Assertions.assertEquals(MY_CONS_GROUP, params.getConsumerGroup()); + Assertions.assertEquals(MY_CONS_INST, params.getConsumerInstance()); + Assertions.assertEquals(MY_ENV, params.getEnvironment()); + Assertions.assertEquals(MY_FETCH_LIMIT, params.getFetchLimit()); + Assertions.assertEquals(MY_FETCH_TIMEOUT, params.getFetchTimeout()); + Assertions.assertEquals(MY_HOST, params.getHostname()); + Assertions.assertEquals(MY_LAT, params.getLatitude()); + Assertions.assertEquals(MY_LONG, params.getLongitude()); + assertTrue(params.isManaged()); + Assertions.assertEquals(MY_PARTITION, params.getPartitionId()); + Assertions.assertEquals(MY_PARTNER, params.getPartner()); + Assertions.assertEquals(MY_PASS, params.getPassword()); + Assertions.assertEquals(MY_PORT, params.getPort()); + Assertions.assertEquals(List.of("localhost"), params.getServers()); + Assertions.assertEquals(MY_TOPIC, params.getTopic()); + Assertions.assertEquals(MY_EFFECTIVE_TOPIC, params.getEffectiveTopic()); + assertTrue(params.isUseHttps()); + Assertions.assertEquals(MY_USERNAME, params.getUserName()); + } + + @Test + void testBooleanGetters() { + // ensure that booleans are independent of each other + testBoolean("true:false:false", TopicParamsBuilder::allowSelfSignedCerts); + testBoolean("false:true:false", TopicParamsBuilder::managed); + testBoolean("false:false:true", TopicParamsBuilder::useHttps); + } + + @Test + void testValidators() { + BusTopicParams params = makeBuilder().build(); + + // test validity methods + assertTrue(params.isAdditionalPropsValid()); + assertFalse(params.isAftEnvironmentInvalid()); + assertTrue(params.isApiKeyValid()); + assertTrue(params.isApiSecretValid()); + assertFalse(params.isClientNameInvalid()); + assertFalse(params.isConsumerGroupInvalid()); + assertFalse(params.isConsumerInstanceInvalid()); + assertFalse(params.isEnvironmentInvalid()); + assertFalse(params.isHostnameInvalid()); + assertFalse(params.isLatitudeInvalid()); + assertFalse(params.isLongitudeInvalid()); + assertFalse(params.isPartitionIdInvalid()); + assertFalse(params.isPartnerInvalid()); + assertTrue(params.isPasswordValid()); + assertFalse(params.isPortInvalid()); + assertFalse(params.isServersInvalid()); + assertFalse(params.isTopicInvalid()); + assertTrue(params.isUserNameValid()); + } + + @Test + void testInvertedValidators() { + Assertions.assertFalse(makeBuilder().additionalProps(null).build().isAdditionalPropsValid()); + Assertions.assertTrue(makeBuilder().aftEnvironment("").build().isAftEnvironmentInvalid()); + Assertions.assertFalse(makeBuilder().apiKey("").build().isApiKeyValid()); + Assertions.assertFalse(makeBuilder().apiSecret("").build().isApiSecretValid()); + Assertions.assertTrue(makeBuilder().clientName("").build().isClientNameInvalid()); + Assertions.assertTrue(makeBuilder().consumerGroup("").build().isConsumerGroupInvalid()); + Assertions.assertTrue(makeBuilder().consumerInstance("").build().isConsumerInstanceInvalid()); + Assertions.assertTrue(makeBuilder().environment("").build().isEnvironmentInvalid()); + Assertions.assertTrue(makeBuilder().hostname("").build().isHostnameInvalid()); + Assertions.assertTrue(makeBuilder().latitude("").build().isLatitudeInvalid()); + Assertions.assertTrue(makeBuilder().longitude("").build().isLongitudeInvalid()); + Assertions.assertTrue(makeBuilder().partitionId("").build().isPartitionIdInvalid()); + Assertions.assertTrue(makeBuilder().partner("").build().isPartnerInvalid()); + Assertions.assertFalse(makeBuilder().password("").build().isPasswordValid()); + Assertions.assertTrue(makeBuilder().port(-1).build().isPortInvalid()); + Assertions.assertTrue(makeBuilder().port(65536).build().isPortInvalid()); + Assertions.assertTrue(makeBuilder().servers(null).build().isServersInvalid()); + Assertions.assertTrue(makeBuilder().servers(new LinkedList<>()).build().isServersInvalid()); + Assertions.assertTrue(makeBuilder().servers(List.of("")).build().isServersInvalid()); + Assertions.assertFalse(makeBuilder().servers(List.of("one-server")).build().isServersInvalid()); + Assertions.assertTrue(makeBuilder().topic("").build().isTopicInvalid()); + Assertions.assertFalse(makeBuilder().userName("").build().isUserNameValid()); + } + + /** + * Tests the boolean methods by applying a function, once with {@code false} and once + * with {@code true}. Verifies that all the boolean methods return the correct + * value by concatenating them. + * + * @param expectedTrue the string that is expected when {@code true} is passed to the + * method + * @param function function to be applied to the builder + */ + private void testBoolean(String expectedTrue, BiConsumer function) { + TopicParamsBuilder topicParamsBuilder = BusTopicParams.builder(); + + // first try the "false" case + function.accept(topicParamsBuilder, false); + + BusTopicParams params = topicParamsBuilder.build(); + assertEquals("false:false:false", + params.isAllowSelfSignedCerts() + ":" + params.isManaged() + ":" + params.isUseHttps()); + + + // now try the "true" case + function.accept(topicParamsBuilder, true); + + params = topicParamsBuilder.build(); + assertEquals(expectedTrue, + params.isAllowSelfSignedCerts() + ":" + params.isManaged() + ":" + params.isUseHttps()); + } + + public TopicParamsBuilder makeBuilder() { + + return BusTopicParams.builder().additionalProps(addProps).aftEnvironment(MY_AFT_ENV).allowSelfSignedCerts(true) + .apiKey(MY_API_KEY).apiSecret(MY_API_SECRET).basePath(MY_BASE_PATH).clientName(MY_CLIENT_NAME) + .consumerGroup(MY_CONS_GROUP).consumerInstance(MY_CONS_INST).environment(MY_ENV) + .fetchLimit(MY_FETCH_LIMIT).fetchTimeout(MY_FETCH_TIMEOUT).hostname(MY_HOST).latitude(MY_LAT) + .longitude(MY_LONG).managed(true).partitionId(MY_PARTITION).partner(MY_PARTNER) + .password(MY_PASS).port(MY_PORT).servers(List.of("localhost")).topic(MY_TOPIC) + .effectiveTopic(MY_EFFECTIVE_TOPIC).useHttps(true).allowTracing(true).userName(MY_USERNAME) + .serializationProvider(MY_SERIALIZER); + } +} diff --git a/gson/pom.xml b/gson/pom.xml index f7dfdbc3..033a8f36 100644 --- a/gson/pom.xml +++ b/gson/pom.xml @@ -34,6 +34,14 @@ jar + + com.google.code.gson + gson + + + com.google.re2j + re2j + jakarta.ws.rs jakarta.ws.rs-api @@ -42,18 +50,10 @@ org.projectlombok lombok - - com.google.code.gson - gson - org.slf4j slf4j-api - - com.google.re2j - re2j - org.assertj assertj-core diff --git a/gson/src/test/java/org/onap/policy/common/gson/internal/ClassWalkerTest.java b/gson/src/test/java/org/onap/policy/common/gson/internal/ClassWalkerTest.java index ee55c626..007724ae 100644 --- a/gson/src/test/java/org/onap/policy/common/gson/internal/ClassWalkerTest.java +++ b/gson/src/test/java/org/onap/policy/common/gson/internal/ClassWalkerTest.java @@ -36,7 +36,8 @@ import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.TreeSet; -import java.util.stream.Collectors; +import lombok.Getter; +import lombok.Setter; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.onap.policy.common.gson.annotation.GsonJsonAnyGetter; @@ -63,20 +64,17 @@ class ClassWalkerTest { void testExamineClassOfQ_testExamineField_testExamineInField_testExamineOutField() { walker.walkClassHierarchy(DerivedFromBottom.class); - assertEquals("[Intfc1, Intfc2, Intfc1, Intfc3, Bottom, DerivedFromBottom]", walker.classes.toString()); + assertEquals("[InterfaceOne, InterfaceTwo, InterfaceOne, InterfaceThree, Bottom, DerivedFromBottom]", + walker.classes.toString()); - List inFields = walker.getInProps(Field.class).stream().map(Field::getName) - .collect(Collectors.toList()); - Collections.sort(inFields); + List inFields = walker.getInProps(Field.class).stream().map(Field::getName).sorted().toList(); assertEquals("[exposedField, overriddenValue, transField]", inFields.toString()); - List outFields = walker.getInProps(Field.class).stream().map(Field::getName) - .collect(Collectors.toList()); - Collections.sort(outFields); + List outFields = walker.getInProps(Field.class).stream().map(Field::getName).sorted().toList(); assertEquals("[exposedField, overriddenValue, transField]", outFields.toString()); // should work with interfaces without throwing an NPE - walker.walkClassHierarchy(Intfc1.class); + walker.walkClassHierarchy(InterfaceOne.class); } @Test @@ -127,17 +125,13 @@ class ClassWalkerTest { assertNotNull(walker.getAnyGetter()); assertEquals("getTheMap", walker.getAnyGetter().getName()); - List getters = walker.getOutProps(Method.class).stream().map(Method::getName) - .collect(Collectors.toList()); - Collections.sort(getters); + List getters = walker.getOutProps(Method.class).stream().map(Method::getName).sorted().toList(); assertEquals("[getId, getOnlyOut, getValue]", getters.toString()); assertNotNull(walker.getAnySetter()); assertEquals("setMapValue", walker.getAnySetter().getName()); - List setters = walker.getInProps(Method.class).stream().map(Method::getName) - .collect(Collectors.toList()); - Collections.sort(setters); + List setters = walker.getInProps(Method.class).stream().map(Method::getName).sorted().toList(); assertEquals("[setId, setOnlyIn, setValue]", setters.toString()); // getter with invalid parameter count @@ -189,8 +183,8 @@ class ClassWalkerTest { * Walker subclass that records items that are examined. */ private static class MyWalker extends ClassWalker { - private List classes = new ArrayList<>(); - private List methods = new ArrayList<>(); + private final List classes = new ArrayList<>(); + private final List methods = new ArrayList<>(); @Override protected void examine(Class clazz) { @@ -218,19 +212,19 @@ class ClassWalkerTest { } } - protected static interface Intfc1 { - int id = 1000; + protected interface InterfaceOne { + int id = 1000; // NOSONAR I think this is meant to be accessible as fields, not constants } - protected static interface Intfc2 { - String text = "intfc2-text"; + protected interface InterfaceTwo { + String text = "intfc2-text"; // NOSONAR I think this is meant to be accessible as fields, not constants } - private static interface Intfc3 { + private interface InterfaceThree { } - protected static class Bottom implements Intfc1, Intfc3 { + protected static class Bottom implements InterfaceOne, InterfaceThree { private int id; public String value; @@ -259,7 +253,7 @@ class ClassWalkerTest { } } - protected static class DerivedFromBottom extends Bottom implements Intfc1, Intfc2 { + protected static class DerivedFromBottom extends Bottom implements InterfaceOne, InterfaceTwo { private String text; protected String anotherValue; @@ -277,29 +271,19 @@ class ClassWalkerTest { } } + @Setter protected static class Data { + @Getter private int id; + // this will be ignored, because there's already a field by this name private String text; - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - // not public, but property provided @GsonJsonProperty("text") protected String getText() { return text; } - // this will be ignored, because there's already a field by this name - public void setText(String text) { - this.text = text; - } - // should only show up in the output list public int getOnlyOut() { return 1100; diff --git a/message-bus/pom.xml b/message-bus/pom.xml new file mode 100644 index 00000000..54724798 --- /dev/null +++ b/message-bus/pom.xml @@ -0,0 +1,142 @@ + + + + 4.0.0 + + org.onap.policy.common + common-modules + 3.0.1-SNAPSHOT + + + message-bus + + + 17 + 17 + UTF-8 + + + + + org.onap.policy.common + capabilities + ${project.version} + provided + + + org.onap.policy.common + common-parameters + ${project.version} + + + org.onap.policy.common + gson + ${project.version} + + + org.onap.policy.common + utils + ${project.version} + + + ch.qos.logback + logback-core + provided + + + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.core + jackson-databind + + + com.google.re2j + re2j + provided + + + io.opentelemetry + opentelemetry-api + + + io.opentelemetry + opentelemetry-context + + + io.opentelemetry.instrumentation + opentelemetry-kafka-clients-2.6 + + + org.apache.commons + commons-collections4 + + + org.apache.commons + commons-lang3 + provided + + + org.apache.kafka + kafka-clients + provided + + + org.projectlombok + lombok + provided + + + org.slf4j + slf4j-api + provided + + + ch.qos.logback + logback-classic + provided + + + org.assertj + assertj-core + test + + + org.mockito + mockito-core + test + + + org.mockito + mockito-junit-jupiter + test + + + org.onap.policy.common + utils-test + ${project.version} + test + + + \ No newline at end of file diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/Topic.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/Topic.java new file mode 100644 index 00000000..48dbb715 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/Topic.java @@ -0,0 +1,90 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2017-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019 Samsung Electronics Co., Ltd. + * Copyright (C) 2022,2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event; + +import java.util.List; +import org.onap.policy.common.capabilities.Lockable; +import org.onap.policy.common.capabilities.Startable; + + +/** + * Essential Topic Data. + */ +public interface Topic extends TopicRegisterable, Startable, Lockable { + + /** + * Underlying Communication infrastructure Types. + */ + enum CommInfrastructure { + /** + * KAFKA Communication Infrastructure. + */ + KAFKA, + /** + * NOOP for internal use only. + */ + NOOP, + /** + * REST Communication Infrastructure. + */ + REST + } + + /** + * Gets the canonical topic name. + * + * @return topic name + */ + String getTopic(); + + /** + * Gets the effective topic that is used in + * the network communication. This name is usually + * the topic name. + * + * @return topic name alias + */ + String getEffectiveTopic(); + + /** + * Gets the communication infrastructure type. + * + * @return CommInfrastructure object + */ + CommInfrastructure getTopicCommInfrastructure(); + + /** + * Return list of servers. + * + * @return bus servers + */ + List getServers(); + + /** + * Get the more recent events in this topic entity. + * + * @return array of most recent events + */ + String[] getRecentEvents(); + +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicEndpoint.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicEndpoint.java new file mode 100644 index 00000000..5511a82c --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicEndpoint.java @@ -0,0 +1,238 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2022,2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event; + +import java.util.List; +import java.util.Properties; +import org.onap.policy.common.capabilities.Lockable; +import org.onap.policy.common.capabilities.Startable; +import org.onap.policy.common.message.bus.event.kafka.KafkaTopicSink; +import org.onap.policy.common.message.bus.event.kafka.KafkaTopicSource; +import org.onap.policy.common.message.bus.event.noop.NoopTopicSink; +import org.onap.policy.common.message.bus.event.noop.NoopTopicSource; +import org.onap.policy.common.parameters.topic.TopicParameterGroup; +import org.onap.policy.common.parameters.topic.TopicParameters; + +/** + * Abstraction to manage the system's Networked Topic Endpoints, sources of all events input into + * the System. + */ +public interface TopicEndpoint extends Startable, Lockable { + + /** + * Add topics configuration (sources and sinks) into a single list. + * + * @param properties topic configuration + * @return topic list + * @throws IllegalArgumentException when invalid arguments are provided + */ + List addTopics(Properties properties); + + /** + * Add topics configuration (sources and sinks) into a single list. + * + * @param params parameters to configure topic + * @return topic list + * @throws IllegalArgumentException when invalid arguments are provided + */ + List addTopics(TopicParameterGroup params); + + /** + * Add Topic Sources to the communication infrastructure initialized per properties. + * + * @param properties properties for Topic Source construction + * @return a list of generic Topic Sources + * @throws IllegalArgumentException when invalid arguments are provided + */ + List addTopicSources(Properties properties); + + + /** + * Add Topic Sources to the communication infrastructure initialized per properties. + * + * @param paramList parameters for Topic Source construction + * @return a list of generic Topic Sources + * @throws IllegalArgumentException when invalid arguments are provided + */ + List addTopicSources(List paramList); + + /** + * Add Topic Sinks to the communication infrastructure initialized per properties. + * + * @param properties properties for Topic Sink construction + * @return a list of generic Topic Sinks + * @throws IllegalArgumentException when invalid arguments are provided + */ + List addTopicSinks(Properties properties); + + /** + * Add Topic Sinks to the communication infrastructure initialized per properties. + * + * @param paramList parameters for Topic Sink construction + * @return a list of generic Topic Sinks + * @throws IllegalArgumentException when invalid arguments are provided + */ + List addTopicSinks(List paramList); + + /** + * Gets all Topic Sources. + * + * @return the Topic Source List + */ + List getTopicSources(); + + /** + * Get the Topic Sources for the given topic name. + * + * @param topicNames the topic name + * + * @return the Topic Source List + * @throws IllegalStateException if the entity is in an invalid state + * @throws IllegalArgumentException if invalid parameters are present + */ + List getTopicSources(List topicNames); + + /** + * Gets the Topic Source for the given topic name and underlying communication infrastructure + * type. + * + * @param commType communication infrastructure type + * @param topicName the topic name + * + * @return the Topic Source + * @throws IllegalStateException if the entity is in an invalid state, for example multiple + * TopicReaders for a topic name and communication infrastructure + * @throws IllegalArgumentException if invalid parameters are present + * @throws UnsupportedOperationException if the operation is not supported. + */ + TopicSource getTopicSource(Topic.CommInfrastructure commType, String topicName); + + /** + * Get the Noop Source for the given topic name. + * + * @param topicName the topic name. + * @return the Noop Source. + */ + NoopTopicSource getNoopTopicSource(String topicName); + + /** + * Get the Kafka Source for the given topic name. + * + * @param topicName the topic name. + * @return the Kafka Source. + */ + KafkaTopicSource getKafkaTopicSource(String topicName); + + /** + * Get the Topic Sinks for the given topic name. + * + * @param topicNames the topic names + * @return the Topic Sink List + */ + List getTopicSinks(List topicNames); + + /** + * Get the Topic Sinks for the given topic name and all the underlying communication + * infrastructure type. + * + * @param topicName the topic name + * + * @return the Topic Sink List + * @throws IllegalStateException if the entity is in an invalid state, for example multiple + * TopicWriters for a topic name and communication infrastructure + * @throws IllegalArgumentException if invalid parameters are present + */ + List getTopicSinks(String topicName); + + /** + * Gets all Topic Sinks. + * + * @return the Topic Sink List + */ + List getTopicSinks(); + + /** + * Get the Topic Sinks for the given topic name and underlying communication infrastructure type. + * + * @param topicName the topic name + * @param commType communication infrastructure type + * + * @return the Topic Sink List + * @throws IllegalStateException if the entity is in an invalid state, for example multiple + * TopicWriters for a topic name and communication infrastructure + * @throws IllegalArgumentException if invalid parameters are present + */ + TopicSink getTopicSink(Topic.CommInfrastructure commType, String topicName); + + /** + * Get the no-op Topic Sink for the given topic name. + * + * @param topicName the topic name + * + * @return the Topic Source + * @throws IllegalStateException if the entity is in an invalid state, for example multiple + * TopicReaders for a topic name and communication infrastructure + * @throws IllegalArgumentException if invalid parameters are present + */ + NoopTopicSink getNoopTopicSink(String topicName); + + /** + * Get the KAFKA Topic Source for the given topic name. + * + * @param topicName the topic name + * + * @return the Topic Source + * @throws IllegalStateException if the entity is in an invalid state, for example multiple + * TopicReaders for a topic name and communication infrastructure + * @throws IllegalArgumentException if invalid parameters are present + */ + KafkaTopicSink getKafkaTopicSink(String topicName); + + /** + * Gets only the KAFKA Topic Sources. + * + * @return the KAFKA Topic Source List + */ + List getKafkaTopicSources(); + + /** + * Gets only the NOOP Topic Sources. + * + * @return the NOOP Topic Source List + */ + List getNoopTopicSources(); + + /** + * Gets only the KAFKA Topic Sinks. + * + * @return the KAFKA Topic Sinks List + */ + List getKafkaTopicSinks(); + + /** + * Gets only the NOOP Topic Sinks. + * + * @return the NOOP Topic Sinks List + */ + List getNoopTopicSinks(); + +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicEndpointManager.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicEndpointManager.java new file mode 100644 index 00000000..40b9c235 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicEndpointManager.java @@ -0,0 +1,36 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class TopicEndpointManager { + + /** + * Topic endpoint manager. + */ + @Getter + static TopicEndpoint manager = new TopicEndpointProxy(); +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicEndpointProxy.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicEndpointProxy.java new file mode 100644 index 00000000..9dbf5418 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicEndpointProxy.java @@ -0,0 +1,485 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2022-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Properties; +import lombok.Getter; +import org.onap.policy.common.capabilities.Startable; +import org.onap.policy.common.gson.annotation.GsonJsonIgnore; +import org.onap.policy.common.message.bus.event.kafka.KafkaTopicFactories; +import org.onap.policy.common.message.bus.event.kafka.KafkaTopicSink; +import org.onap.policy.common.message.bus.event.kafka.KafkaTopicSource; +import org.onap.policy.common.message.bus.event.noop.NoopTopicFactories; +import org.onap.policy.common.message.bus.event.noop.NoopTopicSink; +import org.onap.policy.common.message.bus.event.noop.NoopTopicSource; +import org.onap.policy.common.parameters.topic.TopicParameterGroup; +import org.onap.policy.common.parameters.topic.TopicParameters; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This implementation of the Topic Endpoint Manager, proxies operations to the appropriate + * implementation(s). + */ +@Getter +public class TopicEndpointProxy implements TopicEndpoint { + /** + * Logger. + */ + private static final Logger logger = LoggerFactory.getLogger(TopicEndpointProxy.class); + + /** + * Is this element locked boolean. + */ + private volatile boolean locked = false; + + /** + * Is this element alive boolean. + */ + private volatile boolean alive = false; + + @Override + public List addTopics(Properties properties) { + List topics = new ArrayList<>(addTopicSources(properties)); + topics.addAll(addTopicSinks(properties)); + return topics; + } + + @Override + public List addTopics(TopicParameterGroup params) { + List sinks = + (params.getTopicSinks() != null ? params.getTopicSinks() : Collections.emptyList()); + List sources = + (params.getTopicSources() != null ? params.getTopicSources() : Collections.emptyList()); + + List topics = new ArrayList<>(sinks.size() + sources.size()); + topics.addAll(addTopicSources(sources)); + topics.addAll(addTopicSinks(sinks)); + return topics; + } + + @Override + public List addTopicSources(List paramList) { + List sources = new ArrayList<>(paramList.size()); + + for (TopicParameters param : paramList) { + switch (Topic.CommInfrastructure.valueOf(param.getTopicCommInfrastructure().toUpperCase())) { + case KAFKA: + sources.add(KafkaTopicFactories.getSourceFactory().build(param)); + break; + case NOOP: + sources.add(NoopTopicFactories.getSourceFactory().build(param)); + break; + default: + logger.debug("Unknown source type {} for topic: {}", param.getTopicCommInfrastructure(), + param.getTopic()); + break; + } + } + + lockSources(sources); + + return sources; + } + + @Override + public List addTopicSources(Properties properties) { + + // 1. Create KAFKA Sources + // 2. Create NOOP Sources + + List sources = new ArrayList<>(); + + sources.addAll(KafkaTopicFactories.getSourceFactory().build(properties)); + sources.addAll(NoopTopicFactories.getSourceFactory().build(properties)); + + lockSources(sources); + + return sources; + } + + private void lockSources(List sources) { + if (this.isLocked()) { + sources.forEach(TopicSource::lock); + } + } + + @Override + public List addTopicSinks(List paramList) { + List sinks = new ArrayList<>(paramList.size()); + + for (TopicParameters param : paramList) { + switch (Topic.CommInfrastructure.valueOf(param.getTopicCommInfrastructure().toUpperCase())) { + case KAFKA: + sinks.add(KafkaTopicFactories.getSinkFactory().build(param)); + break; + case NOOP: + sinks.add(NoopTopicFactories.getSinkFactory().build(param)); + break; + default: + logger.debug("Unknown sink type {} for topic: {}", param.getTopicCommInfrastructure(), + param.getTopic()); + break; + } + } + + lockSinks(sinks); + + return sinks; + } + + @Override + public List addTopicSinks(Properties properties) { + // 1. Create KAFKA Sinks + // 2. Create NOOP Sinks + + final List sinks = new ArrayList<>(); + + sinks.addAll(KafkaTopicFactories.getSinkFactory().build(properties)); + sinks.addAll(NoopTopicFactories.getSinkFactory().build(properties)); + + lockSinks(sinks); + + return sinks; + } + + private void lockSinks(List sinks) { + if (this.isLocked()) { + sinks.forEach(TopicSink::lock); + } + } + + @Override + public List getTopicSources() { + + final List sources = new ArrayList<>(); + + sources.addAll(KafkaTopicFactories.getSourceFactory().inventory()); + sources.addAll(NoopTopicFactories.getSourceFactory().inventory()); + + return sources; + } + + @Override + public List getTopicSources(List topicNames) { + + if (topicNames == null) { + throw new IllegalArgumentException("must provide a list of topics"); + } + + final List sources = new ArrayList<>(); + + topicNames.forEach(topic -> { + try { + sources.add(Objects.requireNonNull(this.getKafkaTopicSource(topic))); + } catch (final Exception e) { + logger.debug("No KAFKA source for topic: {}", topic, e); + } + + try { + sources.add(Objects.requireNonNull(this.getNoopTopicSource(topic))); + } catch (final Exception e) { + logger.debug("No NOOP source for topic: {}", topic, e); + } + }); + + return sources; + } + + @Override + public List getTopicSinks() { + + final List sinks = new ArrayList<>(); + + sinks.addAll(KafkaTopicFactories.getSinkFactory().inventory()); + sinks.addAll(NoopTopicFactories.getSinkFactory().inventory()); + + return sinks; + } + + @Override + public List getTopicSinks(List topicNames) { + + if (topicNames == null) { + throw new IllegalArgumentException("must provide a list of topics"); + } + + final List sinks = new ArrayList<>(); + for (final String topic : topicNames) { + try { + sinks.add(Objects.requireNonNull(this.getKafkaTopicSink(topic))); + } catch (final Exception e) { + logger.debug("No KAFKA sink for topic: {}", topic, e); + } + + try { + sinks.add(Objects.requireNonNull(this.getNoopTopicSink(topic))); + } catch (final Exception e) { + logger.debug("No NOOP sink for topic: {}", topic, e); + } + } + return sinks; + } + + @Override + public List getTopicSinks(String topicName) { + if (topicName == null) { + throw paramException(null); + } + + final List sinks = new ArrayList<>(); + + try { + sinks.add(this.getKafkaTopicSink(topicName)); + } catch (final Exception e) { + logNoSink(topicName, e); + } + + try { + sinks.add(this.getNoopTopicSink(topicName)); + } catch (final Exception e) { + logNoSink(topicName, e); + } + + return sinks; + } + + @GsonJsonIgnore + @Override + public List getKafkaTopicSources() { + return KafkaTopicFactories.getSourceFactory().inventory(); + } + + @GsonJsonIgnore + @Override + public List getNoopTopicSources() { + return NoopTopicFactories.getSourceFactory().inventory(); + } + + @Override + @GsonJsonIgnore + public List getKafkaTopicSinks() { + return KafkaTopicFactories.getSinkFactory().inventory(); + } + + @GsonJsonIgnore + @Override + public List getNoopTopicSinks() { + return NoopTopicFactories.getSinkFactory().inventory(); + } + + @Override + public boolean start() { + + synchronized (this) { + if (this.locked) { + throw new IllegalStateException(this + " is locked"); + } + + if (this.alive) { + return true; + } + + this.alive = true; + } + + final List endpoints = this.getEndpoints(); + + var success = true; + for (final Startable endpoint : endpoints) { + try { + success = endpoint.start() && success; + } catch (final Exception e) { + success = false; + logger.error("Problem starting endpoint: {}", endpoint, e); + } + } + + return success; + } + + @Override + public boolean stop() { + + /* + * stop regardless if it is locked, in other words, stop operation has precedence over + * locks. + */ + synchronized (this) { + this.alive = false; + } + + final List endpoints = this.getEndpoints(); + + var success = true; + for (final Startable endpoint : endpoints) { + try { + success = endpoint.stop() && success; + } catch (final Exception e) { + success = false; + logger.error("Problem stopping endpoint: {}", endpoint, e); + } + } + + return success; + } + + /** + * Gets the endpoints. + * + * @return list of managed endpoints + */ + @GsonJsonIgnore + protected List getEndpoints() { + final List endpoints = new ArrayList<>(); + + endpoints.addAll(this.getTopicSources()); + endpoints.addAll(this.getTopicSinks()); + + return endpoints; + } + + @Override + public void shutdown() { + this.stop(); + + KafkaTopicFactories.getSourceFactory().destroy(); + KafkaTopicFactories.getSinkFactory().destroy(); + + NoopTopicFactories.getSinkFactory().destroy(); + NoopTopicFactories.getSourceFactory().destroy(); + + } + + @Override + public boolean lock() { + boolean shouldLock; + + synchronized (this) { + shouldLock = !this.locked; + this.locked = true; + } + + if (shouldLock) { + for (final TopicSource source : this.getTopicSources()) { + source.lock(); + } + + for (final TopicSink sink : this.getTopicSinks()) { + sink.lock(); + } + } + + return true; + } + + @Override + public boolean unlock() { + boolean shouldUnlock; + + synchronized (this) { + shouldUnlock = this.locked; + this.locked = false; + } + + if (shouldUnlock) { + for (final TopicSource source : this.getTopicSources()) { + source.unlock(); + } + + for (final TopicSink sink : this.getTopicSinks()) { + sink.unlock(); + } + } + + return true; + } + + @Override + public TopicSource getTopicSource(Topic.CommInfrastructure commType, String topicName) { + + if (commType == null) { + throw paramException(topicName); + } + + if (topicName == null) { + throw paramException(null); + } + + return switch (commType) { + case KAFKA -> this.getKafkaTopicSource(topicName); + case NOOP -> this.getNoopTopicSource(topicName); + default -> throw new UnsupportedOperationException("Unsupported " + commType.name()); + }; + } + + @Override + public TopicSink getTopicSink(Topic.CommInfrastructure commType, String topicName) { + if (commType == null) { + throw paramException(topicName); + } + + if (topicName == null) { + throw paramException(null); + } + + return switch (commType) { + case KAFKA -> this.getKafkaTopicSink(topicName); + case NOOP -> this.getNoopTopicSink(topicName); + default -> throw new UnsupportedOperationException("Unsupported " + commType.name()); + }; + } + + @Override + public KafkaTopicSource getKafkaTopicSource(String topicName) { + return KafkaTopicFactories.getSourceFactory().get(topicName); + } + + @Override + public NoopTopicSource getNoopTopicSource(String topicName) { + return NoopTopicFactories.getSourceFactory().get(topicName); + } + + @Override + public KafkaTopicSink getKafkaTopicSink(String topicName) { + return KafkaTopicFactories.getSinkFactory().get(topicName); + } + + @Override + public NoopTopicSink getNoopTopicSink(String topicName) { + return NoopTopicFactories.getSinkFactory().get(topicName); + } + + private IllegalArgumentException paramException(String topicName) { + return new IllegalArgumentException( + "Invalid parameter: a communication infrastructure required to fetch " + topicName); + } + + private void logNoSink(String topicName, Exception ex) { + logger.debug("No sink for topic: {}", topicName, ex); + } + +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicListener.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicListener.java new file mode 100644 index 00000000..f9896243 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicListener.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event; + +/** + * Listener for event messages entering the Policy Engine. + */ +@FunctionalInterface +public interface TopicListener { + + /** + * Notification of a new Event over a given Topic. + * + * @param commType communication infrastructure type + * @param topic topic name + * @param event event message as a string + */ + void onTopicEvent(Topic.CommInfrastructure commType, String topic, String event); + +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicRegisterable.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicRegisterable.java new file mode 100644 index 00000000..1d6873e9 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicRegisterable.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event; + +/** + * Marks a Topic entity as registerable. + */ +public interface TopicRegisterable { + + /** + * Register for notification of events with this Topic Entity. + * + * @param topicListener the listener of events + */ + void register(TopicListener topicListener); + + /** + * Unregisters for notification of events with this Topic Entity. + * + * @param topicListener the listener of events + */ + void unregister(TopicListener topicListener); + +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicSink.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicSink.java new file mode 100644 index 00000000..d5269b9a --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicSink.java @@ -0,0 +1,38 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2023-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event; + +/** + * Marks a given Topic Endpoint as able to send messages over a topic. + */ +public interface TopicSink extends Topic { + + /** + * Sends a string message over this Topic Endpoint. + * + * @param message message to send + * @return true if the send operation succeeded, false otherwise + * @throws IllegalArgumentException an invalid message has been provided + * @throws IllegalStateException the entity is in a state that prevents + * it from sending messages, for example, locked or stopped. + */ + boolean send(String message); + +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicSource.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicSource.java new file mode 100644 index 00000000..f0dc3b74 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/TopicSource.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event; + +/** + * Marker for a Topic Entity, indicating that the entity is able to read + * over a topic. + */ +public interface TopicSource extends Topic { + + /** + * Pushes an event into the source programmatically. + * + * @param event the event in json format + * @return true if it can be processed correctly, false otherwise + */ + boolean offer(String event); + +} \ No newline at end of file diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/ApiKeyEnabled.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/ApiKeyEnabled.java new file mode 100644 index 00000000..360a88a2 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/ApiKeyEnabled.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +/** + * API. + */ +public interface ApiKeyEnabled { + /** + * Get API key. + * + * @return api key + */ + String getApiKey(); + + /** + * Get API secret. + * + * @return api secret + */ + String getApiSecret(); +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusConsumer.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusConsumer.java new file mode 100644 index 00000000..925949aa --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusConsumer.java @@ -0,0 +1,278 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2018 Samsung Electronics Co., Ltd. + * Modifications Copyright (C) 2020,2023 Bell Canada. All rights reserved. + * Modifications Copyright (C) 2022-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.DEFAULT_TIMEOUT_MS_FETCH; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.TraceFlags; +import io.opentelemetry.api.trace.TraceState; +import io.opentelemetry.context.Context; +import io.opentelemetry.instrumentation.kafkaclients.v2_6.TracingConsumerInterceptor; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.clients.consumer.OffsetAndMetadata; +import org.apache.kafka.common.TopicPartition; +import org.apache.kafka.common.header.Headers; +import org.onap.policy.common.parameters.topic.BusTopicParams; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Wrapper around libraries to consume from message bus. + */ +public interface BusConsumer { + + /** + * fetch messages. + * + * @return list of messages + * @throws IOException when error encountered by underlying libraries + */ + Iterable fetch() throws IOException; + + /** + * close underlying library consumer. + */ + void close(); + + /** + * Consumer that handles fetch() failures by sleeping. + */ + abstract class FetchingBusConsumer implements BusConsumer { + private static final Logger logger = LoggerFactory.getLogger(FetchingBusConsumer.class); + + /** + * Fetch timeout. + */ + protected int fetchTimeout; + + /** + * Time to sleep on a fetch failure. + */ + @Getter + private final int sleepTime; + + /** + * Counted down when {@link #close()} is invoked. + */ + private final CountDownLatch closeCondition = new CountDownLatch(1); + + + /** + * Constructs the object. + * + * @param busTopicParams parameters for the bus topic + */ + protected FetchingBusConsumer(BusTopicParams busTopicParams) { + this.fetchTimeout = busTopicParams.getFetchTimeout(); + + if (this.fetchTimeout <= 0) { + this.sleepTime = DEFAULT_TIMEOUT_MS_FETCH; + } else { + // don't sleep too long, even if fetch timeout is large + this.sleepTime = Math.min(this.fetchTimeout, DEFAULT_TIMEOUT_MS_FETCH); + } + } + + /** + * Causes the thread to sleep; invoked after fetch() fails. If the consumer is closed, + * or the thread is interrupted, then this will return immediately. + */ + protected void sleepAfterFetchFailure() { + try { + logger.info("{}: backoff for {}ms", this, sleepTime); + if (this.closeCondition.await(this.sleepTime, TimeUnit.MILLISECONDS)) { + logger.info("{}: closed while handling fetch error", this); + } + + } catch (InterruptedException e) { + logger.warn("{}: interrupted while handling fetch error", this, e); + Thread.currentThread().interrupt(); + } + } + + @Override + public void close() { + this.closeCondition.countDown(); + } + } + + /** + * Kafka based consumer. + */ + class KafkaConsumerWrapper extends FetchingBusConsumer { + + /** + * logger. + */ + private static final Logger logger = LoggerFactory.getLogger(KafkaConsumerWrapper.class); + + private static final String KEY_DESERIALIZER = "org.apache.kafka.common.serialization.StringDeserializer"; + + /** + * Kafka consumer. + */ + protected KafkaConsumer consumer; + protected Properties kafkaProps; + + protected boolean allowTracing; + + /** + * Kafka Consumer Wrapper. + * BusTopicParam - object contains the following parameters + * servers - messaging bus hosts. + * topic - topic + * + * @param busTopicParams - The parameters for the bus topic + */ + public KafkaConsumerWrapper(BusTopicParams busTopicParams) { + super(busTopicParams); + + if (busTopicParams.isTopicInvalid()) { + throw new IllegalArgumentException("No topic for Kafka"); + } + + //Setup Properties for consumer + kafkaProps = new Properties(); + kafkaProps.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, + busTopicParams.getServers().get(0)); + + if (busTopicParams.isAdditionalPropsValid()) { + kafkaProps.putAll(busTopicParams.getAdditionalProps()); + } + + if (kafkaProps.get(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG) == null) { + kafkaProps.setProperty(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, KEY_DESERIALIZER); + } + if (kafkaProps.get(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG) == null) { + kafkaProps.setProperty(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, KEY_DESERIALIZER); + } + if (kafkaProps.get(ConsumerConfig.GROUP_ID_CONFIG) == null) { + kafkaProps.setProperty(ConsumerConfig.GROUP_ID_CONFIG, busTopicParams.getConsumerGroup()); + } + if (busTopicParams.isAllowTracing()) { + this.allowTracing = true; + kafkaProps.setProperty(ConsumerConfig.INTERCEPTOR_CLASSES_CONFIG, + TracingConsumerInterceptor.class.getName()); + } + + consumer = new KafkaConsumer<>(kafkaProps); + //Subscribe to the topic + consumer.subscribe(List.of(busTopicParams.getTopic())); + } + + @Override + public Iterable fetch() { + ConsumerRecords records = this.consumer.poll(Duration.ofMillis(fetchTimeout)); + if (records == null || records.count() <= 0) { + return Collections.emptyList(); + } + List messages = new ArrayList<>(records.count()); + try { + if (allowTracing) { + createParentTraceContext(records); + } + + for (TopicPartition partition : records.partitions()) { + List> partitionRecords = records.records(partition); + for (ConsumerRecord partitionRecord : partitionRecords) { + messages.add(partitionRecord.value()); + } + long lastOffset = partitionRecords.get(partitionRecords.size() - 1).offset(); + consumer.commitSync(Collections.singletonMap(partition, new OffsetAndMetadata(lastOffset + 1))); + } + } catch (Exception e) { + logger.error("{}: cannot fetch, throwing exception after sleep...", this); + sleepAfterFetchFailure(); + throw e; + } + return messages; + } + + private void createParentTraceContext(ConsumerRecords records) { + TraceParentInfo traceParentInfo = new TraceParentInfo(); + for (ConsumerRecord consumerRecord : records) { + + Headers consumerRecordHeaders = consumerRecord.headers(); + traceParentInfo = processTraceParentHeader(consumerRecordHeaders); + } + + SpanContext spanContext = SpanContext.createFromRemoteParent( + traceParentInfo.getTraceId(), traceParentInfo.getSpanId(), + TraceFlags.getSampled(), TraceState.builder().build()); + + Context.current().with(Span.wrap(spanContext)).makeCurrent(); + } + + private TraceParentInfo processTraceParentHeader(Headers headers) { + TraceParentInfo traceParentInfo = new TraceParentInfo(); + if (headers.lastHeader("traceparent") != null) { + traceParentInfo.setParentTraceId(new String(headers.lastHeader( + "traceparent").value(), StandardCharsets.UTF_8)); + + String[] parts = traceParentInfo.getParentTraceId().split("-"); + traceParentInfo.setTraceId(parts[1]); + traceParentInfo.setSpanId(parts[2]); + } + + return traceParentInfo; + } + + @Data + @NoArgsConstructor + private static class TraceParentInfo { + private String parentTraceId; + private String traceId; + private String spanId; + } + + @Override + public void close() { + super.close(); + this.consumer.close(); + logger.info("Kafka Consumer exited {}", this); + } + + @Override + public String toString() { + return "KafkaConsumerWrapper [fetchTimeout=" + fetchTimeout + "]"; + } + } +} + + diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusPublisher.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusPublisher.java new file mode 100644 index 00000000..10c7db2d --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusPublisher.java @@ -0,0 +1,43 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2018 Samsung Electronics Co., Ltd. + * Modifications Copyright (C) 2020,2023 Bell Canada. All rights reserved. + * Modifications Copyright (C) 2022-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +public interface BusPublisher { + + String NO_MESSAGE_PROVIDED = "No message provided"; + String LOG_CLOSE = "{}: CLOSE"; + + /** + * sends a message. + * + * @param partitionId id + * @param message the message + * @return true if success, false otherwise + * @throws IllegalArgumentException if no message provided + */ + boolean send(String partitionId, String message); + + /** + * closes the publisher. + */ + void close(); +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusTopicBase.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusTopicBase.java new file mode 100644 index 00000000..6516945a --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusTopicBase.java @@ -0,0 +1,109 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2017-2019, 2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2020 Bell Canada. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +import lombok.Getter; +import org.onap.policy.common.parameters.topic.BusTopicParams; + +/** + * Bus Topic Base. + */ +@Getter +public abstract class BusTopicBase extends TopicBase implements ApiKeyEnabled { + + /** + * API Key. + */ + protected String apiKey; + + /** + * API Secret. + */ + protected String apiSecret; + + /** + * Use https. + */ + protected boolean useHttps; + + /** + * Allow tracing. + */ + protected boolean allowTracing; + + /** + * allow self-signed certificates. + */ + protected boolean allowSelfSignedCerts; + + /** + * Instantiates a new Bus Topic Base. + * + *

servers list of servers + * topic: the topic name + * apiKey: API Key + * apiSecret: API Secret + * useHttps: does connection use HTTPS? + * allowTracing: Is tracing allowed? + * allowSelfSignedCerts: are self-signed certificates allow + * + * @param busTopicParams holds all our parameters + * @throws IllegalArgumentException if invalid parameters are present + */ + protected BusTopicBase(BusTopicParams busTopicParams) { + super(busTopicParams.getServers(), busTopicParams.getTopic(), busTopicParams.getEffectiveTopic()); + this.apiKey = busTopicParams.getApiKey(); + this.apiSecret = busTopicParams.getApiSecret(); + this.useHttps = busTopicParams.isUseHttps(); + this.allowTracing = busTopicParams.isAllowTracing(); + this.allowSelfSignedCerts = busTopicParams.isAllowSelfSignedCerts(); + } + + protected boolean anyNullOrEmpty(String... args) { + for (String arg : args) { + if (arg == null || arg.isEmpty()) { + return true; + } + } + + return false; + } + + protected boolean allNullOrEmpty(String... args) { + for (String arg : args) { + if (!(arg == null || arg.isEmpty())) { + return false; + } + } + + return true; + } + + + @Override + public String toString() { + return "BusTopicBase [apiKey=" + apiKey + ", apiSecret=" + apiSecret + ", useHttps=" + useHttps + + ", allowSelfSignedCerts=" + allowSelfSignedCerts + ", toString()=" + super.toString() + "]"; + } + +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusTopicSink.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusTopicSink.java new file mode 100644 index 00000000..54b08619 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusTopicSink.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2017, 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2023-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +import org.onap.policy.common.message.bus.event.TopicSink; + +/** + * Topic Sink over Bus Infrastructure (KAFKA). + */ +public interface BusTopicSink extends ApiKeyEnabled, TopicSink { + + /** + * Sets the partition key for published messages. + * + * @param partitionKey the partition key + */ + void setPartitionKey(String partitionKey); + + /** + * Return the partition key in used by the system to publish messages. + * + * @return the partition key + */ + String getPartitionKey(); +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusTopicSource.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusTopicSource.java new file mode 100644 index 00000000..974c02bb --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/BusTopicSource.java @@ -0,0 +1,57 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +import org.onap.policy.common.message.bus.event.TopicSource; + +/** + * Generic Topic Source for Bus Communication Infrastructure. + * + */ +public interface BusTopicSource extends ApiKeyEnabled, TopicSource { + + /** + * Gets the consumer group. + * + * @return consumer group + */ + public String getConsumerGroup(); + + /** + * Gets the consumer instance. + * + * @return consumer instance + */ + public String getConsumerInstance(); + + /** + * Gets the fetch timeout. + * + * @return fetch timeout + */ + public int getFetchTimeout(); + + /** + * Gets the fetch limit. + * + * @return fetch limit + */ + public int getFetchLimit(); +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/InlineBusTopicSink.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/InlineBusTopicSink.java new file mode 100644 index 00000000..6a30f00f --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/InlineBusTopicSink.java @@ -0,0 +1,165 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2018-2019 Samsung Electronics Co., Ltd. + * Modifications Copyright (C) 2020 Bell Canada. All rights reserved. + * Modifications Copyright (C) 2023-2024 Nordix Foundation. +* ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +import java.util.UUID; +import lombok.Getter; +import lombok.Setter; +import org.onap.policy.common.message.bus.utils.NetLoggerUtil; +import org.onap.policy.common.message.bus.utils.NetLoggerUtil.EventType; +import org.onap.policy.common.parameters.topic.BusTopicParams; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Transport Agnostic Bus Topic Sink to carry out the core functionality to interact with a sink. + * + */ +public abstract class InlineBusTopicSink extends BusTopicBase implements BusTopicSink { + + /** + * Loggers. + */ + private static final Logger logger = LoggerFactory.getLogger(InlineBusTopicSink.class); + + /** + * The partition key to publish to. + */ + @Getter + @Setter + protected String partitionKey; + + /** + * Message bus publisher. + */ + protected BusPublisher publisher; + + /** + * Constructor for abstract sink. + * @param busTopicParams contains below listed attributes + * servers: servers + * topic: topic + * apiKey: api secret + * apiSecret: api secret + * partitionId: partition id + * useHttps: does connection use HTTPS? + * allowTracing: is tracing allowed? + * allowSelfSignedCerts: are self-signed certificates allow * + * @throws IllegalArgumentException if invalid parameters are passed in + */ + protected InlineBusTopicSink(BusTopicParams busTopicParams) { + + super(busTopicParams); + + if (busTopicParams.isPartitionIdInvalid()) { + this.partitionKey = UUID.randomUUID().toString(); + } else { + this.partitionKey = busTopicParams.getPartitionId(); + } + } + + /** + * Initialize the Bus publisher. + */ + public abstract void init(); + + @Override + public boolean start() { + logger.info("{}: starting", this); + + synchronized (this) { + if (!this.alive) { + if (locked) { + throw new IllegalStateException(this + " is locked."); + } + + this.init(); + this.alive = true; + } + } + + return true; + } + + @Override + public boolean stop() { + + BusPublisher publisherCopy; + synchronized (this) { + this.alive = false; + publisherCopy = this.publisher; + this.publisher = null; + } + + if (publisherCopy != null) { + try { + publisherCopy.close(); + } catch (Exception e) { + logger.warn("{}: cannot stop publisher because of {}", this, e.getMessage(), e); + } + } else { + logger.warn("{}: there is no publisher", this); + return false; + } + + return true; + } + + @Override + public boolean send(String message) { + + if (message == null || message.isEmpty()) { + throw new IllegalArgumentException("Message to send is empty"); + } + + if (!this.alive) { + throw new IllegalStateException(this + " is stopped"); + } + + try { + synchronized (this) { + this.recentEvents.add(message); + } + + NetLoggerUtil.log(EventType.OUT, this.getTopicCommInfrastructure(), this.topic, message); + + publisher.send(this.partitionKey, message); + broadcast(message); + } catch (Exception e) { + logger.warn("{}: cannot send because of {}", this, e.getMessage(), e); + return false; + } + + return true; + } + + @Override + public void shutdown() { + this.stop(); + } + + @Override + public String toString() { + return "InlineBusTopicSink [partitionId=" + partitionKey + ", alive=" + alive + ", publisher=" + publisher + + "]"; + } +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/SingleThreadedBusTopicSource.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/SingleThreadedBusTopicSource.java new file mode 100644 index 00000000..912b698c --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/SingleThreadedBusTopicSource.java @@ -0,0 +1,288 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2018-2019 Samsung Electronics Co., Ltd. + * Modifications Copyright (C) 2020 Bell Canada. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.NO_LIMIT_FETCH; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.NO_TIMEOUT_MS_FETCH; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.util.UUID; +import lombok.Getter; +import org.onap.policy.common.message.bus.event.TopicListener; +import org.onap.policy.common.message.bus.utils.NetLoggerUtil; +import org.onap.policy.common.message.bus.utils.NetLoggerUtil.EventType; +import org.onap.policy.common.parameters.topic.BusTopicParams; +import org.onap.policy.common.utils.network.NetworkUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This topic source implementation specializes in reading messages over a bus topic source and + * notifying its listeners. + */ +public abstract class SingleThreadedBusTopicSource extends BusTopicBase + implements Runnable, BusTopicSource { + + /** + * Not to be converted to PolicyLogger. This will contain all in/out traffic and only + * that in a single file in a concise format. + */ + private static final Logger logger = LoggerFactory.getLogger(SingleThreadedBusTopicSource.class); + + /** + * Bus consumer group. + */ + @Getter + protected final String consumerGroup; + + /** + * Bus consumer instance. + */ + @Getter + protected final String consumerInstance; + + /** + * Bus fetch timeout. + */ + @Getter + protected final int fetchTimeout; + + /** + * Bus fetch limit. + */ + @Getter + protected final int fetchLimit; + + /** + * Message Bus Consumer. + */ + protected BusConsumer consumer; + + /** + * Independent thread reading message over my topic. + */ + protected Thread busPollerThread; + + + /** + * Constructor. + * + * @param busTopicParams topic parameters + * + * @throws IllegalArgumentException An invalid parameter passed in + */ + protected SingleThreadedBusTopicSource(BusTopicParams busTopicParams) { + + super(busTopicParams); + + if (busTopicParams.isConsumerGroupInvalid() && busTopicParams.isConsumerInstanceInvalid()) { + this.consumerGroup = UUID.randomUUID().toString(); + this.consumerInstance = NetworkUtil.getHostname(); + + } else if (busTopicParams.isConsumerGroupInvalid()) { + this.consumerGroup = UUID.randomUUID().toString(); + this.consumerInstance = busTopicParams.getConsumerInstance(); + + } else if (busTopicParams.isConsumerInstanceInvalid()) { + this.consumerGroup = busTopicParams.getConsumerGroup(); + this.consumerInstance = UUID.randomUUID().toString(); + + } else { + this.consumerGroup = busTopicParams.getConsumerGroup(); + this.consumerInstance = busTopicParams.getConsumerInstance(); + } + + if (busTopicParams.getFetchTimeout() <= 0) { + this.fetchTimeout = NO_TIMEOUT_MS_FETCH; + } else { + this.fetchTimeout = busTopicParams.getFetchTimeout(); + } + + if (busTopicParams.getFetchLimit() <= 0) { + this.fetchLimit = NO_LIMIT_FETCH; + } else { + this.fetchLimit = busTopicParams.getFetchLimit(); + } + + } + + /** + * Initialize the Bus client. + */ + public abstract void init() throws MalformedURLException; + + @Override + public void register(TopicListener topicListener) { + + super.register(topicListener); + + try { + if (!alive && !locked) { + this.start(); + } else { + logger.info("{}: register: start not attempted", this); + } + } catch (Exception e) { + logger.warn("{}: cannot start after registration of because of: {}", this, topicListener, e); + } + } + + @Override + public void unregister(TopicListener topicListener) { + boolean stop; + synchronized (this) { + super.unregister(topicListener); + stop = this.topicListeners.isEmpty(); + } + + if (stop) { + this.stop(); + } + } + + @Override + public boolean start() { + logger.info("{}: starting", this); + + synchronized (this) { + + if (alive) { + return true; + } + + if (locked) { + throw new IllegalStateException(this + " is locked."); + } + + if (this.busPollerThread == null || !this.busPollerThread.isAlive() || this.consumer == null) { + + try { + this.init(); + this.alive = true; + this.busPollerThread = makePollerThread(); + this.busPollerThread.setName(this.getTopicCommInfrastructure() + "-source-" + this.getTopic()); + busPollerThread.start(); + return true; + } catch (Exception e) { + throw new IllegalStateException(this + ": cannot start", e); + } + } + } + + return false; + } + + /** + * Makes a new thread to be used for polling. + * + * @return a new Thread + */ + protected Thread makePollerThread() { + return new Thread(this); + } + + @Override + public boolean stop() { + logger.info("{}: stopping", this); + + synchronized (this) { + BusConsumer consumerCopy = this.consumer; + + this.alive = false; + this.consumer = null; + + if (consumerCopy != null) { + try { + consumerCopy.close(); + } catch (Exception e) { + logger.warn("{}: stop failed because of {}", this, e.getMessage(), e); + } + } + } + + Thread.yield(); + + return true; + } + + /** + * Run thread method for the Bus Reader. + */ + @Override + public void run() { + while (this.alive) { + try { + fetchAllMessages(); + } catch (IOException | RuntimeException e) { + logger.error("{}: cannot fetch", this, e); + } + } + + logger.info("{}: exiting thread", this); + } + + private void fetchAllMessages() throws IOException { + for (String event : this.consumer.fetch()) { + synchronized (this) { + this.recentEvents.add(event); + } + + NetLoggerUtil.log(EventType.IN, this.getTopicCommInfrastructure(), this.topic, event); + + broadcast(event); + + if (!this.alive) { + return; + } + } + } + + @Override + public boolean offer(String event) { + if (!this.alive) { + throw new IllegalStateException(this + " is not alive."); + } + + synchronized (this) { + this.recentEvents.add(event); + } + + NetLoggerUtil.log(EventType.IN, this.getTopicCommInfrastructure(), this.topic, event); + + return broadcast(event); + } + + @Override + public String toString() { + return "SingleThreadedBusTopicSource [consumerGroup=" + consumerGroup + ", consumerInstance=" + consumerInstance + + ", fetchTimeout=" + fetchTimeout + ", fetchLimit=" + fetchLimit + ", consumer=" + this.consumer + + ", alive=" + alive + ", locked=" + locked + ", uebThread=" + busPollerThread + ", topicListeners=" + + topicListeners.size() + ", toString()=" + super.toString() + "]"; + } + + @Override + public void shutdown() { + this.stop(); + this.topicListeners.clear(); + } +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/TopicBase.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/TopicBase.java new file mode 100644 index 00000000..4d1fbc9e --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/TopicBase.java @@ -0,0 +1,243 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2020 Bell Canada. All rights reserved. + * Modifications Copyright (C) 2023-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +import java.util.ArrayList; +import java.util.List; +import lombok.AccessLevel; +import lombok.Getter; +import org.apache.commons.collections4.queue.CircularFifoQueue; +import org.onap.policy.common.message.bus.event.Topic; +import org.onap.policy.common.message.bus.event.TopicListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Getter +public abstract class TopicBase implements Topic { + + /** + * Logger. + */ + private static final Logger logger = LoggerFactory.getLogger(TopicBase.class); + + /** + * List of servers. + */ + protected List servers; + + /** + * Topic. + */ + protected final String topic; + + /** + * Topic Alias. + */ + protected final String effectiveTopic; + + /** + * Event cache. + */ + protected CircularFifoQueue recentEvents = new CircularFifoQueue<>(10); + + /** + * Am I running? reflects invocation of start()/stop() !locked & start() => alive stop() => + * !alive. + */ + protected volatile boolean alive = false; + + /** + * Am I locked? reflects invocation of lock()/unlock() operations locked => !alive (but not in + * the other direction necessarily) locked => !offer, !run, !start, !stop (but this last one is + * obvious since locked => !alive). + */ + protected volatile boolean locked = false; + + /** + * All my subscribers for new message notifications. + */ + @Getter(AccessLevel.NONE) + protected final ArrayList topicListeners = new ArrayList<>(); + + /** + * Instantiates a new Topic Base. + * + * @param servers list of servers + * @param topic topic name + * + * @throws IllegalArgumentException if invalid parameters are present + */ + protected TopicBase(List servers, String topic) { + this(servers, topic, topic); + } + + /** + * Instantiates a new Topic Base. + * + * @param servers list of servers + * @param topic topic name + * + * @throws IllegalArgumentException if invalid parameters are present + */ + protected TopicBase(List servers, String topic, String effectiveTopic) { + + if (servers == null || servers.isEmpty()) { + throw new IllegalArgumentException("Server(s) must be provided"); + } + + if (topic == null || topic.isEmpty()) { + throw new IllegalArgumentException("A Topic must be provided"); + } + + String effectiveTopicCopy; + if (effectiveTopic == null || effectiveTopic.isEmpty()) { + effectiveTopicCopy = topic; + } else { + effectiveTopicCopy = effectiveTopic; + } + + this.servers = servers; + this.topic = topic.toLowerCase(); + this.effectiveTopic = effectiveTopicCopy.toLowerCase(); + } + + @Override + public void register(TopicListener topicListener) { + + logger.info("{}: registering {}", this, topicListener); + + synchronized (this) { + if (topicListener == null) { + throw new IllegalArgumentException("TopicListener must be provided"); + } + + for (TopicListener listener : this.topicListeners) { + if (listener == topicListener) { + return; + } + } + + this.topicListeners.add(topicListener); + } + } + + @Override + public void unregister(TopicListener topicListener) { + + logger.info("{}: unregistering {}", this, topicListener); + + synchronized (this) { + if (topicListener == null) { + throw new IllegalArgumentException("TopicListener must be provided"); + } + + this.topicListeners.remove(topicListener); + } + } + + /** + * Broadcast event to all listeners. + * + * @param message the event + * @return true if all notifications are performed with no error, false otherwise + */ + protected boolean broadcast(String message) { + List snapshotListeners = this.snapshotTopicListeners(); + + var success = true; + for (TopicListener topicListener : snapshotListeners) { + try { + topicListener.onTopicEvent(this.getTopicCommInfrastructure(), this.topic, message); + } catch (Exception e) { + logger.warn("{}: notification error @ {} because of {}", this, topicListener, e.getMessage(), e); + success = false; + } + } + return success; + } + + /** + * Take a snapshot of current topic listeners. + * + * @return the topic listeners + */ + protected synchronized List snapshotTopicListeners() { + @SuppressWarnings("unchecked") + List listeners = (List) topicListeners.clone(); + return listeners; + } + + @Override + public boolean lock() { + + logger.info("{}: locking", this); + + synchronized (this) { + if (this.locked) { + return true; + } + + this.locked = true; + } + + return this.stop(); + } + + @Override + public boolean unlock() { + logger.info("{}: unlocking", this); + + synchronized (this) { + if (!this.locked) { + return true; + } + + this.locked = false; + } + + try { + return this.start(); + } catch (Exception e) { + logger.warn("{}: cannot after unlocking because of {}", this, e.getMessage(), e); + return false; + } + } + + @Override + public synchronized String[] getRecentEvents() { + var events = new String[recentEvents.size()]; + return recentEvents.toArray(events); + } + + + @Override + public String toString() { + return "TopicBase [servers=" + servers + + ", topic=" + topic + + ", effectiveTopic=" + effectiveTopic + + ", #recentEvents=" + recentEvents.size() + + ", locked=" + locked + + ", #topicListeners=" + topicListeners.size() + + "]"; + } +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/TopicBaseFactory.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/TopicBaseFactory.java new file mode 100644 index 00000000..d98de653 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/TopicBaseFactory.java @@ -0,0 +1,87 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +import java.util.List; +import java.util.Properties; +import org.onap.policy.common.message.bus.event.Topic; +import org.onap.policy.common.parameters.topic.BusTopicParams; + +/** + * Topic Base Factory. + * + * @param Type. + */ +public interface TopicBaseFactory { + + /** + * build a TopicBase instance. + * + * @param properties properties. + * @return T instance. + */ + List build(Properties properties); + + /** + * build a TopicBase instance. + * + * @param servers servers. + * @param topic topic. + * @param managed managed. + * @return T instance. + */ + T build(List servers, String topic, boolean managed); + + /** + * Construct an instance of an endpoint. + * + * @param param parameters + * @return an instance of T. + */ + T build(BusTopicParams param); + + /** + * destroy TopicBase instance. + * @param topic topic. + */ + void destroy(String topic); + + /** + * destroy. + */ + void destroy(); + + /** + * get T instance. + * + * @param topic topic. + * @return T instance. + */ + T get(String topic); + + /** + * inventory of T instances. + * + * @return T instance list. + */ + List inventory(); +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/TopicBaseHashedFactory.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/TopicBaseHashedFactory.java new file mode 100644 index 00000000..70ff04e4 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/base/TopicBaseHashedFactory.java @@ -0,0 +1,207 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Properties; +import org.onap.policy.common.message.bus.event.Topic; +import org.onap.policy.common.parameters.topic.BusTopicParams; + +/** + * Topic Factory implementation that indexes T instances in a hash table. + */ +public abstract class TopicBaseHashedFactory implements TopicBaseFactory { + + protected static final String MISSING_TOPIC_MESSAGE = "A topic must be provided"; + protected static final String MISSING_SERVERS_MESSAGE = "Servers must be provided"; + + /** + * endpoints. + */ + protected final HashMap endpoints = new HashMap<>(); + + /** + * get the topic names. + * + * @param properties properties. + * @return list of topic names. + */ + protected abstract List getTopicNames(Properties properties); + + /** + * get the servers that this topic uses. + * + * @param topicName name. + * @param properties properties. + * @return list of servers. + */ + protected abstract List getServers(String topicName, Properties properties); + + /** + * Determines if this topic is managed. + * + * @param topicName name. + * @param properties properties. + * @return if managed. + */ + protected abstract boolean isManaged(String topicName, Properties properties); + + /** + * construct an instance of an endpoint. + * + * @param servers servers, + * @param topic topic. + * @return an instance of T. + */ + public abstract T build(List servers, String topic); + + /** + * {@inheritDoc}. + */ + @Override + public List build(Properties properties) { + List topicNames = getTopicNames(properties); + if (topicNames == null || topicNames.isEmpty()) { + return Collections.emptyList(); + } + + List newEndpoints = new ArrayList<>(); + synchronized (this) { + for (String name : topicNames) { + if (this.endpoints.containsKey(name)) { + newEndpoints.add(this.endpoints.get(name)); + continue; + } + + newEndpoints.add(this.build(getServers(name, properties), name, isManaged(name, properties))); + } + } + return newEndpoints; + } + + /** + * {@inheritDoc}. + */ + @Override + public T build(BusTopicParams param) { + return this.build(param.getServers(), param.getTopic(), param.isManaged()); + } + + /** + * {@inheritDoc}. + */ + @Override + public T build(List servers, String topic, boolean managed) { + if (servers == null || servers.isEmpty()) { + throw new IllegalArgumentException(MISSING_SERVERS_MESSAGE); + } + + if (topic == null || topic.isEmpty()) { + throw new IllegalArgumentException(MISSING_TOPIC_MESSAGE); + } + + synchronized (this) { + if (this.endpoints.containsKey(topic)) { + return this.endpoints.get(topic); + } + + var endpoint = build(servers, topic); + if (managed) { + this.endpoints.put(topic, endpoint); + } + + return endpoint; + } + } + + /** + * {@inheritDoc}. + */ + @Override + public void destroy(String topic) { + if (topic == null || topic.isEmpty()) { + throw new IllegalArgumentException(MISSING_TOPIC_MESSAGE); + } + + T endpoint; + synchronized (this) { + if (!this.endpoints.containsKey(topic)) { + return; + } + + endpoint = this.endpoints.remove(topic); + } + endpoint.shutdown(); + } + + /** + * {@inheritDoc}. + */ + @Override + public void destroy() { + final List snapshotEndpoints = this.inventory(); + for (final T snapshot : snapshotEndpoints) { + snapshot.shutdown(); + } + + synchronized (this) { + this.endpoints.clear(); + } + } + + /** + * {@inheritDoc}. + */ + @Override + public T get(String topic) { + if (topic == null || topic.isEmpty()) { + throw new IllegalArgumentException(MISSING_TOPIC_MESSAGE); + } + + synchronized (this) { + if (this.endpoints.containsKey(topic)) { + return this.endpoints.get(topic); + } else { + throw new IllegalStateException(topic + " not found"); + } + } + } + + /** + * {@inheritDoc}. + */ + @Override + public List inventory() { + return new ArrayList<>(this.endpoints.values()); + } + + /** + * {@inheritDoc}. + */ + @Override + public String toString() { + return "TopicBaseHashedFactory[ " + super.toString() + " ]"; + } +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/client/BidirectionalTopicClient.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/client/BidirectionalTopicClient.java new file mode 100644 index 00000000..6ffc188d --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/client/BidirectionalTopicClient.java @@ -0,0 +1,222 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2023-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.client; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.BlockingDeque; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.TimeUnit; +import lombok.Getter; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.TopicEndpoint; +import org.onap.policy.common.message.bus.event.TopicEndpointManager; +import org.onap.policy.common.message.bus.event.TopicListener; +import org.onap.policy.common.message.bus.event.TopicSink; +import org.onap.policy.common.message.bus.event.TopicSource; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A "bidirectional" topic, which is a pair of topics, one of which is used to publish + * requests and the other to receive responses. + */ +@Getter +public class BidirectionalTopicClient { + private static final Logger logger = LoggerFactory.getLogger(BidirectionalTopicClient.class); + private static final Coder coder = new StandardCoder(); + + private final String sinkTopic; + private final String sourceTopic; + private final TopicSink sink; + private final TopicSource source; + private final CommInfrastructure sinkTopicCommInfrastructure; + private final CommInfrastructure sourceTopicCommInfrastructure; + + /** + * Used when checking whether a message sent on the sink topic can be received + * on the source topic. When a matching message is received on the incoming topic, + * {@code true} is placed on the queue. If {@link #stopWaiting()} is called or the waiting + * thread is interrupted, then {@code false} is placed on the queue. Whenever a value + * is pulled from the queue, it is immediately placed back on the queue. + */ + private final BlockingDeque checkerQueue = new LinkedBlockingDeque<>(); + + + /** + * Constructs the object. + * + * @param sinkTopic sink topic name + * @param sourceTopic source topic name + * @throws BidirectionalTopicClientException if either topic does not exist + */ + public BidirectionalTopicClient(String sinkTopic, String sourceTopic) throws BidirectionalTopicClientException { + this.sinkTopic = sinkTopic.toLowerCase(); + this.sourceTopic = sourceTopic.toLowerCase(); + + // init sinkClient + List sinks = getTopicEndpointManager().getTopicSinks(sinkTopic); + if (sinks.isEmpty()) { + throw new BidirectionalTopicClientException("no sinks for topic: " + sinkTopic); + } else if (sinks.size() > 1) { + throw new BidirectionalTopicClientException("too many sinks for topic: " + sinkTopic); + } + + this.sink = sinks.get(0); + + // init source + List sources = getTopicEndpointManager().getTopicSources(Collections.singletonList(sourceTopic)); + if (sources.isEmpty()) { + throw new BidirectionalTopicClientException("no sources for topic: " + sourceTopic); + } else if (sources.size() > 1) { + throw new BidirectionalTopicClientException("too many sources for topic: " + sourceTopic); + } + + this.source = sources.get(0); + + this.sinkTopicCommInfrastructure = sink.getTopicCommInfrastructure(); + this.sourceTopicCommInfrastructure = source.getTopicCommInfrastructure(); + } + + public boolean send(String message) { + return sink.send(message); + } + + public void register(TopicListener topicListener) { + source.register(topicListener); + } + + public boolean offer(String event) { + return source.offer(event); + } + + public void unregister(TopicListener topicListener) { + source.unregister(topicListener); + } + + /** + * Determines whether the topic is ready (i.e., {@link #awaitReady(Object, long)} has + * previously returned {@code true}). + * + * @return {@code true}, if the topic is ready to send and receive + */ + public boolean isReady() { + return Boolean.TRUE.equals(checkerQueue.peek()); + } + + /** + * Waits for the bidirectional topic to become "ready" by publishing a message on the + * sink topic and awaiting receipt of the message on the source topic. If the message + * is not received within a few seconds, then it tries again. This process is + * continued until the message is received, {@link #stopWaiting()} is called, or this thread + * is interrupted. Once this returns, subsequent calls will return immediately, always + * with the same value. + * + * @param message message to be sent to the sink topic. Note: the equals() method must + * return {@code true} if and only if two messages are the same + * @param waitMs time to wait, in milliseconds, before re-sending the message + * @return {@code true} if the message was received from the source topic, + * {@code false} if this method was stopped or interrupted before receipt of + * the message + * @throws CoderException if the message cannot be encoded + */ + public synchronized boolean awaitReady(T message, long waitMs) throws CoderException { + // see if we already know the answer + if (!checkerQueue.isEmpty()) { + return checkerQueue.peek(); + } + + final String messageText = coder.encode(message); + + // class of message to be decoded + final TopicListener listener = getTopicListener(message); + + source.register(listener); + + // loop until the message is received + try { + Boolean result; + do { + send(messageText); + } while ((result = checkerQueue.poll(waitMs, TimeUnit.MILLISECONDS)) == null); + + // put it back on the queue + checkerQueue.add(result); + + } catch (InterruptedException e) { + logger.error("interrupted waiting for topic sink {} source {}", sink.getTopic(), source.getTopic(), e); + Thread.currentThread().interrupt(); + checkerQueue.add(Boolean.FALSE); + + } finally { + source.unregister(listener); + } + + return checkerQueue.peek(); + } + + private TopicListener getTopicListener(T message) { + @SuppressWarnings("unchecked") + final Class clazz = (Class) message.getClass(); + + // create a listener to detect when a matching message is received + return (infra, topic, msg) -> { + try { + T incoming = decode(msg, clazz); + + if (message.equals(incoming)) { + logger.info("topic {} is ready; found matching message {}", topic, incoming); + checkerQueue.add(Boolean.TRUE); + } + + } catch (CoderException e) { + logger.warn("cannot decode message from topic {}", topic, e); + decodeFailed(); + } + }; + } + + /** + * Stops any listeners that are currently stuck in {@link #awaitReady(Object, long)} by + * adding {@code false} to the queue. + */ + public void stopWaiting() { + checkerQueue.add(Boolean.FALSE); + } + + // these may be overridden by junit tests + + protected TopicEndpoint getTopicEndpointManager() { + return TopicEndpointManager.getManager(); + } + + protected T decode(String msg, Class clazz) throws CoderException { + return coder.decode(msg, clazz); + } + + protected void decodeFailed() { + // already logged - nothing else to do + } +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/client/BidirectionalTopicClientException.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/client/BidirectionalTopicClientException.java new file mode 100644 index 00000000..442c5243 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/client/BidirectionalTopicClientException.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2023-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.client; + +import java.io.Serial; + +/** + * Exception thrown by BidirectionalTopicClient class. + */ +public class BidirectionalTopicClientException extends Exception { + @Serial + private static final long serialVersionUID = 1L; + + public BidirectionalTopicClientException() { + super(); + } + + public BidirectionalTopicClientException(String message) { + super(message); + } + + public BidirectionalTopicClientException(Throwable cause) { + super(cause); + } + + public BidirectionalTopicClientException(String message, Throwable cause) { + super(message, cause); + } + + public BidirectionalTopicClientException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/client/TopicSinkClient.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/client/TopicSinkClient.java new file mode 100644 index 00000000..131bf2d7 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/client/TopicSinkClient.java @@ -0,0 +1,114 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019, 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.client; + +import java.util.List; +import lombok.Getter; +import lombok.NonNull; +import org.onap.policy.common.message.bus.event.TopicEndpointManager; +import org.onap.policy.common.message.bus.event.TopicSink; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Client for sending messages to a Topic using TopicSink. + */ +@Getter +public class TopicSinkClient { + private static final Logger logger = LoggerFactory.getLogger(TopicSinkClient.class); + + /** + * Coder used to encode messages being sent to the topic. + */ + private static final Coder CODER = new StandardCoder(); + + /** + * Where messages are published. + */ + private final TopicSink sink; + + /** + * Constructs the object. + * + * @param topic topic to which messages should be published + * @throws TopicSinkClientException if the topic does not exist + */ + public TopicSinkClient(final String topic) throws TopicSinkClientException { + final List lst = getTopicSinks(topic.toLowerCase()); + if (lst.isEmpty()) { + throw new TopicSinkClientException("no sinks for topic: " + topic.toLowerCase()); + } + + this.sink = lst.get(0); + } + + /** + * Constructs the client from a sink object. + * + * @param sink topic sink publisher + */ + public TopicSinkClient(@NonNull TopicSink sink) { + this.sink = sink; + } + + + /** + * Gets the canonical topic name. + * + * @return topic name + */ + public String getTopic() { + return this.sink.getTopic(); + } + + /** + * Sends a message to the topic, after encoding the message as json. + * + * @param message message to be encoded and sent + * @return {@code true} if the message was successfully sent/enqueued, {@code false} otherwise + */ + public boolean send(final Object message) { + try { + final String json = CODER.encode(message); + return sink.send(json); + + } catch (RuntimeException | CoderException e) { + logger.warn("send to {} failed because of {}", sink.getTopic(), e.getMessage(), e); + return false; + } + } + + // the remaining methods are wrappers that can be overridden by junit tests + + /** + * Gets the sinks for a given topic. + * + * @param topic the topic of interest + * @return the sinks for the topic + */ + protected List getTopicSinks(final String topic) { + return TopicEndpointManager.getManager().getTopicSinks(topic); + } +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/client/TopicSinkClientException.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/client/TopicSinkClientException.java new file mode 100644 index 00000000..fad5e119 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/client/TopicSinkClientException.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019, 2023-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.client; + +import java.io.Serial; + +/** + * Exception thrown by TopicSink client classes. + */ +public class TopicSinkClientException extends Exception { + @Serial + private static final long serialVersionUID = 1L; + + public TopicSinkClientException() { + super(); + } + + public TopicSinkClientException(final String message) { + super(message); + } + + public TopicSinkClientException(final Throwable cause) { + super(cause); + } + + public TopicSinkClientException(final String message, final Throwable cause) { + super(message, cause); + } + + public TopicSinkClientException(final String message, final Throwable cause, final boolean enableSuppression, + final boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/IndexedKafkaTopicSinkFactory.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/IndexedKafkaTopicSinkFactory.java new file mode 100644 index 00000000..0497f1f5 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/IndexedKafkaTopicSinkFactory.java @@ -0,0 +1,201 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_KAFKA_SINK_TOPICS; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_TOPIC_SERVERS_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_TOPIC_SINK_PARTITION_KEY_SUFFIX; + +import com.google.re2j.Pattern; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Properties; +import org.apache.commons.lang3.StringUtils; +import org.onap.policy.common.message.bus.utils.KafkaPropertyUtils; +import org.onap.policy.common.parameters.topic.BusTopicParams; +import org.onap.policy.common.utils.properties.PropertyUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Factory of KAFKA Reader Topics indexed by topic name. + */ +class IndexedKafkaTopicSinkFactory implements KafkaTopicSinkFactory { + private static final Pattern COMMA_SPACE_PAT = Pattern.compile("\\s*,\\s*"); + private static final String MISSING_TOPIC = "A topic must be provided"; + + /** + * Logger. + */ + private static final Logger logger = LoggerFactory.getLogger(IndexedKafkaTopicSinkFactory.class); + + /** + * KAFKA Topic Name Index. + */ + protected HashMap kafkaTopicSinks = new HashMap<>(); + + @Override + public KafkaTopicSink build(BusTopicParams busTopicParams) { + + if (busTopicParams.getServers() == null || busTopicParams.getServers().isEmpty()) { + throw new IllegalArgumentException("KAFKA Server(s) must be provided"); + } + + if (StringUtils.isBlank(busTopicParams.getTopic())) { + throw new IllegalArgumentException(MISSING_TOPIC); + } + + synchronized (this) { + if (kafkaTopicSinks.containsKey(busTopicParams.getTopic())) { + return kafkaTopicSinks.get(busTopicParams.getTopic()); + } + + KafkaTopicSink kafkaTopicWriter = makeSink(busTopicParams); + if (busTopicParams.isManaged()) { + kafkaTopicSinks.put(busTopicParams.getTopic(), kafkaTopicWriter); + } + + return kafkaTopicWriter; + } + } + + + @Override + public KafkaTopicSink build(List servers, String topic) { + return this.build(BusTopicParams.builder() + .servers(servers) + .topic(topic) + .managed(true) + .useHttps(false) + .build()); + } + + + @Override + public List build(Properties properties) { + + String writeTopics = properties.getProperty(PROPERTY_KAFKA_SINK_TOPICS); + if (StringUtils.isBlank(writeTopics)) { + logger.info("{}: no topic for KAFKA Sink", this); + return new ArrayList<>(); + } + + List newKafkaTopicSinks = new ArrayList<>(); + synchronized (this) { + for (String topic : COMMA_SPACE_PAT.split(writeTopics)) { + addTopic(newKafkaTopicSinks, topic.toLowerCase(), properties); + } + return newKafkaTopicSinks; + } + } + + private void addTopic(List newKafkaTopicSinks, String topic, Properties properties) { + if (this.kafkaTopicSinks.containsKey(topic)) { + newKafkaTopicSinks.add(this.kafkaTopicSinks.get(topic)); + return; + } + + String topicPrefix = PROPERTY_KAFKA_SINK_TOPICS + "." + topic; + + var props = new PropertyUtils(properties, topicPrefix, + (name, value, ex) -> logger.warn("{}: {} {} is in invalid format for topic sink {} ", + this, name, value, topic)); + + String servers = properties.getProperty(topicPrefix + PROPERTY_TOPIC_SERVERS_SUFFIX); + if (StringUtils.isBlank(servers)) { + logger.error("{}: no KAFKA servers configured for sink {}", this, topic); + return; + } + + KafkaTopicSink kafkaTopicWriter = this.build(KafkaPropertyUtils.makeBuilder(props, topic, servers) + .partitionId(props.getString(PROPERTY_TOPIC_SINK_PARTITION_KEY_SUFFIX, null)) + .build()); + newKafkaTopicSinks.add(kafkaTopicWriter); + } + + @Override + public void destroy(String topic) { + + if (topic == null || topic.isEmpty()) { + throw new IllegalArgumentException(MISSING_TOPIC); + } + + KafkaTopicSink kafkaTopicWriter; + synchronized (this) { + if (!kafkaTopicSinks.containsKey(topic)) { + return; + } + + kafkaTopicWriter = kafkaTopicSinks.remove(topic); + } + + kafkaTopicWriter.shutdown(); + } + + @Override + public void destroy() { + List writers = this.inventory(); + for (KafkaTopicSink writer : writers) { + writer.shutdown(); + } + + synchronized (this) { + this.kafkaTopicSinks.clear(); + } + } + + @Override + public KafkaTopicSink get(String topic) { + + if (topic == null || topic.isEmpty()) { + throw new IllegalArgumentException(MISSING_TOPIC); + } + + synchronized (this) { + if (kafkaTopicSinks.containsKey(topic)) { + return kafkaTopicSinks.get(topic); + } else { + throw new IllegalStateException("KafkaTopicSink for " + topic + " not found"); + } + } + } + + @Override + public synchronized List inventory() { + return new ArrayList<>(this.kafkaTopicSinks.values()); + } + + /** + * Makes a new sink. + * + * @param busTopicParams parameters to use to configure the sink + * @return a new sink + */ + protected KafkaTopicSink makeSink(BusTopicParams busTopicParams) { + return new InlineKafkaTopicSink(busTopicParams); + } + + + @Override + public String toString() { + return "IndexedKafkaTopicSinkFactory " + kafkaTopicSinks.keySet(); + } + +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/IndexedKafkaTopicSourceFactory.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/IndexedKafkaTopicSourceFactory.java new file mode 100644 index 00000000..1aac89ce --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/IndexedKafkaTopicSourceFactory.java @@ -0,0 +1,211 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.DEFAULT_LIMIT_FETCH; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.DEFAULT_TIMEOUT_MS_FETCH; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_KAFKA_SOURCE_TOPICS; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_TOPIC_SERVERS_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_TOPIC_SOURCE_CONSUMER_GROUP_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_TOPIC_SOURCE_CONSUMER_INSTANCE_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_TOPIC_SOURCE_FETCH_LIMIT_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_TOPIC_SOURCE_FETCH_TIMEOUT_SUFFIX; + +import com.google.re2j.Pattern; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Properties; +import org.apache.commons.lang3.StringUtils; +import org.onap.policy.common.message.bus.utils.KafkaPropertyUtils; +import org.onap.policy.common.parameters.topic.BusTopicParams; +import org.onap.policy.common.utils.properties.PropertyUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Factory of KAFKA Source Topics indexed by topic name. + */ +class IndexedKafkaTopicSourceFactory implements KafkaTopicSourceFactory { + private static final Pattern COMMA_SPACE_PAT = Pattern.compile("\\s*,\\s*"); + private static final String MISSING_TOPIC = "A topic must be provided"; + + /** + * Logger. + */ + private static final Logger logger = LoggerFactory.getLogger(IndexedKafkaTopicSourceFactory.class); + + /** + * KAFKA Topic Name Index. + */ + protected HashMap kafkaTopicSources = new HashMap<>(); + + @Override + public KafkaTopicSource build(BusTopicParams busTopicParams) { + if (busTopicParams.getServers() == null || busTopicParams.getServers().isEmpty()) { + throw new IllegalArgumentException("KAFKA Server(s) must be provided"); + } + + if (busTopicParams.getTopic() == null || busTopicParams.getTopic().isEmpty()) { + throw new IllegalArgumentException(MISSING_TOPIC); + } + + synchronized (this) { + if (kafkaTopicSources.containsKey(busTopicParams.getTopic())) { + return kafkaTopicSources.get(busTopicParams.getTopic()); + } + + var kafkaTopicSource = makeSource(busTopicParams); + + kafkaTopicSources.put(busTopicParams.getTopic(), kafkaTopicSource); + + return kafkaTopicSource; + } + } + + @Override + public List build(Properties properties) { + + String readTopics = properties.getProperty(PROPERTY_KAFKA_SOURCE_TOPICS); + if (StringUtils.isBlank(readTopics)) { + logger.info("{}: no topic for KAFKA Source", this); + return new ArrayList<>(); + } + + List newKafkaTopicSources = new ArrayList<>(); + synchronized (this) { + for (String topic : COMMA_SPACE_PAT.split(readTopics)) { + addTopic(newKafkaTopicSources, topic.toLowerCase(), properties); + } + } + return newKafkaTopicSources; + } + + @Override + public KafkaTopicSource build(List servers, String topic) { + return this.build(BusTopicParams.builder() + .servers(servers) + .topic(topic) + .managed(true) + .fetchTimeout(DEFAULT_TIMEOUT_MS_FETCH) + .fetchLimit(DEFAULT_LIMIT_FETCH) + .useHttps(false).build()); + } + + private void addTopic(List newKafkaTopicSources, String topic, Properties properties) { + if (this.kafkaTopicSources.containsKey(topic)) { + newKafkaTopicSources.add(this.kafkaTopicSources.get(topic)); + return; + } + + String topicPrefix = PROPERTY_KAFKA_SOURCE_TOPICS + "." + topic; + + var props = new PropertyUtils(properties, topicPrefix, + (name, value, ex) -> logger.warn("{}: {} {} is in invalid format for topic source {} ", + this, name, value, topic)); + + String servers = properties.getProperty(topicPrefix + PROPERTY_TOPIC_SERVERS_SUFFIX); + if (StringUtils.isBlank(servers)) { + logger.error("{}: no KAFKA servers configured for source {}", this, topic); + return; + } + + var kafkaTopicSource = this.build(KafkaPropertyUtils.makeBuilder(props, topic, servers) + .consumerGroup(props.getString( + PROPERTY_TOPIC_SOURCE_CONSUMER_GROUP_SUFFIX, null)) + .consumerInstance(props.getString( + PROPERTY_TOPIC_SOURCE_CONSUMER_INSTANCE_SUFFIX, null)) + .fetchTimeout(props.getInteger( + PROPERTY_TOPIC_SOURCE_FETCH_TIMEOUT_SUFFIX, + DEFAULT_TIMEOUT_MS_FETCH)) + .fetchLimit(props.getInteger(PROPERTY_TOPIC_SOURCE_FETCH_LIMIT_SUFFIX, + DEFAULT_LIMIT_FETCH)) + .build()); + + newKafkaTopicSources.add(kafkaTopicSource); + } + + /** + * Makes a new source. + * + * @param busTopicParams parameters to use to configure the source + * @return a new source + */ + protected KafkaTopicSource makeSource(BusTopicParams busTopicParams) { + return new SingleThreadedKafkaTopicSource(busTopicParams); + } + + @Override + public void destroy(String topic) { + + if (topic == null || topic.isEmpty()) { + throw new IllegalArgumentException(MISSING_TOPIC); + } + + KafkaTopicSource kafkaTopicSource; + + synchronized (this) { + if (!kafkaTopicSources.containsKey(topic)) { + return; + } + + kafkaTopicSource = kafkaTopicSources.remove(topic); + } + + kafkaTopicSource.shutdown(); + } + + @Override + public void destroy() { + List readers = this.inventory(); + for (KafkaTopicSource reader : readers) { + reader.shutdown(); + } + + synchronized (this) { + this.kafkaTopicSources.clear(); + } + } + + @Override + public KafkaTopicSource get(String topic) { + + if (topic == null || topic.isEmpty()) { + throw new IllegalArgumentException(MISSING_TOPIC); + } + + synchronized (this) { + if (kafkaTopicSources.containsKey(topic)) { + return kafkaTopicSources.get(topic); + } else { + throw new IllegalStateException("KafkaTopiceSource for " + topic + " not found"); + } + } + } + + @Override + public synchronized List inventory() { + return new ArrayList<>(this.kafkaTopicSources.values()); + } + + @Override + public String toString() { + return "IndexedKafkaTopicSourceFactory " + kafkaTopicSources.keySet(); + } +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/InlineKafkaTopicSink.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/InlineKafkaTopicSink.java new file mode 100644 index 00000000..4bdd2b0f --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/InlineKafkaTopicSink.java @@ -0,0 +1,83 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import java.util.Map; +import org.onap.policy.common.message.bus.event.Topic; +import org.onap.policy.common.message.bus.event.base.InlineBusTopicSink; +import org.onap.policy.common.parameters.topic.BusTopicParams; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This implementation publishes events for the associated KAFKA topic, inline with the calling + * thread. + */ +public class InlineKafkaTopicSink extends InlineBusTopicSink implements KafkaTopicSink { + + /** + * Logger. + */ + private static final Logger logger = LoggerFactory.getLogger(InlineKafkaTopicSink.class); + + protected Map additionalProps; + + /** + * Argument-based KAFKA Topic Writer instantiation. BusTopicParams contains the below + * attributes. + * + *

servers list of KAFKA servers available for publishing + * topic the topic to publish to + * partitionId the partition key (optional, autogenerated if not provided) + * useHttps does connection use HTTPS? + * @param busTopicParams contains attributes needed + * @throws IllegalArgumentException if invalid arguments are detected + */ + public InlineKafkaTopicSink(BusTopicParams busTopicParams) { + super(busTopicParams); + this.additionalProps = busTopicParams.getAdditionalProps(); + } + + /** + * Instantiation of internal resources. + */ + @Override + public void init() { + + this.publisher = new KafkaPublisherWrapper(BusTopicParams.builder() + .servers(this.servers) + .topic(this.effectiveTopic) + .useHttps(this.useHttps) + .allowTracing(this.allowTracing) + .additionalProps(this.additionalProps) + .build()); + logger.info("{}: KAFKA SINK created", this); + } + + @Override + public String toString() { + return "InlineKafkaTopicSink [getTopicCommInfrastructure()=" + getTopicCommInfrastructure() + ", toString()=" + + super.toString() + "]"; + } + + @Override + public CommInfrastructure getTopicCommInfrastructure() { + return Topic.CommInfrastructure.KAFKA; + } +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaPublisherWrapper.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaPublisherWrapper.java new file mode 100644 index 00000000..86b9e936 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaPublisherWrapper.java @@ -0,0 +1,121 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import io.opentelemetry.instrumentation.kafkaclients.v2_6.TracingProducerInterceptor; +import java.util.Properties; +import java.util.UUID; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.Producer; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.onap.policy.common.message.bus.event.base.BusPublisher; +import org.onap.policy.common.parameters.topic.BusTopicParams; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Kafka based library publisher. + */ +public class KafkaPublisherWrapper implements BusPublisher { + + private static final Logger logger = LoggerFactory.getLogger(KafkaPublisherWrapper.class); + private static final String KEY_SERIALIZER = "org.apache.kafka.common.serialization.StringSerializer"; + + private final String topic; + + /** + * Kafka publisher. + */ + private final Producer producer; + protected Properties kafkaProps; + + /** + * Kafka Publisher Wrapper. + * + * @param busTopicParams topic parameters + */ + public KafkaPublisherWrapper(BusTopicParams busTopicParams) { + + if (busTopicParams.isTopicInvalid()) { + throw new IllegalArgumentException("No topic for Kafka"); + } + + this.topic = busTopicParams.getTopic(); + + // Setup Properties for consumer + kafkaProps = new Properties(); + kafkaProps.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, busTopicParams.getServers().get(0)); + if (busTopicParams.isAdditionalPropsValid()) { + kafkaProps.putAll(busTopicParams.getAdditionalProps()); + } + + if (kafkaProps.get(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG) == null) { + kafkaProps.setProperty(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, KEY_SERIALIZER); + } + + if (kafkaProps.get(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG) == null) { + kafkaProps.setProperty(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, KEY_SERIALIZER); + } + + if (busTopicParams.isAllowTracing()) { + kafkaProps.setProperty(ProducerConfig.INTERCEPTOR_CLASSES_CONFIG, + TracingProducerInterceptor.class.getName()); + } + + producer = new KafkaProducer<>(kafkaProps); + } + + @Override + public boolean send(String partitionId, String message) { + if (message == null) { + throw new IllegalArgumentException(NO_MESSAGE_PROVIDED); + } + + try { + // Create the record + ProducerRecord producerRecord = + new ProducerRecord<>(topic, UUID.randomUUID().toString(), message); + + this.producer.send(producerRecord); + producer.flush(); + } catch (Exception e) { + logger.warn("{}: SEND of {} cannot be performed because of {}", this, message, e.getMessage(), e); + return false; + } + return true; + } + + @Override + public void close() { + logger.info(LOG_CLOSE, this); + + try { + this.producer.close(); + } catch (Exception e) { + logger.warn("{}: CLOSE FAILED because of {}", this, e.getMessage(), e); + } + } + + @Override + public String toString() { + return "KafkaPublisherWrapper []"; + } + +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicFactories.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicFactories.java new file mode 100644 index 00000000..c10285fc --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicFactories.java @@ -0,0 +1,39 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022, 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class KafkaTopicFactories { + + /** + * Factory for instantiation and management of sinks. + */ + @Getter + private static final KafkaTopicSinkFactory sinkFactory = new IndexedKafkaTopicSinkFactory(); + + /** + * Factory for instantiation and management of sources. + */ + @Getter + private static final KafkaTopicSourceFactory sourceFactory = new IndexedKafkaTopicSourceFactory(); +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSink.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSink.java new file mode 100644 index 00000000..f784a987 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSink.java @@ -0,0 +1,28 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022, 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import org.onap.policy.common.message.bus.event.base.BusTopicSink; + +/** + * Topic Writer over KAFKA Infrastructure. + */ +public interface KafkaTopicSink extends BusTopicSink { + +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSinkFactory.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSinkFactory.java new file mode 100644 index 00000000..8feecbe0 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSinkFactory.java @@ -0,0 +1,89 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022, 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import java.util.List; +import java.util.Properties; +import org.onap.policy.common.parameters.topic.BusTopicParams; + +/** + * KAFKA Topic Sink Factory. + */ +public interface KafkaTopicSinkFactory { + + /** + * Instantiates a new KAFKA Topic Writer. + * + * @param busTopicParams parameters object + * @return an KAFKA Topic Sink + */ + KafkaTopicSink build(BusTopicParams busTopicParams); + + /** + * Creates an KAFKA Topic Writer based on properties files. + * + * @param properties Properties containing initialization values + * + * @return an KAFKA Topic Writer + * @throws IllegalArgumentException if invalid parameters are present + */ + List build(Properties properties); + + /** + * Instantiates a new KAFKA Topic Writer. + * + * @param servers list of servers + * @param topic topic name + * + * @return an KAFKA Topic Writer + * @throws IllegalArgumentException if invalid parameters are present + */ + KafkaTopicSink build(List servers, String topic); + + /** + * Destroys an KAFKA Topic Writer based on a topic. + * + * @param topic topic name + * @throws IllegalArgumentException if invalid parameters are present + */ + void destroy(String topic); + + /** + * Destroys all KAFKA Topic Writers. + */ + void destroy(); + + /** + * gets an KAFKA Topic Writer based on topic name. + * + * @param topic the topic name + * + * @return an KAFKA Topic Writer with topic name + * @throws IllegalArgumentException if an invalid topic is provided + * @throws IllegalStateException if the KAFKA Topic Reader is an incorrect state + */ + KafkaTopicSink get(String topic); + + /** + * Provides a snapshot of the KAFKA Topic Writers. + * + * @return a list of the KAFKA Topic Writers + */ + List inventory(); +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSource.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSource.java new file mode 100644 index 00000000..bddced7a --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSource.java @@ -0,0 +1,28 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022, 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import org.onap.policy.common.message.bus.event.base.BusTopicSource; + +/** + * Kafka Topic Source. + */ +public interface KafkaTopicSource extends BusTopicSource { + +} \ No newline at end of file diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSourceFactory.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSourceFactory.java new file mode 100644 index 00000000..06f4412c --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSourceFactory.java @@ -0,0 +1,88 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import java.util.List; +import java.util.Properties; +import org.onap.policy.common.parameters.topic.BusTopicParams; + +/** + * Kafka Topic Source Factory. + */ +public interface KafkaTopicSourceFactory { + + /** + * Creates a Kafka Topic Source based on properties files. + * + * @param properties Properties containing initialization values + * + * @return a Kafka Topic Source + * @throws IllegalArgumentException if invalid parameters are present + */ + List build(Properties properties); + + /** + * Instantiates a new Kafka Topic Source. + * + * @param busTopicParams parameters object + * @return a Kafka Topic Source + */ + KafkaTopicSource build(BusTopicParams busTopicParams); + + /** + * Instantiates a new Kafka Topic Source. + * + * @param servers list of servers + * @param topic topic name + * + * @return a Kafka Topic Source + * @throws IllegalArgumentException if invalid parameters are present + */ + KafkaTopicSource build(List servers, String topic); + + /** + * Destroys a Kafka Topic Source based on a topic. + * + * @param topic topic name + * @throws IllegalArgumentException if invalid parameters are present + */ + void destroy(String topic); + + /** + * Destroys all Kafka Topic Sources. + */ + void destroy(); + + /** + * Gets a Kafka Topic Source based on topic name. + * + * @param topic the topic name + * @return a Kafka Topic Source with topic name + * @throws IllegalArgumentException if an invalid topic is provided + * @throws IllegalStateException if the Kafka Topic Source is an incorrect state + */ + KafkaTopicSource get(String topic); + + /** + * Provides a snapshot of the Kafka Topic Sources. + * + * @return a list of the Kafka Topic Sources + */ + List inventory(); +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/SingleThreadedKafkaTopicSource.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/SingleThreadedKafkaTopicSource.java new file mode 100644 index 00000000..5691cb12 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/kafka/SingleThreadedKafkaTopicSource.java @@ -0,0 +1,80 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import java.util.Map; +import org.onap.policy.common.message.bus.event.Topic; +import org.onap.policy.common.message.bus.event.base.BusConsumer; +import org.onap.policy.common.message.bus.event.base.SingleThreadedBusTopicSource; +import org.onap.policy.common.parameters.topic.BusTopicParams; + +/** + * This topic source implementation specializes in reading messages over a Kafka Bus topic source and + * notifying its listeners. + */ +public class SingleThreadedKafkaTopicSource extends SingleThreadedBusTopicSource implements KafkaTopicSource { + + protected Map additionalProps = null; + + /** + * Constructor. + * + * @param busTopicParams Parameters object containing all the required inputs + * @throws IllegalArgumentException An invalid parameter passed in + */ + public SingleThreadedKafkaTopicSource(BusTopicParams busTopicParams) { + super(busTopicParams); + this.additionalProps = busTopicParams.getAdditionalProps(); + try { + this.init(); + } catch (Exception e) { + throw new IllegalArgumentException("ERROR during init in kafka-source: cannot create topic " + topic, e); + } + } + + /** + * Initialize the client. + */ + @Override + public void init() { + BusTopicParams.TopicParamsBuilder builder = BusTopicParams.builder() + .servers(this.servers) + .topic(this.effectiveTopic) + .fetchTimeout(this.fetchTimeout) + .consumerGroup(this.consumerGroup) + .useHttps(this.useHttps) + .allowTracing(this.allowTracing); + + this.consumer = new BusConsumer.KafkaConsumerWrapper(builder + .additionalProps(this.additionalProps) + .build()); + } + + @Override + public CommInfrastructure getTopicCommInfrastructure() { + return Topic.CommInfrastructure.KAFKA; + } + + @Override + public String toString() { + return "SingleThreadedKafkaTopicSource [getTopicCommInfrastructure()=" + getTopicCommInfrastructure() + + ", toString()=" + super.toString() + "]"; + } + +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicEndpoint.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicEndpoint.java new file mode 100644 index 00000000..e25aca54 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicEndpoint.java @@ -0,0 +1,141 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019 Samsung Electronics Co., Ltd. + * Modifications Copyright (C) 2020 Bell Canada. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.noop; + +import java.util.List; +import org.onap.policy.common.message.bus.event.base.TopicBase; +import org.onap.policy.common.message.bus.utils.NetLoggerUtil; +import org.onap.policy.common.message.bus.utils.NetLoggerUtil.EventType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * No Operation topic endpoint. + */ +public abstract class NoopTopicEndpoint extends TopicBase { + + /** + * Logger. + */ + private static final Logger logger = LoggerFactory.getLogger(NoopTopicEndpoint.class); + + /** + * Constructs the object. + */ + protected NoopTopicEndpoint(List servers, String topic) { + super(servers, topic); + } + + /** + * I/O. + * + * @param type "IN" or "OUT". + * @param message message. + * @return true if successful. + */ + protected boolean io(EventType type, String message) { + + if (message == null || message.isEmpty()) { + throw new IllegalArgumentException("Message is empty"); + } + + if (!this.alive) { + throw new IllegalStateException(this + " is stopped"); + } + + try { + synchronized (this) { + this.recentEvents.add(message); + } + + NetLoggerUtil.log(type, this.getTopicCommInfrastructure(), this.topic, message); + + broadcast(message); + } catch (Exception e) { + logger.warn("{}: cannot send because of {}", this, e.getMessage(), e); + return false; + } + + return true; + } + + /** + * {@inheritDoc}. + */ + @Override + public CommInfrastructure getTopicCommInfrastructure() { + return CommInfrastructure.NOOP; + } + + /** + * {@inheritDoc}. + */ + @Override + public boolean start() { + logger.info("{}: starting", this); + + synchronized (this) { + if (!this.alive) { + if (locked) { + throw new IllegalStateException(this + " is locked."); + } + + this.alive = true; + } + } + + return true; + } + + /** + * {@inheritDoc}. + */ + @Override + public boolean stop() { + logger.info("{}: stopping", this); + + synchronized (this) { + this.alive = false; + } + return true; + } + + /** + * {@inheritDoc}. + */ + @Override + public void shutdown() { + logger.info("{}: shutdown", this); + + this.stop(); + } + + /** + * {@inheritDoc}. + */ + @Override + public String toString() { + return "NoopTopicEndpoint[" + super.toString() + "]"; + } +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicFactories.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicFactories.java new file mode 100644 index 00000000..506cc9f9 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicFactories.java @@ -0,0 +1,42 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.noop; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class NoopTopicFactories { + + /** + * Factory for instantiation and management of sinks. + */ + @Getter + private static final NoopTopicSinkFactory sinkFactory = new NoopTopicSinkFactory(); + + /** + * Factory for instantiation and management of sources. + */ + @Getter + private static final NoopTopicSourceFactory sourceFactory = new NoopTopicSourceFactory(); +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicFactory.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicFactory.java new file mode 100644 index 00000000..e81dfaea --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicFactory.java @@ -0,0 +1,117 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.noop; + +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_MANAGED_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_TOPIC_SERVERS_SUFFIX; + +import com.google.re2j.Pattern; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Properties; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.base.TopicBaseHashedFactory; + +/** + * Noop Topic Factory. + */ +public abstract class NoopTopicFactory extends TopicBaseHashedFactory { + private static final Pattern COMMA_SPACE_PAT = Pattern.compile("\\s*,\\s*"); + + /** + * Get Topics Property Name. + * + * @return property name. + */ + protected abstract String getTopicsPropertyName(); + + /** + * {@inheritDoc}. + */ + @Override + protected List getTopicNames(Properties properties) { + String topics = properties.getProperty(getTopicsPropertyName()); + if (topics == null || topics.isEmpty()) { + return new ArrayList<>(); + } + + return Arrays.asList(COMMA_SPACE_PAT.split(topics)); + } + + /** + * {@inheritDoc}. + */ + @Override + protected List getServers(String topicName, Properties properties) { + String servers = + properties.getProperty(getTopicsPropertyName() + "." + topicName + + PROPERTY_TOPIC_SERVERS_SUFFIX); + + if (servers == null || servers.isEmpty()) { + servers = CommInfrastructure.NOOP.toString(); + } + + return new ArrayList<>(Arrays.asList(COMMA_SPACE_PAT.split(servers))); + } + + /** + * {@inheritDoc}. + */ + @Override + protected boolean isManaged(String topicName, Properties properties) { + var managedString = + properties.getProperty(getTopicsPropertyName() + "." + topicName + PROPERTY_MANAGED_SUFFIX); + + var managed = true; + if (managedString != null && !managedString.isEmpty()) { + managed = Boolean.parseBoolean(managedString); + } + + return managed; + } + + /** + * {@inheritDoc}. + */ + @Override + public T build(List serverList, String topic, boolean managed) { + List servers; + if (serverList == null || serverList.isEmpty()) { + servers = Collections.singletonList(CommInfrastructure.NOOP.toString()); + } else { + servers = serverList; + } + + return super.build(servers, topic, managed); + } + + /** + * {@inheritDoc}. + */ + @Override + public String toString() { + return "NoopTopicFactory[ " + super.toString() + " ]"; + } +} + diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSink.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSink.java new file mode 100644 index 00000000..b7d78ff4 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSink.java @@ -0,0 +1,56 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.noop; + +import java.util.List; +import org.onap.policy.common.message.bus.event.TopicSink; +import org.onap.policy.common.message.bus.utils.NetLoggerUtil.EventType; + +/** + * No Operation Topic Sink. + */ +public class NoopTopicSink extends NoopTopicEndpoint implements TopicSink { + + /** + * Constructs the object. + */ + public NoopTopicSink(List servers, String topic) { + super(servers, topic); + } + + /** + * {@inheritDoc}. + */ + @Override + public boolean send(String message) { + return super.io(EventType.OUT, message); + } + + /** + * {@inheritDoc}. + */ + @Override + public String toString() { + return "NoopTopicSink[" + super.toString() + "]"; + } + +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSinkFactory.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSinkFactory.java new file mode 100644 index 00000000..cdf4a17b --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSinkFactory.java @@ -0,0 +1,58 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.noop; + +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_NOOP_SINK_TOPICS; + +import java.util.List; + +/** + * Noop Topic Sink Factory. + */ +public class NoopTopicSinkFactory extends NoopTopicFactory { + + /** + * {@inheritDoc}. + */ + @Override + protected String getTopicsPropertyName() { + return PROPERTY_NOOP_SINK_TOPICS; + } + + /** + * {@inheritDoc}. + */ + @Override + public NoopTopicSink build(List servers, String topic) { + return new NoopTopicSink(servers, topic); + } + + /** + * {@inheritDoc}. + */ + @Override + public String toString() { + return "NoopTopicSinkFactory [" + super.toString() + "]"; + } + +} + diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSource.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSource.java new file mode 100644 index 00000000..6e7d0216 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSource.java @@ -0,0 +1,56 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.noop; + +import java.util.List; +import org.onap.policy.common.message.bus.event.TopicSource; +import org.onap.policy.common.message.bus.utils.NetLoggerUtil.EventType; + +/** + * No Operation Topic Source. + */ +public class NoopTopicSource extends NoopTopicEndpoint implements TopicSource { + + /** + * Constructs the object. + */ + public NoopTopicSource(List servers, String topic) { + super(servers, topic); + } + + /** + * {@inheritDoc}. + */ + @Override + public boolean offer(String event) { + return super.io(EventType.IN, event); + } + + /** + * {@inheritDoc}. + */ + @Override + public String toString() { + return "NoopTopicSource[" + super.toString() + "]"; + } + +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSourceFactory.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSourceFactory.java new file mode 100644 index 00000000..5e3a365a --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSourceFactory.java @@ -0,0 +1,56 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.noop; + +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_NOOP_SOURCE_TOPICS; + +import java.util.List; + +/** + * No Operation Topic Source Factory. + */ +public class NoopTopicSourceFactory extends NoopTopicFactory { + + /** + * {@inheritDoc}. + */ + @Override + protected String getTopicsPropertyName() { + return PROPERTY_NOOP_SOURCE_TOPICS; + } + + /** + * {@inheritDoc}. + */ + @Override + public NoopTopicSource build(List servers, String topic) { + return new NoopTopicSource(servers, topic); + } + + /** + * {@inheritDoc}. + */ + @Override + public String toString() { + return "NoopTopicSourceFactory [" + super.toString() + "]"; + } +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/features/NetLoggerFeatureApi.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/features/NetLoggerFeatureApi.java new file mode 100644 index 00000000..6e3b8301 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/features/NetLoggerFeatureApi.java @@ -0,0 +1,54 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.features; + +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.utils.NetLoggerUtil.EventType; +import org.onap.policy.common.utils.services.OrderedService; +import org.slf4j.Logger; + +/** + * Logging Feature API. Provides interception points before and after logging a message. + */ +public interface NetLoggerFeatureApi extends OrderedService { + + /** + * Intercepts a message before it is logged. + * + * @return true if this feature intercepts and takes ownership of the operation + * preventing the invocation of lower priority features. False, otherwise. + */ + default boolean beforeLog(Logger eventLogger, EventType type, CommInfrastructure protocol, String topic, + String message) { + return false; + } + + /** + * Intercepts a message after it is logged. + * + * @return true if this feature intercepts and takes ownership of the operation + * preventing the invocation of lower priority features. False, otherwise. + */ + default boolean afterLog(Logger eventLogger, EventType type, CommInfrastructure protocol, String topic, + String message) { + return false; + } + +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/features/NetLoggerFeatureProviders.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/features/NetLoggerFeatureProviders.java new file mode 100644 index 00000000..4f57ab2a --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/features/NetLoggerFeatureProviders.java @@ -0,0 +1,41 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.features; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.onap.policy.common.utils.services.OrderedServiceImpl; + +/** + * Providers for network logging feature. + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class NetLoggerFeatureProviders { + + /** + * Feature providers implementing this interface. + */ + @Getter + private static final OrderedServiceImpl providers = + new OrderedServiceImpl<>(NetLoggerFeatureApi.class); +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/properties/MessageBusProperties.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/properties/MessageBusProperties.java new file mode 100644 index 00000000..9aa529f3 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/properties/MessageBusProperties.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START=============================================== + * Copyright (C) 2024 Nordix Foundation. + * ======================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END================================================= + */ + +package org.onap.policy.common.message.bus.properties; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class MessageBusProperties { + + /* Generic property suffixes */ + + public static final String PROPERTY_TOPIC_SERVERS_SUFFIX = ".servers"; + public static final String PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX = ".effectiveTopic"; + + public static final String PROPERTY_TOPIC_SOURCE_CONSUMER_GROUP_SUFFIX = ".consumerGroup"; + public static final String PROPERTY_TOPIC_SOURCE_CONSUMER_INSTANCE_SUFFIX = ".consumerInstance"; + public static final String PROPERTY_TOPIC_SOURCE_FETCH_TIMEOUT_SUFFIX = ".fetchTimeout"; + public static final String PROPERTY_TOPIC_SOURCE_FETCH_LIMIT_SUFFIX = ".fetchLimit"; + public static final String PROPERTY_MANAGED_SUFFIX = ".managed"; + public static final String PROPERTY_ADDITIONAL_PROPS_SUFFIX = ".additionalProps"; + + public static final String PROPERTY_TOPIC_SINK_PARTITION_KEY_SUFFIX = ".partitionKey"; + + public static final String PROPERTY_ALLOW_SELF_SIGNED_CERTIFICATES_SUFFIX = ".selfSignedCertificates"; + + public static final String PROPERTY_NOOP_SOURCE_TOPICS = "noop.source.topics"; + public static final String PROPERTY_NOOP_SINK_TOPICS = "noop.sink.topics"; + + /* KAFKA Properties */ + + public static final String PROPERTY_KAFKA_SOURCE_TOPICS = "kafka.source.topics"; + public static final String PROPERTY_KAFKA_SINK_TOPICS = "kafka.sink.topics"; + + /* HTTP Server Properties */ + + public static final String PROPERTY_HTTP_HTTPS_SUFFIX = ".https"; + + /* Topic Sink Values */ + + /* Topic Source values */ + + /** + * Default Timeout fetching in milliseconds. + */ + public static final int DEFAULT_TIMEOUT_MS_FETCH = 15000; + + /** + * Default maximum number of messages fetch at the time. + */ + public static final int DEFAULT_LIMIT_FETCH = 100; + + /** + * Definition of No Timeout fetching. + */ + public static final int NO_TIMEOUT_MS_FETCH = -1; + + /** + * Definition of No limit fetching. + */ + public static final int NO_LIMIT_FETCH = -1; +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/utils/KafkaPropertyUtils.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/utils/KafkaPropertyUtils.java new file mode 100644 index 00000000..cfe62208 --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/utils/KafkaPropertyUtils.java @@ -0,0 +1,80 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2022-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.utils; + +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_ADDITIONAL_PROPS_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_MANAGED_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.re2j.Pattern; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.onap.policy.common.parameters.topic.BusTopicParams; +import org.onap.policy.common.parameters.topic.BusTopicParams.TopicParamsBuilder; +import org.onap.policy.common.utils.properties.PropertyUtils; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class KafkaPropertyUtils { + private static final Pattern COMMA_SPACE_PAT = Pattern.compile("\\s*,\\s*"); + + /** + * Makes a topic builder, configuring it with properties that are common to both + * sources and sinks. + * + * @param props properties to be used to configure the builder + * @param topic topic being configured + * @param servers target servers + * @return a topic builder + */ + public static TopicParamsBuilder makeBuilder(PropertyUtils props, String topic, String servers) { + + final List serverList = new ArrayList<>(Arrays.asList(COMMA_SPACE_PAT.split(servers))); + return BusTopicParams.builder() + .servers(serverList) + .topic(topic) + .effectiveTopic(props.getString(PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX, topic)) + .managed(props.getBoolean(PROPERTY_MANAGED_SUFFIX, true)) + .additionalProps(getAdditionalProps(props.getString(PROPERTY_ADDITIONAL_PROPS_SUFFIX, ""))); + } + + private static Map getAdditionalProps(String additionalPropsString) { + try { + Map additionalProps = new HashMap<>(); + var converted = new ObjectMapper().readValue(additionalPropsString, Map.class); + converted.forEach((k, v) -> { + if (k instanceof String key && v instanceof String value) { + additionalProps.put(key, value); + } + }); + return additionalProps; + } catch (Exception e) { + return Collections.emptyMap(); + } + + } +} diff --git a/message-bus/src/main/java/org/onap/policy/common/message/bus/utils/NetLoggerUtil.java b/message-bus/src/main/java/org/onap/policy/common/message/bus/utils/NetLoggerUtil.java new file mode 100644 index 00000000..b5454e5c --- /dev/null +++ b/message-bus/src/main/java/org/onap/policy/common/message/bus/utils/NetLoggerUtil.java @@ -0,0 +1,134 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.utils; + +import lombok.Getter; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.features.NetLoggerFeatureProviders; +import org.onap.policy.common.utils.services.FeatureApiUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A network logging utility class that allows drools applications code to access the + * network log (or other specified loggers) and logging features. + * + */ +public class NetLoggerUtil { + + /** + * Loggers. + */ + private static final Logger logger = LoggerFactory.getLogger(NetLoggerUtil.class); + @Getter + private static final Logger networkLogger = LoggerFactory.getLogger("network"); + + /** + * Constant for the system line separator. + */ + public static final String SYSTEM_LS = System.lineSeparator(); + + /** + * Specifies if the message is coming in or going out. + */ + public enum EventType { + IN, OUT + } + + /** + * Logs a message to the network logger. + * + * @param type can either be IN or OUT + * @param protocol the protocol used to receive/send the message + * @param topic the topic the message came from or null if the type is REST + * @param message message to be logged + */ + public static void log(EventType type, CommInfrastructure protocol, String topic, String message) { + log(networkLogger, type, protocol, topic, message); + } + + /** + * Logs a message to the specified logger (i.e. a controller logger). + * + * @param eventLogger the logger that will have the message appended + * @param type can either be IN or OUT + * @param protocol the protocol used to receive/send the message + * @param topic the topic the message came from or null if the type is REST + * @param message message to be logged + */ + public static void log(Logger eventLogger, EventType type, CommInfrastructure protocol, String topic, + String message) { + if (eventLogger == null) { + logger.debug("the logger is null, defaulting to network logger"); + eventLogger = networkLogger; + } + + if (featureBeforeLog(eventLogger, type, protocol, topic, message)) { + return; + } + + eventLogger.info("[{}|{}|{}]{}{}", type, protocol, topic, SYSTEM_LS, message); + + featureAfterLog(eventLogger, type, protocol, topic, message); + } + + /** + * Executes features that pre-process a message before it is logged. + * + * @param eventLogger the logger that will have the message appended + * @param type can either be IN or OUT + * @param protocol the protocol used to receive/send the message + * @param topic the topic the message came from or null if the type is REST + * @param message message to be logged + * + * @return true if this feature intercepts and takes ownership of the operation + * preventing the invocation of lower priority features. False, otherwise + */ + private static boolean featureBeforeLog(Logger eventLogger, EventType type, CommInfrastructure protocol, + String topic, String message) { + + return FeatureApiUtils.apply(NetLoggerFeatureProviders.getProviders().getList(), + feature -> feature.beforeLog(eventLogger, type, protocol, topic, message), + (feature, ex) -> logger.error("feature {} before-log failure because of {}", + feature.getClass().getName(), ex.getMessage(), ex)); + } + + /** + * Executes features that post-process a message after it is logged. + * + * @param eventLogger the logger that will have the message appended + * @param type can either be IN or OUT + * @param protocol the protocol used to receive/send the message + * @param topic the topic the message came from or null if the type is rest + * @param message message to be logged + * + * @return true if this feature intercepts and takes ownership of the operation + * preventing the invocation of lower priority features. False, otherwise + */ + private static boolean featureAfterLog(Logger eventLogger, EventType type, CommInfrastructure protocol, + String topic, String message) { + + return FeatureApiUtils.apply(NetLoggerFeatureProviders.getProviders().getList(), + feature -> feature.afterLog(eventLogger, type, protocol, topic, message), + (feature, ex) -> logger.error("feature {} after-log failure because of {}", + feature.getClass().getName(), ex.getMessage(), ex)); + } + +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/CommonTestData.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/CommonTestData.java new file mode 100644 index 00000000..ecd2f20c --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/CommonTestData.java @@ -0,0 +1,111 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019, 2024 Nordix Foundation. + * Modifications Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import org.onap.policy.common.parameters.ParameterGroup; +import org.onap.policy.common.parameters.topic.TopicParameters; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; + +/** + * Class to hold/create all parameters for test cases. + * + * @author Ajith Sreekumar (ajith.sreekumar@est.tech) + */ +public class CommonTestData { + + public static final String TOPIC_NAME = "policy-pdp-pap"; + public static final String TOPIC_INFRA = "kafka"; + public static final String TOPIC_SERVER = "kafka:9092"; + + public static final List TOPIC_PARAMS = + List.of(getTopicParameters(TOPIC_NAME, TOPIC_INFRA, TOPIC_SERVER)); + + protected static final Coder coder = new StandardCoder(); + + /** + * Create topic parameters for test cases. + * + * @param topicName name of topic + * @param topicInfra topicCommInfrastructure + * @param topicServer topic server + * @return topic parameters + */ + public static TopicParameters getTopicParameters(String topicName, String topicInfra, String topicServer) { + final TopicParameters topicParams = new TopicParameters(); + topicParams.setTopic(topicName); + topicParams.setTopicCommInfrastructure(topicInfra); + topicParams.setServers(List.of(topicServer)); + return topicParams; + } + + /** + * Converts the contents of a map to a parameter class. + * + * @param source property map + * @param clazz class of object to be created from the map + * @return a new object represented by the map + */ + public T toObject(final Map source, final Class clazz) { + try { + return coder.decode(coder.encode(source), clazz); + + } catch (final CoderException e) { + throw new RuntimeException("cannot create " + clazz.getName() + " from map", e); + } + } + + /** + * Returns a property map for a TopicParameters map for test cases. + * + * @param isEmpty boolean value to represent that object created should be empty or not + * @return a property map suitable for constructing an object + */ + public Map getTopicParameterGroupMap(final boolean isEmpty) { + final Map map = new TreeMap<>(); + if (!isEmpty) { + map.put("topicSources", TOPIC_PARAMS); + map.put("topicSinks", TOPIC_PARAMS); + } + + return map; + } + + /** + * Gets the standard parameter group as a String. + * + * @param filePath path of the file + * @return the standard parameters + * @throws IOException when file read operation fails + */ + public String getParameterGroupAsString(String filePath) throws IOException { + File file = new File(filePath); + return Files.readString(file.toPath()); + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/TopicEndpointProxyTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/TopicEndpointProxyTest.java new file mode 100644 index 00000000..6f0e38dd --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/TopicEndpointProxyTest.java @@ -0,0 +1,400 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event; + +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.kafka.KafkaTopicFactories; +import org.onap.policy.common.message.bus.event.kafka.KafkaTopicPropertyBuilder; +import org.onap.policy.common.message.bus.event.noop.NoopTopicFactories; +import org.onap.policy.common.message.bus.event.noop.NoopTopicPropertyBuilder; +import org.onap.policy.common.message.bus.properties.MessageBusProperties; +import org.onap.policy.common.parameters.topic.TopicParameterGroup; +import org.onap.policy.common.parameters.topic.TopicParameters; +import org.onap.policy.common.utils.gson.GsonTestUtils; + +class TopicEndpointProxyTest { + + private static final String NOOP_SOURCE_TOPIC = "noop-source"; + private static final String NOOP_SINK_TOPIC = "noop-sink"; + + private static final String KAFKA_SOURCE_TOPIC = "kafka-source"; + private static final String KAFKA_SINK_TOPIC = "kafka-sink"; + + private final Properties configuration = new Properties(); + private final TopicParameterGroup group = new TopicParameterGroup(); + + /** + * Constructor. + */ + public TopicEndpointProxyTest() { + group.setTopicSinks(new LinkedList<>()); + group.setTopicSources(new LinkedList<>()); + + NoopTopicPropertyBuilder noopSourceBuilder = + new NoopTopicPropertyBuilder(MessageBusProperties.PROPERTY_NOOP_SOURCE_TOPICS) + .makeTopic(NOOP_SOURCE_TOPIC); + configuration.putAll(noopSourceBuilder.build()); + group.getTopicSources().add(noopSourceBuilder.getParams()); + + NoopTopicPropertyBuilder noopSinkBuilder = + new NoopTopicPropertyBuilder(MessageBusProperties.PROPERTY_NOOP_SINK_TOPICS) + .makeTopic(NOOP_SINK_TOPIC); + configuration.putAll(noopSinkBuilder.build()); + group.getTopicSinks().add(noopSinkBuilder.getParams()); + + TopicParameters invalidCommInfraParams = + new NoopTopicPropertyBuilder(MessageBusProperties.PROPERTY_NOOP_SOURCE_TOPICS) + .makeTopic(NOOP_SOURCE_TOPIC).getParams(); + invalidCommInfraParams.setTopicCommInfrastructure(Topic.CommInfrastructure.REST.name()); + group.getTopicSources().add(invalidCommInfraParams); + group.getTopicSinks().add(invalidCommInfraParams); + } + + private boolean exists(List topics, String topicName) { + return topics.stream().map(Topic::getTopic).anyMatch(topicName::equals); + } + + private boolean allSources(List topics) { + return exists(topics, NOOP_SOURCE_TOPIC); + } + + private boolean allSinks(List topics) { + return exists(topics, NOOP_SINK_TOPIC); + } + + private boolean anySource(List topics) { + return exists(topics, NOOP_SOURCE_TOPIC); + } + + private boolean anySink(List topics) { + return exists(topics, NOOP_SINK_TOPIC); + } + + /** + * Destroys all managed topics. + */ + @AfterEach + public void tearDown() { + NoopTopicFactories.getSinkFactory().destroy(); + NoopTopicFactories.getSourceFactory().destroy(); + KafkaTopicFactories.getSinkFactory().destroy(); + KafkaTopicFactories.getSourceFactory().destroy(); + } + + @Test + void testSerialize() { + TopicEndpoint manager = new TopicEndpointProxy(); + + manager.addTopicSources(configuration); + manager.addTopicSinks(configuration); + + assertThatCode(() -> new GsonTestUtils().compareGson(manager, TopicEndpointProxyTest.class)) + .doesNotThrowAnyException(); + } + + @Test + void testAddTopicSourcesListOfTopicParameters() { + TopicEndpoint manager = new TopicEndpointProxy(); + + List sources = manager.addTopicSources(group.getTopicSources()); + assertSame(1, sources.size()); + + assertTrue(allSources(sources)); + assertFalse(anySink(sources)); + + sources = manager.addTopicSources(group.getTopicSources()); + assertSame(1, sources.size()); + assertTrue(allSources(sources)); + } + + @Test + void testAddTopicSourcesKafka() { + TopicEndpoint manager = new TopicEndpointProxy(); + + KafkaTopicPropertyBuilder kafkaTopicPropertyBuilder = + new KafkaTopicPropertyBuilder(MessageBusProperties.PROPERTY_KAFKA_SOURCE_TOPICS) + .makeTopic(KAFKA_SOURCE_TOPIC); + + configuration.putAll(kafkaTopicPropertyBuilder.build()); + group.getTopicSources().add(kafkaTopicPropertyBuilder.getParams()); + List sources = manager.addTopicSources(group.getTopicSources()); + assertSame(2, sources.size()); + + configuration.remove(KAFKA_SOURCE_TOPIC); + group.setTopicSources(new LinkedList<>()); + sources = manager.addTopicSources(group.getTopicSources()); + assertSame(0, sources.size()); + } + + @Test + void testAddTopicSourcesProperties() { + TopicEndpoint manager = new TopicEndpointProxy(); + + List sources = manager.addTopicSources(configuration); + assertSame(1, sources.size()); + + assertTrue(allSources(sources)); + assertFalse(anySink(sources)); + } + + @Test + void testAddTopicSinksListOfTopicParameters() { + TopicEndpoint manager = new TopicEndpointProxy(); + + List sinks = manager.addTopicSinks(group.getTopicSinks()); + assertSame(1, sinks.size()); + + assertFalse(anySource(sinks)); + assertTrue(allSinks(sinks)); + } + + @Test + void testAddTopicSinksListOfTopicParametersKafka() { + TopicEndpoint manager = new TopicEndpointProxy(); + + List sinks = manager.addTopicSinks(group.getTopicSinks()); + assertSame(1, sinks.size()); + + KafkaTopicPropertyBuilder kafkaTopicPropertyBuilder = + new KafkaTopicPropertyBuilder(MessageBusProperties.PROPERTY_KAFKA_SINK_TOPICS) + .makeTopic(KAFKA_SINK_TOPIC); + + configuration.putAll(kafkaTopicPropertyBuilder.build()); + group.getTopicSources().add(kafkaTopicPropertyBuilder.getParams()); + sinks = manager.addTopicSinks(group.getTopicSources()); + assertSame(2, sinks.size()); + + configuration.remove(KAFKA_SOURCE_TOPIC); + group.setTopicSources(new LinkedList<>()); + sinks = manager.addTopicSinks(group.getTopicSources()); + assertSame(0, sinks.size()); + } + + @Test + void testAddTopicSinksProperties() { + TopicEndpoint manager = new TopicEndpointProxy(); + + List sinks = manager.addTopicSinks(configuration); + assertSame(1, sinks.size()); + + assertFalse(anySource(sinks)); + assertTrue(allSinks(sinks)); + } + + @Test + void testAddTopicsProperties() { + TopicEndpoint manager = new TopicEndpointProxy(); + + List topics = manager.addTopics(configuration); + assertSame(2, topics.size()); + + assertTrue(allSources(topics)); + assertTrue(allSinks(topics)); + } + + @Test + void testAddTopicsTopicParameterGroup() { + TopicEndpoint manager = new TopicEndpointProxy(); + + List topics = manager.addTopics(group); + assertSame(2, topics.size()); + + assertTrue(allSources(topics)); + assertTrue(allSinks(topics)); + } + + @Test + void testAddTopicsTopicParameterGroupNull() { + TopicEndpoint manager = new TopicEndpointProxy(); + + List topics = manager.addTopics(new TopicParameterGroup()); + assertEquals(0, topics.size()); + } + + @Test + void testLockSinks_lockSources_locked() { + TopicEndpoint manager = new TopicEndpointProxy(); + manager.lock(); + for (Topic topic : manager.addTopics(group)) { + assertTrue(topic.isLocked()); + } + } + + @Test + void testLockSinks_lockSources_unlocked() { + TopicEndpoint manager = new TopicEndpointProxy(); + for (Topic topic : manager.addTopics(group)) { + assertFalse(topic.isLocked()); + } + } + + @Test + void testGetTopicSources() { + TopicEndpoint manager = new TopicEndpointProxy(); + + manager.addTopicSources(configuration); + manager.addTopicSinks(configuration); + + List sources = manager.getTopicSources(); + assertSame(1, sources.size()); + + assertTrue(allSources(sources)); + assertFalse(anySink(sources)); + + assertThatThrownBy(() -> manager.getKafkaTopicSource("testTopic")) + .hasMessageContaining("KafkaTopiceSource for testTopic not found"); + + List topicName = null; + assertThatThrownBy(() -> manager.getTopicSources(topicName)) + .hasMessageContaining("must provide a list of topics"); + } + + @Test + void testGetTopicSinks() { + TopicEndpoint manager = new TopicEndpointProxy(); + + manager.addTopicSources(configuration); + manager.addTopicSinks(configuration); + + List sinks = manager.getTopicSinks(); + assertSame(1, sinks.size()); + + assertFalse(anySource(sinks)); + assertTrue(allSinks(sinks)); + + final List sinks2 = null; + assertThatThrownBy(() -> manager.getTopicSinks(sinks2)).hasMessageContaining("must provide a list of topics"); + + List sinks3 = List.of(NOOP_SINK_TOPIC); + assertThatCode(() -> manager.getTopicSinks(sinks3)).doesNotThrowAnyException(); + + String sinkTest = null; + assertThatThrownBy(() -> manager.getTopicSinks(sinkTest)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("Invalid parameter"); + + assertThatThrownBy(() -> manager.getKafkaTopicSink("testTopic")) + .hasMessageContaining("KafkaTopicSink for testTopic not found"); + } + + @Test + void testGetNoopTopicSources() { + TopicEndpoint manager = new TopicEndpointProxy(); + + manager.addTopicSources(configuration); + assertSame(1, manager.getNoopTopicSources().size()); + } + + @Test + void testGetNoopTopicSinks() { + TopicEndpoint manager = new TopicEndpointProxy(); + + manager.addTopicSinks(configuration); + assertSame(1, manager.getNoopTopicSinks().size()); + } + + @Test + void testLifecycle() { + TopicEndpoint manager = new TopicEndpointProxy(); + + assertTrue(manager.start()); + assertTrue(manager.isAlive()); + + assertTrue(manager.stop()); + assertFalse(manager.isAlive()); + + assertTrue(manager.start()); + assertTrue(manager.isAlive()); + + manager.shutdown(); + assertFalse(manager.isAlive()); + } + + @Test + void testLock() { + TopicEndpoint manager = new TopicEndpointProxy(); + + manager.lock(); + assertTrue(manager.isLocked()); + + manager.unlock(); + assertFalse(manager.isLocked()); + } + + @Test + void testGetTopicSource() { + TopicEndpoint manager = new TopicEndpointProxy(); + manager.addTopicSources(configuration); + + assertSame(NOOP_SOURCE_TOPIC, manager.getTopicSource(CommInfrastructure.NOOP, NOOP_SOURCE_TOPIC).getTopic()); + + assertThatIllegalStateException() + .isThrownBy(() -> manager.getTopicSource(CommInfrastructure.NOOP, NOOP_SINK_TOPIC)); + } + + @Test + void testGetTopicSink() { + TopicEndpoint manager = new TopicEndpointProxy(); + manager.addTopicSinks(configuration); + + assertSame(NOOP_SINK_TOPIC, manager.getTopicSink(CommInfrastructure.NOOP, NOOP_SINK_TOPIC).getTopic()); + + assertThatIllegalStateException() + .isThrownBy(() -> manager.getTopicSink(CommInfrastructure.NOOP, NOOP_SOURCE_TOPIC)); + } + + @Test + void testGetNoopTopicSource() { + TopicEndpoint manager = new TopicEndpointProxy(); + manager.addTopicSources(configuration); + + assertSame(NOOP_SOURCE_TOPIC, manager.getNoopTopicSource(NOOP_SOURCE_TOPIC).getTopic()); + + assertThatIllegalArgumentException().isThrownBy(() -> manager.getNoopTopicSource(null)); + assertThatIllegalArgumentException().isThrownBy(() -> manager.getNoopTopicSource("")); + } + + @Test + void testGetNoopTopicSink() { + TopicEndpoint manager = new TopicEndpointProxy(); + manager.addTopicSinks(configuration); + + assertSame(NOOP_SINK_TOPIC, manager.getNoopTopicSink(NOOP_SINK_TOPIC).getTopic()); + + assertThatIllegalArgumentException().isThrownBy(() -> manager.getNoopTopicSink(null)); + assertThatIllegalArgumentException().isThrownBy(() -> manager.getNoopTopicSink("")); + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/TopicParameterGroupTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/TopicParameterGroupTest.java new file mode 100644 index 00000000..db28892e --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/TopicParameterGroupTest.java @@ -0,0 +1,147 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019-2024 Nordix Foundation. + * Modifications Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.beans.PropertyDescriptor; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.List; +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.Test; +import org.onap.policy.common.parameters.ValidationResult; +import org.onap.policy.common.parameters.topic.BusTopicParams; +import org.onap.policy.common.parameters.topic.TopicParameterGroup; +import org.onap.policy.common.parameters.topic.TopicParameters; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; + +/** + * Class to perform unit test of {@link TopicParameterGroup}. + * + * @author Ajith Sreekumar (ajith.sreekumar@est.tech) + */ +class TopicParameterGroupTest { + private static final CommonTestData testData = new CommonTestData(); + private static final Coder coder = new StandardCoder(); + private final String packageDir = "src/test/resources/org/onap/policy/common/message/bus/parameters/"; + + @Test + void test() throws CoderException { + final TopicParameterGroup topicParameterGroup = + testData.toObject(testData.getTopicParameterGroupMap(false), TopicParameterGroup.class); + final ValidationResult validationResult = topicParameterGroup.validate(); + assertTrue(validationResult.isValid()); + assertEquals(CommonTestData.TOPIC_PARAMS, topicParameterGroup.getTopicSinks()); + assertEquals(CommonTestData.TOPIC_PARAMS, topicParameterGroup.getTopicSources()); + + // these should default to true + assertTrue(new TopicParameters().isManaged()); + assertTrue(coder.decode("{}", TopicParameters.class).isManaged()); + + // but can be overridden + assertFalse(coder.decode("{'managed':false}".replace('\'', '"'), TopicParameters.class).isManaged()); + } + + @Test + void testValidate() { + final TopicParameterGroup topicParameterGroup = + testData.toObject(testData.getTopicParameterGroupMap(false), TopicParameterGroup.class); + final ValidationResult result = topicParameterGroup.validate(); + assertNull(result.getResult()); + assertTrue(result.isValid()); + } + + @Test + void test_valid() throws Exception { + String json = testData.getParameterGroupAsString( + packageDir + "TopicParameters_valid.json"); + TopicParameterGroup topicParameterGroup = coder.decode(json, TopicParameterGroup.class); + final ValidationResult result = topicParameterGroup.validate(); + assertNull(result.getResult()); + assertTrue(result.isValid()); + } + + @Test + void test_invalid() throws Exception { + String json = testData.getParameterGroupAsString( + packageDir + "TopicParameters_invalid.json"); + TopicParameterGroup topicParameterGroup = coder.decode(json, TopicParameterGroup.class); + final ValidationResult result = topicParameterGroup.validate(); + assertFalse(result.isValid()); + assertTrue(result.getResult().contains("INVALID")); + } + + @Test + void test_missing_mandatory_params() throws Exception { + String json = testData.getParameterGroupAsString( + packageDir + "TopicParameters_missing_mandatory.json"); + TopicParameterGroup topicParameterGroup = coder.decode(json, TopicParameterGroup.class); + final ValidationResult result = topicParameterGroup.validate(); + assertTrue(result.getResult().contains("Mandatory parameters are missing")); + assertFalse(result.isValid()); + } + + @Test + void test_allParams() throws Exception { + String json = testData.getParameterGroupAsString( + packageDir + "TopicParameters_all_params.json"); + TopicParameterGroup topicParameterGroup = coder.decode(json, TopicParameterGroup.class); + final ValidationResult result = topicParameterGroup.validate(); + assertNull(result.getResult()); + assertTrue(result.isValid()); + assertTrue(checkIfAllParamsNotEmpty(topicParameterGroup.getTopicSinks())); + assertTrue(checkIfAllParamsNotEmpty(topicParameterGroup.getTopicSources())); + } + + /** + * Method to check if all parameters in TopicParameters are set. + * Any parameters added to @link TopicParameters or @link BusTopicParams must be added to + * TopicParameters_all_params.json. + * + * @param topicParametersList list of topic parameters + * @return true if all parameters are not empty (if string) or true (if boolean) + * @throws Exception the exception + */ + private boolean checkIfAllParamsNotEmpty(List topicParametersList) throws Exception { + for (TopicParameters topicParameters : topicParametersList) { + Field[] fields = BusTopicParams.class.getDeclaredFields(); + for (Field field : fields) { + if (!field.isSynthetic() && !Modifier.isStatic(field.getModifiers())) { + Object parameter = new PropertyDescriptor(field.getName(), TopicParameters.class).getReadMethod() + .invoke(topicParameters); + if ((parameter instanceof String && StringUtils.isBlank(parameter.toString())) + || (parameter instanceof Boolean && !(Boolean) parameter) + || (parameter instanceof Number && ((Number) parameter).longValue() == 0)) { + return false; + } + } + } + } + return true; + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/BusConsumerTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/BusConsumerTest.java new file mode 100644 index 00000000..207023e5 --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/BusConsumerTest.java @@ -0,0 +1,282 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2018-2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2023-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.CountDownLatch; +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.common.TopicPartition; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.policy.common.message.bus.event.base.BusConsumer.FetchingBusConsumer; +import org.onap.policy.common.message.bus.event.base.BusConsumer.KafkaConsumerWrapper; +import org.onap.policy.common.message.bus.properties.MessageBusProperties; +import org.onap.policy.common.parameters.topic.BusTopicParams; + +class BusConsumerTest extends TopicTestBase { + + private static final int SHORT_TIMEOUT_MILLIS = 10; + private static final int LONG_TIMEOUT_MILLIS = 3000; + + @Mock + KafkaConsumer mockedKafkaConsumer; + + AutoCloseable closeable; + + @BeforeEach + @Override + public void setUp() { + super.setUp(); + closeable = MockitoAnnotations.openMocks(this); + } + + @AfterEach + public void tearDown() throws Exception { + closeable.close(); + } + + + @Test + void testFetchingBusConsumer() { + // should not be negative + var cons = new FetchingBusConsumerImpl(makeBuilder().fetchTimeout(-1).build()); + assertThat(cons.getSleepTime()).isEqualTo(MessageBusProperties.DEFAULT_TIMEOUT_MS_FETCH); + + // should not be zero + cons = new FetchingBusConsumerImpl(makeBuilder().fetchTimeout(0).build()); + assertThat(cons.getSleepTime()).isEqualTo(MessageBusProperties.DEFAULT_TIMEOUT_MS_FETCH); + + // should not be too large + cons = new FetchingBusConsumerImpl( + makeBuilder().fetchTimeout(MessageBusProperties.DEFAULT_TIMEOUT_MS_FETCH + 100).build()); + assertThat(cons.getSleepTime()).isEqualTo(MessageBusProperties.DEFAULT_TIMEOUT_MS_FETCH); + + // should not be what was specified + cons = new FetchingBusConsumerImpl(makeBuilder().fetchTimeout(100).build()); + assertThat(cons.getSleepTime()).isEqualTo(100); + } + + @Test + void testFetchingBusConsumerSleepAfterFetchFailure() throws InterruptedException { + + var cons = new FetchingBusConsumerImpl(makeBuilder().fetchTimeout(SHORT_TIMEOUT_MILLIS).build()) { + + private CountDownLatch started = new CountDownLatch(1); + + @Override + protected void sleepAfterFetchFailure() { + started.countDown(); + super.sleepAfterFetchFailure(); + } + }; + + // full sleep + long tstart = System.currentTimeMillis(); + cons.sleepAfterFetchFailure(); + assertThat(System.currentTimeMillis() - tstart).isGreaterThanOrEqualTo(SHORT_TIMEOUT_MILLIS); + + // close while sleeping - sleep should halt prematurely + cons.fetchTimeout = LONG_TIMEOUT_MILLIS; + cons.started = new CountDownLatch(1); + Thread thread = new Thread(cons::sleepAfterFetchFailure); + tstart = System.currentTimeMillis(); + thread.start(); + cons.started.await(); + cons.close(); + thread.join(); + assertThat(System.currentTimeMillis() - tstart).isLessThan(LONG_TIMEOUT_MILLIS); + + // interrupt while sleeping - sleep should halt prematurely + cons.fetchTimeout = LONG_TIMEOUT_MILLIS; + cons.started = new CountDownLatch(1); + thread = new Thread(cons::sleepAfterFetchFailure); + tstart = System.currentTimeMillis(); + thread.start(); + cons.started.await(); + thread.interrupt(); + thread.join(); + assertThat(System.currentTimeMillis() - tstart).isLessThan(LONG_TIMEOUT_MILLIS); + } + + @Test + void testKafkaConsumerWrapper() { + // verify that different wrappers can be built + assertThatCode(() -> new KafkaConsumerWrapper(makeKafkaBuilder().build())).doesNotThrowAnyException(); + } + + @Test + void testKafkaConsumerWrapper_InvalidTopic() { + BusTopicParams params = makeBuilder().topic(null).build(); + assertThatThrownBy(() -> new KafkaConsumerWrapper(params)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void testKafkaConsumerWrapperFetch() { + + //Setup Properties for consumer + Properties kafkaProps = new Properties(); + kafkaProps.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + kafkaProps.setProperty(ConsumerConfig.GROUP_ID_CONFIG, "test"); + kafkaProps.setProperty("enable.auto.commit", "true"); + kafkaProps.setProperty("auto.commit.interval.ms", "1000"); + kafkaProps.setProperty(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, + "org.apache.kafka.common.serialization.StringDeserializer"); + kafkaProps.setProperty(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, + "org.apache.kafka.common.serialization.StringDeserializer"); + kafkaProps.setProperty(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); + kafkaProps.setProperty(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false"); + + KafkaConsumerWrapper kafka = new KafkaConsumerWrapper(makeKafkaBuilder().build()); + KafkaConsumer consumer = new KafkaConsumer<>(kafkaProps); + kafka.consumer = consumer; + + assertThrows(java.lang.IllegalStateException.class, () -> kafka.fetch().iterator().hasNext()); + consumer.close(); + } + + @Test + void testFetchNoMessages() { + KafkaConsumerWrapper kafkaConsumerWrapper = new KafkaConsumerWrapper(makeKafkaBuilder().build()); + kafkaConsumerWrapper.consumer = mockedKafkaConsumer; + + when(mockedKafkaConsumer.poll(any())).thenReturn(new ConsumerRecords<>(Collections.emptyMap())); + + Iterable result = kafkaConsumerWrapper.fetch(); + + verify(mockedKafkaConsumer).poll(any()); + + assertNotNull(result); + + assertFalse(result.iterator().hasNext()); + + mockedKafkaConsumer.close(); + } + + @Test + void testFetchWithMessages() { + // Setup + KafkaConsumerWrapper kafkaConsumerWrapper = new KafkaConsumerWrapper(makeKafkaBuilder().build()); + kafkaConsumerWrapper.consumer = mockedKafkaConsumer; + + ConsumerRecord customerRecord = + new ConsumerRecord<>("my-effective-topic", 0, 0, "key", "value"); + Map>> recordsMap = new HashMap<>(); + recordsMap.put(new TopicPartition("my-effective-topic", 0), Collections.singletonList(customerRecord)); + ConsumerRecords consumerRecords = new ConsumerRecords<>(recordsMap); + + when(mockedKafkaConsumer.poll(any())).thenReturn(consumerRecords); + + Iterable result = kafkaConsumerWrapper.fetch(); + + verify(mockedKafkaConsumer, times(1)).poll(any()); + + verify(mockedKafkaConsumer, times(1)).commitSync(any(Map.class)); + + assertNotNull(result); + + assertTrue(result.iterator().hasNext()); + + assertEquals("value", result.iterator().next()); + + mockedKafkaConsumer.close(); + } + + @Test + void testFetchWithMessagesAndTraceParent() { + // Setup + KafkaConsumerWrapper kafkaConsumerWrapper = new KafkaConsumerWrapper(makeKafkaBuilder().build()); + kafkaConsumerWrapper.consumer = mockedKafkaConsumer; + + ConsumerRecord customerRecord = + new ConsumerRecord<>("my-effective-topic", 0, 0, "key", "value"); + customerRecord.headers().add( + "traceparent", + "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01".getBytes(StandardCharsets.UTF_8) + ); + + Map>> recordsMap = new HashMap<>(); + recordsMap.put(new TopicPartition("my-effective-topic", 0), Collections.singletonList(customerRecord)); + ConsumerRecords consumerRecords = new ConsumerRecords<>(recordsMap); + + when(mockedKafkaConsumer.poll(any())).thenReturn(consumerRecords); + + Iterable result = kafkaConsumerWrapper.fetch(); + + verify(mockedKafkaConsumer, times(1)).poll(any()); + + verify(mockedKafkaConsumer, times(1)).commitSync(any(Map.class)); + + assertNotNull(result); + + assertTrue(result.iterator().hasNext()); + + assertEquals("value", result.iterator().next()); + + mockedKafkaConsumer.close(); + } + + + @Test + void testKafkaConsumerWrapperClose() { + assertThatCode(() -> new KafkaConsumerWrapper(makeKafkaBuilder().build()).close()).doesNotThrowAnyException(); + } + + @Test + void testKafkaConsumerWrapperToString() { + assertNotNull(new KafkaConsumerWrapper(makeKafkaBuilder().build()) {}.toString()); + } + + private static class FetchingBusConsumerImpl extends FetchingBusConsumer { + + protected FetchingBusConsumerImpl(BusTopicParams busTopicParams) { + super(busTopicParams); + } + + @Override + public Iterable fetch() { + return null; + } + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/BusTopicBaseTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/BusTopicBaseTest.java new file mode 100644 index 00000000..343a56a8 --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/BusTopicBaseTest.java @@ -0,0 +1,139 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.policy.common.parameters.topic.BusTopicParams; +import org.onap.policy.common.utils.gson.GsonTestUtils; + +class BusTopicBaseTest extends TopicTestBase { + + private BusTopicBaseImpl base; + + /** + * Initializes the object to be tested. + */ + @BeforeEach + @Override + public void setUp() { + super.setUp(); + + base = new BusTopicBaseImpl(builder.build()); + } + + @Test + void testToString() { + assertNotNull(base.toString()); + } + + @Test + void testSerialize() { + assertThatCode(() -> new GsonTestUtils().compareGson(base, BusTopicBaseTest.class)).doesNotThrowAnyException(); + } + + @Test + void testGetApiKey() { + assertEquals(MY_API_KEY, base.getApiKey()); + } + + @Test + void testGetApiSecret() { + assertEquals(MY_API_SECRET, base.getApiSecret()); + } + + @Test + void testIsUseHttps() { + assertTrue(base.isUseHttps()); + assertFalse(new BusTopicBaseImpl(builder.useHttps(false).build()).isUseHttps()); + } + + @Test + void testIsAllowSelfSignedCerts() { + assertTrue(base.isAllowSelfSignedCerts()); + assertFalse(new BusTopicBaseImpl(builder.allowSelfSignedCerts(false).build()).isAllowSelfSignedCerts()); + } + + @Test + void testTopic() { + assertEquals(MY_TOPIC, base.getTopic()); + assertEquals(MY_EFFECTIVE_TOPIC, base.getEffectiveTopic()); + assertNotEquals(base.getTopic(), base.getEffectiveTopic()); + } + + @Test + void testAnyNullOrEmpty() { + assertFalse(base.anyNullOrEmpty()); + assertFalse(base.anyNullOrEmpty("any-none-null", "any-none-null-B")); + + assertTrue(base.anyNullOrEmpty(null, "any-first-null")); + assertTrue(base.anyNullOrEmpty("any-middle-null", null, "any-middle-null-B")); + assertTrue(base.anyNullOrEmpty("any-last-null", null)); + assertTrue(base.anyNullOrEmpty("any-empty", "")); + } + + @Test + void testAllNullOrEmpty() { + assertTrue(base.allNullOrEmpty()); + assertTrue(base.allNullOrEmpty("")); + assertTrue(base.allNullOrEmpty(null, "")); + + assertFalse(base.allNullOrEmpty("all-ok-only-one")); + assertFalse(base.allNullOrEmpty("all-ok-one", "all-ok-two")); + assertFalse(base.allNullOrEmpty("all-ok-null", null)); + assertFalse(base.allNullOrEmpty("", "all-ok-empty")); + assertFalse(base.allNullOrEmpty("", "all-one-ok", null)); + } + + private static class BusTopicBaseImpl extends BusTopicBase { + + public BusTopicBaseImpl(BusTopicParams busTopicParams) { + super(busTopicParams); + } + + @Override + public CommInfrastructure getTopicCommInfrastructure() { + return CommInfrastructure.NOOP; + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public void shutdown() { + // do nothing + } + + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/BusTopicFactoryTestBase.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/BusTopicFactoryTestBase.java new file mode 100644 index 00000000..bd531114 --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/BusTopicFactoryTestBase.java @@ -0,0 +1,238 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_ALLOW_SELF_SIGNED_CERTIFICATES_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_HTTP_HTTPS_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_MANAGED_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX; + +import java.util.List; +import java.util.Properties; +import java.util.function.Predicate; +import org.onap.policy.common.message.bus.event.Topic; +import org.onap.policy.common.parameters.topic.BusTopicParams; + +/** + * Base class for Topic Factory tests that use BusTopicParams. + * + * @param type of topic managed by the factory + */ +public abstract class BusTopicFactoryTestBase extends TopicFactoryTestBase { + + /** + * Builds a topic. + * + * @param params the parameters used to configure the topic + * @return a new topic + */ + protected abstract T buildTopic(BusTopicParams params); + + /** + * Builds a topic. + * + * @param servers list of servers + * @param topic the topic name + * @return a new topic + */ + protected abstract T buildTopic(List servers, String topic); + + /** + * Gets the parameters used to build the most recent topic. + * + * @return the most recent topic's parameters + */ + protected abstract BusTopicParams getLastParams(); + + /** + * Tests building a topic using BusTopicParams. + */ + public void testBuildBusTopicParams() { + initFactory(); + + // two unmanaged topics + T item = buildTopic(makeBuilder().managed(false).effectiveTopic(null).build()); + T item2 = buildTopic(makeBuilder().managed(false).topic(TOPIC2).build()); + assertNotNull(item); + assertNotNull(item2); + assertEquals(item.getTopic(), item.getEffectiveTopic()); + assertNotEquals(item2.getTopic(), item2.getEffectiveTopic()); + assertNotSame(item, item2); + + // duplicate topics, but since they aren't managed, they should be different + T item3 = buildTopic(makeBuilder().managed(false).build()); + T item4 = buildTopic(makeBuilder().managed(false).effectiveTopic(TOPIC2).build()); + assertNotNull(item3); + assertNotNull(item4); + assertEquals(MY_TOPIC, item4.getTopic()); + assertEquals(TOPIC2, item4.getEffectiveTopic()); + assertNotSame(item, item3); + assertNotSame(item, item4); + assertNotSame(item3, item4); + + // two managed topics + T item5 = buildTopic(makeBuilder().build()); + T item6 = buildTopic(makeBuilder().topic(TOPIC2).build()); + assertNotNull(item5); + assertNotNull(item6); + + // re-build same managed topics - should get exact same objects + assertSame(item5, buildTopic(makeBuilder().topic(MY_TOPIC).build())); + assertSame(item6, buildTopic(makeBuilder().topic(TOPIC2).build())); + } + + /** + * Tests exception cases when building a topic using BusTopicParams. + */ + public void testBuildBusTopicParams_Ex() { + // null topic + assertThatIllegalArgumentException().isThrownBy(() -> buildTopic(makeBuilder().topic(null).build())); + + // empty topic + assertThatIllegalArgumentException().isThrownBy(() -> buildTopic(makeBuilder().topic("").build())); + } + + /** + * Tests building a topic using a list of servers and a topic. + */ + public void testBuildListOfStringString() { + initFactory(); + + T item1 = buildTopic(servers, MY_TOPIC); + assertNotNull(item1); + + // check parameters that were used + BusTopicParams params = getLastParams(); + assertEquals(servers, params.getServers()); + assertEquals(MY_TOPIC, params.getTopic()); + assertTrue(params.isManaged()); + assertFalse(params.isUseHttps()); + + T item2 = buildTopic(servers, TOPIC2); + assertNotNull(item2); + assertNotSame(item1, item2); + + // duplicate - should be the same, as these topics are managed + T item3 = buildTopic(servers, TOPIC2); + assertSame(item2, item3); + } + + /** + * Tests building a topic using Properties. Verifies parameters specific to Bus + * topics. + */ + public void testBuildProperties() { + initFactory(); + + List topics = buildTopics(makePropBuilder().makeTopic(MY_TOPIC).build()); + assertEquals(1, topics.size()); + assertEquals(MY_TOPIC, topics.get(0).getTopic()); + assertEquals(MY_EFFECTIVE_TOPIC, topics.get(0).getEffectiveTopic()); + + BusTopicParams params = getLastParams(); + assertTrue(params.isManaged()); + assertTrue(params.isUseHttps()); + assertTrue(params.isAllowSelfSignedCerts()); + assertEquals(MY_API_KEY, params.getApiKey()); + assertEquals(MY_API_SECRET, params.getApiSecret()); + assertEquals(List.of(SERVER), params.getServers()); + assertEquals(MY_TOPIC, params.getTopic()); + assertEquals(MY_EFFECTIVE_TOPIC, params.getEffectiveTopic()); + + List topics2 = buildTopics(makePropBuilder().makeTopic(TOPIC3) + .removeTopicProperty(PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX).build()); + assertEquals(1, topics2.size()); + assertEquals(TOPIC3, topics2.get(0).getTopic()); + assertEquals(topics2.get(0).getTopic(), topics2.get(0).getEffectiveTopic()); + } + + @Override + void testBuildProperties_Variations() { + super.testBuildProperties_Variations(); + + // check boolean properties that default to true + checkDefault(PROPERTY_MANAGED_SUFFIX, BusTopicParams::isManaged); + + // check boolean properties that default to false + checkDefault(PROPERTY_HTTP_HTTPS_SUFFIX, params -> !params.isUseHttps()); + checkDefault(PROPERTY_ALLOW_SELF_SIGNED_CERTIFICATES_SUFFIX, params -> !params.isAllowSelfSignedCerts()); + } + + /** + * Verifies that a parameter has the correct default, if the original builder property + * is not provided. + * + * @param builderName name of the builder property + * @param validate function to test the validity of the property + * @param values the values to which the property should be set, defaults to + * {@code null} and "" + */ + protected void checkDefault(String builderName, Predicate validate, Object... values) { + Object[] values2 = (values.length > 0 ? values : new Object[] {null, ""}); + + for (Object value : values2) { + // always start with a fresh factory + initFactory(); + + TopicPropertyBuilder builder = makePropBuilder().makeTopic(MY_TOPIC); + + if (value == null) { + builder.removeTopicProperty(builderName); + + } else { + builder.setTopicProperty(builderName, value.toString()); + } + + assertEquals(1, buildTopics(builder.build()).size(), "size for default " + value); + assertTrue(validate.test(getLastParams()), "default for " + value); + } + } + + /** + * Verifies that an "additional" property does not exist, if the original builder + * property is not provided. + * + * @param builderName name of the builder property + * @param addName name of the "additional" property + */ + public void expectNullAddProp(String builderName, String addName) { + + // remove the property + initFactory(); + Properties props = makePropBuilder().makeTopic(MY_TOPIC).removeTopicProperty(builderName).build(); + assertEquals(1, buildTopics(props).size()); + assertFalse(getLastParams().getAdditionalProps().containsKey(addName)); + + + // repeat, this time using an empty string instead of null + initFactory(); + props = makePropBuilder().makeTopic(MY_TOPIC).setTopicProperty(builderName, "").build(); + assertEquals(1, buildTopics(props).size()); + assertFalse(getLastParams().getAdditionalProps().containsKey(addName)); + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/InlineBusTopicSinkTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/InlineBusTopicSinkTest.java new file mode 100644 index 00000000..820fc2c3 --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/InlineBusTopicSinkTest.java @@ -0,0 +1,230 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.TopicListener; +import org.onap.policy.common.parameters.topic.BusTopicParams; +import org.onap.policy.common.utils.gson.GsonTestUtils; + +class InlineBusTopicSinkTest extends TopicTestBase { + + private InlineBusTopicSinkImpl sink; + + /** + * Creates the object to be tested. + */ + @BeforeEach + @Override + public void setUp() { + super.setUp(); + + sink = new InlineBusTopicSinkImpl(makeBuilder().build()); + } + + @AfterEach + public void tearDown() { + sink.shutdown(); + } + + @Test + void testSerialize() { + assertThatCode(() -> new GsonTestUtils().compareGson(sink, InlineBusTopicSinkTest.class)) + .doesNotThrowAnyException(); + } + + @Test + void testInlineBusTopicSinkImpl() { + // verify that different wrappers can be built + sink = new InlineBusTopicSinkImpl(makeBuilder().build()); + assertEquals(MY_PARTITION, sink.getPartitionKey()); + + sink = new InlineBusTopicSinkImpl(makeBuilder().partitionId(null).build()); + assertNotNull(sink.getPartitionKey()); + } + + @Test + void testStart() { + assertTrue(sink.start()); + assertEquals(1, sink.initCount); + + // re-start, init() should not be invoked again + assertTrue(sink.start()); + assertEquals(1, sink.initCount); + } + + @Test + void testStart_Locked() { + sink.lock(); + assertThatThrownBy(() -> sink.start()).isInstanceOf(IllegalStateException.class); + } + + @Test + void testStop() { + BusPublisher pub = mock(BusPublisher.class); + sink.publisher = pub; + + assertTrue(sink.stop()); + verify(pub).close(); + + // stop again, shouldn't not invoke close() again + assertFalse(sink.stop()); + verify(pub).close(); + + // publisher throws exception + sink = new InlineBusTopicSinkImpl(makeBuilder().build()); + sink.publisher = pub; + doThrow(new RuntimeException(EXPECTED)).when(pub).close(); + assertTrue(sink.stop()); + } + + @Test + void testSend() { + sink.start(); + BusPublisher pub = mock(BusPublisher.class); + sink.publisher = pub; + + TopicListener listener = mock(TopicListener.class); + sink.register(listener); + + assertTrue(sink.send(MY_MESSAGE)); + + verify(pub).send(MY_PARTITION, MY_MESSAGE); + verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE); + assertEquals(List.of(MY_MESSAGE), Arrays.asList(sink.getRecentEvents())); + + // arrange for send to throw an exception + when(pub.send(anyString(), anyString())).thenThrow(new RuntimeException(EXPECTED)); + + assertFalse(sink.send(MY_MESSAGE)); + + // no more event deliveries + verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE); + } + + @Test + void testSend_NullMessage() { + sink.start(); + sink.publisher = mock(BusPublisher.class); + + assertThatThrownBy(() -> sink.send(null)).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void testSend_EmptyMessage() { + sink.start(); + sink.publisher = mock(BusPublisher.class); + + assertThatThrownBy(() -> sink.send("")).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void testSend_NotStarted() { + sink.publisher = mock(BusPublisher.class); + assertThatThrownBy(() -> sink.send(MY_MESSAGE)).isInstanceOf(IllegalStateException.class); + } + + @Test + void testSetPartitionKey_getPartitionKey() { + assertEquals(MY_PARTITION, sink.getPartitionKey()); + + sink.setPartitionKey("part-B"); + assertEquals("part-B", sink.getPartitionKey()); + } + + @Test + void testShutdown() { + BusPublisher pub = mock(BusPublisher.class); + sink.publisher = pub; + + sink.shutdown(); + verify(pub).close(); + } + + @Test + void testAnyNullOrEmpty() { + assertFalse(sink.anyNullOrEmpty()); + assertFalse(sink.anyNullOrEmpty("any-none-null", "any-none-null-B")); + + assertTrue(sink.anyNullOrEmpty(null, "any-first-null")); + assertTrue(sink.anyNullOrEmpty("any-middle-null", null, "any-middle-null-B")); + assertTrue(sink.anyNullOrEmpty("any-last-null", null)); + assertTrue(sink.anyNullOrEmpty("any-empty", "")); + } + + @Test + void testAllNullOrEmpty() { + assertTrue(sink.allNullOrEmpty()); + assertTrue(sink.allNullOrEmpty("")); + assertTrue(sink.allNullOrEmpty(null, "")); + + assertFalse(sink.allNullOrEmpty("all-ok-only-one")); + assertFalse(sink.allNullOrEmpty("all-ok-one", "all-ok-two")); + assertFalse(sink.allNullOrEmpty("all-ok-null", null)); + assertFalse(sink.allNullOrEmpty("", "all-ok-empty")); + assertFalse(sink.allNullOrEmpty("", "all-one-ok", null)); + } + + @Test + void testToString() { + assertTrue(sink.toString().startsWith("InlineBusTopicSink [")); + } + + /** + * Implementation of InlineBusTopicSink that tracks the number of times that init() is + * invoked. + */ + private static class InlineBusTopicSinkImpl extends InlineBusTopicSink { + + private int initCount = 0; + + public InlineBusTopicSinkImpl(BusTopicParams busTopicParams) { + super(busTopicParams); + } + + @Override + public CommInfrastructure getTopicCommInfrastructure() { + return CommInfrastructure.NOOP; + } + + @Override + public void init() { + ++initCount; + } + + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/SingleThreadedBusTopicSourceTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/SingleThreadedBusTopicSourceTest.java new file mode 100644 index 00000000..8ad8e8fd --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/SingleThreadedBusTopicSourceTest.java @@ -0,0 +1,375 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2018-2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.util.Arrays; +import java.util.Collections; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.TopicListener; +import org.onap.policy.common.parameters.topic.BusTopicParams; +import org.onap.policy.common.utils.gson.GsonTestUtils; +import org.onap.policy.common.utils.network.NetworkUtil; + +class SingleThreadedBusTopicSourceTest extends TopicTestBase { + private Thread thread; + private BusConsumer cons; + private TopicListener listener; + private SingleThreadedBusTopicSourceImpl source; + + /** + * Creates the object to be tested, as well as various mocks. + */ + @BeforeEach + @Override + public void setUp() { + super.setUp(); + + thread = mock(Thread.class); + cons = mock(BusConsumer.class); + listener = mock(TopicListener.class); + source = new SingleThreadedBusTopicSourceImpl(makeBuilder().build()); + } + + @AfterEach + public void tearDown() { + source.shutdown(); + } + + @Test + void testSerialize() { + assertThatCode(() -> new GsonTestUtils().compareGson(source, SingleThreadedBusTopicSourceTest.class)) + .doesNotThrowAnyException(); + } + + @Test + void testRegister() { + source.register(listener); + assertEquals(1, source.initCount); + source.offer(MY_MESSAGE); + verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE); + + // register another - should not re-init + TopicListener listener2 = mock(TopicListener.class); + source.register(listener2); + assertEquals(1, source.initCount); + source.offer(MY_MESSAGE + "z"); + verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE + "z"); + verify(listener2).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE + "z"); + + // re-register - should not re-init + source.register(listener); + assertEquals(1, source.initCount); + source.offer(MY_MESSAGE2); + verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE2); + + // lock & register - should not init + source = new SingleThreadedBusTopicSourceImpl(makeBuilder().build()); + source.lock(); + source.register(listener); + assertEquals(0, source.initCount); + + // exception during init + source = new SingleThreadedBusTopicSourceImpl(makeBuilder().build()); + source.initEx = true; + source.register(listener); + } + + @Test + void testUnregister() { + TopicListener listener2 = mock(TopicListener.class); + source.register(listener); + source.register(listener2); + + // unregister first listener - should NOT invoke close + source.unregister(listener); + verify(cons, never()).close(); + assertEquals(Arrays.asList(listener2), source.snapshotTopicListeners()); + + // unregister same listener - should not invoke close + source.unregister(listener); + verify(cons, never()).close(); + assertEquals(Arrays.asList(listener2), source.snapshotTopicListeners()); + + // unregister second listener - SHOULD invoke close + source.unregister(listener2); + verify(cons).close(); + assertTrue(source.snapshotTopicListeners().isEmpty()); + + // unregister same listener - should not invoke close again + source.unregister(listener2); + verify(cons).close(); + assertTrue(source.snapshotTopicListeners().isEmpty()); + } + + @Test + void testToString() { + assertTrue(source.toString().startsWith("SingleThreadedBusTopicSource [")); + } + + @Test + void testMakePollerThread() { + SingleThreadedBusTopicSource source2 = new SingleThreadedBusTopicSource(makeBuilder().build()) { + @Override + public CommInfrastructure getTopicCommInfrastructure() { + return CommInfrastructure.NOOP; + } + + @Override + public void init() throws MalformedURLException { + // do nothing + } + }; + + assertNotNull(source2.makePollerThread()); + } + + @Test + void testSingleThreadedBusTopicSource() { + // Note: if the value contains "-", it's probably a UUID + + // verify that different wrappers can be built + source = new SingleThreadedBusTopicSourceImpl(makeBuilder().build()); + assertThat(source.getConsumerGroup()).isEqualTo(MY_CONS_GROUP); + assertThat(source.getConsumerInstance()).isEqualTo(MY_CONS_INST); + + // group is null => group is UUID, instance is as provided + source = new SingleThreadedBusTopicSourceImpl(makeBuilder().consumerGroup(null).build()); + assertThat(source.getConsumerGroup()).contains("-").isNotEqualTo(NetworkUtil.getHostname()); + assertThat(source.getConsumerInstance()).isEqualTo(MY_CONS_INST); + + // instance is null => group is as provided, instance is UUID + source = new SingleThreadedBusTopicSourceImpl(makeBuilder().consumerInstance(null).build()); + assertThat(source.getConsumerGroup()).isEqualTo(MY_CONS_GROUP); + assertThat(source.getConsumerInstance()).contains("-").isNotEqualTo(NetworkUtil.getHostname()); + + // group & instance are null => group is UUID, instance is hostname + source = new SingleThreadedBusTopicSourceImpl(makeBuilder().consumerGroup(null).consumerInstance(null).build()); + assertThat(source.getConsumerGroup()).contains("-").isNotEqualTo(NetworkUtil.getHostname()); + assertThat(source.getConsumerInstance()).isEqualTo(NetworkUtil.getHostname()); + + assertThatCode(() -> new SingleThreadedBusTopicSourceImpl( + makeBuilder().fetchLimit(-1).fetchTimeout(-1).build())).doesNotThrowAnyException(); + } + + @Test + void testStart() { + source.start(); + assertTrue(source.isAlive()); + assertEquals(1, source.initCount); + verify(thread).start(); + + // attempt to start again - nothing should be invoked again + source.start(); + assertTrue(source.isAlive()); + assertEquals(1, source.initCount); + verify(thread).start(); + + // stop & re-start + source.stop(); + source.start(); + assertTrue(source.isAlive()); + assertEquals(2, source.initCount); + verify(thread, times(2)).start(); + } + + @Test + void testStart_Locked() { + source.lock(); + assertThatThrownBy(() -> source.start()).isInstanceOf(IllegalStateException.class); + } + + @Test + void testStart_InitEx() { + assertThatThrownBy(() -> { + source.initEx = true; + + source.start(); + }).isInstanceOf(IllegalStateException.class); + } + + @Test + void testStop() { + source.start(); + source.stop(); + verify(cons).close(); + + // stop it again - not re-closed + source.stop(); + verify(cons).close(); + + // start & stop again, but with an exception + doThrow(new RuntimeException(EXPECTED)).when(cons).close(); + source.start(); + source.stop(); + } + + @Test + void testRun() throws Exception { + source.register(listener); + + /* + * Die in the middle of fetching messages. Also, throw an exception during the + * first fetch attempt. + */ + when(cons.fetch()).thenAnswer(new Answer>() { + int count = 0; + + @Override + public Iterable answer(InvocationOnMock invocation) throws Throwable { + if (++count > 1) { + source.alive = false; + return Arrays.asList(MY_MESSAGE, MY_MESSAGE2); + + } else { + throw new IOException(EXPECTED); + } + } + }); + source.alive = true; + source.run(); + assertEquals(Arrays.asList(MY_MESSAGE), Arrays.asList(source.getRecentEvents())); + verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE); + verify(listener, never()).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE2); + + /* + * Die AFTER fetching messages. + */ + final String msga = "message-A"; + final String msgb = "message-B"; + when(cons.fetch()).thenAnswer(new Answer>() { + int count = 0; + + @Override + public Iterable answer(InvocationOnMock invocation) throws Throwable { + if (++count > 1) { + source.alive = false; + return Collections.emptyList(); + + } else { + return Arrays.asList(msga, msgb); + } + } + }); + source.alive = true; + source.run(); + verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, msga); + verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, msgb); + + assertEquals(Arrays.asList(MY_MESSAGE, msga, msgb), Arrays.asList(source.getRecentEvents())); + } + + @Test + void testOffer() { + source.register(listener); + source.offer(MY_MESSAGE); + verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE); + assertEquals(Arrays.asList(MY_MESSAGE), Arrays.asList(source.getRecentEvents())); + } + + @Test + void testOffer_NotStarted() { + assertThatThrownBy(() -> source.offer(MY_MESSAGE)).isInstanceOf(IllegalStateException.class); + } + + @Test + void testGetConsumerGroup() { + assertEquals(MY_CONS_GROUP, source.getConsumerGroup()); + } + + @Test + void testGetConsumerInstance() { + assertEquals(MY_CONS_INST, source.getConsumerInstance()); + } + + @Test + void testShutdown() { + source.register(listener); + + source.shutdown(); + verify(cons).close(); + assertTrue(source.snapshotTopicListeners().isEmpty()); + } + + @Test + void testGetFetchTimeout() { + assertEquals(MY_FETCH_TIMEOUT, source.getFetchTimeout()); + } + + @Test + void testGetFetchLimit() { + assertEquals(MY_FETCH_LIMIT, source.getFetchLimit()); + } + + /** + * Implementation of SingleThreadedBusTopicSource that counts the number of times + * init() is invoked. + */ + private class SingleThreadedBusTopicSourceImpl extends SingleThreadedBusTopicSource { + + private int initCount = 0; + private boolean initEx = false; + + public SingleThreadedBusTopicSourceImpl(BusTopicParams busTopicParams) { + super(busTopicParams); + } + + @Override + public CommInfrastructure getTopicCommInfrastructure() { + return CommInfrastructure.NOOP; + } + + @Override + public void init() throws MalformedURLException { + ++initCount; + + if (initEx) { + throw new MalformedURLException(EXPECTED); + } + + consumer = cons; + } + + @Override + protected Thread makePollerThread() { + return thread; + } + + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/TopicBaseTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/TopicBaseTest.java new file mode 100644 index 00000000..5ecde258 --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/TopicBaseTest.java @@ -0,0 +1,355 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.TopicListener; +import org.onap.policy.common.utils.gson.GsonTestUtils; + +class TopicBaseTest extends TopicTestBase { + + private TopicBaseImpl base; + + /** + * Creates the object to be tested. + */ + @BeforeEach + @Override + public void setUp() { + super.setUp(); + + base = new TopicBaseImpl(servers, MY_TOPIC); + } + + @Test + void testTopicBase_NullServers() { + assertThatThrownBy(() -> new TopicBaseImpl(null, MY_TOPIC)).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void testTopicBase_EmptyServers() { + List testList = Collections.emptyList(); + assertThatThrownBy(() -> new TopicBaseImpl(testList, MY_TOPIC)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void testTopicBase_NullTopic() { + assertThatThrownBy(() -> new TopicBaseImpl(servers, null)).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void testTopicBase_EmptyTopic() { + assertThatThrownBy(() -> new TopicBaseImpl(servers, "")).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void testTopicBase_EffectiveTopic() { + TopicBase baseEf = new TopicBaseImpl(servers, MY_TOPIC, MY_EFFECTIVE_TOPIC); + assertEquals(MY_TOPIC, baseEf.getTopic()); + assertEquals(MY_EFFECTIVE_TOPIC, baseEf.getEffectiveTopic()); + } + + @Test + void testTopicBase_NullEffectiveTopic() { + TopicBase baseEf = new TopicBaseImpl(servers, MY_TOPIC, null); + assertEquals(MY_TOPIC, baseEf.getTopic()); + assertEquals(MY_TOPIC, baseEf.getEffectiveTopic()); + } + + @Test + void testTopicBase_EmptyEffectiveTopic() { + TopicBase baseEf = new TopicBaseImpl(servers, MY_TOPIC, ""); + assertEquals(MY_TOPIC, baseEf.getTopic()); + assertEquals(MY_TOPIC, baseEf.getEffectiveTopic()); + } + + @Test + void testSerialize() { + assertThatCode(() -> new GsonTestUtils().compareGson(base, TopicBaseTest.class)).doesNotThrowAnyException(); + } + + @Test + void testRegister() { + TopicListener listener = mock(TopicListener.class); + base.register(listener); + assertEquals(List.of(listener), base.snapshotTopicListeners()); + + // re-register - list should be unchanged + base.register(listener); + assertEquals(List.of(listener), base.snapshotTopicListeners()); + + // register a new listener + TopicListener listener2 = mock(TopicListener.class); + base.register(listener2); + assertEquals(List.of(listener, listener2), base.snapshotTopicListeners()); + } + + @Test + void testRegister_NullListener() { + assertThatThrownBy(() -> base.register(null)).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void testUnregister() { + // register two listeners + TopicListener listener = mock(TopicListener.class); + TopicListener listener2 = mock(TopicListener.class); + base.register(listener); + base.register(listener2); + + // unregister one + base.unregister(listener); + assertEquals(List.of(listener2), base.snapshotTopicListeners()); + + // unregister the other + base.unregister(listener2); + assertTrue(base.snapshotTopicListeners().isEmpty()); + + // unregister again + base.unregister(listener2); + assertTrue(base.snapshotTopicListeners().isEmpty()); + } + + @Test + void testUnregister_NullListener() { + base.register(mock(TopicListener.class)); + assertThatThrownBy(() -> base.unregister(null)).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void testBroadcast() { + // register two listeners + TopicListener listener = mock(TopicListener.class); + TopicListener listener2 = mock(TopicListener.class); + base.register(listener); + base.register(listener2); + + // broadcast a message + final String msg1 = "message-A"; + base.broadcast(msg1); + verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, msg1); + verify(listener2).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, msg1); + + // broadcast another message, with an exception + final String msg2 = "message-B"; + doThrow(new RuntimeException(EXPECTED)).when(listener).onTopicEvent(any(), any(), any()); + base.broadcast(msg2); + verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, msg2); + verify(listener2).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, msg2); + } + + @Test + void testLock_testUnlock() { + assertFalse(base.isLocked()); + assertTrue(base.lock()); + assertEquals(0, base.startCount); + assertEquals(1, base.stopCount); + + // lock again - should not stop again + assertTrue(base.isLocked()); + assertTrue(base.lock()); + assertEquals(0, base.startCount); + assertEquals(1, base.stopCount); + + assertTrue(base.isLocked()); + assertTrue(base.unlock()); + assertEquals(1, base.startCount); + assertEquals(1, base.stopCount); + + // unlock again - should not start again + assertFalse(base.isLocked()); + assertTrue(base.unlock()); + assertEquals(1, base.startCount); + assertEquals(1, base.stopCount); + } + + /** + * Tests lock/unlock when the stop/start methods return false. + */ + @Test + void testLock_testUnlock_FalseReturns() { + + // lock, but stop returns false + base.stopReturn = false; + assertFalse(base.lock()); + assertTrue(base.isLocked()); + assertTrue(base.lock()); + + // unlock, but start returns false + base.startReturn = false; + assertFalse(base.unlock()); + assertFalse(base.isLocked()); + assertTrue(base.unlock()); + } + + /** + * Tests lock/unlock when the start method throws an exception. + */ + @Test + void testLock_testUnlock_Exception() { + + // lock & re-lock, but start throws an exception + base.startEx = true; + assertTrue(base.lock()); + assertFalse(base.unlock()); + assertFalse(base.isLocked()); + assertTrue(base.unlock()); + } + + @Test + void testIsLocked() { + assertFalse(base.isLocked()); + base.lock(); + assertTrue(base.isLocked()); + base.unlock(); + assertFalse(base.isLocked()); + } + + @Test + void testGetTopic() { + assertEquals(MY_TOPIC, base.getTopic()); + } + + @Test + void testGetEffectiveTopic() { + assertEquals(MY_TOPIC, base.getTopic()); + assertEquals(MY_TOPIC, base.getEffectiveTopic()); + } + + @Test + void testIsAlive() { + assertFalse(base.isAlive()); + base.start(); + assertTrue(base.isAlive()); + base.stop(); + assertFalse(base.isAlive()); + } + + @Test + void testGetServers() { + assertEquals(servers, base.getServers()); + } + + @Test + void testGetRecentEvents() { + assertEquals(0, base.getRecentEvents().length); + + base.addEvent("recent-A"); + base.addEvent("recent-B"); + + String[] recent = base.getRecentEvents(); + assertEquals(2, recent.length); + assertEquals("recent-A", recent[0]); + assertEquals("recent-B", recent[1]); + } + + @Test + void testToString() { + assertNotNull(base.toString()); + } + + /** + * Implementation of TopicBase. + */ + private static class TopicBaseImpl extends TopicBase { + private int startCount = 0; + private int stopCount = 0; + private boolean startReturn = true; + private boolean stopReturn = true; + private boolean startEx = false; + + /** + * Constructor. + * + * @param servers list of servers + * @param topic topic name + */ + public TopicBaseImpl(List servers, String topic) { + super(servers, topic); + } + + /** + * Constructor. + * + * @param servers list of servers + * @param topic topic name + * @param effectiveTopic effective topic name for network communication + */ + public TopicBaseImpl(List servers, String topic, String effectiveTopic) { + super(servers, topic, effectiveTopic); + } + + @Override + public CommInfrastructure getTopicCommInfrastructure() { + return CommInfrastructure.NOOP; + } + + @Override + public boolean start() { + ++startCount; + + if (startEx) { + throw new RuntimeException(EXPECTED); + } + + alive = true; + return startReturn; + } + + @Override + public boolean stop() { + ++stopCount; + alive = false; + return stopReturn; + } + + @Override + public void shutdown() { + // do nothing + } + + /** + * Adds an event to the list of recent events. + * + * @param event event to be added + */ + public void addEvent(String event) { + recentEvents.add(event); + } + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/TopicFactoryTestBase.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/TopicFactoryTestBase.java new file mode 100644 index 00000000..8444b482 --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/TopicFactoryTestBase.java @@ -0,0 +1,225 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_TOPIC_SERVERS_SUFFIX; + +import java.util.List; +import java.util.Properties; +import org.onap.policy.common.message.bus.event.Topic; + +/** + * Base class for XxxTopicFactory tests. + * + * @param type of topic managed by the factory + */ +public abstract class TopicFactoryTestBase extends TopicTestBase { + + public static final String SERVER = "my-server"; + public static final String TOPIC2 = "my-topic-2"; + public static final String TOPIC3 = "my-topic-3"; + + /** + * Initializes a new factory. + */ + protected abstract void initFactory(); + + /** + * Makes a property builder. + * + * @return a new property builder + */ + protected abstract TopicPropertyBuilder makePropBuilder(); + + /** + * Builds a set of topics. + * + * @param properties the properties used to configure the topics + * @return a list of new topics + */ + protected abstract List buildTopics(Properties properties); + + /** + * Destroys the factory. + */ + protected abstract void destroyFactory(); + + /** + * Destroys a topic within the factory. + * + * @param topic the topic to destroy + */ + protected abstract void destroyTopic(String topic); + + /** + * Gets the list of topics from the factory. + * + * @return the topic inventory + */ + protected abstract List getInventory(); + + /** + * Gets a topic from the factory. + * + * @param topic the topic name + * @return the topic + */ + protected abstract T getTopic(String topic); + + + /** + * Tests building a topic using varied Properties. + */ + void testBuildProperties_Variations() { + initFactory(); + + // null topic list + assertTrue(buildTopics(makePropBuilder().build()).isEmpty()); + + // empty topic list + assertTrue(buildTopics(makePropBuilder().addTopic("").build()).isEmpty()); + + // null servers + assertTrue(buildTopics(makePropBuilder().makeTopic(MY_TOPIC).removeTopicProperty(PROPERTY_TOPIC_SERVERS_SUFFIX) + .build()).isEmpty()); + + // empty servers + assertTrue(buildTopics(makePropBuilder().makeTopic(MY_TOPIC).setTopicProperty(PROPERTY_TOPIC_SERVERS_SUFFIX, "") + .build()).isEmpty()); + } + + /** + * Tests building multiple topics using Properties. + */ + public void testBuildProperties_Multiple() { + initFactory(); + + // make two fully-defined topics, and add two duplicate topic names to the list + TopicPropertyBuilder builder = + makePropBuilder().makeTopic(MY_TOPIC).makeTopic(TOPIC2).addTopic(MY_TOPIC).addTopic(MY_TOPIC); + + List lst = buildTopics(builder.build()); + assertEquals(4, lst.size()); + + int index = 0; + T item = lst.get(index++); + assertNotSame(item, lst.get(index++)); + assertSame(item, lst.get(index++)); + assertSame(item, lst.get(index++)); + } + + /** + * Tests destroy(topic), get(topic), and inventory() methods. + */ + public void testDestroyString_testGet_testInventory() { + initFactory(); + + List lst = buildTopics(makePropBuilder().makeTopic(MY_TOPIC).makeTopic(TOPIC2).build()); + + int index = 0; + T item1 = lst.get(index++); + T item2 = lst.get(index++); + + assertEquals(2, getInventory().size()); + assertTrue(getInventory().contains(item1)); + assertTrue(getInventory().contains(item2)); + + item1.start(); + item2.start(); + + assertEquals(item1, getTopic(MY_TOPIC)); + assertEquals(item2, getTopic(TOPIC2)); + + destroyTopic(MY_TOPIC); + assertFalse(item1.isAlive()); + assertTrue(item2.isAlive()); + assertEquals(item2, getTopic(TOPIC2)); + assertEquals(1, getInventory().size()); + assertTrue(getInventory().contains(item2)); + + // repeat + destroyTopic(MY_TOPIC); + assertFalse(item1.isAlive()); + assertTrue(item2.isAlive()); + + // with other topic + destroyTopic(TOPIC2); + assertFalse(item1.isAlive()); + assertFalse(item2.isAlive()); + assertEquals(0, getInventory().size()); + } + + /** + * Tests exception cases with destroy(topic). + */ + public void testDestroyString_Ex() { + // null topic + assertThatIllegalArgumentException().as("null topic").isThrownBy(() -> destroyTopic(null)); + + // empty topic + assertThatIllegalArgumentException().as("empty topic").isThrownBy(() -> destroyTopic("")); + } + + /** + * Tests the destroy() method. + */ + public void testDestroy() { + initFactory(); + + List lst = buildTopics(makePropBuilder().makeTopic(MY_TOPIC).makeTopic(TOPIC2).build()); + + int index = 0; + T item1 = lst.get(index++); + T item2 = lst.get(index++); + + item1.start(); + item2.start(); + + destroyFactory(); + + assertFalse(item1.isAlive()); + assertFalse(item2.isAlive()); + assertEquals(0, getInventory().size()); + } + + /** + * Tests exception cases with get(topic). + */ + public void testGet_Ex() { + // null topic + assertThatIllegalArgumentException().as("null topic").isThrownBy(() -> getTopic(null)); + + // empty topic + assertThatIllegalArgumentException().as("empty topic").isThrownBy(() -> getTopic("")); + + // unknown topic + initFactory(); + buildTopics(makePropBuilder().makeTopic(MY_TOPIC).build()); + + assertThatIllegalStateException().as("unknown topic").isThrownBy(() -> getTopic(TOPIC2)); + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/TopicPropertyBuilder.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/TopicPropertyBuilder.java new file mode 100644 index 00000000..29c5306b --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/TopicPropertyBuilder.java @@ -0,0 +1,121 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Engine - Common Modules + * ================================================================================ + * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +import java.util.Properties; + +/** + * Builder of properties used when configuring topics. + */ +public abstract class TopicPropertyBuilder { + private final Properties properties = new Properties(); + private final String prefix; + private String topicPrefix; + + /** + * Constructs the object. + * + * @param prefix the prefix for the properties to be built + */ + public TopicPropertyBuilder(String prefix) { + this.prefix = prefix; + } + + /** + * Constructs the properties from the builder. + * + * @return a copy of the properties + */ + public Properties build() { + Properties props = new Properties(); + props.putAll(properties); + + return props; + } + + /** + * Adds a topic to the list of topics, configuring all of its properties with default + * values. + * + * @param topic the topic to be added + * @return this builder + */ + public abstract TopicPropertyBuilder makeTopic(String topic); + + /** + * Adds a topic to the list of topics. Also sets the current topic so that subsequent + * invocations of property methods will manipulate the topic's properties. + * + * @param topic the topic to be added + * @return this builder + */ + public TopicPropertyBuilder addTopic(String topic) { + // add topic to the list of topics + String topicList = properties.getProperty(prefix); + if (topicList == null || topicList.isEmpty()) { + topicList = topic; + } else { + topicList += "," + topic; + } + + properties.setProperty(prefix, topicList); + + setTopic(topic); + + return this; + } + + /** + * Sets the topic for which subsequent properties will be managed. + * + * @param topic the topic + * @return this builder + */ + public TopicPropertyBuilder setTopic(String topic) { + this.topicPrefix = prefix + "." + topic; + return this; + } + + /** + * Sets a topic's property. + * + * @param name name of the property + * @param value value to which the property should be set + * @return this builder + */ + public TopicPropertyBuilder setTopicProperty(String name, Object value) { + properties.setProperty(topicPrefix + name, value.toString()); + return this; + } + + /** + * Removes a topic's property. + * + * @param name name of the property + * @return this builder + */ + public TopicPropertyBuilder removeTopicProperty(String name) { + properties.remove(topicPrefix + name); + return this; + } +} + diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/TopicTestBase.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/TopicTestBase.java new file mode 100644 index 00000000..8d5c3535 --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/base/TopicTestBase.java @@ -0,0 +1,159 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2018-2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.base; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import org.onap.policy.common.parameters.topic.BusTopicParams; +import org.onap.policy.common.parameters.topic.BusTopicParams.TopicParamsBuilder; + +/** + * Base class for Topic Test classes. + */ +public class TopicTestBase { + + public static final String MY_AFT_ENV = "my-aft-env"; + public static final String MY_API_KEY = "my-api-key"; + public static final String MY_API_SECRET = "my-api-secret"; + public static final String MY_BASE_PATH = "my-base"; + public static final String MY_CLIENT_NAME = "my-client"; + public static final String MY_CONS_GROUP = "my-cons-group"; + public static final String MY_CONS_INST = "my-cons-inst"; + public static final String MY_ENV = "my-env"; + public static final int MY_FETCH_LIMIT = 100; + public static final int MY_FETCH_TIMEOUT = 101; + public static final String MY_HOST = "my-host"; + public static final String MY_LAT = "my-lat"; + public static final String MY_LONG = "my-long"; + public static final String MY_PARTNER = "my-partner"; + public static final String MY_PASS = "my-pass"; + public static final int MY_PORT = 102; + public static final String MY_TOPIC = "my-topic"; + public static final String MY_EFFECTIVE_TOPIC = "my-effective-topic"; + public static final String MY_USERNAME = "my-user"; + + public static final String MY_MESSAGE = "my-message"; + public static final String MY_PARTITION = "my-partition"; + public static final String MY_MESSAGE2 = "my-message-2"; + + public static final String MY_SERIALIZER = "org.apache.kafka.common.serialization.StringSerializer"; + public static final int KAFKA_PORT = 9092; + + /** + * Message used within exceptions that are expected. + */ + public static final String EXPECTED = "expected exception"; + + /** + * Additional properties to be added to the parameter builder. + */ + protected Map addProps; + + /** + * Servers to be added to the parameter builder. + */ + protected List servers; + + /** + * Servers to be added to the parameter builder. + */ + protected List kafkaServers; + + /** + * Parameter builder used to build topic parameters. + */ + protected TopicParamsBuilder builder; + + /** + * Initializes {@link #addProps}, {@link #servers}, and {@link #builder}. + */ + public void setUp() { + addProps = new TreeMap<>(); + addProps.put("my-key-A", "my-value-A"); + addProps.put("my-key-B", "my-value-B"); + + servers = Arrays.asList("svra", "svrb"); + kafkaServers = Arrays.asList("localhost:9092", "10.1.2.3:9092"); + + builder = makeBuilder(); + } + + /** + * Makes a fully populated parameter builder. + * + * @return a new parameter builder + */ + public TopicParamsBuilder makeBuilder() { + return makeBuilder(addProps, servers); + } + + /** + * Makes a fully populated parameter builder. + * + * @param addProps additional properties to be added to the builder + * @param servers servers to be added to the builder + * @return a new parameter builder + */ + public TopicParamsBuilder makeBuilder(Map addProps, List servers) { + + return BusTopicParams.builder().additionalProps(addProps).aftEnvironment(MY_AFT_ENV).allowSelfSignedCerts(true) + .apiKey(MY_API_KEY).apiSecret(MY_API_SECRET).basePath(MY_BASE_PATH).clientName(MY_CLIENT_NAME) + .consumerGroup(MY_CONS_GROUP).consumerInstance(MY_CONS_INST).environment(MY_ENV) + .fetchLimit(MY_FETCH_LIMIT).fetchTimeout(MY_FETCH_TIMEOUT).hostname(MY_HOST).latitude(MY_LAT) + .longitude(MY_LONG).managed(true).partitionId(MY_PARTITION).partner(MY_PARTNER) + .password(MY_PASS).port(MY_PORT).servers(servers).topic(MY_TOPIC) + .effectiveTopic(MY_EFFECTIVE_TOPIC).useHttps(true).allowTracing(true).userName(MY_USERNAME) + .serializationProvider(MY_SERIALIZER); + } + + /** + * Makes a fully populated parameter builder. + * + * @return a new parameter builder + */ + public TopicParamsBuilder makeKafkaBuilder() { + addProps.clear(); + String jaas = "org.apache.kafka.common.security.plain.PlainLoginModule " + + "required username=abc password=abc serviceName=kafka;"; + addProps.put("sasl.jaas.config", jaas); + addProps.put("sasl.mechanism", "SCRAM-SHA-512"); + addProps.put("security.protocol", "SASL_PLAINTEXT"); + + return makeKafkaBuilder(addProps, kafkaServers); + } + + /** + * Makes a fully populated parameter builder. + * + * @param addProps additional properties to be added to the builder + * @param servers servers to be added to the builder + * @return a new parameter builder + */ + public TopicParamsBuilder makeKafkaBuilder(Map addProps, List servers) { + + return BusTopicParams.builder().additionalProps(addProps).basePath(MY_BASE_PATH).clientName(MY_CLIENT_NAME) + .consumerGroup(MY_CONS_GROUP).consumerInstance(MY_CONS_INST).environment(MY_ENV) + .hostname(MY_HOST).partitionId(MY_PARTITION).partner(MY_PARTNER).fetchTimeout(MY_FETCH_TIMEOUT) + .port(KAFKA_PORT).servers(servers).topic(MY_TOPIC) + .effectiveTopic(MY_EFFECTIVE_TOPIC).useHttps(false).allowTracing(true); + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/client/BidirectionalTopicClientTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/client/BidirectionalTopicClientTest.java new file mode 100644 index 00000000..ba33ff9a --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/client/BidirectionalTopicClientTest.java @@ -0,0 +1,454 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.client; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.atLeast; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import java.util.Properties; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.TopicEndpoint; +import org.onap.policy.common.message.bus.event.TopicEndpointManager; +import org.onap.policy.common.message.bus.event.TopicListener; +import org.onap.policy.common.message.bus.event.TopicSink; +import org.onap.policy.common.message.bus.event.TopicSource; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; + +@ExtendWith(MockitoExtension.class) +class BidirectionalTopicClientTest { + private static final Coder coder = new StandardCoder(); + private static final long MAX_WAIT_MS = 5000; + private static final long SHORT_WAIT_MS = 1; + private static final String SINK_TOPIC = "my-sink-topic"; + private static final String SOURCE_TOPIC = "my-source-topic"; + private static final String MY_TEXT = "my-text"; + + private static final CommInfrastructure SINK_INFRA = CommInfrastructure.NOOP; + private static final CommInfrastructure SOURCE_INFRA = CommInfrastructure.NOOP; + + @Mock + private TopicSink sink; + @Mock + private TopicSource source; + @Mock + private TopicEndpoint endpoint; + @Mock + private TopicListener listener; + + private MyMessage theMessage; + + private BidirectionalTopicClient client; + private Context context; + + /** + * Configures the endpoints. + */ + @BeforeAll + public static void setUpBeforeClass() { + Properties props = new Properties(); + props.setProperty("noop.sink.topics", SINK_TOPIC); + props.setProperty("noop.source.topics", SOURCE_TOPIC); + + // clear all topics and then configure one sink and one source + TopicEndpointManager.getManager().shutdown(); + TopicEndpointManager.getManager().addTopicSinks(props); + TopicEndpointManager.getManager().addTopicSources(props); + } + + @AfterAll + public static void tearDownAfterClass() { + // clear all topics after the tests + TopicEndpointManager.getManager().shutdown(); + } + + /** + * Creates mocks and an initial client object. + */ + @BeforeEach + public void setUp() throws Exception { + lenient().when(sink.send(anyString())).thenReturn(true); + lenient().when(sink.getTopicCommInfrastructure()).thenReturn(SINK_INFRA); + + lenient().when(source.offer(anyString())).thenReturn(true); + lenient().when(source.getTopicCommInfrastructure()).thenReturn(SOURCE_INFRA); + + lenient().when(endpoint.getTopicSinks(anyString())).thenReturn(Arrays.asList()); + lenient().when(endpoint.getTopicSinks(SINK_TOPIC)).thenReturn(Arrays.asList(sink)); + + lenient().when(endpoint.getTopicSources(any())).thenReturn(Arrays.asList()); + lenient().when(endpoint.getTopicSources(Arrays.asList(SOURCE_TOPIC))).thenReturn(Arrays.asList(source)); + + theMessage = new MyMessage(MY_TEXT); + + client = new BidirectionalTopicClient2(SINK_TOPIC, SOURCE_TOPIC); + + context = new Context(); + } + + @AfterEach + public void tearDown() { + context.stop(); + } + + @Test + void testBidirectionalTopicClient_testGetters() { + assertSame(sink, client.getSink()); + assertSame(source, client.getSource()); + assertEquals(SINK_TOPIC, client.getSinkTopic()); + assertEquals(SOURCE_TOPIC, client.getSourceTopic()); + assertEquals(SINK_INFRA, client.getSinkTopicCommInfrastructure()); + assertEquals(SOURCE_INFRA, client.getSourceTopicCommInfrastructure()); + } + + /** + * Tests the constructor when the sink or source cannot be found. + */ + @Test + void testBidirectionalTopicClientExceptions() { + assertThatThrownBy(() -> new BidirectionalTopicClient2("unknown-sink", SOURCE_TOPIC)) + .isInstanceOf(BidirectionalTopicClientException.class) + .hasMessage("no sinks for topic: unknown-sink"); + + assertThatThrownBy(() -> new BidirectionalTopicClient2(SINK_TOPIC, "unknown-source")) + .isInstanceOf(BidirectionalTopicClientException.class) + .hasMessage("no sources for topic: unknown-source"); + + // too many sources + when(endpoint.getTopicSources(Arrays.asList(SOURCE_TOPIC))).thenReturn(Arrays.asList(source, source)); + + assertThatThrownBy(() -> new BidirectionalTopicClient2(SINK_TOPIC, SOURCE_TOPIC)) + .isInstanceOf(BidirectionalTopicClientException.class) + .hasMessage("too many sources for topic: my-source-topic"); + } + + /** + * Tests the "delegate" methods. + */ + @Test + void testDelegates() { + assertTrue(client.send("hello")); + verify(sink).send("hello"); + + assertTrue(client.offer("incoming")); + verify(source).offer("incoming"); + + client.register(listener); + verify(source).register(listener); + + client.unregister(listener); + verify(source).unregister(listener); + } + + @Test + void testGetTopicEndpointManager() throws BidirectionalTopicClientException { + // use a real manager + client = new BidirectionalTopicClient(SINK_TOPIC, SOURCE_TOPIC); + assertNotNull(client.getTopicEndpointManager()); + + assertNotNull(client.getSink()); + assertNotNull(client.getSource()); + + assertNotSame(sink, client.getSink()); + assertNotSame(source, client.getSource()); + } + + @Test + void testAwaitReceipt() throws Exception { + context.start(theMessage); + assertThat(context.awaitSend(1)).isTrue(); + + verify(source).register(any()); + verify(sink, atLeast(1)).send(any()); + assertThat(context.checker.isReady()).isFalse(); + + inject(theMessage); + + verifyReceipt(); + } + + @Test + void testAwaitReceipt_AlreadyDone() throws Exception { + context.start(theMessage); + assertThat(context.awaitSend(1)).isTrue(); + + inject(theMessage); + + verifyReceipt(); + + // calling again should result in "true" again, without injecting message + context.start(theMessage); + verifyReceipt(); + } + + @Test + void testAwaitReceipt_MessageDoesNotMatch() throws Exception { + context.start(theMessage); + assertThat(context.awaitSend(1)).isTrue(); + + // non-matching message + inject("{}"); + + // wait for a few more calls to "send" and then inject a matching message + assertThat(context.awaitSend(3)).isTrue(); + inject(theMessage); + + verifyReceipt(); + } + + @Test + void testAwaitReceipt_DecodeFails() throws Exception { + context.start(theMessage); + assertThat(context.awaitSend(1)).isTrue(); + + // force a failure and inject the message + context.forceDecodeFailure = true; + inject(theMessage); + + assertThat(context.awaitDecodeFailure()).isTrue(); + + // no more failures + context.forceDecodeFailure = false; + inject(theMessage); + + verifyReceipt(); + } + + @Test + void testAwaitReceipt_Interrupted() throws InterruptedException { + context.start(theMessage); + assertThat(context.awaitSend(1)).isTrue(); + + context.interrupt(); + + verifyNoReceipt(); + } + + @Test + void testAwaitReceipt_MultipleLoops() throws Exception { + context.start(theMessage); + + // wait for multiple "send" calls + assertThat(context.awaitSend(3)).isTrue(); + + inject(theMessage); + + verifyReceipt(); + } + + @Test + void testStop() throws InterruptedException { + context.start(theMessage); + assertThat(context.awaitSend(1)).isTrue(); + + context.stop(); + + verifyNoReceipt(); + } + + /** + * Verifies that awaitReceipt() returns {@code true}. + * + * @throws InterruptedException if interrupted while waiting for the thread to + * terminate + */ + private void verifyReceipt() throws InterruptedException { + assertThat(context.join()).isTrue(); + assertThat(context.result).isTrue(); + assertThat(context.exception).isNull(); + assertThat(context.checker.isReady()).isTrue(); + + verify(source).unregister(any()); + } + + /** + * Verifies that awaitReceipt() returns {@code false}. + * + * @throws InterruptedException if interrupted while waiting for the thread to + * terminate + */ + private void verifyNoReceipt() throws InterruptedException { + assertThat(context.join()).isTrue(); + assertThat(context.result).isFalse(); + assertThat(context.exception).isNull(); + assertThat(context.checker.isReady()).isFalse(); + + verify(source).unregister(any()); + } + + /** + * Injects a message into the source topic. + * + * @param message message to be injected + * @throws CoderException if the message cannot be encoded + */ + private void inject(MyMessage message) throws CoderException { + inject(coder.encode(message)); + } + + /** + * Injects a message into the source topic. + * + * @param message message to be injected + */ + private void inject(String message) { + ArgumentCaptor cap = ArgumentCaptor.forClass(TopicListener.class); + verify(source).register(cap.capture()); + + cap.getValue().onTopicEvent(SOURCE_INFRA, SOURCE_TOPIC, message); + } + + + /** + * BidirectionalTopicClient with some overrides. + */ + private class BidirectionalTopicClient2 extends BidirectionalTopicClient { + + public BidirectionalTopicClient2(String sinkTopic, String sourceTopic) + throws BidirectionalTopicClientException { + super(sinkTopic, sourceTopic); + } + + @Override + protected TopicEndpoint getTopicEndpointManager() { + return endpoint; + } + } + + private class Context { + private Thread thread; + private boolean result; + private Exception exception; + private boolean forceDecodeFailure; + + // released every time the checker publishes a message + private final Semaphore sendSem = new Semaphore(0); + + // released every time a message-decode fails + private final Semaphore decodeFailedSem = new Semaphore(0); + + private final BidirectionalTopicClient2 checker; + + public Context() throws BidirectionalTopicClientException { + + checker = new BidirectionalTopicClient2(SINK_TOPIC, SOURCE_TOPIC) { + + @Override + public boolean send(String messageText) { + boolean result = super.send(messageText); + sendSem.release(); + return result; + } + + @Override + protected T decode(String msg, Class clazz) throws CoderException { + if (forceDecodeFailure) { + throw new CoderException("expected exception"); + } + + return super.decode(msg, clazz); + } + + @Override + protected void decodeFailed() { + super.decodeFailed(); + decodeFailedSem.release(); + } + }; + } + + /** + * Starts the thread. + * + * @param message message to be sent to the sink topic + */ + public void start(MyMessage message) { + thread = new Thread() { + @Override + public void run() { + try { + result = checker.awaitReady(message, SHORT_WAIT_MS); + } catch (Exception e) { + exception = e; + } + } + }; + thread.setDaemon(true); + thread.start(); + } + + public void stop() { + checker.stopWaiting(); + } + + public boolean join() throws InterruptedException { + thread.join(MAX_WAIT_MS); + return !thread.isAlive(); + } + + public void interrupt() { + thread.interrupt(); + } + + public boolean awaitSend(int npermits) throws InterruptedException { + return sendSem.tryAcquire(npermits, MAX_WAIT_MS, TimeUnit.MILLISECONDS); + } + + public boolean awaitDecodeFailure() throws InterruptedException { + return decodeFailedSem.tryAcquire(MAX_WAIT_MS, TimeUnit.MILLISECONDS); + } + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class MyMessage { + private String text; + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/client/TopicClientExceptionTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/client/TopicClientExceptionTest.java new file mode 100644 index 00000000..1ea2f1bc --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/client/TopicClientExceptionTest.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019, 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.client; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; +import org.onap.policy.common.utils.test.ExceptionsTester; + +class TopicClientExceptionTest { + + @Test + void test() { + assertEquals(5, new ExceptionsTester().test(TopicSinkClientException.class)); + assertEquals(5, new ExceptionsTester().test(BidirectionalTopicClientException.class)); + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/client/TopicSinkClientTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/client/TopicSinkClientTest.java new file mode 100644 index 00000000..67b15ec9 --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/client/TopicSinkClientTest.java @@ -0,0 +1,147 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019, 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.client; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.atomic.AtomicReference; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.policy.common.message.bus.event.TopicEndpointManager; +import org.onap.policy.common.message.bus.event.TopicSink; + +class TopicSinkClientTest { + private static final String TOPIC = "my-topic"; + + private TopicSinkClient client; + private TopicSink sink; + private List sinks; + + /** + * Creates mocks and an initial client object. + * + * @throws Exception if an error occurs + */ + @BeforeEach + public void setUp() throws Exception { + sink = mock(TopicSink.class); + when(sink.send(anyString())).thenReturn(true); + + sinks = Arrays.asList(sink, null); + + client = new TopicSinkClient2(TOPIC); + + Properties props = new Properties(); + props.setProperty("noop.sink.topics", TOPIC); + + // clear all topics and then configure one topic + TopicEndpointManager.getManager().shutdown(); + TopicEndpointManager.getManager().addTopicSinks(props); + } + + @AfterAll + public static void tearDown() { + // clear all topics after the tests + TopicEndpointManager.getManager().shutdown(); + } + + /** + * Uses a real NO-OP topic sink. + */ + @Test + void testGetTopicSinks() throws Exception { + + sink = TopicEndpointManager.getManager().getNoopTopicSink(TOPIC); + assertNotNull(sink); + + final AtomicReference evref = new AtomicReference<>(null); + + sink.register((infra, topic, event) -> evref.set(event)); + sink.start(); + + client = new TopicSinkClient(TOPIC); + client.send(100); + + assertEquals("100", evref.get()); + } + + @Test + void testTopicSinkClient() { + // unknown topic -> should throw exception + sinks = new LinkedList<>(); + assertThatThrownBy(() -> new TopicSinkClient2(TOPIC)).isInstanceOf(TopicSinkClientException.class) + .hasMessage("no sinks for topic: my-topic"); + } + + @Test + void testTopicSinkClient_GetTopic() throws TopicSinkClientException { + assertEquals(TOPIC, new TopicSinkClient(TopicEndpointManager.getManager().getNoopTopicSink(TOPIC)).getTopic()); + assertEquals(TOPIC, new TopicSinkClient(TOPIC).getTopic()); + + assertThatThrownBy(() -> new TopicSinkClient((TopicSink) null)) + .hasMessageContaining("sink is marked non-null but is null"); + assertThatThrownBy(() -> new TopicSinkClient("blah")).isInstanceOf(TopicSinkClientException.class) + .hasMessage("no sinks for topic: blah"); + } + + @Test + void testSend() { + client.send(Arrays.asList("abc", "def")); + verify(sink).send("['abc','def']".replace('\'', '"')); + + // sink send fails + when(sink.send(anyString())).thenReturn(false); + assertFalse(client.send("ghi")); + + // sink send throws an exception + final RuntimeException ex = new RuntimeException("expected exception"); + when(sink.send(anyString())).thenThrow(ex); + assertFalse(client.send("jkl")); + } + + /** + * TopicSinkClient with some overrides. + */ + private class TopicSinkClient2 extends TopicSinkClient { + + public TopicSinkClient2(final String topic) throws TopicSinkClientException { + super(topic); + } + + @Override + protected List getTopicSinks(final String topic) { + return sinks; + } + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/IndexedKafkaTopicSourceFactoryTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/IndexedKafkaTopicSourceFactoryTest.java new file mode 100644 index 00000000..a901b07b --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/IndexedKafkaTopicSourceFactoryTest.java @@ -0,0 +1,63 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.List; +import org.junit.jupiter.api.Test; +import org.onap.policy.common.parameters.topic.BusTopicParams; + +class IndexedKafkaTopicSourceFactoryTest { + + private IndexedKafkaTopicSourceFactory factory; + + @Test + void testBuild() { + factory = new IndexedKafkaTopicSourceFactory(); + BusTopicParams params = new BusTopicParams(); + + // set servers to null + params.setServers(null); + assertThatThrownBy(() -> factory.build(params)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("KAFKA Server(s) must be provided"); + + // set servers to empty + params.setServers(List.of()); + assertThatThrownBy(() -> factory.build(params)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("KAFKA Server(s) must be provided"); + + List servers = List.of("kafka:9092", "kafka:29092"); + params.setServers(servers); + + // set topic to null + params.setTopic(null); + assertThatThrownBy(() -> factory.build(params)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("A topic must be provided"); + + // set topic to empty + params.setTopic(""); + assertThatThrownBy(() -> factory.build(params)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("A topic must be provided"); + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/InlineKafkaTopicSinkTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/InlineKafkaTopicSinkTest.java new file mode 100644 index 00000000..c8d6e21e --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/InlineKafkaTopicSinkTest.java @@ -0,0 +1,68 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.base.TopicTestBase; + +class InlineKafkaTopicSinkTest extends TopicTestBase { + private InlineKafkaTopicSink sink; + + /** + * Creates the object to be tested. + */ + @BeforeEach + @Override + public void setUp() { + super.setUp(); + + sink = new InlineKafkaTopicSink(makeKafkaBuilder().build()); + } + + @AfterEach + public void tearDown() { + sink.shutdown(); + } + + @Test + void testToString() { + assertTrue(sink.toString().startsWith("InlineKafkaTopicSink [")); + } + + @Test + void testInit() { + // nothing null + sink = new InlineKafkaTopicSink(makeKafkaBuilder().build()); + sink.init(); + assertThatCode(() -> sink.shutdown()).doesNotThrowAnyException(); + } + + @Test + void testGetTopicCommInfrastructure() { + assertEquals(CommInfrastructure.KAFKA, sink.getTopicCommInfrastructure()); + } + +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaPublisherWrapperTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaPublisherWrapperTest.java new file mode 100644 index 00000000..8e13af23 --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaPublisherWrapperTest.java @@ -0,0 +1,98 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Collections; +import java.util.Properties; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.Producer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentMatchers; +import org.onap.policy.common.parameters.topic.BusTopicParams; + +class KafkaPublisherWrapperTest { + + private KafkaPublisherWrapper kafkaPublisherWrapper; + private Producer mockProducer; + private BusTopicParams mockBusTopicParams; + + @BeforeEach + void setUp() { + mockProducer = mock(KafkaProducer.class); + mockBusTopicParams = mock(BusTopicParams.class); + + when(mockBusTopicParams.getTopic()).thenReturn("testTopic"); + when(mockBusTopicParams.getServers()).thenReturn(Collections.singletonList("localhost:9092")); + when(mockBusTopicParams.isTopicInvalid()).thenReturn(false); + when(mockBusTopicParams.isAdditionalPropsValid()).thenReturn(false); + when(mockBusTopicParams.isAllowTracing()).thenReturn(false); + + kafkaPublisherWrapper = new KafkaPublisherWrapper(mockBusTopicParams) { + private Producer createProducer(Properties props) { // NOSONAR instance creation + return mockProducer; + } + }; + } + + @Test + void testConstructor() { + verify(mockBusTopicParams).getTopic(); + verify(mockBusTopicParams).getServers(); + verify(mockBusTopicParams).isTopicInvalid(); + verify(mockBusTopicParams).isAdditionalPropsValid(); + verify(mockBusTopicParams).isAllowTracing(); + } + + @Test + void testSendSuccess() { + when(mockProducer.send(ArgumentMatchers.any(ProducerRecord.class))).thenReturn(null); + assertTrue(kafkaPublisherWrapper.send("partitionId", "testMessage")); + } + + @Test + void testSendNullMessage() { + IllegalArgumentException thrown = assertThrows( + IllegalArgumentException.class, + () -> kafkaPublisherWrapper.send("partitionId", null), + "Expected send() to throw, but it didn't" + ); + assertEquals("No message provided", thrown.getMessage()); + } + + @Test + void testSendFailure() { + when(mockProducer.send(ArgumentMatchers.any(ProducerRecord.class))).thenThrow(RuntimeException.class); + assertTrue(kafkaPublisherWrapper.send("partitionId", "testMessage")); + } + + @Test + void testClose() { + assertThatCode(kafkaPublisherWrapper::close).doesNotThrowAnyException(); + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicFactoryTestBase.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicFactoryTestBase.java new file mode 100644 index 00000000..1085ee90 --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicFactoryTestBase.java @@ -0,0 +1,47 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; + +import java.util.Collections; +import org.onap.policy.common.message.bus.event.Topic; +import org.onap.policy.common.message.bus.event.base.BusTopicFactoryTestBase; + +/** + * Base class for KafkaTopicXxxFactory tests. + * + * @param type of topic managed by the factory + */ +public abstract class KafkaTopicFactoryTestBase extends BusTopicFactoryTestBase { + + @Override + public void testBuildBusTopicParams_Ex() { + + super.testBuildBusTopicParams_Ex(); + + // null servers + assertThatIllegalArgumentException().as("null servers") + .isThrownBy(() -> buildTopic(makeBuilder().servers(null).build())); + + // empty servers + assertThatIllegalArgumentException().as("empty servers") + .isThrownBy(() -> buildTopic(makeBuilder().servers(Collections.emptyList()).build())); + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicPropertyBuilder.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicPropertyBuilder.java new file mode 100644 index 00000000..6a1be7a0 --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicPropertyBuilder.java @@ -0,0 +1,94 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022, 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import static org.onap.policy.common.message.bus.event.base.TopicTestBase.MY_EFFECTIVE_TOPIC; +import static org.onap.policy.common.message.bus.event.base.TopicTestBase.MY_PARTITION; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_HTTP_HTTPS_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_MANAGED_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_TOPIC_SERVERS_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_TOPIC_SINK_PARTITION_KEY_SUFFIX; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import lombok.Getter; +import org.onap.policy.common.message.bus.event.base.TopicPropertyBuilder; +import org.onap.policy.common.parameters.topic.TopicParameters; + +@Getter +public class KafkaTopicPropertyBuilder extends TopicPropertyBuilder { + + public static final String SERVER = "localhost:9092"; + public static final String TOPIC2 = "my-topic-2"; + public static final String ADDITIONAL_PROPS = "{\"security.protocol\": \"SASL_PLAINTEXT\"," + + "\"sasl.mechanism\": \"SCRAM-SHA-512\",\"sasl.jaas.config\": " + + "\"org.apache.kafka.common.security.plain.PlainLoginModule " + + "required username=abc password=abc serviceName=kafka;\"}"; + + private final TopicParameters params = new TopicParameters(); + + /** + * Constructs the object. + * + * @param prefix the prefix for the properties to be built + */ + public KafkaTopicPropertyBuilder(String prefix) { + super(prefix); + } + + /** + * Adds a topic and configures it's properties with default values. + * + * @param topic the topic to be added + * @return this builder + */ + public KafkaTopicPropertyBuilder makeTopic(String topic) { + addTopic(topic); + + setTopicProperty(PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX, MY_EFFECTIVE_TOPIC); + setTopicProperty(PROPERTY_MANAGED_SUFFIX, "true"); + setTopicProperty(PROPERTY_HTTP_HTTPS_SUFFIX, "true"); + setTopicProperty(PROPERTY_TOPIC_SINK_PARTITION_KEY_SUFFIX, MY_PARTITION); + setTopicProperty(PROPERTY_TOPIC_SERVERS_SUFFIX, SERVER); + setTopicProperty(".additionalProps", ADDITIONAL_PROPS); + + params.setTopicCommInfrastructure("kafka"); + params.setTopic(topic); + params.setEffectiveTopic(MY_EFFECTIVE_TOPIC); + params.setManaged(true); + params.setUseHttps(true); + params.setPartitionId(MY_PARTITION); + params.setServers(List.of(SERVER)); + params.setAdditionalProps(getAdditionalProps()); + + return this; + } + + private Map getAdditionalProps() { + try { + return new ObjectMapper().readValue(ADDITIONAL_PROPS, Map.class); + } catch (JsonProcessingException e) { + return Collections.emptyMap(); + } + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSinkFactoryTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSinkFactoryTest.java new file mode 100644 index 00000000..62210361 --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSinkFactoryTest.java @@ -0,0 +1,200 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022, 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_KAFKA_SINK_TOPICS; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX; + +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.policy.common.message.bus.event.base.TopicPropertyBuilder; +import org.onap.policy.common.parameters.topic.BusTopicParams; + +class KafkaTopicSinkFactoryTest extends KafkaTopicFactoryTestBase { + + private SinkFactory factory; + public static final String KAFKA_SERVER = "localhost:9092"; + + /** + * Creates the object to be tested. + */ + @BeforeEach + @Override + public void setUp() { + super.setUp(); + + factory = new SinkFactory(); + } + + @AfterEach + public void tearDown() { + factory.destroy(); + } + + @Test + @Override + public void testBuildBusTopicParams() { + super.testBuildBusTopicParams(); + super.testBuildBusTopicParams_Ex(); + } + + @Test + @Override + public void testBuildListOfStringString() { + super.testBuildListOfStringString(); + + // check parameters that were used + BusTopicParams params = getLastParams(); + assertFalse(params.isAllowSelfSignedCerts()); + } + + @Test + @Override + public void testBuildProperties() { + List topics = buildTopics(makePropBuilder().makeTopic(MY_TOPIC).build()); + assertEquals(1, topics.size()); + assertEquals(MY_TOPIC, topics.get(0).getTopic()); + assertEquals(MY_EFFECTIVE_TOPIC, topics.get(0).getEffectiveTopic()); + + BusTopicParams params = getLastParams(); + assertTrue(params.isManaged()); + assertFalse(params.isUseHttps()); + assertEquals(List.of(KAFKA_SERVER), params.getServers()); + assertEquals(MY_TOPIC, params.getTopic()); + assertEquals(MY_EFFECTIVE_TOPIC, params.getEffectiveTopic()); + assertEquals(MY_PARTITION, params.getPartitionId()); + assertNotNull(params.getAdditionalProps()); + + List topics2 = buildTopics(makePropBuilder().makeTopic(TOPIC3) + .removeTopicProperty(PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX).build()); + assertEquals(1, topics2.size()); + assertEquals(TOPIC3, topics2.get(0).getTopic()); + assertEquals(topics2.get(0).getTopic(), topics2.get(0).getEffectiveTopic()); + + initFactory(); + + assertEquals(1, buildTopics(makePropBuilder().makeTopic(MY_TOPIC).build()).size()); + } + + @Test + void testBuildFromProperties() { + Properties props = makePropBuilder().makeTopic(MY_TOPIC).build(); + var listTopic = factory.build(props); + assertNotNull(listTopic); + } + + @Test + @Override + public void testDestroyString_testGet_testInventory() { + super.testDestroyString_testGet_testInventory(); + super.testDestroyString_Ex(); + } + + @Test + @Override + public void testDestroy() { + super.testDestroy(); + } + + @Test + void testGet() { + super.testGet_Ex(); + } + + @Test + void testToString() { + assertTrue(factory.toString().startsWith("IndexedKafkaTopicSinkFactory [")); + } + + @Override + protected void initFactory() { + if (factory != null) { + factory.destroy(); + } + + factory = new SinkFactory(); + } + + @Override + protected List buildTopics(Properties properties) { + return factory.build(properties); + } + + @Override + protected KafkaTopicSink buildTopic(BusTopicParams params) { + return factory.build(params); + } + + @Override + protected KafkaTopicSink buildTopic(List servers, String topic) { + return factory.build(servers, topic); + } + + @Override + protected void destroyFactory() { + factory.destroy(); + } + + @Override + protected void destroyTopic(String topic) { + factory.destroy(topic); + } + + @Override + protected List getInventory() { + return factory.inventory(); + } + + @Override + protected KafkaTopicSink getTopic(String topic) { + return factory.get(topic); + } + + @Override + protected BusTopicParams getLastParams() { + return factory.params.getLast(); + } + + @Override + protected TopicPropertyBuilder makePropBuilder() { + return new KafkaTopicPropertyBuilder(PROPERTY_KAFKA_SINK_TOPICS); + } + + /** + * Factory that records the parameters of all the sinks it creates. + */ + private static class SinkFactory extends IndexedKafkaTopicSinkFactory { + private Deque params = new LinkedList<>(); + + @Override + protected KafkaTopicSink makeSink(BusTopicParams busTopicParams) { + params.add(busTopicParams); + return super.makeSink(busTopicParams); + } + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSinkTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSinkTest.java new file mode 100644 index 00000000..8818a27f --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSinkTest.java @@ -0,0 +1,34 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Engine - Common Modules + * ================================================================================ + * Copyright (C) 2022, 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.Test; + +class KafkaTopicSinkTest { + + @Test + void test() { + assertNotNull(KafkaTopicFactories.getSinkFactory()); + } + +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSourceFactoryTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSourceFactoryTest.java new file mode 100644 index 00000000..c91e548b --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSourceFactoryTest.java @@ -0,0 +1,168 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Engine - Common Modules + * ================================================================================ + * Copyright (C) 2022-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_KAFKA_SOURCE_TOPICS; + +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.policy.common.message.bus.event.base.TopicPropertyBuilder; +import org.onap.policy.common.parameters.topic.BusTopicParams; + +class KafkaTopicSourceFactoryTest extends KafkaTopicFactoryTestBase { + + private SourceFactory factory; + + public static final String KAFKA_SERVER = "localhost:9092"; + + /** + * Creates the object to be tested. + */ + @BeforeEach + @Override + public void setUp() { + super.setUp(); + + factory = new SourceFactory(); + } + + @AfterEach + public void tearDown() { + factory.destroy(); + } + + @Test + @Override + public void testBuildProperties() { + + initFactory(); + + List topics = buildTopics(makePropBuilder().makeTopic(MY_TOPIC).build()); + assertEquals(1, topics.size()); + assertEquals(MY_TOPIC, topics.get(0).getTopic()); + assertEquals(MY_EFFECTIVE_TOPIC, topics.get(0).getEffectiveTopic()); + + BusTopicParams params = getLastParams(); + assertTrue(params.isManaged()); + assertFalse(params.isUseHttps()); + assertEquals(List.of(KAFKA_SERVER), params.getServers()); + assertEquals(MY_TOPIC, params.getTopic()); + assertEquals(MY_EFFECTIVE_TOPIC, params.getEffectiveTopic()); + } + + @Test + @Override + public void testDestroyString_testGet_testInventory() { + super.testDestroyString_testGet_testInventory(); + super.testDestroyString_Ex(); + } + + @Test + @Override + public void testDestroy() { + super.testDestroy(); + } + + @Test + void testGet() { + super.testGet_Ex(); + } + + @Test + void testToString() { + assertTrue(factory.toString().startsWith("IndexedKafkaTopicSourceFactory [")); + } + + @Override + protected void initFactory() { + if (factory != null) { + factory.destroy(); + } + + factory = new SourceFactory(); + } + + @Override + protected List buildTopics(Properties properties) { + return factory.build(properties); + } + + @Override + protected KafkaTopicSource buildTopic(BusTopicParams params) { + return factory.build(params); + } + + @Override + protected KafkaTopicSource buildTopic(List servers, String topic) { + return factory.build(servers, topic); + } + + @Override + protected void destroyFactory() { + factory.destroy(); + } + + @Override + protected void destroyTopic(String topic) { + factory.destroy(topic); + } + + @Override + protected List getInventory() { + return factory.inventory(); + } + + @Override + protected KafkaTopicSource getTopic(String topic) { + return factory.get(topic); + } + + @Override + protected BusTopicParams getLastParams() { + return factory.params.getLast(); + } + + @Override + protected TopicPropertyBuilder makePropBuilder() { + return new KafkaTopicPropertyBuilder(PROPERTY_KAFKA_SOURCE_TOPICS); + } + + /** + * Factory that records the parameters of all the sources it creates. + */ + private static class SourceFactory extends IndexedKafkaTopicSourceFactory { + private final Deque params = new LinkedList<>(); + + @Override + protected KafkaTopicSource makeSource(BusTopicParams busTopicParams) { + params.add(busTopicParams); + return super.makeSource(busTopicParams); + } + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSourceTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSourceTest.java new file mode 100644 index 00000000..5572bc01 --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/KafkaTopicSourceTest.java @@ -0,0 +1,34 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Engine - Common Modules + * ================================================================================ + * Copyright (C) 2022-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.Test; + +class KafkaTopicSourceTest { + + @Test + void verifyKafkaTopicFactoriesNotNull() { + assertNotNull(KafkaTopicFactories.getSourceFactory()); + } + +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/SingleThreadedKafkaTopicSourceTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/SingleThreadedKafkaTopicSourceTest.java new file mode 100644 index 00000000..0c732ba7 --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/kafka/SingleThreadedKafkaTopicSourceTest.java @@ -0,0 +1,61 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.kafka; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.base.TopicTestBase; + +class SingleThreadedKafkaTopicSourceTest extends TopicTestBase { + private SingleThreadedKafkaTopicSource source; + + /** + * Creates the object to be tested. + */ + @BeforeEach + @Override + public void setUp() { + super.setUp(); + + source = new SingleThreadedKafkaTopicSource(makeKafkaBuilder().build()); + } + + @AfterEach + public void tearDown() { + source.shutdown(); + } + + @Test + void testToString() { + assertTrue(source.toString().startsWith("SingleThreadedKafkaTopicSource [")); + source.shutdown(); + } + + @Test + void testGetTopicCommInfrastructure() { + assertEquals(CommInfrastructure.KAFKA, source.getTopicCommInfrastructure()); + } + +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicEndpointTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicEndpointTest.java new file mode 100644 index 00000000..3ebec83c --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicEndpointTest.java @@ -0,0 +1,121 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.noop; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import java.util.Arrays; +import java.util.Collections; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.TopicListener; +import org.onap.policy.common.message.bus.event.base.TopicTestBase; + +public abstract class NoopTopicEndpointTest, T extends NoopTopicEndpoint> + extends TopicTestBase { + + protected final F factory; + protected T endpoint; + + public NoopTopicEndpointTest(F factory) { + this.factory = factory; + } + + protected abstract boolean io(String message); + + @BeforeEach + @Override + public void setUp() { + super.setUp(); + this.endpoint = this.factory.build(servers, MY_TOPIC); + } + + @Test + void testIo() { + TopicListener listener = mock(TopicListener.class); + this.endpoint.register(listener); + this.endpoint.start(); + + assertTrue(io(MY_MESSAGE)); + assertSame(MY_MESSAGE, this.endpoint.getRecentEvents()[0]); + assertEquals(Collections.singletonList(MY_MESSAGE), Arrays.asList(this.endpoint.getRecentEvents())); + verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE); + + this.endpoint.unregister(listener); + } + + @Test + void testIoNullMessage() { + assertThatThrownBy(() -> io(null)).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void testIoEmptyMessage() { + assertThatThrownBy(() -> io("")).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void testOfferNotStarted() { + assertThatThrownBy(() -> io(MY_MESSAGE)).isInstanceOf(IllegalStateException.class); + } + + @Test + void testGetTopicCommInfrastructure() { + assertEquals(CommInfrastructure.NOOP, this.endpoint.getTopicCommInfrastructure()); + } + + @Test + void testStart_testStop_testShutdown() { + this.endpoint.start(); + assertTrue(this.endpoint.isAlive()); + + // start again + this.endpoint.start(); + assertTrue(this.endpoint.isAlive()); + + // stop + this.endpoint.stop(); + assertFalse(this.endpoint.isAlive()); + + // re-start again + this.endpoint.start(); + assertTrue(this.endpoint.isAlive()); + + // shutdown + this.endpoint.shutdown(); + assertFalse(this.endpoint.isAlive()); + } + + @Test + void testStart_Locked() { + this.endpoint.lock(); + assertThatThrownBy(() -> this.endpoint.start()).isInstanceOf(IllegalStateException.class); + } + +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicFactoryTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicFactoryTest.java new file mode 100644 index 00000000..4dcba86e --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicFactoryTest.java @@ -0,0 +1,257 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.noop; + +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_MANAGED_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_TOPIC_SERVERS_SUFFIX; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Properties; +import org.apache.commons.lang3.RandomStringUtils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.base.TopicFactoryTestBase; +import org.onap.policy.common.message.bus.event.base.TopicPropertyBuilder; +import org.onap.policy.common.message.bus.event.base.TopicTestBase; +import org.onap.policy.common.parameters.topic.BusTopicParams; + +public abstract class NoopTopicFactoryTest, T extends NoopTopicEndpoint> + extends TopicFactoryTestBase { + + private static final List NOOP_SERVERS = List.of(CommInfrastructure.NOOP.toString()); + private F factory = null; + + protected abstract F buildFactory(); + + /** + * Creates the object to be tested. + */ + @BeforeEach + @Override + public void setUp() { + super.setUp(); + initFactory(); + } + + @AfterEach + void tearDown() { + factory.destroy(); + } + + @Test + void testBuildBusTopicParams() { + initFactory(); + + T item1 = buildTopic(makeParams(servers)); + assertNotNull(item1); + + assertEquals(servers, item1.getServers()); + assertEquals(MY_TOPIC, item1.getTopic()); + } + + @Test + void testBuildListOfStringStringBoolean() { + initFactory(); + + T item1 = buildTopic(servers, MY_TOPIC, true); + assertNotNull(item1); + + assertEquals(servers, item1.getServers()); + assertEquals(MY_TOPIC, item1.getTopic()); + + // managed topic - should not build a new one + assertEquals(item1, buildTopic(servers, MY_TOPIC, true)); + + T item2 = buildTopic(servers, TOPIC2, true); + assertNotNull(item2); + assertNotSame(item1, item2); + + // duplicate - should be the same, as these topics are managed + List randomServers = new ArrayList<>(); + randomServers.add(RandomStringUtils.randomAlphanumeric(8)); + T item3 = buildTopic(randomServers, TOPIC2, true); + assertSame(item2, item3); + + T item4 = buildTopic(Collections.emptyList(), TOPIC2, true); + assertSame(item3, item4); + + // null server list + initFactory(); + assertEquals(NOOP_SERVERS, buildTopic(null, MY_TOPIC, true).getServers()); + + // empty server list + initFactory(); + assertEquals(NOOP_SERVERS, buildTopic(Collections.emptyList(), MY_TOPIC, true).getServers()); + + // unmanaged topic + initFactory(); + item1 = buildTopic(servers, MY_TOPIC, false); + assertNotSame(item1, buildTopic(servers, MY_TOPIC, false)); + } + + @Test + void testBuildListOfStringStringBoolean_NullTopic() { + assertThatThrownBy(() -> buildTopic(servers, null, true)).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void testBuildListOfStringStringBoolean_EmptyTopic() { + assertThatThrownBy(() -> buildTopic(servers, "", true)).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void testBuildProperties() { + // managed topic + initFactory(); + assertEquals(1, buildTopics(makePropBuilder().makeTopic(MY_TOPIC).build()).size()); + assertNotNull(factory.get(MY_TOPIC)); + + // unmanaged topic - get() will throw an exception + initFactory(); + assertEquals(1, buildTopics(makePropBuilder().makeTopic(MY_TOPIC) + .setTopicProperty(PROPERTY_MANAGED_SUFFIX, "false").build()).size()); + assertThatIllegalStateException().isThrownBy(() -> factory.get(MY_TOPIC)); + + // managed undefined - default to true + initFactory(); + assertEquals(1, buildTopics( + makePropBuilder().makeTopic(MY_TOPIC).removeTopicProperty(PROPERTY_MANAGED_SUFFIX).build()) + .size()); + assertNotNull(factory.get(MY_TOPIC)); + + // managed empty - default to true + initFactory(); + assertEquals(1, buildTopics( + makePropBuilder().makeTopic(MY_TOPIC).setTopicProperty(PROPERTY_MANAGED_SUFFIX, "").build()) + .size()); + assertNotNull(factory.get(MY_TOPIC)); + + initFactory(); + + // null topic list + assertTrue(buildTopics(makePropBuilder().build()).isEmpty()); + + // empty topic list + assertTrue(buildTopics(makePropBuilder().addTopic("").build()).isEmpty()); + + // null server list + initFactory(); + T endpoint = buildTopics(makePropBuilder().makeTopic(MY_TOPIC) + .removeTopicProperty(PROPERTY_TOPIC_SERVERS_SUFFIX).build()).get(0); + assertEquals(NOOP_SERVERS, endpoint.getServers()); + + // empty server list + initFactory(); + endpoint = buildTopics(makePropBuilder().makeTopic(MY_TOPIC).setTopicProperty(PROPERTY_TOPIC_SERVERS_SUFFIX, "") + .build()).get(0); + assertEquals(NOOP_SERVERS, endpoint.getServers()); + + // test other options + super.testBuildProperties_Multiple(); + } + + @Test + @Override + public void testDestroyString_testGet_testInventory() { + super.testDestroyString_testGet_testInventory(); + super.testDestroyString_Ex(); + } + + @Test + @Override + public void testDestroy() { + super.testDestroy(); + } + + @Test + void testGet() { + super.testGet_Ex(); + } + + @Override + protected void initFactory() { + if (factory != null) { + factory.destroy(); + } + + factory = buildFactory(); + } + + @Override + protected List buildTopics(Properties properties) { + return factory.build(properties); + } + + protected T buildTopic(BusTopicParams param) { + return factory.build(param); + } + + protected T buildTopic(List servers, String topic, boolean managed) { + return factory.build(servers, topic, managed); + } + + @Override + protected void destroyFactory() { + factory.destroy(); + } + + @Override + protected void destroyTopic(String topic) { + factory.destroy(topic); + } + + @Override + protected List getInventory() { + return factory.inventory(); + } + + @Override + protected T getTopic(String topic) { + return factory.get(topic); + } + + @Override + protected TopicPropertyBuilder makePropBuilder() { + return new NoopTopicPropertyBuilder(factory.getTopicsPropertyName()); + } + + private BusTopicParams makeParams(List servers) { + BusTopicParams params = new BusTopicParams(); + + params.setServers(servers); + params.setTopic(TopicTestBase.MY_TOPIC); + params.setManaged(true); + + return params; + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicPropertyBuilder.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicPropertyBuilder.java new file mode 100644 index 00000000..57b78435 --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicPropertyBuilder.java @@ -0,0 +1,77 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2018-2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.noop; + +import static org.onap.policy.common.message.bus.event.base.TopicTestBase.MY_EFFECTIVE_TOPIC; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_ALLOW_SELF_SIGNED_CERTIFICATES_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_HTTP_HTTPS_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_MANAGED_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX; +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_TOPIC_SERVERS_SUFFIX; + +import java.util.List; +import lombok.Getter; +import org.onap.policy.common.message.bus.event.base.TopicPropertyBuilder; +import org.onap.policy.common.parameters.topic.TopicParameters; + +@Getter +public class NoopTopicPropertyBuilder extends TopicPropertyBuilder { + + public static final String SERVER = "my-server"; + + private final TopicParameters params = new TopicParameters(); + + /** + * Constructs the object. + * + * @param prefix the prefix for the properties to be built + */ + public NoopTopicPropertyBuilder(String prefix) { + super(prefix); + } + + /** + * Adds a topic and configures it's properties with default values. + * + * @param topic the topic to be added + * @return this builder + */ + public NoopTopicPropertyBuilder makeTopic(String topic) { + addTopic(topic); + + setTopicProperty(PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX, MY_EFFECTIVE_TOPIC); + setTopicProperty(PROPERTY_MANAGED_SUFFIX, "true"); + setTopicProperty(PROPERTY_HTTP_HTTPS_SUFFIX, "true"); + setTopicProperty(PROPERTY_ALLOW_SELF_SIGNED_CERTIFICATES_SUFFIX, "true"); + setTopicProperty(PROPERTY_TOPIC_SERVERS_SUFFIX, SERVER); + + params.setTopicCommInfrastructure("noop"); + params.setTopic(topic); + params.setEffectiveTopic(MY_EFFECTIVE_TOPIC); + params.setManaged(true); + params.setUseHttps(true); + params.setAllowSelfSignedCerts(true); + params.setServers(List.of(SERVER)); + + return this; + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSinkFactoryTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSinkFactoryTest.java new file mode 100644 index 00000000..ecd4df1e --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSinkFactoryTest.java @@ -0,0 +1,39 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2018-2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.noop; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class NoopTopicSinkFactoryTest extends NoopTopicFactoryTest { + + @Override + protected NoopTopicSinkFactory buildFactory() { + return new NoopTopicSinkFactory(); + } + + @Test + void testToString() { + assertTrue(new NoopTopicSinkFactory().toString().startsWith("NoopTopicSinkFactory [")); + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSinkTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSinkTest.java new file mode 100644 index 00000000..ecba379f --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSinkTest.java @@ -0,0 +1,58 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.noop; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.Test; + +class NoopTopicSinkTest extends NoopTopicEndpointTest { + + public NoopTopicSinkTest() { + super(new NoopTopicSinkFactory()); + } + + @Override + protected boolean io(String message) { + return endpoint.send(message); + } + + @Test + void testToString() { + assertThat(endpoint.toString()).startsWith("NoopTopicSink"); + } + + @Test + void testSend() { + NoopTopicSink sink = new NoopTopicSink(servers, MY_TOPIC) { + @Override + protected boolean broadcast(String message) { + throw new RuntimeException(EXPECTED); + } + + }; + + sink.start(); + assertFalse(sink.send(MY_MESSAGE)); + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSourceFactoryTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSourceFactoryTest.java new file mode 100644 index 00000000..c9038068 --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSourceFactoryTest.java @@ -0,0 +1,39 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.noop; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class NoopTopicSourceFactoryTest extends NoopTopicFactoryTest { + + @Override + protected NoopTopicSourceFactory buildFactory() { + return new NoopTopicSourceFactory(); + } + + @Test + void testToString() { + assertTrue(new NoopTopicSourceFactory().toString().startsWith("NoopTopicSourceFactory [")); + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSourceTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSourceTest.java new file mode 100644 index 00000000..51ff109b --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/event/noop/NoopTopicSourceTest.java @@ -0,0 +1,56 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.event.noop; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class NoopTopicSourceTest extends NoopTopicEndpointTest { + + public NoopTopicSourceTest() { + super(new NoopTopicSourceFactory()); + } + + @Override + protected boolean io(String message) { + return this.endpoint.offer(message); + } + + @Test + void testToString() { + assertTrue(this.endpoint.toString().startsWith("NoopTopicSource")); + } + + @Test + void testOffer() { + NoopTopicSource source = new NoopTopicSource(servers, MY_TOPIC) { + @Override + protected boolean broadcast(String message) { + throw new RuntimeException(EXPECTED); + } + + }; + + source.start(); + assertFalse(source.offer(MY_MESSAGE)); + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/features/NetLoggerFeatureApiTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/features/NetLoggerFeatureApiTest.java new file mode 100644 index 00000000..776c5d57 --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/features/NetLoggerFeatureApiTest.java @@ -0,0 +1,86 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.features; + +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.utils.NetLoggerUtil.EventType; +import org.slf4j.Logger; + +@ExtendWith(MockitoExtension.class) +class NetLoggerFeatureApiTest { + + @Mock + private Logger mockLogger; + + @Mock + private EventType mockEventType; + + @Mock + private CommInfrastructure mockCommInfrastructure; + + private NetLoggerFeatureApi featureApi; + + @BeforeEach + public void setUp() { + featureApi = new NetLoggerFeatureApi() { + @Override + public boolean beforeLog(Logger eventLogger, EventType type, CommInfrastructure protocol, String topic, + String message) { + return NetLoggerFeatureApi.super.beforeLog(eventLogger, type, protocol, topic, message); + } + + @Override + public boolean afterLog(Logger eventLogger, EventType type, CommInfrastructure protocol, String topic, + String message) { + return NetLoggerFeatureApi.super.afterLog(eventLogger, type, protocol, topic, message); + } + + @Override + public int getSequenceNumber() { + return 0; + } + + @Override + public String getName() { + return NetLoggerFeatureApi.super.getName(); + } + }; + } + + @Test + void testBeforeLogDefaultBehavior() { + boolean result = featureApi.beforeLog(mockLogger, mockEventType, mockCommInfrastructure, + "testTopic", "testMessage"); + assertFalse(result, "Expected beforeLog to return false by default"); + } + + @Test + void testAfterLogDefaultBehavior() { + boolean result = featureApi.afterLog(mockLogger, mockEventType, mockCommInfrastructure, + "testTopic", "testMessage"); + assertFalse(result, "Expected afterLog to return false by default"); + } +} diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/utils/KafkaPropertyUtilsTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/utils/KafkaPropertyUtilsTest.java new file mode 100644 index 00000000..55f6a69f --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/utils/KafkaPropertyUtilsTest.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.utils; + +import static org.onap.policy.common.message.bus.properties.MessageBusProperties.PROPERTY_ADDITIONAL_PROPS_SUFFIX; + +import java.util.Properties; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.onap.policy.common.utils.properties.PropertyUtils; + +class KafkaPropertyUtilsTest { + + @Test + void test() { + var properties = new Properties(); + properties.setProperty("mytopic" + PROPERTY_ADDITIONAL_PROPS_SUFFIX, "{444-"); + PropertyUtils props = new PropertyUtils(properties, "mytopic", null); + + var build = KafkaPropertyUtils.makeBuilder(props, "mytopic", "servers").build(); + Assertions.assertTrue(build.getAdditionalProps().isEmpty()); + + properties.setProperty("mytopic" + PROPERTY_ADDITIONAL_PROPS_SUFFIX, + "{\"security.protocol\": \"SASL_PLAINTEXT\"}"); + build = KafkaPropertyUtils.makeBuilder(props, "mytopic", "servers").build(); + Assertions.assertTrue(build.getAdditionalProps().containsKey("security.protocol")); + + properties.setProperty("mytopic" + PROPERTY_ADDITIONAL_PROPS_SUFFIX, + "{\"security.protocol\": false }"); + build = KafkaPropertyUtils.makeBuilder(props, "mytopic", "servers").build(); + Assertions.assertTrue(build.getAdditionalProps().isEmpty()); + + properties.setProperty("mytopic" + PROPERTY_ADDITIONAL_PROPS_SUFFIX, ""); + build = KafkaPropertyUtils.makeBuilder(props, "mytopic", "servers").build(); + Assertions.assertTrue(build.getAdditionalProps().isEmpty()); + } + +} \ No newline at end of file diff --git a/message-bus/src/test/java/org/onap/policy/common/message/bus/utils/NetLoggerUtilTest.java b/message-bus/src/test/java/org/onap/policy/common/message/bus/utils/NetLoggerUtilTest.java new file mode 100644 index 00000000..df621f5b --- /dev/null +++ b/message-bus/src/test/java/org/onap/policy/common/message/bus/utils/NetLoggerUtilTest.java @@ -0,0 +1,269 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.message.bus.utils; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.AppenderBase; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.features.NetLoggerFeatureApi; +import org.onap.policy.common.message.bus.features.NetLoggerFeatureProviders; +import org.onap.policy.common.message.bus.utils.NetLoggerUtil.EventType; +import org.slf4j.Logger; + +/** + * Test class for network log utilities such as logging and feature invocation. + */ +class NetLoggerUtilTest { + + private static final String TEST_TOPIC = "test-topic"; + private static final String MESSAGE = "hello world!"; + /** + * Test feature used for junits. + */ + private static NetLoggerFeature netLoggerFeature; + + /** + * Obtains the test implementation of NetLoggerFeatureApi. + */ + @BeforeAll + public static void setUp() { + netLoggerFeature = (NetLoggerFeature) NetLoggerFeatureProviders.getProviders().getList().get(0); + } + + /** + * Clears events list and resets return/exceptions flags before invoking every unit test. + */ + @BeforeEach + public void reset() { + TestAppender.clear(); + netLoggerFeature.setReturnValue(false, false); + netLoggerFeature.setExceptions(false, false); + } + + /** + * Tests obtaining the network logger instance. + */ + @Test + void getNetworkLoggerTest() { + assertEquals("network", NetLoggerUtil.getNetworkLogger().getName()); + } + + /** + * Tests logging a message to the network logger and invoking features before/after logging. + */ + @Test + void logTest() { + NetLoggerUtil.log(EventType.IN, CommInfrastructure.NOOP, TEST_TOPIC, MESSAGE); + assertEquals(3, TestAppender.events.size()); + } + + /** + * Tests that the network logger is used to log messages if a logger is not passed in. + */ + @Test + void logDefaultTest() { + NetLoggerUtil.log(null, EventType.IN, CommInfrastructure.NOOP, TEST_TOPIC, MESSAGE); + assertEquals(3, TestAppender.events.size()); + assertEquals("network", TestAppender.events.get(0).getLoggerName()); + } + + /** + * Tests a NetLoggerFeature that replaces base implementation before logging. + */ + @Test + void beforeLogReturnTrueTest() { + netLoggerFeature.setReturnValue(true, false); + NetLoggerUtil.log(null, EventType.IN, CommInfrastructure.NOOP, TEST_TOPIC, MESSAGE); + assertEquals(1, TestAppender.events.size()); + } + + /** + * Tests a NetLoggerFeature that post processes a logged message. + */ + @Test + void afterLogReturnTrueTest() { + netLoggerFeature.setReturnValue(false, true); + NetLoggerUtil.log(null, EventType.IN, CommInfrastructure.NOOP, TEST_TOPIC, MESSAGE); + assertEquals(3, TestAppender.events.size()); + } + + /** + * Tests throwing an exception in the before hook. + */ + @Test + void beforeLogExceptionTest() { + netLoggerFeature.setExceptions(true, false); + NetLoggerUtil.log(null, EventType.IN, CommInfrastructure.NOOP, TEST_TOPIC, MESSAGE); + assertEquals(2, TestAppender.events.size()); + } + + /** + * Tests throwing an exception in the after hook. + */ + @Test + void afterLogExceptionTest() { + netLoggerFeature.setExceptions(false, true); + NetLoggerUtil.log(null, EventType.IN, CommInfrastructure.NOOP, TEST_TOPIC, MESSAGE); + assertEquals(2, TestAppender.events.size()); + } + + /** + * A custom list appender to track messages being logged to the network logger. + * NOTE: Check src/test/resources/logback-test.xml for network logger configurations. + */ + public static class TestAppender extends AppenderBase { + + /** + * List of logged events. + */ + private static final List events = new ArrayList<>(); + + /** + * Called after every unit test to clear list of events. + */ + public static void clear() { + events.clear(); + } + + /** + * Appends each event to the event list. + */ + @Override + protected void append(ILoggingEvent event) { + events.add(event); + } + + } + + /** + * Test implementation of NetLoggerFeatureApi to be used by junits. + */ + public static class NetLoggerFeature implements NetLoggerFeatureApi { + + /** + * Used for setting the return values of before/after hooks. + */ + private boolean beforeReturn = false; + private boolean afterReturn = false; + + /** + * Used for throwing an exception in the before/after hooks. + */ + private boolean beforeException = false; + private boolean afterException = false; + + + /** + * Gets sequence number. + */ + @Override + public int getSequenceNumber() { + return 0; + } + + /** + * Get beforeLog return value. + */ + public boolean getBeforeReturn() { + return this.beforeReturn; + } + + /** + * Get afterLog return value. + */ + public boolean getAfterReturn() { + return this.afterReturn; + } + + /** + * Sets the return value for the before/after hooks. + * + * @param beforeVal beforeLog() return value + * @param afterVal afterLog() return value + */ + public void setReturnValue(boolean beforeVal, boolean afterVal) { + this.beforeReturn = beforeVal; + this.afterReturn = afterVal; + } + + /** + * Gets beforeException boolean. + */ + public boolean getBeforeException() { + return this.beforeException; + } + + /** + * Gets afterException boolean. + */ + public boolean getAfterException() { + return this.afterException; + } + + /** + * Sets before/after flags to determine if the feature should throw an exception. + */ + public void setExceptions(boolean beforeException, boolean afterException) { + this.beforeException = beforeException; + this.afterException = afterException; + } + + /** + * Simple beforeLog message. + */ + @Override + public boolean beforeLog(Logger eventLogger, EventType type, CommInfrastructure protocol, String topic, + String message) { + + if (beforeException) { + throw new RuntimeException("beforeLog exception"); + } + + eventLogger.info("before feature test"); + + return this.beforeReturn; + } + + /** + * Simple afterLog message. + */ + @Override + public boolean afterLog(Logger eventLogger, EventType type, CommInfrastructure protocol, String topic, + String message) { + + if (afterException) { + throw new RuntimeException("afterLog exception"); + } + + eventLogger.info("after feature test"); + + return this.afterReturn; + } + + } + +} diff --git a/message-bus/src/test/resources/META-INF/services/org.onap.policy.common.message.bus.features.NetLoggerFeatureApi b/message-bus/src/test/resources/META-INF/services/org.onap.policy.common.message.bus.features.NetLoggerFeatureApi new file mode 100644 index 00000000..7889cb8f --- /dev/null +++ b/message-bus/src/test/resources/META-INF/services/org.onap.policy.common.message.bus.features.NetLoggerFeatureApi @@ -0,0 +1 @@ +org.onap.policy.common.message.bus.utils.NetLoggerUtilTest$NetLoggerFeature \ No newline at end of file diff --git a/message-bus/src/test/resources/logback-test.xml b/message-bus/src/test/resources/logback-test.xml new file mode 100644 index 00000000..ddf4f8bb --- /dev/null +++ b/message-bus/src/test/resources/logback-test.xml @@ -0,0 +1,42 @@ + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}.%M\(%line\) - %msg%n + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/message-bus/src/test/resources/org/onap/policy/common/message/bus/event/TopicEndpointProxyTest.json b/message-bus/src/test/resources/org/onap/policy/common/message/bus/event/TopicEndpointProxyTest.json new file mode 100644 index 00000000..5b2e712a --- /dev/null +++ b/message-bus/src/test/resources/org/onap/policy/common/message/bus/event/TopicEndpointProxyTest.json @@ -0,0 +1,30 @@ +{ + "locked": false, + "alive": false, + "topicSources": [ + { + "servers": [ + "my-server" + ], + "topic": "noop-source", + "effectiveTopic": "noop-source", + "recentEvents": [], + "alive": false, + "locked": false, + "topicCommInfrastructure": "NOOP" + } + ], + "topicSinks": [ + { + "servers": [ + "my-server" + ], + "topic": "noop-sink", + "effectiveTopic": "noop-sink", + "recentEvents": [], + "alive": false, + "locked": false, + "topicCommInfrastructure": "NOOP" + } + ] +} diff --git a/message-bus/src/test/resources/org/onap/policy/common/message/bus/event/base/BusTopicBaseTest.json b/message-bus/src/test/resources/org/onap/policy/common/message/bus/event/base/BusTopicBaseTest.json new file mode 100644 index 00000000..462278a4 --- /dev/null +++ b/message-bus/src/test/resources/org/onap/policy/common/message/bus/event/base/BusTopicBaseTest.json @@ -0,0 +1,14 @@ +{ + "servers" : [ "svra", "svrb" ], + "topic" : "my-topic", + "effectiveTopic" : "my-effective-topic", + "recentEvents" : [ ], + "alive" : false, + "locked" : false, + "apiKey" : "my-api-key", + "apiSecret" : "my-api-secret", + "useHttps" : true, + "allowTracing": true, + "allowSelfSignedCerts" : true, + "topicCommInfrastructure" : "NOOP" +} diff --git a/message-bus/src/test/resources/org/onap/policy/common/message/bus/event/base/InlineBusTopicSinkTest.json b/message-bus/src/test/resources/org/onap/policy/common/message/bus/event/base/InlineBusTopicSinkTest.json new file mode 100644 index 00000000..1f2fb55f --- /dev/null +++ b/message-bus/src/test/resources/org/onap/policy/common/message/bus/event/base/InlineBusTopicSinkTest.json @@ -0,0 +1,15 @@ +{ + "servers" : [ "svra", "svrb" ], + "topic" : "my-topic", + "effectiveTopic" : "my-effective-topic", + "recentEvents" : [ ], + "alive" : false, + "locked" : false, + "apiKey" : "my-api-key", + "apiSecret" : "my-api-secret", + "useHttps" : true, + "allowTracing": true, + "allowSelfSignedCerts" : true, + "topicCommInfrastructure" : "NOOP", + "partitionKey" : "my-partition" +} diff --git a/message-bus/src/test/resources/org/onap/policy/common/message/bus/event/base/SingleThreadedBusTopicSourceTest.json b/message-bus/src/test/resources/org/onap/policy/common/message/bus/event/base/SingleThreadedBusTopicSourceTest.json new file mode 100644 index 00000000..305620c8 --- /dev/null +++ b/message-bus/src/test/resources/org/onap/policy/common/message/bus/event/base/SingleThreadedBusTopicSourceTest.json @@ -0,0 +1,18 @@ +{ + "servers" : [ "svra", "svrb" ], + "topic" : "my-topic", + "effectiveTopic" : "my-effective-topic", + "recentEvents" : [ ], + "alive" : false, + "locked" : false, + "apiKey" : "my-api-key", + "apiSecret" : "my-api-secret", + "useHttps" : true, + "allowTracing": true, + "allowSelfSignedCerts" : true, + "consumerGroup" : "my-cons-group", + "consumerInstance" : "my-cons-inst", + "fetchTimeout" : 101, + "fetchLimit" : 100, + "topicCommInfrastructure" : "NOOP" +} diff --git a/message-bus/src/test/resources/org/onap/policy/common/message/bus/event/base/TopicBaseTest.json b/message-bus/src/test/resources/org/onap/policy/common/message/bus/event/base/TopicBaseTest.json new file mode 100644 index 00000000..b72b4efd --- /dev/null +++ b/message-bus/src/test/resources/org/onap/policy/common/message/bus/event/base/TopicBaseTest.json @@ -0,0 +1,9 @@ +{ + "servers" : [ "svra", "svrb" ], + "topic" : "my-topic", + "effectiveTopic" : "my-topic", + "recentEvents" : [ ], + "alive" : false, + "locked" : false, + "topicCommInfrastructure" : "NOOP" +} diff --git a/message-bus/src/test/resources/org/onap/policy/common/message/bus/parameters/TopicParameters_all_params.json b/message-bus/src/test/resources/org/onap/policy/common/message/bus/parameters/TopicParameters_all_params.json new file mode 100644 index 00000000..89e464dd --- /dev/null +++ b/message-bus/src/test/resources/org/onap/policy/common/message/bus/parameters/TopicParameters_all_params.json @@ -0,0 +1,62 @@ +{ + "topicSources" : [ { + "topic" : "policy-pdp-pap1", + "servers" : [ "kafka2, kafka3" ], + "topicCommInfrastructure" : "kafka", + "effectiveTopic" : "my-effective-topic", + "apiKey" : "my-api-key", + "apiSecret" : "my-api-secret", + "port": 123, + "useHttps" : true, + "allowTracing": true, + "allowSelfSignedCerts" : true, + "consumerGroup" : "consumer group", + "consumerInstance" : "consumer instance", + "fetchTimeout" : 15000, + "fetchLimit" : 100, + "userName": "username", + "password": "password", + "managed": true, + "environment": "environment1", + "aftEnvironment": "aftEnvironment1", + "partner": "partner1", + "latitude": "1234", + "longitude": "1234", + "partitionId": "partition_id", + "additionalProps": {"xyz":"xyz"}, + "clientName": "clientName1", + "hostname": "hostname1", + "basePath": "basePath1", + "serializationProvider": "serializationProvider1" + }], + "topicSinks" : [ { + "topic" : "policy-pdp-pap1", + "servers" : [ "kafka2, kafka3" ], + "topicCommInfrastructure" : "kafka", + "effectiveTopic" : "my-effective-topic", + "apiKey" : "my-api-key", + "apiSecret" : "my-api-secret", + "port": 123, + "useHttps" : true, + "allowTracing": true, + "allowSelfSignedCerts" : true, + "consumerGroup" : "consumer group", + "consumerInstance" : "consumer instance", + "fetchTimeout" : 15000, + "fetchLimit" : 100, + "userName": "username", + "password": "password", + "managed": true, + "environment": "environment1", + "aftEnvironment": "aftEnvironment1", + "partner": "partner1", + "latitude": "1234", + "longitude": "1234", + "partitionId": "partition_id", + "additionalProps": {"xyz":"xyz"}, + "clientName": "clientName1", + "hostname": "hostname1", + "basePath": "basePath1", + "serializationProvider": "serializationProvider1" + }] +} \ No newline at end of file diff --git a/message-bus/src/test/resources/org/onap/policy/common/message/bus/parameters/TopicParameters_invalid.json b/message-bus/src/test/resources/org/onap/policy/common/message/bus/parameters/TopicParameters_invalid.json new file mode 100644 index 00000000..775b4886 --- /dev/null +++ b/message-bus/src/test/resources/org/onap/policy/common/message/bus/parameters/TopicParameters_invalid.json @@ -0,0 +1,6 @@ +{ + "topicSources" : [{ + "topic" : "ueb-source", + "servers" : ["my-server"] + }] +} \ No newline at end of file diff --git a/message-bus/src/test/resources/org/onap/policy/common/message/bus/parameters/TopicParameters_missing_mandatory.json b/message-bus/src/test/resources/org/onap/policy/common/message/bus/parameters/TopicParameters_missing_mandatory.json new file mode 100644 index 00000000..216c11ec --- /dev/null +++ b/message-bus/src/test/resources/org/onap/policy/common/message/bus/parameters/TopicParameters_missing_mandatory.json @@ -0,0 +1,12 @@ +{ + "topicSources" : [ { + "topic" : "policy-pdp-pap1", + "servers" : [], + "topicCommInfrastructure" : "kafka" + }], + "topicSinks" : [ { + "topic" : "policy-pdp-pap2", + "servers" : [ "kafka1, kafka2" ], + "topicCommInfrastructure" : "kafka" + }] +} \ No newline at end of file diff --git a/message-bus/src/test/resources/org/onap/policy/common/message/bus/parameters/TopicParameters_valid.json b/message-bus/src/test/resources/org/onap/policy/common/message/bus/parameters/TopicParameters_valid.json new file mode 100644 index 00000000..2603bfdc --- /dev/null +++ b/message-bus/src/test/resources/org/onap/policy/common/message/bus/parameters/TopicParameters_valid.json @@ -0,0 +1,30 @@ +{ + "topicSources" : [ { + "topic" : "ueb-source", + "servers" : [ "my-server" ], + "topicCommInfrastructure" : "ueb" + },{ + "topic" : "policy-pdp-pap1", + "servers" : [ "kafka1, kafka2" ], + "topicCommInfrastructure" : "kafka" + },{ + "topic" : "policy-pdp-pap2", + "servers" : [ "kafka2, kafka3" ], + "topicCommInfrastructure" : "kafka" + }], + "topicSinks" : [ { + "topic" : "ueb-sink", + "servers" : [ "my-server" ], + "topicCommInfrastructure" : "ueb" + },{ + "topic" : "policy-pdp-pap2", + "servers" : [ "kafka1, kafka2" ], + "topicCommInfrastructure" : "kafka" + },{ + "topic" : "policy-pdp-pap3", + "servers" : [ "kafka2, kafka3" ], + "topicCommInfrastructure" : "kafka", + "effectiveTopic":"effectiveTopic1", + "allowSelfSignedCerts":true + }] +} \ No newline at end of file diff --git a/policy-endpoints/pom.xml b/policy-endpoints/pom.xml index cacd36c8..4afcf020 100644 --- a/policy-endpoints/pom.xml +++ b/policy-endpoints/pom.xml @@ -53,28 +53,35 @@ org.onap.policy.common capabilities ${project.version} + provided org.onap.policy.common - gson + common-parameters ${project.version} + provided org.onap.policy.common - utils + gson ${project.version} provided org.onap.policy.common - common-parameters + message-bus ${project.version} org.onap.policy.common - utils-test + utils ${project.version} - test + provided + + + com.google.code.gson + gson + provided com.google.guava @@ -82,28 +89,27 @@ provided - org.glassfish.jaxb - jaxb-runtime + com.google.re2j + re2j provided - org.glassfish.jersey.containers - jersey-container-servlet-core + io.prometheus + simpleclient_hotspot - org.glassfish.jersey.core - jersey-server - ${version.jersey} + io.prometheus + simpleclient_servlet_jakarta - org.glassfish.jersey.inject - jersey-hk2 - ${version.jersey} + jakarta.ws.rs + jakarta.ws.rs-api provided - org.eclipse.jetty - jetty-servlet + org.apache.commons + commons-lang3 + provided org.eclipse.jetty @@ -114,47 +120,86 @@ jetty-server - org.apache.kafka - kafka-clients + org.eclipse.jetty + jetty-servlet + + + org.eclipse.jetty + jetty-util + + + org.eclipse.jetty.toolchain + jetty-jakarta-servlet-api + + + org.glassfish.jersey.containers + jersey-container-servlet-core + + + org.glassfish.jersey.core + jersey-client + + + org.glassfish.jersey.core + jersey-server + ${version.jersey} + + + org.projectlombok + lombok provided - org.apache.commons - commons-collections4 + org.slf4j + slf4j-api + provided - org.apache.commons - commons-jexl3 + org.yaml + snakeyaml provided - io.swagger.core.v3 - swagger-annotations - test + ch.qos.logback + logback-classic + provided - io.opentelemetry.instrumentation - opentelemetry-kafka-clients-2.6 + ch.qos.logback + logback-core + provided - io.swagger.core.v3 - swagger-jaxrs2-jakarta + org.glassfish.jaxb + jaxb-runtime + runtime + + + org.glassfish.jersey.inject + jersey-hk2 + ${version.jersey} + runtime + + + commons-io + commons-io provided io.swagger.core.v3 - swagger-jaxrs2-servlet-initializer-v2-jakarta + swagger-annotations provided - io.prometheus - simpleclient_hotspot + io.swagger.core.v3 + swagger-jaxrs2-jakarta provided - io.prometheus - simpleclient_servlet_jakarta - provided + org.onap.policy.common + utils-test + ${project.version} + test org.assertj @@ -163,7 +208,7 @@ org.mockito - mockito-junit-jupiter + mockito-core test diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/Topic.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/Topic.java deleted file mode 100644 index ce8e2387..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/Topic.java +++ /dev/null @@ -1,90 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2017-2020 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2019 Samsung Electronics Co., Ltd. - * Copyright (C) 2022,2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm; - -import java.util.List; -import org.onap.policy.common.capabilities.Lockable; -import org.onap.policy.common.capabilities.Startable; - - -/** - * Essential Topic Data. - */ -public interface Topic extends TopicRegisterable, Startable, Lockable { - - /** - * Underlying Communication infrastructure Types. - */ - enum CommInfrastructure { - /** - * KAFKA Communication Infrastructure. - */ - KAFKA, - /** - * NOOP for internal use only. - */ - NOOP, - /** - * REST Communication Infrastructure. - */ - REST - } - - /** - * Gets the canonical topic name. - * - * @return topic name - */ - String getTopic(); - - /** - * Gets the effective topic that is used in - * the network communication. This name is usually - * the topic name. - * - * @return topic name alias - */ - String getEffectiveTopic(); - - /** - * Gets the communication infrastructure type. - * - * @return CommInfrastructure object - */ - CommInfrastructure getTopicCommInfrastructure(); - - /** - * Return list of servers. - * - * @return bus servers - */ - List getServers(); - - /** - * Get the more recent events in this topic entity. - * - * @return list of most recent events - */ - String[] getRecentEvents(); - -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicEndpoint.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicEndpoint.java deleted file mode 100644 index bf261def..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicEndpoint.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. - * Copyright (C) 2022,2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm; - -import java.util.List; -import java.util.Properties; -import org.onap.policy.common.capabilities.Lockable; -import org.onap.policy.common.capabilities.Startable; -import org.onap.policy.common.endpoints.event.comm.bus.KafkaTopicSink; -import org.onap.policy.common.endpoints.event.comm.bus.KafkaTopicSource; -import org.onap.policy.common.endpoints.event.comm.bus.NoopTopicSink; -import org.onap.policy.common.endpoints.event.comm.bus.NoopTopicSource; -import org.onap.policy.common.endpoints.parameters.TopicParameterGroup; -import org.onap.policy.common.endpoints.parameters.TopicParameters; - -/** - * Abstraction to manage the system's Networked Topic Endpoints, sources of all events input into - * the System. - */ -public interface TopicEndpoint extends Startable, Lockable { - - /** - * Add topics configuration (sources and sinks) into a single list. - * - * @param properties topic configuration - * @return topic list - * @throws IllegalArgumentException when invalid arguments are provided - */ - List addTopics(Properties properties); - - /** - * Add topics configuration (sources and sinks) into a single list. - * - * @param params parameters to configure topic - * @return topic list - * @throws IllegalArgumentException when invalid arguments are provided - */ - List addTopics(TopicParameterGroup params); - - /** - * Add Topic Sources to the communication infrastructure initialized per properties. - * - * @param properties properties for Topic Source construction - * @return a list of generic Topic Sources - * @throws IllegalArgumentException when invalid arguments are provided - */ - List addTopicSources(Properties properties); - - - /** - * Add Topic Sources to the communication infrastructure initialized per properties. - * - * @param paramList parameters for Topic Source construction - * @return a list of generic Topic Sources - * @throws IllegalArgumentException when invalid arguments are provided - */ - List addTopicSources(List paramList); - - /** - * Add Topic Sinks to the communication infrastructure initialized per properties. - * - * @param properties properties for Topic Sink construction - * @return a list of generic Topic Sinks - * @throws IllegalArgumentException when invalid arguments are provided - */ - List addTopicSinks(Properties properties); - - /** - * Add Topic Sinks to the communication infrastructure initialized per properties. - * - * @param paramList parameters for Topic Sink construction - * @return a list of generic Topic Sinks - * @throws IllegalArgumentException when invalid arguments are provided - */ - List addTopicSinks(List paramList); - - /** - * Gets all Topic Sources. - * - * @return the Topic Source List - */ - List getTopicSources(); - - /** - * Get the Topic Sources for the given topic name. - * - * @param topicNames the topic name - * - * @return the Topic Source List - * @throws IllegalStateException if the entity is in an invalid state - * @throws IllegalArgumentException if invalid parameters are present - */ - List getTopicSources(List topicNames); - - /** - * Gets the Topic Source for the given topic name and underlying communication infrastructure - * type. - * - * @param commType communication infrastructure type - * @param topicName the topic name - * - * @return the Topic Source - * @throws IllegalStateException if the entity is in an invalid state, for example multiple - * TopicReaders for a topic name and communication infrastructure - * @throws IllegalArgumentException if invalid parameters are present - * @throws UnsupportedOperationException if the operation is not supported. - */ - TopicSource getTopicSource(Topic.CommInfrastructure commType, String topicName); - - /** - * Get the Noop Source for the given topic name. - * - * @param topicName the topic name. - * @return the Noop Source. - */ - NoopTopicSource getNoopTopicSource(String topicName); - - /** - * Get the Kafka Source for the given topic name. - * - * @param topicName the topic name. - * @return the Kafka Source. - */ - KafkaTopicSource getKafkaTopicSource(String topicName); - - /** - * Get the Topic Sinks for the given topic name. - * - * @param topicNames the topic names - * @return the Topic Sink List - */ - List getTopicSinks(List topicNames); - - /** - * Get the Topic Sinks for the given topic name and all the underlying communication - * infrastructure type. - * - * @param topicName the topic name - * - * @return the Topic Sink List - * @throws IllegalStateException if the entity is in an invalid state, for example multiple - * TopicWriters for a topic name and communication infrastructure - * @throws IllegalArgumentException if invalid parameters are present - */ - List getTopicSinks(String topicName); - - /** - * Gets all Topic Sinks. - * - * @return the Topic Sink List - */ - List getTopicSinks(); - - /** - * Get the Topic Sinks for the given topic name and underlying communication infrastructure type. - * - * @param topicName the topic name - * @param commType communication infrastructure type - * - * @return the Topic Sink List - * @throws IllegalStateException if the entity is in an invalid state, for example multiple - * TopicWriters for a topic name and communication infrastructure - * @throws IllegalArgumentException if invalid parameters are present - */ - TopicSink getTopicSink(Topic.CommInfrastructure commType, String topicName); - - /** - * Get the no-op Topic Sink for the given topic name. - * - * @param topicName the topic name - * - * @return the Topic Source - * @throws IllegalStateException if the entity is in an invalid state, for example multiple - * TopicReaders for a topic name and communication infrastructure - * @throws IllegalArgumentException if invalid parameters are present - */ - NoopTopicSink getNoopTopicSink(String topicName); - - /** - * Get the KAFKA Topic Source for the given topic name. - * - * @param topicName the topic name - * - * @return the Topic Source - * @throws IllegalStateException if the entity is in an invalid state, for example multiple - * TopicReaders for a topic name and communication infrastructure - * @throws IllegalArgumentException if invalid parameters are present - */ - KafkaTopicSink getKafkaTopicSink(String topicName); - - /** - * Gets only the KAFKA Topic Sources. - * - * @return the KAFKA Topic Source List - */ - List getKafkaTopicSources(); - - /** - * Gets only the NOOP Topic Sources. - * - * @return the NOOP Topic Source List - */ - List getNoopTopicSources(); - - /** - * Gets only the KAFKA Topic Sinks. - * - * @return the KAFKA Topic Sinks List - */ - List getKafkaTopicSinks(); - - /** - * Gets only the NOOP Topic Sinks. - * - * @return the NOOP Topic Sinks List - */ - List getNoopTopicSinks(); - -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicEndpointManager.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicEndpointManager.java deleted file mode 100644 index fb18a307..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicEndpointManager.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm; - -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class TopicEndpointManager { - - /** - * Topic endpoint manager. - */ - @Getter - private static TopicEndpoint manager = new TopicEndpointProxy(); -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicEndpointProxy.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicEndpointProxy.java deleted file mode 100644 index 98fbbf0b..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicEndpointProxy.java +++ /dev/null @@ -1,485 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2022-2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.Properties; -import lombok.Getter; -import org.onap.policy.common.capabilities.Startable; -import org.onap.policy.common.endpoints.event.comm.bus.KafkaTopicFactories; -import org.onap.policy.common.endpoints.event.comm.bus.KafkaTopicSink; -import org.onap.policy.common.endpoints.event.comm.bus.KafkaTopicSource; -import org.onap.policy.common.endpoints.event.comm.bus.NoopTopicFactories; -import org.onap.policy.common.endpoints.event.comm.bus.NoopTopicSink; -import org.onap.policy.common.endpoints.event.comm.bus.NoopTopicSource; -import org.onap.policy.common.endpoints.parameters.TopicParameterGroup; -import org.onap.policy.common.endpoints.parameters.TopicParameters; -import org.onap.policy.common.gson.annotation.GsonJsonIgnore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This implementation of the Topic Endpoint Manager, proxies operations to the appropriate - * implementation(s). - */ -@Getter -public class TopicEndpointProxy implements TopicEndpoint { - /** - * Logger. - */ - private static final Logger logger = LoggerFactory.getLogger(TopicEndpointProxy.class); - - /** - * Is this element locked boolean. - */ - private volatile boolean locked = false; - - /** - * Is this element alive boolean. - */ - private volatile boolean alive = false; - - @Override - public List addTopics(Properties properties) { - List topics = new ArrayList<>(addTopicSources(properties)); - topics.addAll(addTopicSinks(properties)); - return topics; - } - - @Override - public List addTopics(TopicParameterGroup params) { - List sinks = - (params.getTopicSinks() != null ? params.getTopicSinks() : Collections.emptyList()); - List sources = - (params.getTopicSources() != null ? params.getTopicSources() : Collections.emptyList()); - - List topics = new ArrayList<>(sinks.size() + sources.size()); - topics.addAll(addTopicSources(sources)); - topics.addAll(addTopicSinks(sinks)); - return topics; - } - - @Override - public List addTopicSources(List paramList) { - List sources = new ArrayList<>(paramList.size()); - - for (TopicParameters param : paramList) { - switch (Topic.CommInfrastructure.valueOf(param.getTopicCommInfrastructure().toUpperCase())) { - case KAFKA: - sources.add(KafkaTopicFactories.getSourceFactory().build(param)); - break; - case NOOP: - sources.add(NoopTopicFactories.getSourceFactory().build(param)); - break; - default: - logger.debug("Unknown source type {} for topic: {}", param.getTopicCommInfrastructure(), - param.getTopic()); - break; - } - } - - lockSources(sources); - - return sources; - } - - @Override - public List addTopicSources(Properties properties) { - - // 1. Create KAFKA Sources - // 2. Create NOOP Sources - - List sources = new ArrayList<>(); - - sources.addAll(KafkaTopicFactories.getSourceFactory().build(properties)); - sources.addAll(NoopTopicFactories.getSourceFactory().build(properties)); - - lockSources(sources); - - return sources; - } - - private void lockSources(List sources) { - if (this.isLocked()) { - sources.forEach(TopicSource::lock); - } - } - - @Override - public List addTopicSinks(List paramList) { - List sinks = new ArrayList<>(paramList.size()); - - for (TopicParameters param : paramList) { - switch (Topic.CommInfrastructure.valueOf(param.getTopicCommInfrastructure().toUpperCase())) { - case KAFKA: - sinks.add(KafkaTopicFactories.getSinkFactory().build(param)); - break; - case NOOP: - sinks.add(NoopTopicFactories.getSinkFactory().build(param)); - break; - default: - logger.debug("Unknown sink type {} for topic: {}", param.getTopicCommInfrastructure(), - param.getTopic()); - break; - } - } - - lockSinks(sinks); - - return sinks; - } - - @Override - public List addTopicSinks(Properties properties) { - // 1. Create KAFKA Sinks - // 2. Create NOOP Sinks - - final List sinks = new ArrayList<>(); - - sinks.addAll(KafkaTopicFactories.getSinkFactory().build(properties)); - sinks.addAll(NoopTopicFactories.getSinkFactory().build(properties)); - - lockSinks(sinks); - - return sinks; - } - - private void lockSinks(List sinks) { - if (this.isLocked()) { - sinks.forEach(TopicSink::lock); - } - } - - @Override - public List getTopicSources() { - - final List sources = new ArrayList<>(); - - sources.addAll(KafkaTopicFactories.getSourceFactory().inventory()); - sources.addAll(NoopTopicFactories.getSourceFactory().inventory()); - - return sources; - } - - @Override - public List getTopicSources(List topicNames) { - - if (topicNames == null) { - throw new IllegalArgumentException("must provide a list of topics"); - } - - final List sources = new ArrayList<>(); - - topicNames.forEach(topic -> { - try { - sources.add(Objects.requireNonNull(this.getKafkaTopicSource(topic))); - } catch (final Exception e) { - logger.debug("No KAFKA source for topic: {}", topic, e); - } - - try { - sources.add(Objects.requireNonNull(this.getNoopTopicSource(topic))); - } catch (final Exception e) { - logger.debug("No NOOP source for topic: {}", topic, e); - } - }); - - return sources; - } - - @Override - public List getTopicSinks() { - - final List sinks = new ArrayList<>(); - - sinks.addAll(KafkaTopicFactories.getSinkFactory().inventory()); - sinks.addAll(NoopTopicFactories.getSinkFactory().inventory()); - - return sinks; - } - - @Override - public List getTopicSinks(List topicNames) { - - if (topicNames == null) { - throw new IllegalArgumentException("must provide a list of topics"); - } - - final List sinks = new ArrayList<>(); - for (final String topic : topicNames) { - try { - sinks.add(Objects.requireNonNull(this.getKafkaTopicSink(topic))); - } catch (final Exception e) { - logger.debug("No KAFKA sink for topic: {}", topic, e); - } - - try { - sinks.add(Objects.requireNonNull(this.getNoopTopicSink(topic))); - } catch (final Exception e) { - logger.debug("No NOOP sink for topic: {}", topic, e); - } - } - return sinks; - } - - @Override - public List getTopicSinks(String topicName) { - if (topicName == null) { - throw paramException(null); - } - - final List sinks = new ArrayList<>(); - - try { - sinks.add(this.getKafkaTopicSink(topicName)); - } catch (final Exception e) { - logNoSink(topicName, e); - } - - try { - sinks.add(this.getNoopTopicSink(topicName)); - } catch (final Exception e) { - logNoSink(topicName, e); - } - - return sinks; - } - - @GsonJsonIgnore - @Override - public List getKafkaTopicSources() { - return KafkaTopicFactories.getSourceFactory().inventory(); - } - - @GsonJsonIgnore - @Override - public List getNoopTopicSources() { - return NoopTopicFactories.getSourceFactory().inventory(); - } - - @Override - @GsonJsonIgnore - public List getKafkaTopicSinks() { - return KafkaTopicFactories.getSinkFactory().inventory(); - } - - @GsonJsonIgnore - @Override - public List getNoopTopicSinks() { - return NoopTopicFactories.getSinkFactory().inventory(); - } - - @Override - public boolean start() { - - synchronized (this) { - if (this.locked) { - throw new IllegalStateException(this + " is locked"); - } - - if (this.alive) { - return true; - } - - this.alive = true; - } - - final List endpoints = this.getEndpoints(); - - var success = true; - for (final Startable endpoint : endpoints) { - try { - success = endpoint.start() && success; - } catch (final Exception e) { - success = false; - logger.error("Problem starting endpoint: {}", endpoint, e); - } - } - - return success; - } - - @Override - public boolean stop() { - - /* - * stop regardless if it is locked, in other words, stop operation has precedence over - * locks. - */ - synchronized (this) { - this.alive = false; - } - - final List endpoints = this.getEndpoints(); - - var success = true; - for (final Startable endpoint : endpoints) { - try { - success = endpoint.stop() && success; - } catch (final Exception e) { - success = false; - logger.error("Problem stopping endpoint: {}", endpoint, e); - } - } - - return success; - } - - /** - * Gets the endpoints. - * - * @return list of managed endpoints - */ - @GsonJsonIgnore - protected List getEndpoints() { - final List endpoints = new ArrayList<>(); - - endpoints.addAll(this.getTopicSources()); - endpoints.addAll(this.getTopicSinks()); - - return endpoints; - } - - @Override - public void shutdown() { - this.stop(); - - KafkaTopicFactories.getSourceFactory().destroy(); - KafkaTopicFactories.getSinkFactory().destroy(); - - NoopTopicFactories.getSinkFactory().destroy(); - NoopTopicFactories.getSourceFactory().destroy(); - - } - - @Override - public boolean lock() { - boolean shouldLock; - - synchronized (this) { - shouldLock = !this.locked; - this.locked = true; - } - - if (shouldLock) { - for (final TopicSource source : this.getTopicSources()) { - source.lock(); - } - - for (final TopicSink sink : this.getTopicSinks()) { - sink.lock(); - } - } - - return true; - } - - @Override - public boolean unlock() { - boolean shouldUnlock; - - synchronized (this) { - shouldUnlock = this.locked; - this.locked = false; - } - - if (shouldUnlock) { - for (final TopicSource source : this.getTopicSources()) { - source.unlock(); - } - - for (final TopicSink sink : this.getTopicSinks()) { - sink.unlock(); - } - } - - return true; - } - - @Override - public TopicSource getTopicSource(Topic.CommInfrastructure commType, String topicName) { - - if (commType == null) { - throw paramException(topicName); - } - - if (topicName == null) { - throw paramException(null); - } - - return switch (commType) { - case KAFKA -> this.getKafkaTopicSource(topicName); - case NOOP -> this.getNoopTopicSource(topicName); - default -> throw new UnsupportedOperationException("Unsupported " + commType.name()); - }; - } - - @Override - public TopicSink getTopicSink(Topic.CommInfrastructure commType, String topicName) { - if (commType == null) { - throw paramException(topicName); - } - - if (topicName == null) { - throw paramException(null); - } - - return switch (commType) { - case KAFKA -> this.getKafkaTopicSink(topicName); - case NOOP -> this.getNoopTopicSink(topicName); - default -> throw new UnsupportedOperationException("Unsupported " + commType.name()); - }; - } - - @Override - public KafkaTopicSource getKafkaTopicSource(String topicName) { - return KafkaTopicFactories.getSourceFactory().get(topicName); - } - - @Override - public NoopTopicSource getNoopTopicSource(String topicName) { - return NoopTopicFactories.getSourceFactory().get(topicName); - } - - @Override - public KafkaTopicSink getKafkaTopicSink(String topicName) { - return KafkaTopicFactories.getSinkFactory().get(topicName); - } - - @Override - public NoopTopicSink getNoopTopicSink(String topicName) { - return NoopTopicFactories.getSinkFactory().get(topicName); - } - - private IllegalArgumentException paramException(String topicName) { - return new IllegalArgumentException( - "Invalid parameter: a communication infrastructure required to fetch " + topicName); - } - - private void logNoSink(String topicName, Exception ex) { - logger.debug("No sink for topic: {}", topicName, ex); - } - -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicListener.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicListener.java deleted file mode 100644 index dd6eedd0..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicListener.java +++ /dev/null @@ -1,38 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm; - -/** - * Listener for event messages entering the Policy Engine. - */ -@FunctionalInterface -public interface TopicListener { - - /** - * Notification of a new Event over a given Topic. - * - * @param commType communication infrastructure type - * @param topic topic name - * @param event event message as a string - */ - public void onTopicEvent(Topic.CommInfrastructure commType, String topic, String event); - -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicRegisterable.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicRegisterable.java deleted file mode 100644 index 207ebc66..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicRegisterable.java +++ /dev/null @@ -1,42 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm; - -/** - * Marks a Topic entity as registerable. - */ -public interface TopicRegisterable { - - /** - * Register for notification of events with this Topic Entity. - * - * @param topicListener the listener of events - */ - public void register(TopicListener topicListener); - - /** - * Unregisters for notification of events with this Topic Entity. - * - * @param topicListener the listener of events - */ - public void unregister(TopicListener topicListener); - -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicSink.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicSink.java deleted file mode 100644 index b67756e5..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicSink.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2023 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm; - -/** - * Marks a given Topic Endpoint as able to send messages over a topic. - */ -public interface TopicSink extends Topic { - - /** - * Sends a string message over this Topic Endpoint. - * - * @param message message to send - * - * @return true if the send operation succeeded, false otherwise - * @throws IllegalArgumentException an invalid message has been provided - * @throws IllegalStateException the entity is in a state that prevents - * it from sending messages, for example, locked or stopped. - */ - boolean send(String message); - -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicSource.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicSource.java deleted file mode 100644 index c1d0829c..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/TopicSource.java +++ /dev/null @@ -1,37 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm; - -/** - * Marker for a Topic Entity, indicating that the entity is able to read - * over a topic. - */ -public interface TopicSource extends Topic { - - /** - * Pushes an event into the source programatically. - * - * @param event the event in json format - * @return true if it can be processed correctly, false otherwise - */ - public boolean offer(String event); - -} \ No newline at end of file diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/ApiKeyEnabled.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/ApiKeyEnabled.java deleted file mode 100644 index 0e06007f..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/ApiKeyEnabled.java +++ /dev/null @@ -1,40 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -/** - * API. - */ -public interface ApiKeyEnabled { - /** - * Get API key. - * - * @return api key - */ - public String getApiKey(); - - /** - * Get API secret. - * - * @return api secret - */ - public String getApiSecret(); -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/BusTopicSink.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/BusTopicSink.java deleted file mode 100644 index ceb9255e..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/BusTopicSink.java +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2017, 2019 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2023-2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import org.onap.policy.common.endpoints.event.comm.TopicSink; - -/** - * Topic Sink over Bus Infrastructure (KAFKA). - */ -public interface BusTopicSink extends ApiKeyEnabled, TopicSink { - - /** - * Sets the partition key for published messages. - * - * @param partitionKey the partition key - */ - void setPartitionKey(String partitionKey); - - /** - * Return the partition key in used by the system to publish messages. - * - * @return the partition key - */ - String getPartitionKey(); -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/BusTopicSource.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/BusTopicSource.java deleted file mode 100644 index 87a06824..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/BusTopicSource.java +++ /dev/null @@ -1,59 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import org.onap.policy.common.endpoints.event.comm.TopicSource; - -/** - * Generic Topic Source for Bus Communication Infrastructure. - * - */ -public interface BusTopicSource extends ApiKeyEnabled, TopicSource { - - /** - * Gets the consumer group. - * - * @return consumer group - */ - public String getConsumerGroup(); - - /** - * Gets the consumer instance. - * - * @return consumer instance - */ - public String getConsumerInstance(); - - /** - * Gets the fetch timeout. - * - * @return fetch timeout - */ - public int getFetchTimeout(); - - /** - * Gets the fetch limit. - * - * @return fetch limit - */ - public int getFetchLimit(); -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/IndexedKafkaTopicSinkFactory.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/IndexedKafkaTopicSinkFactory.java deleted file mode 100644 index f913926e..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/IndexedKafkaTopicSinkFactory.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022-2023 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import com.google.re2j.Pattern; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Properties; -import org.apache.commons.lang3.StringUtils; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; -import org.onap.policy.common.endpoints.event.comm.bus.internal.InlineKafkaTopicSink; -import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; -import org.onap.policy.common.endpoints.utils.KafkaPropertyUtils; -import org.onap.policy.common.endpoints.utils.PropertyUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Factory of KAFKA Reader Topics indexed by topic name. - */ -class IndexedKafkaTopicSinkFactory implements KafkaTopicSinkFactory { - private static final Pattern COMMA_SPACE_PAT = Pattern.compile("\\s*,\\s*"); - private static final String MISSING_TOPIC = "A topic must be provided"; - - /** - * Logger. - */ - private static final Logger logger = LoggerFactory.getLogger(IndexedKafkaTopicSinkFactory.class); - - /** - * KAFKA Topic Name Index. - */ - protected HashMap kafkaTopicSinks = new HashMap<>(); - - @Override - public KafkaTopicSink build(BusTopicParams busTopicParams) { - - if (busTopicParams.getServers() == null || busTopicParams.getServers().isEmpty()) { - throw new IllegalArgumentException("KAFKA Server(s) must be provided"); - } - - if (StringUtils.isBlank(busTopicParams.getTopic())) { - throw new IllegalArgumentException(MISSING_TOPIC); - } - - synchronized (this) { - if (kafkaTopicSinks.containsKey(busTopicParams.getTopic())) { - return kafkaTopicSinks.get(busTopicParams.getTopic()); - } - - KafkaTopicSink kafkaTopicWriter = makeSink(busTopicParams); - if (busTopicParams.isManaged()) { - kafkaTopicSinks.put(busTopicParams.getTopic(), kafkaTopicWriter); - } - - return kafkaTopicWriter; - } - } - - - @Override - public KafkaTopicSink build(List servers, String topic) { - return this.build(BusTopicParams.builder() - .servers(servers) - .topic(topic) - .managed(true) - .useHttps(false) - .build()); - } - - - @Override - public List build(Properties properties) { - - String writeTopics = properties.getProperty(PolicyEndPointProperties.PROPERTY_KAFKA_SINK_TOPICS); - if (StringUtils.isBlank(writeTopics)) { - logger.info("{}: no topic for KAFKA Sink", this); - return new ArrayList<>(); - } - - List newKafkaTopicSinks = new ArrayList<>(); - synchronized (this) { - for (String topic : COMMA_SPACE_PAT.split(writeTopics)) { - addTopic(newKafkaTopicSinks, topic.toLowerCase(), properties); - } - return newKafkaTopicSinks; - } - } - - private void addTopic(List newKafkaTopicSinks, String topic, Properties properties) { - if (this.kafkaTopicSinks.containsKey(topic)) { - newKafkaTopicSinks.add(this.kafkaTopicSinks.get(topic)); - return; - } - - String topicPrefix = PolicyEndPointProperties.PROPERTY_KAFKA_SINK_TOPICS + "." + topic; - - var props = new PropertyUtils(properties, topicPrefix, - (name, value, ex) -> logger.warn("{}: {} {} is in invalid format for topic sink {} ", - this, name, value, topic)); - - String servers = properties.getProperty(topicPrefix + PolicyEndPointProperties.PROPERTY_TOPIC_SERVERS_SUFFIX); - if (StringUtils.isBlank(servers)) { - logger.error("{}: no KAFKA servers configured for sink {}", this, topic); - return; - } - - KafkaTopicSink kafkaTopicWriter = this.build(KafkaPropertyUtils.makeBuilder(props, topic, servers) - .partitionId(props.getString(PolicyEndPointProperties.PROPERTY_TOPIC_SINK_PARTITION_KEY_SUFFIX, null)) - .build()); - newKafkaTopicSinks.add(kafkaTopicWriter); - } - - @Override - public void destroy(String topic) { - - if (topic == null || topic.isEmpty()) { - throw new IllegalArgumentException(MISSING_TOPIC); - } - - KafkaTopicSink kafkaTopicWriter; - synchronized (this) { - if (!kafkaTopicSinks.containsKey(topic)) { - return; - } - - kafkaTopicWriter = kafkaTopicSinks.remove(topic); - } - - kafkaTopicWriter.shutdown(); - } - - @Override - public void destroy() { - List writers = this.inventory(); - for (KafkaTopicSink writer : writers) { - writer.shutdown(); - } - - synchronized (this) { - this.kafkaTopicSinks.clear(); - } - } - - @Override - public KafkaTopicSink get(String topic) { - - if (topic == null || topic.isEmpty()) { - throw new IllegalArgumentException(MISSING_TOPIC); - } - - synchronized (this) { - if (kafkaTopicSinks.containsKey(topic)) { - return kafkaTopicSinks.get(topic); - } else { - throw new IllegalStateException("KafkaTopicSink for " + topic + " not found"); - } - } - } - - @Override - public synchronized List inventory() { - return new ArrayList<>(this.kafkaTopicSinks.values()); - } - - /** - * Makes a new sink. - * - * @param busTopicParams parameters to use to configure the sink - * @return a new sink - */ - protected KafkaTopicSink makeSink(BusTopicParams busTopicParams) { - return new InlineKafkaTopicSink(busTopicParams); - } - - - @Override - public String toString() { - return "IndexedKafkaTopicSinkFactory " + kafkaTopicSinks.keySet(); - } - -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/IndexedKafkaTopicSourceFactory.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/IndexedKafkaTopicSourceFactory.java deleted file mode 100644 index 151d8f69..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/IndexedKafkaTopicSourceFactory.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022-2023 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import com.google.re2j.Pattern; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Properties; -import org.apache.commons.lang3.StringUtils; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; -import org.onap.policy.common.endpoints.event.comm.bus.internal.SingleThreadedKafkaTopicSource; -import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; -import org.onap.policy.common.endpoints.utils.KafkaPropertyUtils; -import org.onap.policy.common.endpoints.utils.PropertyUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Factory of KAFKA Source Topics indexed by topic name. - */ -class IndexedKafkaTopicSourceFactory implements KafkaTopicSourceFactory { - private static final Pattern COMMA_SPACE_PAT = Pattern.compile("\\s*,\\s*"); - private static final String MISSING_TOPIC = "A topic must be provided"; - - /** - * Logger. - */ - private static final Logger logger = LoggerFactory.getLogger(IndexedKafkaTopicSourceFactory.class); - - /** - * KAFKA Topic Name Index. - */ - protected HashMap kafkaTopicSources = new HashMap<>(); - - @Override - public KafkaTopicSource build(BusTopicParams busTopicParams) { - if (busTopicParams.getServers() == null || busTopicParams.getServers().isEmpty()) { - throw new IllegalArgumentException("KAFKA Server(s) must be provided"); - } - - if (busTopicParams.getTopic() == null || busTopicParams.getTopic().isEmpty()) { - throw new IllegalArgumentException(MISSING_TOPIC); - } - - synchronized (this) { - if (kafkaTopicSources.containsKey(busTopicParams.getTopic())) { - return kafkaTopicSources.get(busTopicParams.getTopic()); - } - - var kafkaTopicSource = makeSource(busTopicParams); - - kafkaTopicSources.put(busTopicParams.getTopic(), kafkaTopicSource); - - return kafkaTopicSource; - } - } - - @Override - public List build(Properties properties) { - - String readTopics = properties.getProperty(PolicyEndPointProperties.PROPERTY_KAFKA_SOURCE_TOPICS); - if (StringUtils.isBlank(readTopics)) { - logger.info("{}: no topic for KAFKA Source", this); - return new ArrayList<>(); - } - - List newKafkaTopicSources = new ArrayList<>(); - synchronized (this) { - for (String topic : COMMA_SPACE_PAT.split(readTopics)) { - addTopic(newKafkaTopicSources, topic.toLowerCase(), properties); - } - } - return newKafkaTopicSources; - } - - @Override - public KafkaTopicSource build(List servers, String topic) { - return this.build(BusTopicParams.builder() - .servers(servers) - .topic(topic) - .managed(true) - .fetchTimeout(PolicyEndPointProperties.DEFAULT_TIMEOUT_MS_FETCH) - .fetchLimit(PolicyEndPointProperties.DEFAULT_LIMIT_FETCH) - .useHttps(false).build()); - } - - private void addTopic(List newKafkaTopicSources, String topic, Properties properties) { - if (this.kafkaTopicSources.containsKey(topic)) { - newKafkaTopicSources.add(this.kafkaTopicSources.get(topic)); - return; - } - - String topicPrefix = PolicyEndPointProperties.PROPERTY_KAFKA_SOURCE_TOPICS + "." + topic; - - var props = new PropertyUtils(properties, topicPrefix, - (name, value, ex) -> logger.warn("{}: {} {} is in invalid format for topic source {} ", - this, name, value, topic)); - - String servers = properties.getProperty(topicPrefix + PolicyEndPointProperties.PROPERTY_TOPIC_SERVERS_SUFFIX); - if (StringUtils.isBlank(servers)) { - logger.error("{}: no KAFKA servers configured for source {}", this, topic); - return; - } - - var kafkaTopicSource = this.build(KafkaPropertyUtils.makeBuilder(props, topic, servers) - .consumerGroup(props.getString( - PolicyEndPointProperties.PROPERTY_TOPIC_SOURCE_CONSUMER_GROUP_SUFFIX, null)) - .consumerInstance(props.getString( - PolicyEndPointProperties.PROPERTY_TOPIC_SOURCE_CONSUMER_INSTANCE_SUFFIX, null)) - .fetchTimeout(props.getInteger( - PolicyEndPointProperties.PROPERTY_TOPIC_SOURCE_FETCH_TIMEOUT_SUFFIX, - PolicyEndPointProperties.DEFAULT_TIMEOUT_MS_FETCH)) - .fetchLimit(props.getInteger(PolicyEndPointProperties.PROPERTY_TOPIC_SOURCE_FETCH_LIMIT_SUFFIX, - PolicyEndPointProperties.DEFAULT_LIMIT_FETCH)) - .build()); - - newKafkaTopicSources.add(kafkaTopicSource); - } - - /** - * Makes a new source. - * - * @param busTopicParams parameters to use to configure the source - * @return a new source - */ - protected KafkaTopicSource makeSource(BusTopicParams busTopicParams) { - return new SingleThreadedKafkaTopicSource(busTopicParams); - } - - @Override - public void destroy(String topic) { - - if (topic == null || topic.isEmpty()) { - throw new IllegalArgumentException(MISSING_TOPIC); - } - - KafkaTopicSource kafkaTopicSource; - - synchronized (this) { - if (!kafkaTopicSources.containsKey(topic)) { - return; - } - - kafkaTopicSource = kafkaTopicSources.remove(topic); - } - - kafkaTopicSource.shutdown(); - } - - @Override - public void destroy() { - List readers = this.inventory(); - for (KafkaTopicSource reader : readers) { - reader.shutdown(); - } - - synchronized (this) { - this.kafkaTopicSources.clear(); - } - } - - @Override - public KafkaTopicSource get(String topic) { - - if (topic == null || topic.isEmpty()) { - throw new IllegalArgumentException(MISSING_TOPIC); - } - - synchronized (this) { - if (kafkaTopicSources.containsKey(topic)) { - return kafkaTopicSources.get(topic); - } else { - throw new IllegalStateException("KafkaTopiceSource for " + topic + " not found"); - } - } - } - - @Override - public synchronized List inventory() { - return new ArrayList<>(this.kafkaTopicSources.values()); - } - - @Override - public String toString() { - return "IndexedKafkaTopicSourceFactory " + kafkaTopicSources.keySet(); - } -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicFactories.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicFactories.java deleted file mode 100644 index 60db3857..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicFactories.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class KafkaTopicFactories { - - /** - * Factory for instantiation and management of sinks. - */ - @Getter - private static final KafkaTopicSinkFactory sinkFactory = new IndexedKafkaTopicSinkFactory(); - - /** - * Factory for instantiation and management of sources. - */ - @Getter - private static final KafkaTopicSourceFactory sourceFactory = new IndexedKafkaTopicSourceFactory(); -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSink.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSink.java deleted file mode 100644 index 960a02c5..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSink.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -/** - * Topic Writer over KAFKA Infrastructure. - */ -public interface KafkaTopicSink extends BusTopicSink { - -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSinkFactory.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSinkFactory.java deleted file mode 100644 index fa5e56f9..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSinkFactory.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import java.util.List; -import java.util.Properties; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; - -/** - * KAFKA Topic Sink Factory. - */ -public interface KafkaTopicSinkFactory { - - /** - * Instantiates a new KAFKA Topic Writer. - * - * @param busTopicParams parameters object - * @return an KAFKA Topic Sink - */ - KafkaTopicSink build(BusTopicParams busTopicParams); - - /** - * Creates an KAFKA Topic Writer based on properties files. - * - * @param properties Properties containing initialization values - * - * @return an KAFKA Topic Writer - * @throws IllegalArgumentException if invalid parameters are present - */ - List build(Properties properties); - - /** - * Instantiates a new KAFKA Topic Writer. - * - * @param servers list of servers - * @param topic topic name - * - * @return an KAFKA Topic Writer - * @throws IllegalArgumentException if invalid parameters are present - */ - KafkaTopicSink build(List servers, String topic); - - /** - * Destroys an KAFKA Topic Writer based on a topic. - * - * @param topic topic name - * @throws IllegalArgumentException if invalid parameters are present - */ - void destroy(String topic); - - /** - * Destroys all KAFKA Topic Writers. - */ - void destroy(); - - /** - * gets an KAFKA Topic Writer based on topic name. - * - * @param topic the topic name - * - * @return an KAFKA Topic Writer with topic name - * @throws IllegalArgumentException if an invalid topic is provided - * @throws IllegalStateException if the KAFKA Topic Reader is an incorrect state - */ - KafkaTopicSink get(String topic); - - /** - * Provides a snapshot of the KAFKA Topic Writers. - * - * @return a list of the KAFKA Topic Writers - */ - List inventory(); -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSource.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSource.java deleted file mode 100644 index 03efd083..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSource.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -/** - * Kafka Topic Source. - */ -public interface KafkaTopicSource extends BusTopicSource { - -} \ No newline at end of file diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSourceFactory.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSourceFactory.java deleted file mode 100644 index e5642daa..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSourceFactory.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022-2023 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import java.util.List; -import java.util.Properties; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; - -/** - * Kafka Topic Source Factory. - */ -public interface KafkaTopicSourceFactory { - - /** - * Creates a Kafka Topic Source based on properties files. - * - * @param properties Properties containing initialization values - * - * @return a Kafka Topic Source - * @throws IllegalArgumentException if invalid parameters are present - */ - List build(Properties properties); - - /** - * Instantiates a new Kafka Topic Source. - * - * @param busTopicParams parameters object - * @return a Kafka Topic Source - */ - KafkaTopicSource build(BusTopicParams busTopicParams); - - /** - * Instantiates a new Kafka Topic Source. - * - * @param servers list of servers - * @param topic topic name - * - * @return a Kafka Topic Source - * @throws IllegalArgumentException if invalid parameters are present - */ - KafkaTopicSource build(List servers, String topic); - - /** - * Destroys a Kafka Topic Source based on a topic. - * - * @param topic topic name - * @throws IllegalArgumentException if invalid parameters are present - */ - void destroy(String topic); - - /** - * Destroys all Kafka Topic Sources. - */ - void destroy(); - - /** - * Gets a Kafka Topic Source based on topic name. - * - * @param topic the topic name - * @return a Kafka Topic Source with topic name - * @throws IllegalArgumentException if an invalid topic is provided - * @throws IllegalStateException if the Kafka Topic Source is an incorrect state - */ - KafkaTopicSource get(String topic); - - /** - * Provides a snapshot of the Kafka Topic Sources. - * - * @return a list of the Kafka Topic Sources - */ - List inventory(); -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicEndpoint.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicEndpoint.java deleted file mode 100644 index 73ff6ed6..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicEndpoint.java +++ /dev/null @@ -1,140 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2019 Samsung Electronics Co., Ltd. - * Modifications Copyright (C) 2020 Bell Canada. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import java.util.List; -import org.onap.policy.common.endpoints.event.comm.bus.internal.TopicBase; -import org.onap.policy.common.endpoints.utils.NetLoggerUtil; -import org.onap.policy.common.endpoints.utils.NetLoggerUtil.EventType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * No Operation topic endpoint. - */ -public abstract class NoopTopicEndpoint extends TopicBase { - - /** - * Logger. - */ - private static Logger logger = LoggerFactory.getLogger(NoopTopicEndpoint.class); - - /** - * Constructs the object. - */ - protected NoopTopicEndpoint(List servers, String topic) { - super(servers, topic); - } - - /** - * I/O. - * - * @param type "IN" or "OUT". - * @param message message. - * @return true if successful. - */ - protected boolean io(EventType type, String message) { - - if (message == null || message.isEmpty()) { - throw new IllegalArgumentException("Message is empty"); - } - - if (!this.alive) { - throw new IllegalStateException(this + " is stopped"); - } - - try { - synchronized (this) { - this.recentEvents.add(message); - } - - NetLoggerUtil.log(type, this.getTopicCommInfrastructure(), this.topic, message); - - broadcast(message); - } catch (Exception e) { - logger.warn("{}: cannot send because of {}", this, e.getMessage(), e); - return false; - } - - return true; - } - - /** - * {@inheritDoc}. - */ - @Override - public CommInfrastructure getTopicCommInfrastructure() { - return CommInfrastructure.NOOP; - } - - /** - * {@inheritDoc}. - */ - @Override - public boolean start() { - logger.info("{}: starting", this); - - synchronized (this) { - if (!this.alive) { - if (locked) { - throw new IllegalStateException(this + " is locked."); - } - - this.alive = true; - } - } - - return true; - } - - /** - * {@inheritDoc}. - */ - @Override - public boolean stop() { - logger.info("{}: stopping", this); - - synchronized (this) { - this.alive = false; - } - return true; - } - - /** - * {@inheritDoc}. - */ - @Override - public void shutdown() { - logger.info("{}: shutdown", this); - - this.stop(); - } - - /** - * {@inheritDoc}. - */ - @Override - public String toString() { - return "NoopTopicEndpoint[" + super.toString() + "]"; - } -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicFactories.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicFactories.java deleted file mode 100644 index c3e7e0a4..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicFactories.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class NoopTopicFactories { - - /** - * Factory for instantiation and management of sinks. - */ - @Getter - private static final NoopTopicSinkFactory sinkFactory = new NoopTopicSinkFactory(); - - /** - * Factory for instantiation and management of sources. - */ - @Getter - private static final NoopTopicSourceFactory sourceFactory = new NoopTopicSourceFactory(); -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicFactory.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicFactory.java deleted file mode 100644 index dfe7c2c4..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicFactory.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import com.google.re2j.Pattern; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Properties; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; - -/** - * Noop Topic Factory. - */ -public abstract class NoopTopicFactory extends TopicBaseHashedFactory { - private static final Pattern COMMA_SPACE_PAT = Pattern.compile("\\s*,\\s*"); - - /** - * Get Topics Property Name. - * - * @return property name. - */ - protected abstract String getTopicsPropertyName(); - - /** - * {@inheritDoc}. - */ - @Override - protected List getTopicNames(Properties properties) { - String topics = properties.getProperty(getTopicsPropertyName()); - if (topics == null || topics.isEmpty()) { - return new ArrayList<>(); - } - - return Arrays.asList(COMMA_SPACE_PAT.split(topics)); - } - - /** - * {@inheritDoc}. - */ - @Override - protected List getServers(String topicName, Properties properties) { - String servers = - properties.getProperty(getTopicsPropertyName() + "." + topicName - + PolicyEndPointProperties.PROPERTY_TOPIC_SERVERS_SUFFIX); - - if (servers == null || servers.isEmpty()) { - servers = CommInfrastructure.NOOP.toString(); - } - - return new ArrayList<>(Arrays.asList(COMMA_SPACE_PAT.split(servers))); - } - - /** - * {@inheritDoc}. - */ - @Override - protected boolean isManaged(String topicName, Properties properties) { - var managedString = - properties.getProperty(getTopicsPropertyName() - + "." + topicName + PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX); - - var managed = true; - if (managedString != null && !managedString.isEmpty()) { - managed = Boolean.parseBoolean(managedString); - } - - return managed; - } - - /** - * {@inheritDoc}. - */ - @Override - public T build(List serverList, String topic, boolean managed) { - List servers; - if (serverList == null || serverList.isEmpty()) { - servers = Collections.singletonList(CommInfrastructure.NOOP.toString()); - } else { - servers = serverList; - } - - return super.build(servers, topic, managed); - } - - /** - * {@inheritDoc}. - */ - @Override - public String toString() { - return "NoopTopicFactory[ " + super.toString() + " ]"; - } -} - diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSink.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSink.java deleted file mode 100644 index e7accad5..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSink.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import java.util.List; -import org.onap.policy.common.endpoints.event.comm.TopicSink; -import org.onap.policy.common.endpoints.utils.NetLoggerUtil.EventType; - -/** - * No Operation Topic Sink. - */ -public class NoopTopicSink extends NoopTopicEndpoint implements TopicSink { - - /** - * Constructs the object. - */ - public NoopTopicSink(List servers, String topic) { - super(servers, topic); - } - - /** - * {@inheritDoc}. - */ - @Override - public boolean send(String message) { - return super.io(EventType.OUT, message); - } - - /** - * {@inheritDoc}. - */ - @Override - public String toString() { - return "NoopTopicSink[" + super.toString() + "]"; - } - -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSinkFactory.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSinkFactory.java deleted file mode 100644 index 0c38d196..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSinkFactory.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import java.util.List; -import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; - -/** - * Noop Topic Sink Factory. - */ -public class NoopTopicSinkFactory extends NoopTopicFactory { - - /** - * {@inheritDoc}. - */ - @Override - protected String getTopicsPropertyName() { - return PolicyEndPointProperties.PROPERTY_NOOP_SINK_TOPICS; - } - - /** - * {@inheritDoc}. - */ - @Override - protected NoopTopicSink build(List servers, String topic) { - return new NoopTopicSink(servers, topic); - } - - /** - * {@inheritDoc}. - */ - @Override - public String toString() { - return "NoopTopicSinkFactory [" + super.toString() + "]"; - } - -} - diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSource.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSource.java deleted file mode 100644 index 6f2c4a1e..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSource.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import java.util.List; -import org.onap.policy.common.endpoints.event.comm.TopicSource; -import org.onap.policy.common.endpoints.utils.NetLoggerUtil.EventType; - -/** - * No Operation Topic Source. - */ -public class NoopTopicSource extends NoopTopicEndpoint implements TopicSource { - - /** - * Constructs the object. - */ - public NoopTopicSource(List servers, String topic) { - super(servers, topic); - } - - /** - * {@inheritDoc}. - */ - @Override - public boolean offer(String event) { - return super.io(EventType.IN, event); - } - - /** - * {@inheritDoc}. - */ - @Override - public String toString() { - return "NoopTopicSource[" + super.toString() + "]"; - } - -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSourceFactory.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSourceFactory.java deleted file mode 100644 index ca5e41d3..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSourceFactory.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import java.util.List; -import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; - -/** - * No Operation Topic Source Factory. - */ -public class NoopTopicSourceFactory extends NoopTopicFactory { - - /** - * {@inheritDoc}. - */ - @Override - protected String getTopicsPropertyName() { - return PolicyEndPointProperties.PROPERTY_NOOP_SOURCE_TOPICS; - } - - /** - * {@inheritDoc}. - */ - @Override - protected NoopTopicSource build(List servers, String topic) { - return new NoopTopicSource(servers, topic); - } - - /** - * {@inheritDoc}. - */ - @Override - public String toString() { - return "NoopTopicSourceFactory [" + super.toString() + "]"; - } -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/TopicBaseFactory.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/TopicBaseFactory.java deleted file mode 100644 index a6b5b1d9..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/TopicBaseFactory.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import java.util.List; -import java.util.Properties; -import org.onap.policy.common.endpoints.event.comm.Topic; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; - -/** - * Topic Base Factory. - * - * @param Type. - */ -public interface TopicBaseFactory { - - /** - * build a TopicBase instance. - * - * @param properties properties. - * @return T instance. - */ - List build(Properties properties); - - /** - * build a TopicBase instance. - * - * @param servers servers. - * @param topic topic. - * @param managed managed. - * @return T instance. - */ - T build(List servers, String topic, boolean managed); - - /** - * Construct an instance of an endpoint. - * - * @param param parameters - * @return an instance of T. - */ - T build(BusTopicParams param); - - /** - * destroy TopicBase instance. - * @param topic topic. - */ - void destroy(String topic); - - /** - * destroy. - */ - void destroy(); - - /** - * get T instance. - * - * @param topic topic. - * @return T instance. - */ - T get(String topic); - - /** - * inventory of T instances. - * - * @return T instance list. - */ - List inventory(); -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/TopicBaseHashedFactory.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/TopicBaseHashedFactory.java deleted file mode 100644 index c785ef04..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/TopicBaseHashedFactory.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Properties; -import org.onap.policy.common.endpoints.event.comm.Topic; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; - -/** - * Topic Factory implementation that indexes T instances in a hash table. - */ -public abstract class TopicBaseHashedFactory implements TopicBaseFactory { - - protected static final String MISSING_TOPIC_MESSAGE = "A topic must be provided"; - protected static final String MISSING_SERVERS_MESSAGE = "Servers must be provided"; - - /** - * endpoints. - */ - protected final HashMap endpoints = new HashMap<>(); - - /** - * get the topic names. - * - * @param properties properties. - * @return list of topic names. - */ - protected abstract List getTopicNames(Properties properties); - - /** - * get the servers that this topic uses. - * - * @param topicName name. - * @param properties properties. - * @return list of servers. - */ - protected abstract List getServers(String topicName, Properties properties); - - /** - * Determines if this topic is managed. - * - * @param topicName name. - * @param properties properties. - * @return if managed. - */ - protected abstract boolean isManaged(String topicName, Properties properties); - - /** - * construct an instance of an endpoint. - * - * @param servers servers, - * @param topic topic. - * @return an instance of T. - */ - protected abstract T build(List servers, String topic); - - /** - * {@inheritDoc}. - */ - @Override - public List build(Properties properties) { - List topicNames = getTopicNames(properties); - if (topicNames == null || topicNames.isEmpty()) { - return Collections.emptyList(); - } - - List newEndpoints = new ArrayList<>(); - synchronized (this) { - for (String name : topicNames) { - if (this.endpoints.containsKey(name)) { - newEndpoints.add(this.endpoints.get(name)); - continue; - } - - newEndpoints.add(this.build(getServers(name, properties), name, isManaged(name, properties))); - } - } - return newEndpoints; - } - - /** - * {@inheritDoc}. - */ - @Override - public T build(BusTopicParams param) { - return this.build(param.getServers(), param.getTopic(), param.isManaged()); - } - - /** - * {@inheritDoc}. - */ - @Override - public T build(List servers, String topic, boolean managed) { - if (servers == null || servers.isEmpty()) { - throw new IllegalArgumentException(MISSING_SERVERS_MESSAGE); - } - - if (topic == null || topic.isEmpty()) { - throw new IllegalArgumentException(MISSING_TOPIC_MESSAGE); - } - - synchronized (this) { - if (this.endpoints.containsKey(topic)) { - return this.endpoints.get(topic); - } - - var endpoint = build(servers, topic); - if (managed) { - this.endpoints.put(topic, endpoint); - } - - return endpoint; - } - } - - /** - * {@inheritDoc}. - */ - @Override - public void destroy(String topic) { - if (topic == null || topic.isEmpty()) { - throw new IllegalArgumentException(MISSING_TOPIC_MESSAGE); - } - - T endpoint; - synchronized (this) { - if (!this.endpoints.containsKey(topic)) { - return; - } - - endpoint = this.endpoints.remove(topic); - } - endpoint.shutdown(); - } - - /** - * {@inheritDoc}. - */ - @Override - public void destroy() { - final List snapshotEndpoints = this.inventory(); - for (final T snapshot : snapshotEndpoints) { - snapshot.shutdown(); - } - - synchronized (this) { - this.endpoints.clear(); - } - } - - /** - * {@inheritDoc}. - */ - @Override - public T get(String topic) { - if (topic == null || topic.isEmpty()) { - throw new IllegalArgumentException(MISSING_TOPIC_MESSAGE); - } - - synchronized (this) { - if (this.endpoints.containsKey(topic)) { - return this.endpoints.get(topic); - } else { - throw new IllegalStateException(topic + " not found"); - } - } - } - - /** - * {@inheritDoc}. - */ - @Override - public List inventory() { - return new ArrayList<>(this.endpoints.values()); - } - - /** - * {@inheritDoc}. - */ - @Override - public String toString() { - return "TopicBaseHashedFactory[ " + super.toString() + " ]"; - } -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusConsumer.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusConsumer.java deleted file mode 100644 index b46c2715..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusConsumer.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2018 Samsung Electronics Co., Ltd. - * Modifications Copyright (C) 2020,2023 Bell Canada. All rights reserved. - * Modifications Copyright (C) 2022-2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus.internal; - -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.api.trace.TraceFlags; -import io.opentelemetry.api.trace.TraceState; -import io.opentelemetry.context.Context; -import io.opentelemetry.instrumentation.kafkaclients.v2_6.TracingConsumerInterceptor; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.time.Duration; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Properties; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import lombok.Data; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.apache.kafka.clients.consumer.ConsumerConfig; -import org.apache.kafka.clients.consumer.ConsumerRecord; -import org.apache.kafka.clients.consumer.ConsumerRecords; -import org.apache.kafka.clients.consumer.KafkaConsumer; -import org.apache.kafka.clients.consumer.OffsetAndMetadata; -import org.apache.kafka.common.TopicPartition; -import org.apache.kafka.common.header.Headers; -import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Wrapper around libraries to consume from message bus. - */ -public interface BusConsumer { - - /** - * fetch messages. - * - * @return list of messages - * @throws IOException when error encountered by underlying libraries - */ - public Iterable fetch() throws IOException; - - /** - * close underlying library consumer. - */ - public void close(); - - /** - * Consumer that handles fetch() failures by sleeping. - */ - abstract class FetchingBusConsumer implements BusConsumer { - private static final Logger logger = LoggerFactory.getLogger(FetchingBusConsumer.class); - - /** - * Fetch timeout. - */ - protected int fetchTimeout; - - /** - * Time to sleep on a fetch failure. - */ - @Getter - private final int sleepTime; - - /** - * Counted down when {@link #close()} is invoked. - */ - private final CountDownLatch closeCondition = new CountDownLatch(1); - - - /** - * Constructs the object. - * - * @param busTopicParams parameters for the bus topic - */ - protected FetchingBusConsumer(BusTopicParams busTopicParams) { - this.fetchTimeout = busTopicParams.getFetchTimeout(); - - if (this.fetchTimeout <= 0) { - this.sleepTime = PolicyEndPointProperties.DEFAULT_TIMEOUT_MS_FETCH; - } else { - // don't sleep too long, even if fetch timeout is large - this.sleepTime = Math.min(this.fetchTimeout, PolicyEndPointProperties.DEFAULT_TIMEOUT_MS_FETCH); - } - } - - /** - * Causes the thread to sleep; invoked after fetch() fails. If the consumer is closed, - * or the thread is interrupted, then this will return immediately. - */ - protected void sleepAfterFetchFailure() { - try { - logger.info("{}: backoff for {}ms", this, sleepTime); - if (this.closeCondition.await(this.sleepTime, TimeUnit.MILLISECONDS)) { - logger.info("{}: closed while handling fetch error", this); - } - - } catch (InterruptedException e) { - logger.warn("{}: interrupted while handling fetch error", this, e); - Thread.currentThread().interrupt(); - } - } - - @Override - public void close() { - this.closeCondition.countDown(); - } - } - - /** - * Kafka based consumer. - */ - class KafkaConsumerWrapper extends FetchingBusConsumer { - - /** - * logger. - */ - private static final Logger logger = LoggerFactory.getLogger(KafkaConsumerWrapper.class); - - private static final String KEY_DESERIALIZER = "org.apache.kafka.common.serialization.StringDeserializer"; - - /** - * Kafka consumer. - */ - protected KafkaConsumer consumer; - protected Properties kafkaProps; - - protected boolean allowTracing; - - /** - * Kafka Consumer Wrapper. - * BusTopicParam - object contains the following parameters - * servers - messaging bus hosts. - * topic - topic - * - * @param busTopicParams - The parameters for the bus topic - */ - public KafkaConsumerWrapper(BusTopicParams busTopicParams) { - super(busTopicParams); - - if (busTopicParams.isTopicInvalid()) { - throw new IllegalArgumentException("No topic for Kafka"); - } - - //Setup Properties for consumer - kafkaProps = new Properties(); - kafkaProps.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, - busTopicParams.getServers().get(0)); - - if (busTopicParams.isAdditionalPropsValid()) { - kafkaProps.putAll(busTopicParams.getAdditionalProps()); - } - - if (kafkaProps.get(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG) == null) { - kafkaProps.setProperty(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, KEY_DESERIALIZER); - } - if (kafkaProps.get(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG) == null) { - kafkaProps.setProperty(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, KEY_DESERIALIZER); - } - if (kafkaProps.get(ConsumerConfig.GROUP_ID_CONFIG) == null) { - kafkaProps.setProperty(ConsumerConfig.GROUP_ID_CONFIG, busTopicParams.getConsumerGroup()); - } - if (busTopicParams.isAllowTracing()) { - this.allowTracing = true; - kafkaProps.setProperty(ConsumerConfig.INTERCEPTOR_CLASSES_CONFIG, - TracingConsumerInterceptor.class.getName()); - } - - consumer = new KafkaConsumer<>(kafkaProps); - //Subscribe to the topic - consumer.subscribe(List.of(busTopicParams.getTopic())); - } - - @Override - public Iterable fetch() { - ConsumerRecords records = this.consumer.poll(Duration.ofMillis(fetchTimeout)); - if (records == null || records.count() <= 0) { - return Collections.emptyList(); - } - List messages = new ArrayList<>(records.count()); - try { - if (allowTracing) { - createParentTraceContext(records); - } - - for (TopicPartition partition : records.partitions()) { - List> partitionRecords = records.records(partition); - for (ConsumerRecord partitionRecord : partitionRecords) { - messages.add(partitionRecord.value()); - } - long lastOffset = partitionRecords.get(partitionRecords.size() - 1).offset(); - consumer.commitSync(Collections.singletonMap(partition, new OffsetAndMetadata(lastOffset + 1))); - } - } catch (Exception e) { - logger.error("{}: cannot fetch, throwing exception after sleep...", this); - sleepAfterFetchFailure(); - throw e; - } - return messages; - } - - private void createParentTraceContext(ConsumerRecords records) { - TraceParentInfo traceParentInfo = new TraceParentInfo(); - for (ConsumerRecord consumerRecord : records) { - - Headers consumerRecordHeaders = consumerRecord.headers(); - traceParentInfo = processTraceParentHeader(consumerRecordHeaders); - } - - SpanContext spanContext = SpanContext.createFromRemoteParent( - traceParentInfo.getTraceId(), traceParentInfo.getSpanId(), - TraceFlags.getSampled(), TraceState.builder().build()); - - Context.current().with(Span.wrap(spanContext)).makeCurrent(); - } - - private TraceParentInfo processTraceParentHeader(Headers headers) { - TraceParentInfo traceParentInfo = new TraceParentInfo(); - if (headers.lastHeader("traceparent") != null) { - traceParentInfo.setParentTraceId(new String(headers.lastHeader( - "traceparent").value(), StandardCharsets.UTF_8)); - - String[] parts = traceParentInfo.getParentTraceId().split("-"); - traceParentInfo.setTraceId(parts[1]); - traceParentInfo.setSpanId(parts[2]); - } - - return traceParentInfo; - } - - @Data - @NoArgsConstructor - private static class TraceParentInfo { - private String parentTraceId; - private String traceId; - private String spanId; - } - - @Override - public void close() { - super.close(); - this.consumer.close(); - logger.info("Kafka Consumer exited {}", this); - } - - @Override - public String toString() { - return "KafkaConsumerWrapper [fetchTimeout=" + fetchTimeout + "]"; - } - } -} - - diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusPublisher.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusPublisher.java deleted file mode 100644 index 1b57e48e..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusPublisher.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2018 Samsung Electronics Co., Ltd. - * Modifications Copyright (C) 2020,2023 Bell Canada. All rights reserved. - * Modifications Copyright (C) 2022-2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus.internal; - -import io.opentelemetry.instrumentation.kafkaclients.v2_6.TracingProducerInterceptor; -import java.util.Properties; -import java.util.UUID; -import org.apache.kafka.clients.producer.KafkaProducer; -import org.apache.kafka.clients.producer.Producer; -import org.apache.kafka.clients.producer.ProducerConfig; -import org.apache.kafka.clients.producer.ProducerRecord; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public interface BusPublisher { - - String NO_MESSAGE_PROVIDED = "No message provided"; - String LOG_CLOSE = "{}: CLOSE"; - String LOG_CLOSE_FAILED = "{}: CLOSE FAILED"; - - /** - * sends a message. - * - * @param partitionId id - * @param message the message - * @return true if success, false otherwise - * @throws IllegalArgumentException if no message provided - */ - boolean send(String partitionId, String message); - - /** - * closes the publisher. - */ - void close(); - - /** - * Kafka based library publisher. - */ - class KafkaPublisherWrapper implements BusPublisher { - - private static final Logger logger = LoggerFactory.getLogger(KafkaPublisherWrapper.class); - private static final String KEY_SERIALIZER = "org.apache.kafka.common.serialization.StringSerializer"; - - private final String topic; - - /** - * Kafka publisher. - */ - private final Producer producer; - protected Properties kafkaProps; - - /** - * Kafka Publisher Wrapper. - * - * @param busTopicParams topic parameters - */ - protected KafkaPublisherWrapper(BusTopicParams busTopicParams) { - - if (busTopicParams.isTopicInvalid()) { - throw new IllegalArgumentException("No topic for Kafka"); - } - - this.topic = busTopicParams.getTopic(); - - // Setup Properties for consumer - kafkaProps = new Properties(); - kafkaProps.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, busTopicParams.getServers().get(0)); - if (busTopicParams.isAdditionalPropsValid()) { - kafkaProps.putAll(busTopicParams.getAdditionalProps()); - } - if (kafkaProps.get(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG) == null) { - kafkaProps.setProperty(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, KEY_SERIALIZER); - } - if (kafkaProps.get(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG) == null) { - kafkaProps.setProperty(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, KEY_SERIALIZER); - } - - if (busTopicParams.isAllowTracing()) { - kafkaProps.setProperty(ProducerConfig.INTERCEPTOR_CLASSES_CONFIG, - TracingProducerInterceptor.class.getName()); - } - - producer = new KafkaProducer<>(kafkaProps); - } - - @Override - public boolean send(String partitionId, String message) { - if (message == null) { - throw new IllegalArgumentException(NO_MESSAGE_PROVIDED); - } - - try { - // Create the record - ProducerRecord producerRecord = - new ProducerRecord<>(topic, UUID.randomUUID().toString(), message); - - this.producer.send(producerRecord); - producer.flush(); - } catch (Exception e) { - logger.warn("{}: SEND of {} cannot be performed because of {}", this, message, e.getMessage(), e); - return false; - } - return true; - } - - @Override - public void close() { - logger.info(LOG_CLOSE, this); - - try { - this.producer.close(); - } catch (Exception e) { - logger.warn("{}: CLOSE FAILED because of {}", this, e.getMessage(), e); - } - } - - @Override - public String toString() { - return "KafkaPublisherWrapper []"; - } - - } -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicBase.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicBase.java deleted file mode 100644 index f8236d3d..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicBase.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2017-2019, 2021 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2020 Bell Canada. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus.internal; - -import lombok.Getter; -import org.onap.policy.common.endpoints.event.comm.bus.ApiKeyEnabled; - -/** - * Bus Topic Base. - */ -@Getter -public abstract class BusTopicBase extends TopicBase implements ApiKeyEnabled { - - /** - * API Key. - */ - protected String apiKey; - - /** - * API Secret. - */ - protected String apiSecret; - - /** - * Use https. - */ - protected boolean useHttps; - - /** - * Allow tracing. - */ - protected boolean allowTracing; - - /** - * allow self signed certificates. - */ - protected boolean allowSelfSignedCerts; - - /** - * Instantiates a new Bus Topic Base. - * - *

servers list of servers - * topic topic name - * apiKey API Key - * apiSecret API Secret - * useHttps does connection use HTTPS? - * allowTracing Is tracing allowed? - * allowSelfSignedCerts are self-signed certificates allow - * @param busTopicParams holds all our parameters - * @throws IllegalArgumentException if invalid parameters are present - */ - protected BusTopicBase(BusTopicParams busTopicParams) { - super(busTopicParams.getServers(), busTopicParams.getTopic(), busTopicParams.getEffectiveTopic()); - this.apiKey = busTopicParams.getApiKey(); - this.apiSecret = busTopicParams.getApiSecret(); - this.useHttps = busTopicParams.isUseHttps(); - this.allowTracing = busTopicParams.isAllowTracing(); - this.allowSelfSignedCerts = busTopicParams.isAllowSelfSignedCerts(); - } - - protected boolean anyNullOrEmpty(String... args) { - for (String arg : args) { - if (arg == null || arg.isEmpty()) { - return true; - } - } - - return false; - } - - protected boolean allNullOrEmpty(String... args) { - for (String arg : args) { - if (!(arg == null || arg.isEmpty())) { - return false; - } - } - - return true; - } - - - @Override - public String toString() { - return "BusTopicBase [apiKey=" + apiKey + ", apiSecret=" + apiSecret + ", useHttps=" + useHttps - + ", allowSelfSignedCerts=" + allowSelfSignedCerts + ", toString()=" + super.toString() + "]"; - } - -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicParams.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicParams.java deleted file mode 100644 index 53a6ab66..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicParams.java +++ /dev/null @@ -1,338 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved. - * Modifications Copyright (C) 2018-2019, 2021 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2019, 2023-2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus.internal; - -import java.util.List; -import java.util.Map; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import org.apache.commons.lang3.StringUtils; - -/** - * Member variables of this Params class are as follows. - * - *

servers Kafka servers - * topic Kafka Topic to be monitored - * apiKey Kafka API Key (optional) - * apiSecret Kafka API Secret (optional) - * consumerGroup kafka Reader Consumer Group - * consumerInstance Kafka Reader Instance - * fetchTimeout kafka fetch timeout - * fetchLimit Kafka fetch limit - * environment DME2 Environment - * aftEnvironment DME2 AFT Environment - * partner DME2 Partner - * latitude DME2 Latitude - * longitude DME2 Longitude - * additionalProps Additional properties to pass to DME2 - * useHttps does connection use HTTPS? - * allowTracing is message tracing allowed? - * allowSelfSignedCerts are self-signed certificates allow - */ -@Getter -@Setter -public class BusTopicParams { - - private int port; - private List servers; - private Map additionalProps; - private String topic; - private String effectiveTopic; - private String apiKey; - private String apiSecret; - private String consumerGroup; - private String consumerInstance; - private int fetchTimeout; - private int fetchLimit; - private boolean useHttps; - private boolean allowTracing; - private boolean allowSelfSignedCerts; - private boolean managed; - - private String userName; - private String password; - private String environment; - private String aftEnvironment; - private String partner; - private String latitude; - private String longitude; - private String partitionId; - private String clientName; - private String hostname; - private String basePath; - @Getter - private String serializationProvider; - - public static TopicParamsBuilder builder() { - return new TopicParamsBuilder(); - } - - /** - * Methods to Check if the property is INVALID. - */ - - boolean isEnvironmentInvalid() { - return StringUtils.isBlank(environment); - } - - boolean isAftEnvironmentInvalid() { - return StringUtils.isBlank(aftEnvironment); - } - - boolean isLatitudeInvalid() { - return StringUtils.isBlank(latitude); - } - - boolean isLongitudeInvalid() { - return StringUtils.isBlank(longitude); - } - - boolean isConsumerInstanceInvalid() { - return StringUtils.isBlank(consumerInstance); - } - - boolean isConsumerGroupInvalid() { - return StringUtils.isBlank(consumerGroup); - } - - public boolean isClientNameInvalid() { - return StringUtils.isBlank(clientName); - } - - boolean isPartnerInvalid() { - return StringUtils.isBlank(partner); - } - - boolean isServersInvalid() { - return (servers == null || servers.isEmpty() - || (servers.size() == 1 && ("".equals(servers.get(0))))); - } - - boolean isTopicInvalid() { - return StringUtils.isBlank(topic); - } - - boolean isPartitionIdInvalid() { - return StringUtils.isBlank(partitionId); - } - - public boolean isHostnameInvalid() { - return StringUtils.isBlank(hostname); - } - - public boolean isPortInvalid() { - return (getPort() <= 0 || getPort() >= 65535); - } - - /** - * Methods to Check if the property is Valid. - */ - - boolean isApiKeyValid() { - return StringUtils.isNotBlank(apiKey); - } - - boolean isApiSecretValid() { - return StringUtils.isNotBlank(apiSecret); - } - - boolean isUserNameValid() { - return StringUtils.isNotBlank(userName); - } - - boolean isPasswordValid() { - return StringUtils.isNotBlank(password); - } - - boolean isAdditionalPropsValid() { - return additionalProps != null; - } - - public void setEffectiveTopic(String effectiveTopic) { - this.effectiveTopic = topicToLowerCase(effectiveTopic); - } - - public void setTopic(String topic) { - this.topic = topicToLowerCase(topic); - } - - public String getEffectiveTopic() { - return topicToLowerCase(effectiveTopic); - } - - public String getTopic() { - return topicToLowerCase(topic); - } - - private String topicToLowerCase(String topic) { - return (topic == null || topic.isEmpty()) ? topic : topic.toLowerCase(); - } - - @NoArgsConstructor(access = AccessLevel.PRIVATE) - public static class TopicParamsBuilder { - - final BusTopicParams params = new BusTopicParams(); - - public TopicParamsBuilder servers(List servers) { - this.params.servers = servers; - return this; - } - - public TopicParamsBuilder topic(String topic) { - this.params.setTopic(topic); - return this; - } - - public TopicParamsBuilder effectiveTopic(String effectiveTopic) { - this.params.setEffectiveTopic(effectiveTopic); - return this; - } - - public TopicParamsBuilder apiKey(String apiKey) { - this.params.apiKey = apiKey; - return this; - } - - public TopicParamsBuilder apiSecret(String apiSecret) { - this.params.apiSecret = apiSecret; - return this; - } - - public TopicParamsBuilder consumerGroup(String consumerGroup) { - this.params.consumerGroup = consumerGroup; - return this; - } - - public TopicParamsBuilder consumerInstance(String consumerInstance) { - this.params.consumerInstance = consumerInstance; - return this; - } - - public TopicParamsBuilder fetchTimeout(int fetchTimeout) { - this.params.fetchTimeout = fetchTimeout; - return this; - } - - public TopicParamsBuilder fetchLimit(int fetchLimit) { - this.params.fetchLimit = fetchLimit; - return this; - } - - public TopicParamsBuilder useHttps(boolean useHttps) { - this.params.useHttps = useHttps; - return this; - } - - public TopicParamsBuilder allowTracing(boolean allowTracing) { - this.params.allowTracing = allowTracing; - return this; - } - - public TopicParamsBuilder allowSelfSignedCerts(boolean allowSelfSignedCerts) { - this.params.allowSelfSignedCerts = allowSelfSignedCerts; - return this; - } - - public TopicParamsBuilder userName(String userName) { - this.params.userName = userName; - return this; - } - - public TopicParamsBuilder password(String password) { - this.params.password = password; - return this; - } - - public TopicParamsBuilder environment(String environment) { - this.params.environment = environment; - return this; - } - - public TopicParamsBuilder aftEnvironment(String aftEnvironment) { - this.params.aftEnvironment = aftEnvironment; - return this; - } - - public TopicParamsBuilder partner(String partner) { - this.params.partner = partner; - return this; - } - - public TopicParamsBuilder latitude(String latitude) { - this.params.latitude = latitude; - return this; - } - - public TopicParamsBuilder longitude(String longitude) { - this.params.longitude = longitude; - return this; - } - - public TopicParamsBuilder additionalProps(Map additionalProps) { - this.params.additionalProps = additionalProps; - return this; - } - - public TopicParamsBuilder partitionId(String partitionId) { - this.params.partitionId = partitionId; - return this; - } - - public BusTopicParams build() { - return params; - } - - public TopicParamsBuilder managed(boolean managed) { - this.params.managed = managed; - return this; - } - - public TopicParamsBuilder hostname(String hostname) { - this.params.hostname = hostname; - return this; - } - - public TopicParamsBuilder clientName(String clientName) { - this.params.clientName = clientName; - return this; - } - - public TopicParamsBuilder port(int port) { - this.params.port = port; - return this; - } - - public TopicParamsBuilder basePath(String basePath) { - this.params.basePath = basePath; - return this; - } - - public TopicParamsBuilder serializationProvider(String serializationProvider) { - this.params.serializationProvider = serializationProvider; - return this; - } - } -} - diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineBusTopicSink.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineBusTopicSink.java deleted file mode 100644 index 9b724072..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineBusTopicSink.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2018-2019 Samsung Electronics Co., Ltd. - * Modifications Copyright (C) 2020 Bell Canada. All rights reserved. - * Modifications Copyright (C) 2023-2024 Nordix Foundation. -* ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus.internal; - -import java.util.UUID; -import lombok.Getter; -import lombok.Setter; -import org.onap.policy.common.endpoints.event.comm.bus.BusTopicSink; -import org.onap.policy.common.endpoints.utils.NetLoggerUtil; -import org.onap.policy.common.endpoints.utils.NetLoggerUtil.EventType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Transport Agnostic Bus Topic Sink to carry out the core functionality to interact with a sink. - * - */ -public abstract class InlineBusTopicSink extends BusTopicBase implements BusTopicSink { - - /** - * Loggers. - */ - private static Logger logger = LoggerFactory.getLogger(InlineBusTopicSink.class); - - /** - * The partition key to publish to. - */ - @Getter - @Setter - protected String partitionKey; - - /** - * Message bus publisher. - */ - protected BusPublisher publisher; - - /** - * Constructor for abstract sink. - * @param busTopicParams contains below listed attributes - * servers servers - * topic topic - * apiKey api secret - * apiSecret api secret - * partitionId partition id - * useHttps does connection use HTTPS? - * allowTracing is tracing allowed? - * allowSelfSignedCerts are self-signed certificates allow * - * @throws IllegalArgumentException if invalid parameters are passed in - */ - protected InlineBusTopicSink(BusTopicParams busTopicParams) { - - super(busTopicParams); - - if (busTopicParams.isPartitionIdInvalid()) { - this.partitionKey = UUID.randomUUID().toString(); - } else { - this.partitionKey = busTopicParams.getPartitionId(); - } - } - - /** - * Initialize the Bus publisher. - */ - public abstract void init(); - - @Override - public boolean start() { - logger.info("{}: starting", this); - - synchronized (this) { - if (!this.alive) { - if (locked) { - throw new IllegalStateException(this + " is locked."); - } - - this.init(); - this.alive = true; - } - } - - return true; - } - - @Override - public boolean stop() { - - BusPublisher publisherCopy; - synchronized (this) { - this.alive = false; - publisherCopy = this.publisher; - this.publisher = null; - } - - if (publisherCopy != null) { - try { - publisherCopy.close(); - } catch (Exception e) { - logger.warn("{}: cannot stop publisher because of {}", this, e.getMessage(), e); - } - } else { - logger.warn("{}: there is no publisher", this); - return false; - } - - return true; - } - - @Override - public boolean send(String message) { - - if (message == null || message.isEmpty()) { - throw new IllegalArgumentException("Message to send is empty"); - } - - if (!this.alive) { - throw new IllegalStateException(this + " is stopped"); - } - - try { - synchronized (this) { - this.recentEvents.add(message); - } - - NetLoggerUtil.log(EventType.OUT, this.getTopicCommInfrastructure(), this.topic, message); - - publisher.send(this.partitionKey, message); - broadcast(message); - } catch (Exception e) { - logger.warn("{}: cannot send because of {}", this, e.getMessage(), e); - return false; - } - - return true; - } - - @Override - public void shutdown() { - this.stop(); - } - - @Override - public String toString() { - return "InlineBusTopicSink [partitionId=" + partitionKey + ", alive=" + alive + ", publisher=" + publisher - + "]"; - } -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineKafkaTopicSink.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineKafkaTopicSink.java deleted file mode 100644 index 6354f762..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineKafkaTopicSink.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022-2023 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus.internal; - -import java.util.Map; -import org.onap.policy.common.endpoints.event.comm.Topic; -import org.onap.policy.common.endpoints.event.comm.bus.KafkaTopicSink; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This implementation publishes events for the associated KAFKA topic, inline with the calling - * thread. - */ -public class InlineKafkaTopicSink extends InlineBusTopicSink implements KafkaTopicSink { - - /** - * Logger. - */ - private static final Logger logger = LoggerFactory.getLogger(InlineKafkaTopicSink.class); - - protected Map additionalProps; - - /** - * Argument-based KAFKA Topic Writer instantiation. BusTopicParams contains the below - * attributes. - * - *

servers list of KAFKA servers available for publishing - * topic the topic to publish to - * partitionId the partition key (optional, autogenerated if not provided) - * useHttps does connection use HTTPS? - * @param busTopicParams contains attributes needed - * @throws IllegalArgumentException if invalid arguments are detected - */ - public InlineKafkaTopicSink(BusTopicParams busTopicParams) { - super(busTopicParams); - this.additionalProps = busTopicParams.getAdditionalProps(); - } - - /** - * Instantiation of internal resources. - */ - @Override - public void init() { - - this.publisher = new BusPublisher.KafkaPublisherWrapper(BusTopicParams.builder() - .servers(this.servers) - .topic(this.effectiveTopic) - .useHttps(this.useHttps) - .allowTracing(this.allowTracing) - .additionalProps(this.additionalProps) - .build()); - logger.info("{}: KAFKA SINK created", this); - } - - @Override - public String toString() { - return "InlineKafkaTopicSink [getTopicCommInfrastructure()=" + getTopicCommInfrastructure() + ", toString()=" - + super.toString() + "]"; - } - - @Override - public CommInfrastructure getTopicCommInfrastructure() { - return Topic.CommInfrastructure.KAFKA; - } -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedBusTopicSource.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedBusTopicSource.java deleted file mode 100644 index f98b481f..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedBusTopicSource.java +++ /dev/null @@ -1,287 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2018-2019 Samsung Electronics Co., Ltd. - * Modifications Copyright (C) 2020 Bell Canada. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus.internal; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.util.UUID; -import lombok.Getter; -import org.onap.policy.common.endpoints.event.comm.TopicListener; -import org.onap.policy.common.endpoints.event.comm.bus.BusTopicSource; -import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; -import org.onap.policy.common.endpoints.utils.NetLoggerUtil; -import org.onap.policy.common.endpoints.utils.NetLoggerUtil.EventType; -import org.onap.policy.common.utils.network.NetworkUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This topic source implementation specializes in reading messages over a bus topic source and - * notifying its listeners. - */ -public abstract class SingleThreadedBusTopicSource extends BusTopicBase - implements Runnable, BusTopicSource { - - /** - * Not to be converted to PolicyLogger. This will contain all instract /out traffic and only - * that in a single file in a concise format. - */ - private static Logger logger = LoggerFactory.getLogger(SingleThreadedBusTopicSource.class); - - /** - * Bus consumer group. - */ - @Getter - protected final String consumerGroup; - - /** - * Bus consumer instance. - */ - @Getter - protected final String consumerInstance; - - /** - * Bus fetch timeout. - */ - @Getter - protected final int fetchTimeout; - - /** - * Bus fetch limit. - */ - @Getter - protected final int fetchLimit; - - /** - * Message Bus Consumer. - */ - protected BusConsumer consumer; - - /** - * Independent thread reading message over my topic. - */ - protected Thread busPollerThread; - - - /** - * Constructor. - * - * @param busTopicParams topic parameters - * - * @throws IllegalArgumentException An invalid parameter passed in - */ - protected SingleThreadedBusTopicSource(BusTopicParams busTopicParams) { - - super(busTopicParams); - - if (busTopicParams.isConsumerGroupInvalid() && busTopicParams.isConsumerInstanceInvalid()) { - this.consumerGroup = UUID.randomUUID().toString(); - this.consumerInstance = NetworkUtil.getHostname(); - - } else if (busTopicParams.isConsumerGroupInvalid()) { - this.consumerGroup = UUID.randomUUID().toString(); - this.consumerInstance = busTopicParams.getConsumerInstance(); - - } else if (busTopicParams.isConsumerInstanceInvalid()) { - this.consumerGroup = busTopicParams.getConsumerGroup(); - this.consumerInstance = UUID.randomUUID().toString(); - - } else { - this.consumerGroup = busTopicParams.getConsumerGroup(); - this.consumerInstance = busTopicParams.getConsumerInstance(); - } - - if (busTopicParams.getFetchTimeout() <= 0) { - this.fetchTimeout = PolicyEndPointProperties.NO_TIMEOUT_MS_FETCH; - } else { - this.fetchTimeout = busTopicParams.getFetchTimeout(); - } - - if (busTopicParams.getFetchLimit() <= 0) { - this.fetchLimit = PolicyEndPointProperties.NO_LIMIT_FETCH; - } else { - this.fetchLimit = busTopicParams.getFetchLimit(); - } - - } - - /** - * Initialize the Bus client. - */ - public abstract void init() throws MalformedURLException; - - @Override - public void register(TopicListener topicListener) { - - super.register(topicListener); - - try { - if (!alive && !locked) { - this.start(); - } else { - logger.info("{}: register: start not attempted", this); - } - } catch (Exception e) { - logger.warn("{}: cannot start after registration of because of: {}", this, topicListener, e); - } - } - - @Override - public void unregister(TopicListener topicListener) { - boolean stop; - synchronized (this) { - super.unregister(topicListener); - stop = this.topicListeners.isEmpty(); - } - - if (stop) { - this.stop(); - } - } - - @Override - public boolean start() { - logger.info("{}: starting", this); - - synchronized (this) { - - if (alive) { - return true; - } - - if (locked) { - throw new IllegalStateException(this + " is locked."); - } - - if (this.busPollerThread == null || !this.busPollerThread.isAlive() || this.consumer == null) { - - try { - this.init(); - this.alive = true; - this.busPollerThread = makePollerThread(); - this.busPollerThread.setName(this.getTopicCommInfrastructure() + "-source-" + this.getTopic()); - busPollerThread.start(); - return true; - } catch (Exception e) { - throw new IllegalStateException(this + ": cannot start", e); - } - } - } - - return false; - } - - /** - * Makes a new thread to be used for polling. - * - * @return a new Thread - */ - protected Thread makePollerThread() { - return new Thread(this); - } - - @Override - public boolean stop() { - logger.info("{}: stopping", this); - - synchronized (this) { - BusConsumer consumerCopy = this.consumer; - - this.alive = false; - this.consumer = null; - - if (consumerCopy != null) { - try { - consumerCopy.close(); - } catch (Exception e) { - logger.warn("{}: stop failed because of {}", this, e.getMessage(), e); - } - } - } - - Thread.yield(); - - return true; - } - - /** - * Run thread method for the Bus Reader. - */ - @Override - public void run() { - while (this.alive) { - try { - fetchAllMessages(); - } catch (IOException | RuntimeException e) { - logger.error("{}: cannot fetch", this, e); - } - } - - logger.info("{}: exiting thread", this); - } - - private void fetchAllMessages() throws IOException { - for (String event : this.consumer.fetch()) { - synchronized (this) { - this.recentEvents.add(event); - } - - NetLoggerUtil.log(EventType.IN, this.getTopicCommInfrastructure(), this.topic, event); - - broadcast(event); - - if (!this.alive) { - return; - } - } - } - - @Override - public boolean offer(String event) { - if (!this.alive) { - throw new IllegalStateException(this + " is not alive."); - } - - synchronized (this) { - this.recentEvents.add(event); - } - - NetLoggerUtil.log(EventType.IN, this.getTopicCommInfrastructure(), this.topic, event); - - return broadcast(event); - } - - @Override - public String toString() { - return "SingleThreadedBusTopicSource [consumerGroup=" + consumerGroup + ", consumerInstance=" + consumerInstance - + ", fetchTimeout=" + fetchTimeout + ", fetchLimit=" + fetchLimit + ", consumer=" + this.consumer - + ", alive=" + alive + ", locked=" + locked + ", uebThread=" + busPollerThread + ", topicListeners=" - + topicListeners.size() + ", toString()=" + super.toString() + "]"; - } - - @Override - public void shutdown() { - this.stop(); - this.topicListeners.clear(); - } -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedKafkaTopicSource.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedKafkaTopicSource.java deleted file mode 100644 index 869273f0..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedKafkaTopicSource.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022-2023 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus.internal; - -import java.net.MalformedURLException; -import java.util.Map; -import org.onap.policy.common.endpoints.event.comm.Topic; -import org.onap.policy.common.endpoints.event.comm.bus.KafkaTopicSource; - -/** - * This topic source implementation specializes in reading messages over a Kafka Bus topic source and - * notifying its listeners. - */ -public class SingleThreadedKafkaTopicSource extends SingleThreadedBusTopicSource implements KafkaTopicSource { - - protected Map additionalProps = null; - - /** - * Constructor. - * - * @param busTopicParams Parameters object containing all the required inputs - * @throws IllegalArgumentException An invalid parameter passed in - */ - public SingleThreadedKafkaTopicSource(BusTopicParams busTopicParams) { - super(busTopicParams); - this.additionalProps = busTopicParams.getAdditionalProps(); - try { - this.init(); - } catch (Exception e) { - throw new IllegalArgumentException("ERROR during init in kafka-source: cannot create topic " + topic, e); - } - } - - /** - * Initialize the Cambria client. - */ - @Override - public void init() throws MalformedURLException { - BusTopicParams.TopicParamsBuilder builder = BusTopicParams.builder() - .servers(this.servers) - .topic(this.effectiveTopic) - .fetchTimeout(this.fetchTimeout) - .consumerGroup(this.consumerGroup) - .useHttps(this.useHttps) - .allowTracing(this.allowTracing); - - this.consumer = new BusConsumer.KafkaConsumerWrapper(builder - .additionalProps(this.additionalProps) - .build()); - } - - @Override - public CommInfrastructure getTopicCommInfrastructure() { - return Topic.CommInfrastructure.KAFKA; - } - - @Override - public String toString() { - return "SingleThreadedKafkaTopicSource [getTopicCommInfrastructure()=" + getTopicCommInfrastructure() - + ", toString()=" + super.toString() + "]"; - } - -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/TopicBase.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/TopicBase.java deleted file mode 100644 index c63fbcc2..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/bus/internal/TopicBase.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2020 Bell Canada. All rights reserved. - * Modifications Copyright (C) 2023 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus.internal; - -import java.util.ArrayList; -import java.util.List; -import lombok.AccessLevel; -import lombok.Getter; -import org.apache.commons.collections4.queue.CircularFifoQueue; -import org.onap.policy.common.endpoints.event.comm.Topic; -import org.onap.policy.common.endpoints.event.comm.TopicListener; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@Getter -public abstract class TopicBase implements Topic { - - /** - * Logger. - */ - private static final Logger logger = LoggerFactory.getLogger(TopicBase.class); - - /** - * List of servers. - */ - protected List servers; - - /** - * Topic. - */ - protected final String topic; - - /** - * Topic Alias. - */ - protected final String effectiveTopic; - - /** - * Event cache. - */ - protected CircularFifoQueue recentEvents = new CircularFifoQueue<>(10); - - /** - * Am I running? reflects invocation of start()/stop() !locked & start() => alive stop() => - * !alive. - */ - protected volatile boolean alive = false; - - /** - * Am I locked? reflects invocation of lock()/unlock() operations locked => !alive (but not in - * the other direction necessarily) locked => !offer, !run, !start, !stop (but this last one is - * obvious since locked => !alive). - */ - protected volatile boolean locked = false; - - /** - * All my subscribers for new message notifications. - */ - @Getter(AccessLevel.NONE) - protected final ArrayList topicListeners = new ArrayList<>(); - - /** - * Instantiates a new Topic Base. - * - * @param servers list of servers - * @param topic topic name - * - * @throws IllegalArgumentException if invalid parameters are present - */ - protected TopicBase(List servers, String topic) { - this(servers, topic, topic); - } - - /** - * Instantiates a new Topic Base. - * - * @param servers list of servers - * @param topic topic name - * - * @throws IllegalArgumentException if invalid parameters are present - */ - protected TopicBase(List servers, String topic, String effectiveTopic) { - - if (servers == null || servers.isEmpty()) { - throw new IllegalArgumentException("Server(s) must be provided"); - } - - if (topic == null || topic.isEmpty()) { - throw new IllegalArgumentException("A Topic must be provided"); - } - - String effectiveTopicCopy; - if (effectiveTopic == null || effectiveTopic.isEmpty()) { - effectiveTopicCopy = topic; - } else { - effectiveTopicCopy = effectiveTopic; - } - - this.servers = servers; - this.topic = topic.toLowerCase(); - this.effectiveTopic = effectiveTopicCopy.toLowerCase(); - } - - @Override - public void register(TopicListener topicListener) { - - logger.info("{}: registering {}", this, topicListener); - - synchronized (this) { - if (topicListener == null) { - throw new IllegalArgumentException("TopicListener must be provided"); - } - - for (TopicListener listener : this.topicListeners) { - if (listener == topicListener) { - return; - } - } - - this.topicListeners.add(topicListener); - } - } - - @Override - public void unregister(TopicListener topicListener) { - - logger.info("{}: unregistering {}", this, topicListener); - - synchronized (this) { - if (topicListener == null) { - throw new IllegalArgumentException("TopicListener must be provided"); - } - - this.topicListeners.remove(topicListener); - } - } - - /** - * Broadcast event to all listeners. - * - * @param message the event - * @return true if all notifications are performed with no error, false otherwise - */ - protected boolean broadcast(String message) { - List snapshotListeners = this.snapshotTopicListeners(); - - var success = true; - for (TopicListener topicListener : snapshotListeners) { - try { - topicListener.onTopicEvent(this.getTopicCommInfrastructure(), this.topic, message); - } catch (Exception e) { - logger.warn("{}: notification error @ {} because of {}", this, topicListener, e.getMessage(), e); - success = false; - } - } - return success; - } - - /** - * Take a snapshot of current topic listeners. - * - * @return the topic listeners - */ - protected synchronized List snapshotTopicListeners() { - @SuppressWarnings("unchecked") - List listeners = (List) topicListeners.clone(); - return listeners; - } - - @Override - public boolean lock() { - - logger.info("{}: locking", this); - - synchronized (this) { - if (this.locked) { - return true; - } - - this.locked = true; - } - - return this.stop(); - } - - @Override - public boolean unlock() { - logger.info("{}: unlocking", this); - - synchronized (this) { - if (!this.locked) { - return true; - } - - this.locked = false; - } - - try { - return this.start(); - } catch (Exception e) { - logger.warn("{}: cannot after unlocking because of {}", this, e.getMessage(), e); - return false; - } - } - - @Override - public synchronized String[] getRecentEvents() { - var events = new String[recentEvents.size()]; - return recentEvents.toArray(events); - } - - - @Override - public String toString() { - return "TopicBase [servers=" + servers - + ", topic=" + topic - + ", effectiveTopic=" + effectiveTopic - + ", #recentEvents=" + recentEvents.size() - + ", locked=" + locked - + ", #topicListeners=" + topicListeners.size() - + "]"; - } -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/BidirectionalTopicClient.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/BidirectionalTopicClient.java deleted file mode 100644 index 4f601fa8..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/BidirectionalTopicClient.java +++ /dev/null @@ -1,224 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2023 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.client; - -import jakarta.validation.constraints.NotNull; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.BlockingDeque; -import java.util.concurrent.LinkedBlockingDeque; -import java.util.concurrent.TimeUnit; -import lombok.Getter; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.endpoints.event.comm.TopicEndpoint; -import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager; -import org.onap.policy.common.endpoints.event.comm.TopicListener; -import org.onap.policy.common.endpoints.event.comm.TopicSink; -import org.onap.policy.common.endpoints.event.comm.TopicSource; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A "bidirectional" topic, which is a pair of topics, one of which is used to publish - * requests and the other to receive responses. - */ -@Getter -public class BidirectionalTopicClient { - private static final Logger logger = LoggerFactory.getLogger(BidirectionalTopicClient.class); - private static final Coder coder = new StandardCoder(); - - private final String sinkTopic; - private final String sourceTopic; - private final TopicSink sink; - private final TopicSource source; - private final CommInfrastructure sinkTopicCommInfrastructure; - private final CommInfrastructure sourceTopicCommInfrastructure; - - /** - * Used when checking whether a message sent on the sink topic can be received - * on the source topic. When a matching message is received on the incoming topic, - * {@code true} is placed on the queue. If {@link #stopWaiting()} is called or the waiting - * thread is interrupted, then {@code false} is placed on the queue. Whenever a value - * is pulled from the queue, it is immediately placed back on the queue. - */ - private final BlockingDeque checkerQueue = new LinkedBlockingDeque<>(); - - - /** - * Constructs the object. - * - * @param sinkTopic sink topic name - * @param sourceTopic source topic name - * @throws BidirectionalTopicClientException if either topic does not exist - */ - public BidirectionalTopicClient(String sinkTopic, String sourceTopic) throws BidirectionalTopicClientException { - this.sinkTopic = sinkTopic.toLowerCase(); - this.sourceTopic = sourceTopic.toLowerCase(); - - // init sinkClient - List sinks = getTopicEndpointManager().getTopicSinks(sinkTopic); - if (sinks.isEmpty()) { - throw new BidirectionalTopicClientException("no sinks for topic: " + sinkTopic); - } else if (sinks.size() > 1) { - throw new BidirectionalTopicClientException("too many sinks for topic: " + sinkTopic); - } - - this.sink = sinks.get(0); - - // init source - List sources = getTopicEndpointManager().getTopicSources(Collections.singletonList(sourceTopic)); - if (sources.isEmpty()) { - throw new BidirectionalTopicClientException("no sources for topic: " + sourceTopic); - } else if (sources.size() > 1) { - throw new BidirectionalTopicClientException("too many sources for topic: " + sourceTopic); - } - - this.source = sources.get(0); - - this.sinkTopicCommInfrastructure = sink.getTopicCommInfrastructure(); - this.sourceTopicCommInfrastructure = source.getTopicCommInfrastructure(); - } - - public boolean send(String message) { - return sink.send(message); - } - - public void register(TopicListener topicListener) { - source.register(topicListener); - } - - public boolean offer(String event) { - return source.offer(event); - } - - public void unregister(TopicListener topicListener) { - source.unregister(topicListener); - } - - /** - * Determines whether the topic is ready (i.e., {@link #awaitReady(Object, long)} has - * previously returned {@code true}). - * - * @return {@code true}, if the topic is ready to send and receive - */ - public boolean isReady() { - return Boolean.TRUE.equals(checkerQueue.peek()); - } - - /** - * Waits for the bidirectional topic to become "ready" by publishing a message on the - * sink topic and awaiting receipt of the message on the source topic. If the message - * is not received within a few seconds, then it tries again. This process is - * continued until the message is received, {@link #stopWaiting()} is called, or this thread - * is interrupted. Once this returns, subsequent calls will return immediately, always - * with the same value. - * - * @param message message to be sent to the sink topic. Note: the equals() method must - * return {@code true} if and only if two messages are the same - * @param waitMs time to wait, in milliseconds, before re-sending the message - * @return {@code true} if the message was received from the source topic, - * {@code false} if this method was stopped or interrupted before receipt of - * the message - * @throws CoderException if the message cannot be encoded - */ - public synchronized boolean awaitReady(T message, long waitMs) throws CoderException { - // see if we already know the answer - if (!checkerQueue.isEmpty()) { - return checkerQueue.peek(); - } - - final String messageText = coder.encode(message); - - // class of message to be decoded - final TopicListener listener = getTopicListener(message); - - source.register(listener); - - // loop until the message is received - try { - Boolean result; - do { - send(messageText); - } while ((result = checkerQueue.poll(waitMs, TimeUnit.MILLISECONDS)) == null); - - // put it back on the queue - checkerQueue.add(result); - - } catch (InterruptedException e) { - logger.error("interrupted waiting for topic sink {} source {}", sink.getTopic(), source.getTopic(), e); - Thread.currentThread().interrupt(); - checkerQueue.add(Boolean.FALSE); - - } finally { - source.unregister(listener); - } - - return checkerQueue.peek(); - } - - @NotNull - private TopicListener getTopicListener(T message) { - @SuppressWarnings("unchecked") - final Class clazz = (Class) message.getClass(); - - // create a listener to detect when a matching message is received - return (infra, topic, msg) -> { - try { - T incoming = decode(msg, clazz); - - if (message.equals(incoming)) { - logger.info("topic {} is ready; found matching message {}", topic, incoming); - checkerQueue.add(Boolean.TRUE); - } - - } catch (CoderException e) { - logger.warn("cannot decode message from topic {}", topic, e); - decodeFailed(); - } - }; - } - - /** - * Stops any listeners that are currently stuck in {@link #awaitReady(Object)} by - * adding {@code false} to the queue. - */ - public void stopWaiting() { - checkerQueue.add(Boolean.FALSE); - } - - // these may be overridden by junit tests - - protected TopicEndpoint getTopicEndpointManager() { - return TopicEndpointManager.getManager(); - } - - protected T decode(String msg, Class clazz) throws CoderException { - return coder.decode(msg, clazz); - } - - protected void decodeFailed() { - // already logged - nothing else to do - } -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/BidirectionalTopicClientException.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/BidirectionalTopicClientException.java deleted file mode 100644 index 1037d3af..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/BidirectionalTopicClientException.java +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2023 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.client; - -import java.io.Serial; - -/** - * Exception thrown by BidirectionalTopicClient class. - */ -public class BidirectionalTopicClientException extends Exception { - @Serial - private static final long serialVersionUID = 1L; - - public BidirectionalTopicClientException() { - super(); - } - - public BidirectionalTopicClientException(String message) { - super(message); - } - - public BidirectionalTopicClientException(Throwable cause) { - super(cause); - } - - public BidirectionalTopicClientException(String message, Throwable cause) { - super(message, cause); - } - - public BidirectionalTopicClientException(String message, Throwable cause, boolean enableSuppression, - boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - } -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClient.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClient.java deleted file mode 100644 index 0ccc8a75..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClient.java +++ /dev/null @@ -1,114 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP PAP - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2019, 2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.client; - -import java.util.List; -import lombok.Getter; -import lombok.NonNull; -import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager; -import org.onap.policy.common.endpoints.event.comm.TopicSink; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Client for sending messages to a Topic using TopicSink. - */ -@Getter -public class TopicSinkClient { - private static final Logger logger = LoggerFactory.getLogger(TopicSinkClient.class); - - /** - * Coder used to encode messages being sent to the topic. - */ - private static final Coder CODER = new StandardCoder(); - - /** - * Where messages are published. - */ - private final TopicSink sink; - - /** - * Constructs the object. - * - * @param topic topic to which messages should be published - * @throws TopicSinkClientException if the topic does not exist - */ - public TopicSinkClient(final String topic) throws TopicSinkClientException { - final List lst = getTopicSinks(topic.toLowerCase()); - if (lst.isEmpty()) { - throw new TopicSinkClientException("no sinks for topic: " + topic.toLowerCase()); - } - - this.sink = lst.get(0); - } - - /** - * Constructs the client from a sink object. - * - * @param sink topic sink publisher - */ - public TopicSinkClient(@NonNull TopicSink sink) { - this.sink = sink; - } - - - /** - * Gets the canonical topic name. - * - * @return topic name - */ - public String getTopic() { - return this.sink.getTopic(); - } - - /** - * Sends a message to the topic, after encoding the message as json. - * - * @param message message to be encoded and sent - * @return {@code true} if the message was successfully sent/enqueued, {@code false} otherwise - */ - public boolean send(final Object message) { - try { - final String json = CODER.encode(message); - return sink.send(json); - - } catch (RuntimeException | CoderException e) { - logger.warn("send to {} failed because of {}", sink.getTopic(), e.getMessage(), e); - return false; - } - } - - // the remaining methods are wrappers that can be overridden by junit tests - - /** - * Gets the sinks for a given topic. - * - * @param topic the topic of interest - * @return the sinks for the topic - */ - protected List getTopicSinks(final String topic) { - return TopicEndpointManager.getManager().getTopicSinks(topic); - } -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientException.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientException.java deleted file mode 100644 index 431d4f34..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientException.java +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP PAP - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2019, 2023 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.client; - -import java.io.Serial; - -/** - * Exception thrown by TopicSink client classes. - */ -public class TopicSinkClientException extends Exception { - @Serial - private static final long serialVersionUID = 1L; - - public TopicSinkClientException() { - super(); - } - - public TopicSinkClientException(final String message) { - super(message); - } - - public TopicSinkClientException(final Throwable cause) { - super(cause); - } - - public TopicSinkClientException(final String message, final Throwable cause) { - super(message, cause); - } - - public TopicSinkClientException(final String message, final Throwable cause, final boolean enableSuppression, - final boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - } - -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/features/NetLoggerFeatureApi.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/features/NetLoggerFeatureApi.java deleted file mode 100644 index a99ecd26..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/features/NetLoggerFeatureApi.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.features; - -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.endpoints.utils.NetLoggerUtil.EventType; -import org.onap.policy.common.utils.services.OrderedService; -import org.slf4j.Logger; - -/** - * Logging Feature API. Provides interception points before and after logging a message. - */ -public interface NetLoggerFeatureApi extends OrderedService { - - /** - * Intercepts a message before it is logged. - * - * @return true if this feature intercepts and takes ownership of the operation - * preventing the invocation of lower priority features. False, otherwise. - */ - default boolean beforeLog(Logger eventLogger, EventType type, CommInfrastructure protocol, String topic, - String message) { - return false; - } - - /** - * Intercepts a message after it is logged. - * - * @return true if this feature intercepts and takes ownership of the operation - * preventing the invocation of lower priority features. False, otherwise. - */ - default boolean afterLog(Logger eventLogger, EventType type, CommInfrastructure protocol, String topic, - String message) { - return false; - } - -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/features/NetLoggerFeatureProviders.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/features/NetLoggerFeatureProviders.java deleted file mode 100644 index ba84b551..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/features/NetLoggerFeatureProviders.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.features; - -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.onap.policy.common.utils.services.OrderedServiceImpl; - -/** - * Providers for network logging feature. - */ -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class NetLoggerFeatureProviders { - - /** - * Feature providers implementing this interface. - */ - @Getter - private static final OrderedServiceImpl providers = - new OrderedServiceImpl<>(NetLoggerFeatureApi.class); -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/HttpClientFactory.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/HttpClientFactory.java index b155f729..0c76d5fa 100644 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/HttpClientFactory.java +++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/HttpClientFactory.java @@ -4,6 +4,7 @@ * ================================================================================ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. * Modifications Copyright (C) 2018 Samsung Electronics Co., Ltd. + * Modifications Copyright (C) 2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +24,7 @@ package org.onap.policy.common.endpoints.http.client; import java.util.List; import java.util.Properties; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; +import org.onap.policy.common.parameters.topic.BusTopicParams; /** * Http Client Factory. diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/IndexedHttpClientFactory.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/IndexedHttpClientFactory.java index 5f0b1d6e..16d1a263 100644 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/IndexedHttpClientFactory.java +++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/IndexedHttpClientFactory.java @@ -3,7 +3,7 @@ * ONAP * ================================================================================ * Copyright (C) 2017-2019, 2021 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2023 Nordix Foundation. + * Modifications Copyright (C) 2023-2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,10 +29,10 @@ import java.util.HashMap; import java.util.List; import java.util.Properties; import org.apache.commons.lang3.StringUtils; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; import org.onap.policy.common.endpoints.http.client.internal.JerseyClient; import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; -import org.onap.policy.common.endpoints.utils.PropertyUtils; +import org.onap.policy.common.parameters.topic.BusTopicParams; +import org.onap.policy.common.utils.properties.PropertyUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/internal/JerseyClient.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/internal/JerseyClient.java index 130b6c15..d708d7c0 100644 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/internal/JerseyClient.java +++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/client/internal/JerseyClient.java @@ -4,7 +4,7 @@ * ================================================================================ * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved. * Modifications Copyright (C) 2018 Samsung Electronics Co., Ltd. - * Modifications Copyright (C) 2019, 2023 Nordix Foundation. + * Modifications Copyright (C) 2019, 2023-2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,8 +43,8 @@ import lombok.ToString; import org.apache.commons.lang3.StringUtils; import org.glassfish.jersey.client.ClientProperties; import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; import org.onap.policy.common.endpoints.http.client.HttpClient; +import org.onap.policy.common.parameters.topic.BusTopicParams; import org.onap.policy.common.utils.network.NetworkUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/IndexedHttpServletServerFactory.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/IndexedHttpServletServerFactory.java index 7c9aca4c..a67c47fb 100644 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/IndexedHttpServletServerFactory.java +++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/IndexedHttpServletServerFactory.java @@ -31,7 +31,7 @@ import org.apache.commons.lang3.StringUtils; import org.onap.policy.common.endpoints.http.server.internal.JettyJerseyServer; import org.onap.policy.common.endpoints.http.server.internal.JettyStaticResourceServer; import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; -import org.onap.policy.common.endpoints.utils.PropertyUtils; +import org.onap.policy.common.utils.properties.PropertyUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/RestServer.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/RestServer.java index 7e6ce866..10acc179 100644 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/RestServer.java +++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/RestServer.java @@ -29,9 +29,9 @@ import java.util.Optional; import java.util.Properties; import java.util.stream.Collectors; import lombok.ToString; -import org.onap.policy.common.endpoints.parameters.RestServerParameters; import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; import org.onap.policy.common.gson.GsonMessageBodyHandler; +import org.onap.policy.common.parameters.rest.RestServerParameters; import org.onap.policy.common.utils.services.ServiceManagerContainer; /** diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/JsonListener.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/JsonListener.java index 2e171070..90c8338f 100644 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/JsonListener.java +++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/JsonListener.java @@ -4,6 +4,7 @@ * ================================================================================ * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. * Modifications Copyright (C) 2020 Bell Canada. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,8 +24,8 @@ package org.onap.policy.common.endpoints.listeners; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.endpoints.event.comm.TopicListener; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.TopicListener; import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/MessageTypeDispatcher.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/MessageTypeDispatcher.java index 41f9abdb..6639b416 100644 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/MessageTypeDispatcher.java +++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/MessageTypeDispatcher.java @@ -3,6 +3,7 @@ * ONAP * ================================================================================ * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +22,7 @@ package org.onap.policy.common.endpoints.listeners; import java.util.concurrent.ConcurrentHashMap; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; import org.onap.policy.common.utils.coder.StandardCoderObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/RequestIdDispatcher.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/RequestIdDispatcher.java index e575e33b..368fd42b 100644 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/RequestIdDispatcher.java +++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/RequestIdDispatcher.java @@ -3,6 +3,7 @@ * ONAP * ================================================================================ * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +24,7 @@ package org.onap.policy.common.endpoints.listeners; import com.google.common.base.Strings; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; import org.onap.policy.common.utils.coder.StandardCoderObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/ScoListener.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/ScoListener.java index dc6ff12a..bdb30eb1 100644 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/ScoListener.java +++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/ScoListener.java @@ -4,6 +4,7 @@ * ================================================================================ * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. * Modifications Copyright (C) 2020 Bell Canada. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +24,7 @@ package org.onap.policy.common.endpoints.listeners; import lombok.AccessLevel; import lombok.AllArgsConstructor; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/TypedMessageListener.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/TypedMessageListener.java index eea1622b..a879db03 100644 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/TypedMessageListener.java +++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/listeners/TypedMessageListener.java @@ -3,6 +3,7 @@ * ONAP * ================================================================================ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +21,7 @@ package org.onap.policy.common.endpoints.listeners; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; /** * Listener for messages of a certain type. diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/parameters/RestClientParameters.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/parameters/RestClientParameters.java deleted file mode 100644 index 5d02e753..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/parameters/RestClientParameters.java +++ /dev/null @@ -1,57 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.parameters; - -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; -import org.onap.policy.common.parameters.BeanValidationResult; -import org.onap.policy.common.parameters.ParameterGroup; -import org.onap.policy.common.parameters.ValidationStatus; - -public class RestClientParameters extends BusTopicParams implements ParameterGroup { - - private static final String MSG_IS_BLANK = "is blank"; - - @Override - public String getName() { - return getClientName(); - } - - @Override - public void setName(String name) { - setClientName(name); - } - - @Override - public BeanValidationResult validate() { - var result = new BeanValidationResult(getClientName(), this); - if (isHostnameInvalid()) { - result.addResult("hostname", getHostname(), ValidationStatus.INVALID, MSG_IS_BLANK); - } - if (isClientNameInvalid()) { - result.addResult("clientName", getClientName(), ValidationStatus.INVALID, MSG_IS_BLANK); - } - if (isPortInvalid()) { - result.addResult("port", getPort(), ValidationStatus.INVALID, "is not valid"); - } - return result; - } -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/parameters/RestServerParameters.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/parameters/RestServerParameters.java deleted file mode 100644 index 9ffe5cb7..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/parameters/RestServerParameters.java +++ /dev/null @@ -1,57 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2019,2023 Nordix Foundation. - * Modifications Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2021 Bell Canada. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.parameters; - -import lombok.Getter; -import org.onap.policy.common.parameters.ParameterGroupImpl; -import org.onap.policy.common.parameters.annotations.Min; -import org.onap.policy.common.parameters.annotations.NotBlank; -import org.onap.policy.common.parameters.annotations.NotNull; - -/** - * Class to hold all parameters needed for rest server. - * - * @author Ajith Sreekumar (ajith.sreekumar@est.tech) - */ -@NotBlank -@Getter -public class RestServerParameters extends ParameterGroupImpl { - @NotNull - private String host; - - @Min(value = 1) - private int port; - - private String userName; - private String password; - private boolean https; - private boolean sniHostCHeck; - private boolean aaf; - private boolean prometheus; - private String servletClass; - private String servletUriPath; - - public RestServerParameters() { - super(RestServerParameters.class.getSimpleName()); - } -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/parameters/TopicParameterGroup.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/parameters/TopicParameterGroup.java deleted file mode 100644 index d63134bc..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/parameters/TopicParameterGroup.java +++ /dev/null @@ -1,92 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2019, 2024 Nordix Foundation. - * Modifications Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.parameters; - -import java.util.List; -import lombok.Getter; -import lombok.Setter; -import org.apache.commons.lang3.StringUtils; -import org.onap.policy.common.parameters.BeanValidationResult; -import org.onap.policy.common.parameters.ParameterGroupImpl; -import org.onap.policy.common.parameters.ValidationStatus; -import org.onap.policy.common.parameters.annotations.NotBlank; -import org.onap.policy.common.parameters.annotations.NotNull; - -/** - * Class to hold all parameters needed for topic properties. - * - * @author Ajith Sreekumar (ajith.sreekumar@est.tech) - */ -@NotNull -@NotBlank -@Getter -@Setter -public class TopicParameterGroup extends ParameterGroupImpl { - - private List topicSources; - private List topicSinks; - - public TopicParameterGroup() { - super(TopicParameterGroup.class.getSimpleName()); - } - - /** - * {@inheritDoc}. - */ - @Override - public BeanValidationResult validate() { - BeanValidationResult result = super.validate(); - if (result.isValid()) { - var errorMsg = new StringBuilder(); - StringBuilder missingSourceParams = checkMissingMandatoryParams(topicSources); - if (!missingSourceParams.isEmpty()) { - errorMsg.append(missingSourceParams.append("missing in topicSources. ")); - } - StringBuilder missingSinkParams = checkMissingMandatoryParams(topicSinks); - if (!missingSinkParams.isEmpty()) { - errorMsg.append(missingSinkParams.append("missing in topicSinks.")); - } - - if (!errorMsg.isEmpty()) { - errorMsg.insert(0, "Mandatory parameters are missing. "); - result.setResult(ValidationStatus.INVALID, errorMsg.toString()); - } - } - return result; - } - - private StringBuilder checkMissingMandatoryParams(List topicParametersList) { - var missingParams = new StringBuilder(); - for (TopicParameters topicParameters : topicParametersList) { - if (StringUtils.isBlank(topicParameters.getTopic())) { - missingParams.append("topic, "); - } - if (StringUtils.isBlank(topicParameters.getTopicCommInfrastructure())) { - missingParams.append("topicCommInfrastructure, "); - } - if (null == topicParameters.getServers() || topicParameters.getServers().isEmpty()) { - missingParams.append("servers, "); - } - } - return missingParams; - } -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/parameters/TopicParameters.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/parameters/TopicParameters.java deleted file mode 100644 index 94042441..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/parameters/TopicParameters.java +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2019 Nordix Foundation. - * Modifications Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.parameters; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; -import org.onap.policy.common.parameters.annotations.NotBlank; -import org.onap.policy.common.parameters.annotations.NotNull; - -/** - * Class to hold topic details such as name, server and topicCommInfrastructure. - * - * @author Ajith Sreekumar (ajith.sreekumar@est.tech) - */ -@NotNull -@NotBlank -@Getter -@Setter -@EqualsAndHashCode(callSuper = false) -public class TopicParameters extends BusTopicParams { - private String topicCommInfrastructure; - - public TopicParameters() { - // this defaults to true - setManaged(true); - } -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/properties/PolicyEndPointProperties.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/properties/PolicyEndPointProperties.java index 5d36a313..bfb29bdf 100644 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/properties/PolicyEndPointProperties.java +++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/properties/PolicyEndPointProperties.java @@ -29,34 +29,9 @@ public final class PolicyEndPointProperties { /* Generic property suffixes */ - public static final String PROPERTY_TOPIC_SERVERS_SUFFIX = ".servers"; - public static final String PROPERTY_TOPIC_TOPICS_SUFFIX = ".topics"; - public static final String PROPERTY_TOPIC_API_KEY_SUFFIX = ".apiKey"; - public static final String PROPERTY_TOPIC_API_SECRET_SUFFIX = ".apiSecret"; - public static final String PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX = ".effectiveTopic"; - public static final String PROPERTY_TOPIC_EVENTS_SUFFIX = ".events"; - public static final String PROPERTY_TOPIC_EVENTS_FILTER_SUFFIX = ".filter"; - public static final String PROPERTY_TOPIC_EVENTS_CUSTOM_MODEL_CODER_GSON_SUFFIX = ".events.custom.gson"; - - public static final String PROPERTY_TOPIC_SOURCE_CONSUMER_GROUP_SUFFIX = ".consumerGroup"; - public static final String PROPERTY_TOPIC_SOURCE_CONSUMER_INSTANCE_SUFFIX = ".consumerInstance"; - public static final String PROPERTY_TOPIC_SOURCE_FETCH_TIMEOUT_SUFFIX = ".fetchTimeout"; - public static final String PROPERTY_TOPIC_SOURCE_FETCH_LIMIT_SUFFIX = ".fetchLimit"; public static final String PROPERTY_MANAGED_SUFFIX = ".managed"; - public static final String PROPERTY_ADDITIONAL_PROPS_SUFFIX = ".additionalProps"; - - public static final String PROPERTY_TOPIC_SINK_PARTITION_KEY_SUFFIX = ".partitionKey"; - public static final String PROPERTY_ALLOW_SELF_SIGNED_CERTIFICATES_SUFFIX = ".selfSignedCertificates"; - public static final String PROPERTY_NOOP_SOURCE_TOPICS = "noop.source.topics"; - public static final String PROPERTY_NOOP_SINK_TOPICS = "noop.sink.topics"; - - /* KAFKA Properties */ - - public static final String PROPERTY_KAFKA_SOURCE_TOPICS = "kafka.source.topics"; - public static final String PROPERTY_KAFKA_SINK_TOPICS = "kafka.sink.topics"; - /* HTTP Server Properties */ public static final String PROPERTY_HTTP_SERVER_SERVICES = "http.server.services"; @@ -90,33 +65,4 @@ public final class PolicyEndPointProperties { public static final String PROPERTY_HTTP_URL_SUFFIX = PROPERTY_HTTP_CONTEXT_URIPATH_SUFFIX; - /* Topic Sink Values */ - - /** - * Log Failures after X number of retries. - */ - public static final int DEFAULT_LOG_SEND_FAILURES_AFTER = 1; - - - /* Topic Source values */ - - /** - * Default Timeout fetching in milliseconds. - */ - public static final int DEFAULT_TIMEOUT_MS_FETCH = 15000; - - /** - * Default maximum number of messages fetch at the time. - */ - public static final int DEFAULT_LIMIT_FETCH = 100; - - /** - * Definition of No Timeout fetching. - */ - public static final int NO_TIMEOUT_MS_FETCH = -1; - - /** - * Definition of No limit fetching. - */ - public static final int NO_LIMIT_FETCH = -1; } diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/report/HealthCheckReport.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/report/HealthCheckReport.java deleted file mode 100644 index bb80fccb..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/report/HealthCheckReport.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2018 Ericsson. All rights reserved. - * Modifications Copyright (C) 2018, 2021 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.report; - -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -/** - * Class to represent health check report of a service. - * - * @author Ram Krishna Verma (ram.krishna.verma@ericsson.com) - */ -@Getter -@Setter -@ToString -public class HealthCheckReport { - - private String name; - private String url; - private boolean healthy; - private int code; - private String message; -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/utils/KafkaPropertyUtils.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/utils/KafkaPropertyUtils.java deleted file mode 100644 index 2e137ce7..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/utils/KafkaPropertyUtils.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2022-2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.utils; - -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_ADDITIONAL_PROPS_SUFFIX; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.re2j.Pattern; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams.TopicParamsBuilder; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class KafkaPropertyUtils { - private static final Pattern COMMA_SPACE_PAT = Pattern.compile("\\s*,\\s*"); - - /** - * Makes a topic builder, configuring it with properties that are common to both - * sources and sinks. - * - * @param props properties to be used to configure the builder - * @param topic topic being configured - * @param servers target servers - * @return a topic builder - */ - public static TopicParamsBuilder makeBuilder(PropertyUtils props, String topic, String servers) { - - final List serverList = new ArrayList<>(Arrays.asList(COMMA_SPACE_PAT.split(servers))); - return BusTopicParams.builder() - .servers(serverList) - .topic(topic) - .effectiveTopic(props.getString(PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX, topic)) - .managed(props.getBoolean(PROPERTY_MANAGED_SUFFIX, true)) - .additionalProps(getAdditionalProps(props.getString(PROPERTY_ADDITIONAL_PROPS_SUFFIX, ""))); - } - - private static Map getAdditionalProps(String additionalPropsString) { - try { - Map additionalProps = new HashMap<>(); - var converted = new ObjectMapper().readValue(additionalPropsString, Map.class); - converted.forEach((k, v) -> { - if (k instanceof String key && v instanceof String value) { - additionalProps.put(key, value); - } - }); - return additionalProps; - } catch (Exception e) { - return Collections.emptyMap(); - } - - } -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/utils/NetLoggerUtil.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/utils/NetLoggerUtil.java deleted file mode 100644 index 6002c3f6..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/utils/NetLoggerUtil.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.utils; - -import lombok.Getter; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.endpoints.features.NetLoggerFeatureProviders; -import org.onap.policy.common.utils.services.FeatureApiUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A network logging utility class that allows drools applications code to access the - * network log (or other specified loggers) and logging features. - * - */ -public class NetLoggerUtil { - - /** - * Loggers. - */ - private static final Logger logger = LoggerFactory.getLogger(NetLoggerUtil.class); - @Getter - private static final Logger networkLogger = LoggerFactory.getLogger("network"); - - /** - * Constant for the system line separator. - */ - public static final String SYSTEM_LS = System.lineSeparator(); - - /** - * Specifies if the message is coming in or going out. - */ - public enum EventType { - IN, OUT - } - - /** - * Logs a message to the network logger. - * - * @param type can either be IN or OUT - * @param protocol the protocol used to receive/send the message - * @param topic the topic the message came from or null if the type is REST - * @param message message to be logged - */ - public static void log(EventType type, CommInfrastructure protocol, String topic, String message) { - log(networkLogger, type, protocol, topic, message); - } - - /** - * Logs a message to the specified logger (i.e. a controller logger). - * - * @param eventLogger the logger that will have the message appended - * @param type can either be IN or OUT - * @param protocol the protocol used to receive/send the message - * @param topic the topic the message came from or null if the type is REST - * @param message message to be logged - */ - public static void log(Logger eventLogger, EventType type, CommInfrastructure protocol, String topic, - String message) { - if (eventLogger == null) { - logger.debug("the logger is null, defaulting to network logger"); - eventLogger = networkLogger; - } - - if (featureBeforeLog(eventLogger, type, protocol, topic, message)) { - return; - } - - eventLogger.info("[{}|{}|{}]{}{}", type, protocol, topic, SYSTEM_LS, message); - - featureAfterLog(eventLogger, type, protocol, topic, message); - } - - /** - * Executes features that pre-process a message before it is logged. - * - * @param eventLogger the logger that will have the message appended - * @param type can either be IN or OUT - * @param protocol the protocol used to receive/send the message - * @param topic the topic the message came from or null if the type is REST - * @param message message to be logged - * - * @return true if this feature intercepts and takes ownership of the operation - * preventing the invocation of lower priority features. False, otherwise - */ - private static boolean featureBeforeLog(Logger eventLogger, EventType type, CommInfrastructure protocol, - String topic, String message) { - - return FeatureApiUtils.apply(NetLoggerFeatureProviders.getProviders().getList(), - feature -> feature.beforeLog(eventLogger, type, protocol, topic, message), - (feature, ex) -> logger.error("feature {} before-log failure because of {}", - feature.getClass().getName(), ex.getMessage(), ex)); - } - - /** - * Executes features that post-process a message after it is logged. - * - * @param eventLogger the logger that will have the message appended - * @param type can either be IN or OUT - * @param protocol the protocol used to receive/send the message - * @param topic the topic the message came from or null if the type is rest - * @param message message to be logged - * - * @return true if this feature intercepts and takes ownership of the operation - * preventing the invocation of lower priority features. False, otherwise - */ - private static boolean featureAfterLog(Logger eventLogger, EventType type, CommInfrastructure protocol, - String topic, String message) { - - return FeatureApiUtils.apply(NetLoggerFeatureProviders.getProviders().getList(), - feature -> feature.afterLog(eventLogger, type, protocol, topic, message), - (feature, ex) -> logger.error("feature {} after-log failure because of {}", - feature.getClass().getName(), ex.getMessage(), ex)); - } - -} diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/utils/PropertyUtils.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/utils/PropertyUtils.java deleted file mode 100644 index 904f9535..00000000 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/utils/PropertyUtils.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.utils; - -import java.util.Properties; -import lombok.AllArgsConstructor; -import org.apache.commons.lang3.StringUtils; - -/** - * Utilities for extracting property values and converting them to other types. - */ -@AllArgsConstructor -public class PropertyUtils { - /** - * Properties on which to work. - */ - private Properties properties; - - /** - * Prefix to prepend to property names. - */ - private String prefix; - - /** - * Function to invoke if a property value is invalid. - */ - private TriConsumer invalidHandler; - - /** - * Gets a string property. - * - * @param propName name of the property whose value is to be retrieved - * @param defaultValue value to use if the property value is empty or does not exist - * @return the property's value - */ - public String getString(String propName, String defaultValue) { - String propValue = getProperty(propName); - return (StringUtils.isBlank(propValue) ? defaultValue : propValue); - } - - /** - * Gets a boolean property. - * - * @param propName name of the property whose value is to be retrieved - * @param defaultValue value to use if the property value is empty or does not exist - * @return the property's value - */ - public boolean getBoolean(String propName, boolean defaultValue) { - String propValue = getProperty(propName); - - if (!StringUtils.isBlank(propValue)) { - return Boolean.parseBoolean(propValue); - } - - return defaultValue; - } - - /** - * Gets an integer property. - * - * @param propName name of the property whose value is to be retrieved - * @param defaultValue value to use if the property value is empty or does not exist - * @return the property's value - */ - public int getInteger(String propName, int defaultValue) { - String propValue = getProperty(propName); - - if (!StringUtils.isBlank(propValue)) { - try { - return Integer.parseInt(propValue); - - } catch (NumberFormatException nfe) { - invalidHandler.accept(getFullName(propName), propValue, nfe); - } - } - - return defaultValue; - } - - - /** - * Gets a property's value. - * - * @param propName name of the property whose value is to be retrieved - * @return the property's value, or {@code null} if it does not exist - */ - private String getProperty(String propName) { - return properties.getProperty(getFullName(propName)); - } - - /** - * Gets the full property name, with the prefix prepended. - * - * @param propName property name, without the prefix - * @return the full property name - */ - private String getFullName(String propName) { - return prefix + propName; - } - - @FunctionalInterface - public static interface TriConsumer { - public void accept(A propName, B propValue, C exception); - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/TopicEndpointProxyTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/TopicEndpointProxyTest.java deleted file mode 100644 index a30904dd..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/TopicEndpointProxyTest.java +++ /dev/null @@ -1,400 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm; - -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.LinkedList; -import java.util.List; -import java.util.Properties; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.endpoints.event.comm.bus.KafkaTopicFactories; -import org.onap.policy.common.endpoints.event.comm.bus.KafkaTopicPropertyBuilder; -import org.onap.policy.common.endpoints.event.comm.bus.NoopTopicFactories; -import org.onap.policy.common.endpoints.event.comm.bus.NoopTopicPropertyBuilder; -import org.onap.policy.common.endpoints.parameters.TopicParameterGroup; -import org.onap.policy.common.endpoints.parameters.TopicParameters; -import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; -import org.onap.policy.common.utils.gson.GsonTestUtils; - -class TopicEndpointProxyTest { - - private static final String NOOP_SOURCE_TOPIC = "noop-source"; - private static final String NOOP_SINK_TOPIC = "noop-sink"; - - private static final String KAFKA_SOURCE_TOPIC = "kafka-source"; - private static final String KAFKA_SINK_TOPIC = "kafka-sink"; - - private final Properties configuration = new Properties(); - private final TopicParameterGroup group = new TopicParameterGroup(); - - /** - * Constructor. - */ - public TopicEndpointProxyTest() { - group.setTopicSinks(new LinkedList<>()); - group.setTopicSources(new LinkedList<>()); - - NoopTopicPropertyBuilder noopSourceBuilder = - new NoopTopicPropertyBuilder(PolicyEndPointProperties.PROPERTY_NOOP_SOURCE_TOPICS) - .makeTopic(NOOP_SOURCE_TOPIC); - configuration.putAll(noopSourceBuilder.build()); - group.getTopicSources().add(noopSourceBuilder.getParams()); - - NoopTopicPropertyBuilder noopSinkBuilder = - new NoopTopicPropertyBuilder(PolicyEndPointProperties.PROPERTY_NOOP_SINK_TOPICS) - .makeTopic(NOOP_SINK_TOPIC); - configuration.putAll(noopSinkBuilder.build()); - group.getTopicSinks().add(noopSinkBuilder.getParams()); - - TopicParameters invalidCommInfraParams = - new NoopTopicPropertyBuilder(PolicyEndPointProperties.PROPERTY_NOOP_SOURCE_TOPICS) - .makeTopic(NOOP_SOURCE_TOPIC).getParams(); - invalidCommInfraParams.setTopicCommInfrastructure(Topic.CommInfrastructure.REST.name()); - group.getTopicSources().add(invalidCommInfraParams); - group.getTopicSinks().add(invalidCommInfraParams); - } - - private boolean exists(List topics, String topicName) { - return topics.stream().map(Topic::getTopic).anyMatch(topicName::equals); - } - - private boolean allSources(List topics) { - return exists(topics, NOOP_SOURCE_TOPIC); - } - - private boolean allSinks(List topics) { - return exists(topics, NOOP_SINK_TOPIC); - } - - private boolean anySource(List topics) { - return exists(topics, NOOP_SOURCE_TOPIC); - } - - private boolean anySink(List topics) { - return exists(topics, NOOP_SINK_TOPIC); - } - - /** - * Destroys all managed topics. - */ - @AfterEach - public void tearDown() { - NoopTopicFactories.getSinkFactory().destroy(); - NoopTopicFactories.getSourceFactory().destroy(); - KafkaTopicFactories.getSinkFactory().destroy(); - KafkaTopicFactories.getSourceFactory().destroy(); - } - - @Test - void testSerialize() { - TopicEndpoint manager = new TopicEndpointProxy(); - - manager.addTopicSources(configuration); - manager.addTopicSinks(configuration); - - assertThatCode(() -> new GsonTestUtils().compareGson(manager, TopicEndpointProxyTest.class)) - .doesNotThrowAnyException(); - } - - @Test - void testAddTopicSourcesListOfTopicParameters() { - TopicEndpoint manager = new TopicEndpointProxy(); - - List sources = manager.addTopicSources(group.getTopicSources()); - assertSame(1, sources.size()); - - assertTrue(allSources(sources)); - assertFalse(anySink(sources)); - - sources = manager.addTopicSources(group.getTopicSources()); - assertSame(1, sources.size()); - assertTrue(allSources(sources)); - } - - @Test - void testAddTopicSourcesKafka() { - TopicEndpoint manager = new TopicEndpointProxy(); - - KafkaTopicPropertyBuilder kafkaTopicPropertyBuilder = - new KafkaTopicPropertyBuilder(PolicyEndPointProperties.PROPERTY_KAFKA_SOURCE_TOPICS) - .makeTopic(KAFKA_SOURCE_TOPIC); - - configuration.putAll(kafkaTopicPropertyBuilder.build()); - group.getTopicSources().add(kafkaTopicPropertyBuilder.getParams()); - List sources = manager.addTopicSources(group.getTopicSources()); - assertSame(2, sources.size()); - - configuration.remove(KAFKA_SOURCE_TOPIC); - group.setTopicSources(new LinkedList<>()); - sources = manager.addTopicSources(group.getTopicSources()); - assertSame(0, sources.size()); - } - - @Test - void testAddTopicSourcesProperties() { - TopicEndpoint manager = new TopicEndpointProxy(); - - List sources = manager.addTopicSources(configuration); - assertSame(1, sources.size()); - - assertTrue(allSources(sources)); - assertFalse(anySink(sources)); - } - - @Test - void testAddTopicSinksListOfTopicParameters() { - TopicEndpoint manager = new TopicEndpointProxy(); - - List sinks = manager.addTopicSinks(group.getTopicSinks()); - assertSame(1, sinks.size()); - - assertFalse(anySource(sinks)); - assertTrue(allSinks(sinks)); - } - - @Test - void testAddTopicSinksListOfTopicParametersKafka() { - TopicEndpoint manager = new TopicEndpointProxy(); - - List sinks = manager.addTopicSinks(group.getTopicSinks()); - assertSame(1, sinks.size()); - - KafkaTopicPropertyBuilder kafkaTopicPropertyBuilder = - new KafkaTopicPropertyBuilder(PolicyEndPointProperties.PROPERTY_KAFKA_SINK_TOPICS) - .makeTopic(KAFKA_SINK_TOPIC); - - configuration.putAll(kafkaTopicPropertyBuilder.build()); - group.getTopicSources().add(kafkaTopicPropertyBuilder.getParams()); - sinks = manager.addTopicSinks(group.getTopicSources()); - assertSame(2, sinks.size()); - - configuration.remove(KAFKA_SOURCE_TOPIC); - group.setTopicSources(new LinkedList<>()); - sinks = manager.addTopicSinks(group.getTopicSources()); - assertSame(0, sinks.size()); - } - - @Test - void testAddTopicSinksProperties() { - TopicEndpoint manager = new TopicEndpointProxy(); - - List sinks = manager.addTopicSinks(configuration); - assertSame(1, sinks.size()); - - assertFalse(anySource(sinks)); - assertTrue(allSinks(sinks)); - } - - @Test - void testAddTopicsProperties() { - TopicEndpoint manager = new TopicEndpointProxy(); - - List topics = manager.addTopics(configuration); - assertSame(2, topics.size()); - - assertTrue(allSources(topics)); - assertTrue(allSinks(topics)); - } - - @Test - void testAddTopicsTopicParameterGroup() { - TopicEndpoint manager = new TopicEndpointProxy(); - - List topics = manager.addTopics(group); - assertSame(2, topics.size()); - - assertTrue(allSources(topics)); - assertTrue(allSinks(topics)); - } - - @Test - void testAddTopicsTopicParameterGroupNull() { - TopicEndpoint manager = new TopicEndpointProxy(); - - List topics = manager.addTopics(new TopicParameterGroup()); - assertEquals(0, topics.size()); - } - - @Test - void testLockSinks_lockSources_locked() { - TopicEndpoint manager = new TopicEndpointProxy(); - manager.lock(); - for (Topic topic : manager.addTopics(group)) { - assertTrue(topic.isLocked()); - } - } - - @Test - void testLockSinks_lockSources_unlocked() { - TopicEndpoint manager = new TopicEndpointProxy(); - for (Topic topic : manager.addTopics(group)) { - assertFalse(topic.isLocked()); - } - } - - @Test - void testGetTopicSources() { - TopicEndpoint manager = new TopicEndpointProxy(); - - manager.addTopicSources(configuration); - manager.addTopicSinks(configuration); - - List sources = manager.getTopicSources(); - assertSame(1, sources.size()); - - assertTrue(allSources(sources)); - assertFalse(anySink(sources)); - - assertThatThrownBy(() -> manager.getKafkaTopicSource("testTopic")) - .hasMessageContaining("KafkaTopiceSource for testTopic not found"); - - List topicName = null; - assertThatThrownBy(() -> manager.getTopicSources(topicName)) - .hasMessageContaining("must provide a list of topics"); - } - - @Test - void testGetTopicSinks() { - TopicEndpoint manager = new TopicEndpointProxy(); - - manager.addTopicSources(configuration); - manager.addTopicSinks(configuration); - - List sinks = manager.getTopicSinks(); - assertSame(1, sinks.size()); - - assertFalse(anySource(sinks)); - assertTrue(allSinks(sinks)); - - final List sinks2 = null; - assertThatThrownBy(() -> manager.getTopicSinks(sinks2)).hasMessageContaining("must provide a list of topics"); - - List sinks3 = List.of(NOOP_SINK_TOPIC); - assertThatCode(() -> manager.getTopicSinks(sinks3)).doesNotThrowAnyException(); - - String sinkTest = null; - assertThatThrownBy(() -> manager.getTopicSinks(sinkTest)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("Invalid parameter"); - - assertThatThrownBy(() -> manager.getKafkaTopicSink("testTopic")) - .hasMessageContaining("KafkaTopicSink for testTopic not found"); - } - - @Test - void testGetNoopTopicSources() { - TopicEndpoint manager = new TopicEndpointProxy(); - - manager.addTopicSources(configuration); - assertSame(1, manager.getNoopTopicSources().size()); - } - - @Test - void testGetNoopTopicSinks() { - TopicEndpoint manager = new TopicEndpointProxy(); - - manager.addTopicSinks(configuration); - assertSame(1, manager.getNoopTopicSinks().size()); - } - - @Test - void testLifecycle() { - TopicEndpoint manager = new TopicEndpointProxy(); - - assertTrue(manager.start()); - assertTrue(manager.isAlive()); - - assertTrue(manager.stop()); - assertFalse(manager.isAlive()); - - assertTrue(manager.start()); - assertTrue(manager.isAlive()); - - manager.shutdown(); - assertFalse(manager.isAlive()); - } - - @Test - void testLock() { - TopicEndpoint manager = new TopicEndpointProxy(); - - manager.lock(); - assertTrue(manager.isLocked()); - - manager.unlock(); - assertFalse(manager.isLocked()); - } - - @Test - void testGetTopicSource() { - TopicEndpoint manager = new TopicEndpointProxy(); - manager.addTopicSources(configuration); - - assertSame(NOOP_SOURCE_TOPIC, manager.getTopicSource(CommInfrastructure.NOOP, NOOP_SOURCE_TOPIC).getTopic()); - - assertThatIllegalStateException() - .isThrownBy(() -> manager.getTopicSource(CommInfrastructure.NOOP, NOOP_SINK_TOPIC)); - } - - @Test - void testGetTopicSink() { - TopicEndpoint manager = new TopicEndpointProxy(); - manager.addTopicSinks(configuration); - - assertSame(NOOP_SINK_TOPIC, manager.getTopicSink(CommInfrastructure.NOOP, NOOP_SINK_TOPIC).getTopic()); - - assertThatIllegalStateException() - .isThrownBy(() -> manager.getTopicSink(CommInfrastructure.NOOP, NOOP_SOURCE_TOPIC)); - } - - @Test - void testGetNoopTopicSource() { - TopicEndpoint manager = new TopicEndpointProxy(); - manager.addTopicSources(configuration); - - assertSame(NOOP_SOURCE_TOPIC, manager.getNoopTopicSource(NOOP_SOURCE_TOPIC).getTopic()); - - assertThatIllegalArgumentException().isThrownBy(() -> manager.getNoopTopicSource(null)); - assertThatIllegalArgumentException().isThrownBy(() -> manager.getNoopTopicSource("")); - } - - @Test - void testGetNoopTopicSink() { - TopicEndpoint manager = new TopicEndpointProxy(); - manager.addTopicSinks(configuration); - - assertSame(NOOP_SINK_TOPIC, manager.getNoopTopicSink(NOOP_SINK_TOPIC).getTopic()); - - assertThatIllegalArgumentException().isThrownBy(() -> manager.getNoopTopicSink(null)); - assertThatIllegalArgumentException().isThrownBy(() -> manager.getNoopTopicSink("")); - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/BusTopicFactoryTestBase.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/BusTopicFactoryTestBase.java deleted file mode 100644 index b2a35408..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/BusTopicFactoryTestBase.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNotSame; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_ALLOW_SELF_SIGNED_CERTIFICATES_SUFFIX; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_HTTP_HTTPS_SUFFIX; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX; - -import java.util.Arrays; -import java.util.List; -import java.util.Properties; -import java.util.function.Predicate; -import org.onap.policy.common.endpoints.event.comm.Topic; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; - -/** - * Base class for Topic Factory tests that use BusTopicParams. - * - * @param type of topic managed by the factory - */ -public abstract class BusTopicFactoryTestBase extends TopicFactoryTestBase { - - /** - * Builds a topic. - * - * @param params the parameters used to configure the topic - * @return a new topic - */ - protected abstract T buildTopic(BusTopicParams params); - - /** - * Builds a topic. - * - * @param servers list of servers - * @param topic the topic name - * @return a new topic - */ - protected abstract T buildTopic(List servers, String topic); - - /** - * Gets the parameters used to build the most recent topic. - * - * @return the most recent topic's parameters - */ - protected abstract BusTopicParams getLastParams(); - - /** - * Tests building a topic using BusTopicParams. - */ - void testBuildBusTopicParams() { - initFactory(); - - // two unmanaged topics - T item = buildTopic(makeBuilder().managed(false).effectiveTopic(null).build()); - T item2 = buildTopic(makeBuilder().managed(false).topic(TOPIC2).build()); - assertNotNull(item); - assertNotNull(item2); - assertEquals(item.getTopic(), item.getEffectiveTopic()); - assertNotEquals(item2.getTopic(), item2.getEffectiveTopic()); - assertNotSame(item, item2); - - // duplicate topics, but since they aren't managed, they should be different - T item3 = buildTopic(makeBuilder().managed(false).build()); - T item4 = buildTopic(makeBuilder().managed(false).effectiveTopic(TOPIC2).build()); - assertNotNull(item3); - assertNotNull(item4); - assertEquals(MY_TOPIC, item4.getTopic()); - assertEquals(TOPIC2, item4.getEffectiveTopic()); - assertNotSame(item, item3); - assertNotSame(item, item4); - assertNotSame(item3, item4); - - // two managed topics - T item5 = buildTopic(makeBuilder().build()); - T item6 = buildTopic(makeBuilder().topic(TOPIC2).build()); - assertNotNull(item5); - assertNotNull(item6); - - // re-build same managed topics - should get exact same objects - assertSame(item5, buildTopic(makeBuilder().topic(MY_TOPIC).build())); - assertSame(item6, buildTopic(makeBuilder().topic(TOPIC2).build())); - } - - /** - * Tests exception cases when building a topic using BusTopicParams. - */ - void testBuildBusTopicParams_Ex() { - // null topic - assertThatIllegalArgumentException().isThrownBy(() -> buildTopic(makeBuilder().topic(null).build())); - - // empty topic - assertThatIllegalArgumentException().isThrownBy(() -> buildTopic(makeBuilder().topic("").build())); - } - - /** - * Tests building a topic using a list of servers and a topic. - */ - void testBuildListOfStringString() { - initFactory(); - - T item1 = buildTopic(servers, MY_TOPIC); - assertNotNull(item1); - - // check parameters that were used - BusTopicParams params = getLastParams(); - assertEquals(servers, params.getServers()); - assertEquals(MY_TOPIC, params.getTopic()); - assertEquals(true, params.isManaged()); - assertEquals(false, params.isUseHttps()); - - T item2 = buildTopic(servers, TOPIC2); - assertNotNull(item2); - assertNotSame(item1, item2); - - // duplicate - should be the same, as these topics are managed - T item3 = buildTopic(servers, TOPIC2); - assertSame(item2, item3); - } - - /** - * Tests building a topic using Properties. Verifies parameters specific to Bus - * topics. - */ - void testBuildProperties() { - initFactory(); - - List topics = buildTopics(makePropBuilder().makeTopic(MY_TOPIC).build()); - assertEquals(1, topics.size()); - assertEquals(MY_TOPIC, topics.get(0).getTopic()); - assertEquals(MY_EFFECTIVE_TOPIC, topics.get(0).getEffectiveTopic()); - - BusTopicParams params = getLastParams(); - assertEquals(true, params.isManaged()); - assertEquals(true, params.isUseHttps()); - assertEquals(true, params.isAllowSelfSignedCerts()); - assertEquals(MY_API_KEY, params.getApiKey()); - assertEquals(MY_API_SECRET, params.getApiSecret()); - assertEquals(Arrays.asList(SERVER), params.getServers()); - assertEquals(MY_TOPIC, params.getTopic()); - assertEquals(MY_EFFECTIVE_TOPIC, params.getEffectiveTopic()); - - List topics2 = buildTopics(makePropBuilder().makeTopic(TOPIC3) - .removeTopicProperty(PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX).build()); - assertEquals(1, topics2.size()); - assertEquals(TOPIC3, topics2.get(0).getTopic()); - assertEquals(topics2.get(0).getTopic(), topics2.get(0).getEffectiveTopic()); - } - - @Override - void testBuildProperties_Variations() { - super.testBuildProperties_Variations(); - - // check boolean properties that default to true - checkDefault(PROPERTY_MANAGED_SUFFIX, BusTopicParams::isManaged); - - // check boolean properties that default to false - checkDefault(PROPERTY_HTTP_HTTPS_SUFFIX, params -> !params.isUseHttps()); - checkDefault(PROPERTY_ALLOW_SELF_SIGNED_CERTIFICATES_SUFFIX, params -> !params.isAllowSelfSignedCerts()); - } - - /** - * Verifies that a parameter has the correct default, if the original builder property - * is not provided. - * - * @param builderName name of the builder property - * @param validate function to test the validity of the property - * @param values the values to which the property should be set, defaults to - * {@code null} and "" - */ - protected void checkDefault(String builderName, Predicate validate, Object... values) { - Object[] values2 = (values.length > 0 ? values : new Object[] {null, ""}); - - for (Object value : values2) { - // always start with a fresh factory - initFactory(); - - TopicPropertyBuilder builder = makePropBuilder().makeTopic(MY_TOPIC); - - if (value == null) { - builder.removeTopicProperty(builderName); - - } else { - builder.setTopicProperty(builderName, value.toString()); - } - - assertEquals(1, buildTopics(builder.build()).size(), "size for default " + value); - assertTrue(validate.test(getLastParams()), "default for " + value); - } - } - - /** - * Verifies that an "additional" property does not exist, if the original builder - * property is not provided. - * - * @param builderName name of the builder property - * @param addName name of the "additional" property - */ - protected void expectNullAddProp(String builderName, String addName) { - - // remove the property - initFactory(); - Properties props = makePropBuilder().makeTopic(MY_TOPIC).removeTopicProperty(builderName).build(); - assertEquals(1, buildTopics(props).size()); - assertFalse(getLastParams().getAdditionalProps().containsKey(addName)); - - - // repeat, this time using an empty string instead of null - initFactory(); - props = makePropBuilder().makeTopic(MY_TOPIC).setTopicProperty(builderName, "").build(); - assertEquals(1, buildTopics(props).size()); - assertFalse(getLastParams().getAdditionalProps().containsKey(addName)); - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/IndexedKafkaTopicSourceFactoryTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/IndexedKafkaTopicSourceFactoryTest.java deleted file mode 100644 index 80229419..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/IndexedKafkaTopicSourceFactoryTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import java.util.List; -import org.apache.kafka.clients.ClientUtils; -import org.junit.jupiter.api.Test; -import org.mockito.Mock; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; - -class IndexedKafkaTopicSourceFactoryTest { - - private IndexedKafkaTopicSourceFactory factory; - - @Mock - ClientUtils mockClientUtils; - - @Test - void testBuild() { - factory = new IndexedKafkaTopicSourceFactory(); - BusTopicParams params = new BusTopicParams(); - - // set servers to null - params.setServers(null); - assertThatThrownBy(() -> factory.build(params)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("KAFKA Server(s) must be provided"); - - // set servers to empty - params.setServers(List.of()); - assertThatThrownBy(() -> factory.build(params)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("KAFKA Server(s) must be provided"); - - List servers = List.of("kafka:9092", "kafka:29092"); - params.setServers(servers); - - // set topic to null - params.setTopic(null); - assertThatThrownBy(() -> factory.build(params)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("A topic must be provided"); - - // set topic to empty - params.setTopic(""); - assertThatThrownBy(() -> factory.build(params)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("A topic must be provided"); - - params.setTopic("topic01"); - - assertThatThrownBy(() -> factory.build(servers, "topic1")) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("cannot create topic"); - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicFactoryTestBase.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicFactoryTestBase.java deleted file mode 100644 index 084e0404..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicFactoryTestBase.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2022-2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; - -import java.util.Collections; -import org.onap.policy.common.endpoints.event.comm.Topic; - -/** - * Base class for KafkaTopicXxxFactory tests. - * - * @param type of topic managed by the factory - */ -public abstract class KafkaTopicFactoryTestBase extends BusTopicFactoryTestBase { - - @Override - void testBuildBusTopicParams_Ex() { - - super.testBuildBusTopicParams_Ex(); - - // null servers - assertThatIllegalArgumentException().as("null servers") - .isThrownBy(() -> buildTopic(makeBuilder().servers(null).build())); - - // empty servers - assertThatIllegalArgumentException().as("empty servers") - .isThrownBy(() -> buildTopic(makeBuilder().servers(Collections.emptyList()).build())); - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicPropertyBuilder.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicPropertyBuilder.java deleted file mode 100644 index b49f58e2..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicPropertyBuilder.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022, 2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import static org.onap.policy.common.endpoints.event.comm.bus.TopicTestBase.MY_EFFECTIVE_TOPIC; -import static org.onap.policy.common.endpoints.event.comm.bus.TopicTestBase.MY_PARTITION; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_HTTP_HTTPS_SUFFIX; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_TOPIC_SERVERS_SUFFIX; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_TOPIC_SINK_PARTITION_KEY_SUFFIX; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import lombok.Getter; -import org.onap.policy.common.endpoints.parameters.TopicParameters; - -@Getter -public class KafkaTopicPropertyBuilder extends TopicPropertyBuilder { - - public static final String SERVER = "localhost:9092"; - public static final String TOPIC2 = "my-topic-2"; - public static final String ADDITIONAL_PROPS = "{\"security.protocol\": \"SASL_PLAINTEXT\"," - + "\"sasl.mechanism\": \"SCRAM-SHA-512\",\"sasl.jaas.config\": " - + "\"org.apache.kafka.common.security.plain.PlainLoginModule " - + "required username=abc password=abc serviceName=kafka;\"}"; - - private final TopicParameters params = new TopicParameters(); - - /** - * Constructs the object. - * - * @param prefix the prefix for the properties to be built - */ - public KafkaTopicPropertyBuilder(String prefix) { - super(prefix); - } - - /** - * Adds a topic and configures it's properties with default values. - * - * @param topic the topic to be added - * @return this builder - */ - public KafkaTopicPropertyBuilder makeTopic(String topic) { - addTopic(topic); - - setTopicProperty(PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX, MY_EFFECTIVE_TOPIC); - setTopicProperty(PROPERTY_MANAGED_SUFFIX, "true"); - setTopicProperty(PROPERTY_HTTP_HTTPS_SUFFIX, "true"); - setTopicProperty(PROPERTY_TOPIC_SINK_PARTITION_KEY_SUFFIX, MY_PARTITION); - setTopicProperty(PROPERTY_TOPIC_SERVERS_SUFFIX, SERVER); - setTopicProperty(".additionalProps", ADDITIONAL_PROPS); - - params.setTopicCommInfrastructure("kafka"); - params.setTopic(topic); - params.setEffectiveTopic(MY_EFFECTIVE_TOPIC); - params.setManaged(true); - params.setUseHttps(true); - params.setPartitionId(MY_PARTITION); - params.setServers(List.of(SERVER)); - params.setAdditionalProps(getAdditionalProps()); - - return this; - } - - private Map getAdditionalProps() { - try { - return new ObjectMapper().readValue(ADDITIONAL_PROPS, Map.class); - } catch (JsonProcessingException e) { - return Collections.emptyMap(); - } - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSinkFactoryTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSinkFactoryTest.java deleted file mode 100644 index 5ff6782f..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSinkFactoryTest.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2022, 2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_KAFKA_SINK_TOPICS; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX; - -import java.util.Deque; -import java.util.LinkedList; -import java.util.List; -import java.util.Properties; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; - -class KafkaTopicSinkFactoryTest extends KafkaTopicFactoryTestBase { - - private SinkFactory factory; - public static final String KAFKA_SERVER = "localhost:9092"; - - /** - * Creates the object to be tested. - */ - @BeforeEach - @Override - public void setUp() { - super.setUp(); - - factory = new SinkFactory(); - } - - @AfterEach - public void tearDown() { - factory.destroy(); - } - - @Test - @Override - void testBuildBusTopicParams() { - super.testBuildBusTopicParams(); - super.testBuildBusTopicParams_Ex(); - } - - @Test - @Override - void testBuildListOfStringString() { - super.testBuildListOfStringString(); - - // check parameters that were used - BusTopicParams params = getLastParams(); - assertFalse(params.isAllowSelfSignedCerts()); - } - - @Test - @Override - void testBuildProperties() { - List topics = buildTopics(makePropBuilder().makeTopic(MY_TOPIC).build()); - assertEquals(1, topics.size()); - assertEquals(MY_TOPIC, topics.get(0).getTopic()); - assertEquals(MY_EFFECTIVE_TOPIC, topics.get(0).getEffectiveTopic()); - - BusTopicParams params = getLastParams(); - assertTrue(params.isManaged()); - assertFalse(params.isUseHttps()); - assertEquals(List.of(KAFKA_SERVER), params.getServers()); - assertEquals(MY_TOPIC, params.getTopic()); - assertEquals(MY_EFFECTIVE_TOPIC, params.getEffectiveTopic()); - assertEquals(MY_PARTITION, params.getPartitionId()); - assertNotNull(params.getAdditionalProps()); - - List topics2 = buildTopics(makePropBuilder().makeTopic(TOPIC3) - .removeTopicProperty(PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX).build()); - assertEquals(1, topics2.size()); - assertEquals(TOPIC3, topics2.get(0).getTopic()); - assertEquals(topics2.get(0).getTopic(), topics2.get(0).getEffectiveTopic()); - - initFactory(); - - assertEquals(1, buildTopics(makePropBuilder().makeTopic(MY_TOPIC).build()).size()); - } - - @Test - void testBuildFromProperties() { - Properties props = makePropBuilder().makeTopic(MY_TOPIC).build(); - var listTopic = factory.build(props); - assertNotNull(listTopic); - } - - @Test - @Override - void testDestroyString_testGet_testInventory() { - super.testDestroyString_testGet_testInventory(); - super.testDestroyString_Ex(); - } - - @Test - @Override - void testDestroy() { - super.testDestroy(); - } - - @Test - void testGet() { - super.testGet_Ex(); - } - - @Test - void testToString() { - assertTrue(factory.toString().startsWith("IndexedKafkaTopicSinkFactory [")); - } - - @Override - protected void initFactory() { - if (factory != null) { - factory.destroy(); - } - - factory = new SinkFactory(); - } - - @Override - protected List buildTopics(Properties properties) { - return factory.build(properties); - } - - @Override - protected KafkaTopicSink buildTopic(BusTopicParams params) { - return factory.build(params); - } - - @Override - protected KafkaTopicSink buildTopic(List servers, String topic) { - return factory.build(servers, topic); - } - - @Override - protected void destroyFactory() { - factory.destroy(); - } - - @Override - protected void destroyTopic(String topic) { - factory.destroy(topic); - } - - @Override - protected List getInventory() { - return factory.inventory(); - } - - @Override - protected KafkaTopicSink getTopic(String topic) { - return factory.get(topic); - } - - @Override - protected BusTopicParams getLastParams() { - return factory.params.getLast(); - } - - @Override - protected TopicPropertyBuilder makePropBuilder() { - return new KafkaTopicPropertyBuilder(PROPERTY_KAFKA_SINK_TOPICS); - } - - /** - * Factory that records the parameters of all the sinks it creates. - */ - private static class SinkFactory extends IndexedKafkaTopicSinkFactory { - private Deque params = new LinkedList<>(); - - @Override - protected KafkaTopicSink makeSink(BusTopicParams busTopicParams) { - params.add(busTopicParams); - return super.makeSink(busTopicParams); - } - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSinkTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSinkTest.java deleted file mode 100644 index a34dac74..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSinkTest.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP Policy Engine - Common Modules - * ================================================================================ - * Copyright (C) 2022, 2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import org.junit.jupiter.api.Test; - -class KafkaTopicSinkTest { - - @Test - void test() { - assertNotNull(KafkaTopicFactories.getSinkFactory()); - } - -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSourceFactoryTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSourceFactoryTest.java deleted file mode 100644 index 3e4ffda5..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSourceFactoryTest.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP Policy Engine - Common Modules - * ================================================================================ - * Copyright (C) 2022-2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_KAFKA_SOURCE_TOPICS; - -import java.util.Deque; -import java.util.LinkedList; -import java.util.List; -import java.util.Properties; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; - -class KafkaTopicSourceFactoryTest extends KafkaTopicFactoryTestBase { - - private SourceFactory factory; - - public static final String KAFKA_SERVER = "localhost:9092"; - - /** - * Creates the object to be tested. - */ - @BeforeEach - @Override - public void setUp() { - super.setUp(); - - factory = new SourceFactory(); - } - - @AfterEach - public void tearDown() { - factory.destroy(); - } - - @Test - @Override - void testBuildProperties() { - - initFactory(); - - List topics = buildTopics(makePropBuilder().makeTopic(MY_TOPIC).build()); - assertEquals(1, topics.size()); - assertEquals(MY_TOPIC, topics.get(0).getTopic()); - assertEquals(MY_EFFECTIVE_TOPIC, topics.get(0).getEffectiveTopic()); - - BusTopicParams params = getLastParams(); - assertTrue(params.isManaged()); - assertFalse(params.isUseHttps()); - assertEquals(List.of(KAFKA_SERVER), params.getServers()); - assertEquals(MY_TOPIC, params.getTopic()); - assertEquals(MY_EFFECTIVE_TOPIC, params.getEffectiveTopic()); - } - - @Test - @Override - void testDestroyString_testGet_testInventory() { - super.testDestroyString_testGet_testInventory(); - super.testDestroyString_Ex(); - } - - @Test - @Override - void testDestroy() { - super.testDestroy(); - } - - @Test - void testGet() { - super.testGet_Ex(); - } - - @Test - void testToString() { - assertTrue(factory.toString().startsWith("IndexedKafkaTopicSourceFactory [")); - } - - @Override - protected void initFactory() { - if (factory != null) { - factory.destroy(); - } - - factory = new SourceFactory(); - } - - @Override - protected List buildTopics(Properties properties) { - return factory.build(properties); - } - - @Override - protected KafkaTopicSource buildTopic(BusTopicParams params) { - return factory.build(params); - } - - @Override - protected KafkaTopicSource buildTopic(List servers, String topic) { - return factory.build(servers, topic); - } - - @Override - protected void destroyFactory() { - factory.destroy(); - } - - @Override - protected void destroyTopic(String topic) { - factory.destroy(topic); - } - - @Override - protected List getInventory() { - return factory.inventory(); - } - - @Override - protected KafkaTopicSource getTopic(String topic) { - return factory.get(topic); - } - - @Override - protected BusTopicParams getLastParams() { - return factory.params.getLast(); - } - - @Override - protected TopicPropertyBuilder makePropBuilder() { - return new KafkaTopicPropertyBuilder(PROPERTY_KAFKA_SOURCE_TOPICS); - } - - /** - * Factory that records the parameters of all the sources it creates. - */ - private static class SourceFactory extends IndexedKafkaTopicSourceFactory { - private Deque params = new LinkedList<>(); - - @Override - protected KafkaTopicSource makeSource(BusTopicParams busTopicParams) { - params.add(busTopicParams); - return super.makeSource(busTopicParams); - } - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSourceTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSourceTest.java deleted file mode 100644 index 6afe5576..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/KafkaTopicSourceTest.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP Policy Engine - Common Modules - * ================================================================================ - * Copyright (C) 2022-2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import org.junit.jupiter.api.Test; - -class KafkaTopicSourceTest { - - @Test - void verifyKafkaTopicFactoriesNotNull() { - assertNotNull(KafkaTopicFactories.getSourceFactory()); - } - -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicEndpointTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicEndpointTest.java deleted file mode 100644 index fd8f3a96..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicEndpointTest.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -import java.util.Arrays; -import java.util.Collections; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.endpoints.event.comm.TopicListener; - -public abstract class NoopTopicEndpointTest, T extends NoopTopicEndpoint> - extends TopicTestBase { - - protected final F factory; - protected T endpoint; - - public NoopTopicEndpointTest(F factory) { - this.factory = factory; - } - - protected abstract boolean io(String message); - - @BeforeEach - @Override - public void setUp() { - super.setUp(); - this.endpoint = this.factory.build(servers, MY_TOPIC); - } - - @Test - void testIo() { - TopicListener listener = mock(TopicListener.class); - this.endpoint.register(listener); - this.endpoint.start(); - - assertTrue(io(MY_MESSAGE)); - assertSame(MY_MESSAGE, this.endpoint.getRecentEvents()[0]); - assertEquals(Collections.singletonList(MY_MESSAGE), Arrays.asList(this.endpoint.getRecentEvents())); - verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE); - - this.endpoint.unregister(listener); - } - - @Test - void testIoNullMessage() { - assertThatThrownBy(() -> io(null)).isInstanceOf(IllegalArgumentException.class); - } - - @Test - void testIoEmptyMessage() { - assertThatThrownBy(() -> io("")).isInstanceOf(IllegalArgumentException.class); - } - - @Test - void testOfferNotStarted() { - assertThatThrownBy(() -> io(MY_MESSAGE)).isInstanceOf(IllegalStateException.class); - } - - @Test - void testGetTopicCommInfrastructure() { - assertEquals(CommInfrastructure.NOOP, this.endpoint.getTopicCommInfrastructure()); - } - - @Test - void testStart_testStop_testShutdown() { - this.endpoint.start(); - assertTrue(this.endpoint.isAlive()); - - // start again - this.endpoint.start(); - assertTrue(this.endpoint.isAlive()); - - // stop - this.endpoint.stop(); - assertFalse(this.endpoint.isAlive()); - - // re-start again - this.endpoint.start(); - assertTrue(this.endpoint.isAlive()); - - // shutdown - this.endpoint.shutdown(); - assertFalse(this.endpoint.isAlive()); - } - - @Test - void testStart_Locked() { - this.endpoint.lock(); - assertThatThrownBy(() -> this.endpoint.start()).isInstanceOf(IllegalStateException.class); - } - -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicFactoryTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicFactoryTest.java deleted file mode 100644 index 3a0ec95f..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicFactoryTest.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNotSame; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_TOPIC_SERVERS_SUFFIX; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Properties; -import org.apache.commons.lang3.RandomStringUtils; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; - -public abstract class NoopTopicFactoryTest, T extends NoopTopicEndpoint> - extends TopicFactoryTestBase { - - private static final List NOOP_SERVERS = Arrays.asList(CommInfrastructure.NOOP.toString()); - private F factory = null; - - protected abstract F buildFactory(); - - /** - * Creates the object to be tested. - */ - @BeforeEach - @Override - public void setUp() { - super.setUp(); - initFactory(); - } - - @AfterEach - void tearDown() { - factory.destroy(); - } - - @Test - void testBuildBusTopicParams() { - initFactory(); - - T item1 = buildTopic(makeParams(servers, MY_TOPIC, true)); - assertNotNull(item1); - - assertEquals(servers, item1.getServers()); - assertEquals(MY_TOPIC, item1.getTopic()); - } - - @Test - void testBuildListOfStringStringBoolean() { - initFactory(); - - T item1 = buildTopic(servers, MY_TOPIC, true); - assertNotNull(item1); - - assertEquals(servers, item1.getServers()); - assertEquals(MY_TOPIC, item1.getTopic()); - - // managed topic - should not build a new one - assertEquals(item1, buildTopic(servers, MY_TOPIC, true)); - - T item2 = buildTopic(servers, TOPIC2, true); - assertNotNull(item2); - assertNotSame(item1, item2); - - // duplicate - should be the same, as these topics are managed - List randomServers = new ArrayList<>(); - randomServers.add(RandomStringUtils.randomAlphanumeric(8)); - T item3 = buildTopic(randomServers, TOPIC2, true); - assertSame(item2, item3); - - T item4 = buildTopic(Collections.emptyList(), TOPIC2, true); - assertSame(item3, item4); - - // null server list - initFactory(); - assertEquals(NOOP_SERVERS, buildTopic(null, MY_TOPIC, true).getServers()); - - // empty server list - initFactory(); - assertEquals(NOOP_SERVERS, buildTopic(Collections.emptyList(), MY_TOPIC, true).getServers()); - - // unmanaged topic - initFactory(); - item1 = buildTopic(servers, MY_TOPIC, false); - assertNotSame(item1, buildTopic(servers, MY_TOPIC, false)); - } - - @Test - void testBuildListOfStringStringBoolean_NullTopic() { - assertThatThrownBy(() -> buildTopic(servers, null, true)).isInstanceOf(IllegalArgumentException.class); - } - - @Test - void testBuildListOfStringStringBoolean_EmptyTopic() { - assertThatThrownBy(() -> buildTopic(servers, "", true)).isInstanceOf(IllegalArgumentException.class); - } - - @Test - void testBuildProperties() { - // managed topic - initFactory(); - assertEquals(1, buildTopics(makePropBuilder().makeTopic(MY_TOPIC).build()).size()); - assertNotNull(factory.get(MY_TOPIC)); - - // unmanaged topic - get() will throw an exception - initFactory(); - assertEquals(1, buildTopics(makePropBuilder().makeTopic(MY_TOPIC) - .setTopicProperty(PROPERTY_MANAGED_SUFFIX, "false").build()).size()); - assertThatIllegalStateException().isThrownBy(() -> factory.get(MY_TOPIC)); - - // managed undefined - default to true - initFactory(); - assertEquals(1, buildTopics( - makePropBuilder().makeTopic(MY_TOPIC).removeTopicProperty(PROPERTY_MANAGED_SUFFIX).build()) - .size()); - assertNotNull(factory.get(MY_TOPIC)); - - // managed empty - default to true - initFactory(); - assertEquals(1, buildTopics( - makePropBuilder().makeTopic(MY_TOPIC).setTopicProperty(PROPERTY_MANAGED_SUFFIX, "").build()) - .size()); - assertNotNull(factory.get(MY_TOPIC)); - - initFactory(); - - // null topic list - assertTrue(buildTopics(makePropBuilder().build()).isEmpty()); - - // empty topic list - assertTrue(buildTopics(makePropBuilder().addTopic("").build()).isEmpty()); - - // null server list - initFactory(); - T endpoint = buildTopics(makePropBuilder().makeTopic(MY_TOPIC) - .removeTopicProperty(PROPERTY_TOPIC_SERVERS_SUFFIX).build()).get(0); - assertEquals(NOOP_SERVERS, endpoint.getServers()); - - // empty server list - initFactory(); - endpoint = buildTopics(makePropBuilder().makeTopic(MY_TOPIC).setTopicProperty(PROPERTY_TOPIC_SERVERS_SUFFIX, "") - .build()).get(0); - assertEquals(NOOP_SERVERS, endpoint.getServers()); - - // test other options - super.testBuildProperties_Multiple(); - } - - @Test - @Override - void testDestroyString_testGet_testInventory() { - super.testDestroyString_testGet_testInventory(); - super.testDestroyString_Ex(); - } - - @Test - @Override - void testDestroy() { - super.testDestroy(); - } - - @Test - void testGet() { - super.testGet_Ex(); - } - - @Override - protected void initFactory() { - if (factory != null) { - factory.destroy(); - } - - factory = buildFactory(); - } - - @Override - protected List buildTopics(Properties properties) { - return factory.build(properties); - } - - protected T buildTopic(BusTopicParams param) { - return factory.build(param); - } - - protected T buildTopic(List servers, String topic, boolean managed) { - return factory.build(servers, topic, managed); - } - - @Override - protected void destroyFactory() { - factory.destroy(); - } - - @Override - protected void destroyTopic(String topic) { - factory.destroy(topic); - } - - @Override - protected List getInventory() { - return factory.inventory(); - } - - @Override - protected T getTopic(String topic) { - return factory.get(topic); - } - - @Override - protected TopicPropertyBuilder makePropBuilder() { - return new NoopTopicPropertyBuilder(factory.getTopicsPropertyName()); - } - - private BusTopicParams makeParams(List servers, String topic, boolean managed) { - BusTopicParams params = new BusTopicParams(); - - params.setServers(servers); - params.setTopic(topic); - params.setManaged(managed); - - return params; - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicPropertyBuilder.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicPropertyBuilder.java deleted file mode 100644 index 3f0553f8..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicPropertyBuilder.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2018-2019 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import static org.onap.policy.common.endpoints.event.comm.bus.TopicTestBase.MY_EFFECTIVE_TOPIC; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_ALLOW_SELF_SIGNED_CERTIFICATES_SUFFIX; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_HTTP_HTTPS_SUFFIX; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_TOPIC_SERVERS_SUFFIX; - -import java.util.Arrays; -import lombok.Getter; -import org.onap.policy.common.endpoints.parameters.TopicParameters; - -public class NoopTopicPropertyBuilder extends TopicPropertyBuilder { - - public static final String SERVER = "my-server"; - public static final String TOPIC2 = "my-topic-2"; - - @Getter - private TopicParameters params = new TopicParameters(); - - /** - * Constructs the object. - * - * @param prefix the prefix for the properties to be built - */ - public NoopTopicPropertyBuilder(String prefix) { - super(prefix); - } - - /** - * Adds a topic and configures it's properties with default values. - * - * @param topic the topic to be added - * @return this builder - */ - public NoopTopicPropertyBuilder makeTopic(String topic) { - addTopic(topic); - - setTopicProperty(PROPERTY_TOPIC_EFFECTIVE_TOPIC_SUFFIX, MY_EFFECTIVE_TOPIC); - setTopicProperty(PROPERTY_MANAGED_SUFFIX, "true"); - setTopicProperty(PROPERTY_HTTP_HTTPS_SUFFIX, "true"); - setTopicProperty(PROPERTY_ALLOW_SELF_SIGNED_CERTIFICATES_SUFFIX, "true"); - setTopicProperty(PROPERTY_TOPIC_SERVERS_SUFFIX, SERVER); - - params.setTopicCommInfrastructure("noop"); - params.setTopic(topic); - params.setEffectiveTopic(MY_EFFECTIVE_TOPIC); - params.setManaged(true); - params.setUseHttps(true); - params.setAllowSelfSignedCerts(true); - params.setServers(Arrays.asList(SERVER)); - - return this; - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSinkFactoryTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSinkFactoryTest.java deleted file mode 100644 index 872fabf9..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSinkFactoryTest.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2018-2019 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; - -class NoopTopicSinkFactoryTest extends NoopTopicFactoryTest { - - @Override - protected NoopTopicSinkFactory buildFactory() { - return new NoopTopicSinkFactory(); - } - - @Test - void testToString() { - assertTrue(new NoopTopicSinkFactory().toString().startsWith("NoopTopicSinkFactory [")); - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSinkTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSinkTest.java deleted file mode 100644 index 26de1647..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSinkTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; - -import org.junit.jupiter.api.Test; - -class NoopTopicSinkTest extends NoopTopicEndpointTest { - - public NoopTopicSinkTest() { - super(new NoopTopicSinkFactory()); - } - - @Override - protected boolean io(String message) { - return endpoint.send(message); - } - - @Test - void testToString() { - assertThat(endpoint.toString()).startsWith("NoopTopicSink"); - } - - @Test - void testSend() { - NoopTopicSink sink = new NoopTopicSink(servers, MY_TOPIC) { - @Override - protected boolean broadcast(String message) { - throw new RuntimeException(EXPECTED); - } - - }; - - sink.start(); - assertFalse(sink.send(MY_MESSAGE)); - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSourceFactoryTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSourceFactoryTest.java deleted file mode 100644 index fe5343f5..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSourceFactoryTest.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; - -class NoopTopicSourceFactoryTest extends NoopTopicFactoryTest { - - @Override - protected NoopTopicSourceFactory buildFactory() { - return new NoopTopicSourceFactory(); - } - - @Test - void testToString() { - assertTrue(new NoopTopicSourceFactory().toString().startsWith("NoopTopicSourceFactory [")); - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSourceTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSourceTest.java deleted file mode 100644 index a28a619e..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/NoopTopicSourceTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; - -class NoopTopicSourceTest extends NoopTopicEndpointTest { - - public NoopTopicSourceTest() { - super(new NoopTopicSourceFactory()); - } - - @Override - protected boolean io(String message) { - return this.endpoint.offer(message); - } - - @Test - void testToString() { - assertTrue(this.endpoint.toString().startsWith("NoopTopicSource")); - } - - @Test - void testOffer() { - NoopTopicSource source = new NoopTopicSource(servers, MY_TOPIC) { - @Override - protected boolean broadcast(String message) { - throw new RuntimeException(EXPECTED); - } - - }; - - source.start(); - assertFalse(source.offer(MY_MESSAGE)); - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/TopicFactoryTestBase.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/TopicFactoryTestBase.java deleted file mode 100644 index 0efbf3c2..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/TopicFactoryTestBase.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotSame; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_TOPIC_SERVERS_SUFFIX; - -import java.util.List; -import java.util.Properties; -import org.onap.policy.common.endpoints.event.comm.Topic; - -/** - * Base class for XxxTopicFactory tests. - * - * @param type of topic managed by the factory - */ -public abstract class TopicFactoryTestBase extends TopicTestBase { - - public static final String SERVER = "my-server"; - public static final String TOPIC2 = "my-topic-2"; - public static final String TOPIC3 = "my-topic-3"; - - /** - * Initializes a new factory. - */ - protected abstract void initFactory(); - - /** - * Makes a property builder. - * - * @return a new property builder - */ - protected abstract TopicPropertyBuilder makePropBuilder(); - - /** - * Builds a set of topics. - * - * @param properties the properties used to configure the topics - * @return a list of new topics - */ - protected abstract List buildTopics(Properties properties); - - /** - * Destroys the factory. - */ - protected abstract void destroyFactory(); - - /** - * Destroys a topic within the factory. - * - * @param topic the topic to destroy - */ - protected abstract void destroyTopic(String topic); - - /** - * Gets the list of topics from the factory. - * - * @return the topic inventory - */ - protected abstract List getInventory(); - - /** - * Gets a topic from the factory. - * - * @param topic the topic name - * @return the topic - */ - protected abstract T getTopic(String topic); - - - /** - * Tests building a topic using varied Properties. - */ - void testBuildProperties_Variations() { - initFactory(); - - // null topic list - assertTrue(buildTopics(makePropBuilder().build()).isEmpty()); - - // empty topic list - assertTrue(buildTopics(makePropBuilder().addTopic("").build()).isEmpty()); - - // null servers - assertTrue(buildTopics(makePropBuilder().makeTopic(MY_TOPIC).removeTopicProperty(PROPERTY_TOPIC_SERVERS_SUFFIX) - .build()).isEmpty()); - - // empty servers - assertTrue(buildTopics(makePropBuilder().makeTopic(MY_TOPIC).setTopicProperty(PROPERTY_TOPIC_SERVERS_SUFFIX, "") - .build()).isEmpty()); - } - - /** - * Tests building multiple topics using Properties. - */ - void testBuildProperties_Multiple() { - initFactory(); - - // make two fully-defined topics, and add two duplicate topic names to the list - TopicPropertyBuilder builder = - makePropBuilder().makeTopic(MY_TOPIC).makeTopic(TOPIC2).addTopic(MY_TOPIC).addTopic(MY_TOPIC); - - List lst = buildTopics(builder.build()); - assertEquals(4, lst.size()); - - int index = 0; - T item = lst.get(index++); - assertNotSame(item, lst.get(index++)); - assertSame(item, lst.get(index++)); - assertSame(item, lst.get(index++)); - } - - /** - * Tests destroy(topic), get(topic), and inventory() methods. - */ - void testDestroyString_testGet_testInventory() { - initFactory(); - - List lst = buildTopics(makePropBuilder().makeTopic(MY_TOPIC).makeTopic(TOPIC2).build()); - - int index = 0; - T item1 = lst.get(index++); - T item2 = lst.get(index++); - - assertEquals(2, getInventory().size()); - assertTrue(getInventory().contains(item1)); - assertTrue(getInventory().contains(item2)); - - item1.start(); - item2.start(); - - assertEquals(item1, getTopic(MY_TOPIC)); - assertEquals(item2, getTopic(TOPIC2)); - - destroyTopic(MY_TOPIC); - assertFalse(item1.isAlive()); - assertTrue(item2.isAlive()); - assertEquals(item2, getTopic(TOPIC2)); - assertEquals(1, getInventory().size()); - assertTrue(getInventory().contains(item2)); - - // repeat - destroyTopic(MY_TOPIC); - assertFalse(item1.isAlive()); - assertTrue(item2.isAlive()); - - // with other topic - destroyTopic(TOPIC2); - assertFalse(item1.isAlive()); - assertFalse(item2.isAlive()); - assertEquals(0, getInventory().size()); - } - - /** - * Tests exception cases with destroy(topic). - */ - void testDestroyString_Ex() { - // null topic - assertThatIllegalArgumentException().as("null topic").isThrownBy(() -> destroyTopic(null)); - - // empty topic - assertThatIllegalArgumentException().as("empty topic").isThrownBy(() -> destroyTopic("")); - } - - /** - * Tests the destroy() method. - */ - void testDestroy() { - initFactory(); - - List lst = buildTopics(makePropBuilder().makeTopic(MY_TOPIC).makeTopic(TOPIC2).build()); - - int index = 0; - T item1 = lst.get(index++); - T item2 = lst.get(index++); - - item1.start(); - item2.start(); - - destroyFactory(); - - assertFalse(item1.isAlive()); - assertFalse(item2.isAlive()); - assertEquals(0, getInventory().size()); - } - - /** - * Tests exception cases with get(topic). - */ - void testGet_Ex() { - // null topic - assertThatIllegalArgumentException().as("null topic").isThrownBy(() -> getTopic(null)); - - // empty topic - assertThatIllegalArgumentException().as("empty topic").isThrownBy(() -> getTopic("")); - - // unknown topic - initFactory(); - buildTopics(makePropBuilder().makeTopic(MY_TOPIC).build()); - - assertThatIllegalStateException().as("unknown topic").isThrownBy(() -> getTopic(TOPIC2)); - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/TopicPropertyBuilder.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/TopicPropertyBuilder.java deleted file mode 100644 index e8031c1a..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/TopicPropertyBuilder.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP Policy Engine - Common Modules - * ================================================================================ - * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import java.util.Properties; - -/** - * Builder of properties used when configuring topics. - */ -public abstract class TopicPropertyBuilder { - private final Properties properties = new Properties(); - private final String prefix; - private String topicPrefix; - - /** - * Constructs the object. - * - * @param prefix the prefix for the properties to be built - */ - public TopicPropertyBuilder(String prefix) { - this.prefix = prefix; - } - - /** - * Constructs the properties from the builder. - * - * @return a copy of the properties - */ - public Properties build() { - Properties props = new Properties(); - props.putAll(properties); - - return props; - } - - /** - * Adds a topic to the list of topics, configuring all of its properties with default - * values. - * - * @param topic the topic to be added - * @return this builder - */ - public abstract TopicPropertyBuilder makeTopic(String topic); - - /** - * Adds a topic to the list of topics. Also sets the current topic so that subsequent - * invocations of property methods will manipulate the topic's properties. - * - * @param topic the topic to be added - * @return this builder - */ - public TopicPropertyBuilder addTopic(String topic) { - // add topic to the list of topics - String topicList = properties.getProperty(prefix); - if (topicList == null || topicList.isEmpty()) { - topicList = topic; - } else { - topicList += "," + topic; - } - - properties.setProperty(prefix, topicList); - - setTopic(topic); - - return this; - } - - /** - * Sets the topic for which subsequent properties will be managed. - * - * @param topic the topic - * @return this builder - */ - public TopicPropertyBuilder setTopic(String topic) { - this.topicPrefix = prefix + "." + topic; - return this; - } - - /** - * Sets a topic's property. - * - * @param name name of the property - * @param value value to which the property should be set - * @return this builder - */ - public TopicPropertyBuilder setTopicProperty(String name, Object value) { - properties.setProperty(topicPrefix + name, value.toString()); - return this; - } - - /** - * Removes a topic's property. - * - * @param name name of the property - * @return this builder - */ - public TopicPropertyBuilder removeTopicProperty(String name) { - properties.remove(topicPrefix + name); - return this; - } -} - diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/TopicTestBase.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/TopicTestBase.java deleted file mode 100644 index 00111fb2..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/TopicTestBase.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2018-2019 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams.TopicParamsBuilder; - -/** - * Base class for Topic Test classes. - */ -public class TopicTestBase { - - public static final String MY_AFT_ENV = "my-aft-env"; - public static final String MY_API_KEY = "my-api-key"; - public static final String MY_API_SECRET = "my-api-secret"; - public static final String MY_BASE_PATH = "my-base"; - public static final String MY_CLIENT_NAME = "my-client"; - public static final String MY_CONS_GROUP = "my-cons-group"; - public static final String MY_CONS_INST = "my-cons-inst"; - public static final String MY_ENV = "my-env"; - public static final int MY_FETCH_LIMIT = 100; - public static final int MY_FETCH_TIMEOUT = 101; - public static final String MY_HOST = "my-host"; - public static final String MY_LAT = "my-lat"; - public static final String MY_LONG = "my-long"; - public static final String MY_PARTNER = "my-partner"; - public static final String MY_PASS = "my-pass"; - public static final int MY_PORT = 102; - public static final String MY_TOPIC = "my-topic"; - public static final String MY_EFFECTIVE_TOPIC = "my-effective-topic"; - public static final String MY_USERNAME = "my-user"; - - public static final String MY_MESSAGE = "my-message"; - public static final String MY_PARTITION = "my-partition"; - public static final String MY_MESSAGE2 = "my-message-2"; - public static final String MY_PARTITION2 = "my-partition-2"; - - public static final String ROUTE_PROP = "routeOffer"; - public static final String MY_ROUTE = "my-route"; - public static final String MY_SERIALIZER = "org.apache.kafka.common.serialization.StringSerializer"; - public static final int KAFKA_PORT = 9092; - - /** - * Message used within exceptions that are expected. - */ - public static final String EXPECTED = "expected exception"; - - /** - * Additional properties to be added to the parameter builder. - */ - protected Map addProps; - - /** - * Servers to be added to the parameter builder. - */ - protected List servers; - - /** - * Servers to be added to the parameter builder. - */ - protected List kafkaServers; - - /** - * Parameter builder used to build topic parameters. - */ - protected TopicParamsBuilder builder; - - /** - * Initializes {@link #addProps}, {@link #servers}, and {@link #builder}. - */ - public void setUp() { - addProps = new TreeMap<>(); - addProps.put("my-key-A", "my-value-A"); - addProps.put("my-key-B", "my-value-B"); - - servers = Arrays.asList("svra", "svrb"); - kafkaServers = Arrays.asList("localhost:9092", "10.1.2.3:9092"); - - builder = makeBuilder(); - } - - /** - * Makes a fully populated parameter builder. - * - * @return a new parameter builder - */ - public TopicParamsBuilder makeBuilder() { - return makeBuilder(addProps, servers); - } - - /** - * Makes a fully populated parameter builder. - * - * @param addProps additional properties to be added to the builder - * @param servers servers to be added to the builder - * @return a new parameter builder - */ - public TopicParamsBuilder makeBuilder(Map addProps, List servers) { - - return BusTopicParams.builder().additionalProps(addProps).aftEnvironment(MY_AFT_ENV).allowSelfSignedCerts(true) - .apiKey(MY_API_KEY).apiSecret(MY_API_SECRET).basePath(MY_BASE_PATH).clientName(MY_CLIENT_NAME) - .consumerGroup(MY_CONS_GROUP).consumerInstance(MY_CONS_INST).environment(MY_ENV) - .fetchLimit(MY_FETCH_LIMIT).fetchTimeout(MY_FETCH_TIMEOUT).hostname(MY_HOST).latitude(MY_LAT) - .longitude(MY_LONG).managed(true).partitionId(MY_PARTITION).partner(MY_PARTNER) - .password(MY_PASS).port(MY_PORT).servers(servers).topic(MY_TOPIC) - .effectiveTopic(MY_EFFECTIVE_TOPIC).useHttps(true).allowTracing(true).userName(MY_USERNAME) - .serializationProvider(MY_SERIALIZER); - } - - /** - * Makes a fully populated parameter builder. - * - * @return a new parameter builder - */ - public TopicParamsBuilder makeKafkaBuilder() { - addProps.clear(); - String jaas = "org.apache.kafka.common.security.plain.PlainLoginModule " - + "required username=abc password=abc serviceName=kafka;"; - addProps.put("sasl.jaas.config", jaas); - addProps.put("sasl.mechanism", "SCRAM-SHA-512"); - addProps.put("security.protocol", "SASL_PLAINTEXT"); - - return makeKafkaBuilder(addProps, kafkaServers); - } - - /** - * Makes a fully populated parameter builder. - * - * @param addProps additional properties to be added to the builder - * @param servers servers to be added to the builder - * @return a new parameter builder - */ - public TopicParamsBuilder makeKafkaBuilder(Map addProps, List servers) { - - return BusTopicParams.builder().additionalProps(addProps).basePath(MY_BASE_PATH).clientName(MY_CLIENT_NAME) - .consumerGroup(MY_CONS_GROUP).consumerInstance(MY_CONS_INST).environment(MY_ENV) - .hostname(MY_HOST).partitionId(MY_PARTITION).partner(MY_PARTNER).fetchTimeout(MY_FETCH_TIMEOUT) - .port(KAFKA_PORT).servers(servers).topic(MY_TOPIC) - .effectiveTopic(MY_EFFECTIVE_TOPIC).useHttps(false).allowTracing(true); - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusConsumerTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusConsumerTest.java deleted file mode 100644 index 36efff90..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusConsumerTest.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2018-2021 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2023-2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus.internal; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.concurrent.CountDownLatch; -import org.apache.kafka.clients.consumer.ConsumerConfig; -import org.apache.kafka.clients.consumer.ConsumerRecord; -import org.apache.kafka.clients.consumer.ConsumerRecords; -import org.apache.kafka.clients.consumer.KafkaConsumer; -import org.apache.kafka.common.TopicPartition; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.onap.policy.common.endpoints.event.comm.bus.TopicTestBase; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusConsumer.FetchingBusConsumer; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusConsumer.KafkaConsumerWrapper; -import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; - -class BusConsumerTest extends TopicTestBase { - - private static final int SHORT_TIMEOUT_MILLIS = 10; - private static final int LONG_TIMEOUT_MILLIS = 3000; - - @Mock - KafkaConsumer mockedKafkaConsumer; - - AutoCloseable closeable; - - @BeforeEach - @Override - public void setUp() { - super.setUp(); - closeable = MockitoAnnotations.openMocks(this); - } - - @AfterEach - public void tearDown() throws Exception { - closeable.close(); - } - - - @Test - void testFetchingBusConsumer() { - // should not be negative - var cons = new FetchingBusConsumerImpl(makeBuilder().fetchTimeout(-1).build()); - assertThat(cons.getSleepTime()).isEqualTo(PolicyEndPointProperties.DEFAULT_TIMEOUT_MS_FETCH); - - // should not be zero - cons = new FetchingBusConsumerImpl(makeBuilder().fetchTimeout(0).build()); - assertThat(cons.getSleepTime()).isEqualTo(PolicyEndPointProperties.DEFAULT_TIMEOUT_MS_FETCH); - - // should not be too large - cons = new FetchingBusConsumerImpl( - makeBuilder().fetchTimeout(PolicyEndPointProperties.DEFAULT_TIMEOUT_MS_FETCH + 100).build()); - assertThat(cons.getSleepTime()).isEqualTo(PolicyEndPointProperties.DEFAULT_TIMEOUT_MS_FETCH); - - // should not be what was specified - cons = new FetchingBusConsumerImpl(makeBuilder().fetchTimeout(100).build()); - assertThat(cons.getSleepTime()).isEqualTo(100); - } - - @Test - void testFetchingBusConsumerSleepAfterFetchFailure() throws InterruptedException { - - var cons = new FetchingBusConsumerImpl(makeBuilder().fetchTimeout(SHORT_TIMEOUT_MILLIS).build()) { - - private CountDownLatch started = new CountDownLatch(1); - - @Override - protected void sleepAfterFetchFailure() { - started.countDown(); - super.sleepAfterFetchFailure(); - } - }; - - // full sleep - long tstart = System.currentTimeMillis(); - cons.sleepAfterFetchFailure(); - assertThat(System.currentTimeMillis() - tstart).isGreaterThanOrEqualTo(SHORT_TIMEOUT_MILLIS); - - // close while sleeping - sleep should halt prematurely - cons.fetchTimeout = LONG_TIMEOUT_MILLIS; - cons.started = new CountDownLatch(1); - Thread thread = new Thread(cons::sleepAfterFetchFailure); - tstart = System.currentTimeMillis(); - thread.start(); - cons.started.await(); - cons.close(); - thread.join(); - assertThat(System.currentTimeMillis() - tstart).isLessThan(LONG_TIMEOUT_MILLIS); - - // interrupt while sleeping - sleep should halt prematurely - cons.fetchTimeout = LONG_TIMEOUT_MILLIS; - cons.started = new CountDownLatch(1); - thread = new Thread(cons::sleepAfterFetchFailure); - tstart = System.currentTimeMillis(); - thread.start(); - cons.started.await(); - thread.interrupt(); - thread.join(); - assertThat(System.currentTimeMillis() - tstart).isLessThan(LONG_TIMEOUT_MILLIS); - } - - @Test - void testKafkaConsumerWrapper() { - // verify that different wrappers can be built - assertThatCode(() -> new KafkaConsumerWrapper(makeKafkaBuilder().build())).doesNotThrowAnyException(); - } - - @Test - void testKafkaConsumerWrapper_InvalidTopic() { - BusTopicParams params = makeBuilder().topic(null).build(); - assertThatThrownBy(() -> new KafkaConsumerWrapper(params)) - .isInstanceOf(IllegalArgumentException.class); - } - - @Test - void testKafkaConsumerWrapperFetch() { - - //Setup Properties for consumer - Properties kafkaProps = new Properties(); - kafkaProps.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); - kafkaProps.setProperty(ConsumerConfig.GROUP_ID_CONFIG, "test"); - kafkaProps.setProperty("enable.auto.commit", "true"); - kafkaProps.setProperty("auto.commit.interval.ms", "1000"); - kafkaProps.setProperty(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, - "org.apache.kafka.common.serialization.StringDeserializer"); - kafkaProps.setProperty(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, - "org.apache.kafka.common.serialization.StringDeserializer"); - kafkaProps.setProperty(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); - kafkaProps.setProperty(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false"); - - KafkaConsumerWrapper kafka = new KafkaConsumerWrapper(makeKafkaBuilder().build()); - KafkaConsumer consumer = new KafkaConsumer<>(kafkaProps); - kafka.consumer = consumer; - - assertThrows(java.lang.IllegalStateException.class, () -> kafka.fetch().iterator().hasNext()); - consumer.close(); - } - - @Test - void testFetchNoMessages() { - KafkaConsumerWrapper kafkaConsumerWrapper = new KafkaConsumerWrapper(makeKafkaBuilder().build()); - kafkaConsumerWrapper.consumer = mockedKafkaConsumer; - - when(mockedKafkaConsumer.poll(any())).thenReturn(new ConsumerRecords<>(Collections.emptyMap())); - - Iterable result = kafkaConsumerWrapper.fetch(); - - verify(mockedKafkaConsumer).poll(any()); - - assertNotNull(result); - - assertFalse(result.iterator().hasNext()); - - mockedKafkaConsumer.close(); - } - - @Test - void testFetchWithMessages() { - // Setup - KafkaConsumerWrapper kafkaConsumerWrapper = new KafkaConsumerWrapper(makeKafkaBuilder().build()); - kafkaConsumerWrapper.consumer = mockedKafkaConsumer; - - ConsumerRecord customerRecord = - new ConsumerRecord<>("my-effective-topic", 0, 0, "key", "value"); - Map>> recordsMap = new HashMap<>(); - recordsMap.put(new TopicPartition("my-effective-topic", 0), Collections.singletonList(customerRecord)); - ConsumerRecords consumerRecords = new ConsumerRecords<>(recordsMap); - - when(mockedKafkaConsumer.poll(any())).thenReturn(consumerRecords); - - Iterable result = kafkaConsumerWrapper.fetch(); - - verify(mockedKafkaConsumer, times(1)).poll(any()); - - verify(mockedKafkaConsumer, times(1)).commitSync(any(Map.class)); - - assertNotNull(result); - - assertTrue(result.iterator().hasNext()); - - assertEquals("value", result.iterator().next()); - - mockedKafkaConsumer.close(); - } - - @Test - void testFetchWithMessagesAndTraceparent() { - // Setup - KafkaConsumerWrapper kafkaConsumerWrapper = new KafkaConsumerWrapper(makeKafkaBuilder().build()); - kafkaConsumerWrapper.consumer = mockedKafkaConsumer; - - ConsumerRecord customerRecord = - new ConsumerRecord<>("my-effective-topic", 0, 0, "key", "value"); - customerRecord.headers().add( - "traceparent", - "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01".getBytes(StandardCharsets.UTF_8) - ); - - Map>> recordsMap = new HashMap<>(); - recordsMap.put(new TopicPartition("my-effective-topic", 0), Collections.singletonList(customerRecord)); - ConsumerRecords consumerRecords = new ConsumerRecords<>(recordsMap); - - when(mockedKafkaConsumer.poll(any())).thenReturn(consumerRecords); - - Iterable result = kafkaConsumerWrapper.fetch(); - - verify(mockedKafkaConsumer, times(1)).poll(any()); - - verify(mockedKafkaConsumer, times(1)).commitSync(any(Map.class)); - - assertNotNull(result); - - assertTrue(result.iterator().hasNext()); - - assertEquals("value", result.iterator().next()); - - mockedKafkaConsumer.close(); - } - - - @Test - void testKafkaConsumerWrapperClose() { - assertThatCode(() -> new KafkaConsumerWrapper(makeKafkaBuilder().build()).close()).doesNotThrowAnyException(); - } - - @Test - void testKafkaConsumerWrapperToString() { - assertNotNull(new KafkaConsumerWrapper(makeKafkaBuilder().build()) {}.toString()); - } - - private static class FetchingBusConsumerImpl extends FetchingBusConsumer { - - protected FetchingBusConsumerImpl(BusTopicParams busTopicParams) { - super(busTopicParams); - } - - @Override - public Iterable fetch() { - return null; - } - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicBaseTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicBaseTest.java deleted file mode 100644 index f24f7e2e..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicBaseTest.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus.internal; - -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.onap.policy.common.endpoints.event.comm.bus.TopicTestBase; -import org.onap.policy.common.utils.gson.GsonTestUtils; - -class BusTopicBaseTest extends TopicTestBase { - - private BusTopicBaseImpl base; - - /** - * Initializes the object to be tested. - */ - @BeforeEach - @Override - public void setUp() { - super.setUp(); - - base = new BusTopicBaseImpl(builder.build()); - } - - @Test - void testToString() { - assertNotNull(base.toString()); - } - - @Test - void testSerialize() { - assertThatCode(() -> new GsonTestUtils().compareGson(base, BusTopicBaseTest.class)).doesNotThrowAnyException(); - } - - @Test - void testGetApiKey() { - assertEquals(MY_API_KEY, base.getApiKey()); - } - - @Test - void testGetApiSecret() { - assertEquals(MY_API_SECRET, base.getApiSecret()); - } - - @Test - void testIsUseHttps() { - assertTrue(base.isUseHttps()); - assertFalse(new BusTopicBaseImpl(builder.useHttps(false).build()).isUseHttps()); - } - - @Test - void testIsAllowSelfSignedCerts() { - assertTrue(base.isAllowSelfSignedCerts()); - assertFalse(new BusTopicBaseImpl(builder.allowSelfSignedCerts(false).build()).isAllowSelfSignedCerts()); - } - - @Test - void testTopic() { - assertEquals(MY_TOPIC, base.getTopic()); - assertEquals(MY_EFFECTIVE_TOPIC, base.getEffectiveTopic()); - assertNotEquals(base.getTopic(), base.getEffectiveTopic()); - } - - @Test - void testAnyNullOrEmpty() { - assertFalse(base.anyNullOrEmpty()); - assertFalse(base.anyNullOrEmpty("any-none-null", "any-none-null-B")); - - assertTrue(base.anyNullOrEmpty(null, "any-first-null")); - assertTrue(base.anyNullOrEmpty("any-middle-null", null, "any-middle-null-B")); - assertTrue(base.anyNullOrEmpty("any-last-null", null)); - assertTrue(base.anyNullOrEmpty("any-empty", "")); - } - - @Test - void testAllNullOrEmpty() { - assertTrue(base.allNullOrEmpty()); - assertTrue(base.allNullOrEmpty("")); - assertTrue(base.allNullOrEmpty(null, "")); - - assertFalse(base.allNullOrEmpty("all-ok-only-one")); - assertFalse(base.allNullOrEmpty("all-ok-one", "all-ok-two")); - assertFalse(base.allNullOrEmpty("all-ok-null", null)); - assertFalse(base.allNullOrEmpty("", "all-ok-empty")); - assertFalse(base.allNullOrEmpty("", "all-one-ok", null)); - } - - private static class BusTopicBaseImpl extends BusTopicBase { - - public BusTopicBaseImpl(BusTopicParams busTopicParams) { - super(busTopicParams); - } - - @Override - public CommInfrastructure getTopicCommInfrastructure() { - return CommInfrastructure.NOOP; - } - - @Override - public boolean start() { - return true; - } - - @Override - public boolean stop() { - return true; - } - - @Override - public void shutdown() { - // do nothing - } - - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicParamsTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicParamsTest.java deleted file mode 100644 index e016ca2b..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicParamsTest.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus.internal; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.LinkedList; -import java.util.List; -import java.util.function.BiConsumer; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.onap.policy.common.endpoints.event.comm.bus.TopicTestBase; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams.TopicParamsBuilder; - -class BusTopicParamsTest extends TopicTestBase { - - @BeforeEach - @Override - public void setUp() { - super.setUp(); - } - - @Test - void testGetters() { - BusTopicParams params = makeBuilder().build(); - - assertEquals(addProps, params.getAdditionalProps()); - assertEquals(MY_AFT_ENV, params.getAftEnvironment()); - assertTrue(params.isAllowSelfSignedCerts()); - assertEquals(MY_API_KEY, params.getApiKey()); - assertEquals(MY_API_SECRET, params.getApiSecret()); - assertEquals(MY_BASE_PATH, params.getBasePath()); - assertEquals(MY_CLIENT_NAME, params.getClientName()); - assertEquals(MY_CONS_GROUP, params.getConsumerGroup()); - assertEquals(MY_CONS_INST, params.getConsumerInstance()); - assertEquals(MY_ENV, params.getEnvironment()); - assertEquals(MY_FETCH_LIMIT, params.getFetchLimit()); - assertEquals(MY_FETCH_TIMEOUT, params.getFetchTimeout()); - assertEquals(MY_HOST, params.getHostname()); - assertEquals(MY_LAT, params.getLatitude()); - assertEquals(MY_LONG, params.getLongitude()); - assertTrue(params.isManaged()); - assertEquals(MY_PARTITION, params.getPartitionId()); - assertEquals(MY_PARTNER, params.getPartner()); - assertEquals(MY_PASS, params.getPassword()); - assertEquals(MY_PORT, params.getPort()); - assertEquals(servers, params.getServers()); - assertEquals(MY_TOPIC, params.getTopic()); - assertEquals(MY_EFFECTIVE_TOPIC, params.getEffectiveTopic()); - assertTrue(params.isUseHttps()); - assertEquals(MY_USERNAME, params.getUserName()); - } - - @Test - void testBooleanGetters() { - // ensure that booleans are independent of each other - testBoolean("true:false:false", TopicParamsBuilder::allowSelfSignedCerts); - testBoolean("false:true:false", TopicParamsBuilder::managed); - testBoolean("false:false:true", TopicParamsBuilder::useHttps); - } - - @Test - void testValidators() { - BusTopicParams params = makeBuilder().build(); - - // test validity methods - assertTrue(params.isAdditionalPropsValid()); - assertFalse(params.isAftEnvironmentInvalid()); - assertTrue(params.isApiKeyValid()); - assertTrue(params.isApiSecretValid()); - assertFalse(params.isClientNameInvalid()); - assertFalse(params.isConsumerGroupInvalid()); - assertFalse(params.isConsumerInstanceInvalid()); - assertFalse(params.isEnvironmentInvalid()); - assertFalse(params.isHostnameInvalid()); - assertFalse(params.isLatitudeInvalid()); - assertFalse(params.isLongitudeInvalid()); - assertFalse(params.isPartitionIdInvalid()); - assertFalse(params.isPartnerInvalid()); - assertTrue(params.isPasswordValid()); - assertFalse(params.isPortInvalid()); - assertFalse(params.isServersInvalid()); - assertFalse(params.isTopicInvalid()); - assertTrue(params.isUserNameValid()); - } - - @Test - void testInvertedValidators() { - assertFalse(makeBuilder().additionalProps(null).build().isAdditionalPropsValid()); - assertTrue(makeBuilder().aftEnvironment("").build().isAftEnvironmentInvalid()); - assertFalse(makeBuilder().apiKey("").build().isApiKeyValid()); - assertFalse(makeBuilder().apiSecret("").build().isApiSecretValid()); - assertTrue(makeBuilder().clientName("").build().isClientNameInvalid()); - assertTrue(makeBuilder().consumerGroup("").build().isConsumerGroupInvalid()); - assertTrue(makeBuilder().consumerInstance("").build().isConsumerInstanceInvalid()); - assertTrue(makeBuilder().environment("").build().isEnvironmentInvalid()); - assertTrue(makeBuilder().hostname("").build().isHostnameInvalid()); - assertTrue(makeBuilder().latitude("").build().isLatitudeInvalid()); - assertTrue(makeBuilder().longitude("").build().isLongitudeInvalid()); - assertTrue(makeBuilder().partitionId("").build().isPartitionIdInvalid()); - assertTrue(makeBuilder().partner("").build().isPartnerInvalid()); - assertFalse(makeBuilder().password("").build().isPasswordValid()); - assertTrue(makeBuilder().port(-1).build().isPortInvalid()); - assertTrue(makeBuilder().port(65536).build().isPortInvalid()); - assertTrue(makeBuilder().servers(null).build().isServersInvalid()); - assertTrue(makeBuilder().servers(new LinkedList<>()).build().isServersInvalid()); - assertTrue(makeBuilder().servers(List.of("")).build().isServersInvalid()); - assertFalse(makeBuilder().servers(List.of("one-server")).build().isServersInvalid()); - assertTrue(makeBuilder().topic("").build().isTopicInvalid()); - assertFalse(makeBuilder().userName("").build().isUserNameValid()); - } - - /** - * Tests the boolean methods by applying a function, once with {@code false} and once - * with {@code true}. Verifies that all the boolean methods return the correct - * value by concatenating them. - * - * @param expectedTrue the string that is expected when {@code true} is passed to the - * method - * @param function function to be applied to the builder - */ - private void testBoolean(String expectedTrue, BiConsumer function) { - TopicParamsBuilder builder = BusTopicParams.builder(); - - // first try the "false" case - function.accept(builder, false); - - BusTopicParams params = builder.build(); - assertEquals("false:false:false", - params.isAllowSelfSignedCerts() + ":" + params.isManaged() + ":" + params.isUseHttps()); - - - // now try the "true" case - function.accept(builder, true); - - params = builder.build(); - assertEquals(expectedTrue, - params.isAllowSelfSignedCerts() + ":" + params.isManaged() + ":" + params.isUseHttps()); - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineBusTopicSinkTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineBusTopicSinkTest.java deleted file mode 100644 index ce363269..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineBusTopicSinkTest.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus.internal; - -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.Arrays; -import java.util.List; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.endpoints.event.comm.TopicListener; -import org.onap.policy.common.endpoints.event.comm.bus.TopicTestBase; -import org.onap.policy.common.utils.gson.GsonTestUtils; - -class InlineBusTopicSinkTest extends TopicTestBase { - - private InlineBusTopicSinkImpl sink; - - /** - * Creates the object to be tested. - */ - @BeforeEach - @Override - public void setUp() { - super.setUp(); - - sink = new InlineBusTopicSinkImpl(makeBuilder().build()); - } - - @AfterEach - public void tearDown() { - sink.shutdown(); - } - - @Test - void testSerialize() { - assertThatCode(() -> new GsonTestUtils().compareGson(sink, InlineBusTopicSinkTest.class)) - .doesNotThrowAnyException(); - } - - @Test - void testInlineBusTopicSinkImpl() { - // verify that different wrappers can be built - sink = new InlineBusTopicSinkImpl(makeBuilder().build()); - assertEquals(MY_PARTITION, sink.getPartitionKey()); - - sink = new InlineBusTopicSinkImpl(makeBuilder().partitionId(null).build()); - assertNotNull(sink.getPartitionKey()); - } - - @Test - void testStart() { - assertTrue(sink.start()); - assertEquals(1, sink.initCount); - - // re-start, init() should not be invoked again - assertTrue(sink.start()); - assertEquals(1, sink.initCount); - } - - @Test - void testStart_Locked() { - sink.lock(); - assertThatThrownBy(() -> sink.start()).isInstanceOf(IllegalStateException.class); - } - - @Test - void testStop() { - BusPublisher pub = mock(BusPublisher.class); - sink.publisher = pub; - - assertTrue(sink.stop()); - verify(pub).close(); - - // stop again, shouldn't not invoke close() again - assertFalse(sink.stop()); - verify(pub).close(); - - // publisher throws exception - sink = new InlineBusTopicSinkImpl(makeBuilder().build()); - sink.publisher = pub; - doThrow(new RuntimeException(EXPECTED)).when(pub).close(); - assertTrue(sink.stop()); - } - - @Test - void testSend() { - sink.start(); - BusPublisher pub = mock(BusPublisher.class); - sink.publisher = pub; - - TopicListener listener = mock(TopicListener.class); - sink.register(listener); - - assertTrue(sink.send(MY_MESSAGE)); - - verify(pub).send(MY_PARTITION, MY_MESSAGE); - verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE); - assertEquals(List.of(MY_MESSAGE), Arrays.asList(sink.getRecentEvents())); - - // arrange for send to throw an exception - when(pub.send(anyString(), anyString())).thenThrow(new RuntimeException(EXPECTED)); - - assertFalse(sink.send(MY_MESSAGE)); - - // no more event deliveries - verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE); - } - - @Test - void testSend_NullMessage() { - sink.start(); - sink.publisher = mock(BusPublisher.class); - - assertThatThrownBy(() -> sink.send(null)).isInstanceOf(IllegalArgumentException.class); - } - - @Test - void testSend_EmptyMessage() { - sink.start(); - sink.publisher = mock(BusPublisher.class); - - assertThatThrownBy(() -> sink.send("")).isInstanceOf(IllegalArgumentException.class); - } - - @Test - void testSend_NotStarted() { - sink.publisher = mock(BusPublisher.class); - assertThatThrownBy(() -> sink.send(MY_MESSAGE)).isInstanceOf(IllegalStateException.class); - } - - @Test - void testSetPartitionKey_getPartitionKey() { - assertEquals(MY_PARTITION, sink.getPartitionKey()); - - sink.setPartitionKey("part-B"); - assertEquals("part-B", sink.getPartitionKey()); - } - - @Test - void testShutdown() { - BusPublisher pub = mock(BusPublisher.class); - sink.publisher = pub; - - sink.shutdown(); - verify(pub).close(); - } - - @Test - void testAnyNullOrEmpty() { - assertFalse(sink.anyNullOrEmpty()); - assertFalse(sink.anyNullOrEmpty("any-none-null", "any-none-null-B")); - - assertTrue(sink.anyNullOrEmpty(null, "any-first-null")); - assertTrue(sink.anyNullOrEmpty("any-middle-null", null, "any-middle-null-B")); - assertTrue(sink.anyNullOrEmpty("any-last-null", null)); - assertTrue(sink.anyNullOrEmpty("any-empty", "")); - } - - @Test - void testAllNullOrEmpty() { - assertTrue(sink.allNullOrEmpty()); - assertTrue(sink.allNullOrEmpty("")); - assertTrue(sink.allNullOrEmpty(null, "")); - - assertFalse(sink.allNullOrEmpty("all-ok-only-one")); - assertFalse(sink.allNullOrEmpty("all-ok-one", "all-ok-two")); - assertFalse(sink.allNullOrEmpty("all-ok-null", null)); - assertFalse(sink.allNullOrEmpty("", "all-ok-empty")); - assertFalse(sink.allNullOrEmpty("", "all-one-ok", null)); - } - - @Test - void testToString() { - assertTrue(sink.toString().startsWith("InlineBusTopicSink [")); - } - - /** - * Implementation of InlineBusTopicSink that tracks the number of times that init() is - * invoked. - */ - private static class InlineBusTopicSinkImpl extends InlineBusTopicSink { - - private int initCount = 0; - - public InlineBusTopicSinkImpl(BusTopicParams busTopicParams) { - super(busTopicParams); - } - - @Override - public CommInfrastructure getTopicCommInfrastructure() { - return CommInfrastructure.NOOP; - } - - @Override - public void init() { - ++initCount; - } - - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineKafkaTopicSinkTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineKafkaTopicSinkTest.java deleted file mode 100644 index 91412ff6..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineKafkaTopicSinkTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2022-2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus.internal; - -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.endpoints.event.comm.bus.TopicTestBase; - -class InlineKafkaTopicSinkTest extends TopicTestBase { - private InlineKafkaTopicSink sink; - - /** - * Creates the object to be tested. - */ - @BeforeEach - @Override - public void setUp() { - super.setUp(); - - sink = new InlineKafkaTopicSink(makeKafkaBuilder().build()); - } - - @AfterEach - public void tearDown() { - sink.shutdown(); - } - - @Test - void testToString() { - assertTrue(sink.toString().startsWith("InlineKafkaTopicSink [")); - } - - @Test - void testInit() { - // nothing null - sink = new InlineKafkaTopicSink(makeKafkaBuilder().build()); - sink.init(); - assertThatCode(() -> sink.shutdown()).doesNotThrowAnyException(); - } - - @Test - void testGetTopicCommInfrastructure() { - assertEquals(CommInfrastructure.KAFKA, sink.getTopicCommInfrastructure()); - } - -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/KafkaPublisherWrapperTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/KafkaPublisherWrapperTest.java deleted file mode 100644 index 1f7c2cf7..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/KafkaPublisherWrapperTest.java +++ /dev/null @@ -1,97 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2024 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus.internal; - -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.Collections; -import java.util.Properties; -import org.apache.kafka.clients.producer.KafkaProducer; -import org.apache.kafka.clients.producer.Producer; -import org.apache.kafka.clients.producer.ProducerRecord; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentMatchers; - -class KafkaPublisherWrapperTest { - - private BusPublisher.KafkaPublisherWrapper kafkaPublisherWrapper; - private Producer mockProducer; - private BusTopicParams mockBusTopicParams; - - @BeforeEach - void setUp() { - mockProducer = mock(KafkaProducer.class); - mockBusTopicParams = mock(BusTopicParams.class); - - when(mockBusTopicParams.getTopic()).thenReturn("testTopic"); - when(mockBusTopicParams.getServers()).thenReturn(Collections.singletonList("localhost:9092")); - when(mockBusTopicParams.isTopicInvalid()).thenReturn(false); - when(mockBusTopicParams.isAdditionalPropsValid()).thenReturn(false); - when(mockBusTopicParams.isAllowTracing()).thenReturn(false); - - kafkaPublisherWrapper = new BusPublisher.KafkaPublisherWrapper(mockBusTopicParams) { - protected Producer createProducer(Properties props) { // NOSONAR instance creation - return mockProducer; - } - }; - } - - @Test - void testConstructor() { - verify(mockBusTopicParams).getTopic(); - verify(mockBusTopicParams).getServers(); - verify(mockBusTopicParams).isTopicInvalid(); - verify(mockBusTopicParams).isAdditionalPropsValid(); - verify(mockBusTopicParams).isAllowTracing(); - } - - @Test - void testSendSuccess() { - when(mockProducer.send(ArgumentMatchers.any(ProducerRecord.class))).thenReturn(null); - assertTrue(kafkaPublisherWrapper.send("partitionId", "testMessage")); - } - - @Test - void testSendNullMessage() { - IllegalArgumentException thrown = assertThrows( - IllegalArgumentException.class, - () -> kafkaPublisherWrapper.send("partitionId", null), - "Expected send() to throw, but it didn't" - ); - assertEquals("No message provided", thrown.getMessage()); - } - - @Test - void testSendFailure() { - when(mockProducer.send(ArgumentMatchers.any(ProducerRecord.class))).thenThrow(RuntimeException.class); - assertTrue(kafkaPublisherWrapper.send("partitionId", "testMessage")); - } - - @Test - void testClose() { - assertThatCode(kafkaPublisherWrapper::close).doesNotThrowAnyException(); - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedBusTopicSourceTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedBusTopicSourceTest.java deleted file mode 100644 index bc2d3779..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedBusTopicSourceTest.java +++ /dev/null @@ -1,377 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2018-2021 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus.internal; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.util.Arrays; -import java.util.Collections; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.endpoints.event.comm.TopicListener; -import org.onap.policy.common.endpoints.event.comm.bus.TopicTestBase; -import org.onap.policy.common.utils.gson.GsonTestUtils; -import org.onap.policy.common.utils.network.NetworkUtil; - -class SingleThreadedBusTopicSourceTest extends TopicTestBase { - private Thread thread; - private BusConsumer cons; - private TopicListener listener; - private SingleThreadedBusTopicSourceImpl source; - - /** - * Creates the object to be tested, as well as various mocks. - */ - @BeforeEach - @Override - public void setUp() { - super.setUp(); - - thread = mock(Thread.class); - cons = mock(BusConsumer.class); - listener = mock(TopicListener.class); - source = new SingleThreadedBusTopicSourceImpl(makeBuilder().build()); - } - - @AfterEach - public void tearDown() { - source.shutdown(); - } - - @Test - void testSerialize() { - assertThatCode(() -> new GsonTestUtils().compareGson(source, SingleThreadedBusTopicSourceTest.class)) - .doesNotThrowAnyException(); - } - - @Test - void testRegister() { - source.register(listener); - assertEquals(1, source.initCount); - source.offer(MY_MESSAGE); - verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE); - - // register another - should not re-init - TopicListener listener2 = mock(TopicListener.class); - source.register(listener2); - assertEquals(1, source.initCount); - source.offer(MY_MESSAGE + "z"); - verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE + "z"); - verify(listener2).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE + "z"); - - // re-register - should not re-init - source.register(listener); - assertEquals(1, source.initCount); - source.offer(MY_MESSAGE2); - verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE2); - - // lock & register - should not init - source = new SingleThreadedBusTopicSourceImpl(makeBuilder().build()); - source.lock(); - source.register(listener); - assertEquals(0, source.initCount); - - // exception during init - source = new SingleThreadedBusTopicSourceImpl(makeBuilder().build()); - source.initEx = true; - source.register(listener); - } - - @Test - void testUnregister() { - TopicListener listener2 = mock(TopicListener.class); - source.register(listener); - source.register(listener2); - - // unregister first listener - should NOT invoke close - source.unregister(listener); - verify(cons, never()).close(); - assertEquals(Arrays.asList(listener2), source.snapshotTopicListeners()); - - // unregister same listener - should not invoke close - source.unregister(listener); - verify(cons, never()).close(); - assertEquals(Arrays.asList(listener2), source.snapshotTopicListeners()); - - // unregister second listener - SHOULD invoke close - source.unregister(listener2); - verify(cons).close(); - assertTrue(source.snapshotTopicListeners().isEmpty()); - - // unregister same listener - should not invoke close again - source.unregister(listener2); - verify(cons).close(); - assertTrue(source.snapshotTopicListeners().isEmpty()); - } - - @Test - void testToString() { - assertTrue(source.toString().startsWith("SingleThreadedBusTopicSource [")); - } - - @Test - void testMakePollerThread() { - SingleThreadedBusTopicSource source2 = new SingleThreadedBusTopicSource(makeBuilder().build()) { - @Override - public CommInfrastructure getTopicCommInfrastructure() { - return CommInfrastructure.NOOP; - } - - @Override - public void init() throws MalformedURLException { - // do nothing - } - }; - - assertNotNull(source2.makePollerThread()); - } - - @Test - void testSingleThreadedBusTopicSource() { - // Note: if the value contains "-", it's probably a UUID - - // verify that different wrappers can be built - source = new SingleThreadedBusTopicSourceImpl(makeBuilder().build()); - assertThat(source.getConsumerGroup()).isEqualTo(MY_CONS_GROUP); - assertThat(source.getConsumerInstance()).isEqualTo(MY_CONS_INST); - - // group is null => group is UUID, instance is as provided - source = new SingleThreadedBusTopicSourceImpl(makeBuilder().consumerGroup(null).build()); - assertThat(source.getConsumerGroup()).contains("-").isNotEqualTo(NetworkUtil.getHostname()); - assertThat(source.getConsumerInstance()).isEqualTo(MY_CONS_INST); - - // instance is null => group is as provided, instance is UUID - source = new SingleThreadedBusTopicSourceImpl(makeBuilder().consumerInstance(null).build()); - assertThat(source.getConsumerGroup()).isEqualTo(MY_CONS_GROUP); - assertThat(source.getConsumerInstance()).contains("-").isNotEqualTo(NetworkUtil.getHostname()); - - // group & instance are null => group is UUID, instance is hostname - source = new SingleThreadedBusTopicSourceImpl(makeBuilder().consumerGroup(null).consumerInstance(null).build()); - assertThat(source.getConsumerGroup()).contains("-").isNotEqualTo(NetworkUtil.getHostname()); - assertThat(source.getConsumerInstance()).isEqualTo(NetworkUtil.getHostname()); - - assertThatCode(() -> new SingleThreadedBusTopicSourceImpl( - makeBuilder().fetchLimit(-1).fetchTimeout(-1).build())).doesNotThrowAnyException(); - } - - @Test - void testStart() { - source.start(); - assertTrue(source.isAlive()); - assertEquals(1, source.initCount); - verify(thread).start(); - - // attempt to start again - nothing should be invoked again - source.start(); - assertTrue(source.isAlive()); - assertEquals(1, source.initCount); - verify(thread).start(); - - // stop & re-start - source.stop(); - source.start(); - assertTrue(source.isAlive()); - assertEquals(2, source.initCount); - verify(thread, times(2)).start(); - } - - @Test - void testStart_Locked() { - source.lock(); - assertThatThrownBy(() -> source.start()).isInstanceOf(IllegalStateException.class); - } - - @Test - void testStart_InitEx() { - assertThatThrownBy(() -> { - source.initEx = true; - - source.start(); - }).isInstanceOf(IllegalStateException.class); - } - - @Test - void testStop() { - source.start(); - source.stop(); - verify(cons).close(); - - // stop it again - not re-closed - source.stop(); - verify(cons).close(); - - // start & stop again, but with an exception - doThrow(new RuntimeException(EXPECTED)).when(cons).close(); - source.start(); - source.stop(); - } - - @Test - void testRun() throws Exception { - source.register(listener); - - /* - * Die in the middle of fetching messages. Also, throw an exception during the - * first fetch attempt. - */ - when(cons.fetch()).thenAnswer(new Answer>() { - int count = 0; - - @Override - public Iterable answer(InvocationOnMock invocation) throws Throwable { - if (++count > 1) { - source.alive = false; - return Arrays.asList(MY_MESSAGE, MY_MESSAGE2); - - } else { - throw new IOException(EXPECTED); - } - } - }); - source.alive = true; - source.run(); - assertEquals(Arrays.asList(MY_MESSAGE), Arrays.asList(source.getRecentEvents())); - verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE); - verify(listener, never()).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE2); - - /* - * Die AFTER fetching messages. - */ - final String msga = "message-A"; - final String msgb = "message-B"; - when(cons.fetch()).thenAnswer(new Answer>() { - int count = 0; - - @Override - public Iterable answer(InvocationOnMock invocation) throws Throwable { - if (++count > 1) { - source.alive = false; - return Collections.emptyList(); - - } else { - return Arrays.asList(msga, msgb); - } - } - }); - source.alive = true; - source.run(); - verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, msga); - verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, msgb); - - assertEquals(Arrays.asList(MY_MESSAGE, msga, msgb), Arrays.asList(source.getRecentEvents())); - } - - @Test - void testOffer() { - source.register(listener); - source.offer(MY_MESSAGE); - verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, MY_MESSAGE); - assertEquals(Arrays.asList(MY_MESSAGE), Arrays.asList(source.getRecentEvents())); - } - - @Test - void testOffer_NotStarted() { - assertThatThrownBy(() -> source.offer(MY_MESSAGE)).isInstanceOf(IllegalStateException.class); - } - - @Test - void testGetConsumerGroup() { - assertEquals(MY_CONS_GROUP, source.getConsumerGroup()); - } - - @Test - void testGetConsumerInstance() { - assertEquals(MY_CONS_INST, source.getConsumerInstance()); - } - - @Test - void testShutdown() { - source.register(listener); - - source.shutdown(); - verify(cons).close(); - assertTrue(source.snapshotTopicListeners().isEmpty()); - } - - @Test - void testGetFetchTimeout() { - assertEquals(MY_FETCH_TIMEOUT, source.getFetchTimeout()); - } - - @Test - void testGetFetchLimit() { - assertEquals(MY_FETCH_LIMIT, source.getFetchLimit()); - } - - /** - * Implementation of SingleThreadedBusTopicSource that counts the number of times - * init() is invoked. - */ - private class SingleThreadedBusTopicSourceImpl extends SingleThreadedBusTopicSource { - - private int initCount = 0; - private boolean initEx = false; - - public SingleThreadedBusTopicSourceImpl(BusTopicParams busTopicParams) { - super(busTopicParams); - } - - @Override - public CommInfrastructure getTopicCommInfrastructure() { - return CommInfrastructure.NOOP; - } - - @Override - public void init() throws MalformedURLException { - ++initCount; - - if (initEx) { - throw new MalformedURLException(EXPECTED); - } - - consumer = cons; - } - - @Override - protected Thread makePollerThread() { - return thread; - } - - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedKafkaTopicSourceTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedKafkaTopicSourceTest.java deleted file mode 100644 index 84df1228..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedKafkaTopicSourceTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus.internal; - -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.endpoints.event.comm.bus.TopicTestBase; -import org.onap.policy.common.utils.gson.GsonTestUtils; - -class SingleThreadedKafkaTopicSourceTest extends TopicTestBase { - private SingleThreadedKafkaTopicSource source; - - /** - * Creates the object to be tested. - */ - @BeforeEach - @Override - public void setUp() { - super.setUp(); - - source = new SingleThreadedKafkaTopicSource(makeKafkaBuilder().build()); - } - - @AfterEach - public void tearDown() { - source.shutdown(); - } - - void testSerialize() { - assertThatCode(() -> new GsonTestUtils().compareGson(source, SingleThreadedKafkaTopicSourceTest.class)) - .doesNotThrowAnyException(); - } - - @Test - void testToString() { - assertTrue(source.toString().startsWith("SingleThreadedKafkaTopicSource [")); - source.shutdown(); - } - - @Test - void testGetTopicCommInfrastructure() { - assertEquals(CommInfrastructure.KAFKA, source.getTopicCommInfrastructure()); - } - -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/TopicBaseTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/TopicBaseTest.java deleted file mode 100644 index fe719848..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/bus/internal/TopicBaseTest.java +++ /dev/null @@ -1,357 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.bus.internal; - -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.endpoints.event.comm.TopicListener; -import org.onap.policy.common.endpoints.event.comm.bus.TopicTestBase; -import org.onap.policy.common.utils.gson.GsonTestUtils; - -class TopicBaseTest extends TopicTestBase { - - private TopicBaseImpl base; - - /** - * Creates the object to be tested. - */ - @BeforeEach - @Override - public void setUp() { - super.setUp(); - - base = new TopicBaseImpl(servers, MY_TOPIC); - } - - @Test - void testTopicBase_NullServers() { - assertThatThrownBy(() -> new TopicBaseImpl(null, MY_TOPIC)).isInstanceOf(IllegalArgumentException.class); - } - - @Test - void testTopicBase_EmptyServers() { - List testList = Collections.emptyList(); - assertThatThrownBy(() -> new TopicBaseImpl(testList, MY_TOPIC)) - .isInstanceOf(IllegalArgumentException.class); - } - - @Test - void testTopicBase_NullTopic() { - assertThatThrownBy(() -> new TopicBaseImpl(servers, null)).isInstanceOf(IllegalArgumentException.class); - } - - @Test - void testTopicBase_EmptyTopic() { - assertThatThrownBy(() -> new TopicBaseImpl(servers, "")).isInstanceOf(IllegalArgumentException.class); - } - - @Test - void testTopicBase_EffectiveTopic() { - TopicBase baseEf = new TopicBaseImpl(servers, MY_TOPIC, MY_EFFECTIVE_TOPIC); - assertEquals(MY_TOPIC, baseEf.getTopic()); - assertEquals(MY_EFFECTIVE_TOPIC, baseEf.getEffectiveTopic()); - } - - @Test - void testTopicBase_NullEffectiveTopic() { - TopicBase baseEf = new TopicBaseImpl(servers, MY_TOPIC, null); - assertEquals(MY_TOPIC, baseEf.getTopic()); - assertEquals(MY_TOPIC, baseEf.getEffectiveTopic()); - } - - @Test - void testTopicBase_EmptyEffectiveTopic() { - TopicBase baseEf = new TopicBaseImpl(servers, MY_TOPIC, ""); - assertEquals(MY_TOPIC, baseEf.getTopic()); - assertEquals(MY_TOPIC, baseEf.getEffectiveTopic()); - } - - @Test - void testSerialize() { - assertThatCode(() -> new GsonTestUtils().compareGson(base, TopicBaseTest.class)).doesNotThrowAnyException(); - } - - @Test - void testRegister() { - TopicListener listener = mock(TopicListener.class); - base.register(listener); - assertEquals(Arrays.asList(listener), base.snapshotTopicListeners()); - - // re-register - list should be unchanged - base.register(listener); - assertEquals(Arrays.asList(listener), base.snapshotTopicListeners()); - - // register a new listener - TopicListener listener2 = mock(TopicListener.class); - base.register(listener2); - assertEquals(Arrays.asList(listener, listener2), base.snapshotTopicListeners()); - } - - @Test - void testRegister_NullListener() { - assertThatThrownBy(() -> base.register(null)).isInstanceOf(IllegalArgumentException.class); - } - - @Test - void testUnregister() { - // register two listeners - TopicListener listener = mock(TopicListener.class); - TopicListener listener2 = mock(TopicListener.class); - base.register(listener); - base.register(listener2); - - // unregister one - base.unregister(listener); - assertEquals(Arrays.asList(listener2), base.snapshotTopicListeners()); - - // unregister the other - base.unregister(listener2); - assertTrue(base.snapshotTopicListeners().isEmpty()); - - // unregister again - base.unregister(listener2); - assertTrue(base.snapshotTopicListeners().isEmpty()); - } - - @Test - void testUnregister_NullListener() { - base.register(mock(TopicListener.class)); - assertThatThrownBy(() -> base.unregister(null)).isInstanceOf(IllegalArgumentException.class); - } - - @Test - void testBroadcast() { - // register two listeners - TopicListener listener = mock(TopicListener.class); - TopicListener listener2 = mock(TopicListener.class); - base.register(listener); - base.register(listener2); - - // broadcast a message - final String msg1 = "message-A"; - base.broadcast(msg1); - verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, msg1); - verify(listener2).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, msg1); - - // broadcast another message, with an exception - final String msg2 = "message-B"; - doThrow(new RuntimeException(EXPECTED)).when(listener).onTopicEvent(any(), any(), any()); - base.broadcast(msg2); - verify(listener).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, msg2); - verify(listener2).onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, msg2); - } - - @Test - void testLock_testUnlock() { - assertFalse(base.isLocked()); - assertTrue(base.lock()); - assertEquals(0, base.startCount); - assertEquals(1, base.stopCount); - - // lock again - should not stop again - assertTrue(base.isLocked()); - assertTrue(base.lock()); - assertEquals(0, base.startCount); - assertEquals(1, base.stopCount); - - assertTrue(base.isLocked()); - assertTrue(base.unlock()); - assertEquals(1, base.startCount); - assertEquals(1, base.stopCount); - - // unlock again - should not start again - assertFalse(base.isLocked()); - assertTrue(base.unlock()); - assertEquals(1, base.startCount); - assertEquals(1, base.stopCount); - } - - /** - * Tests lock/unlock when the stop/start methods return false. - */ - @Test - void testLock_testUnlock_FalseReturns() { - - // lock, but stop returns false - base.stopReturn = false; - assertFalse(base.lock()); - assertTrue(base.isLocked()); - assertTrue(base.lock()); - - // unlock, but start returns false - base.startReturn = false; - assertFalse(base.unlock()); - assertFalse(base.isLocked()); - assertTrue(base.unlock()); - } - - /** - * Tests lock/unlock when the start method throws an exception. - */ - @Test - void testLock_testUnlock_Exception() { - - // lock & re-lock, but start throws an exception - base.startEx = true; - assertTrue(base.lock()); - assertFalse(base.unlock()); - assertFalse(base.isLocked()); - assertTrue(base.unlock()); - } - - @Test - void testIsLocked() { - assertFalse(base.isLocked()); - base.lock(); - assertTrue(base.isLocked()); - base.unlock(); - assertFalse(base.isLocked()); - } - - @Test - void testGetTopic() { - assertEquals(MY_TOPIC, base.getTopic()); - } - - @Test - void testGetEffectiveTopic() { - assertEquals(MY_TOPIC, base.getTopic()); - assertEquals(MY_TOPIC, base.getEffectiveTopic()); - } - - @Test - void testIsAlive() { - assertFalse(base.isAlive()); - base.start(); - assertTrue(base.isAlive()); - base.stop(); - assertFalse(base.isAlive()); - } - - @Test - void testGetServers() { - assertEquals(servers, base.getServers()); - } - - @Test - void testGetRecentEvents() { - assertEquals(0, base.getRecentEvents().length); - - base.addEvent("recent-A"); - base.addEvent("recent-B"); - - String[] recent = base.getRecentEvents(); - assertEquals(2, recent.length); - assertEquals("recent-A", recent[0]); - assertEquals("recent-B", recent[1]); - } - - @Test - void testToString() { - assertNotNull(base.toString()); - } - - /** - * Implementation of TopicBase. - */ - private static class TopicBaseImpl extends TopicBase { - private int startCount = 0; - private int stopCount = 0; - private boolean startReturn = true; - private boolean stopReturn = true; - private boolean startEx = false; - - /** - * Constructor. - * - * @param servers list of servers - * @param topic topic name - */ - public TopicBaseImpl(List servers, String topic) { - super(servers, topic); - } - - /** - * Constructor. - * - * @param servers list of servers - * @param topic topic name - * @param effectiveTopic effective topic name for network communication - */ - public TopicBaseImpl(List servers, String topic, String effectiveTopic) { - super(servers, topic, effectiveTopic); - } - - @Override - public CommInfrastructure getTopicCommInfrastructure() { - return CommInfrastructure.NOOP; - } - - @Override - public boolean start() { - ++startCount; - - if (startEx) { - throw new RuntimeException(EXPECTED); - } - - alive = true; - return startReturn; - } - - @Override - public boolean stop() { - ++stopCount; - alive = false; - return stopReturn; - } - - @Override - public void shutdown() { - // do nothing - } - - /** - * Adds an event to the list of recent events. - * - * @param event event to be added - */ - public void addEvent(String event) { - recentEvents.add(event); - } - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/BidirectionalTopicClientTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/BidirectionalTopicClientTest.java deleted file mode 100644 index 890fa720..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/BidirectionalTopicClientTest.java +++ /dev/null @@ -1,454 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.client; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNotSame; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.atLeast; -import static org.mockito.Mockito.lenient; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.Arrays; -import java.util.Properties; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.endpoints.event.comm.TopicEndpoint; -import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager; -import org.onap.policy.common.endpoints.event.comm.TopicListener; -import org.onap.policy.common.endpoints.event.comm.TopicSink; -import org.onap.policy.common.endpoints.event.comm.TopicSource; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; - -@ExtendWith(MockitoExtension.class) -class BidirectionalTopicClientTest { - private static final Coder coder = new StandardCoder(); - private static final long MAX_WAIT_MS = 5000; - private static final long SHORT_WAIT_MS = 1; - private static final String SINK_TOPIC = "my-sink-topic"; - private static final String SOURCE_TOPIC = "my-source-topic"; - private static final String MY_TEXT = "my-text"; - - private static final CommInfrastructure SINK_INFRA = CommInfrastructure.NOOP; - private static final CommInfrastructure SOURCE_INFRA = CommInfrastructure.NOOP; - - @Mock - private TopicSink sink; - @Mock - private TopicSource source; - @Mock - private TopicEndpoint endpoint; - @Mock - private TopicListener listener; - - private MyMessage theMessage; - - private BidirectionalTopicClient client; - private Context context; - - /** - * Configures the endpoints. - */ - @BeforeAll - public static void setUpBeforeClass() { - Properties props = new Properties(); - props.setProperty("noop.sink.topics", SINK_TOPIC); - props.setProperty("noop.source.topics", SOURCE_TOPIC); - - // clear all topics and then configure one sink and one source - TopicEndpointManager.getManager().shutdown(); - TopicEndpointManager.getManager().addTopicSinks(props); - TopicEndpointManager.getManager().addTopicSources(props); - } - - @AfterAll - public static void tearDownAfterClass() { - // clear all topics after the tests - TopicEndpointManager.getManager().shutdown(); - } - - /** - * Creates mocks and an initial client object. - */ - @BeforeEach - public void setUp() throws Exception { - lenient().when(sink.send(anyString())).thenReturn(true); - lenient().when(sink.getTopicCommInfrastructure()).thenReturn(SINK_INFRA); - - lenient().when(source.offer(anyString())).thenReturn(true); - lenient().when(source.getTopicCommInfrastructure()).thenReturn(SOURCE_INFRA); - - lenient().when(endpoint.getTopicSinks(anyString())).thenReturn(Arrays.asList()); - lenient().when(endpoint.getTopicSinks(SINK_TOPIC)).thenReturn(Arrays.asList(sink)); - - lenient().when(endpoint.getTopicSources(any())).thenReturn(Arrays.asList()); - lenient().when(endpoint.getTopicSources(Arrays.asList(SOURCE_TOPIC))).thenReturn(Arrays.asList(source)); - - theMessage = new MyMessage(MY_TEXT); - - client = new BidirectionalTopicClient2(SINK_TOPIC, SOURCE_TOPIC); - - context = new Context(); - } - - @AfterEach - public void tearDown() { - context.stop(); - } - - @Test - void testBidirectionalTopicClient_testGetters() { - assertSame(sink, client.getSink()); - assertSame(source, client.getSource()); - assertEquals(SINK_TOPIC, client.getSinkTopic()); - assertEquals(SOURCE_TOPIC, client.getSourceTopic()); - assertEquals(SINK_INFRA, client.getSinkTopicCommInfrastructure()); - assertEquals(SOURCE_INFRA, client.getSourceTopicCommInfrastructure()); - } - - /** - * Tests the constructor when the sink or source cannot be found. - */ - @Test - void testBidirectionalTopicClientExceptions() { - assertThatThrownBy(() -> new BidirectionalTopicClient2("unknown-sink", SOURCE_TOPIC)) - .isInstanceOf(BidirectionalTopicClientException.class) - .hasMessage("no sinks for topic: unknown-sink"); - - assertThatThrownBy(() -> new BidirectionalTopicClient2(SINK_TOPIC, "unknown-source")) - .isInstanceOf(BidirectionalTopicClientException.class) - .hasMessage("no sources for topic: unknown-source"); - - // too many sources - when(endpoint.getTopicSources(Arrays.asList(SOURCE_TOPIC))).thenReturn(Arrays.asList(source, source)); - - assertThatThrownBy(() -> new BidirectionalTopicClient2(SINK_TOPIC, SOURCE_TOPIC)) - .isInstanceOf(BidirectionalTopicClientException.class) - .hasMessage("too many sources for topic: my-source-topic"); - } - - /** - * Tests the "delegate" methods. - */ - @Test - void testDelegates() { - assertTrue(client.send("hello")); - verify(sink).send("hello"); - - assertTrue(client.offer("incoming")); - verify(source).offer("incoming"); - - client.register(listener); - verify(source).register(listener); - - client.unregister(listener); - verify(source).unregister(listener); - } - - @Test - void testGetTopicEndpointManager() throws BidirectionalTopicClientException { - // use a real manager - client = new BidirectionalTopicClient(SINK_TOPIC, SOURCE_TOPIC); - assertNotNull(client.getTopicEndpointManager()); - - assertNotNull(client.getSink()); - assertNotNull(client.getSource()); - - assertNotSame(sink, client.getSink()); - assertNotSame(source, client.getSource()); - } - - @Test - void testAwaitReceipt() throws Exception { - context.start(theMessage); - assertThat(context.awaitSend(1)).isTrue(); - - verify(source).register(any()); - verify(sink, atLeast(1)).send(any()); - assertThat(context.checker.isReady()).isFalse(); - - inject(theMessage); - - verifyReceipt(); - } - - @Test - void testAwaitReceipt_AlreadyDone() throws Exception { - context.start(theMessage); - assertThat(context.awaitSend(1)).isTrue(); - - inject(theMessage); - - verifyReceipt(); - - // calling again should result in "true" again, without injecting message - context.start(theMessage); - verifyReceipt(); - } - - @Test - void testAwaitReceipt_MessageDoesNotMatch() throws Exception { - context.start(theMessage); - assertThat(context.awaitSend(1)).isTrue(); - - // non-matching message - inject("{}"); - - // wait for a few more calls to "send" and then inject a matching message - assertThat(context.awaitSend(3)).isTrue(); - inject(theMessage); - - verifyReceipt(); - } - - @Test - void testAwaitReceipt_DecodeFails() throws Exception { - context.start(theMessage); - assertThat(context.awaitSend(1)).isTrue(); - - // force a failure and inject the message - context.forceDecodeFailure = true; - inject(theMessage); - - assertThat(context.awaitDecodeFailure()).isTrue(); - - // no more failures - context.forceDecodeFailure = false; - inject(theMessage); - - verifyReceipt(); - } - - @Test - void testAwaitReceipt_Interrupted() throws InterruptedException { - context.start(theMessage); - assertThat(context.awaitSend(1)).isTrue(); - - context.interrupt(); - - verifyNoReceipt(); - } - - @Test - void testAwaitReceipt_MultipleLoops() throws Exception { - context.start(theMessage); - - // wait for multiple "send" calls - assertThat(context.awaitSend(3)).isTrue(); - - inject(theMessage); - - verifyReceipt(); - } - - @Test - void testStop() throws InterruptedException { - context.start(theMessage); - assertThat(context.awaitSend(1)).isTrue(); - - context.stop(); - - verifyNoReceipt(); - } - - /** - * Verifies that awaitReceipt() returns {@code true}. - * - * @throws InterruptedException if interrupted while waiting for the thread to - * terminate - */ - private void verifyReceipt() throws InterruptedException { - assertThat(context.join()).isTrue(); - assertThat(context.result).isTrue(); - assertThat(context.exception).isNull(); - assertThat(context.checker.isReady()).isTrue(); - - verify(source).unregister(any()); - } - - /** - * Verifies that awaitReceipt() returns {@code false}. - * - * @throws InterruptedException if interrupted while waiting for the thread to - * terminate - */ - private void verifyNoReceipt() throws InterruptedException { - assertThat(context.join()).isTrue(); - assertThat(context.result).isFalse(); - assertThat(context.exception).isNull(); - assertThat(context.checker.isReady()).isFalse(); - - verify(source).unregister(any()); - } - - /** - * Injects a message into the source topic. - * - * @param message message to be injected - * @throws CoderException if the message cannot be encoded - */ - private void inject(MyMessage message) throws CoderException { - inject(coder.encode(message)); - } - - /** - * Injects a message into the source topic. - * - * @param message message to be injected - */ - private void inject(String message) { - ArgumentCaptor cap = ArgumentCaptor.forClass(TopicListener.class); - verify(source).register(cap.capture()); - - cap.getValue().onTopicEvent(SOURCE_INFRA, SOURCE_TOPIC, message); - } - - - /** - * BidirectionalTopicClient with some overrides. - */ - private class BidirectionalTopicClient2 extends BidirectionalTopicClient { - - public BidirectionalTopicClient2(String sinkTopic, String sourceTopic) - throws BidirectionalTopicClientException { - super(sinkTopic, sourceTopic); - } - - @Override - protected TopicEndpoint getTopicEndpointManager() { - return endpoint; - } - } - - private class Context { - private Thread thread; - private boolean result; - private Exception exception; - private boolean forceDecodeFailure; - - // released every time the checker publishes a message - private final Semaphore sendSem = new Semaphore(0); - - // released every time a message-decode fails - private final Semaphore decodeFailedSem = new Semaphore(0); - - private final BidirectionalTopicClient2 checker; - - public Context() throws BidirectionalTopicClientException { - - checker = new BidirectionalTopicClient2(SINK_TOPIC, SOURCE_TOPIC) { - - @Override - public boolean send(String messageText) { - boolean result = super.send(messageText); - sendSem.release(); - return result; - } - - @Override - protected T decode(String msg, Class clazz) throws CoderException { - if (forceDecodeFailure) { - throw new CoderException("expected exception"); - } - - return super.decode(msg, clazz); - } - - @Override - protected void decodeFailed() { - super.decodeFailed(); - decodeFailedSem.release(); - } - }; - } - - /** - * Starts the thread. - * - * @param message message to be sent to the sink topic - */ - public void start(MyMessage message) { - thread = new Thread() { - @Override - public void run() { - try { - result = checker.awaitReady(message, SHORT_WAIT_MS); - } catch (Exception e) { - exception = e; - } - } - }; - thread.setDaemon(true); - thread.start(); - } - - public void stop() { - checker.stopWaiting(); - } - - public boolean join() throws InterruptedException { - thread.join(MAX_WAIT_MS); - return !thread.isAlive(); - } - - public void interrupt() { - thread.interrupt(); - } - - public boolean awaitSend(int npermits) throws InterruptedException { - return sendSem.tryAcquire(npermits, MAX_WAIT_MS, TimeUnit.MILLISECONDS); - } - - public boolean awaitDecodeFailure() throws InterruptedException { - return decodeFailedSem.tryAcquire(MAX_WAIT_MS, TimeUnit.MILLISECONDS); - } - } - - @Data - @NoArgsConstructor - @AllArgsConstructor - public static class MyMessage { - private String text; - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/TopicClientExceptionTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/TopicClientExceptionTest.java deleted file mode 100644 index ba935822..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/TopicClientExceptionTest.java +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP PAP - * ================================================================================ - * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2019, 2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.client; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Test; -import org.onap.policy.common.utils.test.ExceptionsTester; - -class TopicClientExceptionTest { - - @Test - void test() { - assertEquals(5, new ExceptionsTester().test(TopicSinkClientException.class)); - assertEquals(5, new ExceptionsTester().test(BidirectionalTopicClientException.class)); - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientTest.java deleted file mode 100644 index 81621195..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientTest.java +++ /dev/null @@ -1,146 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP PAP - * ================================================================================ - * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2019, 2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.event.comm.client; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; -import java.util.Properties; -import java.util.concurrent.atomic.AtomicReference; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager; -import org.onap.policy.common.endpoints.event.comm.TopicSink; - -class TopicSinkClientTest { - private static final String TOPIC = "my-topic"; - - private TopicSinkClient client; - private TopicSink sink; - private List sinks; - - /** - * Creates mocks and an initial client object. - * - * @throws Exception if an error occurs - */ - @BeforeEach - public void setUp() throws Exception { - sink = mock(TopicSink.class); - when(sink.send(anyString())).thenReturn(true); - - sinks = Arrays.asList(sink, null); - - client = new TopicSinkClient2(TOPIC); - - Properties props = new Properties(); - props.setProperty("noop.sink.topics", TOPIC); - - // clear all topics and then configure one topic - TopicEndpointManager.getManager().shutdown(); - TopicEndpointManager.getManager().addTopicSinks(props); - } - - @AfterAll - public static void tearDown() { - // clear all topics after the tests - TopicEndpointManager.getManager().shutdown(); - } - - /** - * Uses a real NO-OP topic sink. - */ - @Test - void testGetTopicSinks() throws Exception { - - sink = TopicEndpointManager.getManager().getNoopTopicSink(TOPIC); - assertNotNull(sink); - - final AtomicReference evref = new AtomicReference<>(null); - - sink.register((infra, topic, event) -> evref.set(event)); - sink.start(); - - client = new TopicSinkClient(TOPIC); - client.send(100); - - assertEquals("100", evref.get()); - } - - @Test - void testTopicSinkClient() { - // unknown topic -> should throw exception - sinks = new LinkedList<>(); - assertThatThrownBy(() -> new TopicSinkClient2(TOPIC)).isInstanceOf(TopicSinkClientException.class) - .hasMessage("no sinks for topic: my-topic"); - } - - @Test - void testTopicSinkClient_GetTopic() throws TopicSinkClientException { - assertEquals(TOPIC, new TopicSinkClient(TopicEndpointManager.getManager().getNoopTopicSink(TOPIC)).getTopic()); - assertEquals(TOPIC, new TopicSinkClient(TOPIC).getTopic()); - - assertThatThrownBy(() -> new TopicSinkClient((TopicSink) null)).isInstanceOf(IllegalArgumentException.class); - assertThatThrownBy(() -> new TopicSinkClient("blah")).isInstanceOf(TopicSinkClientException.class) - .hasMessage("no sinks for topic: blah"); - } - - @Test - void testSend() { - client.send(Arrays.asList("abc", "def")); - verify(sink).send("['abc','def']".replace('\'', '"')); - - // sink send fails - when(sink.send(anyString())).thenReturn(false); - assertFalse(client.send("ghi")); - - // sink send throws an exception - final RuntimeException ex = new RuntimeException("expected exception"); - when(sink.send(anyString())).thenThrow(ex); - assertFalse(client.send("jkl")); - } - - /** - * TopicSinkClient with some overrides. - */ - private class TopicSinkClient2 extends TopicSinkClient { - - public TopicSinkClient2(final String topic) throws TopicSinkClientException { - super(topic); - } - - @Override - protected List getTopicSinks(final String topic) { - return sinks; - } - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/features/NetLoggerFeatureApiTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/features/NetLoggerFeatureApiTest.java deleted file mode 100644 index 2ea64239..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/features/NetLoggerFeatureApiTest.java +++ /dev/null @@ -1,86 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.features; - -import static org.junit.jupiter.api.Assertions.assertFalse; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.endpoints.utils.NetLoggerUtil.EventType; -import org.slf4j.Logger; - -@ExtendWith(MockitoExtension.class) -class NetLoggerFeatureApiTest { - - @Mock - private Logger mockLogger; - - @Mock - private EventType mockEventType; - - @Mock - private CommInfrastructure mockCommInfrastructure; - - private NetLoggerFeatureApi featureApi; - - @BeforeEach - public void setUp() { - featureApi = new NetLoggerFeatureApi() { - @Override - public boolean beforeLog(Logger eventLogger, EventType type, CommInfrastructure protocol, String topic, - String message) { - return NetLoggerFeatureApi.super.beforeLog(eventLogger, type, protocol, topic, message); - } - - @Override - public boolean afterLog(Logger eventLogger, EventType type, CommInfrastructure protocol, String topic, - String message) { - return NetLoggerFeatureApi.super.afterLog(eventLogger, type, protocol, topic, message); - } - - @Override - public int getSequenceNumber() { - return 0; - } - - @Override - public String getName() { - return NetLoggerFeatureApi.super.getName(); - } - }; - } - - @Test - void testBeforeLogDefaultBehavior() { - boolean result = featureApi.beforeLog(mockLogger, mockEventType, mockCommInfrastructure, - "testTopic", "testMessage"); - assertFalse(result, "Expected beforeLog to return false by default"); - } - - @Test - void testAfterLogDefaultBehavior() { - boolean result = featureApi.afterLog(mockLogger, mockEventType, mockCommInfrastructure, - "testTopic", "testMessage"); - assertFalse(result, "Expected afterLog to return false by default"); - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/HttpClientTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/HttpClientTest.java index 3d80aa81..10d40051 100644 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/HttpClientTest.java +++ b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/HttpClientTest.java @@ -41,11 +41,11 @@ import java.util.TreeMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import lombok.Getter; +import lombok.Setter; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; import org.onap.policy.common.endpoints.http.client.HttpClient; import org.onap.policy.common.endpoints.http.client.HttpClientConfigException; import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance; @@ -53,6 +53,7 @@ import org.onap.policy.common.endpoints.http.server.HttpServletServer; import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance; import org.onap.policy.common.endpoints.http.server.internal.JettyJerseyServer; import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; +import org.onap.policy.common.parameters.topic.BusTopicParams; import org.onap.policy.common.utils.network.NetworkUtil; class HttpClientTest { @@ -532,6 +533,8 @@ class HttpClientTest { } + @Setter + @Getter static class MyEntity { private String myParameter; @@ -540,14 +543,6 @@ class HttpClientTest { this.myParameter = myParameter; } - public void setMyParameter(final String myParameter) { - this.myParameter = myParameter; - } - - public String getMyParameter() { - return myParameter; - } - } static class MyCallback implements InvocationCallback { @@ -557,7 +552,7 @@ class HttpClientTest { @Getter private Throwable throwable; - private CountDownLatch latch = new CountDownLatch(1); + private final CountDownLatch latch = new CountDownLatch(1); @Override public void completed(Response response) { diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/HttpServerTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/HttpServerTest.java index 818851ff..399754a6 100644 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/HttpServerTest.java +++ b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/HttpServerTest.java @@ -242,7 +242,7 @@ class HttpServerTest { */ @Test void testExplicitPrometheusServer() throws Exception { - logger.info("-- testPrometheusServer() --"); + logger.info("-- testExplicitPrometheusServer() --"); HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory() .build(PROMETHEUS, LOCALHOST, port, "/", false, true); @@ -261,7 +261,7 @@ class HttpServerTest { */ @Test void testPrometheusJaxRsFilterSwaggerServer() throws Exception { - logger.info("-- testPrometheusServer() --"); + logger.info("-- testPrometheusJaxRsFilterSwaggerServer() --"); HttpServletServer server = HttpServletServerFactoryInstance.getServerFactory() .build(PROMETHEUS, LOCALHOST, port, "/", true, true); diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/RestServerTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/RestServerTest.java index 18030409..431dae7c 100644 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/RestServerTest.java +++ b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/http/server/test/RestServerTest.java @@ -65,9 +65,9 @@ import org.onap.policy.common.endpoints.http.server.RestServer; import org.onap.policy.common.endpoints.http.server.RestServer.Factory; import org.onap.policy.common.endpoints.http.server.YamlExceptionMapper; import org.onap.policy.common.endpoints.http.server.YamlMessageBodyHandler; -import org.onap.policy.common.endpoints.parameters.RestServerParameters; import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; import org.onap.policy.common.gson.GsonMessageBodyHandler; +import org.onap.policy.common.parameters.rest.RestServerParameters; import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.common.utils.network.NetworkUtil; import org.springframework.test.util.ReflectionTestUtils; diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/listeners/JsonListenerTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/listeners/JsonListenerTest.java index 11cd3c56..c2e5f90d 100644 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/listeners/JsonListenerTest.java +++ b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/listeners/JsonListenerTest.java @@ -36,7 +36,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; import org.onap.policy.common.utils.coder.StandardCoderObject; import org.onap.policy.common.utils.test.log.logback.ExtractAppender; import org.slf4j.LoggerFactory; diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/listeners/MessageTypeDispatcherTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/listeners/MessageTypeDispatcherTest.java index 95dd9f53..e0184bd1 100644 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/listeners/MessageTypeDispatcherTest.java +++ b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/listeners/MessageTypeDispatcherTest.java @@ -37,7 +37,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; import org.onap.policy.common.utils.coder.StandardCoderObject; import org.onap.policy.common.utils.test.log.logback.ExtractAppender; import org.slf4j.LoggerFactory; diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/listeners/RequestIdDispatcherTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/listeners/RequestIdDispatcherTest.java index 1158a4c9..ac61ae7c 100644 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/listeners/RequestIdDispatcherTest.java +++ b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/listeners/RequestIdDispatcherTest.java @@ -37,7 +37,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/listeners/ScoListenerTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/listeners/ScoListenerTest.java index 4236a77c..cb8fb70d 100644 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/listeners/ScoListenerTest.java +++ b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/listeners/ScoListenerTest.java @@ -34,7 +34,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.message.bus.event.Topic.CommInfrastructure; import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; @@ -62,8 +62,6 @@ class ScoListenerTest { private static final Coder coder = new StandardCoder(); private ScoListener primary; - private MyMessage status; - private StandardCoderObject sco; /** * Initializes statics. @@ -108,8 +106,8 @@ class ScoListenerTest { void testOnTopicEvent() { primary = spy(primary); - status = new MyMessage(NAME); - sco = makeSco(status); + MyMessage status = new MyMessage(NAME); + StandardCoderObject sco = makeSco(status); primary.onTopicEvent(INFRA, TOPIC, sco); verify(primary).onTopicEvent(INFRA, TOPIC, sco, status); @@ -117,7 +115,7 @@ class ScoListenerTest { // undecodable message logger.addAppender(appender); - primary.onTopicEvent(INFRA, TOPIC, makeSco("[]")); + primary.onTopicEvent(INFRA, TOPIC, makeSco()); verify(primary, times(1)).onTopicEvent(INFRA, TOPIC, sco, status); assertTrue(appender.getExtracted().toString().contains("unable to decode")); } @@ -125,12 +123,11 @@ class ScoListenerTest { /** * Makes a standard object from a JSON string. * - * @param source message to be converted * @return a standard object representing the message */ - private StandardCoderObject makeSco(String source) { + private StandardCoderObject makeSco() { try { - return coder.decode(source, StandardCoderObject.class); + return coder.decode("[]", StandardCoderObject.class); } catch (CoderException e) { throw new RuntimeException(e); @@ -184,13 +181,10 @@ class ScoListenerTest { } MyMessage other = (MyMessage) obj; if (name == null) { - if (other.name != null) { - return false; - } - } else if (!name.equals(other.name)) { - return false; + return other.name == null; + } else { + return name.equals(other.name); } - return true; } } } diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/parameters/CommonTestData.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/parameters/CommonTestData.java deleted file mode 100644 index ce0f58de..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/parameters/CommonTestData.java +++ /dev/null @@ -1,142 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2019, 2024 Nordix Foundation. - * Modifications Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.parameters; - -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import org.onap.policy.common.parameters.ParameterGroup; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; - -/** - * Class to hold/create all parameters for test cases. - * - * @author Ajith Sreekumar (ajith.sreekumar@est.tech) - */ -public class CommonTestData { - - public static final String REST_SERVER_PASS = "zb!XztG34"; - public static final String REST_SERVER_USER = "healthcheck"; - public static final int REST_SERVER_PORT = 6969; - public static final String REST_SERVER_HOST = "0.0.0.0"; - public static final boolean REST_SERVER_HTTPS = true; - public static final boolean REST_SERVER_AAF = false; - - public static final String TOPIC_NAME = "policy-pdp-pap"; - public static final String TOPIC_INFRA = "kafka"; - public static final String TOPIC_SERVER = "kafka:9092"; - - public static final List TOPIC_PARAMS = - Arrays.asList(getTopicParameters(TOPIC_NAME, TOPIC_INFRA, TOPIC_SERVER)); - - protected static final Coder coder = new StandardCoder(); - - /** - * Create topic parameters for test cases. - * - * @param topicName name of topic - * @param topicInfra topicCommInfrastructure - * @param topicServer topic server - * - * @return topic parameters - */ - public static TopicParameters getTopicParameters(String topicName, String topicInfra, String topicServer) { - final TopicParameters topicParams = new TopicParameters(); - topicParams.setTopic(topicName); - topicParams.setTopicCommInfrastructure(topicInfra); - topicParams.setServers(Arrays.asList(topicServer)); - return topicParams; - } - - /** - * Converts the contents of a map to a parameter class. - * - * @param source property map - * @param clazz class of object to be created from the map - * @return a new object represented by the map - */ - public T toObject(final Map source, final Class clazz) { - try { - return coder.decode(coder.encode(source), clazz); - - } catch (final CoderException e) { - throw new RuntimeException("cannot create " + clazz.getName() + " from map", e); - } - } - - /** - * Returns a property map for a RestServerParameters map for test cases. - * - * @param isEmpty boolean value to represent that object created should be empty or not - * @return a property map suitable for constructing an object - */ - public Map getRestServerParametersMap(final boolean isEmpty) { - final Map map = new TreeMap<>(); - map.put("https", REST_SERVER_HTTPS); - map.put("aaf", REST_SERVER_AAF); - - if (!isEmpty) { - map.put("host", REST_SERVER_HOST); - map.put("port", REST_SERVER_PORT); - map.put("userName", REST_SERVER_USER); - map.put("password", REST_SERVER_PASS); - } - - return map; - } - - /** - * Returns a property map for a TopicParameters map for test cases. - * - * @param isEmpty boolean value to represent that object created should be empty or not - * @return a property map suitable for constructing an object - */ - public Map getTopicParameterGroupMap(final boolean isEmpty) { - final Map map = new TreeMap<>(); - if (!isEmpty) { - map.put("topicSources", TOPIC_PARAMS); - map.put("topicSinks", TOPIC_PARAMS); - } - - return map; - } - - /** - * Gets the standard parameter group as a String. - * - * @param filePath path of the file - * @return the standard parameters - * @throws IOException when file read operation fails - */ - public String getParameterGroupAsString(String filePath) throws IOException { - File file = new File(filePath); - return new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8); - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/parameters/RestClientParametersTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/parameters/RestClientParametersTest.java deleted file mode 100644 index 6013ff2d..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/parameters/RestClientParametersTest.java +++ /dev/null @@ -1,116 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2024 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.parameters; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.onap.policy.common.parameters.BeanValidationResult; -import org.onap.policy.common.parameters.ValidationStatus; - -class RestClientParametersTest { - - private RestClientParameters params; - - @BeforeEach - void setUp() { - params = new RestClientParameters(); - } - - @Test - void testValidate_ValidParameters() { - params.setHostname("localhost"); - params.setClientName("testClient"); - params.setPort(8080); - - BeanValidationResult result = params.validate(); - - assertEquals(ValidationStatus.CLEAN, result.getStatus(), "Expected the parameters to be valid"); - assertNull(result.getResult(), "Expected no validation errors"); - } - - @Test - void testValidate_InvalidHostname() { - params.setHostname(""); - params.setClientName("testClient"); - params.setPort(8080); - - BeanValidationResult result = params.validate(); - - assertEquals(ValidationStatus.INVALID, result.getStatus(), "Expected the parameters to be invalid"); - assertTrue(result.getResult().contains("hostname") && result.getResult().contains("is blank"), - "Expected invalid hostname error message"); - } - - @Test - void testValidate_InvalidClientName() { - params.setHostname("localhost"); - params.setClientName(""); - params.setPort(8080); - - BeanValidationResult result = params.validate(); - - assertEquals(ValidationStatus.INVALID, result.getStatus(), "Expected the parameters to be invalid"); - assertTrue(result.getResult().contains("clientName") && result.getResult().contains("is blank"), - "Expected invalid clientName error message"); - } - - @Test - void testValidate_InvalidPort() { - params.setHostname("localhost"); - params.setClientName("testClient"); - params.setPort(-1); - - BeanValidationResult result = params.validate(); - - assertEquals(ValidationStatus.INVALID, result.getStatus(), "Expected the parameters to be invalid"); - assertTrue(result.getResult().contains("port") && result.getResult().contains("is not valid"), - "Expected invalid port error message"); - } - - @Test - void testValidate_MultipleInvalidParameters() { - params.setHostname(""); - params.setClientName(""); - params.setPort(-1); - - BeanValidationResult result = params.validate(); - - assertEquals(ValidationStatus.INVALID, result.getStatus(), "Expected the parameters to be invalid"); - - assertTrue(result.getResult().contains("hostname") && result.getResult().contains("is blank"), - "Expected invalid hostname error message"); - - assertTrue(result.getResult().contains("clientName") && result.getResult().contains("is blank"), - "Expected invalid clientName error message"); - - assertTrue(result.getResult().contains("port") && result.getResult().contains("is not valid"), - "Expected invalid port error message"); - } - - @Test - void testGetAndSetName() { - String name = "testClient"; - params.setName(name); - assertEquals(name, params.getName(), "Expected the client name to be set and retrieved correctly"); - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/parameters/RestServerParametersTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/parameters/RestServerParametersTest.java deleted file mode 100644 index 6492b900..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/parameters/RestServerParametersTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2019-2024 Nordix Foundation. - * Modifications Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.parameters; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; -import org.onap.policy.common.parameters.ValidationResult; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.StandardCoder; - -/** - * Class to perform unit test of {@link RestServerParameters}. - * - * @author Ajith Sreekumar (ajith.sreekumar@est.tech) - */ -class RestServerParametersTest { - - private static CommonTestData testData = new CommonTestData(); - private static final Coder coder = new StandardCoder(); - - @Test - void test() { - final RestServerParameters restServerParameters = - testData.toObject(testData.getRestServerParametersMap(false), RestServerParameters.class); - final ValidationResult validationResult = restServerParameters.validate(); - assertTrue(validationResult.isValid()); - assertEquals(CommonTestData.REST_SERVER_HOST, restServerParameters.getHost()); - assertEquals(CommonTestData.REST_SERVER_PORT, restServerParameters.getPort()); - assertEquals(CommonTestData.REST_SERVER_USER, restServerParameters.getUserName()); - assertEquals(CommonTestData.REST_SERVER_PASS, restServerParameters.getPassword()); - assertEquals(CommonTestData.REST_SERVER_HTTPS, restServerParameters.isHttps()); - assertEquals(CommonTestData.REST_SERVER_AAF, restServerParameters.isAaf()); - } - - @Test - void testValidate() { - final RestServerParameters restServerParameters = - testData.toObject(testData.getRestServerParametersMap(false), RestServerParameters.class); - final ValidationResult result = restServerParameters.validate(); - assertNull(result.getResult()); - assertTrue(result.isValid()); - } - - @Test - void test_valid() throws Exception { - String json = testData.getParameterGroupAsString( - "src/test/resources/org/onap/policy/common/endpoints/parameters/RestServerParameters_valid.json"); - RestServerParameters restServerParameters = coder.decode(json, RestServerParameters.class); - final ValidationResult result = restServerParameters.validate(); - assertNull(result.getResult()); - assertTrue(result.isValid()); - } - - @Test - void test_invalid() throws Exception { - String json = testData.getParameterGroupAsString( - "src/test/resources/org/onap/policy/common/endpoints/parameters/RestServerParameters_invalid.json"); - RestServerParameters restServerParameters = coder.decode(json, RestServerParameters.class); - final ValidationResult result = restServerParameters.validate(); - assertFalse(result.isValid()); - assertThat(result.getResult()).contains("item has status INVALID"); - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/parameters/TopicParameterGroupTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/parameters/TopicParameterGroupTest.java deleted file mode 100644 index a81263a9..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/parameters/TopicParameterGroupTest.java +++ /dev/null @@ -1,144 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2019-2024 Nordix Foundation. - * Modifications Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.parameters; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.beans.PropertyDescriptor; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.List; -import org.apache.commons.lang3.StringUtils; -import org.junit.jupiter.api.Test; -import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; -import org.onap.policy.common.parameters.ValidationResult; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; - -/** - * Class to perform unit test of {@link TopicParameterGroup}. - * - * @author Ajith Sreekumar (ajith.sreekumar@est.tech) - */ -class TopicParameterGroupTest { - private static CommonTestData testData = new CommonTestData(); - private static final Coder coder = new StandardCoder(); - - @Test - void test() throws CoderException { - final TopicParameterGroup topicParameterGroup = - testData.toObject(testData.getTopicParameterGroupMap(false), TopicParameterGroup.class); - final ValidationResult validationResult = topicParameterGroup.validate(); - assertTrue(validationResult.isValid()); - assertEquals(CommonTestData.TOPIC_PARAMS, topicParameterGroup.getTopicSinks()); - assertEquals(CommonTestData.TOPIC_PARAMS, topicParameterGroup.getTopicSources()); - - // these should default to true - assertTrue(new TopicParameters().isManaged()); - assertTrue(coder.decode("{}", TopicParameters.class).isManaged()); - - // but can be overridden - assertFalse(coder.decode("{'managed':false}".replace('\'', '"'), TopicParameters.class).isManaged()); - } - - @Test - void testValidate() { - final TopicParameterGroup topicParameterGroup = - testData.toObject(testData.getTopicParameterGroupMap(false), TopicParameterGroup.class); - final ValidationResult result = topicParameterGroup.validate(); - assertNull(result.getResult()); - assertTrue(result.isValid()); - } - - @Test - void test_valid() throws Exception { - String json = testData.getParameterGroupAsString( - "src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_valid.json"); - TopicParameterGroup topicParameterGroup = coder.decode(json, TopicParameterGroup.class); - final ValidationResult result = topicParameterGroup.validate(); - assertNull(result.getResult()); - assertTrue(result.isValid()); - } - - @Test - void test_invalid() throws Exception { - String json = testData.getParameterGroupAsString( - "src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_invalid.json"); - TopicParameterGroup topicParameterGroup = coder.decode(json, TopicParameterGroup.class); - final ValidationResult result = topicParameterGroup.validate(); - assertFalse(result.isValid()); - assertTrue(result.getResult().contains("INVALID")); - } - - @Test - void test_missing_mandatory_params() throws Exception { - String json = testData.getParameterGroupAsString( - "src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_missing_mandatory.json"); - TopicParameterGroup topicParameterGroup = coder.decode(json, TopicParameterGroup.class); - final ValidationResult result = topicParameterGroup.validate(); - assertTrue(result.getResult().contains("Mandatory parameters are missing")); - assertFalse(result.isValid()); - } - - @Test - void test_allparams() throws Exception { - String json = testData.getParameterGroupAsString( - "src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_all_params.json"); - TopicParameterGroup topicParameterGroup = coder.decode(json, TopicParameterGroup.class); - final ValidationResult result = topicParameterGroup.validate(); - assertNull(result.getResult()); - assertTrue(result.isValid()); - assertTrue(checkIfAllParamsNotEmpty(topicParameterGroup.getTopicSinks())); - assertTrue(checkIfAllParamsNotEmpty(topicParameterGroup.getTopicSources())); - } - - /** - * Method to check if all parameters in TopicParameters are set. - * Any parameters added to @link TopicParameters or @link BusTopicParams must be added to - * TopicParameters_all_params.json. - * - * @param topicParametersList list of topic parameters - * @return true if all parameters are not empty (if string) or true (if boolean) - * @throws Exception the exception - */ - private boolean checkIfAllParamsNotEmpty(List topicParametersList) throws Exception { - for (TopicParameters topicParameters : topicParametersList) { - Field[] fields = BusTopicParams.class.getDeclaredFields(); - for (Field field : fields) { - if (!field.isSynthetic() && !Modifier.isStatic(field.getModifiers())) { - Object parameter = new PropertyDescriptor(field.getName(), TopicParameters.class).getReadMethod() - .invoke(topicParameters); - if ((parameter instanceof String && StringUtils.isBlank(parameter.toString())) - || (parameter instanceof Boolean && !(Boolean) parameter) - || (parameter instanceof Number && ((Number) parameter).longValue() == 0)) { - return false; - } - } - } - } - return true; - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/report/TestHealthCheckReport.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/report/TestHealthCheckReport.java deleted file mode 100644 index 62db30b2..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/report/TestHealthCheckReport.java +++ /dev/null @@ -1,50 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2018 Ericsson. All rights reserved. - * Modifications Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.report; - -import com.openpojo.reflection.filters.FilterClassName; -import com.openpojo.validation.Validator; -import com.openpojo.validation.ValidatorBuilder; -import com.openpojo.validation.rule.impl.GetterMustExistRule; -import com.openpojo.validation.rule.impl.SetterMustExistRule; -import com.openpojo.validation.test.impl.GetterTester; -import com.openpojo.validation.test.impl.SetterTester; -import org.junit.jupiter.api.Test; -import org.onap.policy.common.utils.test.ToStringTester; - -/** - * Class to perform unit test of HealthCheckReport. - * - * @author Ram Krishna Verma (ram.krishna.verma@ericsson.com) - */ -class TestHealthCheckReport { - - @Test - void testHealthCheckReport() { - final Validator validator = - ValidatorBuilder.create().with(new GetterMustExistRule()).with(new SetterMustExistRule()) - .with(new GetterTester()).with(new SetterTester()).with(new ToStringTester()).build(); - validator.validate(HealthCheckReport.class.getPackage().getName(), - new FilterClassName(HealthCheckReport.class.getName())); - } -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/rest/CommonTestData.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/rest/CommonTestData.java new file mode 100644 index 00000000..3e16b8a5 --- /dev/null +++ b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/rest/CommonTestData.java @@ -0,0 +1,99 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019, 2024 Nordix Foundation. + * Modifications Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.endpoints.rest; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Map; +import java.util.TreeMap; +import org.onap.policy.common.parameters.ParameterGroup; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; + +/** + * Class to hold/create all parameters for test cases. + * + * @author Ajith Sreekumar (ajith.sreekumar@est.tech) + */ +public class CommonTestData { + + public static final String REST_SERVER_PASS = "zb!XztG34"; + public static final String REST_SERVER_USER = "healthcheck"; + public static final int REST_SERVER_PORT = 6969; + public static final String REST_SERVER_HOST = "0.0.0.0"; + public static final boolean REST_SERVER_HTTPS = true; + public static final boolean REST_SERVER_AAF = false; + + protected static final Coder coder = new StandardCoder(); + + /** + * Converts the contents of a map to a parameter class. + * + * @param source property map + * @param clazz class of object to be created from the map + * @return a new object represented by the map + */ + public T toObject(final Map source, final Class clazz) { + try { + return coder.decode(coder.encode(source), clazz); + + } catch (final CoderException e) { + throw new RuntimeException("cannot create " + clazz.getName() + " from map", e); + } + } + + /** + * Returns a property map for a RestServerParameters map for test cases. + * + * @param isEmpty boolean value to represent that object created should be empty or not + * @return a property map suitable for constructing an object + */ + public Map getRestServerParametersMap(final boolean isEmpty) { + final Map map = new TreeMap<>(); + map.put("https", REST_SERVER_HTTPS); + map.put("aaf", REST_SERVER_AAF); + + if (!isEmpty) { + map.put("host", REST_SERVER_HOST); + map.put("port", REST_SERVER_PORT); + map.put("userName", REST_SERVER_USER); + map.put("password", REST_SERVER_PASS); + } + + return map; + } + + /** + * Gets the standard parameter group as a String. + * + * @param filePath path of the file + * @return the standard parameters + * @throws IOException when file read operation fails + */ + public String getParameterGroupAsString(String filePath) throws IOException { + File file = new File(filePath); + return Files.readString(file.toPath()); + } +} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/rest/RestServerParametersTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/rest/RestServerParametersTest.java new file mode 100644 index 00000000..ccabc455 --- /dev/null +++ b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/rest/RestServerParametersTest.java @@ -0,0 +1,88 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019-2024 Nordix Foundation. + * Modifications Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.endpoints.rest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.onap.policy.common.parameters.ValidationResult; +import org.onap.policy.common.parameters.rest.RestServerParameters; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.StandardCoder; + +/** + * Class to perform unit test of {@link RestServerParameters}. + * + * @author Ajith Sreekumar (ajith.sreekumar@est.tech) + */ +class RestServerParametersTest { + + private static final CommonTestData testData = new CommonTestData(); + private static final Coder coder = new StandardCoder(); + + @Test + void test() { + final RestServerParameters restServerParameters = + testData.toObject(testData.getRestServerParametersMap(false), RestServerParameters.class); + final ValidationResult validationResult = restServerParameters.validate(); + assertTrue(validationResult.isValid()); + assertEquals(CommonTestData.REST_SERVER_HOST, restServerParameters.getHost()); + assertEquals(CommonTestData.REST_SERVER_PORT, restServerParameters.getPort()); + assertEquals(CommonTestData.REST_SERVER_USER, restServerParameters.getUserName()); + assertEquals(CommonTestData.REST_SERVER_PASS, restServerParameters.getPassword()); + assertEquals(CommonTestData.REST_SERVER_HTTPS, restServerParameters.isHttps()); + assertEquals(CommonTestData.REST_SERVER_AAF, restServerParameters.isAaf()); + } + + @Test + void testValidate() { + final RestServerParameters restServerParameters = + testData.toObject(testData.getRestServerParametersMap(false), RestServerParameters.class); + final ValidationResult result = restServerParameters.validate(); + assertNull(result.getResult()); + assertTrue(result.isValid()); + } + + @Test + void test_valid() throws Exception { + String json = testData.getParameterGroupAsString( + "src/test/resources/org/onap/policy/common/endpoints/rest/RestServerParameters_valid.json"); + RestServerParameters restServerParameters = coder.decode(json, RestServerParameters.class); + final ValidationResult result = restServerParameters.validate(); + assertNull(result.getResult()); + assertTrue(result.isValid()); + } + + @Test + void test_invalid() throws Exception { + String json = testData.getParameterGroupAsString( + "src/test/resources/org/onap/policy/common/endpoints/rest/RestServerParameters_invalid.json"); + RestServerParameters restServerParameters = coder.decode(json, RestServerParameters.class); + final ValidationResult result = restServerParameters.validate(); + assertFalse(result.isValid()); + assertThat(result.getResult()).contains("item has status INVALID"); + } +} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/utils/KafkaPropertyUtilsTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/utils/KafkaPropertyUtilsTest.java deleted file mode 100644 index 52caa470..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/utils/KafkaPropertyUtilsTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.utils; - -import static org.onap.policy.common.endpoints.properties.PolicyEndPointProperties.PROPERTY_ADDITIONAL_PROPS_SUFFIX; - -import java.util.Properties; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -class KafkaPropertyUtilsTest { - - @Test - void test() { - var properties = new Properties(); - properties.setProperty("mytopic" + PROPERTY_ADDITIONAL_PROPS_SUFFIX, "{444-"); - PropertyUtils props = new PropertyUtils(properties, "mytopic", null); - - var build = KafkaPropertyUtils.makeBuilder(props, "mytopic", "servers").build(); - Assertions.assertTrue(build.getAdditionalProps().isEmpty()); - - properties.setProperty("mytopic" + PROPERTY_ADDITIONAL_PROPS_SUFFIX, - "{\"security.protocol\": \"SASL_PLAINTEXT\"}"); - build = KafkaPropertyUtils.makeBuilder(props, "mytopic", "servers").build(); - Assertions.assertTrue(build.getAdditionalProps().containsKey("security.protocol")); - - properties.setProperty("mytopic" + PROPERTY_ADDITIONAL_PROPS_SUFFIX, - "{\"security.protocol\": false }"); - build = KafkaPropertyUtils.makeBuilder(props, "mytopic", "servers").build(); - Assertions.assertTrue(build.getAdditionalProps().isEmpty()); - - properties.setProperty("mytopic" + PROPERTY_ADDITIONAL_PROPS_SUFFIX, ""); - build = KafkaPropertyUtils.makeBuilder(props, "mytopic", "servers").build(); - Assertions.assertTrue(build.getAdditionalProps().isEmpty()); - } - -} \ No newline at end of file diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/utils/NetLoggerUtilTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/utils/NetLoggerUtilTest.java deleted file mode 100644 index 123d1a77..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/utils/NetLoggerUtilTest.java +++ /dev/null @@ -1,271 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * policy-endpoints - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2024 Nordix Foundation - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.utils; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.AppenderBase; -import java.util.ArrayList; -import java.util.List; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.endpoints.features.NetLoggerFeatureApi; -import org.onap.policy.common.endpoints.features.NetLoggerFeatureProviders; -import org.onap.policy.common.endpoints.utils.NetLoggerUtil.EventType; -import org.slf4j.Logger; - -/** - * Test class for network log utilities such as logging and feature invocation. - */ -class NetLoggerUtilTest { - - private static final String TEST_TOPIC = "test-topic"; - private static final String MESSAGE = "hello world!"; - /** - * Test feature used for junits. - */ - private static NetLoggerFeature netLoggerFeature; - - /** - * Obtains the test implementation of NetLoggerFeatureApi. - */ - @BeforeAll - public static void setUp() { - netLoggerFeature = (NetLoggerFeature) NetLoggerFeatureProviders.getProviders().getList().get(0); - } - - /** - * Clears events list and resets return/exceptions flags before invoking every unit test. - */ - @BeforeEach - public void reset() { - TestAppender.clear(); - netLoggerFeature.setReturnValue(false, false); - netLoggerFeature.setExceptions(false, false); - } - - /** - * Tests obtaining the network logger instance. - */ - @Test - void getNetworkLoggerTest() { - assertEquals("network", NetLoggerUtil.getNetworkLogger().getName()); - } - - /** - * Tests logging a message to the network logger and invoking features before/after logging. - */ - @Test - void logTest() { - NetLoggerUtil.log(EventType.IN, CommInfrastructure.NOOP, TEST_TOPIC, MESSAGE); - assertEquals(3, TestAppender.events.size()); - } - - /** - * Tests that the network logger is used to log messages if a logger is not passed in. - */ - @Test - void logDefaultTest() { - NetLoggerUtil.log(null, EventType.IN, CommInfrastructure.NOOP, TEST_TOPIC, MESSAGE); - assertEquals(3, TestAppender.events.size()); - assertEquals("network", TestAppender.events.get(0).getLoggerName()); - } - - /** - * Tests a NetLoggerFeature that replaces base implementation before logging. - */ - @Test - void beforeLogReturnTrueTest() { - netLoggerFeature.setReturnValue(true, false); - NetLoggerUtil.log(null, EventType.IN, CommInfrastructure.NOOP, TEST_TOPIC, MESSAGE); - assertEquals(1, TestAppender.events.size()); - } - - /** - * Tests a NetLoggerFeature that post processes a logged message. - */ - @Test - void afterLogReturnTrueTest() { - netLoggerFeature.setReturnValue(false, true); - NetLoggerUtil.log(null, EventType.IN, CommInfrastructure.NOOP, TEST_TOPIC, MESSAGE); - assertEquals(3, TestAppender.events.size()); - } - - /** - * Tests throwing an exception in the before hook. - */ - @Test - void beforeLogExceptionTest() { - netLoggerFeature.setExceptions(true, false); - NetLoggerUtil.log(null, EventType.IN, CommInfrastructure.NOOP, TEST_TOPIC, MESSAGE); - assertEquals(2, TestAppender.events.size()); - } - - /** - * Tests throwing an exception in the after hook. - */ - @Test - void afterLogExceptionTest() { - netLoggerFeature.setExceptions(false, true); - NetLoggerUtil.log(null, EventType.IN, CommInfrastructure.NOOP, TEST_TOPIC, MESSAGE); - assertEquals(2, TestAppender.events.size()); - } - - /** - * A custom list appender to track messages being logged to the network logger. - * NOTE: Check src/test/resources/logback-test.xml for network logger configurations. - */ - public static class TestAppender extends AppenderBase { - - /** - * List of logged events. - */ - private static final List events = new ArrayList<>(); - - /** - * Called after every unit test to clear list of events. - */ - public static void clear() { - events.clear(); - } - - /** - * Appends each event to the event list. - */ - @Override - protected void append(ILoggingEvent event) { - events.add(event); - } - - } - - /** - * Test implementation of NetLoggerFeatureApi to be used by junits. - */ - public static class NetLoggerFeature implements NetLoggerFeatureApi { - - /** - * Used for setting the return values of before/after hooks. - */ - private boolean beforeReturn = false; - private boolean afterReturn = false; - - /** - * Used for throwing an exception in the before/after hooks. - */ - private boolean beforeException = false; - private boolean afterException = false; - - - /** - * Gets sequence number. - */ - @Override - public int getSequenceNumber() { - return 0; - } - - /** - * Get beforeLog return value. - */ - public boolean getBeforeReturn() { - return this.beforeReturn; - } - - /** - * Get afterLog return value. - */ - public boolean getAfterReturn() { - return this.afterReturn; - } - - /** - * Sets the return value for the before/after hooks. - * - * @param beforeVal beforeLog() return value - * @param afterVal afterLog() return value - */ - public void setReturnValue(boolean beforeVal, boolean afterVal) { - this.beforeReturn = beforeVal; - this.afterReturn = afterVal; - } - - /** - * Gets beforeException boolean. - */ - public boolean getBeforeException() { - return this.beforeException; - } - - /** - * Gets afterException boolean. - */ - public boolean getAfterException() { - return this.afterException; - } - - /** - * Sets before/after flags to determine if the feature should throw an exception. - */ - public void setExceptions(boolean beforeException, boolean afterException) { - this.beforeException = beforeException; - this.afterException = afterException; - } - - /** - * Simple beforeLog message. - */ - @Override - public boolean beforeLog(Logger eventLogger, EventType type, CommInfrastructure protocol, String topic, - String message) { - - if (beforeException) { - throw new RuntimeException("beforeLog exception"); - } - - eventLogger.info("before feature test"); - - return this.beforeReturn; - } - - /** - * Simple afterLog message. - */ - @Override - public boolean afterLog(Logger eventLogger, EventType type, CommInfrastructure protocol, String topic, - String message) { - - if (afterException) { - throw new RuntimeException("afterLog exception"); - } - - eventLogger.info("after feature test"); - - return this.afterReturn; - } - - } - -} diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/utils/PropertyUtilsTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/utils/PropertyUtilsTest.java deleted file mode 100644 index a639382f..00000000 --- a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/utils/PropertyUtilsTest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * ONAP - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2023-2024 Nordix Foundation. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.common.endpoints.utils; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.Properties; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -class PropertyUtilsTest { - private static final String DFLT_STRING = "my-default"; - private static final int DLFT_INT = 1000; - - private PropertyUtils utils; - private String invalidName; - private String invalidValue; - private Exception invalidEx; - - /** - * Initializes {@link #utils}. - */ - @BeforeEach - public void setUp() { - Properties properties = new Properties(); - properties.put("myPrefix.my-string", "some text"); - properties.put("myPrefix.empty-string", ""); - - properties.put("myPrefix.my-bool", "true"); - properties.put("myPrefix.my-bool2", "false"); - properties.put("myPrefix.empty-bool", ""); - properties.put("myPrefix.invalid-bool", "not a bool"); - - properties.put("myPrefix.my-int", "100"); - properties.put("myPrefix.my-int2", "200"); - properties.put("myPrefix.empty-int", ""); - properties.put("myPrefix.invalid-int", "not an int"); - - utils = new PropertyUtils(properties, "myPrefix", (name, value, ex) -> { - invalidName = name; - invalidValue = value; - invalidEx = ex; - }); - } - - @Test - void testGetString() { - assertEquals("some text", utils.getString(".my-string", DFLT_STRING)); - assertEquals(DFLT_STRING, utils.getString(".empty-string", DFLT_STRING)); - assertEquals(DFLT_STRING, utils.getString(".missing-string", DFLT_STRING)); - - assertNull(invalidName); - assertNull(invalidValue); - assertNull(invalidEx); - } - - @Test - void testGetBoolean() { - assertTrue(utils.getBoolean(".my-bool", false)); - assertFalse(utils.getBoolean(".my-bool2", true)); - assertTrue(utils.getBoolean(".empty-bool", true)); - assertFalse(utils.getBoolean(".invalid-bool", true)); - assertTrue(utils.getBoolean(".missing-bool", true)); - - assertNull(invalidName); - assertNull(invalidValue); - assertNull(invalidEx); - } - - @Test - void testGetInteger() { - assertEquals(100, utils.getInteger(".my-int", DLFT_INT)); - assertEquals(200, utils.getInteger(".my-int2", DLFT_INT)); - assertEquals(DLFT_INT, utils.getInteger(".empty-int", DLFT_INT)); - assertEquals(DLFT_INT, utils.getInteger(".missing-int", DLFT_INT)); - - assertNull(invalidName); - assertNull(invalidValue); - assertNull(invalidEx); - - assertEquals(DLFT_INT, utils.getInteger(".invalid-int", DLFT_INT)); - - assertEquals("myPrefix.invalid-int", invalidName); - assertEquals("not an int", invalidValue); - assertTrue(invalidEx instanceof NumberFormatException); - } - -} diff --git a/policy-endpoints/src/test/resources/META-INF/services/org.onap.policy.common.endpoints.features.NetLoggerFeatureApi b/policy-endpoints/src/test/resources/META-INF/services/org.onap.policy.common.endpoints.features.NetLoggerFeatureApi deleted file mode 100644 index c861ad18..00000000 --- a/policy-endpoints/src/test/resources/META-INF/services/org.onap.policy.common.endpoints.features.NetLoggerFeatureApi +++ /dev/null @@ -1 +0,0 @@ -org.onap.policy.common.endpoints.utils.NetLoggerUtilTest$NetLoggerFeature diff --git a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/TopicEndpointProxyTest.json b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/TopicEndpointProxyTest.json deleted file mode 100644 index 5b2e712a..00000000 --- a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/TopicEndpointProxyTest.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "locked": false, - "alive": false, - "topicSources": [ - { - "servers": [ - "my-server" - ], - "topic": "noop-source", - "effectiveTopic": "noop-source", - "recentEvents": [], - "alive": false, - "locked": false, - "topicCommInfrastructure": "NOOP" - } - ], - "topicSinks": [ - { - "servers": [ - "my-server" - ], - "topic": "noop-sink", - "effectiveTopic": "noop-sink", - "recentEvents": [], - "alive": false, - "locked": false, - "topicCommInfrastructure": "NOOP" - } - ] -} diff --git a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicBaseTest.json b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicBaseTest.json deleted file mode 100644 index 462278a4..00000000 --- a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/BusTopicBaseTest.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "servers" : [ "svra", "svrb" ], - "topic" : "my-topic", - "effectiveTopic" : "my-effective-topic", - "recentEvents" : [ ], - "alive" : false, - "locked" : false, - "apiKey" : "my-api-key", - "apiSecret" : "my-api-secret", - "useHttps" : true, - "allowTracing": true, - "allowSelfSignedCerts" : true, - "topicCommInfrastructure" : "NOOP" -} diff --git a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineBusTopicSinkTest.json b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineBusTopicSinkTest.json deleted file mode 100644 index 1f2fb55f..00000000 --- a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineBusTopicSinkTest.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "servers" : [ "svra", "svrb" ], - "topic" : "my-topic", - "effectiveTopic" : "my-effective-topic", - "recentEvents" : [ ], - "alive" : false, - "locked" : false, - "apiKey" : "my-api-key", - "apiSecret" : "my-api-secret", - "useHttps" : true, - "allowTracing": true, - "allowSelfSignedCerts" : true, - "topicCommInfrastructure" : "NOOP", - "partitionKey" : "my-partition" -} diff --git a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineKafkaTopicSinkTest.json b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineKafkaTopicSinkTest.json deleted file mode 100644 index dc1f1f75..00000000 --- a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/InlineKafkaTopicSinkTest.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "servers": [ - "svra", - "svrb" - ], - "topic": "my-topic", - "effectiveTopic": "my-effective-topic", - "recentEvents": [], - "alive": false, - "locked": false, - "useHttps": false, - "allowTracing": false, - "topicCommInfrastructure": "KAFKA", - "partitionKey": "my-partition", - "additionalProps": { - "security.protocol": "SASL_PLAINTEXT", - "sasl.mechanism": "SCRAM-SHA-512", - "sasl.jaas.config": "org.apache.kafka.common.security.plain.PlainLoginModule required username=abc password=abc serviceName=kafka;" - } -} diff --git a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedBusTopicSourceTest.json b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedBusTopicSourceTest.json deleted file mode 100644 index 305620c8..00000000 --- a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedBusTopicSourceTest.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "servers" : [ "svra", "svrb" ], - "topic" : "my-topic", - "effectiveTopic" : "my-effective-topic", - "recentEvents" : [ ], - "alive" : false, - "locked" : false, - "apiKey" : "my-api-key", - "apiSecret" : "my-api-secret", - "useHttps" : true, - "allowTracing": true, - "allowSelfSignedCerts" : true, - "consumerGroup" : "my-cons-group", - "consumerInstance" : "my-cons-inst", - "fetchTimeout" : 101, - "fetchLimit" : 100, - "topicCommInfrastructure" : "NOOP" -} diff --git a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedKafkaTopicSourceTest.json b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedKafkaTopicSourceTest.json deleted file mode 100644 index a101d235..00000000 --- a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/SingleThreadedKafkaTopicSourceTest.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "servers": [ - "localhost:9092", - "10.1.2.3:9092" - ], - "topic": "my-topic", - "effectiveTopic": "my-effective-topic", - "recentEvents": [], - "alive": false, - "locked": false, - "useHttps": false, - "allowTracing": false, - "topicCommInfrastructure": "KAFKA", - "additionalProps": { - "security.protocol": "SASL_PLAINTEXT", - "sasl.mechanism": "SCRAM-SHA-512", - "sasl.jaas.config": "org.apache.kafka.common.security.plain.PlainLoginModule required username=abc password=abc serviceName=kafka;" - } -} diff --git a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/TopicBaseTest.json b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/TopicBaseTest.json deleted file mode 100644 index b72b4efd..00000000 --- a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/event/comm/bus/internal/TopicBaseTest.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "servers" : [ "svra", "svrb" ], - "topic" : "my-topic", - "effectiveTopic" : "my-topic", - "recentEvents" : [ ], - "alive" : false, - "locked" : false, - "topicCommInfrastructure" : "NOOP" -} diff --git a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/RestServerParameters_invalid.json b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/RestServerParameters_invalid.json deleted file mode 100644 index a7455525..00000000 --- a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/RestServerParameters_invalid.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "port": 6969, - "userName": "username", - "password": "password", - "https": true -} \ No newline at end of file diff --git a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/RestServerParameters_valid.json b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/RestServerParameters_valid.json deleted file mode 100644 index 61d793a8..00000000 --- a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/RestServerParameters_valid.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "host": "0.0.0.0", - "port": 6969, - "userName": "username", - "password": "password", - "https": true -} \ No newline at end of file diff --git a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_all_params.json b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_all_params.json deleted file mode 100644 index 89e464dd..00000000 --- a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_all_params.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "topicSources" : [ { - "topic" : "policy-pdp-pap1", - "servers" : [ "kafka2, kafka3" ], - "topicCommInfrastructure" : "kafka", - "effectiveTopic" : "my-effective-topic", - "apiKey" : "my-api-key", - "apiSecret" : "my-api-secret", - "port": 123, - "useHttps" : true, - "allowTracing": true, - "allowSelfSignedCerts" : true, - "consumerGroup" : "consumer group", - "consumerInstance" : "consumer instance", - "fetchTimeout" : 15000, - "fetchLimit" : 100, - "userName": "username", - "password": "password", - "managed": true, - "environment": "environment1", - "aftEnvironment": "aftEnvironment1", - "partner": "partner1", - "latitude": "1234", - "longitude": "1234", - "partitionId": "partition_id", - "additionalProps": {"xyz":"xyz"}, - "clientName": "clientName1", - "hostname": "hostname1", - "basePath": "basePath1", - "serializationProvider": "serializationProvider1" - }], - "topicSinks" : [ { - "topic" : "policy-pdp-pap1", - "servers" : [ "kafka2, kafka3" ], - "topicCommInfrastructure" : "kafka", - "effectiveTopic" : "my-effective-topic", - "apiKey" : "my-api-key", - "apiSecret" : "my-api-secret", - "port": 123, - "useHttps" : true, - "allowTracing": true, - "allowSelfSignedCerts" : true, - "consumerGroup" : "consumer group", - "consumerInstance" : "consumer instance", - "fetchTimeout" : 15000, - "fetchLimit" : 100, - "userName": "username", - "password": "password", - "managed": true, - "environment": "environment1", - "aftEnvironment": "aftEnvironment1", - "partner": "partner1", - "latitude": "1234", - "longitude": "1234", - "partitionId": "partition_id", - "additionalProps": {"xyz":"xyz"}, - "clientName": "clientName1", - "hostname": "hostname1", - "basePath": "basePath1", - "serializationProvider": "serializationProvider1" - }] -} \ No newline at end of file diff --git a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_invalid.json b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_invalid.json deleted file mode 100644 index 775b4886..00000000 --- a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_invalid.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "topicSources" : [{ - "topic" : "ueb-source", - "servers" : ["my-server"] - }] -} \ No newline at end of file diff --git a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_missing_mandatory.json b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_missing_mandatory.json deleted file mode 100644 index 216c11ec..00000000 --- a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_missing_mandatory.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "topicSources" : [ { - "topic" : "policy-pdp-pap1", - "servers" : [], - "topicCommInfrastructure" : "kafka" - }], - "topicSinks" : [ { - "topic" : "policy-pdp-pap2", - "servers" : [ "kafka1, kafka2" ], - "topicCommInfrastructure" : "kafka" - }] -} \ No newline at end of file diff --git a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_valid.json b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_valid.json deleted file mode 100644 index 2603bfdc..00000000 --- a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/parameters/TopicParameters_valid.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "topicSources" : [ { - "topic" : "ueb-source", - "servers" : [ "my-server" ], - "topicCommInfrastructure" : "ueb" - },{ - "topic" : "policy-pdp-pap1", - "servers" : [ "kafka1, kafka2" ], - "topicCommInfrastructure" : "kafka" - },{ - "topic" : "policy-pdp-pap2", - "servers" : [ "kafka2, kafka3" ], - "topicCommInfrastructure" : "kafka" - }], - "topicSinks" : [ { - "topic" : "ueb-sink", - "servers" : [ "my-server" ], - "topicCommInfrastructure" : "ueb" - },{ - "topic" : "policy-pdp-pap2", - "servers" : [ "kafka1, kafka2" ], - "topicCommInfrastructure" : "kafka" - },{ - "topic" : "policy-pdp-pap3", - "servers" : [ "kafka2, kafka3" ], - "topicCommInfrastructure" : "kafka", - "effectiveTopic":"effectiveTopic1", - "allowSelfSignedCerts":true - }] -} \ No newline at end of file diff --git a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/RestServerParameters_invalid.json b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/RestServerParameters_invalid.json new file mode 100644 index 00000000..a7455525 --- /dev/null +++ b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/RestServerParameters_invalid.json @@ -0,0 +1,6 @@ +{ + "port": 6969, + "userName": "username", + "password": "password", + "https": true +} \ No newline at end of file diff --git a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/RestServerParameters_valid.json b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/RestServerParameters_valid.json new file mode 100644 index 00000000..61d793a8 --- /dev/null +++ b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/RestServerParameters_valid.json @@ -0,0 +1,7 @@ +{ + "host": "0.0.0.0", + "port": 6969, + "userName": "username", + "password": "password", + "https": true +} \ No newline at end of file diff --git a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/TopicParameters_all_params.json b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/TopicParameters_all_params.json new file mode 100644 index 00000000..89e464dd --- /dev/null +++ b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/TopicParameters_all_params.json @@ -0,0 +1,62 @@ +{ + "topicSources" : [ { + "topic" : "policy-pdp-pap1", + "servers" : [ "kafka2, kafka3" ], + "topicCommInfrastructure" : "kafka", + "effectiveTopic" : "my-effective-topic", + "apiKey" : "my-api-key", + "apiSecret" : "my-api-secret", + "port": 123, + "useHttps" : true, + "allowTracing": true, + "allowSelfSignedCerts" : true, + "consumerGroup" : "consumer group", + "consumerInstance" : "consumer instance", + "fetchTimeout" : 15000, + "fetchLimit" : 100, + "userName": "username", + "password": "password", + "managed": true, + "environment": "environment1", + "aftEnvironment": "aftEnvironment1", + "partner": "partner1", + "latitude": "1234", + "longitude": "1234", + "partitionId": "partition_id", + "additionalProps": {"xyz":"xyz"}, + "clientName": "clientName1", + "hostname": "hostname1", + "basePath": "basePath1", + "serializationProvider": "serializationProvider1" + }], + "topicSinks" : [ { + "topic" : "policy-pdp-pap1", + "servers" : [ "kafka2, kafka3" ], + "topicCommInfrastructure" : "kafka", + "effectiveTopic" : "my-effective-topic", + "apiKey" : "my-api-key", + "apiSecret" : "my-api-secret", + "port": 123, + "useHttps" : true, + "allowTracing": true, + "allowSelfSignedCerts" : true, + "consumerGroup" : "consumer group", + "consumerInstance" : "consumer instance", + "fetchTimeout" : 15000, + "fetchLimit" : 100, + "userName": "username", + "password": "password", + "managed": true, + "environment": "environment1", + "aftEnvironment": "aftEnvironment1", + "partner": "partner1", + "latitude": "1234", + "longitude": "1234", + "partitionId": "partition_id", + "additionalProps": {"xyz":"xyz"}, + "clientName": "clientName1", + "hostname": "hostname1", + "basePath": "basePath1", + "serializationProvider": "serializationProvider1" + }] +} \ No newline at end of file diff --git a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/TopicParameters_invalid.json b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/TopicParameters_invalid.json new file mode 100644 index 00000000..775b4886 --- /dev/null +++ b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/TopicParameters_invalid.json @@ -0,0 +1,6 @@ +{ + "topicSources" : [{ + "topic" : "ueb-source", + "servers" : ["my-server"] + }] +} \ No newline at end of file diff --git a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/TopicParameters_missing_mandatory.json b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/TopicParameters_missing_mandatory.json new file mode 100644 index 00000000..216c11ec --- /dev/null +++ b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/TopicParameters_missing_mandatory.json @@ -0,0 +1,12 @@ +{ + "topicSources" : [ { + "topic" : "policy-pdp-pap1", + "servers" : [], + "topicCommInfrastructure" : "kafka" + }], + "topicSinks" : [ { + "topic" : "policy-pdp-pap2", + "servers" : [ "kafka1, kafka2" ], + "topicCommInfrastructure" : "kafka" + }] +} \ No newline at end of file diff --git a/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/TopicParameters_valid.json b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/TopicParameters_valid.json new file mode 100644 index 00000000..2603bfdc --- /dev/null +++ b/policy-endpoints/src/test/resources/org/onap/policy/common/endpoints/rest/TopicParameters_valid.json @@ -0,0 +1,30 @@ +{ + "topicSources" : [ { + "topic" : "ueb-source", + "servers" : [ "my-server" ], + "topicCommInfrastructure" : "ueb" + },{ + "topic" : "policy-pdp-pap1", + "servers" : [ "kafka1, kafka2" ], + "topicCommInfrastructure" : "kafka" + },{ + "topic" : "policy-pdp-pap2", + "servers" : [ "kafka2, kafka3" ], + "topicCommInfrastructure" : "kafka" + }], + "topicSinks" : [ { + "topic" : "ueb-sink", + "servers" : [ "my-server" ], + "topicCommInfrastructure" : "ueb" + },{ + "topic" : "policy-pdp-pap2", + "servers" : [ "kafka1, kafka2" ], + "topicCommInfrastructure" : "kafka" + },{ + "topic" : "policy-pdp-pap3", + "servers" : [ "kafka2, kafka3" ], + "topicCommInfrastructure" : "kafka", + "effectiveTopic":"effectiveTopic1", + "allowSelfSignedCerts":true + }] +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index e841eb43..572d62bd 100644 --- a/pom.xml +++ b/pom.xml @@ -49,12 +49,13 @@ capabilities - utils-test - utils - gson common-parameters - policy-endpoints + gson + utils + utils-test spring-utils + message-bus + policy-endpoints diff --git a/spring-utils/pom.xml b/spring-utils/pom.xml index d5d5d848..d81b4f07 100644 --- a/spring-utils/pom.xml +++ b/spring-utils/pom.xml @@ -40,6 +40,10 @@ utils ${project.version} + + org.springframework + spring-core + org.springframework spring-web @@ -50,13 +54,9 @@ org.mockito - mockito-junit-jupiter + mockito-core test - - org.assertj - assertj-core - \ No newline at end of file diff --git a/utils-test/pom.xml b/utils-test/pom.xml index 6338cc08..a8a282e8 100644 --- a/utils-test/pom.xml +++ b/utils-test/pom.xml @@ -3,7 +3,7 @@ ONAP Policy Engine - Common Modules ================================================================================ Copyright (C) 2018-2021 AT&T Intellectual Property. All rights reserved. - Modificaitons Copyright (C) 2023-2024 Nordix Foundation. + Modifications Copyright (C) 2023-2024 Nordix Foundation. ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,7 +19,8 @@ ============LICENSE_END========================================================= --> - + 4.0.0 @@ -40,42 +41,84 @@ - org.bouncycastle - bcpkix-fips + org.onap.policy.common + utils + ${project.version} + + + org.onap.policy.common + gson + ${project.version} + provided org.apache.commons commons-jexl3 + + + org.bouncycastle + bcpkix-fips + + + ch.qos.logback + logback-classic provided - org.onap.policy.common - utils - ${project.version} + ch.qos.logback + logback-core provided - - - - org.awaitility - awaitility - test + + com.google.code.gson + gson + provided + + + com.google.re2j + re2j + provided com.openpojo openpojo compile + + org.hamcrest + hamcrest + compile + org.junit.jupiter junit-jupiter-api compile + + org.projectlombok + lombok + provided + + + org.slf4j + slf4j-api + provided + org.assertj assertj-core test + + org.awaitility + awaitility + test + + + org.mockito + mockito-core + test + org.mockito mockito-junit-jupiter @@ -86,11 +129,5 @@ spring-test test - - org.hamcrest - hamcrest-core - 2.2 - compile - diff --git a/utils/pom.xml b/utils/pom.xml index 791a048a..18550e4e 100644 --- a/utils/pom.xml +++ b/utils/pom.xml @@ -45,12 +45,21 @@ ${project.version} - commons-net - commons-net + ch.qos.logback + logback-classic - org.slf4j - slf4j-api + ch.qos.logback + logback-core + + + com.google.code.gson + gson + provided + + + com.google.re2j + re2j provided @@ -62,42 +71,59 @@ commons-io - jakarta.persistence - jakarta.persistence-api + commons-net + commons-net - ch.qos.logback - logback-classic + jakarta.persistence + jakarta.persistence-api - ch.qos.logback - logback-core + jakarta.xml.bind + jakarta.xml.bind-api org.apache.commons commons-lang3 - com.google.re2j - re2j + org.projectlombok + lombok + provided + + + org.slf4j + slf4j-api + provided org.yaml snakeyaml + + com.openpojo + openpojo + test + org.assertj assertj-core test + + org.hamcrest + hamcrest + test + org.mockito - mockito-junit-jupiter + mockito-core test - jakarta.xml.bind - jakarta.xml.bind-api + org.mockito + mockito-junit-jupiter + test diff --git a/utils/src/main/java/org/onap/policy/common/utils/properties/PropertyUtils.java b/utils/src/main/java/org/onap/policy/common/utils/properties/PropertyUtils.java new file mode 100644 index 00000000..7155323b --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/properties/PropertyUtils.java @@ -0,0 +1,123 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.properties; + +import java.util.Properties; +import lombok.AllArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * Utilities for extracting property values and converting them to other types. + */ +@AllArgsConstructor +public class PropertyUtils { + /** + * Properties on which to work. + */ + private Properties properties; + + /** + * Prefix to prepend to property names. + */ + private String prefix; + + /** + * Function to invoke if a property value is invalid. + */ + private TriConsumer invalidHandler; + + /** + * Gets a string property. + * + * @param propName name of the property whose value is to be retrieved + * @param defaultValue value to use if the property value is empty or does not exist + * @return the property's value + */ + public String getString(String propName, String defaultValue) { + String propValue = getProperty(propName); + return (StringUtils.isBlank(propValue) ? defaultValue : propValue); + } + + /** + * Gets a boolean property. + * + * @param propName name of the property whose value is to be retrieved + * @param defaultValue value to use if the property value is empty or does not exist + * @return the property's value + */ + public boolean getBoolean(String propName, boolean defaultValue) { + String propValue = getProperty(propName); + + if (!StringUtils.isBlank(propValue)) { + return Boolean.parseBoolean(propValue); + } + + return defaultValue; + } + + /** + * Gets an integer property. + * + * @param propName name of the property whose value is to be retrieved + * @param defaultValue value to use if the property value is empty or does not exist + * @return the property's value + */ + public int getInteger(String propName, int defaultValue) { + String propValue = getProperty(propName); + + if (!StringUtils.isBlank(propValue)) { + try { + return Integer.parseInt(propValue); + + } catch (NumberFormatException nfe) { + invalidHandler.accept(getFullName(propName), propValue, nfe); + } + } + + return defaultValue; + } + + + /** + * Gets a property's value. + * + * @param propName name of the property whose value is to be retrieved + * @return the property's value, or {@code null} if it does not exist + */ + private String getProperty(String propName) { + return properties.getProperty(getFullName(propName)); + } + + /** + * Gets the full property name, with the prefix prepended. + * + * @param propName property name, without the prefix + * @return the full property name + */ + private String getFullName(String propName) { + return prefix + propName; + } + + @FunctionalInterface + public static interface TriConsumer { + public void accept(A propName, B propValue, C exception); + } +} diff --git a/utils/src/main/java/org/onap/policy/common/utils/report/HealthCheckReport.java b/utils/src/main/java/org/onap/policy/common/utils/report/HealthCheckReport.java new file mode 100644 index 00000000..78356cfb --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/report/HealthCheckReport.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START=============================================================== + * Copyright (C) 2018 Ericsson. All rights reserved. + * Modifications Copyright (C) 2018, 2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. + * ======================================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.report; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + * Class to represent health check report of a service. + * + * @author Ram Krishna Verma (ram.krishna.verma@ericsson.com) + */ +@Getter +@Setter +@ToString +public class HealthCheckReport { + + private String name; + private String url; + private boolean healthy; + private int code; + private String message; +} diff --git a/utils/src/main/java/org/onap/policy/common/utils/services/OrderedServiceImpl.java b/utils/src/main/java/org/onap/policy/common/utils/services/OrderedServiceImpl.java index 998d6742..3726ef89 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/services/OrderedServiceImpl.java +++ b/utils/src/main/java/org/onap/policy/common/utils/services/OrderedServiceImpl.java @@ -3,6 +3,7 @@ * utils * ================================================================================ * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,22 +36,22 @@ import org.slf4j.LoggerFactory; */ public class OrderedServiceImpl { // logger - private static Logger logger = LoggerFactory.getLogger(OrderedServiceImpl.class); + private static final Logger logger = LoggerFactory.getLogger(OrderedServiceImpl.class); // sorted list of instances implementing the service private List implementers = null; // 'ServiceLoader' that is used to discover and create the services - private ServiceLoader serviceLoader = null; + private final ServiceLoader serviceLoader; // use this to ensure that we only use one unique instance of each class - private static Map, OrderedService> classToSingleton = new HashMap<>(); + private static final Map, OrderedService> classToSingleton = new HashMap<>(); /** * Constructor - create the 'ServiceLoader' instance. * * @param clazz the class object associated with 'T' (I supposed it could - * be a subclass, but I'm not sure this is useful) + * be a subclass, but I'm not sure if this is useful) */ public OrderedServiceImpl(Class clazz) { // This constructor wouldn't be needed if 'T.class' was legal @@ -60,8 +61,7 @@ public class OrderedServiceImpl { /** * Get List of implementers. * - * @return the sorted list of services implementing interface 'T' discovered - * by 'ServiceLoader'. + * @return the sorted list of services implementing interface 'T' discovered by 'ServiceLoader'. */ public synchronized List getList() { if (implementers == null) { @@ -78,12 +78,11 @@ public class OrderedServiceImpl { * expensive operation in terms of CPU and elapsed time, so it is best if it * isn't invoked too frequently. * - * @return the sorted list of services implementing interface 'T' discovered - * by 'ServiceLoader'. + * @return the sorted list of services implementing interface 'T' discovered by 'ServiceLoader'. */ @SuppressWarnings("unchecked") public synchronized List rebuildList() { - // build a list of all of the current implementors + // build a list of all the current implementors List tmp = new LinkedList<>(); for (T service : serviceLoader) { tmp.add((T) getSingleton(service)); @@ -91,7 +90,7 @@ public class OrderedServiceImpl { // Sort the list according to sequence number, and then alphabetically // according to full class name. - Collections.sort(tmp, (o1, o2) -> { + tmp.sort((o1, o2) -> { int s1 = o1.getSequenceNumber(); int s2 = o2.getSequenceNumber(); if (s1 < s2) { @@ -112,7 +111,7 @@ public class OrderedServiceImpl { /** * If a service implements multiple APIs managed by 'ServiceLoader', a * separate instance is created for each API. This method ensures that - * the first instance is used in all of the lists. + * the first instance is used in all the lists. * * @param service this is the object created by ServiceLoader * @return the object to use in place of 'service'. If 'service' is the first diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/PropertyUtilsTest.java b/utils/src/test/java/org/onap/policy/common/utils/properties/PropertyUtilsTest.java new file mode 100644 index 00000000..a8b37f57 --- /dev/null +++ b/utils/src/test/java/org/onap/policy/common/utils/properties/PropertyUtilsTest.java @@ -0,0 +1,110 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2023-2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.properties; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Properties; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class PropertyUtilsTest { + private static final String DFLT_STRING = "my-default"; + private static final int DLFT_INT = 1000; + + private PropertyUtils utils; + private String invalidName; + private String invalidValue; + private Exception invalidEx; + + /** + * Initializes {@link #utils}. + */ + @BeforeEach + public void setUp() { + Properties properties = new Properties(); + properties.put("myPrefix.my-string", "some text"); + properties.put("myPrefix.empty-string", ""); + + properties.put("myPrefix.my-bool", "true"); + properties.put("myPrefix.my-bool2", "false"); + properties.put("myPrefix.empty-bool", ""); + properties.put("myPrefix.invalid-bool", "not a bool"); + + properties.put("myPrefix.my-int", "100"); + properties.put("myPrefix.my-int2", "200"); + properties.put("myPrefix.empty-int", ""); + properties.put("myPrefix.invalid-int", "not an int"); + + utils = new PropertyUtils(properties, "myPrefix", (name, value, ex) -> { + invalidName = name; + invalidValue = value; + invalidEx = ex; + }); + } + + @Test + void testGetString() { + assertEquals("some text", utils.getString(".my-string", DFLT_STRING)); + assertEquals(DFLT_STRING, utils.getString(".empty-string", DFLT_STRING)); + assertEquals(DFLT_STRING, utils.getString(".missing-string", DFLT_STRING)); + + assertNull(invalidName); + assertNull(invalidValue); + assertNull(invalidEx); + } + + @Test + void testGetBoolean() { + assertTrue(utils.getBoolean(".my-bool", false)); + assertFalse(utils.getBoolean(".my-bool2", true)); + assertTrue(utils.getBoolean(".empty-bool", true)); + assertFalse(utils.getBoolean(".invalid-bool", true)); + assertTrue(utils.getBoolean(".missing-bool", true)); + + assertNull(invalidName); + assertNull(invalidValue); + assertNull(invalidEx); + } + + @Test + void testGetInteger() { + assertEquals(100, utils.getInteger(".my-int", DLFT_INT)); + assertEquals(200, utils.getInteger(".my-int2", DLFT_INT)); + assertEquals(DLFT_INT, utils.getInteger(".empty-int", DLFT_INT)); + assertEquals(DLFT_INT, utils.getInteger(".missing-int", DLFT_INT)); + + assertNull(invalidName); + assertNull(invalidValue); + assertNull(invalidEx); + + assertEquals(DLFT_INT, utils.getInteger(".invalid-int", DLFT_INT)); + + assertEquals("myPrefix.invalid-int", invalidName); + assertEquals("not an int", invalidValue); + assertTrue(invalidEx instanceof NumberFormatException); + } + +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/report/TestHealthCheckReport.java b/utils/src/test/java/org/onap/policy/common/utils/report/TestHealthCheckReport.java new file mode 100644 index 00000000..3a207022 --- /dev/null +++ b/utils/src/test/java/org/onap/policy/common/utils/report/TestHealthCheckReport.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * Modifications Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.report; + +import static org.hamcrest.CoreMatchers.anyOf; +import static org.hamcrest.CoreMatchers.anything; + +import com.openpojo.reflection.PojoClass; +import com.openpojo.reflection.filters.FilterClassName; +import com.openpojo.validation.Validator; +import com.openpojo.validation.ValidatorBuilder; +import com.openpojo.validation.affirm.Affirm; +import com.openpojo.validation.rule.impl.GetterMustExistRule; +import com.openpojo.validation.rule.impl.SetterMustExistRule; +import com.openpojo.validation.test.Tester; +import com.openpojo.validation.test.impl.GetterTester; +import com.openpojo.validation.test.impl.SetterTester; +import com.openpojo.validation.utils.ValidationHelper; +import org.hamcrest.Matcher; +import org.junit.jupiter.api.Test; + +/** + * Class to perform unit test of HealthCheckReport. + * + * @author Ram Krishna Verma (ram.krishna.verma@ericsson.com) + */ +class TestHealthCheckReport { + + @Test + void testHealthCheckReport() { + final Validator validator = + ValidatorBuilder.create().with(new GetterMustExistRule()).with(new SetterMustExistRule()) + .with(new GetterTester()).with(new SetterTester()).with(new ToStringTester()).build(); + validator.validate(HealthCheckReport.class.getPackage().getName(), + new FilterClassName(HealthCheckReport.class.getName())); + } + + static class ToStringTester implements Tester { + + private final Matcher matcher; + + public ToStringTester() { + matcher = anything(); + } + + @Override + public void run(final PojoClass pojoClass) { + final Class clazz = pojoClass.getClazz(); + if (anyOf(matcher).matches(clazz)) { + final Object classInstance = ValidationHelper.getBasicInstance(pojoClass); + + Affirm.affirmFalse("Found default toString output", + classInstance.toString().matches(Object.class.getName() + "@" + "\\w+")); + } + + } + } +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/resources/ResourceUtilsTest.java b/utils/src/test/java/org/onap/policy/common/utils/resources/ResourceUtilsTest.java index d1e891ca..9db367cf 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/resources/ResourceUtilsTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/resources/ResourceUtilsTest.java @@ -313,7 +313,7 @@ class ResourceUtilsTest { normalizePath(resultD2.iterator().next())); Set resultJ0 = ResourceUtils.getDirectoryContents("com"); - assertTrue(resultJ0.contains("com/google/gson/")); + assertTrue(resultJ0.contains("com/google/")); assertEquals("com/google/", normalizePath(resultJ0.iterator().next())); Set resultJ1 = ResourceUtils.getDirectoryContents("com/google/gson"); -- cgit 1.2.3-korg