2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2020-2021 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.common.rules.test;
23 import java.io.FileNotFoundException;
24 import java.io.IOException;
25 import java.util.LinkedList;
26 import java.util.List;
27 import java.util.function.Function;
28 import org.onap.policy.common.endpoints.event.comm.TopicEndpoint;
29 import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager;
30 import org.onap.policy.common.utils.coder.Coder;
31 import org.onap.policy.common.utils.coder.CoderException;
32 import org.onap.policy.common.utils.resources.ResourceUtils;
33 import org.onap.policy.drools.protocol.coders.EventProtocolCoder;
34 import org.onap.policy.drools.protocol.coders.EventProtocolCoderConstants;
35 import org.onap.policy.drools.system.PolicyController;
38 * Mechanism by which junit tests can manage topic messages.
42 * Wherever this string appears within an input file, it is replaced by a value passed
43 * as a parameter to the {@link #inject(String, String, String)} method.
45 private static final String REPLACE_ME = "${replaceMe}";
48 * Listeners that have been created and registered by "this" object.
50 private final List<Listener<?>> listeners = new LinkedList<>();
53 * Unregisters all of the listeners.
55 public void destroy() {
56 listeners.forEach(Listener::unregister);
60 * Injects the content of the given file onto a NOOP topic SOURCE.
62 * @param topicName topic on which to inject
63 * @param file file whose content is to be injected
65 public void inject(String topicName, String file) {
66 inject(topicName, file, REPLACE_ME);
70 * Injects the content of the given file onto a NOOP topic SOURCE, with the given
73 * @param topicName topic on which to inject
74 * @param file file whose content is to be injected
75 * @param newText text to be substituted for occurrences of "${replaceMe}" in the
78 public void inject(String topicName, String file, String newText) {
80 var text = ResourceUtils.getResourceAsString(file);
82 throw new FileNotFoundException(file);
84 text = text.replace(REPLACE_ME, newText);
85 getTopicManager().getNoopTopicSource(topicName).offer(text);
86 } catch (IOException e) {
87 throw new TopicException(e);
92 * Creates a listener for messages published on a NOOP topic SINK. Messages are
93 * decoded using the coder associated with the controller.
95 * @param <T> message type
96 * @param topicName name of the topic on which to listen
97 * @param expectedClass type of message expected
98 * @param controller controller whose decoders are to be used
99 * @return a new listener
101 public <T> Listener<T> createListener(String topicName, Class<T> expectedClass, PolicyController controller) {
102 EventProtocolCoder mgr = getProtocolCoder();
103 String groupId = controller.getDrools().getGroupId();
104 String artifactId = controller.getDrools().getArtifactId();
107 return createListener(topicName,
108 event -> expectedClass.cast(mgr.decode(groupId, artifactId, topicName, event)));
113 * Creates a listener for messages published on a NOOP topic SINK. Messages are
114 * decoded using the specified coder.
116 * @param <T> message type
117 * @param topicName name of the topic on which to listen
118 * @param expectedClass type of message expected
119 * @param coder coder to decode the messages
120 * @return a new listener
122 public <T> Listener<T> createListener(String topicName, Class<T> expectedClass, Coder coder) {
123 Function<String, T> decoder = event -> {
125 return coder.decode(event, expectedClass);
126 } catch (CoderException e) {
127 throw new IllegalArgumentException("cannot decode message", e);
131 return createListener(topicName, decoder);
135 * Creates a listener for messages published on a NOOP topic SINK. Messages are
136 * decoded using the specified decoder.
138 * @param <T> message type
139 * @param topicName name of the topic on which to listen
140 * @param decoder function that takes a message and decodes it into the desired type
141 * @return a new listener
143 public <T> Listener<T> createListener(String topicName, Function<String, T> decoder) {
144 Listener<T> listener = makeListener(topicName, decoder);
145 listeners.add(listener);
150 // these methods may be overridden by junit tests
152 protected TopicEndpoint getTopicManager() {
153 return TopicEndpointManager.getManager();
156 protected EventProtocolCoder getProtocolCoder() {
157 return EventProtocolCoderConstants.getManager();
160 protected <T> Listener<T> makeListener(String topicName, Function<String, T> decoder) {
161 return new Listener<>(topicName, decoder) {
163 protected TopicEndpoint getTopicManager() {
164 return Topics.this.getTopicManager();