f71559acb870c68d28bad18ebf3e2509b22010fd
[policy/drools-applications.git] /
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.common.rules.test;
22
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;
36
37 /**
38  * Mechanism by which junit tests can manage topic messages.
39  */
40 public class Topics {
41     /**
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.
44      */
45     private static final String REPLACE_ME = "${replaceMe}";
46
47     /**
48      * Listeners that have been created and registered by "this" object.
49      */
50     private final List<Listener<?>> listeners = new LinkedList<>();
51
52
53     /**
54      * Constructs the object.
55      */
56     public Topics() {
57         super();
58     }
59
60     /**
61      * Unregisters all of the listeners.
62      */
63     public void destroy() {
64         listeners.forEach(Listener::unregister);
65     }
66
67     /**
68      * Injects the content of the given file onto a NOOP topic SOURCE.
69      *
70      * @param topicName topic on which to inject
71      * @param file file whose content is to be injected
72      */
73     public void inject(String topicName, String file) {
74         inject(topicName, file, REPLACE_ME);
75     }
76
77     /**
78      * Injects the content of the given file onto a NOOP topic SOURCE, with the given
79      * substitution.
80      *
81      * @param topicName topic on which to inject
82      * @param file file whose content is to be injected
83      * @param newText text to be substituted for occurrences of "${replaceMe}" in the
84      *        source file
85      */
86     public void inject(String topicName, String file, String newText) {
87         try {
88             String text = ResourceUtils.getResourceAsString(file);
89             if (text == null) {
90                 throw new FileNotFoundException(file);
91             }
92             text = text.replace(REPLACE_ME, newText);
93             getTopicManager().getNoopTopicSource(topicName).offer(text);
94         } catch (IOException e) {
95             throw new TopicException(e);
96         }
97     }
98
99     /**
100      * Creates a listener for messages published on a NOOP topic SINK. Messages are
101      * decoded using the coder associated with the controller.
102      *
103      * @param <T> message type
104      * @param topicName name of the topic on which to listen
105      * @param expectedClass type of message expected
106      * @param controller controller whose decoders are to be used
107      * @return a new listener
108      */
109     public <T> Listener<T> createListener(String topicName, Class<T> expectedClass, PolicyController controller) {
110         EventProtocolCoder mgr = getProtocolCoder();
111         String groupId = controller.getDrools().getGroupId();
112         String artifactId = controller.getDrools().getArtifactId();
113
114         // @formatter:off
115         return createListener(topicName,
116             event -> expectedClass.cast(mgr.decode(groupId, artifactId, topicName, event)));
117         // @formatter:on
118     }
119
120     /**
121      * Creates a listener for messages published on a NOOP topic SINK. Messages are
122      * decoded using the specified coder.
123      *
124      * @param <T> message type
125      * @param topicName name of the topic on which to listen
126      * @param expectedClass type of message expected
127      * @param coder coder to decode the messages
128      * @return a new listener
129      */
130     public <T> Listener<T> createListener(String topicName, Class<T> expectedClass, Coder coder) {
131         Function<String, T> decoder = event -> {
132             try {
133                 return coder.decode(event, expectedClass);
134             } catch (CoderException e) {
135                 throw new IllegalArgumentException("cannot decode message", e);
136             }
137         };
138
139         return createListener(topicName, decoder);
140     }
141
142     /**
143      * Creates a listener for messages published on a NOOP topic SINK. Messages are
144      * decoded using the specified decoder.
145      *
146      * @param <T> message type
147      * @param topicName name of the topic on which to listen
148      * @param decoder function that takes a message and decodes it into the desired type
149      * @return a new listener
150      */
151     public <T> Listener<T> createListener(String topicName, Function<String, T> decoder) {
152         Listener<T> listener = makeListener(topicName, decoder);
153         listeners.add(listener);
154
155         return listener;
156     }
157
158     // these methods may be overridden by junit tests
159
160     protected TopicEndpoint getTopicManager() {
161         return TopicEndpointManager.getManager();
162     }
163
164     protected EventProtocolCoder getProtocolCoder() {
165         return EventProtocolCoderConstants.getManager();
166     }
167
168     protected <T> Listener<T> makeListener(String topicName, Function<String, T> decoder) {
169         return new Listener<>(topicName, decoder) {
170             @Override
171             protected TopicEndpoint getTopicManager() {
172                 return Topics.this.getTopicManager();
173             }
174         };
175     }
176 }