2 * ============LICENSE_START=======================================================
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 * Modifications Copyright (c) 2019 Samsung
9 * ================================================================================
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 * ============LICENSE_END=========================================================
24 package org.onap.so.asdc.client;
27 import com.fasterxml.jackson.annotation.JsonInclude.Include;
28 import com.fasterxml.jackson.core.JsonProcessingException;
29 import com.fasterxml.jackson.databind.DeserializationFeature;
30 import com.fasterxml.jackson.databind.MapperFeature;
31 import com.fasterxml.jackson.databind.ObjectMapper;
33 import java.io.FileOutputStream;
34 import java.io.IOException;
35 import java.io.UnsupportedEncodingException;
36 import java.nio.file.Paths;
37 import java.util.List;
38 import java.util.Optional;
39 import org.onap.so.logger.LoggingAnchor;
40 import org.onap.sdc.api.IDistributionClient;
41 import org.onap.sdc.api.consumer.IDistributionStatusMessage;
42 import org.onap.sdc.api.consumer.IFinalDistrStatusMessage;
43 import org.onap.sdc.api.notification.IArtifactInfo;
44 import org.onap.sdc.api.notification.INotificationData;
45 import org.onap.sdc.api.notification.IResourceInstance;
46 import org.onap.sdc.api.results.IDistributionClientDownloadResult;
47 import org.onap.sdc.api.results.IDistributionClientResult;
48 import org.onap.sdc.impl.DistributionClientFactory;
49 import org.onap.sdc.utils.DistributionActionResultEnum;
50 import org.onap.sdc.utils.DistributionStatusEnum;
51 import org.onap.so.asdc.activity.DeployActivitySpecs;
52 import org.onap.so.asdc.client.exceptions.ASDCControllerException;
53 import org.onap.so.asdc.client.exceptions.ASDCDownloadException;
54 import org.onap.so.asdc.client.exceptions.ASDCParametersException;
55 import org.onap.so.asdc.client.exceptions.ArtifactInstallerException;
56 import org.onap.so.asdc.installer.IVfResourceInstaller;
57 import org.onap.so.asdc.installer.PnfResourceStructure;
58 import org.onap.so.asdc.installer.ResourceStructure;
59 import org.onap.so.asdc.installer.ResourceType;
60 import org.onap.so.asdc.installer.ToscaResourceStructure;
61 import org.onap.so.asdc.installer.VfResourceStructure;
62 import org.onap.so.asdc.installer.heat.ToscaResourceInstaller;
63 import org.onap.so.asdc.tenantIsolation.DistributionStatus;
64 import org.onap.so.asdc.tenantIsolation.WatchdogDistribution;
65 import org.onap.so.asdc.util.ASDCNotificationLogging;
66 import org.onap.so.db.request.beans.WatchdogComponentDistributionStatus;
67 import org.onap.so.db.request.beans.WatchdogDistributionStatus;
68 import org.onap.so.db.request.data.repository.WatchdogComponentDistributionStatusRepository;
69 import org.onap.so.db.request.data.repository.WatchdogDistributionStatusRepository;
70 import org.onap.so.logger.ErrorCode;
71 import org.onap.so.logger.MessageEnum;
72 import org.slf4j.Logger;
73 import org.slf4j.LoggerFactory;
74 import org.springframework.beans.factory.annotation.Autowired;
75 import org.springframework.orm.ObjectOptimisticLockingFailureException;
76 import org.springframework.stereotype.Component;
79 public class ASDCController {
81 protected static final Logger logger = LoggerFactory.getLogger(ASDCController.class);
83 private static final String UNKNOWN = "Unknown";
85 protected boolean isAsdcClientAutoManaged = false;
87 protected String controllerName;
89 private ASDCControllerStatus controllerStatus = ASDCControllerStatus.STOPPED;
91 protected int nbOfNotificationsOngoing = 0;
94 private ToscaResourceInstaller toscaInstaller;
97 private WatchdogDistributionStatusRepository wdsRepo;
100 protected WatchdogComponentDistributionStatusRepository watchdogCDStatusRepository;
103 private ASDCConfiguration asdcConfig;
106 private ASDCStatusCallBack asdcStatusCallBack;
109 private ASDCNotificationCallBack asdcNotificationCallBack;
111 private IDistributionClient distributionClient;
113 private static final String UUID_PARAM = "(UUID:";
115 protected static final String MSO = "SO";
118 private WatchdogDistribution wd;
121 DeployActivitySpecs deployActivitySpecs;
123 public ASDCController() {
127 public ASDCController(String controllerConfigName) {
128 isAsdcClientAutoManaged = true;
129 this.controllerName = controllerConfigName;
132 public ASDCController(String controllerConfigName, IDistributionClient asdcClient,
133 IVfResourceInstaller resourceinstaller) {
134 distributionClient = asdcClient;
137 public ASDCController(String controllerConfigName, IDistributionClient asdcClient) {
138 distributionClient = asdcClient;
139 this.controllerName = controllerConfigName;
142 public int getNbOfNotificationsOngoing() {
143 return nbOfNotificationsOngoing;
146 public IDistributionClient getDistributionClient() {
147 return distributionClient;
150 public void setDistributionClient(IDistributionClient distributionClient) {
151 this.distributionClient = distributionClient;
154 protected void changeControllerStatus(ASDCControllerStatus newControllerStatus) {
155 switch (newControllerStatus) {
158 ++this.nbOfNotificationsOngoing;
159 this.controllerStatus = newControllerStatus;
163 if (this.nbOfNotificationsOngoing > 1) {
164 --this.nbOfNotificationsOngoing;
166 this.nbOfNotificationsOngoing = 0;
167 this.controllerStatus = newControllerStatus;
172 this.controllerStatus = newControllerStatus;
178 public ASDCControllerStatus getControllerStatus() {
179 return this.controllerStatus;
182 public String getControllerName() {
183 return controllerName;
186 public void setControllerName(String controllerName) {
187 this.controllerName = controllerName;
191 * This method initializes the ASDC Controller and the ASDC Client.
193 * @throws ASDCControllerException It throws an exception if the ASDC Client cannot be instantiated or if an init
194 * attempt is done when already initialized
195 * @throws ASDCParametersException If there is an issue with the parameters provided
196 * @throws IOException In case of issues when trying to load the key file
198 public void initASDC() throws ASDCControllerException {
199 String event = "Initialize the ASDC Controller";
201 if (this.getControllerStatus() != ASDCControllerStatus.STOPPED) {
202 String endEvent = "The controller is already initialized, call the closeASDC method first";
203 throw new ASDCControllerException(endEvent);
206 if (asdcConfig != null) {
207 asdcConfig.setAsdcControllerName(controllerName);
210 if (this.distributionClient == null) {
211 distributionClient = DistributionClientFactory.createDistributionClient();
214 IDistributionClientResult result =
215 this.distributionClient.init(asdcConfig, asdcNotificationCallBack, asdcStatusCallBack);
216 if (!result.getDistributionActionResult().equals(DistributionActionResultEnum.SUCCESS)) {
218 "ASDC distribution client init failed with reason:" + result.getDistributionMessageResult();
219 logger.debug(endEvent);
220 this.changeControllerStatus(ASDCControllerStatus.STOPPED);
221 throw new ASDCControllerException("Initialization of the ASDC Controller failed with reason: "
222 + result.getDistributionMessageResult());
225 result = this.distributionClient.start();
226 if (!result.getDistributionActionResult().equals(DistributionActionResultEnum.SUCCESS)) {
228 "ASDC distribution client start failed with reason:" + result.getDistributionMessageResult();
229 logger.debug(endEvent);
230 this.changeControllerStatus(ASDCControllerStatus.STOPPED);
231 throw new ASDCControllerException(
232 "Startup of the ASDC Controller failed with reason: " + result.getDistributionMessageResult());
235 this.changeControllerStatus(ASDCControllerStatus.IDLE);
236 logger.info(LoggingAnchor.THREE, MessageEnum.ASDC_INIT_ASDC_CLIENT_SUC.toString(), "ASDC",
237 "changeControllerStatus");
241 * This method closes the ASDC Controller and the ASDC Client.
243 * @throws ASDCControllerException It throws an exception if the ASDC Client cannot be closed because it's currently
244 * BUSY in processing notifications.
246 public void closeASDC() throws ASDCControllerException {
248 if (this.getControllerStatus() == ASDCControllerStatus.BUSY) {
249 throw new ASDCControllerException("Cannot close the ASDC controller as it's currently in BUSY state");
251 if (this.distributionClient != null) {
252 this.distributionClient.stop();
253 // If auto managed we can set it to Null, ASDCController controls it.
254 // In the other case the client of this class has specified it, so we can't reset it
255 if (isAsdcClientAutoManaged) {
256 // Next init will initialize it with a new ASDC Client
257 this.distributionClient = null;
261 this.changeControllerStatus(ASDCControllerStatus.STOPPED);
264 protected boolean checkResourceAlreadyDeployed(ResourceStructure resource, boolean serviceDeployed)
265 throws ArtifactInstallerException {
268 if (toscaInstaller.isResourceAlreadyDeployed(resource, serviceDeployed)) {
269 logger.info(LoggingAnchor.FOUR, MessageEnum.ASDC_ARTIFACT_ALREADY_EXIST.toString(),
270 resource.getResourceInstance().getResourceInstanceName(),
271 resource.getResourceInstance().getResourceUUID(), resource.getResourceInstance().getResourceName());
273 this.sendDeployNotificationsForResource(resource, DistributionStatusEnum.ALREADY_DOWNLOADED, null);
274 this.sendDeployNotificationsForResource(resource, DistributionStatusEnum.ALREADY_DEPLOYED, null);
282 protected void notifyErrorToAsdc(INotificationData iNotif, ToscaResourceStructure toscaResourceStructure,
283 DistributionStatusEnum deployStatus, VfResourceStructure resourceStructure, String errorMessage) {
284 // do csar lever first
285 this.sendCsarDeployNotification(iNotif, resourceStructure, toscaResourceStructure, deployStatus, errorMessage);
287 for (IResourceInstance resource : iNotif.getResources()) {
288 resourceStructure = new VfResourceStructure(iNotif, resource);
289 errorMessage = String.format("Resource with UUID: %s already exists", resource.getResourceUUID());
290 this.sendCsarDeployNotification(iNotif, resourceStructure, toscaResourceStructure, deployStatus,
295 protected boolean isCsarAlreadyDeployed(INotificationData iNotif, ToscaResourceStructure toscaResourceStructure) {
296 VfResourceStructure resourceStructure = null;
297 String errorMessage = "";
298 boolean csarAlreadyDeployed = false;
299 DistributionStatusEnum deployStatus = DistributionStatusEnum.DEPLOY_OK;
300 WatchdogComponentDistributionStatus wdStatus =
301 new WatchdogComponentDistributionStatus(iNotif.getDistributionID(), MSO);
303 csarAlreadyDeployed = toscaInstaller.isCsarAlreadyDeployed(toscaResourceStructure);
304 if (csarAlreadyDeployed) {
305 deployStatus = DistributionStatusEnum.ALREADY_DEPLOYED;
306 resourceStructure = new VfResourceStructure(iNotif, null);
307 errorMessage = String.format("Csar with UUID: %s already exists",
308 toscaResourceStructure.getToscaArtifact().getArtifactUUID());
309 wdStatus.setComponentDistributionStatus(DistributionStatusEnum.COMPONENT_DONE_OK.name());
310 watchdogCDStatusRepository.saveAndFlush(wdStatus);
311 logger.error(errorMessage);
313 } catch (ArtifactInstallerException e) {
314 deployStatus = DistributionStatusEnum.DEPLOY_ERROR;
315 resourceStructure = new VfResourceStructure(iNotif, null);
316 errorMessage = e.getMessage();
317 wdStatus.setComponentDistributionStatus(DistributionStatusEnum.COMPONENT_DONE_ERROR.name());
318 watchdogCDStatusRepository.saveAndFlush(wdStatus);
319 logger.warn("Tosca Checksums don't match, Tosca validation check failed", e);
322 if (deployStatus != DistributionStatusEnum.DEPLOY_OK) {
323 notifyErrorToAsdc(iNotif, toscaResourceStructure, deployStatus, resourceStructure, errorMessage);
326 return csarAlreadyDeployed;
329 protected IDistributionClientDownloadResult downloadTheArtifact(IArtifactInfo artifact, String distributionId)
330 throws ASDCDownloadException {
332 logger.info("Trying to download the artifact UUID: {} from URL: {}", artifact.getArtifactUUID(),
333 artifact.getArtifactURL());
334 IDistributionClientDownloadResult downloadResult;
337 downloadResult = distributionClient.download(artifact);
338 if (null == downloadResult) {
339 logger.info(LoggingAnchor.TWO, MessageEnum.ASDC_ARTIFACT_NULL.toString(), artifact.getArtifactUUID());
340 return downloadResult;
342 } catch (RuntimeException e) {
343 logger.debug("Not able to download the artifact due to an exception: " + artifact.getArtifactURL());
344 this.sendASDCNotification(NotificationType.DOWNLOAD, artifact.getArtifactURL(), asdcConfig.getConsumerID(),
345 distributionId, DistributionStatusEnum.DOWNLOAD_ERROR, e.getMessage(), System.currentTimeMillis());
347 throw new ASDCDownloadException("Exception caught when downloading the artifact", e);
350 if (DistributionActionResultEnum.SUCCESS.equals(downloadResult.getDistributionActionResult())) {
351 logger.info(LoggingAnchor.FOUR, MessageEnum.ASDC_ARTIFACT_DOWNLOAD_SUC.toString(),
352 artifact.getArtifactURL(), artifact.getArtifactUUID(),
353 String.valueOf(downloadResult.getArtifactPayload().length));
356 logger.error(LoggingAnchor.SEVEN, MessageEnum.ASDC_ARTIFACT_DOWNLOAD_FAIL.toString(),
357 artifact.getArtifactName(), artifact.getArtifactURL(), artifact.getArtifactUUID(),
358 downloadResult.getDistributionMessageResult(), ErrorCode.DataError.getValue(),
359 "ASDC artifact download fail");
361 this.sendASDCNotification(NotificationType.DOWNLOAD, artifact.getArtifactURL(), asdcConfig.getConsumerID(),
362 distributionId, DistributionStatusEnum.DOWNLOAD_ERROR,
363 downloadResult.getDistributionMessageResult(), System.currentTimeMillis());
365 throw new ASDCDownloadException("Artifact " + artifact.getArtifactName()
366 + " could not be downloaded from ASDC URL " + artifact.getArtifactURL() + UUID_PARAM
367 + artifact.getArtifactUUID() + ")" + System.lineSeparator() + "Error message is "
368 + downloadResult.getDistributionMessageResult() + System.lineSeparator());
372 this.sendASDCNotification(NotificationType.DOWNLOAD, artifact.getArtifactURL(), asdcConfig.getConsumerID(),
373 distributionId, DistributionStatusEnum.DOWNLOAD_OK, null, System.currentTimeMillis());
374 return downloadResult;
378 private void writeArtifactToFile(IArtifactInfo artifact, IDistributionClientDownloadResult resultArtifact) {
381 Paths.get(getMsoConfigPath(), "ASDC", artifact.getArtifactVersion(), artifact.getArtifactName())
382 .normalize().toString();
384 logger.info("Trying to write artifact UUID: {}, URL: {} to file: {}", artifact.getArtifactUUID(),
385 artifact.getArtifactURL(), filePath);
387 // make parent directory
388 File file = new File(filePath);
389 File fileParent = file.getParentFile();
390 if (!fileParent.exists()) {
394 byte[] payloadBytes = resultArtifact.getArtifactPayload();
396 try (FileOutputStream outFile = new FileOutputStream(filePath)) {
397 logger.info(LoggingAnchor.FOUR, MessageEnum.ASDC_RECEIVE_SERVICE_NOTIF.toString(),
398 "***WRITE FILE ARTIFACT NAME", "ASDC", artifact.getArtifactName());
399 outFile.write(payloadBytes, 0, payloadBytes.length);
400 } catch (Exception e) {
401 logger.debug("Exception :", e);
402 logger.error(LoggingAnchor.SEVEN, MessageEnum.ASDC_ARTIFACT_DOWNLOAD_FAIL.toString(),
403 artifact.getArtifactName(), artifact.getArtifactURL(), artifact.getArtifactUUID(),
404 resultArtifact.getDistributionMessageResult(), ErrorCode.DataError.getValue(),
405 "ASDC write to file failed");
411 protected void sendDeployNotificationsForResource(ResourceStructure resourceStructure,
412 DistributionStatusEnum distribStatus, String errorReason) {
414 for (IArtifactInfo artifactInfo : resourceStructure.getResourceInstance().getArtifacts()) {
416 if ((DistributionStatusEnum.DEPLOY_OK.equals(distribStatus)
417 && !("OTHER").equalsIgnoreCase(artifactInfo.getArtifactType())
418 && !resourceStructure.isAlreadyDeployed())
419 // This could be NULL if the artifact is a VF module artifact, this won't be present in the MAP
420 && resourceStructure.getArtifactsMapByUUID().get(artifactInfo.getArtifactUUID()) != null
421 && resourceStructure.getArtifactsMapByUUID().get(artifactInfo.getArtifactUUID())
422 .getDeployedInDb() == 0) {
423 this.sendASDCNotification(NotificationType.DEPLOY, artifactInfo.getArtifactURL(),
424 asdcConfig.getConsumerID(), resourceStructure.getNotification().getDistributionID(),
425 DistributionStatusEnum.DEPLOY_ERROR,
426 "The artifact has not been used by the modules defined in the resource",
427 System.currentTimeMillis());
429 this.sendASDCNotification(NotificationType.DEPLOY, artifactInfo.getArtifactURL(),
430 asdcConfig.getConsumerID(), resourceStructure.getNotification().getDistributionID(),
431 distribStatus, errorReason, System.currentTimeMillis());
436 protected void sendCsarDeployNotification(INotificationData iNotif, ResourceStructure resourceStructure,
437 ToscaResourceStructure toscaResourceStructure, DistributionStatusEnum statusEnum, String errorReason) {
439 IArtifactInfo csarArtifact = toscaResourceStructure.getToscaArtifact();
441 this.sendASDCNotification(NotificationType.DEPLOY, csarArtifact.getArtifactURL(), asdcConfig.getConsumerID(),
442 resourceStructure.getNotification().getDistributionID(), statusEnum, errorReason,
443 System.currentTimeMillis());
447 protected void deployResourceStructure(ResourceStructure resourceStructure,
448 ToscaResourceStructure toscaResourceStructure) throws ArtifactInstallerException {
450 logger.info(LoggingAnchor.FOUR, MessageEnum.ASDC_START_DEPLOY_ARTIFACT.toString(),
451 resourceStructure.getResourceInstance().getResourceInstanceName(),
452 resourceStructure.getResourceInstance().getResourceUUID(), "ASDC");
454 resourceStructure.prepareInstall();
455 toscaInstaller.installTheResource(toscaResourceStructure, resourceStructure);
457 } catch (ArtifactInstallerException e) {
458 logger.info(LoggingAnchor.SIX, MessageEnum.ASDC_ARTIFACT_DOWNLOAD_FAIL.toString(),
459 resourceStructure.getResourceInstance().getResourceName(),
460 resourceStructure.getResourceInstance().getResourceUUID(),
461 String.valueOf(resourceStructure.getNumberOfResources()), "ASDC", "deployResourceStructure");
462 sendDeployNotificationsForResource(resourceStructure, DistributionStatusEnum.DEPLOY_ERROR, e.getMessage());
466 if (resourceStructure.isDeployedSuccessfully() || toscaResourceStructure.isDeployedSuccessfully()) {
467 logger.info(LoggingAnchor.SIX, MessageEnum.ASDC_ARTIFACT_DEPLOY_SUC.toString(),
468 resourceStructure.getResourceInstance().getResourceName(),
469 resourceStructure.getResourceInstance().getResourceUUID(),
470 String.valueOf(resourceStructure.getNumberOfResources()), "ASDC", "deployResourceStructure");
471 sendDeployNotificationsForResource(resourceStructure, DistributionStatusEnum.DEPLOY_OK, null);
477 private enum NotificationType {
481 protected void sendASDCNotification(NotificationType notificationType, String artifactURL, String consumerID,
482 String distributionID, DistributionStatusEnum status, String errorReason, long timestamp) {
484 String event = "Sending " + notificationType.name() + "(" + status.name() + ")"
485 + " notification to ASDC for artifact:" + artifactURL;
487 if (errorReason != null) {
488 event = event + "(" + errorReason + ")";
490 logger.info(LoggingAnchor.SIX, MessageEnum.ASDC_SEND_NOTIF_ASDC.toString(), notificationType.name(),
491 status.name(), artifactURL, "ASDC", "sendASDCNotification");
496 IDistributionStatusMessage message =
497 new DistributionStatusMessage(artifactURL, consumerID, distributionID, status, timestamp);
499 switch (notificationType) {
501 if (errorReason != null) {
502 this.distributionClient.sendDownloadStatus(message, errorReason);
504 this.distributionClient.sendDownloadStatus(message);
509 if (errorReason != null) {
510 this.distributionClient.sendDeploymentStatus(message, errorReason);
512 this.distributionClient.sendDeploymentStatus(message);
519 } catch (RuntimeException e) {
520 logger.warn(LoggingAnchor.FIVE, MessageEnum.ASDC_SEND_NOTIF_ASDC_EXEC.toString(), "ASDC",
521 "sendASDCNotification", ErrorCode.SchemaError.getValue(), "RuntimeException - sendASDCNotification",
526 protected void sendFinalDistributionStatus(String distributionID, DistributionStatusEnum status,
527 String errorReason) {
529 logger.debug("Enter sendFinalDistributionStatus with DistributionID " + distributionID + " and Status of "
530 + status.name() + " and ErrorReason " + errorReason);
532 long subStarttime = System.currentTimeMillis();
535 IFinalDistrStatusMessage finalDistribution = new FinalDistributionStatusMessage(distributionID, status,
536 subStarttime, asdcConfig.getConsumerID());
538 if (errorReason == null) {
539 this.distributionClient.sendFinalDistrStatus(finalDistribution);
541 this.distributionClient.sendFinalDistrStatus(finalDistribution, errorReason);
545 } catch (RuntimeException e) {
546 logger.debug("Exception caught in sendFinalDistributionStatus {}", e.getMessage());
547 logger.warn(LoggingAnchor.FIVE, MessageEnum.ASDC_SEND_NOTIF_ASDC_EXEC.toString(), "ASDC",
548 "sendASDCNotification", ErrorCode.SchemaError.getValue(), "RuntimeException - sendASDCNotification",
553 private Optional<String> getNotificationJson(INotificationData iNotif) {
554 ObjectMapper mapper = new ObjectMapper();
555 mapper.setSerializationInclusion(Include.NON_NULL);
556 mapper.setSerializationInclusion(Include.NON_EMPTY);
557 mapper.setSerializationInclusion(Include.NON_ABSENT);
558 mapper.enable(MapperFeature.USE_ANNOTATIONS);
559 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
560 Optional<String> returnValue = Optional.empty();
562 returnValue = Optional.of(mapper.writeValueAsString(iNotif));
563 } catch (JsonProcessingException e) {
564 logger.error("Error converting incoming ASDC notification to JSON", e);
569 public void treatNotification(INotificationData iNotif) {
571 int noOfArtifacts = 0;
573 for (IResourceInstance resource : iNotif.getResources()) {
574 noOfArtifacts += resource.getArtifacts().size();
576 logger.info(LoggingAnchor.FOUR, MessageEnum.ASDC_RECEIVE_CALLBACK_NOTIF.toString(),
577 String.valueOf(noOfArtifacts), iNotif.getServiceUUID(), "ASDC");
579 logger.debug(ASDCNotificationLogging.dumpASDCNotification(iNotif));
580 logger.info(LoggingAnchor.FOUR, MessageEnum.ASDC_RECEIVE_SERVICE_NOTIF.toString(), iNotif.getServiceUUID(),
581 "ASDC", "treatNotification");
583 this.changeControllerStatus(ASDCControllerStatus.BUSY);
584 Optional<String> notificationMessage = getNotificationJson(iNotif);
585 toscaInstaller.processWatchdog(iNotif.getDistributionID(), iNotif.getServiceUUID(), notificationMessage,
586 asdcConfig.getConsumerID());
588 // Process only the Resource artifacts in MSO
589 this.processResourceNotification(iNotif);
591 // ********************************************************************************************************
592 // Start Watchdog loop and wait for all components to complete before reporting final status back.
593 // **If timer expires first then we will report a Distribution Error back to ASDC
594 // ********************************************************************************************************
595 long initialStartTime = System.currentTimeMillis();
596 boolean componentsComplete = false;
597 String distributionStatus = null;
598 String watchdogError = null;
599 String overallStatus = null;
600 int watchDogTimeout = asdcConfig.getWatchDogTimeout() * 1000;
601 boolean isDeploySuccess = false;
603 while (!componentsComplete && (System.currentTimeMillis() - initialStartTime) < watchDogTimeout) {
606 distributionStatus = wd.getOverallDistributionStatus(iNotif.getDistributionID());
607 Thread.sleep(watchDogTimeout / 10);
608 } catch (Exception e) {
609 logger.debug("Exception in Watchdog Loop {}", e.getMessage());
610 Thread.sleep(watchDogTimeout / 10);
613 if (distributionStatus != null
614 && !distributionStatus.equalsIgnoreCase(DistributionStatus.INCOMPLETE.name())) {
616 if (distributionStatus.equalsIgnoreCase(DistributionStatus.SUCCESS.name())) {
617 isDeploySuccess = true;
618 overallStatus = DistributionStatusEnum.DISTRIBUTION_COMPLETE_OK.name();
620 overallStatus = DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR.name();
622 componentsComplete = true;
626 if (!componentsComplete) {
627 logger.debug("Timeout of {} seconds was reached before all components reported status",
629 watchdogError = "Timeout occurred while waiting for all components to report status";
630 overallStatus = DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR.name();
633 if (distributionStatus == null) {
634 overallStatus = DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR.name();
635 logger.debug("DistributionStatus is null for DistributionId: {}", iNotif.getDistributionID());
639 wd.executePatchAAI(iNotif.getDistributionID(), iNotif.getServiceInvariantUUID(), overallStatus);
640 logger.debug("A&AI Updated succefully with Distribution Status!");
641 } catch (Exception e) {
642 logger.debug("Exception in Watchdog executePatchAAI(): {}", e.getMessage());
643 watchdogError = "Error calling A&AI " + e.getMessage();
644 if (e.getCause() != null) {
645 logger.debug("Exception caused by: {}", e.getCause().getMessage());
649 wd.updateCatalogDBStatus(iNotif.getServiceInvariantUUID(), overallStatus);
651 if (isDeploySuccess && watchdogError == null) {
652 sendFinalDistributionStatus(iNotif.getDistributionID(), DistributionStatusEnum.DISTRIBUTION_COMPLETE_OK,
654 WatchdogDistributionStatus wds = new WatchdogDistributionStatus(iNotif.getDistributionID());
655 wds.setDistributionIdStatus(DistributionStatusEnum.DISTRIBUTION_COMPLETE_OK.toString());
658 sendFinalDistributionStatus(iNotif.getDistributionID(),
659 DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR, watchdogError);
660 WatchdogDistributionStatus wds = new WatchdogDistributionStatus(iNotif.getDistributionID());
661 wds.setDistributionIdStatus(DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR.toString());
665 } catch (ObjectOptimisticLockingFailureException e) {
668 "OptimisticLockingFailure for DistributionId: {} Another process "
669 + "has already altered this distribution, so not going to process it on this site.",
670 iNotif.getDistributionID());
671 logger.error(LoggingAnchor.FIVE, MessageEnum.ASDC_GENERAL_EXCEPTION_ARG.toString(),
672 "Database concurrency exception: ", "ASDC", "treatNotification",
673 ErrorCode.BusinessProcesssError.getValue(), "RuntimeException in treatNotification", e);
675 } catch (Exception e) {
676 logger.error("", MessageEnum.ASDC_GENERAL_EXCEPTION_ARG.toString(),
677 "Unexpected exception caught during the notification processing", "ASDC", "treatNotification",
678 ErrorCode.SchemaError.getValue(), "RuntimeException in treatNotification", e);
681 wd.executePatchAAI(iNotif.getDistributionID(), iNotif.getServiceInvariantUUID(),
682 DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR.name());
683 logger.debug("A&AI Updated succefully with Distribution Status of {}",
684 DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR.name());
685 } catch (Exception aaiException) {
686 logger.debug("Exception in executePatchAAI(): {}", aaiException);
687 if (aaiException.getCause() != null) {
688 logger.debug("Exception caused by: {}", aaiException.getCause().getMessage());
692 sendFinalDistributionStatus(iNotif.getDistributionID(), DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR,
695 WatchdogDistributionStatus wds = new WatchdogDistributionStatus(iNotif.getDistributionID());
696 wds.setDistributionIdStatus(DistributionStatusEnum.DISTRIBUTION_COMPLETE_ERROR.toString());
700 this.changeControllerStatus(ASDCControllerStatus.IDLE);
704 protected void processResourceNotification(INotificationData iNotif) {
705 // For each artifact, create a structure describing the VFModule in a ordered flat level
706 ResourceStructure resourceStructure = null;
707 String msoConfigPath = getMsoConfigPath();
708 boolean hasVFResource = false;
709 ToscaResourceStructure toscaResourceStructure = new ToscaResourceStructure(msoConfigPath);
710 DistributionStatusEnum deployStatus = DistributionStatusEnum.DEPLOY_OK;
711 String errorMessage = null;
712 boolean serviceDeployed = false;
715 this.processCsarServiceArtifacts(iNotif, toscaResourceStructure);
716 IArtifactInfo iArtifact = toscaResourceStructure.getToscaArtifact();
718 msoConfigPath + "/ASDC/" + iArtifact.getArtifactVersion() + "/" + iArtifact.getArtifactName();
719 File csarFile = new File(filePath);
722 if (isCsarAlreadyDeployed(iNotif, toscaResourceStructure)) {
726 for (IResourceInstance resource : iNotif.getResources()) {
728 String resourceType = resource.getResourceType();
731 logger.info("Processing Resource Type: {}, Model UUID: {}", resourceType, resource.getResourceUUID());
733 if ("VF".equals(resourceType) && resource.getArtifacts() != null
734 && !resource.getArtifacts().isEmpty()) {
735 resourceStructure = new VfResourceStructure(iNotif, resource);
736 } else if ("PNF".equals(resourceType)) {
737 resourceStructure = new PnfResourceStructure(iNotif, resource);
739 // There are cases where the Service has no VF resources, those are handled here
740 logger.info("No resources found for Service: {}", iNotif.getServiceUUID());
741 resourceStructure = new VfResourceStructure(iNotif, new ResourceInstance());
742 resourceStructure.setResourceType(ResourceType.OTHER);
747 if (!this.checkResourceAlreadyDeployed(resourceStructure, serviceDeployed)) {
749 logger.debug("Processing Resource Type: " + resourceType + " and Model UUID: "
750 + resourceStructure.getResourceInstance().getResourceUUID());
752 if ("VF".equals(resourceType) && resource.getArtifacts() != null
753 && !resource.getArtifacts().isEmpty()) {
754 hasVFResource = true;
755 for (IArtifactInfo artifact : resource.getArtifacts()) {
756 IDistributionClientDownloadResult resultArtifact =
757 this.downloadTheArtifact(artifact, iNotif.getDistributionID());
758 if (resultArtifact != null) {
760 if (ASDCConfiguration.VF_MODULES_METADATA.equals(artifact.getArtifactType())) {
761 logger.debug("VF_MODULE_ARTIFACT: "
762 + new String(resultArtifact.getArtifactPayload(), "UTF-8"));
763 logger.debug(ASDCNotificationLogging
764 .dumpVfModuleMetaDataList(((VfResourceStructure) resourceStructure)
765 .decodeVfModuleArtifact(resultArtifact.getArtifactPayload())));
767 if (!ASDCConfiguration.WORKFLOW.equals(artifact.getArtifactType())) {
768 resourceStructure.addArtifactToStructure(distributionClient, artifact,
771 writeArtifactToFile(artifact, resultArtifact);
773 "Adding workflow artifact to structure: " + artifact.getArtifactName());
774 resourceStructure.addWorkflowArtifactToStructure(artifact, resultArtifact);
779 // Deploy VF resource and artifacts
780 logger.debug("Preparing to deploy Service: {}", iNotif.getServiceUUID());
783 this.deployResourceStructure(resourceStructure, toscaResourceStructure);
784 serviceDeployed = true;
788 } catch (ArtifactInstallerException e) {
789 deployStatus = DistributionStatusEnum.DEPLOY_ERROR;
790 errorMessage = e.getMessage();
791 logger.error("Exception occurred", e);
795 if (!hasVFResource) {
797 logger.debug("No resources found for Service: " + iNotif.getServiceUUID());
799 logger.debug("Preparing to deploy Service: {}", iNotif.getServiceUUID());
801 this.deployResourceStructure(resourceStructure, toscaResourceStructure);
802 } catch (ArtifactInstallerException e) {
803 deployStatus = DistributionStatusEnum.DEPLOY_ERROR;
804 errorMessage = e.getMessage();
805 logger.error("Exception occurred", e);
809 this.sendCsarDeployNotification(iNotif, resourceStructure, toscaResourceStructure, deployStatus,
812 } catch (ASDCDownloadException | UnsupportedEncodingException e) {
813 logger.error(LoggingAnchor.SIX, MessageEnum.ASDC_GENERAL_EXCEPTION_ARG.toString(),
814 "Exception caught during Installation of artifact", "ASDC", "processResourceNotification",
815 ErrorCode.BusinessProcesssError.getValue(), "Exception in processResourceNotification", e);
819 private String getMsoConfigPath() {
820 String msoConfigPath = System.getProperty("mso.config.path");
821 if (msoConfigPath == null) {
822 logger.info("Unable to find the system property mso.config.path, use the default configuration");
823 msoConfigPath = asdcConfig.getPropertyOrNull("mso.config.defaultpath");
825 if (msoConfigPath == null) {
826 logger.info("Unable to find the property: {} from configuration.", "mso.config.defaultpath");
829 logger.info("MSO config path is: {}", msoConfigPath);
830 return msoConfigPath;
833 protected void processCsarServiceArtifacts(INotificationData iNotif,
834 ToscaResourceStructure toscaResourceStructure) {
836 List<IArtifactInfo> serviceArtifacts = iNotif.getServiceArtifacts();
838 for (IArtifactInfo artifact : serviceArtifacts) {
840 if (artifact.getArtifactType().equals(ASDCConfiguration.TOSCA_CSAR)) {
844 toscaResourceStructure.setToscaArtifact(artifact);
846 IDistributionClientDownloadResult resultArtifact =
847 this.downloadTheArtifact(artifact, iNotif.getDistributionID());
849 writeArtifactToFile(artifact, resultArtifact);
851 toscaResourceStructure.updateResourceStructure(artifact);
853 toscaResourceStructure.setServiceVersion(iNotif.getServiceVersion());
855 logger.debug(ASDCNotificationLogging.dumpCSARNotification(iNotif, toscaResourceStructure));
858 } catch (Exception e) {
859 logger.error(LoggingAnchor.SIX, MessageEnum.ASDC_GENERAL_EXCEPTION_ARG.toString(),
860 "Exception caught during processCsarServiceArtifacts", "ASDC",
861 "processCsarServiceArtifacts", ErrorCode.BusinessProcesssError.getValue(),
862 "Exception in processCsarServiceArtifacts", e);
864 } else if (artifact.getArtifactType().equals(ASDCConfiguration.WORKFLOW)) {
868 IDistributionClientDownloadResult resultArtifact =
869 this.downloadTheArtifact(artifact, iNotif.getDistributionID());
871 writeArtifactToFile(artifact, resultArtifact);
873 toscaResourceStructure.setToscaArtifact(artifact);
875 logger.debug(ASDCNotificationLogging.dumpASDCNotification(iNotif));
878 } catch (Exception e) {
879 logger.info("Whats the error {}", e.getMessage());
880 logger.error(LoggingAnchor.SIX, MessageEnum.ASDC_GENERAL_EXCEPTION_ARG.toString(),
881 "Exception caught during processCsarServiceArtifacts", "ASDC",
882 "processCsarServiceArtifacts", ErrorCode.BusinessProcesssError.getValue(),
883 "Exception in processCsarServiceArtifacts", e);
894 * @return the address of the ASDC we are connected to.
896 public String getAddress() {
897 if (asdcConfig != null) {
898 return asdcConfig.getAsdcAddress();
904 * @return the environment name of the ASDC we are connected to.
906 public String getEnvironment() {
907 if (asdcConfig != null) {
908 return asdcConfig.getEnvironmentName();