2  * ============LICENSE_START=======================================================
 
   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
 
  11  *      http://www.apache.org/licenses/LICENSE-2.0
 
  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=========================================================
 
  21 package org.onap.policy.controlloop.actorserviceprovider.topic;
 
  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;
 
  30 import java.util.Arrays;
 
  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;
 
  40 public class ForwarderTest {
 
  41     private static final String TEXT = "some text";
 
  43     private static final String KEY1 = "requestId";
 
  44     private static final String KEY2 = "container";
 
  45     private static final String SUBKEY = "subRequestId";
 
  47     private static final String VALUEA_REQID = "hello";
 
  48     private static final String VALUEA_SUBREQID = "world";
 
  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";
 
  55     private static final String VALUEC_REQID = "bye";
 
  56     private static final String VALUEC_SUBREQID = "bye-bye";
 
  59     private BiConsumer<String, StandardCoderObject> listener1;
 
  62     private BiConsumer<String, StandardCoderObject> listener1b;
 
  65     private BiConsumer<String, StandardCoderObject> listener2;
 
  68     private BiConsumer<String, StandardCoderObject> listener3;
 
  70     private Forwarder forwarder;
 
  78         MockitoAnnotations.initMocks(this);
 
  79         forwarder = new Forwarder(Arrays.asList(new SelectorKey(KEY1), new SelectorKey(KEY2, SUBKEY)));
 
  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);
 
  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");
 
  98     public void testUnregister() {
 
 100         forwarder.unregister(Arrays.asList(VALUEA_REQID, VALUEA_SUBREQID), listener1b);
 
 102         StandardCoderObject sco = makeMessage(Map.of(KEY1, VALUEA_REQID, KEY2, Map.of(SUBKEY, VALUEA_SUBREQID)));
 
 103         forwarder.onMessage(TEXT, sco);
 
 105         verify(listener1).accept(TEXT, sco);
 
 106         verify(listener1b, never()).accept(any(), any());
 
 109         forwarder.unregister(Arrays.asList(VALUEA_REQID, VALUEA_SUBREQID), listener1);
 
 110         forwarder.onMessage(TEXT, sco);
 
 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);
 
 117         // no more messages to listener1 or 1b
 
 118         verify(listener1).accept(any(), any());
 
 119         verify(listener1b, never()).accept(any(), any());
 
 123     public void testOnMessage() {
 
 124         StandardCoderObject sco = makeMessage(Map.of(KEY1, VALUEA_REQID, KEY2, Map.of(SUBKEY, VALUEA_SUBREQID)));
 
 125         forwarder.onMessage(TEXT, sco);
 
 127         verify(listener1).accept(TEXT, sco);
 
 128         verify(listener1b).accept(TEXT, sco);
 
 130         // repeat - counts should increment
 
 131         forwarder.onMessage(TEXT, sco);
 
 133         verify(listener1, times(2)).accept(TEXT, sco);
 
 134         verify(listener1b, times(2)).accept(TEXT, sco);
 
 136         // should not have been invoked
 
 137         verify(listener2, never()).accept(any(), any());
 
 138         verify(listener3, never()).accept(any(), any());
 
 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);
 
 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);
 
 149         // message has no listeners
 
 150         sco = makeMessage(Map.of(KEY1, "xyzzy", KEY2, Map.of(SUBKEY, VALUEB_SUBREQID)));
 
 151         forwarder.onMessage(TEXT, sco);
 
 153         // message doesn't have both keys
 
 154         sco = makeMessage(Map.of(KEY1, VALUEA_REQID));
 
 155         forwarder.onMessage(TEXT, sco);
 
 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());
 
 163         // listener throws an exception
 
 164         doThrow(new IllegalStateException("expected exception")).when(listener1).accept(any(), any());
 
 168      * Tests onMessage() when listener1 throws an exception.
 
 171     public void testOnMessageListenerException1() {
 
 172         doThrow(new IllegalStateException("expected exception")).when(listener1).accept(any(), any());
 
 174         StandardCoderObject sco = makeMessage(Map.of(KEY1, VALUEA_REQID, KEY2, Map.of(SUBKEY, VALUEA_SUBREQID)));
 
 175         forwarder.onMessage(TEXT, sco);
 
 177         verify(listener1b).accept(TEXT, sco);
 
 181      * Tests onMessage() when listener1b throws an exception.
 
 184     public void testOnMessageListenerException1b() {
 
 185         doThrow(new IllegalStateException("expected exception")).when(listener1b).accept(any(), any());
 
 187         StandardCoderObject sco = makeMessage(Map.of(KEY1, VALUEA_REQID, KEY2, Map.of(SUBKEY, VALUEA_SUBREQID)));
 
 188         forwarder.onMessage(TEXT, sco);
 
 190         verify(listener1).accept(TEXT, sco);
 
 194      * Makes a message from a map.
 
 196     private StandardCoderObject makeMessage(Map<String, Object> map) {
 
 197         return Util.translate("", map, StandardCoderObject.class);