56be0817f44057b41073342b1530639f4f0f35f5
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Nordix Foundation.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.clamp.controlloop.participant.simulator.main.rest;
22
23 import static org.junit.Assert.assertTrue;
24
25 import java.io.File;
26 import java.io.FileNotFoundException;
27 import java.time.Instant;
28 import java.util.ArrayList;
29 import java.util.LinkedHashMap;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Set;
33 import java.util.UUID;
34 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
35 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement;
36 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElementDefinition;
37 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
38 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
39 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantDefinition;
40 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUpdates;
41 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopStateChange;
42 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopUpdate;
43 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate;
44 import org.onap.policy.clamp.controlloop.participant.simulator.main.parameters.CommonTestData;
45 import org.onap.policy.common.utils.coder.Coder;
46 import org.onap.policy.common.utils.coder.CoderException;
47 import org.onap.policy.common.utils.coder.StandardCoder;
48 import org.onap.policy.common.utils.coder.YamlJsonTranslator;
49 import org.onap.policy.common.utils.resources.ResourceUtils;
50 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
51 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
52 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
55
56 public class TestListenerUtils {
57
58     private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator();
59     private static final Coder CODER = new StandardCoder();
60     static CommonTestData commonTestData = new CommonTestData();
61     private static final Logger LOGGER = LoggerFactory.getLogger(TestListenerUtils.class);
62     private static final String CONTROL_LOOP_ELEMENT = "org.onap.policy.clamp.controlloop.ControlLoopElement";
63
64     private TestListenerUtils() {}
65
66     /**
67      * Method to create a controlLoop from a yaml file.
68      *
69      * @return ControlLoop controlloop
70      */
71     public static ControlLoop createControlLoop() {
72         ControlLoop controlLoop = new ControlLoop();
73         Map<UUID, ControlLoopElement> elements = new LinkedHashMap<>();
74         ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead();
75         Map<String, ToscaNodeTemplate> nodeTemplatesMap =
76                 toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates();
77         for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry : nodeTemplatesMap.entrySet()) {
78             ControlLoopElement clElement = new ControlLoopElement();
79             clElement.setId(UUID.randomUUID());
80
81             ToscaConceptIdentifier clElementParticipantId = new ToscaConceptIdentifier();
82             clElementParticipantId.setName(toscaInputEntry.getKey());
83             clElementParticipantId.setVersion(toscaInputEntry.getValue().getVersion());
84             clElement.setParticipantId(clElementParticipantId);
85             clElement.setParticipantType(clElementParticipantId);
86
87             clElement.setDefinition(clElementParticipantId);
88             clElement.setState(ControlLoopState.UNINITIALISED);
89             clElement.setDescription(toscaInputEntry.getValue().getDescription());
90             clElement.setOrderedState(ControlLoopOrderedState.UNINITIALISED);
91             elements.put(clElement.getId(), clElement);
92         }
93         controlLoop.setElements(elements);
94         controlLoop.setName("PMSHInstance0");
95         controlLoop.setVersion("1.0.0");
96
97         ToscaConceptIdentifier definition = new ToscaConceptIdentifier();
98         definition.setName("PMSHInstance0");
99         definition.setVersion("1.0.0");
100         controlLoop.setDefinition(definition);
101
102         return controlLoop;
103     }
104
105     /**
106      * Method to create ControlLoopStateChange message from the arguments passed.
107      *
108      * @param controlLoopOrderedState controlLoopOrderedState
109      *
110      * @return ControlLoopStateChange message
111      */
112     public static ControlLoopStateChange createControlLoopStateChangeMsg(
113             final ControlLoopOrderedState controlLoopOrderedState) {
114         final ControlLoopStateChange clStateChangeMsg = new ControlLoopStateChange();
115
116         ToscaConceptIdentifier controlLoopId = new ToscaConceptIdentifier("PMSHInstance0", "1.0.0");
117         ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_CDS_Blueprint", "1.0.0");
118
119         clStateChangeMsg.setControlLoopId(controlLoopId);
120         clStateChangeMsg.setParticipantId(participantId);
121         clStateChangeMsg.setTimestamp(Instant.now());
122         clStateChangeMsg.setOrderedState(controlLoopOrderedState);
123
124         return clStateChangeMsg;
125     }
126
127     /**
128      * Method to create ControlLoopUpdateMsg.
129      *
130      * @return ControlLoopUpdate message
131      */
132     public static ControlLoopUpdate createControlLoopUpdateMsg() {
133         final ControlLoopUpdate clUpdateMsg = new ControlLoopUpdate();
134         ToscaConceptIdentifier controlLoopId =
135             new ToscaConceptIdentifier("PMSHInstance0", "1.0.0");
136         ToscaConceptIdentifier participantId =
137             new ToscaConceptIdentifier("org.onap.PM_Policy", "0.0.0");
138
139         clUpdateMsg.setControlLoopId(controlLoopId);
140         clUpdateMsg.setParticipantId(participantId);
141         clUpdateMsg.setMessageId(UUID.randomUUID());
142         clUpdateMsg.setTimestamp(Instant.now());
143
144         Map<UUID, ControlLoopElement> elements = new LinkedHashMap<>();
145         ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead();
146         Map<String, ToscaNodeTemplate> nodeTemplatesMap =
147                 toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates();
148         for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry : nodeTemplatesMap.entrySet()) {
149             if (toscaInputEntry.getValue().getType().contains(CONTROL_LOOP_ELEMENT)) {
150                 ControlLoopElement clElement = new ControlLoopElement();
151                 clElement.setId(UUID.randomUUID());
152                 ToscaConceptIdentifier clParticipantType;
153                 try {
154                     clParticipantType = CODER.decode(
155                             toscaInputEntry.getValue().getProperties().get("participantType").toString(),
156                             ToscaConceptIdentifier.class);
157                 } catch (CoderException e) {
158                     throw new RuntimeException("cannot get ParticipantType from toscaNodeTemplate", e);
159                 }
160
161                 clElement.setParticipantId(clParticipantType);
162                 clElement.setParticipantType(clParticipantType);
163
164                 clElement.setDefinition(new ToscaConceptIdentifier(toscaInputEntry.getKey(),
165                     toscaInputEntry.getValue().getVersion()));
166                 clElement.setState(ControlLoopState.UNINITIALISED);
167                 clElement.setDescription(toscaInputEntry.getValue().getDescription());
168                 clElement.setOrderedState(ControlLoopOrderedState.PASSIVE);
169                 elements.put(clElement.getId(), clElement);
170             }
171         }
172
173         List<ParticipantUpdates> participantUpdates = new ArrayList<>();
174         for (ControlLoopElement element : elements.values()) {
175             prepareParticipantUpdateForControlLoop(element, participantUpdates);
176         }
177         clUpdateMsg.setParticipantUpdatesList(participantUpdates);
178         return clUpdateMsg;
179     }
180
181     private static void prepareParticipantUpdateForControlLoop(ControlLoopElement clElement,
182         List<ParticipantUpdates> participantUpdates) {
183         if (participantUpdates.isEmpty()) {
184             participantUpdates.add(getControlLoopElementList(clElement));
185         } else {
186             boolean participantExists = false;
187             for (ParticipantUpdates participantUpdate : participantUpdates) {
188                 if (participantUpdate.getParticipantId().equals(clElement.getParticipantId())) {
189                     participantUpdate.getControlLoopElementList().add(clElement);
190                     participantExists = true;
191                 }
192             }
193             if (!participantExists) {
194                 participantUpdates.add(getControlLoopElementList(clElement));
195             }
196         }
197     }
198
199     private static ParticipantUpdates getControlLoopElementList(ControlLoopElement clElement) {
200         ParticipantUpdates participantUpdate = new ParticipantUpdates();
201         List<ControlLoopElement> controlLoopElementList = new ArrayList<>();
202         participantUpdate.setParticipantId(clElement.getParticipantId());
203         controlLoopElementList.add(clElement);
204         participantUpdate.setControlLoopElementList(controlLoopElementList);
205         return participantUpdate;
206     }
207
208     /**
209      * Method to create participantUpdateMsg.
210      *
211      * @return ParticipantUpdate message
212      */
213     public static ParticipantUpdate createParticipantUpdateMsg() {
214         final ParticipantUpdate participantUpdateMsg = new ParticipantUpdate();
215         ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_Policy", "1.0.0");
216         ToscaConceptIdentifier participantType = new ToscaConceptIdentifier(
217                 "org.onap.policy.controlloop.PolicyControlLoopParticipant", "2.3.1");
218
219         participantUpdateMsg.setParticipantId(participantId);
220         participantUpdateMsg.setTimestamp(Instant.now());
221         participantUpdateMsg.setParticipantType(participantType);
222         participantUpdateMsg.setTimestamp(Instant.ofEpochMilli(3000));
223         participantUpdateMsg.setMessageId(UUID.randomUUID());
224
225         ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead();
226         // Add policies to the toscaServiceTemplate
227
228         List<ParticipantDefinition> participantDefinitionUpdates = new ArrayList<>();
229         for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry :
230             toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().entrySet()) {
231             if (toscaInputEntry.getValue().getType().contains(CONTROL_LOOP_ELEMENT)) {
232                 ToscaConceptIdentifier clParticipantType;
233                 try {
234                     clParticipantType = CODER.decode(
235                             toscaInputEntry.getValue().getProperties().get("participantType").toString(),
236                             ToscaConceptIdentifier.class);
237                 } catch (CoderException e) {
238                     throw new RuntimeException("cannot get ParticipantType from toscaNodeTemplate", e);
239                 }
240                 prepareParticipantDefinitionUpdate(clParticipantType, toscaInputEntry.getKey(),
241                     toscaInputEntry.getValue(), participantDefinitionUpdates);
242             }
243         }
244
245         participantUpdateMsg.setParticipantDefinitionUpdates(participantDefinitionUpdates);
246         return participantUpdateMsg;
247     }
248
249     private static void prepareParticipantDefinitionUpdate(ToscaConceptIdentifier clParticipantType, String entryKey,
250         ToscaNodeTemplate entryValue, List<ParticipantDefinition> participantDefinitionUpdates) {
251
252         var clDefinition = new ControlLoopElementDefinition();
253         clDefinition.setClElementDefinitionId(new ToscaConceptIdentifier(
254             entryKey, entryValue.getVersion()));
255         clDefinition.setControlLoopElementToscaNodeTemplate(entryValue);
256         List<ControlLoopElementDefinition> controlLoopElementDefinitionList = new ArrayList<>();
257
258         if (participantDefinitionUpdates.isEmpty()) {
259             participantDefinitionUpdates.add(getParticipantDefinition(clDefinition, clParticipantType,
260                 controlLoopElementDefinitionList));
261         } else {
262             boolean participantExists = false;
263             for (ParticipantDefinition participantDefinitionUpdate : participantDefinitionUpdates) {
264                 if (participantDefinitionUpdate.getParticipantType().equals(clParticipantType)) {
265                     participantDefinitionUpdate.getControlLoopElementDefinitionList().add(clDefinition);
266                     participantExists = true;
267                 }
268             }
269             if (!participantExists) {
270                 participantDefinitionUpdates.add(getParticipantDefinition(clDefinition, clParticipantType,
271                     controlLoopElementDefinitionList));
272             }
273         }
274     }
275
276     private static ParticipantDefinition getParticipantDefinition(ControlLoopElementDefinition clDefinition,
277         ToscaConceptIdentifier clParticipantType,
278         List<ControlLoopElementDefinition> controlLoopElementDefinitionList) {
279         ParticipantDefinition participantDefinition = new ParticipantDefinition();
280         participantDefinition.setParticipantType(clParticipantType);
281         controlLoopElementDefinitionList.add(clDefinition);
282         participantDefinition.setControlLoopElementDefinitionList(controlLoopElementDefinitionList);
283         return participantDefinition;
284     }
285
286     /**
287      * Method to create ControlLoopUpdate using the arguments passed.
288      *
289      * @param jsonFilePath the path of the controlloop content
290      *
291      * @return ControlLoopUpdate message
292      * @throws CoderException exception while reading the file to object
293      */
294     public static ControlLoopUpdate createParticipantClUpdateMsgFromJson(String jsonFilePath)
295             throws CoderException {
296         ControlLoopUpdate controlLoopUpdateMsg =
297                 CODER.decode(new File(jsonFilePath), ControlLoopUpdate.class);
298         return controlLoopUpdateMsg;
299     }
300
301     private static ToscaServiceTemplate testControlLoopRead() {
302         Set<String> controlLoopDirectoryContents =
303                 ResourceUtils.getDirectoryContents("src/test/resources/rest/servicetemplates");
304
305         boolean atLeastOneControlLoopTested = false;
306         ToscaServiceTemplate toscaServiceTemplate = null;
307
308         for (String controlLoopFilePath : controlLoopDirectoryContents) {
309             if (!controlLoopFilePath.endsWith(".yaml")) {
310                 continue;
311             }
312             atLeastOneControlLoopTested = true;
313             toscaServiceTemplate = testControlLoopYamlSerialization(controlLoopFilePath);
314         }
315
316         assertTrue(atLeastOneControlLoopTested);
317         return toscaServiceTemplate;
318     }
319
320     private static ToscaServiceTemplate testControlLoopYamlSerialization(String controlLoopFilePath) {
321         try {
322             String controlLoopString = ResourceUtils.getResourceAsString(controlLoopFilePath);
323             if (controlLoopString == null) {
324                 throw new FileNotFoundException(controlLoopFilePath);
325             }
326
327             ToscaServiceTemplate serviceTemplate = yamlTranslator.fromYaml(
328                             controlLoopString, ToscaServiceTemplate.class);
329             return serviceTemplate;
330         } catch (FileNotFoundException e) {
331             LOGGER.error("cannot find YAML file", controlLoopFilePath);
332             throw new IllegalArgumentException(e);
333         }
334     }
335 }