ca763f1199e657488e2aa240122fd39145b4bde1
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Nordix Foundation.
4  * ================================================================================
5  * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * SPDX-License-Identifier: Apache-2.0
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.policy.clamp.controlloop.participant.dcae.main.handler;
24
25 import java.time.Instant;
26 import java.util.UUID;
27 import java.util.concurrent.TimeUnit;
28 import lombok.Setter;
29 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics;
30 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement;
31 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
32 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
33 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType;
34 import org.onap.policy.clamp.controlloop.participant.dcae.httpclient.ClampHttpClient;
35 import org.onap.policy.clamp.controlloop.participant.dcae.httpclient.ConsulDcaeHttpClient;
36 import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.ParticipantDcaeParameters;
37 import org.onap.policy.clamp.controlloop.participant.dcae.model.Loop;
38 import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener;
39 import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi;
40 import org.onap.policy.common.utils.resources.ResourceUtils;
41 import org.onap.policy.models.base.PfModelException;
42 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
43 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46 import org.springframework.stereotype.Component;
47
48 /**
49  * This class handles implementation of controlLoopElement updates.
50  */
51 @Component
52 public class ControlLoopElementHandler implements ControlLoopElementListener {
53
54     private static final Logger LOGGER = LoggerFactory.getLogger(ControlLoopElementHandler.class);
55     private final ClampHttpClient clampClient;
56     private final ConsulDcaeHttpClient consulClient;
57
58     @Setter
59     private ParticipantIntermediaryApi intermediaryApi;
60
61     private static final String LOOP = "pmsh_loop";
62     private static final String TEMPLATE = "LOOP_TEMPLATE_k8s_pmsh";
63     private static final String POLICY = "policy";
64
65     private static final String BLUEPRINT_DEPLOYED = "BLUEPRINT_DEPLOYED";
66     private static final String MICROSERVICE_INSTALLED_SUCCESSFULLY = "MICROSERVICE_INSTALLED_SUCCESSFULLY";
67
68     private int checkCount;
69     private int secCount;
70
71     private String bodyConsul;
72
73     /**
74      * Constructor.
75      *
76      * @param clampClient the CLAMP client
77      * @param consulClient the Consul client
78      */
79     public ControlLoopElementHandler(ClampHttpClient clampClient, ConsulDcaeHttpClient consulClient,
80             ParticipantDcaeParameters parameters) {
81         this.clampClient = clampClient;
82         this.consulClient = consulClient;
83         this.checkCount = parameters.getCheckCount();
84         this.secCount = parameters.getSecCount();
85         bodyConsul = ResourceUtils.getResourceAsString(parameters.getJsonBodyConsulPath());
86     }
87
88     /**
89      * Callback method to handle a control loop element state change.
90      *
91      * @param controlLoopElementId the ID of the control loop element
92      * @param currentState the current state of the control loop element
93      * @param newState the state to which the control loop element is changing to
94      */
95     @Override
96     public void controlLoopElementStateChange(ToscaConceptIdentifier controlLoopId,
97             UUID controlLoopElementId, ControlLoopState currentState,
98             ControlLoopOrderedState newState) {
99         switch (newState) {
100             case UNINITIALISED:
101                 var loop = clampClient.getstatus(LOOP);
102                 if (loop != null) {
103                     clampClient.undeploy(LOOP);
104                     intermediaryApi.updateControlLoopElementState(controlLoopId,
105                             controlLoopElementId, newState,
106                             ControlLoopState.UNINITIALISED, ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE);
107                 }
108                 break;
109             case PASSIVE:
110                 intermediaryApi.updateControlLoopElementState(controlLoopId,
111                     controlLoopElementId, newState, ControlLoopState.PASSIVE,
112                     ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE);
113                 break;
114             case RUNNING:
115                 intermediaryApi.updateControlLoopElementState(controlLoopId,
116                     controlLoopElementId, newState, ControlLoopState.RUNNING,
117                     ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE);
118                 break;
119             default:
120                 LOGGER.debug("Unknown orderedstate {}", newState);
121                 break;
122         }
123     }
124
125     private Loop getStatus() throws PfModelException {
126         var loop = clampClient.getstatus(LOOP);
127         if (loop == null) {
128             loop = clampClient.create(LOOP, TEMPLATE);
129         }
130         if (loop == null) {
131             throw new PfModelException(null, "");
132         }
133         return loop;
134     }
135
136     private void deploy() throws PfModelException {
137         if (!consulClient.deploy(POLICY, bodyConsul)) {
138             throw new PfModelException(null, "deploy to consul failed");
139         }
140         if (!clampClient.deploy(LOOP)) {
141             throw new PfModelException(null, "deploy failed");
142         }
143     }
144
145     /**
146      * Callback method to handle an update on a control loop element.
147      *
148      * @param element the information on the control loop element
149      * @param nodeTemplate toscaNodeTemplate
150      * @throws PfModelException in case of an exception
151      */
152     @Override
153     public void controlLoopElementUpdate(ToscaConceptIdentifier controlLoopId,
154             ControlLoopElement element, ToscaNodeTemplate nodeTemplate)
155              throws PfModelException {
156         try {
157             var loop = getStatus();
158
159             if (BLUEPRINT_DEPLOYED.equals(ClampHttpClient.getStatusCode(loop))) {
160                 deploy();
161                 var deployedFlag = false;
162                 for (var i = 0; i < checkCount; i++) {
163                     // sleep 10 seconds
164                     TimeUnit.SECONDS.sleep(secCount);
165                     loop = getStatus();
166                     String status = ClampHttpClient.getStatusCode(loop);
167                     if (MICROSERVICE_INSTALLED_SUCCESSFULLY.equals(status)) {
168                         intermediaryApi.updateControlLoopElementState(controlLoopId, element.getId(),
169                             element.getOrderedState(), ControlLoopState.PASSIVE,
170                             ParticipantMessageType.CONTROL_LOOP_UPDATE);
171                         deployedFlag = true;
172                         break;
173                     }
174                 }
175                 if (!deployedFlag) {
176                     LOGGER.warn("DCAE is not deployed properly, ClElement state will be UNINITIALISED2PASSIVE");
177                     intermediaryApi.updateControlLoopElementState(controlLoopId, element.getId(),
178                         element.getOrderedState(), ControlLoopState.UNINITIALISED2PASSIVE,
179                         ParticipantMessageType.CONTROL_LOOP_UPDATE);
180                 }
181             }
182         } catch (PfModelException e) {
183             throw e;
184         } catch (InterruptedException e) {
185             Thread.currentThread().interrupt();
186             throw new PfModelException(null, e.getMessage(), e);
187         } catch (Exception e) {
188             throw new PfModelException(null, e.getMessage(), e);
189         }
190     }
191
192     /**
193      * Handle controlLoopElement statistics.
194      *
195      * @param controlLoopElementId controlloop element id
196      */
197     @Override
198     public void handleStatistics(UUID controlLoopElementId) {
199         var clElement = intermediaryApi.getControlLoopElement(controlLoopElementId);
200         if (clElement != null) {
201             var clElementStatistics = new ClElementStatistics();
202             clElementStatistics.setControlLoopState(clElement.getState());
203             clElementStatistics.setTimeStamp(Instant.now());
204             intermediaryApi.updateControlLoopElementStatistics(controlLoopElementId, clElementStatistics);
205         }
206     }
207 }