Fix some sonars in policy-models
[policy/models.git] / models-interactions / model-actors / actorServiceProvider / src / test / java / org / onap / policy / controlloop / actorserviceprovider / impl / BidirectionalTopicActorTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.controlloop.actorserviceprovider.impl;
22
23 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
24 import static org.assertj.core.api.Assertions.assertThatThrownBy;
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertNotNull;
27 import static org.junit.Assert.assertNotSame;
28 import static org.junit.Assert.assertNull;
29 import static org.junit.Assert.assertSame;
30 import static org.mockito.Mockito.never;
31 import static org.mockito.Mockito.verify;
32
33 import java.util.Map;
34 import java.util.Properties;
35 import java.util.TreeMap;
36 import java.util.function.Function;
37 import org.junit.AfterClass;
38 import org.junit.Before;
39 import org.junit.BeforeClass;
40 import org.junit.Test;
41 import org.mockito.Mock;
42 import org.mockito.MockitoAnnotations;
43 import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager;
44 import org.onap.policy.common.endpoints.event.comm.client.BidirectionalTopicClientException;
45 import org.onap.policy.controlloop.actorserviceprovider.Util;
46 import org.onap.policy.controlloop.actorserviceprovider.parameters.BidirectionalTopicActorParams;
47 import org.onap.policy.controlloop.actorserviceprovider.parameters.ParameterValidationRuntimeException;
48 import org.onap.policy.controlloop.actorserviceprovider.topic.BidirectionalTopicHandler;
49
50 public class BidirectionalTopicActorTest {
51
52     private static final String ACTOR = "my-actor";
53     private static final String UNKNOWN = "unknown";
54     private static final String MY_SINK = "my-sink";
55     private static final String MY_SOURCE1 = "my-source-A";
56     private static final String MY_SOURCE2 = "my-source-B";
57     private static final int TIMEOUT = 10;
58
59     @Mock
60     private BidirectionalTopicHandler handler1;
61     @Mock
62     private BidirectionalTopicHandler handler2;
63
64     private BidirectionalTopicActor<BidirectionalTopicActorParams> actor;
65
66
67     /**
68      * Configures the endpoints.
69      */
70     @BeforeClass
71     public static void setUpBeforeClass() {
72         Properties props = new Properties();
73         props.setProperty("noop.sink.topics", MY_SINK);
74         props.setProperty("noop.source.topics", MY_SOURCE1 + "," + MY_SOURCE2);
75
76         // clear all topics and then configure one sink and two sources
77         TopicEndpointManager.getManager().shutdown();
78         TopicEndpointManager.getManager().addTopicSinks(props);
79         TopicEndpointManager.getManager().addTopicSources(props);
80     }
81
82     @AfterClass
83     public static void tearDownAfterClass() {
84         // clear all topics after the tests
85         TopicEndpointManager.getManager().shutdown();
86     }
87
88     /**
89      * Sets up.
90      */
91     @Before
92     public void setUp() {
93         MockitoAnnotations.initMocks(this);
94
95         actor = new MyActor();
96         actor.configure(Util.translateToMap(ACTOR, makeParams()));
97     }
98
99     @Test
100     public void testDoStart() throws BidirectionalTopicClientException {
101         // allocate some handlers
102         actor.getTopicHandler(MY_SINK, MY_SOURCE1);
103         actor.getTopicHandler(MY_SINK, MY_SOURCE2);
104
105         // start it
106         actor.start();
107
108         verify(handler1).start();
109         verify(handler2).start();
110
111         verify(handler1, never()).stop();
112         verify(handler2, never()).stop();
113
114         verify(handler1, never()).shutdown();
115         verify(handler2, never()).shutdown();
116     }
117
118     @Test
119     public void testDoStop() throws BidirectionalTopicClientException {
120         // allocate some handlers
121         actor.getTopicHandler(MY_SINK, MY_SOURCE1);
122         actor.getTopicHandler(MY_SINK, MY_SOURCE2);
123
124         // start it
125         actor.start();
126
127         // stop it
128         actor.stop();
129
130         verify(handler1).stop();
131         verify(handler2).stop();
132
133         verify(handler1, never()).shutdown();
134         verify(handler2, never()).shutdown();
135     }
136
137     @Test
138     public void testDoShutdown() {
139         // allocate some handlers
140         actor.getTopicHandler(MY_SINK, MY_SOURCE1);
141         actor.getTopicHandler(MY_SINK, MY_SOURCE2);
142
143         // start it
144         actor.start();
145
146         // stop it
147         actor.shutdown();
148
149         verify(handler1).shutdown();
150         verify(handler2).shutdown();
151
152         verify(handler1, never()).stop();
153         verify(handler2, never()).stop();
154     }
155
156     @Test
157     public void testMakeOperatorParameters() {
158         BidirectionalTopicActorParams params = makeParams();
159
160         final BidirectionalTopicActor<BidirectionalTopicActorParams> prov =
161                         new BidirectionalTopicActor<>(ACTOR, BidirectionalTopicActorParams.class);
162         Function<String, Map<String, Object>> maker =
163                         prov.makeOperatorParameters(Util.translateToMap(prov.getName(), params));
164
165         assertNull(maker.apply(UNKNOWN));
166
167         // use a TreeMap to ensure the properties are sorted
168         assertEquals("{sinkTopic=my-sink, sourceTopic=my-source-A, timeoutSec=10}",
169                         new TreeMap<>(maker.apply("operA")).toString());
170
171         assertEquals("{sinkTopic=my-sink, sourceTopic=topicB, timeoutSec=10}",
172                         new TreeMap<>(maker.apply("operB")).toString());
173
174         // with invalid actor parameters
175         params.setOperations(null);
176         Map<String, Object> map = Util.translateToMap(prov.getName(), params);
177         assertThatThrownBy(() -> prov.makeOperatorParameters(map))
178                         .isInstanceOf(ParameterValidationRuntimeException.class);
179     }
180
181     @Test
182     public void testBidirectionalTopicActor() {
183         assertEquals(ACTOR, actor.getName());
184         assertEquals(ACTOR, actor.getFullName());
185     }
186
187     @Test
188     public void testGetTopicHandler() {
189         assertSame(handler1, actor.getTopicHandler(MY_SINK, MY_SOURCE1));
190         assertSame(handler2, actor.getTopicHandler(MY_SINK, MY_SOURCE2));
191
192         assertThatIllegalArgumentException().isThrownBy(() -> actor.getTopicHandler(UNKNOWN, MY_SOURCE1));
193     }
194
195     @Test
196     public void testMakeTopicHandler() {
197         // use a real actor
198         actor = new BidirectionalTopicActor<>(ACTOR, BidirectionalTopicActorParams.class);
199
200         handler1 = actor.getTopicHandler(MY_SINK, MY_SOURCE1);
201         handler2 = actor.getTopicHandler(MY_SINK, MY_SOURCE2);
202
203         assertNotNull(handler1);
204         assertNotNull(handler2);
205         assertNotSame(handler1, handler2);
206     }
207
208
209     private BidirectionalTopicActorParams makeParams() {
210         BidirectionalTopicActorParams params = new BidirectionalTopicActorParams();
211         params.setSinkTopic(MY_SINK);
212         params.setSourceTopic(MY_SOURCE1);
213         params.setTimeoutSec(TIMEOUT);
214
215         // @formatter:off
216         params.setOperations(Map.of(
217                         "operA", Map.of(),
218                         "operB", Map.of("sourceTopic", "topicB")));
219         // @formatter:on
220         return params;
221     }
222
223     private class MyActor extends BidirectionalTopicActor<BidirectionalTopicActorParams> {
224
225         public MyActor() {
226             super(ACTOR, BidirectionalTopicActorParams.class);
227         }
228
229         @Override
230         protected BidirectionalTopicHandler makeTopicHandler(String sinkTopic, String sourceTopic)
231                         throws BidirectionalTopicClientException {
232
233             if (MY_SINK.equals(sinkTopic)) {
234                 if (MY_SOURCE1.equals(sourceTopic)) {
235                     return handler1;
236                 } else if (MY_SOURCE2.equals(sourceTopic)) {
237                     return handler2;
238                 }
239             }
240
241             throw new BidirectionalTopicClientException("no topic " + sinkTopic + "/" + sourceTopic);
242         }
243     }
244 }