2  * ============LICENSE_START=======================================================
 
   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
 
  13  *      http://www.apache.org/licenses/LICENSE-2.0
 
  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=========================================================
 
  23 package org.onap.so.adapters.tasks.orchestration;
 
  25 import java.io.ByteArrayInputStream;
 
  26 import java.io.StringReader;
 
  27 import java.util.HashMap;
 
  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;
 
  56 public class PollService extends ExternalTaskUtils {
 
  58     private static final Logger logger = LoggerFactory.getLogger(PollService.class);
 
  61     private MsoHeatUtils msoHeatUtils;
 
  64     private VnfAdapterUtils vnfAdapterUtils;
 
  67     private AuditMDCSetup mdcSetup;
 
  69     public PollService() {
 
  70         super(RetrySequenceLevel.SHORT);
 
  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;
 
  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());
 
  93                         pollDeleteResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
 
  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());
 
 103                         pollDeleteResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
 
 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);
 
 118         } catch (Exception e) {
 
 119             logger.error("Error during External Task Poll Service", e);
 
 120             errorMessage = e.toString();
 
 121             variables.put("openstackAdapterErrorMessage", errorMessage);
 
 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());
 
 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);
 
 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()));
 
 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());
 
 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);
 
 157                 pollCreateResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
 
 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());
 
 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);
 
 174                 logger.debug("Executing External Task Poll Service for Create Vf Module");
 
 175                 pollCreateResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
 
 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);
 
 190             logger.debug("Executing External Task Poll Service for Create Network");
 
 191             pollCreateResource(req.getCloudSiteId(), req.getTenantId(), externalTask, success);
 
 195     private void pollCreateResource(String cloudSiteId, String tenantId, ExternalTask externalTask,
 
 196             MutableBoolean success) throws MsoException {
 
 197         Stack currentStack = createCurrentStack(externalTask.getVariable("stackId"));
 
 199                 msoHeatUtils.pollStackForStatus(1, currentStack, "CREATE_IN_PROGRESS", cloudSiteId, tenantId, false);
 
 200         msoHeatUtils.postProcessStackCreate(stack, false, 0, false, cloudSiteId, tenantId, null);
 
 204     private void pollDeleteResource(String cloudSiteId, String tenantId, ExternalTask externalTask,
 
 205             MutableBoolean success) throws MsoException {
 
 206         Stack currentStack = createCurrentStack(externalTask.getVariable("stackId"));
 
 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);
 
 215     private void pollUpdateResource(String cloudSiteId, String tenantId, ExternalTask externalTask,
 
 216             MutableBoolean success) throws MsoException {
 
 217         Stack currentStack = createCurrentStack(externalTask.getVariable("stackId"));
 
 219                 msoHeatUtils.pollStackForStatus(1, currentStack, "UPDATE_IN_PROGRESS", cloudSiteId, tenantId, false);
 
 220         msoHeatUtils.postProcessStackUpdate(stack);
 
 224     protected Optional<String> findRequestType(String xmlString) {
 
 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();
 
 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]);
 
 245         currentStack.setStackName(stackName);