AT&T 1712 and 1802 release code
[so.git] / asdc-controller / src / main / java / org / openecomp / mso / asdc / client / ASDCController.java
index 22c4b04..6a75229 100644 (file)
@@ -1,5 +1,5 @@
 /*-\r
- * ============LICENSE_START=======================================================\r
+d * ============LICENSE_START=======================================================\r
  * ONAP - SO\r
  * ================================================================================\r
  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.\r
@@ -26,14 +26,18 @@ import java.io.File;
 import java.io.FileOutputStream;\r
 import java.io.IOException;\r
 import java.io.UnsupportedEncodingException;\r
+import java.util.ArrayList;\r
 import java.util.List;\r
 \r
 import org.openecomp.sdc.api.IDistributionClient;\r
 import org.openecomp.sdc.api.consumer.IDistributionStatusMessage;\r
+import org.openecomp.sdc.api.consumer.IFinalDistrStatusMessage;\r
 import org.openecomp.sdc.api.consumer.INotificationCallback;\r
+import org.openecomp.sdc.api.consumer.IStatusCallback;\r
 import org.openecomp.sdc.api.notification.IArtifactInfo;\r
 import org.openecomp.sdc.api.notification.INotificationData;\r
 import org.openecomp.sdc.api.notification.IResourceInstance;\r
+import org.openecomp.sdc.api.notification.IStatusData;\r
 import org.openecomp.sdc.api.results.IDistributionClientDownloadResult;\r
 import org.openecomp.sdc.api.results.IDistributionClientResult;\r
 import org.openecomp.sdc.impl.DistributionClientFactory;\r
@@ -48,10 +52,14 @@ import org.openecomp.mso.asdc.installer.ToscaResourceStructure;
 import org.openecomp.mso.asdc.installer.VfResourceStructure;\r
 import org.openecomp.mso.asdc.installer.heat.ToscaResourceInstaller;\r
 import org.openecomp.mso.asdc.installer.heat.VfResourceInstaller;\r
+import org.openecomp.mso.asdc.tenantIsolation.DistributionStatus;\r
+import org.openecomp.mso.asdc.tenantIsolation.WatchdogDistribution;\r
 import org.openecomp.mso.asdc.util.ASDCNotificationLogging;\r
 import org.openecomp.mso.logger.MessageEnum;\r
 import org.openecomp.mso.logger.MsoAlarmLogger;\r
 import org.openecomp.mso.logger.MsoLogger;\r
+import org.openecomp.mso.properties.MsoPropertiesFactory;\r
+import org.openecomp.mso.requestsdb.WatchdogDistributionStatusDb;\r
 import org.openecomp.mso.utils.UUIDChecker;\r
 \r
 public class ASDCController {\r
@@ -66,6 +74,96 @@ public class ASDCController {
 \r
     protected ToscaResourceInstaller toscaInstaller;\r
     \r
+    private static MsoPropertiesFactory msoPropertiesFactory = new MsoPropertiesFactory();\r
+    \r
+   \r
+   private final class ResourceInstance implements IResourceInstance {\r
+              \r
+        @Override\r
+        public String getResourceInstanceName(){\r
+               return new String();\r
+        }\r
+        \r
+        @Override\r
+        public String getResourceName(){\r
+               return new String();\r
+        }\r
+        \r
+        @Override\r
+        public String getResourceVersion(){\r
+               return new String();\r
+        }\r
+        \r
+        @Override\r
+        public String getResourceType(){\r
+               return new String();\r
+        }\r
+        \r
+        @Override\r
+        public String getResourceUUID(){\r
+               return new String();\r
+        }\r
+        \r
+        // Method descriptor #10 ()Ljava/util/List;\r
+        @Override\r
+        public java.util.List getArtifacts(){\r
+               return new ArrayList();\r
+        }\r
+        \r
+        @Override\r
+        public String getResourceInvariantUUID(){\r
+               return new String();\r
+        }\r
+        \r
+        @Override\r
+        public String getResourceCustomizationUUID(){\r
+               return new String();\r
+        }\r
+        \r
+        @Override\r
+        public String getCategory(){\r
+               return new String();\r
+        }\r
+        \r
+        @Override\r
+        public String getSubcategory(){\r
+               return new String();\r
+        }\r
+       \r
+    }\r
+    \r
+   private final class ASDCStatusCallBack implements IStatusCallback {\r
+               \r
+        @Override\r
+        public void activateCallback (IStatusData iStatus) {\r
+               \r
+            long startTime = System.currentTimeMillis ();\r
+            UUIDChecker.generateUUID (LOGGER);\r
+            MsoLogger.setServiceName ("ASDCStatusCallBack");\r
+            MsoLogger.setLogContext (iStatus.getDistributionID (), iStatus.getComponentName());\r
+            String event = "Receive a callback componentStatus in ASDC, for componentName: " + iStatus.getComponentName() + " and status of " + iStatus.getStatus() + " distributionID of " + iStatus.getDistributionID() + \r
+                              " consumerID of " + iStatus.getConsumerID() + " errorReason of " + iStatus.getErrorReason();\r
+            \r
+            try{\r
+               \r
+               if (iStatus.getStatus() == DistributionStatusEnum.COMPONENT_DONE_OK || \r
+                       iStatus.getStatus() == DistributionStatusEnum.COMPONENT_DONE_ERROR) {\r
+                                       \r
+                       LOGGER.debug(event);\r
+            \r
+                       toscaInstaller.installTheComponentStatus(iStatus);\r
+               \r
+               }\r
+            \r
+            }catch(ArtifactInstallerException e){\r
+               System.out.println("Error in ASDCStatusCallback " + e.getMessage());\r
+               LOGGER.debug("Error in ASDCStatusCallback " + e.getMessage());\r
+            }\r
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Completed the Status Call Back"); \r
+        }\r
+       \r
+    }\r
+    \r
 \r
     /**\r
      * Inner class for Notification callback\r
@@ -96,6 +194,7 @@ public class ASDCController {
             LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Completed the treatment of the notification");\r
         }\r
     }\r
+    \r
 \r
     // ***** Controller STATUS code\r
 \r
@@ -136,7 +235,6 @@ public class ASDCController {
     }\r
 \r
     // ***** END of Controller STATUS code\r
-\r
     protected ASDCConfiguration asdcConfig;\r
     private IDistributionClient distributionClient;\r
     private IVfResourceInstaller resourceInstaller;\r
@@ -224,7 +322,7 @@ public class ASDCController {
         }\r
         long initStartTime = System.currentTimeMillis ();\r
         IDistributionClientResult result = this.distributionClient.init (asdcConfig,\r
-                                                                         new ASDCNotificationCallBack (this));\r
+                                                                         new ASDCNotificationCallBack (this), new ASDCStatusCallBack());\r
         if (!result.getDistributionActionResult ().equals (DistributionActionResultEnum.SUCCESS)) {\r
             String endEvent = "ASDC distribution client init failed with reason:"\r
                               + result.getDistributionMessageResult ();\r
@@ -284,20 +382,20 @@ public class ASDCController {
 \r
     private boolean checkResourceAlreadyDeployed (VfResourceStructure resource) throws ArtifactInstallerException {\r
 \r
-       if (toscaInstaller.isResourceAlreadyDeployed (resource)) {\r
-            LOGGER.info (MessageEnum.ASDC_ARTIFACT_ALREADY_EXIST,\r
+       \r
+               if (toscaInstaller.isResourceAlreadyDeployed (resource)) {\r
+                       LOGGER.info (MessageEnum.ASDC_ARTIFACT_ALREADY_EXIST,\r
                     resource.getResourceInstance().getResourceInstanceName(),\r
                     resource.getResourceInstance().getResourceUUID(),\r
                     resource.getResourceInstance().getResourceName(), "", "");\r
 \r
-            this.sendDeployNotificationsForResource(resource,DistributionStatusEnum.ALREADY_DOWNLOADED,null);\r
-            this.sendDeployNotificationsForResource(resource,DistributionStatusEnum.ALREADY_DEPLOYED,null);\r
-\r
-            return true;\r
-        } else {\r
-            return false;\r
-        }\r
+                       this.sendDeployNotificationsForResource(resource,DistributionStatusEnum.ALREADY_DOWNLOADED,null);\r
+                       this.sendDeployNotificationsForResource(resource,DistributionStatusEnum.ALREADY_DEPLOYED,null);\r
 \r
+               return true;\r
+       } else {\r
+               return false;\r
+       }\r
     }\r
 \r
     private final static String UUID_PARAM = "(UUID:";\r
@@ -413,7 +511,7 @@ public class ASDCController {
 \r
        for (IArtifactInfo artifactInfo : vfResourceStructure.getResourceInstance().getArtifacts()) {\r
 \r
-               if (DistributionStatusEnum.DEPLOY_OK.equals(distribStatus)\r
+               if ((DistributionStatusEnum.DEPLOY_OK.equals(distribStatus) && !artifactInfo.getArtifactType().equalsIgnoreCase("OTHER"))\r
                                // This could be NULL if the artifact is a VF module artifact, this won't be present in the MAP\r
                                && vfResourceStructure.getArtifactsMapByUUID().get(artifactInfo.getArtifactUUID()) != null\r
                                && vfResourceStructure.getArtifactsMapByUUID().get(artifactInfo.getArtifactUUID()).getDeployedInDb() == 0) {\r
@@ -435,7 +533,34 @@ public class ASDCController {
                }\r
        }\r
     }\r
-\r
+    \r
+    private void sendCsarDeployNotification(INotificationData iNotif, VfResourceStructure resourceStructure, ToscaResourceStructure toscaResourceStructure, boolean deploySuccessful, String errorReason) {\r
+       \r
+                       IArtifactInfo csarArtifact = toscaResourceStructure.getToscaArtifact();\r
+                       \r
+                       if(deploySuccessful){\r
+                               \r
+                       this.sendASDCNotification (NotificationType.DEPLOY,\r
+                                         csarArtifact.getArtifactURL (),\r
+                                 asdcConfig.getConsumerID (),\r
+                                 resourceStructure.getNotification().getDistributionID(),\r
+                                 DistributionStatusEnum.DEPLOY_OK,\r
+                                 errorReason,\r
+                                 System.currentTimeMillis ());\r
+                               \r
+                       } else {\r
+                               \r
+                               this.sendASDCNotification (NotificationType.DEPLOY,\r
+                                         csarArtifact.getArtifactURL (),\r
+                                 asdcConfig.getConsumerID (),\r
+                                 resourceStructure.getNotification().getDistributionID(),\r
+                                 DistributionStatusEnum.DEPLOY_ERROR,\r
+                                 errorReason,\r
+                                 System.currentTimeMillis ());\r
+                               \r
+                       }\r
+    }\r
+    \r
     private void deployResourceStructure (VfResourceStructure resourceStructure, ToscaResourceStructure toscaResourceStructure) throws ArtifactInstallerException {\r
 \r
        LOGGER.info (MessageEnum.ASDC_START_DEPLOY_ARTIFACT, resourceStructure.getResourceInstance().getResourceInstanceName(), resourceStructure.getResourceInstance().getResourceUUID(), "ASDC", "deployResourceStructure");\r
@@ -445,21 +570,10 @@ public class ASDCController {
                if("VF".equals(resourceType) && !"Allotted Resource".equalsIgnoreCase(category)){\r
                        resourceStructure.createVfModuleStructures();\r
                }\r
-               //resourceInstaller.installTheResource (resourceStructure);\r
-                               \r
-                       //ToscaResourceInstaller tri = new ToscaResourceInstaller();\r
-               toscaInstaller.installTheResource(toscaResourceStructure, resourceStructure);\r
-                       \r
-               /*      if(toscaResourceStructure.isVnfAlreadyInstalled()){\r
-                   LOGGER.info (MessageEnum.ASDC_ARTIFACT_ALREADY_EXIST,\r
-                               toscaResourceStructure.getCatalogVnfResource().getModelName(),\r
-                               toscaResourceStructure.getCatalogVnfResource().getModelUuid(),\r
-                               toscaResourceStructure.getCatalogVnfResource().getModelUuid(),"","");\r
+               \r
 \r
-            \r
-                   this.sendDeployNotificationsForResource(resourceStructure,DistributionStatusEnum.ALREADY_DOWNLOADED,null);\r
-                   this.sendDeployNotificationsForResource(resourceStructure,DistributionStatusEnum.ALREADY_DEPLOYED,null);\r
-                       } */\r
+               toscaInstaller.installTheResource(toscaResourceStructure, resourceStructure);\r
+                                                       \r
 \r
         } catch (ArtifactInstallerException e) {\r
                LOGGER.info (MessageEnum.ASDC_ARTIFACT_DOWNLOAD_FAIL,\r
@@ -470,7 +584,7 @@ public class ASDCController {
                throw e;\r
         }\r
 \r
-        if (resourceStructure.isDeployedSuccessfully()) {\r
+        if (resourceStructure.isDeployedSuccessfully() || toscaResourceStructure.isDeployedSuccessfully()) {\r
                LOGGER.info (MessageEnum.ASDC_ARTIFACT_DEPLOY_SUC,\r
                                resourceStructure.getResourceInstance().getResourceName(),\r
                                resourceStructure.getResourceInstance().getResourceUUID(),\r
@@ -479,6 +593,7 @@ public class ASDCController {
         }\r
 \r
     }\r
+    \r
 \r
     private enum NotificationType {\r
        DOWNLOAD, DEPLOY\r
@@ -541,10 +656,42 @@ public class ASDCController {
         }\r
         LOGGER.recordMetricEvent (subStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully sent notification to ASDC", "ASDC", action, null);\r
     }\r
+    \r
+    private void sendFinalDistributionStatus (\r
+               String distributionID,\r
+               DistributionStatusEnum status,\r
+               String errorReason) {\r
+\r
+\r
+       LOGGER.debug ("Enter sendFinalDistributionStatus with DistributionID " + distributionID + " and Status of " + status.name() + " and ErrorReason " + errorReason);\r
+\r
+       long subStarttime = System.currentTimeMillis ();\r
+       try {\r
+               \r
+               \r
+               IFinalDistrStatusMessage finalDistribution = new FinalDistributionStatusMessage(distributionID,status,subStarttime, asdcConfig.getConsumerID());\r
+               \r
+               if(errorReason == null){\r
+                       this.distributionClient.sendFinalDistrStatus(finalDistribution);\r
+               }else{\r
+                       this.distributionClient.sendFinalDistrStatus(finalDistribution, errorReason);\r
+               }\r
+               \r
\r
+       } catch (RuntimeException e) {\r
+               // TODO: May be a list containing the unsent notification should be\r
+               // kept\r
+               LOGGER.debug ("Exception caught in sendFinalDistributionStatus " + e.getMessage());\r
+               LOGGER.warn (MessageEnum.ASDC_SEND_NOTIF_ASDC_EXEC, "ASDC", "sendASDCNotification", MsoLogger.ErrorCode.SchemaError, "RuntimeException - sendASDCNotification", e);\r
+       }\r
+       LOGGER.recordMetricEvent (subStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully sent Final notification to ASDC", "ASDC", null, null);\r
+    }\r
 \r
     public void treatNotification (INotificationData iNotif) {\r
 \r
        int noOfArtifacts = 0;\r
+       WatchdogDistribution wd = new WatchdogDistribution();\r
+\r
        for (IResourceInstance resource : iNotif.getResources ()) {\r
                noOfArtifacts += resource.getArtifacts ().size ();\r
        }\r
@@ -561,21 +708,102 @@ public class ASDCController {
                                                \r
                        // Process only the Resource artifacts in MSO\r
                        for (IResourceInstance resource : iNotif.getResources()) {\r
-\r
-                               // We process only VNF(VF) and Network(VL) resources on MSO Side\r
-                               // We process only VNF resource on MSO Side\r
-                               if ("VF".equals(resource.getResourceType()) || "VL".equals(resource.getResourceType())) {\r
-                                       this.processResourceNotification(iNotif,resource);\r
-                               }\r
+                               \r
+                               // We process only VNF(VF), Network(VL) and PNF resources on MSO Side\r
+                               //if ("VF".equals(resource.getResourceType()) || "VL".equals(resource.getResourceType()) || "PNF".equals(resource.getResourceType())){\r
+                               this.processResourceNotification(iNotif,resource);\r
+                               //}\r
 \r
                        }\r
+                       \r
+                       //Handle services without any resources \r
+                       if (iNotif.getResources() == null || iNotif.getResources().size() < 1){\r
+                               \r
+                               this.processResourceNotification(iNotif, new ResourceInstance());\r
+                       }\r
+                       \r
+                       //********************************************************************************************************\r
+                       //Start Watchdog loop and wait for all components to complete before reporting final status back. \r
+                       // **If timer expires first then we will report a Distribution Error back to ASDC\r
+                       //********************************************************************************************************\r
+               long initialStartTime = System.currentTimeMillis();\r
+               boolean componentsComplete = false;\r
+               String distributionStatus = null;\r
+               String watchdogError = null;\r
+               String overallStatus = null;\r
+               int watchDogTimeout = asdcConfig.getWatchDogTimeout() * 1000;\r
+               boolean isDeploySuccess = false;\r
+               WatchdogDistributionStatusDb wdDistributionStatus = WatchdogDistributionStatusDb.getInstance();\r
+               \r
+                                               \r
+               while(componentsComplete == false && (System.currentTimeMillis() - initialStartTime) < watchDogTimeout)\r
+               {\r
+                                               \r
+                       try{\r
+                       \r
+                               distributionStatus = wd.getOverallDistributionStatus(iNotif.getDistributionID());\r
+                               Thread.sleep(watchDogTimeout / 10);\r
+               \r
+                       }catch(Exception e){\r
+                               LOGGER.debug ("Exception in Watchdog Loop " + e.getMessage());\r
+                               Thread.sleep(watchDogTimeout / 10);\r
+                       }\r
+                       \r
+                       if(distributionStatus != null && !distributionStatus.equalsIgnoreCase(DistributionStatus.INCOMPLETE.name())){\r
+                               \r
+                               if(distributionStatus.equalsIgnoreCase(DistributionStatus.SUCCESS.name())){\r
+                                       isDeploySuccess = true;\r
+                                       overallStatus = DistributionStatusEnum.DISTRIBUTION_COMPLETE_OK.name();\r
+                               }else{\r
+                                       overallStatus = DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR.name();\r
+                               }\r
+                               \r
+                               componentsComplete = true;\r
+                       }\r
+               }\r
+               \r
+               if(componentsComplete == false){\r
+                       LOGGER.debug("Timeout of " + watchDogTimeout + " seconds was reached before all components reported status");\r
+                       watchdogError = "Timeout occurred while waiting for all components to report status";\r
+                       overallStatus = DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR.name();\r
+               }\r
+               \r
+               if(distributionStatus == null){\r
+                       overallStatus = DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR.name();\r
+                       LOGGER.debug("DistributionStatus is null for DistributionId: " + iNotif.getDistributionID());\r
+                               \r
+               }\r
+               \r
+               try {\r
+                       wd.executePatchAAI(iNotif.getDistributionID(), iNotif.getServiceInvariantUUID(), overallStatus);\r
+                       LOGGER.debug ("A&AI Updated succefully with Distribution Status!");\r
+               }\r
+               catch(Exception e) {\r
+                       LOGGER.debug ("Exception in Watchdog executePatchAAI(): " + e.getMessage());\r
+                       watchdogError = "Error calling A&AI " + e.getMessage();\r
+                       if(e.getCause() != null) {\r
+                               LOGGER.debug ("Exception caused by: " + e.getCause().getMessage());\r
+                       }\r
+               }\r
+       \r
+               \r
+               if(isDeploySuccess && watchdogError == null){\r
+                       sendFinalDistributionStatus(iNotif.getDistributionID(), DistributionStatusEnum.DISTRIBUTION_COMPLETE_OK, null);\r
+                       wdDistributionStatus.updateWatchdogDistributionIdStatus(iNotif.getDistributionID(), DistributionStatusEnum.DISTRIBUTION_COMPLETE_OK.name());        \r
+               } else {\r
+                       sendFinalDistributionStatus(iNotif.getDistributionID(), DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR, watchdogError);\r
+                       wdDistributionStatus.updateWatchdogDistributionIdStatus(iNotif.getDistributionID(), DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR.name());        \r
+               }\r
+               \r
+               \r
 \r
-\r
-\r
-        } catch (RuntimeException e) {\r
+        } catch (Exception e) {\r
             LOGGER.error (MessageEnum.ASDC_GENERAL_EXCEPTION_ARG,\r
                           "Unexpected exception caught during the notification processing", "ASDC", "treatNotification", MsoLogger.ErrorCode.SchemaError, "RuntimeException in treatNotification",\r
                           e);\r
+            \r
+             sendFinalDistributionStatus(iNotif.getDistributionID(), DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR, e.getMessage());\r
+            \r
         } finally {\r
             this.changeControllerStatus (ASDCControllerStatus.IDLE);\r
         }\r
@@ -586,6 +814,8 @@ public class ASDCController {
                // For each artifact, create a structure describing the VFModule in a ordered flat level\r
        VfResourceStructure resourceStructure = new VfResourceStructure(iNotif,resource);\r
        ToscaResourceStructure toscaResourceStructure = new ToscaResourceStructure();\r
+       boolean deploySuccessful = true;\r
+       String errorMessage = null;\r
 \r
                try {\r
 \r
@@ -605,12 +835,22 @@ public class ASDCController {
                                                }\r
 \r
                                }\r
-\r
                                this.processCsarServiceArtifacts(iNotif, toscaResourceStructure);\r
                                \r
-                               this.deployResourceStructure(resourceStructure, toscaResourceStructure);\r
+                               try{\r
+                               \r
+                                       this.deployResourceStructure(resourceStructure, toscaResourceStructure);\r
+                                       \r
+                               } catch(ArtifactInstallerException e){\r
+                                       deploySuccessful = false;\r
+                                       errorMessage = e.getMessage();\r
+                               }\r
+                                                                                               \r
+                                       this.sendCsarDeployNotification(iNotif, resourceStructure, toscaResourceStructure, deploySuccessful, errorMessage);\r
+                                       \r
 \r
-                       }\r
+\r
+               }\r
                } catch (ArtifactInstallerException | ASDCDownloadException | UnsupportedEncodingException e) {\r
                        LOGGER.error(MessageEnum.ASDC_GENERAL_EXCEPTION_ARG,\r
                                        "Exception caught during Installation of artifact", "ASDC", "processResourceNotification", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in processResourceNotification", e);\r