4c87e0875633e27e0a877a3a8b2eace61239901f
[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.policy.main.utils;
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.policy.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
86             clElement.setDefinition(clElementParticipantId);
87             clElement.setState(ControlLoopState.UNINITIALISED);
88             clElement.setDescription(toscaInputEntry.getValue().getDescription());
89             clElement.setOrderedState(ControlLoopOrderedState.UNINITIALISED);
90             elements.put(clElement.getId(), clElement);
91         }
92         controlLoop.setElements(elements);
93         controlLoop.setName("PMSHInstance0");
94         controlLoop.setVersion("1.0.0");
95
96         ToscaConceptIdentifier definition = new ToscaConceptIdentifier();
97         definition.setName("PMSHInstance0");
98         definition.setVersion("1.0.0");
99         controlLoop.setDefinition(definition);
100
101         return controlLoop;
102     }
103
104     /**
105      * Method to create ControlLoopStateChange message from the arguments passed.
106      *
107      * @param controlLoopOrderedState controlLoopOrderedState
108      *
109      * @return ControlLoopStateChange message
110      */
111     public static ControlLoopStateChange createControlLoopStateChangeMsg(
112             final ControlLoopOrderedState controlLoopOrderedState) {
113         final ControlLoopStateChange clStateChangeMsg = new ControlLoopStateChange();
114
115         ToscaConceptIdentifier controlLoopId = new ToscaConceptIdentifier();
116         controlLoopId.setName("PMSHInstance0");
117         controlLoopId.setVersion("1.0.0");
118
119         ToscaConceptIdentifier participantId = new ToscaConceptIdentifier();
120         participantId.setName("org.onap.PM_Policy");
121         participantId.setVersion("0.0.0");
122
123         clStateChangeMsg.setControlLoopId(controlLoopId);
124         clStateChangeMsg.setParticipantId(participantId);
125         clStateChangeMsg.setTimestamp(Instant.now());
126         clStateChangeMsg.setOrderedState(controlLoopOrderedState);
127
128         return clStateChangeMsg;
129     }
130
131     /**
132      * Method to create ControlLoopUpdateMsg.
133      *
134      * @return ControlLoopUpdate message
135      */
136     public static ControlLoopUpdate createControlLoopUpdateMsg() {
137         final ControlLoopUpdate clUpdateMsg = new ControlLoopUpdate();
138         ToscaConceptIdentifier controlLoopId =
139             new ToscaConceptIdentifier("PMSHInstance0", "1.0.0");
140         ToscaConceptIdentifier participantId =
141             new ToscaConceptIdentifier("org.onap.PM_Policy", "0.0.0");
142
143         clUpdateMsg.setControlLoopId(controlLoopId);
144         clUpdateMsg.setParticipantId(participantId);
145         clUpdateMsg.setMessageId(UUID.randomUUID());
146         clUpdateMsg.setTimestamp(Instant.now());
147
148         Map<UUID, ControlLoopElement> elements = new LinkedHashMap<>();
149         ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead();
150         Map<String, ToscaNodeTemplate> nodeTemplatesMap =
151                 toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates();
152         for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry : nodeTemplatesMap.entrySet()) {
153             if (toscaInputEntry.getValue().getType().contains(CONTROL_LOOP_ELEMENT)) {
154                 ControlLoopElement clElement = new ControlLoopElement();
155                 clElement.setId(UUID.randomUUID());
156                 ToscaConceptIdentifier clParticipantId;
157                 try {
158                     clParticipantId = CODER.decode(
159                             toscaInputEntry.getValue().getProperties().get("participant_id").toString(),
160                             ToscaConceptIdentifier.class);
161                 } catch (CoderException e) {
162                     throw new RuntimeException("cannot get ParticipantId from toscaNodeTemplate", e);
163                 }
164
165                 clElement.setParticipantId(clParticipantId);
166                 clElement.setParticipantType(clParticipantId);
167
168                 clElement.setDefinition(new ToscaConceptIdentifier(toscaInputEntry.getKey(),
169                     toscaInputEntry.getValue().getVersion()));
170                 clElement.setState(ControlLoopState.UNINITIALISED);
171                 clElement.setDescription(toscaInputEntry.getValue().getDescription());
172                 clElement.setOrderedState(ControlLoopOrderedState.PASSIVE);
173                 elements.put(clElement.getId(), clElement);
174             }
175         }
176
177         List<ParticipantUpdates> participantUpdates = new ArrayList<>();
178         for (ControlLoopElement element : elements.values()) {
179             prepareParticipantUpdateForControlLoop(element, participantUpdates);
180         }
181         clUpdateMsg.setParticipantUpdatesList(participantUpdates);
182         return clUpdateMsg;
183     }
184
185     private static void prepareParticipantUpdateForControlLoop(ControlLoopElement clElement,
186         List<ParticipantUpdates> participantUpdates) {
187         if (participantUpdates.isEmpty()) {
188             participantUpdates.add(getControlLoopElementList(clElement));
189         } else {
190             boolean participantExists = false;
191             for (ParticipantUpdates participantUpdate : participantUpdates) {
192                 if (participantUpdate.getParticipantId().equals(clElement.getParticipantId())) {
193                     participantUpdate.getControlLoopElementList().add(clElement);
194                     participantExists = true;
195                 }
196             }
197             if (!participantExists) {
198                 participantUpdates.add(getControlLoopElementList(clElement));
199             }
200         }
201     }
202
203     private static ParticipantUpdates getControlLoopElementList(ControlLoopElement clElement) {
204         ParticipantUpdates participantUpdate = new ParticipantUpdates();
205         List<ControlLoopElement> controlLoopElementList = new ArrayList<>();
206         participantUpdate.setParticipantId(clElement.getParticipantId());
207         controlLoopElementList.add(clElement);
208         participantUpdate.setControlLoopElementList(controlLoopElementList);
209         return participantUpdate;
210     }
211
212     /**
213      * Method to create participantUpdateMsg.
214      *
215      * @return ParticipantUpdate message
216      */
217     public static ParticipantUpdate createParticipantUpdateMsg() {
218         final ParticipantUpdate participantUpdateMsg = new ParticipantUpdate();
219         ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_Policy", "1.0.0");
220         ToscaConceptIdentifier participantType = new ToscaConceptIdentifier(
221                 "org.onap.policy.controlloop.PolicyControlLoopParticipant", "2.3.1");
222
223         participantUpdateMsg.setParticipantId(participantId);
224         participantUpdateMsg.setTimestamp(Instant.now());
225         participantUpdateMsg.setParticipantType(participantType);
226         participantUpdateMsg.setTimestamp(Instant.ofEpochMilli(3000));
227         participantUpdateMsg.setMessageId(UUID.randomUUID());
228
229         ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead();
230         // Add policies to the toscaServiceTemplate
231         TestListenerUtils.addPoliciesToToscaServiceTemplate(toscaServiceTemplate);
232
233         List<ParticipantDefinition> participantDefinitionUpdates = new ArrayList<>();
234         for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry :
235             toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().entrySet()) {
236             if (toscaInputEntry.getValue().getType().contains(CONTROL_LOOP_ELEMENT)) {
237                 ToscaConceptIdentifier clParticipantId;
238                 try {
239                     clParticipantId = CODER.decode(
240                             toscaInputEntry.getValue().getProperties().get("participant_id").toString(),
241                             ToscaConceptIdentifier.class);
242                 } catch (CoderException e) {
243                     throw new RuntimeException("cannot get ParticipantId from toscaNodeTemplate", e);
244                 }
245                 prepareParticipantDefinitionUpdate(clParticipantId, toscaInputEntry.getKey(),
246                     toscaInputEntry.getValue(), participantDefinitionUpdates);
247             }
248         }
249
250         participantUpdateMsg.setParticipantDefinitionUpdates(participantDefinitionUpdates);
251         participantUpdateMsg.setToscaServiceTemplate(toscaServiceTemplate);
252         return participantUpdateMsg;
253     }
254
255     private static void prepareParticipantDefinitionUpdate(ToscaConceptIdentifier clParticipantId, String entryKey,
256         ToscaNodeTemplate entryValue, List<ParticipantDefinition> participantDefinitionUpdates) {
257
258         var clDefinition = new ControlLoopElementDefinition();
259         clDefinition.setClElementDefinitionId(new ToscaConceptIdentifier(
260             entryKey, entryValue.getVersion()));
261         clDefinition.setControlLoopElementToscaNodeTemplate(entryValue);
262         List<ControlLoopElementDefinition> controlLoopElementDefinitionList = new ArrayList<>();
263
264         if (participantDefinitionUpdates.isEmpty()) {
265             participantDefinitionUpdates.add(getParticipantDefinition(clDefinition, clParticipantId,
266                 controlLoopElementDefinitionList));
267         } else {
268             boolean participantExists = false;
269             for (ParticipantDefinition participantDefinitionUpdate : participantDefinitionUpdates) {
270                 if (participantDefinitionUpdate.getParticipantId().equals(clParticipantId)) {
271                     participantDefinitionUpdate.getControlLoopElementDefinitionList().add(clDefinition);
272                     participantExists = true;
273                 }
274             }
275             if (!participantExists) {
276                 participantDefinitionUpdates.add(getParticipantDefinition(clDefinition, clParticipantId,
277                     controlLoopElementDefinitionList));
278             }
279         }
280     }
281
282     private static ParticipantDefinition getParticipantDefinition(ControlLoopElementDefinition clDefinition,
283         ToscaConceptIdentifier clParticipantId,
284         List<ControlLoopElementDefinition> controlLoopElementDefinitionList) {
285         ParticipantDefinition participantDefinition = new ParticipantDefinition();
286         participantDefinition.setParticipantId(clParticipantId);
287         controlLoopElementDefinitionList.add(clDefinition);
288         participantDefinition.setControlLoopElementDefinitionList(controlLoopElementDefinitionList);
289         return participantDefinition;
290     }
291
292     /**
293      * Method to create ControlLoopUpdate using the arguments passed.
294      *
295      * @param jsonFilePath the path of the controlloop content
296      *
297      * @return ControlLoopUpdate message
298      * @throws CoderException exception while reading the file to object
299      */
300     public static ControlLoopUpdate createParticipantClUpdateMsgFromJson(String jsonFilePath) throws CoderException {
301         ControlLoopUpdate controlLoopUpdateMsg = CODER.decode(new File(jsonFilePath), ControlLoopUpdate.class);
302         return controlLoopUpdateMsg;
303     }
304
305     private static ToscaServiceTemplate testControlLoopRead() {
306         Set<String> controlLoopDirectoryContents =
307                 ResourceUtils.getDirectoryContents("src/test/resources/utils/servicetemplates");
308
309         boolean atLeastOneControlLoopTested = false;
310         ToscaServiceTemplate toscaServiceTemplate = null;
311
312         for (String controlLoopFilePath : controlLoopDirectoryContents) {
313             if (!controlLoopFilePath.endsWith(".yaml")) {
314                 continue;
315             }
316             atLeastOneControlLoopTested = true;
317             toscaServiceTemplate = testControlLoopYamlSerialization(controlLoopFilePath);
318         }
319
320         // Add policy_types to the toscaServiceTemplate
321         addPolicyTypesToToscaServiceTemplate(toscaServiceTemplate);
322
323         assertTrue(atLeastOneControlLoopTested);
324         return toscaServiceTemplate;
325     }
326
327     private static void addPolicyTypesToToscaServiceTemplate(
328             ToscaServiceTemplate toscaServiceTemplate) {
329         Set<String> policyTypeDirectoryContents = ResourceUtils.getDirectoryContents("policytypes");
330
331         for (String policyTypeFilePath : policyTypeDirectoryContents) {
332             String policyTypeString = ResourceUtils.getResourceAsString(policyTypeFilePath);
333
334             ToscaServiceTemplate foundPolicyTypeSt =
335                     yamlTranslator.fromYaml(policyTypeString, ToscaServiceTemplate.class);
336
337             toscaServiceTemplate.setDerivedFrom(foundPolicyTypeSt.getDerivedFrom());
338             toscaServiceTemplate.setDescription(foundPolicyTypeSt.getDescription());
339             toscaServiceTemplate.setMetadata(foundPolicyTypeSt.getMetadata());
340             toscaServiceTemplate.setName(foundPolicyTypeSt.getName());
341             toscaServiceTemplate.setToscaDefinitionsVersion(foundPolicyTypeSt.getToscaDefinitionsVersion());
342             toscaServiceTemplate.setVersion(foundPolicyTypeSt.getVersion());
343
344             if (foundPolicyTypeSt.getDataTypes() != null) {
345                 if (toscaServiceTemplate.getDataTypes() == null) {
346                     toscaServiceTemplate.setDataTypes(foundPolicyTypeSt.getDataTypes());
347                 } else {
348                     toscaServiceTemplate.getDataTypes().putAll(foundPolicyTypeSt.getDataTypes());
349                 }
350             }
351
352             if (toscaServiceTemplate.getPolicyTypes() == null) {
353                 toscaServiceTemplate.setPolicyTypes(foundPolicyTypeSt.getPolicyTypes());
354             } else {
355                 toscaServiceTemplate.getPolicyTypes().putAll(foundPolicyTypeSt.getPolicyTypes());
356             }
357         }
358     }
359
360     /**
361      * Method to add polcies to the toscaServiceTemplate.
362      *
363      * @param toscaServiceTemplate to add policies
364      */
365     public static void addPoliciesToToscaServiceTemplate(ToscaServiceTemplate toscaServiceTemplate) {
366         Set<String> policiesDirectoryContents = ResourceUtils.getDirectoryContents("policies");
367
368         for (String policiesFilePath : policiesDirectoryContents) {
369             String policiesString = ResourceUtils.getResourceAsString(policiesFilePath);
370
371             ToscaServiceTemplate foundPoliciesSt =
372                     yamlTranslator.fromYaml(policiesString, ToscaServiceTemplate.class);
373             toscaServiceTemplate.getToscaTopologyTemplate().setPolicies(
374                     foundPoliciesSt.getToscaTopologyTemplate().getPolicies());
375         }
376     }
377
378     private static ToscaServiceTemplate testControlLoopYamlSerialization(String controlLoopFilePath) {
379         try {
380             String controlLoopString = ResourceUtils.getResourceAsString(controlLoopFilePath);
381             if (controlLoopString == null) {
382                 throw new FileNotFoundException(controlLoopFilePath);
383             }
384
385             ToscaServiceTemplate serviceTemplate = yamlTranslator.fromYaml(
386                     controlLoopString, ToscaServiceTemplate.class);
387             return serviceTemplate;
388         } catch (FileNotFoundException e) {
389             LOGGER.error("cannot find YAML file", controlLoopFilePath);
390             throw new IllegalArgumentException(e);
391         }
392     }
393 }