6a5381cf3e145e316cc5cb92cb12b7d0e897d10c
[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.logging.tasks.AuditMDCSetup;
44 import org.onap.so.openstack.exceptions.MsoException;
45 import org.onap.so.openstack.utils.MsoHeatUtils;
46 import org.onap.so.utils.ExternalTaskUtils;
47 import org.onap.so.utils.RetrySequenceLevel;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50 import org.springframework.beans.factory.annotation.Autowired;
51 import org.springframework.stereotype.Component;
52 import com.woorea.openstack.heat.model.Stack;
53
54 @Component
55 public class PollService extends ExternalTaskUtils {
56
57     private static final Logger logger = LoggerFactory.getLogger(PollService.class);
58
59     @Autowired
60     private MsoHeatUtils msoHeatUtils;
61
62     @Autowired
63     private AuditMDCSetup mdcSetup;
64
65     public PollService() {
66         super(RetrySequenceLevel.SHORT);
67     }
68
69     public void executeExternalTask(ExternalTask externalTask, ExternalTaskService externalTaskService) {
70         mdcSetup.setupMDC(externalTask);
71         logger.debug("Starting External Task Poll Service");
72         Map<String, Object> variables = new HashMap<>();
73         MutableBoolean success = new MutableBoolean();
74         String errorMessage = null;
75         try {
76             String xmlRequest = externalTask.getVariable("openstackAdapterTaskRequest");
77             if (xmlRequest != null) {
78                 Optional<String> requestType = findRequestType(xmlRequest);
79                 if ("createVolumeGroupRequest".equals(requestType.get())) {
80                     determineCreateVolumeGroupStatus(xmlRequest, externalTask, success);
81                 } else if ("createVfModuleRequest".equals(requestType.get())) {
82                     determineCreateVfModuleStatus(xmlRequest, externalTask, success);
83                 } else if ("deleteVfModuleRequest".equals(requestType.get())) {
84                     logger.debug("Executing External Task Poll Service for Delete Vf Module");
85                     DeleteVfModuleRequest req =
86                             JAXB.unmarshal(new StringReader(xmlRequest), DeleteVfModuleRequest.class);
87                     pollDeleteResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
88                 } else if ("deleteVolumeGroupRequest".equals(requestType.get())) {
89                     logger.debug("Executing External Task Poll Service for Delete Volume Group");
90                     DeleteVolumeGroupRequest req =
91                             JAXB.unmarshal(new StringReader(xmlRequest), DeleteVolumeGroupRequest.class);
92                     pollDeleteResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
93                 } else if ("createNetworkRequest".equals(requestType.get())) {
94                     determineCreateNetworkStatus(xmlRequest, externalTask, success);
95                 } else if ("deleteNetworkRequest".equals(requestType.get())) {
96                     logger.debug("Executing External Task Poll Service for Delete Network");
97                     DeleteNetworkRequest req = JAXB.unmarshal(new StringReader(xmlRequest), DeleteNetworkRequest.class);
98                     pollDeleteResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
99                 } else if ("updateNetworkRequest".equals(requestType.get())) {
100                     UpdateNetworkRequest req = JAXB.unmarshal(new StringReader(xmlRequest), UpdateNetworkRequest.class);
101                     pollUpdateResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
102                 }
103             }
104         } catch (Exception e) {
105             logger.error("Error during External Task Poll Service", e);
106             errorMessage = e.toString();
107             variables.put("openstackAdapterErrorMessage", errorMessage);
108         }
109
110         variables.put("OpenstackPollSuccess", success.booleanValue());
111         if (success.isTrue()) {
112             externalTaskService.complete(externalTask, variables);
113             logger.debug("The External Task Id: {}  Successful", externalTask.getId());
114         } else {
115             if (externalTask.getRetries() == null) {
116                 logger.debug("The External Task Id: {}  Failed, Setting Retries to Default Start Value: {}",
117                         externalTask.getId(), getRetrySequence().length);
118                 externalTaskService.handleFailure(externalTask, "errorMessage", "errorDetails",
119                         getRetrySequence().length, 10000);
120             } else if (externalTask.getRetries() != null && externalTask.getRetries() - 1 == 0) {
121                 logger.debug("The External Task Id: {}  Failed, All Retries Exhausted", externalTask.getId());
122                 externalTaskService.complete(externalTask, variables);
123             } else {
124                 logger.debug("The External Task Id: {}  Failed, Decrementing Retries: {} , Retry Delay: {}",
125                         externalTask.getId(), externalTask.getRetries() - 1,
126                         calculateRetryDelay(externalTask.getRetries()));
127                 externalTaskService.handleFailure(externalTask, "errorMessage", "errorDetails",
128                         externalTask.getRetries() - 1, calculateRetryDelay(externalTask.getRetries()));
129             }
130         }
131     }
132
133     private void determineCreateVolumeGroupStatus(String xmlRequest, ExternalTask externalTask, MutableBoolean success)
134             throws MsoException {
135         CreateVolumeGroupRequest req = JAXB.unmarshal(new StringReader(xmlRequest), CreateVolumeGroupRequest.class);
136         boolean pollRollbackStatus = externalTask.getVariable("PollRollbackStatus");
137         if (pollRollbackStatus) {
138             logger.debug("Executing External Task Poll Service for Rollback Create Volume Group");
139             pollDeleteResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
140         } else {
141             pollCreateResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
142         }
143     }
144
145     private void determineCreateVfModuleStatus(String xmlRequest, ExternalTask externalTask, MutableBoolean success)
146             throws MsoException {
147         CreateVfModuleRequest req = JAXB.unmarshal(new StringReader(xmlRequest), CreateVfModuleRequest.class);
148         boolean pollRollbackStatus = externalTask.getVariable("PollRollbackStatus");
149         if (pollRollbackStatus) {
150             logger.debug("Executing External Task Poll Service for Rollback Create Vf Module");
151             pollDeleteResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
152         } else {
153             logger.debug("Executing External Task Poll Service for Create Vf Module");
154             pollCreateResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
155         }
156     }
157
158     private void determineCreateNetworkStatus(String xmlRequest, ExternalTask externalTask, MutableBoolean success)
159             throws MsoException {
160         CreateNetworkRequest req = JAXB.unmarshal(new StringReader(xmlRequest), CreateNetworkRequest.class);
161         boolean pollRollbackStatus = externalTask.getVariable("PollRollbackStatus");
162         if (pollRollbackStatus) {
163             logger.debug("Executing External Task Poll Service for Rollback Create Network");
164             pollDeleteResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
165         } else {
166             logger.debug("Executing External Task Poll Service for Create Network");
167             pollCreateResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
168         }
169     }
170
171     private void pollCreateResource(String cloudSiteId, String tenantId, ExternalTask externalTask,
172             MutableBoolean success) throws MsoException {
173         Stack currentStack = createCurrentStack(externalTask.getVariable("stackId"));
174         Stack stack =
175                 msoHeatUtils.pollStackForStatus(1, currentStack, "CREATE_IN_PROGRESS", cloudSiteId, tenantId, false);
176         msoHeatUtils.postProcessStackCreate(stack, false, 0, false, cloudSiteId, tenantId, null);
177         success.setTrue();
178     }
179
180     private void pollDeleteResource(String cloudSiteId, String tenantId, ExternalTask externalTask,
181             MutableBoolean success) throws MsoException {
182         Stack currentStack = createCurrentStack(externalTask.getVariable("stackId"));
183         Stack stack =
184                 msoHeatUtils.pollStackForStatus(1, currentStack, "DELETE_IN_PROGRESS", cloudSiteId, tenantId, true);
185         if (stack != null) { // if stack is null it was not found and no need to do post process
186             msoHeatUtils.postProcessStackDelete(stack);
187         }
188         success.setTrue();
189     }
190
191     private void pollUpdateResource(String cloudSiteId, String tenantId, ExternalTask externalTask,
192             MutableBoolean success) throws MsoException {
193         Stack currentStack = createCurrentStack(externalTask.getVariable("stackId"));
194         Stack stack =
195                 msoHeatUtils.pollStackForStatus(1, currentStack, "UPDATE_IN_PROGRESS", cloudSiteId, tenantId, false);
196         msoHeatUtils.postProcessStackUpdate(stack);
197         success.setTrue();
198     }
199
200     protected Optional<String> findRequestType(String xmlString) {
201         try {
202             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
203             DocumentBuilder builder = factory.newDocumentBuilder();
204             org.w3c.dom.Document doc;
205             doc = builder.parse(new ByteArrayInputStream(xmlString.getBytes("UTF-8")));
206             return Optional.of(doc.getDocumentElement().getNodeName());
207         } catch (Exception e) {
208             logger.error("Error Finding Request Type", e);
209             return Optional.empty();
210         }
211     }
212
213     private Stack createCurrentStack(String canonicalStackId) {
214         Stack currentStack = new Stack();
215         String stackName = canonicalStackId;
216         if (canonicalStackId.contains("/")) {
217             String[] stacks = canonicalStackId.split("/");
218             stackName = stacks[0];
219             currentStack.setId(stacks[1]);
220         }
221         currentStack.setStackName(stackName);
222         return currentStack;
223     }
224
225 }