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