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