Use BidirectionalTopicClient from policy-common
[policy/models.git] / models-interactions / model-actors / actorServiceProvider / src / test / java / org / onap / policy / controlloop / actorserviceprovider / topic / ForwarderTest.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.topic;
22
23 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
24 import static org.mockito.ArgumentMatchers.any;
25 import static org.mockito.Mockito.doThrow;
26 import static org.mockito.Mockito.never;
27 import static org.mockito.Mockito.times;
28 import static org.mockito.Mockito.verify;
29
30 import java.util.Arrays;
31 import java.util.Map;
32 import java.util.function.BiConsumer;
33 import org.junit.Before;
34 import org.junit.Test;
35 import org.mockito.Mock;
36 import org.mockito.MockitoAnnotations;
37 import org.onap.policy.common.utils.coder.StandardCoderObject;
38 import org.onap.policy.controlloop.actorserviceprovider.Util;
39
40 public class ForwarderTest {
41     private static final String TEXT = "some text";
42
43     private static final String KEY1 = "requestId";
44     private static final String KEY2 = "container";
45     private static final String SUBKEY = "subRequestId";
46
47     private static final String VALUEA_REQID = "hello";
48     private static final String VALUEA_SUBREQID = "world";
49
50     // request id is shared with value A
51     private static final String VALUEB_REQID = "hello";
52     private static final String VALUEB_SUBREQID = "another world";
53
54     // unique values
55     private static final String VALUEC_REQID = "bye";
56     private static final String VALUEC_SUBREQID = "bye-bye";
57
58     @Mock
59     private BiConsumer<String, StandardCoderObject> listener1;
60
61     @Mock
62     private BiConsumer<String, StandardCoderObject> listener1b;
63
64     @Mock
65     private BiConsumer<String, StandardCoderObject> listener2;
66
67     @Mock
68     private BiConsumer<String, StandardCoderObject> listener3;
69
70     private Forwarder forwarder;
71
72
73     /**
74      * Sets up.
75      */
76     @Before
77     public void setUp() {
78         MockitoAnnotations.initMocks(this);
79         forwarder = new Forwarder(Arrays.asList(new SelectorKey(KEY1), new SelectorKey(KEY2, SUBKEY)));
80
81         forwarder.register(Arrays.asList(VALUEA_REQID, VALUEA_SUBREQID), listener1);
82         forwarder.register(Arrays.asList(VALUEA_REQID, VALUEA_SUBREQID), listener1b);
83         forwarder.register(Arrays.asList(VALUEB_REQID, VALUEB_SUBREQID), listener2);
84         forwarder.register(Arrays.asList(VALUEC_REQID, VALUEC_SUBREQID), listener3);
85     }
86
87     @Test
88     public void testRegister() {
89         // key size mismatches
90         assertThatIllegalArgumentException().isThrownBy(() -> forwarder.register(Arrays.asList(), listener1))
91                         .withMessage("key/value mismatch");
92         assertThatIllegalArgumentException()
93                         .isThrownBy(() -> forwarder.register(Arrays.asList(VALUEA_REQID), listener1))
94                         .withMessage("key/value mismatch");
95     }
96
97     @Test
98     public void testUnregister() {
99         // remove listener1b
100         forwarder.unregister(Arrays.asList(VALUEA_REQID, VALUEA_SUBREQID), listener1b);
101
102         StandardCoderObject sco = makeMessage(Map.of(KEY1, VALUEA_REQID, KEY2, Map.of(SUBKEY, VALUEA_SUBREQID)));
103         forwarder.onMessage(TEXT, sco);
104
105         verify(listener1).accept(TEXT, sco);
106         verify(listener1b, never()).accept(any(), any());
107
108         // remove listener1
109         forwarder.unregister(Arrays.asList(VALUEA_REQID, VALUEA_SUBREQID), listener1);
110         forwarder.onMessage(TEXT, sco);
111
112         // route a message to listener2
113         sco = makeMessage(Map.of(KEY1, VALUEB_REQID, KEY2, Map.of(SUBKEY, VALUEB_SUBREQID)));
114         forwarder.onMessage(TEXT, sco);
115         verify(listener2).accept(TEXT, sco);
116
117         // no more messages to listener1 or 1b
118         verify(listener1).accept(any(), any());
119         verify(listener1b, never()).accept(any(), any());
120     }
121
122     @Test
123     public void testOnMessage() {
124         StandardCoderObject sco = makeMessage(Map.of(KEY1, VALUEA_REQID, KEY2, Map.of(SUBKEY, VALUEA_SUBREQID)));
125         forwarder.onMessage(TEXT, sco);
126
127         verify(listener1).accept(TEXT, sco);
128         verify(listener1b).accept(TEXT, sco);
129
130         // repeat - counts should increment
131         forwarder.onMessage(TEXT, sco);
132
133         verify(listener1, times(2)).accept(TEXT, sco);
134         verify(listener1b, times(2)).accept(TEXT, sco);
135
136         // should not have been invoked
137         verify(listener2, never()).accept(any(), any());
138         verify(listener3, never()).accept(any(), any());
139
140         // try other listeners now
141         sco = makeMessage(Map.of(KEY1, VALUEB_REQID, KEY2, Map.of(SUBKEY, VALUEB_SUBREQID)));
142         forwarder.onMessage(TEXT, sco);
143         verify(listener2).accept(TEXT, sco);
144
145         sco = makeMessage(Map.of(KEY1, VALUEC_REQID, KEY2, Map.of(SUBKEY, VALUEC_SUBREQID)));
146         forwarder.onMessage(TEXT, sco);
147         verify(listener3).accept(TEXT, sco);
148
149         // message has no listeners
150         sco = makeMessage(Map.of(KEY1, "xyzzy", KEY2, Map.of(SUBKEY, VALUEB_SUBREQID)));
151         forwarder.onMessage(TEXT, sco);
152
153         // message doesn't have both keys
154         sco = makeMessage(Map.of(KEY1, VALUEA_REQID));
155         forwarder.onMessage(TEXT, sco);
156
157         // counts should not have incremented
158         verify(listener1, times(2)).accept(any(), any());
159         verify(listener1b, times(2)).accept(any(), any());
160         verify(listener2).accept(any(), any());
161         verify(listener3).accept(any(), any());
162
163         // listener throws an exception
164         doThrow(new IllegalStateException("expected exception")).when(listener1).accept(any(), any());
165     }
166
167     /*
168      * Tests onMessage() when listener1 throws an exception.
169      */
170     @Test
171     public void testOnMessageListenerException1() {
172         doThrow(new IllegalStateException("expected exception")).when(listener1).accept(any(), any());
173
174         StandardCoderObject sco = makeMessage(Map.of(KEY1, VALUEA_REQID, KEY2, Map.of(SUBKEY, VALUEA_SUBREQID)));
175         forwarder.onMessage(TEXT, sco);
176
177         verify(listener1b).accept(TEXT, sco);
178     }
179
180     /*
181      * Tests onMessage() when listener1b throws an exception.
182      */
183     @Test
184     public void testOnMessageListenerException1b() {
185         doThrow(new IllegalStateException("expected exception")).when(listener1b).accept(any(), any());
186
187         StandardCoderObject sco = makeMessage(Map.of(KEY1, VALUEA_REQID, KEY2, Map.of(SUBKEY, VALUEA_SUBREQID)));
188         forwarder.onMessage(TEXT, sco);
189
190         verify(listener1).accept(TEXT, sco);
191     }
192
193     /**
194      * Makes a message from a map.
195      */
196     private StandardCoderObject makeMessage(Map<String, Object> map) {
197         return Util.translate("", map, StandardCoderObject.class);
198     }
199 }