c319fdc23c1dc5b4b61639e197b3e5fd6357a58a
[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                         pollDeleteResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
94                     } else {
95                         success.setTrue();
96                     }
97                 } else if ("deleteVolumeGroupRequest".equals(requestType.get())) {
98                     logger.debug("Executing External Task Poll Service for Delete Volume Group");
99                     DeleteVolumeGroupRequest req =
100                             JAXB.unmarshal(new StringReader(xmlRequest), DeleteVolumeGroupRequest.class);
101                     boolean isMulticloud = vnfAdapterUtils.isMulticloudMode(null, req.getCloudSiteId());
102                     if (!isMulticloud) {
103                         pollDeleteResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
104                     } else {
105                         success.setTrue();
106                     }
107                 } else if ("createNetworkRequest".equals(requestType.get())) {
108                     determineCreateNetworkStatus(xmlRequest, externalTask, success);
109                 } else if ("deleteNetworkRequest".equals(requestType.get())) {
110                     logger.debug("Executing External Task Poll Service for Delete Network");
111                     DeleteNetworkRequest req = JAXB.unmarshal(new StringReader(xmlRequest), DeleteNetworkRequest.class);
112                     pollDeleteResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
113                 } else if ("updateNetworkRequest".equals(requestType.get())) {
114                     UpdateNetworkRequest req = JAXB.unmarshal(new StringReader(xmlRequest), UpdateNetworkRequest.class);
115                     pollUpdateResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
116                 }
117             }
118         } catch (Exception e) {
119             logger.error("Error during External Task Poll Service", e);
120             errorMessage = e.toString();
121             variables.put("openstackAdapterErrorMessage", errorMessage);
122         }
123
124         variables.put("OpenstackPollSuccess", success.booleanValue());
125         if (success.isTrue()) {
126             externalTaskService.complete(externalTask, variables);
127             logger.debug("The External Task Id: {}  Successful", externalTask.getId());
128         } else {
129             if (externalTask.getRetries() == null) {
130                 logger.debug("The External Task Id: {}  Failed, Setting Retries to Default Start Value: {}",
131                         externalTask.getId(), getRetrySequence().length);
132                 externalTaskService.handleFailure(externalTask, "errorMessage", "errorDetails",
133                         getRetrySequence().length, 10000);
134             } else if (externalTask.getRetries() != null && externalTask.getRetries() - 1 == 0) {
135                 logger.debug("The External Task Id: {}  Failed, All Retries Exhausted", externalTask.getId());
136                 externalTaskService.complete(externalTask, variables);
137             } else {
138                 logger.debug("The External Task Id: {}  Failed, Decrementing Retries: {} , Retry Delay: {}",
139                         externalTask.getId(), externalTask.getRetries() - 1,
140                         calculateRetryDelay(externalTask.getRetries()));
141                 externalTaskService.handleFailure(externalTask, "errorMessage", "errorDetails",
142                         externalTask.getRetries() - 1, calculateRetryDelay(externalTask.getRetries()));
143             }
144         }
145     }
146
147     private void determineCreateVolumeGroupStatus(String xmlRequest, ExternalTask externalTask, MutableBoolean success)
148             throws MsoException {
149         CreateVolumeGroupRequest req = JAXB.unmarshal(new StringReader(xmlRequest), CreateVolumeGroupRequest.class);
150         boolean isMulticloud = vnfAdapterUtils.isMulticloudMode(null, req.getCloudSiteId());
151         if (!isMulticloud) {
152             boolean pollRollbackStatus = externalTask.getVariable("PollRollbackStatus");
153             if (pollRollbackStatus) {
154                 logger.debug("Executing External Task Poll Service for Rollback Create Volume Group");
155                 pollDeleteResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
156             } else {
157                 pollCreateResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
158             }
159         } else {
160             success.setTrue();
161         }
162     }
163
164     private void determineCreateVfModuleStatus(String xmlRequest, ExternalTask externalTask, MutableBoolean success)
165             throws MsoException {
166         CreateVfModuleRequest req = JAXB.unmarshal(new StringReader(xmlRequest), CreateVfModuleRequest.class);
167         boolean isMulticloud = vnfAdapterUtils.isMulticloudMode(null, req.getCloudSiteId());
168         if (!isMulticloud) {
169             boolean pollRollbackStatus = externalTask.getVariable("PollRollbackStatus");
170             if (pollRollbackStatus) {
171                 logger.debug("Executing External Task Poll Service for Rollback Create Vf Module");
172                 pollDeleteResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
173             } else {
174                 logger.debug("Executing External Task Poll Service for Create Vf Module");
175                 pollCreateResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
176             }
177         } else {
178             success.setTrue();
179         }
180     }
181
182     private void determineCreateNetworkStatus(String xmlRequest, ExternalTask externalTask, MutableBoolean success)
183             throws MsoException {
184         CreateNetworkRequest req = JAXB.unmarshal(new StringReader(xmlRequest), CreateNetworkRequest.class);
185         boolean pollRollbackStatus = externalTask.getVariable("PollRollbackStatus");
186         if (pollRollbackStatus) {
187             logger.debug("Executing External Task Poll Service for Rollback Create Network");
188             pollDeleteResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
189         } else {
190             logger.debug("Executing External Task Poll Service for Create Network");
191             pollCreateResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
192         }
193     }
194
195     private void pollCreateResource(String cloudSiteId, String tenantId, ExternalTask externalTask,
196             MutableBoolean success) throws MsoException {
197         Stack currentStack = createCurrentStack(externalTask.getVariable("stackId"));
198         Stack stack =
199                 msoHeatUtils.pollStackForStatus(1, currentStack, "CREATE_IN_PROGRESS", cloudSiteId, tenantId, false);
200         msoHeatUtils.postProcessStackCreate(stack, false, 0, false, cloudSiteId, tenantId, null);
201         success.setTrue();
202     }
203
204     private void pollDeleteResource(String cloudSiteId, String tenantId, ExternalTask externalTask,
205             MutableBoolean success) throws MsoException {
206         Stack currentStack = createCurrentStack(externalTask.getVariable("stackId"));
207         Stack stack =
208                 msoHeatUtils.pollStackForStatus(1, currentStack, "DELETE_IN_PROGRESS", cloudSiteId, tenantId, true);
209         if (stack != null) { // if stack is null it was not found and no need to do post process
210             msoHeatUtils.postProcessStackDelete(stack);
211         }
212         success.setTrue();
213     }
214
215     private void pollUpdateResource(String cloudSiteId, String tenantId, ExternalTask externalTask,
216             MutableBoolean success) throws MsoException {
217         Stack currentStack = createCurrentStack(externalTask.getVariable("stackId"));
218         Stack stack =
219                 msoHeatUtils.pollStackForStatus(1, currentStack, "UPDATE_IN_PROGRESS", cloudSiteId, tenantId, false);
220         msoHeatUtils.postProcessStackUpdate(stack);
221         success.setTrue();
222     }
223
224     protected Optional<String> findRequestType(String xmlString) {
225         try {
226             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
227             DocumentBuilder builder = factory.newDocumentBuilder();
228             org.w3c.dom.Document doc;
229             doc = builder.parse(new ByteArrayInputStream(xmlString.getBytes("UTF-8")));
230             return Optional.of(doc.getDocumentElement().getNodeName());
231         } catch (Exception e) {
232             logger.error("Error Finding Request Type", e);
233             return Optional.empty();
234         }
235     }
236
237     private Stack createCurrentStack(String canonicalStackId) {
238         Stack currentStack = new Stack();
239         String stackName = canonicalStackId;
240         if (canonicalStackId.contains("/")) {
241             String[] stacks = canonicalStackId.split("/");
242             stackName = stacks[0];
243             currentStack.setId(stacks[1]);
244         }
245         currentStack.setStackName(stackName);
246         return currentStack;
247     }
248
249 }