10116a240289361fa9a465dd5537cab70688844a
[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.runtime.supervision.comm;
22
23 import java.time.Instant;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.LinkedHashMap;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.UUID;
30 import org.junit.jupiter.api.AfterAll;
31 import org.junit.jupiter.api.BeforeAll;
32 import org.junit.jupiter.api.Test;
33 import org.mockito.Mockito;
34 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElementDefinition;
35 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantDefinition;
36 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ClElementStatisticsProvider;
37 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
38 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider;
39 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantStatisticsProvider;
40 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregister;
41 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregisterAck;
42 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegister;
43 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegisterAck;
44 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate;
45 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdateAck;
46 import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider;
47 import org.onap.policy.clamp.controlloop.runtime.instantiation.InstantiationUtils;
48 import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup;
49 import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider;
50 import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler;
51 import org.onap.policy.clamp.controlloop.runtime.util.CommonTestData;
52 import org.onap.policy.clamp.controlloop.runtime.util.rest.CommonRestController;
53 import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
54 import org.onap.policy.common.endpoints.event.comm.TopicSink;
55 import org.onap.policy.common.utils.coder.Coder;
56 import org.onap.policy.common.utils.coder.CoderException;
57 import org.onap.policy.common.utils.coder.StandardCoder;
58 import org.onap.policy.common.utils.coder.YamlJsonTranslator;
59 import org.onap.policy.common.utils.resources.ResourceUtils;
60 import org.onap.policy.models.base.PfModelException;
61 import org.onap.policy.models.provider.PolicyModelsProvider;
62 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
63 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
64 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
65
66 class SupervisionMessagesTest extends CommonRestController {
67
68     private static final String TOSCA_SERVICE_TEMPLATE_YAML =
69             "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml";
70     private static final Object lockit = new Object();
71     private static final CommInfrastructure INFRA = CommInfrastructure.NOOP;
72     private static final String TOPIC = "my-topic";
73     private static SupervisionHandler supervisionHandler;
74     private static CommissioningProvider commissioningProvider;
75     private static ControlLoopProvider clProvider;
76     private static PolicyModelsProvider modelsProvider;
77     private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator();
78     private static final String TOSCA_TEMPLATE_YAML =
79             "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml";
80     private static final String CONTROL_LOOP_ELEMENT = "ControlLoopElement";
81     private static final Coder CODER = new StandardCoder();
82
83     /**
84      * setup Db Provider Parameters.
85      *
86      * @throws PfModelException if an error occurs
87      */
88     @BeforeAll
89     public static void setupDbProviderParameters() throws PfModelException {
90         ClRuntimeParameterGroup controlLoopParameters = CommonTestData.geParameterGroup("instantproviderdb");
91
92         modelsProvider = CommonTestData.getPolicyModelsProvider(controlLoopParameters.getDatabaseProviderParameters());
93         clProvider = new ControlLoopProvider(controlLoopParameters.getDatabaseProviderParameters());
94         var participantStatisticsProvider =
95                 new ParticipantStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters());
96         var clElementStatisticsProvider =
97                 new ClElementStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters());
98         commissioningProvider = new CommissioningProvider(modelsProvider, clProvider);
99         var monitoringProvider =
100                 new MonitoringProvider(participantStatisticsProvider, clElementStatisticsProvider, clProvider);
101         var participantProvider = new ParticipantProvider(controlLoopParameters.getDatabaseProviderParameters());
102         var controlLoopUpdatePublisher = Mockito.mock(ControlLoopUpdatePublisher.class);
103         var controlLoopStateChangePublisher = Mockito.mock(ControlLoopStateChangePublisher.class);
104         var participantRegisterAckPublisher = Mockito.mock(ParticipantRegisterAckPublisher.class);
105         var participantDeregisterAckPublisher = Mockito.mock(ParticipantDeregisterAckPublisher.class);
106         var participantUpdatePublisher = Mockito.mock(ParticipantUpdatePublisher.class);
107         supervisionHandler = new SupervisionHandler(clProvider, participantProvider, monitoringProvider,
108                 controlLoopUpdatePublisher, controlLoopStateChangePublisher, participantRegisterAckPublisher,
109                 participantDeregisterAckPublisher, participantUpdatePublisher);
110     }
111
112     @AfterAll
113     public static void closeDbProvider() throws PfModelException {
114         clProvider.close();
115         modelsProvider.close();
116     }
117
118     @Test
119     void testReceiveParticipantRegister() throws Exception {
120         final ParticipantRegister participantRegisterMsg = new ParticipantRegister();
121         participantRegisterMsg.setParticipantId(getParticipantId());
122         participantRegisterMsg.setTimestamp(Instant.now());
123         participantRegisterMsg.setParticipantType(getParticipantType());
124
125         synchronized (lockit) {
126             ParticipantRegisterListener participantRegisterListener =
127                     new ParticipantRegisterListener(supervisionHandler);
128             ToscaServiceTemplate serviceTemplate = yamlTranslator.fromYaml(
129                     ResourceUtils.getResourceAsString(TOSCA_SERVICE_TEMPLATE_YAML), ToscaServiceTemplate.class);
130
131             commissioningProvider.createControlLoopDefinitions(serviceTemplate);
132             participantRegisterListener.onTopicEvent(INFRA, TOPIC, null, participantRegisterMsg);
133         }
134     }
135
136     @Test
137     void testSendParticipantRegisterAck() throws Exception {
138         final ParticipantRegisterAck participantRegisterAckMsg = new ParticipantRegisterAck();
139         participantRegisterAckMsg.setMessage("ParticipantRegisterAck message");
140         participantRegisterAckMsg.setResponseTo(UUID.randomUUID());
141         participantRegisterAckMsg.setResult(true);
142
143         synchronized (lockit) {
144             ParticipantRegisterAckPublisher clRegisterAckPublisher = new ParticipantRegisterAckPublisher();
145             clRegisterAckPublisher.active(Collections.singletonList(Mockito.mock(TopicSink.class)));
146             clRegisterAckPublisher.send(participantRegisterAckMsg);
147         }
148     }
149
150     @Test
151     void testReceiveParticipantDeregister() throws Exception {
152         final ParticipantDeregister participantDeregisterMsg = new ParticipantDeregister();
153         participantDeregisterMsg.setParticipantId(getParticipantId());
154         participantDeregisterMsg.setTimestamp(Instant.now());
155         participantDeregisterMsg.setParticipantType(getParticipantType());
156
157         synchronized (lockit) {
158             ParticipantDeregisterListener participantDeregisterListener =
159                     new ParticipantDeregisterListener(supervisionHandler);
160             participantDeregisterListener.onTopicEvent(INFRA, TOPIC, null, participantDeregisterMsg);
161         }
162     }
163
164     @Test
165     void testSendParticipantDeregisterAck() throws Exception {
166         final ParticipantDeregisterAck participantDeregisterAckMsg = new ParticipantDeregisterAck();
167         participantDeregisterAckMsg.setMessage("ParticipantDeregisterAck message");
168         participantDeregisterAckMsg.setResponseTo(UUID.randomUUID());
169         participantDeregisterAckMsg.setResult(true);
170
171         synchronized (lockit) {
172             ParticipantDeregisterAckPublisher clDeregisterAckPublisher = new ParticipantDeregisterAckPublisher();
173             clDeregisterAckPublisher.active(Collections.singletonList(Mockito.mock(TopicSink.class)));
174             clDeregisterAckPublisher.send(participantDeregisterAckMsg);
175         }
176     }
177
178     @Test
179     void testSendParticipantUpdate() throws Exception {
180         InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, commissioningProvider);
181         commissioningProvider.getToscaServiceTemplate(null, null);
182
183         final ParticipantUpdate participantUpdateMsg = new ParticipantUpdate();
184         participantUpdateMsg.setParticipantId(getParticipantId());
185         participantUpdateMsg.setTimestamp(Instant.now());
186         participantUpdateMsg.setParticipantType(getParticipantType());
187         participantUpdateMsg.setTimestamp(Instant.ofEpochMilli(3000));
188         participantUpdateMsg.setMessageId(UUID.randomUUID());
189
190         ToscaServiceTemplate toscaServiceTemplate = commissioningProvider.getToscaServiceTemplate(null, null);
191         List<ParticipantDefinition> participantDefinitionUpdates = new ArrayList<>();
192         for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry :
193             toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().entrySet()) {
194             if (toscaInputEntry.getValue().getType().contains(CONTROL_LOOP_ELEMENT)) {
195                 ToscaConceptIdentifier clParticipantId;
196                 try {
197                     clParticipantId = CODER.decode(
198                             toscaInputEntry.getValue().getProperties().get("participant_id").toString(),
199                             ToscaConceptIdentifier.class);
200                 } catch (CoderException e) {
201                     throw new RuntimeException("cannot get ParticipantId from toscaNodeTemplate", e);
202                 }
203                 prepareParticipantDefinitionUpdate(clParticipantId, toscaInputEntry.getKey(),
204                     toscaInputEntry.getValue(), participantDefinitionUpdates);
205             }
206         }
207
208         participantUpdateMsg.setParticipantDefinitionUpdates(participantDefinitionUpdates);
209         participantUpdateMsg.setToscaServiceTemplate(toscaServiceTemplate);
210         synchronized (lockit) {
211             ParticipantUpdatePublisher participantUpdatePublisher =
212                 new ParticipantUpdatePublisher(commissioningProvider);
213             participantUpdatePublisher.active(Collections.singletonList(Mockito.mock(TopicSink.class)));
214             participantUpdatePublisher.send(participantUpdateMsg);
215         }
216     }
217
218     private void prepareParticipantDefinitionUpdate(ToscaConceptIdentifier clParticipantId, String entryKey,
219         ToscaNodeTemplate entryValue, List<ParticipantDefinition> participantDefinitionUpdates) {
220
221         var clDefinition = new ControlLoopElementDefinition();
222         clDefinition.setClElementDefinitionId(new ToscaConceptIdentifier(
223             entryKey, entryValue.getVersion()));
224         clDefinition.setControlLoopElementToscaNodeTemplate(entryValue);
225         List<ControlLoopElementDefinition> controlLoopElementDefinitionList = new ArrayList<>();
226
227         if (participantDefinitionUpdates.isEmpty()) {
228             participantDefinitionUpdates.add(getParticipantDefinition(clDefinition, clParticipantId,
229                 controlLoopElementDefinitionList));
230         } else {
231             boolean participantExists = false;
232             for (ParticipantDefinition participantDefinitionUpdate : participantDefinitionUpdates) {
233                 if (participantDefinitionUpdate.getParticipantId().equals(clParticipantId)) {
234                     participantDefinitionUpdate.getControlLoopElementDefinitionList().add(clDefinition);
235                     participantExists = true;
236                 }
237             }
238             if (!participantExists) {
239                 participantDefinitionUpdates.add(getParticipantDefinition(clDefinition, clParticipantId,
240                     controlLoopElementDefinitionList));
241             }
242         }
243     }
244
245     private ParticipantDefinition getParticipantDefinition(ControlLoopElementDefinition clDefinition,
246         ToscaConceptIdentifier clParticipantId,
247         List<ControlLoopElementDefinition> controlLoopElementDefinitionList) {
248         ParticipantDefinition participantDefinition = new ParticipantDefinition();
249         participantDefinition.setParticipantId(clParticipantId);
250         controlLoopElementDefinitionList.add(clDefinition);
251         participantDefinition.setControlLoopElementDefinitionList(controlLoopElementDefinitionList);
252         return participantDefinition;
253     }
254
255     @Test
256     void testReceiveParticipantUpdateAckMessage() throws Exception {
257         final ParticipantUpdateAck participantUpdateAckMsg = new ParticipantUpdateAck();
258         participantUpdateAckMsg.setMessage("ParticipantUpdateAck message");
259         participantUpdateAckMsg.setResponseTo(UUID.randomUUID());
260         participantUpdateAckMsg.setResult(true);
261
262         synchronized (lockit) {
263             ParticipantUpdateAckListener participantUpdateAckListener =
264                     new ParticipantUpdateAckListener(supervisionHandler);
265             participantUpdateAckListener.onTopicEvent(INFRA, TOPIC, null, participantUpdateAckMsg);
266         }
267     }
268
269     private ToscaConceptIdentifier getParticipantId() {
270         return new ToscaConceptIdentifier("org.onap.PM_Policy", "1.0.0");
271     }
272
273     private ToscaConceptIdentifier getParticipantType() {
274         return new ToscaConceptIdentifier("org.onap.policy.controlloop.PolicyControlLoopParticipant", "2.3.1");
275     }
276 }