bcc3a701cfe528eab80a99bcb560ea49f97c4cfe
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Nordix Foundation.
4  *  Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.clamp.controlloop.runtime.supervision.comm;
23
24 import static org.assertj.core.api.Assertions.assertThatCode;
25
26 import java.time.Instant;
27 import java.util.ArrayList;
28 import java.util.Collections;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.UUID;
32 import org.junit.jupiter.api.AfterAll;
33 import org.junit.jupiter.api.BeforeAll;
34 import org.junit.jupiter.api.Test;
35 import org.mockito.Mockito;
36 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElementDefinition;
37 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantDefinition;
38 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUtils;
39 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ClElementStatisticsProvider;
40 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
41 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider;
42 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantStatisticsProvider;
43 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregister;
44 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregisterAck;
45 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegister;
46 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegisterAck;
47 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate;
48 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdateAck;
49 import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider;
50 import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup;
51 import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider;
52 import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler;
53 import org.onap.policy.clamp.controlloop.runtime.util.CommonTestData;
54 import org.onap.policy.clamp.controlloop.runtime.util.rest.CommonRestController;
55 import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
56 import org.onap.policy.common.endpoints.event.comm.TopicSink;
57 import org.onap.policy.common.utils.coder.YamlJsonTranslator;
58 import org.onap.policy.common.utils.resources.ResourceUtils;
59 import org.onap.policy.models.base.PfModelException;
60 import org.onap.policy.models.provider.PolicyModelsProvider;
61 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
62 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
63 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
64
65 class SupervisionMessagesTest extends CommonRestController {
66
67     private static final String TOSCA_SERVICE_TEMPLATE_YAML =
68             "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml";
69     private static final Object lockit = new Object();
70     private static final CommInfrastructure INFRA = CommInfrastructure.NOOP;
71     private static final String TOPIC = "my-topic";
72     private static SupervisionHandler supervisionHandler;
73     private static CommissioningProvider commissioningProvider;
74     private static ControlLoopProvider clProvider;
75     private static PolicyModelsProvider modelsProvider;
76     private static ParticipantProvider participantProvider;
77     private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator();
78
79     /**
80      * setup Db Provider Parameters.
81      *
82      * @throws PfModelException if an error occurs
83      */
84     @BeforeAll
85     public static void setupDbProviderParameters() throws PfModelException {
86         ClRuntimeParameterGroup controlLoopParameters = CommonTestData.geParameterGroup("instantproviderdb");
87
88         modelsProvider = CommonTestData.getPolicyModelsProvider(controlLoopParameters.getDatabaseProviderParameters());
89         clProvider = new ControlLoopProvider(controlLoopParameters.getDatabaseProviderParameters());
90         participantProvider = new ParticipantProvider(controlLoopParameters.getDatabaseProviderParameters());
91
92         var participantStatisticsProvider =
93                 new ParticipantStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters());
94         var clElementStatisticsProvider =
95                 new ClElementStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters());
96         commissioningProvider = new CommissioningProvider(modelsProvider, clProvider, null, participantProvider);
97         var monitoringProvider =
98                 new MonitoringProvider(participantStatisticsProvider, clElementStatisticsProvider, clProvider);
99         var participantProvider = new ParticipantProvider(controlLoopParameters.getDatabaseProviderParameters());
100         var controlLoopUpdatePublisher = Mockito.mock(ControlLoopUpdatePublisher.class);
101         var controlLoopStateChangePublisher = Mockito.mock(ControlLoopStateChangePublisher.class);
102         var participantRegisterAckPublisher = Mockito.mock(ParticipantRegisterAckPublisher.class);
103         var participantDeregisterAckPublisher = Mockito.mock(ParticipantDeregisterAckPublisher.class);
104         var participantUpdatePublisher = Mockito.mock(ParticipantUpdatePublisher.class);
105         supervisionHandler = new SupervisionHandler(clProvider, participantProvider, monitoringProvider,
106                 controlLoopUpdatePublisher, controlLoopStateChangePublisher, participantRegisterAckPublisher,
107                 participantDeregisterAckPublisher, participantUpdatePublisher);
108     }
109
110     @AfterAll
111     public static void closeDbProvider() throws PfModelException {
112         clProvider.close();
113         modelsProvider.close();
114     }
115
116     @Test
117     void testReceiveParticipantRegister() throws Exception {
118         final ParticipantRegister participantRegisterMsg = new ParticipantRegister();
119         participantRegisterMsg.setParticipantId(getParticipantId());
120         participantRegisterMsg.setTimestamp(Instant.now());
121         participantRegisterMsg.setParticipantType(getParticipantType());
122
123         synchronized (lockit) {
124             ParticipantRegisterListener participantRegisterListener =
125                     new ParticipantRegisterListener(supervisionHandler);
126             ToscaServiceTemplate serviceTemplate = yamlTranslator.fromYaml(
127                     ResourceUtils.getResourceAsString(TOSCA_SERVICE_TEMPLATE_YAML), ToscaServiceTemplate.class);
128
129             // List<ToscaNodeTemplate> listOfTemplates = commissioningProvider.getControlLoopDefinitions(null, null);
130             commissioningProvider.createControlLoopDefinitions(serviceTemplate);
131             assertThatCode(() -> participantRegisterListener.onTopicEvent(INFRA, TOPIC, null, participantRegisterMsg))
132                     .doesNotThrowAnyException();
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             assertThatCode(() -> clRegisterAckPublisher.send(participantRegisterAckMsg)).doesNotThrowAnyException();
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             assertThatCode(
161                     () -> participantDeregisterListener.onTopicEvent(INFRA, TOPIC, null, participantDeregisterMsg))
162                             .doesNotThrowAnyException();
163         }
164     }
165
166     @Test
167     void testSendParticipantDeregisterAck() throws Exception {
168         final ParticipantDeregisterAck participantDeregisterAckMsg = new ParticipantDeregisterAck();
169         participantDeregisterAckMsg.setMessage("ParticipantDeregisterAck message");
170         participantDeregisterAckMsg.setResponseTo(UUID.randomUUID());
171         participantDeregisterAckMsg.setResult(true);
172
173         synchronized (lockit) {
174             ParticipantDeregisterAckPublisher clDeregisterAckPublisher = new ParticipantDeregisterAckPublisher();
175             clDeregisterAckPublisher.active(Collections.singletonList(Mockito.mock(TopicSink.class)));
176             assertThatCode(() -> clDeregisterAckPublisher.send(participantDeregisterAckMsg)).doesNotThrowAnyException();
177         }
178     }
179
180     @Test
181     void testSendParticipantUpdate() throws Exception {
182         final ParticipantUpdate participantUpdateMsg = new ParticipantUpdate();
183         participantUpdateMsg.setParticipantId(getParticipantId());
184         participantUpdateMsg.setTimestamp(Instant.now());
185         participantUpdateMsg.setParticipantType(getParticipantType());
186         participantUpdateMsg.setTimestamp(Instant.ofEpochMilli(3000));
187         participantUpdateMsg.setMessageId(UUID.randomUUID());
188
189         ToscaServiceTemplate toscaServiceTemplate = commissioningProvider.getToscaServiceTemplate(null, null);
190         List<ParticipantDefinition> participantDefinitionUpdates = new ArrayList<>();
191         for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry : toscaServiceTemplate.getToscaTopologyTemplate()
192                 .getNodeTemplates().entrySet()) {
193             if (ParticipantUtils.checkIfNodeTemplateIsControlLoopElement(toscaInputEntry.getValue(),
194                     toscaServiceTemplate)) {
195                 var clParticipantType =
196                         ParticipantUtils.findParticipantType(toscaInputEntry.getValue().getProperties());
197                 prepareParticipantDefinitionUpdate(clParticipantType, toscaInputEntry.getKey(),
198                         toscaInputEntry.getValue(), participantDefinitionUpdates);
199             }
200         }
201
202         participantUpdateMsg.setParticipantDefinitionUpdates(participantDefinitionUpdates);
203         synchronized (lockit) {
204             ParticipantUpdatePublisher participantUpdatePublisher = new ParticipantUpdatePublisher(modelsProvider);
205             participantUpdatePublisher.active(Collections.singletonList(Mockito.mock(TopicSink.class)));
206             assertThatCode(() -> participantUpdatePublisher.send(participantUpdateMsg)).doesNotThrowAnyException();
207         }
208     }
209
210     private void prepareParticipantDefinitionUpdate(ToscaConceptIdentifier clParticipantType, String entryKey,
211             ToscaNodeTemplate entryValue, List<ParticipantDefinition> participantDefinitionUpdates) {
212
213         var clDefinition = new ControlLoopElementDefinition();
214         clDefinition.setClElementDefinitionId(new ToscaConceptIdentifier(entryKey, entryValue.getVersion()));
215         clDefinition.setControlLoopElementToscaNodeTemplate(entryValue);
216         List<ControlLoopElementDefinition> controlLoopElementDefinitionList = new ArrayList<>();
217
218         if (participantDefinitionUpdates.isEmpty()) {
219             participantDefinitionUpdates
220                     .add(getParticipantDefinition(clDefinition, clParticipantType, controlLoopElementDefinitionList));
221         } else {
222             boolean participantExists = false;
223             for (ParticipantDefinition participantDefinitionUpdate : participantDefinitionUpdates) {
224                 if (participantDefinitionUpdate.getParticipantType().equals(clParticipantType)) {
225                     participantDefinitionUpdate.getControlLoopElementDefinitionList().add(clDefinition);
226                     participantExists = true;
227                 }
228             }
229             if (!participantExists) {
230                 participantDefinitionUpdates.add(
231                         getParticipantDefinition(clDefinition, clParticipantType, controlLoopElementDefinitionList));
232             }
233         }
234     }
235
236     private ParticipantDefinition getParticipantDefinition(ControlLoopElementDefinition clDefinition,
237             ToscaConceptIdentifier clParticipantType,
238             List<ControlLoopElementDefinition> controlLoopElementDefinitionList) {
239         ParticipantDefinition participantDefinition = new ParticipantDefinition();
240         participantDefinition.setParticipantType(clParticipantType);
241         controlLoopElementDefinitionList.add(clDefinition);
242         participantDefinition.setControlLoopElementDefinitionList(controlLoopElementDefinitionList);
243         return participantDefinition;
244     }
245
246     @Test
247     void testReceiveParticipantUpdateAckMessage() throws Exception {
248         final ParticipantUpdateAck participantUpdateAckMsg = new ParticipantUpdateAck();
249         participantUpdateAckMsg.setMessage("ParticipantUpdateAck message");
250         participantUpdateAckMsg.setResponseTo(UUID.randomUUID());
251         participantUpdateAckMsg.setResult(true);
252         participantUpdateAckMsg.setParticipantId(getParticipantId());
253         participantUpdateAckMsg.setParticipantType(getParticipantType());
254
255         synchronized (lockit) {
256             ParticipantUpdateAckListener participantUpdateAckListener =
257                     new ParticipantUpdateAckListener(supervisionHandler);
258             assertThatCode(() -> participantUpdateAckListener.onTopicEvent(INFRA, TOPIC, null, participantUpdateAckMsg))
259                     .doesNotThrowAnyException();
260         }
261     }
262
263     private ToscaConceptIdentifier getParticipantId() {
264         return new ToscaConceptIdentifier("org.onap.PM_Policy", "1.0.0");
265     }
266
267     private ToscaConceptIdentifier getParticipantType() {
268         return new ToscaConceptIdentifier("org.onap.policy.controlloop.PolicyControlLoopParticipant", "2.3.1");
269     }
270 }