ddbda5da629fadf2219c7d06df1cd7fa760bf6b9
[so.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.adapters.tasks.orchestration;
24
25 import java.io.ByteArrayInputStream;
26 import java.io.StringReader;
27 import java.util.HashMap;
28 import java.util.Map;
29 import java.util.Optional;
30 import javax.xml.bind.JAXB;
31 import javax.xml.parsers.DocumentBuilder;
32 import javax.xml.parsers.DocumentBuilderFactory;
33 import org.apache.commons.lang3.mutable.MutableBoolean;
34 import org.camunda.bpm.client.task.ExternalTask;
35 import org.camunda.bpm.client.task.ExternalTaskService;
36 import org.onap.so.adapters.nwrest.CreateNetworkRequest;
37 import org.onap.so.adapters.vnfrest.CreateVfModuleRequest;
38 import org.onap.so.adapters.vnfrest.CreateVolumeGroupRequest;
39 import org.onap.so.adapters.vnfrest.DeleteVfModuleRequest;
40 import org.onap.so.adapters.vnfrest.DeleteVolumeGroupRequest;
41 import org.onap.so.adapters.nwrest.DeleteNetworkRequest;
42 import org.onap.so.adapters.nwrest.UpdateNetworkRequest;
43 import org.onap.so.adapters.vnf.VnfAdapterUtils;
44 import org.onap.so.logging.tasks.AuditMDCSetup;
45 import org.onap.so.openstack.exceptions.MsoException;
46 import org.onap.so.openstack.utils.MsoHeatUtils;
47 import org.onap.so.utils.ExternalTaskUtils;
48 import org.onap.so.utils.RetrySequenceLevel;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51 import org.springframework.beans.factory.annotation.Autowired;
52 import org.springframework.stereotype.Component;
53 import com.woorea.openstack.heat.model.Stack;
54
55 @Component
56 public class PollService extends ExternalTaskUtils {
57
58     private static final Logger logger = LoggerFactory.getLogger(PollService.class);
59
60     @Autowired
61     private MsoHeatUtils msoHeatUtils;
62
63     @Autowired
64     private VnfAdapterUtils vnfAdapterUtils;
65
66     @Autowired
67     private AuditMDCSetup mdcSetup;
68
69     public PollService() {
70         super(RetrySequenceLevel.SHORT);
71     }
72
73     public void executeExternalTask(ExternalTask externalTask, ExternalTaskService externalTaskService) {
74         mdcSetup.setupMDC(externalTask);
75         logger.debug("Starting External Task Poll Service");
76         Map<String, Object> variables = new HashMap<>();
77         MutableBoolean success = new MutableBoolean();
78         String errorMessage = null;
79         try {
80             String xmlRequest = externalTask.getVariable("openstackAdapterTaskRequest");
81             if (xmlRequest != null) {
82                 Optional<String> requestType = findRequestType(xmlRequest);
83                 if ("createVolumeGroupRequest".equals(requestType.get())) {
84                     determineCreateVolumeGroupStatus(xmlRequest, externalTask, success);
85                 } else if ("createVfModuleRequest".equals(requestType.get())) {
86                     determineCreateVfModuleStatus(xmlRequest, externalTask, success);
87                 } else if ("deleteVfModuleRequest".equals(requestType.get())) {
88                     logger.debug("Executing External Task Poll Service for Delete Vf Module");
89                     DeleteVfModuleRequest req =
90                             JAXB.unmarshal(new StringReader(xmlRequest), DeleteVfModuleRequest.class);
91                     boolean isMulticloud = vnfAdapterUtils.isMulticloudMode(null, req.getCloudSiteId());
92                     if (!isMulticloud) {
93                         int timeoutMinutes = msoHeatUtils.getVfHeatTimeoutValue(req.getModelCustomizationUuid(), false);
94                         pollDeleteResource(timeoutMinutes, req.getCloudSiteId(), req.getTenantId(), externalTask,
95                                 success);
96                     } else {
97                         success.setTrue();
98                     }
99                 } else if ("deleteVolumeGroupRequest".equals(requestType.get())) {
100                     logger.debug("Executing External Task Poll Service for Delete Volume Group");
101                     DeleteVolumeGroupRequest req =
102                             JAXB.unmarshal(new StringReader(xmlRequest), DeleteVolumeGroupRequest.class);
103                     boolean isMulticloud = vnfAdapterUtils.isMulticloudMode(null, req.getCloudSiteId());
104                     if (!isMulticloud) {
105                         pollDeleteResource(118, req.getCloudSiteId(), req.getTenantId(), externalTask, success);
106                     } else {
107                         success.setTrue();
108                     }
109                 } else if ("createNetworkRequest".equals(requestType.get())) {
110                     determineCreateNetworkStatus(xmlRequest, externalTask, success);
111                 } else if ("deleteNetworkRequest".equals(requestType.get())) {
112                     logger.debug("Executing External Task Poll Service for Delete Network");
113                     DeleteNetworkRequest req = JAXB.unmarshal(new StringReader(xmlRequest), DeleteNetworkRequest.class);
114                     pollDeleteResource(118, req.getCloudSiteId(), req.getTenantId(), externalTask, success);
115                 } else if ("updateNetworkRequest".equals(requestType.get())) {
116                     UpdateNetworkRequest req = JAXB.unmarshal(new StringReader(xmlRequest), UpdateNetworkRequest.class);
117                     pollUpdateResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
118                 }
119             }
120         } catch (Exception e) {
121             logger.error("Error during External Task Poll Service", e);
122             errorMessage = e.toString();
123             variables.put("openstackAdapterErrorMessage", errorMessage);
124         }
125
126         variables.put("OpenstackPollSuccess", success.booleanValue());
127         if (success.isTrue()) {
128             externalTaskService.complete(externalTask, variables);
129             logger.debug("The External Task Id: {}  Successful", externalTask.getId());
130         } else {
131             if (externalTask.getRetries() == null) {
132                 logger.debug("The External Task Id: {}  Failed, Setting Retries to Default Start Value: {}",
133                         externalTask.getId(), getRetrySequence().length);
134                 externalTaskService.handleFailure(externalTask, "errorMessage", "errorDetails",
135                         getRetrySequence().length, 10000);
136             } else if (externalTask.getRetries() != null && externalTask.getRetries() - 1 == 0) {
137                 logger.debug("The External Task Id: {}  Failed, All Retries Exhausted", externalTask.getId());
138                 externalTaskService.complete(externalTask, variables);
139             } else {
140                 logger.debug("The External Task Id: {}  Failed, Decrementing Retries: {} , Retry Delay: {}",
141                         externalTask.getId(), externalTask.getRetries() - 1,
142                         calculateRetryDelay(externalTask.getRetries()));
143                 externalTaskService.handleFailure(externalTask, "errorMessage", "errorDetails",
144                         externalTask.getRetries() - 1, calculateRetryDelay(externalTask.getRetries()));
145             }
146         }
147     }
148
149     private void determineCreateVolumeGroupStatus(String xmlRequest, ExternalTask externalTask, MutableBoolean success)
150             throws MsoException {
151         CreateVolumeGroupRequest req = JAXB.unmarshal(new StringReader(xmlRequest), CreateVolumeGroupRequest.class);
152         boolean isMulticloud = vnfAdapterUtils.isMulticloudMode(null, req.getCloudSiteId());
153         if (!isMulticloud) {
154             boolean pollRollbackStatus = externalTask.getVariable("PollRollbackStatus");
155             if (pollRollbackStatus) {
156                 logger.debug("Executing External Task Poll Service for Rollback Create Volume Group");
157                 pollDeleteResource(118, req.getCloudSiteId(), req.getTenantId(), externalTask, success);
158             } else {
159                 int timeoutMinutes = msoHeatUtils.getVfHeatTimeoutValue(req.getModelCustomizationUuid(), true);
160                 pollCreateResource(timeoutMinutes, req.getCloudSiteId(), req.getTenantId(), externalTask, success);
161             }
162         } else {
163             success.setTrue();
164         }
165     }
166
167     private void determineCreateVfModuleStatus(String xmlRequest, ExternalTask externalTask, MutableBoolean success)
168             throws MsoException {
169         CreateVfModuleRequest req = JAXB.unmarshal(new StringReader(xmlRequest), CreateVfModuleRequest.class);
170         boolean isMulticloud = vnfAdapterUtils.isMulticloudMode(null, req.getCloudSiteId());
171         if (!isMulticloud) {
172             boolean pollRollbackStatus = externalTask.getVariable("PollRollbackStatus");
173             int timeoutMinutes = msoHeatUtils.getVfHeatTimeoutValue(req.getModelCustomizationUuid(), false);
174             if (pollRollbackStatus) {
175                 logger.debug("Executing External Task Poll Service for Rollback Create Vf Module");
176                 pollDeleteResource(timeoutMinutes, req.getCloudSiteId(), req.getTenantId(), externalTask, success);
177             } else {
178                 logger.debug("Executing External Task Poll Service for Create Vf Module");
179                 pollCreateResource(timeoutMinutes, req.getCloudSiteId(), req.getTenantId(), externalTask, success);
180             }
181         } else {
182             success.setTrue();
183         }
184     }
185
186     private void determineCreateNetworkStatus(String xmlRequest, ExternalTask externalTask, MutableBoolean success)
187             throws MsoException {
188         CreateNetworkRequest req = JAXB.unmarshal(new StringReader(xmlRequest), CreateNetworkRequest.class);
189         boolean pollRollbackStatus = externalTask.getVariable("PollRollbackStatus");
190         int timeoutMinutes =
191                 msoHeatUtils.getNetworkHeatTimeoutValue(req.getModelCustomizationUuid(), req.getNetworkType());
192         if (pollRollbackStatus) {
193             logger.debug("Executing External Task Poll Service for Rollback Create Network");
194             pollDeleteResource(timeoutMinutes, req.getCloudSiteId(), req.getTenantId(), externalTask, success);
195         } else {
196             logger.debug("Executing External Task Poll Service for Create Network");
197             pollCreateResource(timeoutMinutes, req.getCloudSiteId(), req.getTenantId(), externalTask, success);
198         }
199     }
200
201     private void pollCreateResource(int pollingTimeout, String cloudSiteId, String tenantId, ExternalTask externalTask,
202             MutableBoolean success) throws MsoException {
203         Stack currentStack = createCurrentStack(externalTask.getVariable("stackId"));
204         Stack stack = msoHeatUtils.pollStackForStatus(pollingTimeout, currentStack, "CREATE_IN_PROGRESS", cloudSiteId,
205                 tenantId, false);
206         msoHeatUtils.postProcessStackCreate(stack, false, 0, false, cloudSiteId, tenantId, null);
207         success.setTrue();
208     }
209
210     private void pollDeleteResource(int pollingTimeout, String cloudSiteId, String tenantId, ExternalTask externalTask,
211             MutableBoolean success) throws MsoException {
212         Stack currentStack = createCurrentStack(externalTask.getVariable("stackId"));
213         Stack stack = msoHeatUtils.pollStackForStatus(pollingTimeout, currentStack, "DELETE_IN_PROGRESS", cloudSiteId,
214                 tenantId, true);
215         if (stack != null) { // if stack is null it was not found and no need to do post process
216             msoHeatUtils.postProcessStackDelete(stack);
217         }
218         success.setTrue();
219     }
220
221     private void pollUpdateResource(String cloudSiteId, String tenantId, ExternalTask externalTask,
222             MutableBoolean success) throws MsoException {
223         Stack currentStack = createCurrentStack(externalTask.getVariable("stackId"));
224         Stack stack =
225                 msoHeatUtils.pollStackForStatus(1, currentStack, "UPDATE_IN_PROGRESS", cloudSiteId, tenantId, false);
226         msoHeatUtils.postProcessStackUpdate(stack);
227         success.setTrue();
228     }
229
230     protected Optional<String> findRequestType(String xmlString) {
231         try {
232             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
233             DocumentBuilder builder = factory.newDocumentBuilder();
234             org.w3c.dom.Document doc;
235             doc = builder.parse(new ByteArrayInputStream(xmlString.getBytes("UTF-8")));
236             return Optional.of(doc.getDocumentElement().getNodeName());
237         } catch (Exception e) {
238             logger.error("Error Finding Request Type", e);
239             return Optional.empty();
240         }
241     }
242
243     private Stack createCurrentStack(String canonicalStackId) {
244         Stack currentStack = new Stack();
245         String stackName = canonicalStackId;
246         if (canonicalStackId.contains("/")) {
247             String[] stacks = canonicalStackId.split("/");
248             stackName = stacks[0];
249             currentStack.setId(stacks[1]);
250         }
251         currentStack.setStackName(stackName);
252         return currentStack;
253     }
254 }