Use BidirectionalTopicClient from policy-common
[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 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 prov = new BidirectionalTopicActor(ACTOR);
161         Function<String, Map<String, Object>> maker =
162                         prov.makeOperatorParameters(Util.translateToMap(prov.getName(), params));
163
164         assertNull(maker.apply(UNKNOWN));
165
166         // use a TreeMap to ensure the properties are sorted
167         assertEquals("{sinkTopic=my-sink, sourceTopic=my-source-A, timeoutSec=10}",
168                         new TreeMap<>(maker.apply("operA")).toString());
169
170         assertEquals("{sinkTopic=my-sink, sourceTopic=topicB, timeoutSec=10}",
171                         new TreeMap<>(maker.apply("operB")).toString());
172
173         // with invalid actor parameters
174         params.setOperation(null);
175         assertThatThrownBy(() -> prov.makeOperatorParameters(Util.translateToMap(prov.getName(), params)))
176                         .isInstanceOf(ParameterValidationRuntimeException.class);
177     }
178
179     @Test
180     public void testBidirectionalTopicActor() {
181         assertEquals(ACTOR, actor.getName());
182         assertEquals(ACTOR, actor.getFullName());
183     }
184
185     @Test
186     public void testGetTopicHandler() {
187         assertSame(handler1, actor.getTopicHandler(MY_SINK, MY_SOURCE1));
188         assertSame(handler2, actor.getTopicHandler(MY_SINK, MY_SOURCE2));
189
190         assertThatIllegalArgumentException().isThrownBy(() -> actor.getTopicHandler(UNKNOWN, MY_SOURCE1));
191     }
192
193     @Test
194     public void testMakeTopicHandler() {
195         // use a real actor
196         actor = new BidirectionalTopicActor(ACTOR);
197
198         handler1 = actor.getTopicHandler(MY_SINK, MY_SOURCE1);
199         handler2 = actor.getTopicHandler(MY_SINK, MY_SOURCE2);
200
201         assertNotNull(handler1);
202         assertNotNull(handler2);
203         assertNotSame(handler1, handler2);
204     }
205
206
207     private BidirectionalTopicActorParams makeParams() {
208         BidirectionalTopicActorParams params = new BidirectionalTopicActorParams();
209         params.setSinkTopic(MY_SINK);
210         params.setSourceTopic(MY_SOURCE1);
211         params.setTimeoutSec(TIMEOUT);
212
213         // @formatter:off
214         params.setOperation(Map.of(
215                         "operA", Map.of(),
216                         "operB", Map.of("sourceTopic", "topicB")));
217         // @formatter:on
218         return params;
219     }
220
221     private class MyActor extends BidirectionalTopicActor {
222
223         public MyActor() {
224             super(ACTOR);
225         }
226
227         @Override
228         protected BidirectionalTopicHandler makeTopicHandler(String sinkTopic, String sourceTopic)
229                         throws BidirectionalTopicClientException {
230
231             if (MY_SINK.equals(sinkTopic)) {
232                 if (MY_SOURCE1.equals(sourceTopic)) {
233                     return handler1;
234                 } else if (MY_SOURCE2.equals(sourceTopic)) {
235                     return handler2;
236                 }
237             }
238
239             throw new BidirectionalTopicClientException("no topic " + sinkTopic + "/" + sourceTopic);
240         }
241     }
242 }