Add initial version of code
[nonrtric/plt/rappmanager.git] / rapp-manager-acm / src / main / java / com / oransc / rappmanager / acm / service / AcmDeployer.java
1 /*-
2  * ============LICENSE_START======================================================================
3  * Copyright (C) 2023 Nordix Foundation. All rights reserved.
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  * ============LICENSE_END========================================================================
17  */
18
19 package com.oransc.rappmanager.acm.service;
20
21 import com.oransc.rappmanager.acm.configuration.ACMConfiguration;
22 import com.oransc.rappmanager.acm.rest.AutomationCompositionDefinitionApiClient;
23 import com.oransc.rappmanager.acm.rest.AutomationCompositionInstanceApiClient;
24 import com.oransc.rappmanager.acm.rest.ParticipantMonitoringApiClient;
25 import com.oransc.rappmanager.models.Rapp;
26 import com.oransc.rappmanager.models.RappCsarConfigurationHandler;
27 import com.oransc.rappmanager.models.RappDeployer;
28 import com.oransc.rappmanager.models.RappEvent;
29 import com.oransc.rappmanager.models.RappState;
30 import com.oransc.rappmanager.models.cache.RappCacheService;
31 import com.oransc.rappmanager.models.statemachine.RappStateMachine;
32 import java.util.List;
33 import java.util.UUID;
34 import java.util.concurrent.TimeUnit;
35 import lombok.Getter;
36 import lombok.RequiredArgsConstructor;
37 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
38 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
39 import org.onap.policy.clamp.models.acm.concepts.DeployState;
40 import org.onap.policy.clamp.models.acm.concepts.LockState;
41 import org.onap.policy.clamp.models.acm.concepts.ParticipantInformation;
42 import org.onap.policy.clamp.models.acm.messages.rest.commissioning.AcTypeStateUpdate;
43 import org.onap.policy.clamp.models.acm.messages.rest.commissioning.CommissioningResponse;
44 import org.onap.policy.clamp.models.acm.messages.rest.commissioning.PrimeOrder;
45 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AcInstanceStateUpdate;
46 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
47 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationResponse;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50 import org.springframework.stereotype.Service;
51 import org.springframework.web.client.RestClientException;
52
53 @Service
54 @RequiredArgsConstructor
55 public class AcmDeployer implements RappDeployer {
56
57     Logger logger = LoggerFactory.getLogger(AcmDeployer.class);
58
59     private final ParticipantMonitoringApiClient participantMonitoringApiClient;
60     private final AutomationCompositionDefinitionApiClient automationCompositionDefinitionApiClient;
61     private final AutomationCompositionInstanceApiClient automationCompositionInstanceApiClient;
62     private final RappCsarConfigurationHandler rappCsarConfigurationHandler;
63     private final RappCacheService rappCacheService;
64     private final RappStateMachine rappStateMachine;
65     private final ACMConfiguration acmConfiguration;
66     @Getter
67     private UUID compositionId;
68
69     public List<ParticipantInformation> getAllParticipants() {
70         return participantMonitoringApiClient.queryParticipants(null, null, UUID.randomUUID());
71     }
72
73
74     void updateACMInstanceState(Rapp rapp, DeployOrder deployOrder) {
75         AcInstanceStateUpdate acInstanceStateUpdate = new AcInstanceStateUpdate();
76         acInstanceStateUpdate.setDeployOrder(deployOrder);
77         automationCompositionInstanceApiClient.compositionInstanceState(rapp.getCompositionId(),
78                 rapp.getCompositionInstanceId(), acInstanceStateUpdate, UUID.randomUUID());
79     }
80
81     public void primeACMComposition(UUID compositionId, PrimeOrder primeOrder) {
82         AcTypeStateUpdate acTypeStateUpdate = new AcTypeStateUpdate();
83         acTypeStateUpdate.setPrimeOrder(primeOrder);
84         automationCompositionDefinitionApiClient.compositionDefinitionPriming(compositionId, UUID.randomUUID(),
85                 acTypeStateUpdate);
86     }
87
88     public CommissioningResponse createComposition(String compositionPayload) {
89         CommissioningResponse commissioningResponse = null;
90         try {
91             commissioningResponse =
92                     automationCompositionDefinitionApiClient.createCompositionDefinitions(compositionPayload,
93                             UUID.randomUUID());
94             compositionId = commissioningResponse.getCompositionId();
95         } catch (Exception e) {
96             logger.warn("Error in creating composition", e);
97         }
98         return commissioningResponse;
99     }
100
101     public CommissioningResponse deleteComposition(UUID compositionId) {
102         return automationCompositionDefinitionApiClient.deleteCompositionDefinition(compositionId, UUID.randomUUID());
103     }
104
105     public boolean isCompositionStateEquals(UUID compositionId, AcTypeState acTypeState) {
106         //automationCompositionDefinitionApiClient.getCompositionDefinition(compositionId, UUID.randomUUID()).getState().equals(acTypeState);
107         //TODO httpmessage converter doesn't map AutomationCompositionDefinition properly, Fix that and check the response
108         return true;
109     }
110
111     boolean isCompositionInstanceStateEquals(UUID compositionId, UUID compositionIntanceId, DeployState deployState) {
112         return automationCompositionInstanceApiClient.getCompositionInstance(compositionId, compositionIntanceId,
113                 UUID.randomUUID()).getDeployState().equals(deployState);
114     }
115
116     boolean waitForCompositionInstanceTargetState(Rapp rapp, DeployState deployState) {
117         boolean targetInstanceStateTransition = false;
118         try {
119             for (int i = 0; i < acmConfiguration.getMaxRetries(); i++) {
120                 logger.debug("Composition instance state check {}", i + 1);
121                 if (isCompositionInstanceStateEquals(rapp.getCompositionId(), rapp.getCompositionInstanceId(),
122                         deployState)) {
123                     sendRappStateEvent(rapp, deployState);
124                     logger.info("Composition instance {} state is {}", rapp.getCompositionInstanceId(), deployState);
125                     targetInstanceStateTransition = true;
126                     break;
127                 } else {
128                     TimeUnit.SECONDS.sleep(acmConfiguration.getRetryInterval());
129                 }
130             }
131         } catch (Exception e) {
132             logger.warn("Unable to get composition instance state for composition {}", rapp.getCompositionId());
133         }
134         return targetInstanceStateTransition;
135     }
136
137     @Override
138     public boolean deployRapp(Rapp rapp) {
139         try {
140             rapp.setCompositionId(getCompositionId());
141             String instantiationPayload =
142                     rappCsarConfigurationHandler.getInstantiationPayload(rapp, getCompositionId());
143             InstantiationResponse instantiationResponse =
144                     automationCompositionInstanceApiClient.createCompositionInstance(getCompositionId(),
145                             instantiationPayload, UUID.randomUUID());
146             if (instantiationResponse.getInstanceId() != null) {
147                 rapp.setCompositionInstanceId(instantiationResponse.getInstanceId());
148                 updateACMInstanceState(rapp, DeployOrder.DEPLOY);
149                 return true;
150             }
151         } catch (Exception e) {
152             logger.warn("Error in deploying Rapp", e);
153         }
154         return false;
155     }
156
157     @Override
158     public boolean undeployRapp(Rapp rapp) {
159         AutomationComposition automationComposition =
160                 automationCompositionInstanceApiClient.getCompositionInstance(rapp.getCompositionId(),
161                         rapp.getCompositionInstanceId(), UUID.randomUUID());
162         if (automationComposition.getDeployState().equals(DeployState.DEPLOYED) && automationComposition.getLockState()
163                                                                                            .equals(LockState.LOCKED)) {
164             updateACMInstanceState(rapp, DeployOrder.UNDEPLOY);
165             if (waitForCompositionInstanceTargetState(rapp, DeployState.UNDEPLOYED)) {
166                 automationCompositionInstanceApiClient.deleteCompositionInstance(
167                         automationComposition.getCompositionId(), automationComposition.getInstanceId(),
168                         UUID.randomUUID());
169                 rappStateMachine.sendRappEvent(rapp, RappEvent.ACMUNDEPLOYED);
170                 return true;
171             }
172         }
173         return false;
174     }
175
176     public void syncRappStatus(Rapp rapp) {
177         if (rapp.getCompositionId() != null && rapp.getCompositionInstanceId() != null) {
178             try {
179                 AutomationComposition compositionInstance =
180                         automationCompositionInstanceApiClient.getCompositionInstance(rapp.getCompositionId(),
181                                 rapp.getCompositionInstanceId(), UUID.randomUUID());
182                 logger.info("ACM details are " + compositionInstance.toString());
183                 sendRappStateEvent(rapp, compositionInstance.getDeployState());
184             } catch (RestClientException exception) {
185                 logger.warn("Unable to get the ACM details for rapp {}", rapp.getName());
186             }
187         }
188     }
189
190     void sendRappStateEvent(Rapp rapp, DeployState deployState) {
191         if (deployState.equals(DeployState.DEPLOYED)) {
192             rappStateMachine.sendRappEvent(rapp, RappEvent.ACMDEPLOYED);
193         } else if (deployState.equals(DeployState.UNDEPLOYED)) {
194             rappStateMachine.sendRappEvent(rapp, RappEvent.ACMUNDEPLOYED);
195         } else if (deployState.equals(DeployState.DEPLOYING)) {
196             rappStateMachine.sendRappEvent(rapp, RappEvent.DEPLOYING);
197         } else if (deployState.equals(DeployState.UNDEPLOYING)) {
198             rappStateMachine.sendRappEvent(rapp, RappEvent.UNDEPLOYING);
199         }
200     }
201 }