Containerization feature of SO
[so.git] / asdc-controller / src / main / java / org / onap / so / asdc / client / ASDCController.java
1 /*-
2 d * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * Copyright (C) 2017 Huawei Technologies Co., Ltd. All rights reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.so.asdc.client;
23
24
25 import java.io.FileOutputStream;
26 import java.io.IOException;
27 import java.io.UnsupportedEncodingException;
28 import java.util.List;
29
30 import org.onap.sdc.api.IDistributionClient;
31 import org.onap.sdc.api.consumer.IDistributionStatusMessage;
32 import org.onap.sdc.api.consumer.IFinalDistrStatusMessage;
33 import org.onap.sdc.api.notification.IArtifactInfo;
34 import org.onap.sdc.api.notification.INotificationData;
35 import org.onap.sdc.api.notification.IResourceInstance;
36 import org.onap.sdc.api.results.IDistributionClientDownloadResult;
37 import org.onap.sdc.api.results.IDistributionClientResult;
38 import org.onap.sdc.impl.DistributionClientFactory;
39 import org.onap.sdc.utils.DistributionActionResultEnum;
40 import org.onap.sdc.utils.DistributionStatusEnum;
41 import org.onap.so.asdc.client.exceptions.ASDCControllerException;
42 import org.onap.so.asdc.client.exceptions.ASDCDownloadException;
43 import org.onap.so.asdc.client.exceptions.ASDCParametersException;
44 import org.onap.so.asdc.client.exceptions.ArtifactInstallerException;
45 import org.onap.so.asdc.installer.IVfResourceInstaller;
46 import org.onap.so.asdc.installer.ToscaResourceStructure;
47 import org.onap.so.asdc.installer.VfResourceStructure;
48 import org.onap.so.asdc.installer.heat.ToscaResourceInstaller;
49 import org.onap.so.asdc.tenantIsolation.DistributionStatus;
50 import org.onap.so.asdc.tenantIsolation.WatchdogDistribution;
51 import org.onap.so.asdc.util.ASDCNotificationLogging;
52 import org.onap.so.db.request.beans.WatchdogDistributionStatus;
53 import org.onap.so.db.request.data.repository.WatchdogDistributionStatusRepository;
54 import org.onap.so.logger.MessageEnum;
55 import org.onap.so.logger.MsoAlarmLogger;
56 import org.onap.so.logger.MsoLogger;
57 import org.springframework.beans.factory.annotation.Autowired;
58 import org.springframework.stereotype.Component;
59
60 @Component
61 public class ASDCController {
62
63     protected static final MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.ASDC,ASDCController.class);
64
65     protected static MsoAlarmLogger alarmLogger = new MsoAlarmLogger ();
66
67     protected boolean isAsdcClientAutoManaged = false;
68
69     protected String controllerName;
70     
71     private ASDCControllerStatus controllerStatus = ASDCControllerStatus.STOPPED;
72     
73     protected int nbOfNotificationsOngoing = 0;
74
75     @Autowired
76     private ToscaResourceInstaller toscaInstaller;
77     
78     @Autowired
79     private WatchdogDistributionStatusRepository wdsRepo;
80     
81     @Autowired
82     private ASDCConfiguration asdcConfig;
83     
84     @Autowired
85     private ASDCStatusCallBack asdcStatusCallBack;
86     
87     @Autowired
88     private ASDCNotificationCallBack asdcNotificationCallBack;
89     
90     private IDistributionClient distributionClient;
91     
92     private static final String UUID_PARAM = "(UUID:";
93     
94     @Autowired
95     private WatchdogDistribution wd;
96    
97
98     public int getNbOfNotificationsOngoing () {
99         return nbOfNotificationsOngoing;
100     }    
101
102     public IDistributionClient getDistributionClient() {
103                 return distributionClient;
104         }
105
106
107
108         public void setDistributionClient(IDistributionClient distributionClient) {
109                 this.distributionClient = distributionClient;
110         }
111
112
113
114         protected void changeControllerStatus (ASDCControllerStatus newControllerStatus) {
115         switch (newControllerStatus) {
116
117             case BUSY:
118                 ++this.nbOfNotificationsOngoing;
119                 this.controllerStatus = newControllerStatus;
120                 break;
121
122             case IDLE:
123                 if (this.nbOfNotificationsOngoing > 1) {
124                     --this.nbOfNotificationsOngoing;
125                 } else {
126                     this.nbOfNotificationsOngoing = 0;
127                     this.controllerStatus = newControllerStatus;
128                 }
129
130                 break;
131             default:
132                 this.controllerStatus = newControllerStatus;
133                 break;
134
135         }
136     }
137
138     public ASDCControllerStatus getControllerStatus () {
139         return this.controllerStatus;
140     }
141     
142     public ASDCController () {
143         isAsdcClientAutoManaged = true;        
144     }
145
146     public ASDCController (String controllerConfigName) {
147         isAsdcClientAutoManaged = true;
148         this.controllerName = controllerConfigName;
149     }
150
151     public ASDCController (String controllerConfigName, IDistributionClient asdcClient, IVfResourceInstaller resourceinstaller) {
152         distributionClient = asdcClient;       
153     }
154
155     public ASDCController (String controllerConfigName,IDistributionClient asdcClient) {
156         distributionClient = asdcClient;
157         this.controllerName = controllerConfigName;     
158     }
159     public String getControllerName() {
160                 return controllerName;
161         }
162
163         public void setControllerName(String controllerName) {
164                 this.controllerName = controllerName;
165         }
166
167         /**
168      * This method initializes the ASDC Controller and the ASDC Client.
169      *
170      * @throws ASDCControllerException It throws an exception if the ASDC Client cannot be instantiated or if an init
171      *         attempt is done when already initialized
172      * @throws ASDCParametersException If there is an issue with the parameters provided
173      * @throws IOException In case of issues when trying to load the key file
174      */
175     public void initASDC () throws ASDCControllerException {
176         String event = "Initialize the ASDC Controller";
177         MsoLogger.setServiceName ("InitASDC");
178         LOGGER.debug (event);
179         if (this.getControllerStatus () != ASDCControllerStatus.STOPPED) {
180             String endEvent = "The controller is already initialized, call the closeASDC method first";
181             throw new ASDCControllerException (endEvent);
182         }
183
184         if (asdcConfig != null) {          
185             asdcConfig.setAsdcControllerName(controllerName);
186         }    
187
188         if (this.distributionClient == null) {
189             distributionClient = DistributionClientFactory.createDistributionClient ();
190         }
191         
192         long initStartTime = System.currentTimeMillis ();
193         IDistributionClientResult result = this.distributionClient.init (asdcConfig,
194                                                                          asdcNotificationCallBack, asdcStatusCallBack);
195         if (!result.getDistributionActionResult ().equals (DistributionActionResultEnum.SUCCESS)) {
196             String endEvent = "ASDC distribution client init failed with reason:"
197                               + result.getDistributionMessageResult ();
198             LOGGER.recordMetricEvent (initStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.UnknownError, "Initialization of the ASDC Controller failed with reason:" + result.getDistributionMessageResult (), "ASDC", "init", null);
199             LOGGER.debug (endEvent);
200             this.changeControllerStatus (ASDCControllerStatus.STOPPED);
201             throw new ASDCControllerException ("Initialization of the ASDC Controller failed with reason: "
202                                                + result.getDistributionMessageResult ());
203         }
204         LOGGER.recordMetricEvent (initStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully initialize ASDC Controller", "ASDC", "init", null);
205
206         long clientstartStartTime = System.currentTimeMillis ();
207         result = this.distributionClient.start ();
208         if (!result.getDistributionActionResult ().equals (DistributionActionResultEnum.SUCCESS)) {
209             String endEvent = "ASDC distribution client start failed with reason:"
210                               + result.getDistributionMessageResult ();
211             LOGGER.recordMetricEvent (clientstartStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.UnknownError, endEvent, "ASDC", "start", null);
212             LOGGER.debug (endEvent);           
213             this.changeControllerStatus (ASDCControllerStatus.STOPPED);
214             throw new ASDCControllerException ("Startup of the ASDC Controller failed with reason: "
215                                                + result.getDistributionMessageResult ());
216         }
217         LOGGER.recordMetricEvent (clientstartStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully start ASDC distribution client", "ASDC", "start", null);
218
219
220         this.changeControllerStatus (ASDCControllerStatus.IDLE);
221         LOGGER.info (MessageEnum.ASDC_INIT_ASDC_CLIENT_SUC, "ASDC", "changeControllerStatus","");
222     }
223
224     /**
225      * This method closes the ASDC Controller and the ASDC Client.
226      *
227      * @throws ASDCControllerException It throws an exception if the ASDC Client cannot be closed because
228      *         it's currently BUSY in processing notifications.
229      */
230     public void closeASDC () throws ASDCControllerException {
231
232         MsoLogger.setServiceName ("CloseController");
233         if (this.getControllerStatus () == ASDCControllerStatus.BUSY) {
234             throw new ASDCControllerException ("Cannot close the ASDC controller as it's currently in BUSY state");
235         }
236         if (this.distributionClient != null) {
237             this.distributionClient.stop ();
238             // If auto managed we can set it to Null, ASDCController controls it.
239             // In the other case the client of this class has specified it, so we can't reset it
240             if (isAsdcClientAutoManaged) {
241                 // Next init will initialize it with a new ASDC Client
242                 this.distributionClient = null;
243             }
244
245         }
246         this.changeControllerStatus (ASDCControllerStatus.STOPPED);
247     }
248
249     private boolean checkResourceAlreadyDeployed (VfResourceStructure resource) throws ArtifactInstallerException {
250
251         
252                 if (toscaInstaller.isResourceAlreadyDeployed (resource)) {
253                         LOGGER.info (MessageEnum.ASDC_ARTIFACT_ALREADY_EXIST,
254                     resource.getResourceInstance().getResourceInstanceName(),
255                     resource.getResourceInstance().getResourceUUID(),
256                     resource.getResourceInstance().getResourceName(), "", "");
257
258                         this.sendDeployNotificationsForResource(resource,DistributionStatusEnum.ALREADY_DOWNLOADED,null);
259                         this.sendDeployNotificationsForResource(resource,DistributionStatusEnum.ALREADY_DEPLOYED,null);
260
261                 return true;
262         } else {
263                 return false;
264         }
265     }
266
267    
268
269     private IDistributionClientDownloadResult downloadTheArtifact (IArtifactInfo artifact,
270                                                                    String distributionId) throws ASDCDownloadException {
271
272         LOGGER.debug ("Trying to download the artifact : " + artifact.getArtifactURL ()
273                       + UUID_PARAM
274                       + artifact.getArtifactUUID ()
275                       + ")");
276         IDistributionClientDownloadResult downloadResult;
277
278
279         try {
280             downloadResult = distributionClient.download (artifact);
281             if (null == downloadResult) {
282                 LOGGER.info (MessageEnum.ASDC_ARTIFACT_NULL, artifact.getArtifactUUID (), "", "");
283                 return downloadResult;
284             }
285         } catch (RuntimeException e) {
286             LOGGER.debug ("Not able to download the artifact due to an exception: " + artifact.getArtifactURL ());
287             this.sendASDCNotification (NotificationType.DOWNLOAD,
288                                        artifact.getArtifactURL (),
289                                        asdcConfig.getConsumerID (),
290                                        distributionId,
291                                        DistributionStatusEnum.DOWNLOAD_ERROR,
292                                        e.getMessage (),
293                                        System.currentTimeMillis ());
294
295             throw new ASDCDownloadException ("Exception caught when downloading the artifact", e);
296         }
297
298         if (DistributionActionResultEnum.SUCCESS.equals(downloadResult.getDistributionActionResult ())) {
299
300             LOGGER.info (MessageEnum.ASDC_ARTIFACT_DOWNLOAD_SUC,
301                          artifact.getArtifactURL (),
302                          artifact.getArtifactUUID (),
303                          String.valueOf (downloadResult.getArtifactPayload ().length), "", "");
304
305         } else {
306
307             LOGGER.error (MessageEnum.ASDC_ARTIFACT_DOWNLOAD_FAIL,
308                           artifact.getArtifactName (),
309                           artifact.getArtifactURL (),
310                           artifact.getArtifactUUID (),
311                           downloadResult.getDistributionMessageResult (), "", "", MsoLogger.ErrorCode.DataError, "ASDC artifact download fail");
312
313             this.sendASDCNotification (NotificationType.DOWNLOAD,
314                                        artifact.getArtifactURL (),
315                                        asdcConfig.getConsumerID (),
316                                        distributionId,
317                                        DistributionStatusEnum.DOWNLOAD_ERROR,
318                                        downloadResult.getDistributionMessageResult (),
319                                        System.currentTimeMillis ());
320
321             throw new ASDCDownloadException ("Artifact " + artifact.getArtifactName ()
322                                              + " could not be downloaded from ASDC URL "
323                                              + artifact.getArtifactURL ()
324                                              + UUID_PARAM
325                                              + artifact.getArtifactUUID ()
326                                              + ")"
327                                              + System.lineSeparator ()
328                                              + "Error message is "
329                                              + downloadResult.getDistributionMessageResult ()
330                                              + System.lineSeparator ());
331
332         }
333
334         this.sendASDCNotification (NotificationType.DOWNLOAD,
335                                    artifact.getArtifactURL (),
336                                    asdcConfig.getConsumerID (),
337                                    distributionId,
338                                    DistributionStatusEnum.DOWNLOAD_OK,
339                                    null,
340                                    System.currentTimeMillis ());
341         return downloadResult;
342
343     }
344
345     private void writeArtifactToFile (IArtifactInfo artifact,
346                 IDistributionClientDownloadResult resultArtifact) {
347
348         LOGGER.debug ("Trying to write artifact to file : " + artifact.getArtifactURL ()
349                         + UUID_PARAM
350                         + artifact.getArtifactUUID ()
351                         + ")");
352         
353         byte[] payloadBytes = resultArtifact.getArtifactPayload();
354         
355         try (FileOutputStream outFile = new FileOutputStream(System.getProperty("mso.config.path") + "/ASDC" + "/" + artifact.getArtifactName())) {
356                 LOGGER.info(MessageEnum.ASDC_RECEIVE_SERVICE_NOTIF, "***WRITE FILE ARTIFACT NAME", "ASDC", artifact.getArtifactName());
357                 outFile.write(payloadBytes, 0, payloadBytes.length);
358                 outFile.close();
359         } catch (Exception e) { 
360                         LOGGER.debug("Exception :",e);
361             LOGGER.error(MessageEnum.ASDC_ARTIFACT_DOWNLOAD_FAIL,
362                                 artifact.getArtifactName (),
363                                 artifact.getArtifactURL (),
364                                 artifact.getArtifactUUID (),
365                                 resultArtifact.getDistributionMessageResult (), "", "", MsoLogger.ErrorCode.DataError, "ASDC write to file failed"); 
366         } 
367         
368     }
369
370
371     private void sendDeployNotificationsForResource(VfResourceStructure vfResourceStructure,DistributionStatusEnum distribStatus, String errorReason) {
372
373         for (IArtifactInfo artifactInfo : vfResourceStructure.getResourceInstance().getArtifacts()) {
374
375                 if ((DistributionStatusEnum.DEPLOY_OK.equals(distribStatus) && !artifactInfo.getArtifactType().equalsIgnoreCase("OTHER") && !vfResourceStructure.isAlreadyDeployed())
376                                 // This could be NULL if the artifact is a VF module artifact, this won't be present in the MAP
377                                 && vfResourceStructure.getArtifactsMapByUUID().get(artifactInfo.getArtifactUUID()) != null
378                                 && vfResourceStructure.getArtifactsMapByUUID().get(artifactInfo.getArtifactUUID()).getDeployedInDb() == 0) {
379                         this.sendASDCNotification (NotificationType.DEPLOY,
380                                         artifactInfo.getArtifactURL (),
381                           asdcConfig.getConsumerID (),
382                           vfResourceStructure.getNotification().getDistributionID(),
383                           DistributionStatusEnum.DEPLOY_ERROR,
384                           "The artifact has not been used by the modules defined in the resource",
385                           System.currentTimeMillis ());
386                 } else {
387                         this.sendASDCNotification (NotificationType.DEPLOY,
388                                         artifactInfo.getArtifactURL (),
389                           asdcConfig.getConsumerID (),
390                           vfResourceStructure.getNotification().getDistributionID(),
391                           distribStatus,
392                           errorReason,
393                           System.currentTimeMillis ());
394                 }
395         }
396     }
397     
398     private void sendCsarDeployNotification(INotificationData iNotif, VfResourceStructure resourceStructure, ToscaResourceStructure toscaResourceStructure, boolean deploySuccessful, String errorReason) {
399         
400                 IArtifactInfo csarArtifact = toscaResourceStructure.getToscaArtifact();
401                 
402                 if(deploySuccessful){
403                         
404                 this.sendASDCNotification (NotificationType.DEPLOY,
405                                   csarArtifact.getArtifactURL (),
406                           asdcConfig.getConsumerID (),
407                           resourceStructure.getNotification().getDistributionID(),
408                           DistributionStatusEnum.DEPLOY_OK,
409                           errorReason,
410                           System.currentTimeMillis ());
411                         
412                 } else {
413                         
414                         this.sendASDCNotification (NotificationType.DEPLOY,
415                           csarArtifact.getArtifactURL (),
416                   asdcConfig.getConsumerID (),
417                   resourceStructure.getNotification().getDistributionID(),
418                   DistributionStatusEnum.DEPLOY_ERROR,
419                   errorReason,
420                   System.currentTimeMillis ());
421                         
422                 }
423     }
424     
425     private void deployResourceStructure (VfResourceStructure resourceStructure, ToscaResourceStructure toscaResourceStructure) throws ArtifactInstallerException {
426
427         LOGGER.info (MessageEnum.ASDC_START_DEPLOY_ARTIFACT, resourceStructure.getResourceInstance().getResourceInstanceName(), resourceStructure.getResourceInstance().getResourceUUID(), "ASDC");
428         try {
429                 String resourceType = resourceStructure.getResourceInstance().getResourceType();
430                 String category = resourceStructure.getResourceInstance().getCategory();
431                 if("VF".equals(resourceType) && !"Allotted Resource".equalsIgnoreCase(category)){
432                         resourceStructure.createVfModuleStructures();
433                 }
434                 toscaInstaller.installTheResource(toscaResourceStructure, resourceStructure);                                                   
435
436         } catch (ArtifactInstallerException e) {
437                 LOGGER.info (MessageEnum.ASDC_ARTIFACT_DOWNLOAD_FAIL,
438                                 resourceStructure.getResourceInstance().getResourceName(),
439                                 resourceStructure.getResourceInstance().getResourceUUID(),
440                         String.valueOf (resourceStructure.getVfModuleStructure().size()), "ASDC", "deployResourceStructure");
441                 sendDeployNotificationsForResource(resourceStructure,DistributionStatusEnum.DEPLOY_ERROR,e.getMessage());
442                 throw e;
443         }
444
445         if (resourceStructure.isDeployedSuccessfully() || toscaResourceStructure.isDeployedSuccessfully()) {
446                 LOGGER.info (MessageEnum.ASDC_ARTIFACT_DEPLOY_SUC,
447                                 resourceStructure.getResourceInstance().getResourceName(),
448                                 resourceStructure.getResourceInstance().getResourceUUID(),
449                         String.valueOf (resourceStructure.getVfModuleStructure().size()), "ASDC", "deployResourceStructure");
450                 sendDeployNotificationsForResource(resourceStructure,DistributionStatusEnum.DEPLOY_OK ,null);
451         }
452
453     }
454     
455
456     private enum NotificationType {
457         DOWNLOAD, DEPLOY
458     }
459
460     private void sendASDCNotification (NotificationType notificationType,
461                                        String artifactURL,
462                                        String consumerID,
463                                        String distributionID,
464                                        DistributionStatusEnum status,
465                                        String errorReason,
466                                        long timestamp) {
467
468         String event = "Sending " + notificationType.name ()
469                        + "("
470                        + status.name ()
471                        + ")"
472                        + " notification to ASDC for artifact:"
473                        + artifactURL;
474
475         if (errorReason != null) {
476                 event=event+"("+errorReason+")";
477         }
478         LOGGER.info (MessageEnum.ASDC_SEND_NOTIF_ASDC, notificationType.name (), status.name (), artifactURL, "ASDC", "sendASDCNotification");
479         LOGGER.debug (event);
480
481         long subStarttime = System.currentTimeMillis ();
482         String action = "";
483         try {
484             IDistributionStatusMessage message = new DistributionStatusMessage (artifactURL,
485                                                                                 consumerID,
486                                                                                 distributionID,
487                                                                                 status,
488                                                                                 timestamp);
489
490             switch (notificationType) {
491                 case DOWNLOAD:
492                     if (errorReason != null) {
493                         this.distributionClient.sendDownloadStatus (message, errorReason);
494                     } else {
495                         this.distributionClient.sendDownloadStatus (message);
496                     }
497                     action = "sendDownloadStatus";
498                     break;
499                 case DEPLOY:
500                     if (errorReason != null) {
501                         this.distributionClient.sendDeploymentStatus (message, errorReason);
502                     } else {
503                         this.distributionClient.sendDeploymentStatus (message);
504                     }
505                     action = "sendDeploymentdStatus";
506                     break;
507                 default:
508                         break;
509             }
510         } catch (RuntimeException e) {           
511             LOGGER.warn (MessageEnum.ASDC_SEND_NOTIF_ASDC_EXEC, "ASDC", "sendASDCNotification", MsoLogger.ErrorCode.SchemaError, "RuntimeException - sendASDCNotification", e);
512         }
513         LOGGER.recordMetricEvent (subStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully sent notification to ASDC", "ASDC", action, null);
514     }
515     
516     private void sendFinalDistributionStatus (
517                 String distributionID,
518                 DistributionStatusEnum status,
519                 String errorReason) {
520
521
522         LOGGER.debug ("Enter sendFinalDistributionStatus with DistributionID " + distributionID + " and Status of " + status.name() + " and ErrorReason " + errorReason);
523
524         long subStarttime = System.currentTimeMillis ();
525         try {
526                 
527                 
528                 IFinalDistrStatusMessage finalDistribution = new FinalDistributionStatusMessage(distributionID,status,subStarttime, asdcConfig.getConsumerID());
529                 
530                 if(errorReason == null){
531                         this.distributionClient.sendFinalDistrStatus(finalDistribution);
532                 }else{
533                         this.distributionClient.sendFinalDistrStatus(finalDistribution, errorReason);
534                 }
535                 
536  
537         } catch (RuntimeException e) {                  
538                 LOGGER.debug ("Exception caught in sendFinalDistributionStatus " + e.getMessage());
539                 LOGGER.warn (MessageEnum.ASDC_SEND_NOTIF_ASDC_EXEC, "ASDC", "sendASDCNotification", MsoLogger.ErrorCode.SchemaError, "RuntimeException - sendASDCNotification", e);
540         }
541         LOGGER.recordMetricEvent (subStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully sent Final notification to ASDC", "ASDC", null, null);
542     }
543
544     public void treatNotification (INotificationData iNotif) {
545
546         int noOfArtifacts = 0;
547         
548
549         for (IResourceInstance resource : iNotif.getResources ()) {
550                 noOfArtifacts += resource.getArtifacts ().size ();
551         }
552         LOGGER.info (MessageEnum.ASDC_RECEIVE_CALLBACK_NOTIF,
553                      String.valueOf (noOfArtifacts),
554                      iNotif.getServiceUUID (), "ASDC");
555
556         try {
557                 LOGGER.debug(ASDCNotificationLogging.dumpASDCNotification(iNotif));
558                         LOGGER.info(MessageEnum.ASDC_RECEIVE_SERVICE_NOTIF, iNotif.getServiceUUID(), "ASDC", "treatNotification");
559                         this.changeControllerStatus(ASDCControllerStatus.BUSY);
560                         toscaInstaller.processWatchdog(iNotif.getDistributionID(),iNotif.getServiceUUID());     
561                         
562                         // Process only the Resource artifacts in MSO                           
563                         this.processResourceNotification(iNotif);
564                         
565                         //********************************************************************************************************
566                         //Start Watchdog loop and wait for all components to complete before reporting final status back. 
567                         // **If timer expires first then we will report a Distribution Error back to ASDC
568                         //********************************************************************************************************
569                 long initialStartTime = System.currentTimeMillis();
570                 boolean componentsComplete = false;
571                 String distributionStatus = null;
572                 String watchdogError = null;
573                 String overallStatus = null;
574                 int watchDogTimeout = asdcConfig.getWatchDogTimeout() * 1000;
575                 boolean isDeploySuccess = false;                
576                                                 
577                 while(!componentsComplete && (System.currentTimeMillis() - initialStartTime) < watchDogTimeout)
578                 {
579                                                 
580                         try{                    
581                                 distributionStatus = wd.getOverallDistributionStatus(iNotif.getDistributionID());
582                                 Thread.sleep(watchDogTimeout / 10);             
583                         }catch(Exception e){
584                                 LOGGER.debug ("Exception in Watchdog Loop " + e.getMessage());
585                                 Thread.sleep(watchDogTimeout / 10);
586                         }
587                         
588                         if(distributionStatus != null && !distributionStatus.equalsIgnoreCase(DistributionStatus.INCOMPLETE.name())){
589                                 
590                                 if(distributionStatus.equalsIgnoreCase(DistributionStatus.SUCCESS.name())){
591                                         isDeploySuccess = true;
592                                         overallStatus = DistributionStatusEnum.DISTRIBUTION_COMPLETE_OK.name();
593                                 }else{
594                                         overallStatus = DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR.name();
595                                 }                               
596                                 componentsComplete = true;
597                         }
598                 }
599                 
600                 if(!componentsComplete){
601                         LOGGER.debug("Timeout of " + watchDogTimeout + " seconds was reached before all components reported status");
602                         watchdogError = "Timeout occurred while waiting for all components to report status";
603                         overallStatus = DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR.name();
604                 }
605                 
606                 if(distributionStatus == null){         
607                         overallStatus = DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR.name();
608                         LOGGER.debug("DistributionStatus is null for DistributionId: " + iNotif.getDistributionID());                           
609                 }
610                 
611                 try {
612                         wd.executePatchAAI(iNotif.getDistributionID(), iNotif.getServiceInvariantUUID(), overallStatus);
613                         LOGGER.debug ("A&AI Updated succefully with Distribution Status!");
614                 }
615                 catch(Exception e) {
616                         LOGGER.debug ("Exception in Watchdog executePatchAAI(): " + e.getMessage());
617                         watchdogError = "Error calling A&AI " + e.getMessage();
618                         if(e.getCause() != null) {
619                                 LOGGER.debug ("Exception caused by: " + e.getCause().getMessage());
620                         }
621                 }
622         
623                 
624                 if(isDeploySuccess && watchdogError == null){
625                         sendFinalDistributionStatus(iNotif.getDistributionID(), DistributionStatusEnum.DISTRIBUTION_COMPLETE_OK, null);
626                         WatchdogDistributionStatus wds = new WatchdogDistributionStatus(iNotif.getDistributionID());
627                         wds.setDistributionIdStatus(DistributionStatusEnum.DISTRIBUTION_COMPLETE_OK.toString());
628                         wdsRepo.save(wds);
629                 } else {
630                         sendFinalDistributionStatus(iNotif.getDistributionID(), DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR, watchdogError);
631                         WatchdogDistributionStatus wds = new WatchdogDistributionStatus(iNotif.getDistributionID());
632                         wds.setDistributionIdStatus(DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR.toString());
633                         wdsRepo.save(wds);
634                 }
635                 
636                 
637
638         } catch (Exception e) {
639             LOGGER.error (MessageEnum.ASDC_GENERAL_EXCEPTION_ARG,
640                           "Unexpected exception caught during the notification processing",  "ASDC", "treatNotification", MsoLogger.ErrorCode.SchemaError, "RuntimeException in treatNotification",
641                           e);
642             
643                 try {
644                         wd.executePatchAAI(iNotif.getDistributionID(), iNotif.getServiceInvariantUUID(), DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR.name());
645                         LOGGER.debug ("A&AI Updated succefully with Distribution Status of " + DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR.name());
646                 }
647                 catch(Exception aaiException) {
648                         LOGGER.debug ("Exception in executePatchAAI(): " + aaiException.getMessage());
649                         if(aaiException.getCause() != null) {
650                                 LOGGER.debug ("Exception caused by: " + aaiException.getCause().getMessage());
651                         }
652                 }
653             
654              sendFinalDistributionStatus(iNotif.getDistributionID(), DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR, e.getMessage());
655              
656                  WatchdogDistributionStatus wds = new WatchdogDistributionStatus(iNotif.getDistributionID());
657                  wds.setDistributionIdStatus(DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR.toString());
658                  wdsRepo.save(wds);
659             
660         } finally {
661             this.changeControllerStatus (ASDCControllerStatus.IDLE);
662         }
663     }
664
665     private void processResourceNotification (INotificationData iNotif) {
666         // For each artifact, create a structure describing the VFModule in a ordered flat level
667         VfResourceStructure resourceStructure = null;
668         ToscaResourceStructure toscaResourceStructure = new ToscaResourceStructure();
669         boolean deploySuccessful = true;
670         String errorMessage = null;
671
672         try {
673                 
674                         this.processCsarServiceArtifacts(iNotif, toscaResourceStructure);       
675                         
676                 for (IResourceInstance resource : iNotif.getResources()){
677                         
678                         resourceStructure = new VfResourceStructure(iNotif,resource);
679                         
680                         String resourceType = resourceStructure.getResourceInstance().getResourceType();
681                 String category = resourceStructure.getResourceInstance().getCategory();
682                                         
683                 LOGGER.debug("Processing Resource Type: " + resourceType + " and Model UUID: " + resourceStructure.getResourceInstance().getResourceUUID());
684                         
685                                 if("VF".equals(resourceType) && !"Allotted Resource".equalsIgnoreCase(category)){
686                         
687                                 for (IArtifactInfo artifact : resource.getArtifacts()) {
688                                         IDistributionClientDownloadResult resultArtifact = this.downloadTheArtifact(artifact,
689                                                         iNotif.getDistributionID());
690                                         if (resultArtifact != null) {
691                                                 if (ASDCConfiguration.VF_MODULES_METADATA.equals(artifact.getArtifactType())) {
692                                                         LOGGER.debug("VF_MODULE_ARTIFACT: "+new String(resultArtifact.getArtifactPayload(),"UTF-8"));
693                                                         LOGGER.debug(ASDCNotificationLogging.dumpVfModuleMetaDataList(resourceStructure.decodeVfModuleArtifact(resultArtifact.getArtifactPayload())));
694                                                 }
695                                                 resourceStructure.addArtifactToStructure(distributionClient,artifact, resultArtifact);
696                                         }
697                                 }
698                                 }                               
699                  }                      
700                          try{
701
702                                 //Deploy All resources and artifacts
703                                 LOGGER.debug("Preparing to deploy Service: " + iNotif.getServiceUUID());
704                                 if(resourceStructure == null){
705                                         resourceStructure = new VfResourceStructure(iNotif,new ResourceInstance()); 
706                                 }
707                                 this.deployResourceStructure(resourceStructure, toscaResourceStructure);
708
709
710                          } catch(ArtifactInstallerException e){
711                                 deploySuccessful = false;
712                                 errorMessage = e.getMessage();
713                          }
714
715                          this.sendCsarDeployNotification(iNotif, resourceStructure, toscaResourceStructure, deploySuccessful, errorMessage);
716                 
717         } catch (ASDCDownloadException | UnsupportedEncodingException e) {
718                 LOGGER.error(MessageEnum.ASDC_GENERAL_EXCEPTION_ARG,
719                                 "Exception caught during Installation of artifact", "ASDC", "processResourceNotification", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in processResourceNotification", e);
720         }
721     }
722     private void processCsarServiceArtifacts (INotificationData iNotif, ToscaResourceStructure toscaResourceStructure) {
723         
724         List<IArtifactInfo> serviceArtifacts = iNotif.getServiceArtifacts();
725         
726                 for(IArtifactInfo artifact : serviceArtifacts){
727                 
728                         if(artifact.getArtifactType().equals(ASDCConfiguration.TOSCA_CSAR)){
729                                 
730                                 try{
731                                         
732                                         toscaResourceStructure.setToscaArtifact(artifact);
733                                         
734                                         IDistributionClientDownloadResult resultArtifact = this.downloadTheArtifact(artifact,iNotif.getDistributionID());
735                                         
736                                         writeArtifactToFile(artifact, resultArtifact);
737                                         
738                                         toscaResourceStructure.updateResourceStructure(artifact);
739                                         
740                                         toscaResourceStructure.setServiceVersion(iNotif.getServiceVersion());
741                                         
742                                         LOGGER.debug(ASDCNotificationLogging.dumpCSARNotification(iNotif, toscaResourceStructure));
743                                         
744
745                                 } catch(Exception e){
746                                         LOGGER.error(MessageEnum.ASDC_GENERAL_EXCEPTION_ARG,
747                                                         "Exception caught during processCsarServiceArtifacts", "ASDC", "processCsarServiceArtifacts", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in processCsarServiceArtifacts", e);
748                                 }
749                         }
750                                 
751                 }
752     }
753     
754     private static final String UNKNOWN="Unknown";
755
756     /**
757      * @return the address of the ASDC we are connected to.
758      */
759     public String getAddress () {
760         if (asdcConfig != null) {
761             return asdcConfig.getAsdcAddress ();
762         }
763         return UNKNOWN;
764     }
765
766     /**
767      * @return the environment name of the ASDC we are connected to.
768      */
769     public String getEnvironment () {
770         if (asdcConfig != null) {
771             return asdcConfig.getEnvironmentName ();
772         }
773         return UNKNOWN;
774     }
775
776 }