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