df49f7c49410eadaf3908b1f12c30177f76bf08f
[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.dcae.main.rest;
22
23 import java.io.File;
24 import java.time.Instant;
25 import java.util.ArrayList;
26 import java.util.LinkedHashMap;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.UUID;
30 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
31 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement;
32 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElementDefinition;
33 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
34 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
35 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantDefinition;
36 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUpdates;
37 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopStateChange;
38 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopUpdate;
39 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate;
40 import org.onap.policy.common.utils.coder.Coder;
41 import org.onap.policy.common.utils.coder.CoderException;
42 import org.onap.policy.common.utils.coder.StandardCoder;
43 import org.onap.policy.common.utils.coder.YamlJsonTranslator;
44 import org.onap.policy.common.utils.resources.ResourceUtils;
45 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
46 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
47 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
48
49 public class TestListenerUtils {
50
51     private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator();
52     private static final Coder CODER = new StandardCoder();
53     private static final String TOSCA_TEMPLATE_YAML = "examples/controlloop/PMSubscriptionHandling.yaml";
54     private static final String CONTROL_LOOP_ELEMENT = "org.onap.policy.clamp.controlloop.ControlLoopElement";
55
56     /**
57      * Method to create a controlLoop from a yaml file.
58      *
59      * @return ControlLoop controlloop
60      */
61     public static ControlLoop createControlLoop() {
62         ControlLoop controlLoop = new ControlLoop();
63         Map<UUID, ControlLoopElement> elements = new LinkedHashMap<>();
64         ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead();
65         Map<String, ToscaNodeTemplate> nodeTemplatesMap =
66                 toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates();
67         for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry : nodeTemplatesMap.entrySet()) {
68             ControlLoopElement clElement = new ControlLoopElement();
69             clElement.setId(UUID.randomUUID());
70
71             ToscaConceptIdentifier clElementParticipantId = new ToscaConceptIdentifier();
72             clElementParticipantId.setName(toscaInputEntry.getKey());
73             clElementParticipantId.setVersion(toscaInputEntry.getValue().getVersion());
74             clElement.setParticipantId(clElementParticipantId);
75
76             clElement.setDefinition(clElementParticipantId);
77             clElement.setState(ControlLoopState.UNINITIALISED);
78             clElement.setDescription(toscaInputEntry.getValue().getDescription());
79             clElement.setOrderedState(ControlLoopOrderedState.UNINITIALISED);
80             elements.put(clElement.getId(), clElement);
81         }
82         controlLoop.setElements(elements);
83         controlLoop.setName("PMSHInstance0");
84         controlLoop.setVersion("1.0.0");
85
86         ToscaConceptIdentifier definition = new ToscaConceptIdentifier();
87         definition.setName("PMSHInstance0");
88         definition.setVersion("1.0.0");
89         controlLoop.setDefinition(definition);
90
91         return controlLoop;
92     }
93
94     /**
95      * Method to create ControlLoopStateChange message from the arguments passed.
96      *
97      * @param controlLoopOrderedState controlLoopOrderedState
98      *
99      * @return ControlLoopStateChange message
100      */
101     public static ControlLoopStateChange createControlLoopStateChangeMsg(
102             final ControlLoopOrderedState controlLoopOrderedState) {
103         final ControlLoopStateChange clStateChangeMsg = new ControlLoopStateChange();
104
105         ToscaConceptIdentifier controlLoopId = new ToscaConceptIdentifier();
106         controlLoopId.setName("PMSHInstance0");
107         controlLoopId.setVersion("1.0.0");
108
109         ToscaConceptIdentifier participantId = new ToscaConceptIdentifier();
110         participantId.setName("DCAEParticipant0");
111         participantId.setVersion("1.0.0");
112
113         clStateChangeMsg.setControlLoopId(controlLoopId);
114         clStateChangeMsg.setParticipantId(participantId);
115         clStateChangeMsg.setTimestamp(Instant.now());
116         clStateChangeMsg.setOrderedState(controlLoopOrderedState);
117
118         return clStateChangeMsg;
119     }
120
121     /**
122      * Method to create ControlLoopUpdateMsg.
123      *
124      * @return ControlLoopUpdate message
125      */
126     public static ControlLoopUpdate createControlLoopUpdateMsg() {
127         final ControlLoopUpdate clUpdateMsg = new ControlLoopUpdate();
128         ToscaConceptIdentifier controlLoopId =
129             new ToscaConceptIdentifier("PMSHInstance0", "1.0.0");
130         ToscaConceptIdentifier participantId =
131             new ToscaConceptIdentifier("org.onap.PM_Policy", "0.0.0");
132
133         clUpdateMsg.setControlLoopId(controlLoopId);
134         clUpdateMsg.setParticipantId(participantId);
135         clUpdateMsg.setMessageId(UUID.randomUUID());
136         clUpdateMsg.setTimestamp(Instant.now());
137
138         Map<UUID, ControlLoopElement> elements = new LinkedHashMap<>();
139         ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead();
140         Map<String, ToscaNodeTemplate> nodeTemplatesMap =
141                 toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates();
142         for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry : nodeTemplatesMap.entrySet()) {
143             if (checkIfNodeTemplateIsControlLoopElement(toscaInputEntry.getValue(), toscaServiceTemplate)) {
144                 ControlLoopElement clElement = new ControlLoopElement();
145                 clElement.setId(UUID.randomUUID());
146                 ToscaConceptIdentifier clParticipantType;
147                 try {
148                     clParticipantType = CODER.decode(
149                             toscaInputEntry.getValue().getProperties().get("participantType").toString(),
150                             ToscaConceptIdentifier.class);
151                 } catch (CoderException e) {
152                     throw new RuntimeException("cannot get ParticipantType from toscaNodeTemplate", e);
153                 }
154
155                 clElement.setParticipantId(clParticipantType);
156                 clElement.setParticipantType(clParticipantType);
157
158                 clElement.setDefinition(new ToscaConceptIdentifier(toscaInputEntry.getKey(),
159                     toscaInputEntry.getValue().getVersion()));
160                 clElement.setState(ControlLoopState.UNINITIALISED);
161                 clElement.setDescription(toscaInputEntry.getValue().getDescription());
162                 clElement.setOrderedState(ControlLoopOrderedState.PASSIVE);
163                 elements.put(clElement.getId(), clElement);
164             }
165         }
166
167         List<ParticipantUpdates> participantUpdates = new ArrayList<>();
168         for (ControlLoopElement element : elements.values()) {
169             prepareParticipantUpdateForControlLoop(element, participantUpdates);
170         }
171         clUpdateMsg.setParticipantUpdatesList(participantUpdates);
172         return clUpdateMsg;
173     }
174
175     private static boolean checkIfNodeTemplateIsControlLoopElement(ToscaNodeTemplate nodeTemplate,
176             ToscaServiceTemplate toscaServiceTemplate) {
177         if (nodeTemplate.getType().contains(CONTROL_LOOP_ELEMENT)) {
178             return true;
179         } else {
180             var nodeType = toscaServiceTemplate.getNodeTypes().get(nodeTemplate.getType());
181             if (nodeType != null) {
182                 var derivedFrom = nodeType.getDerivedFrom();
183                 if (derivedFrom != null) {
184                     return derivedFrom.contains(CONTROL_LOOP_ELEMENT) ? true : false;
185                 }
186             }
187         }
188         return false;
189     }
190
191     private static void prepareParticipantUpdateForControlLoop(ControlLoopElement clElement,
192         List<ParticipantUpdates> participantUpdates) {
193         if (participantUpdates.isEmpty()) {
194             participantUpdates.add(getControlLoopElementList(clElement));
195         } else {
196             boolean participantExists = false;
197             for (ParticipantUpdates participantUpdate : participantUpdates) {
198                 if (participantUpdate.getParticipantId().equals(clElement.getParticipantId())) {
199                     participantUpdate.getControlLoopElementList().add(clElement);
200                     participantExists = true;
201                 }
202             }
203             if (!participantExists) {
204                 participantUpdates.add(getControlLoopElementList(clElement));
205             }
206         }
207     }
208
209     private static ParticipantUpdates getControlLoopElementList(ControlLoopElement clElement) {
210         ParticipantUpdates participantUpdate = new ParticipantUpdates();
211         List<ControlLoopElement> controlLoopElementList = new ArrayList<>();
212         participantUpdate.setParticipantId(clElement.getParticipantId());
213         controlLoopElementList.add(clElement);
214         participantUpdate.setControlLoopElementList(controlLoopElementList);
215         return participantUpdate;
216     }
217
218     /**
219      * Method to create participantUpdateMsg.
220      *
221      * @return ParticipantUpdate message
222      */
223     public static ParticipantUpdate createParticipantUpdateMsg() {
224         final ParticipantUpdate participantUpdateMsg = new ParticipantUpdate();
225         ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_Policy", "1.0.0");
226         ToscaConceptIdentifier participantType = new ToscaConceptIdentifier(
227                 "org.onap.policy.controlloop.PolicyControlLoopParticipant", "2.3.1");
228
229         participantUpdateMsg.setParticipantId(participantId);
230         participantUpdateMsg.setTimestamp(Instant.now());
231         participantUpdateMsg.setParticipantType(participantType);
232         participantUpdateMsg.setTimestamp(Instant.ofEpochMilli(3000));
233         participantUpdateMsg.setMessageId(UUID.randomUUID());
234
235         ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead();
236
237         List<ParticipantDefinition> participantDefinitionUpdates = new ArrayList<>();
238         for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry :
239             toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().entrySet()) {
240             if (checkIfNodeTemplateIsControlLoopElement(toscaInputEntry.getValue(), toscaServiceTemplate)) {
241                 ToscaConceptIdentifier clParticipantType;
242                 try {
243                     clParticipantType = CODER.decode(
244                             toscaInputEntry.getValue().getProperties().get("participantType").toString(),
245                             ToscaConceptIdentifier.class);
246                 } catch (CoderException e) {
247                     throw new RuntimeException("cannot get ParticipantType from toscaNodeTemplate", e);
248                 }
249                 prepareParticipantDefinitionUpdate(clParticipantType, toscaInputEntry.getKey(),
250                     toscaInputEntry.getValue(), participantDefinitionUpdates);
251             }
252         }
253
254         participantUpdateMsg.setParticipantDefinitionUpdates(participantDefinitionUpdates);
255         return participantUpdateMsg;
256     }
257
258     private static void prepareParticipantDefinitionUpdate(ToscaConceptIdentifier clParticipantType, String entryKey,
259         ToscaNodeTemplate entryValue, List<ParticipantDefinition> participantDefinitionUpdates) {
260
261         var clDefinition = new ControlLoopElementDefinition();
262         clDefinition.setClElementDefinitionId(new ToscaConceptIdentifier(
263             entryKey, entryValue.getVersion()));
264         clDefinition.setControlLoopElementToscaNodeTemplate(entryValue);
265         List<ControlLoopElementDefinition> controlLoopElementDefinitionList = new ArrayList<>();
266
267         if (participantDefinitionUpdates.isEmpty()) {
268             participantDefinitionUpdates.add(getParticipantDefinition(clDefinition, clParticipantType,
269                 controlLoopElementDefinitionList));
270         } else {
271             boolean participantExists = false;
272             for (ParticipantDefinition participantDefinitionUpdate : participantDefinitionUpdates) {
273                 if (participantDefinitionUpdate.getParticipantType().equals(clParticipantType)) {
274                     participantDefinitionUpdate.getControlLoopElementDefinitionList().add(clDefinition);
275                     participantExists = true;
276                 }
277             }
278             if (!participantExists) {
279                 participantDefinitionUpdates.add(getParticipantDefinition(clDefinition, clParticipantType,
280                     controlLoopElementDefinitionList));
281             }
282         }
283     }
284
285     private static ParticipantDefinition getParticipantDefinition(ControlLoopElementDefinition clDefinition,
286         ToscaConceptIdentifier clParticipantType,
287         List<ControlLoopElementDefinition> controlLoopElementDefinitionList) {
288         ParticipantDefinition participantDefinition = new ParticipantDefinition();
289         participantDefinition.setParticipantType(clParticipantType);
290         controlLoopElementDefinitionList.add(clDefinition);
291         participantDefinition.setControlLoopElementDefinitionList(controlLoopElementDefinitionList);
292         return participantDefinition;
293     }
294
295     public static ToscaConceptIdentifier getControlLoopId() {
296         return new ToscaConceptIdentifier("PMSHInstance0", "1.0.0");
297     }
298
299     /**
300      * Method to create a deep copy of ControlLoopUpdateMsg.
301      *
302      * @return ControlLoopUpdate message
303      */
304     public static ControlLoopUpdate createCopyControlLoopUpdateMsg(ControlLoopUpdate cpy) {
305         return new ControlLoopUpdate(cpy);
306     }
307
308     /**
309      * Method to create ControlLoopUpdate using the arguments passed.
310      *
311      * @param jsonFilePath the path of the controlloop content
312      *
313      * @return ControlLoopUpdate message
314      * @throws CoderException exception while reading the file to object
315      */
316     public static ControlLoopUpdate createParticipantClUpdateMsgFromJson(String jsonFilePath)
317             throws CoderException {
318         ControlLoopUpdate controlLoopUpdateMsg =
319                 CODER.decode(new File(jsonFilePath), ControlLoopUpdate.class);
320         return controlLoopUpdateMsg;
321     }
322
323     private static ToscaServiceTemplate testControlLoopRead() {
324         return testControlLoopYamlSerialization(TOSCA_TEMPLATE_YAML);
325     }
326
327     private static ToscaServiceTemplate testControlLoopYamlSerialization(String controlLoopFilePath) {
328         String controlLoopString = ResourceUtils.getResourceAsString(controlLoopFilePath);
329         ToscaServiceTemplate serviceTemplate = yamlTranslator.fromYaml(controlLoopString, ToscaServiceTemplate.class);
330         return serviceTemplate;
331     }
332 }