-/*-\r
- * ============LICENSE_START=======================================================\r
- * ONAP CLAMP\r
- * ================================================================================\r
- * Copyright (C) 2018 AT&T Intellectual Property. All rights\r
- * reserved.\r
- * ================================================================================\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- * ============LICENSE_END============================================\r
- * ===================================================================\r
- * \r
- */\r
-\r
-package org.onap.clamp.clds.sdc.controller;\r
-\r
-import com.att.eelf.configuration.EELFLogger;\r
-import com.att.eelf.configuration.EELFManager;\r
-\r
-import java.util.Date;\r
-import java.util.Map.Entry;\r
-import java.util.concurrent.ThreadLocalRandom;\r
-\r
-import org.onap.clamp.clds.config.ClampProperties;\r
-import org.onap.clamp.clds.config.sdc.SdcSingleControllerConfiguration;\r
-import org.onap.clamp.clds.exception.sdc.controller.CsarHandlerException;\r
-import org.onap.clamp.clds.exception.sdc.controller.SdcArtifactInstallerException;\r
-import org.onap.clamp.clds.exception.sdc.controller.SdcControllerException;\r
-import org.onap.clamp.clds.exception.sdc.controller.SdcDownloadException;\r
-import org.onap.clamp.clds.exception.sdc.controller.SdcParametersException;\r
-import org.onap.clamp.clds.sdc.controller.installer.BlueprintArtifact;\r
-import org.onap.clamp.clds.sdc.controller.installer.CsarHandler;\r
-import org.onap.clamp.clds.sdc.controller.installer.CsarInstaller;\r
-import org.onap.clamp.clds.util.LoggingUtils;\r
-import org.onap.sdc.api.IDistributionClient;\r
-import org.onap.sdc.api.consumer.IDistributionStatusMessage;\r
-import org.onap.sdc.api.consumer.INotificationCallback;\r
-import org.onap.sdc.api.notification.IArtifactInfo;\r
-import org.onap.sdc.api.notification.INotificationData;\r
-import org.onap.sdc.api.results.IDistributionClientDownloadResult;\r
-import org.onap.sdc.api.results.IDistributionClientResult;\r
-import org.onap.sdc.impl.DistributionClientFactory;\r
-import org.onap.sdc.tosca.parser.exceptions.SdcToscaParserException;\r
-import org.onap.sdc.utils.DistributionActionResultEnum;\r
-import org.onap.sdc.utils.DistributionStatusEnum;\r
-\r
-/**\r
- * This class handles one sdc controller defined in the config.\r
- */\r
-public class SdcSingleController {\r
-\r
- private static final EELFLogger logger = EELFManager.getInstance().getLogger(SdcSingleController.class);\r
- private boolean isSdcClientAutoManaged = false;\r
- private CsarInstaller csarInstaller;\r
- private ClampProperties refProp;\r
- public static final String CONFIG_SDC_FOLDER = "sdc.csarFolder";\r
- private int nbOfNotificationsOngoing = 0;\r
- private SdcSingleControllerStatus controllerStatus = SdcSingleControllerStatus.STOPPED;\r
- private SdcSingleControllerConfiguration sdcConfig;\r
- private IDistributionClient distributionClient;\r
-\r
- /**\r
- * Inner class for Notification callback\r
- */\r
- private final class SdcNotificationCallBack implements INotificationCallback {\r
-\r
- private SdcSingleController sdcController;\r
-\r
- SdcNotificationCallBack(SdcSingleController controller) {\r
- sdcController = controller;\r
- }\r
-\r
- /**\r
- * This method can be called multiple times at the same moment. The\r
- * controller must be thread safe !\r
- */\r
- @Override\r
- public void activateCallback(INotificationData iNotif) {\r
- Date startTime = new Date();\r
- logger.info("Receive a callback notification in SDC, nb of resources: " + iNotif.getResources().size());\r
- sdcController.treatNotification(iNotif);\r
- LoggingUtils.setTimeContext(startTime, new Date());\r
- LoggingUtils.setResponseContext("0", "SDC Notification received and processed successfully",\r
- this.getClass().getName());\r
- }\r
- }\r
-\r
- public int getNbOfNotificationsOngoing() {\r
- return nbOfNotificationsOngoing;\r
- }\r
-\r
- private void changeControllerStatusIdle() {\r
- if (this.nbOfNotificationsOngoing > 1) {\r
- --this.nbOfNotificationsOngoing;\r
- } else {\r
- this.nbOfNotificationsOngoing = 0;\r
- this.controllerStatus = SdcSingleControllerStatus.IDLE;\r
- }\r
- }\r
-\r
- protected final synchronized void changeControllerStatus(SdcSingleControllerStatus newControllerStatus) {\r
- switch (newControllerStatus) {\r
- case BUSY:\r
- ++this.nbOfNotificationsOngoing;\r
- this.controllerStatus = newControllerStatus;\r
- break;\r
- case IDLE:\r
- this.changeControllerStatusIdle();\r
- break;\r
- default:\r
- this.controllerStatus = newControllerStatus;\r
- break;\r
- }\r
- }\r
-\r
- public final synchronized SdcSingleControllerStatus getControllerStatus() {\r
- return this.controllerStatus;\r
- }\r
-\r
- public SdcSingleController(ClampProperties clampProp, CsarInstaller csarInstaller,\r
- SdcSingleControllerConfiguration sdcSingleConfig, boolean isClientAutoManaged) {\r
- this.isSdcClientAutoManaged = isClientAutoManaged;\r
- this.sdcConfig = sdcSingleConfig;\r
- this.refProp = clampProp;\r
- this.csarInstaller = csarInstaller;\r
- }\r
-\r
- /**\r
- * This method initializes the SDC Controller and the SDC Client.\r
- *\r
- * @throws SdcControllerException\r
- * It throws an exception if the SDC Client cannot be\r
- * instantiated or if an init attempt is done when already\r
- * initialized\r
- * @throws SdcParametersException\r
- * If there is an issue with the parameters provided\r
- */\r
- public void initSdc() throws SdcControllerException {\r
- logger.info("Attempt to initialize the SDC Controller: " + sdcConfig.getSdcControllerName());\r
- if (this.getControllerStatus() != SdcSingleControllerStatus.STOPPED) {\r
- throw new SdcControllerException("The controller is already initialized, call the closeSDC method first");\r
- }\r
- if (this.distributionClient == null) {\r
- distributionClient = DistributionClientFactory.createDistributionClient();\r
- }\r
- IDistributionClientResult result = this.distributionClient.init(sdcConfig, new SdcNotificationCallBack(this));\r
- if (!result.getDistributionActionResult().equals(DistributionActionResultEnum.SUCCESS)) {\r
- logger.error("SDC distribution client init failed with reason:" + result.getDistributionMessageResult());\r
- this.changeControllerStatus(SdcSingleControllerStatus.STOPPED);\r
- throw new SdcControllerException("Initialization of the SDC Controller failed with reason: "\r
- + result.getDistributionMessageResult());\r
- }\r
- logger.info("SDC Controller successfully initialized: " + sdcConfig.getSdcControllerName());\r
- logger.info("Attempt to start the SDC Controller: " + sdcConfig.getSdcControllerName());\r
- result = this.distributionClient.start();\r
- if (!result.getDistributionActionResult().equals(DistributionActionResultEnum.SUCCESS)) {\r
- logger.error("SDC distribution client start failed with reason:" + result.getDistributionMessageResult());\r
- this.changeControllerStatus(SdcSingleControllerStatus.STOPPED);\r
- throw new SdcControllerException(\r
- "Startup of the SDC Controller failed with reason: " + result.getDistributionMessageResult());\r
- }\r
- logger.info("SDC Controller successfully started: " + sdcConfig.getSdcControllerName());\r
- this.changeControllerStatus(SdcSingleControllerStatus.IDLE);\r
- }\r
-\r
- /**\r
- * This method closes the SDC Controller and the SDC Client.\r
- *\r
- * @throws SdcControllerException\r
- * It throws an exception if the SDC Client cannot be closed\r
- * because it's currently BUSY in processing notifications.\r
- */\r
- public void closeSdc() throws SdcControllerException {\r
- if (this.getControllerStatus() == SdcSingleControllerStatus.BUSY) {\r
- throw new SdcControllerException("Cannot close the SDC controller as it's currently in BUSY state");\r
- }\r
- if (this.distributionClient != null) {\r
- this.distributionClient.stop();\r
- // If auto managed we can set it to Null, SdcController controls it.\r
- // In the other case the client of this class has specified it, so\r
- // we can't reset it\r
- if (isSdcClientAutoManaged) {\r
- // Next init will initialize it with a new SDC Client\r
- this.distributionClient = null;\r
- }\r
- }\r
- this.changeControllerStatus(SdcSingleControllerStatus.STOPPED);\r
- }\r
-\r
- private void sendAllNotificationForCsarHandler(INotificationData iNotif, CsarHandler csar,\r
- NotificationType notificationType, DistributionStatusEnum distributionStatus, String errorMessage) {\r
- if (csar != null) {\r
- // Notify for the CSAR\r
- this.sendSdcNotification(notificationType, csar.getArtifactElement().getArtifactURL(),\r
- sdcConfig.getConsumerID(), iNotif.getDistributionID(), distributionStatus, errorMessage,\r
- System.currentTimeMillis());\r
- // Notify for all VF resources found\r
- for (Entry<String, BlueprintArtifact> blueprint : csar.getMapOfBlueprints().entrySet()) {\r
- // Normally always 1 artifact in resource for Clamp as we\r
- // specified\r
- // only VF_METADATA type\r
- this.sendSdcNotification(notificationType,\r
- blueprint.getValue().getResourceAttached().getArtifacts().get(0).getArtifactURL(),\r
- sdcConfig.getConsumerID(), iNotif.getDistributionID(), distributionStatus, errorMessage,\r
- System.currentTimeMillis());\r
- }\r
- } else {\r
- this.sendSdcNotification(notificationType, null, sdcConfig.getConsumerID(), iNotif.getDistributionID(),\r
- distributionStatus, errorMessage, System.currentTimeMillis());\r
- }\r
- }\r
-\r
- /**\r
- * This method processes the notification received from Sdc.\r
- * \r
- * @param iNotif\r
- * The INotificationData\r
- */\r
- public void treatNotification(INotificationData iNotif) {\r
- CsarHandler csar = null;\r
- try {\r
- // wait for a random time, so that 2 running Clamp will not treat\r
- // the same Notification at the same time\r
- Thread.sleep(ThreadLocalRandom.current().nextInt(1, 10) * 1000L);\r
- logger.info("Notification received for service UUID:" + iNotif.getServiceUUID());\r
- this.changeControllerStatus(SdcSingleControllerStatus.BUSY);\r
- csar = new CsarHandler(iNotif, this.sdcConfig.getSdcControllerName(),\r
- refProp.getStringValue(CONFIG_SDC_FOLDER));\r
- csar.save(downloadTheArtifact(csar.getArtifactElement()));\r
- if (csarInstaller.isCsarAlreadyDeployed(csar)) {\r
- sendAllNotificationForCsarHandler(iNotif, csar, NotificationType.DOWNLOAD,\r
- DistributionStatusEnum.ALREADY_DOWNLOADED, null);\r
- sendAllNotificationForCsarHandler(iNotif, csar, NotificationType.DEPLOY,\r
- DistributionStatusEnum.ALREADY_DEPLOYED, null);\r
- } else {\r
- sendAllNotificationForCsarHandler(iNotif, csar, NotificationType.DOWNLOAD,\r
- DistributionStatusEnum.DOWNLOAD_OK, null);\r
- csarInstaller.installTheCsar(csar);\r
- sendAllNotificationForCsarHandler(iNotif, csar, NotificationType.DEPLOY,\r
- DistributionStatusEnum.DEPLOY_OK, null);\r
- }\r
- } catch (SdcArtifactInstallerException | SdcToscaParserException e) {\r
- logger.error("SdcArtifactInstallerException exception caught during the notification processing", e);\r
- sendAllNotificationForCsarHandler(iNotif, csar, NotificationType.DEPLOY,\r
- DistributionStatusEnum.DEPLOY_ERROR, e.getMessage());\r
- } catch (SdcDownloadException | CsarHandlerException e) {\r
- logger.error("SdcDownloadException exception caught during the notification processing", e);\r
- sendAllNotificationForCsarHandler(iNotif, csar, NotificationType.DOWNLOAD,\r
- DistributionStatusEnum.DOWNLOAD_ERROR, e.getMessage());\r
- } catch (InterruptedException e) {\r
- logger.error("Interrupt exception caught during the notification processing", e);\r
- sendAllNotificationForCsarHandler(iNotif, csar, NotificationType.DEPLOY,\r
- DistributionStatusEnum.DEPLOY_ERROR, e.getMessage());\r
- Thread.currentThread().interrupt();\r
- } catch (RuntimeException e) {\r
- logger.error("Unexpected exception caught during the notification processing", e);\r
- sendAllNotificationForCsarHandler(iNotif, csar, NotificationType.DEPLOY,\r
- DistributionStatusEnum.DEPLOY_ERROR, e.getMessage());\r
- } finally {\r
- this.changeControllerStatus(SdcSingleControllerStatus.IDLE);\r
- }\r
- }\r
-\r
- private enum NotificationType {\r
- DOWNLOAD, DEPLOY\r
- }\r
-\r
- private IDistributionClientDownloadResult downloadTheArtifact(IArtifactInfo artifact) throws SdcDownloadException {\r
- logger.info("Trying to download the artifact : " + artifact.getArtifactURL() + " UUID: "\r
- + artifact.getArtifactUUID());\r
- IDistributionClientDownloadResult downloadResult;\r
- try {\r
- downloadResult = distributionClient.download(artifact);\r
- if (null == downloadResult) {\r
- logger.info("downloadResult is Null for: " + artifact.getArtifactUUID());\r
- return null;\r
- }\r
- } catch (RuntimeException e) {\r
- throw new SdcDownloadException("Exception caught when downloading the artifact", e);\r
- }\r
- if (DistributionActionResultEnum.SUCCESS.equals(downloadResult.getDistributionActionResult())) {\r
- logger.info("Successfully downloaded the artifact " + artifact.getArtifactURL() + " UUID "\r
- + artifact.getArtifactUUID() + "Size of payload " + downloadResult.getArtifactPayload().length);\r
- } else {\r
- throw new SdcDownloadException("Artifact " + artifact.getArtifactName()\r
- + " could not be downloaded from SDC URL " + artifact.getArtifactURL() + " UUID "\r
- + artifact.getArtifactUUID() + ")" + System.lineSeparator() + "Error message is "\r
- + downloadResult.getDistributionMessageResult() + System.lineSeparator());\r
- }\r
- return downloadResult;\r
- }\r
-\r
- private void sendSdcNotification(NotificationType notificationType, String artifactURL, String consumerID,\r
- String distributionID, DistributionStatusEnum status, String errorReason, long timestamp) {\r
- String event = "Sending " + notificationType.name() + "(" + status.name() + ")"\r
- + " notification to SDC for artifact:" + artifactURL;\r
- if (errorReason != null) {\r
- event = event + "(" + errorReason + ")";\r
- }\r
- logger.info(event);\r
- String action = "";\r
- try {\r
- IDistributionStatusMessage message = new DistributionStatusMessage(artifactURL, consumerID, distributionID,\r
- status, timestamp);\r
- switch (notificationType) {\r
- case DOWNLOAD:\r
- this.sendDownloadStatus(message, errorReason);\r
- action = "sendDownloadStatus";\r
- break;\r
- case DEPLOY:\r
- this.sendDeploymentStatus(message, errorReason);\r
- action = "sendDeploymentdStatus";\r
- break;\r
- default:\r
- break;\r
- }\r
- } catch (RuntimeException e) {\r
- logger.warn("Unable to send the SDC Notification (" + action + ") due to an exception", e);\r
- }\r
- logger.info("SDC Notification sent successfully(" + action + ")");\r
- }\r
-\r
- private void sendDownloadStatus(IDistributionStatusMessage message, String errorReason) {\r
- if (errorReason != null) {\r
- this.distributionClient.sendDownloadStatus(message, errorReason);\r
- } else {\r
- this.distributionClient.sendDownloadStatus(message);\r
- }\r
- }\r
-\r
- private void sendDeploymentStatus(IDistributionStatusMessage message, String errorReason) {\r
- if (errorReason != null) {\r
- this.distributionClient.sendDeploymentStatus(message, errorReason);\r
- } else {\r
- this.distributionClient.sendDeploymentStatus(message);\r
- }\r
- }\r
-}\r
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2018-2019 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * Modifications copyright (c) 2018 Nokia
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.clds.sdc.controller;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+import java.util.Date;
+import java.util.Map.Entry;
+import java.util.concurrent.ThreadLocalRandom;
+
+import org.onap.clamp.clds.config.ClampProperties;
+import org.onap.clamp.clds.config.sdc.SdcSingleControllerConfiguration;
+import org.onap.clamp.clds.exception.sdc.controller.BlueprintParserException;
+import org.onap.clamp.clds.exception.sdc.controller.CsarHandlerException;
+import org.onap.clamp.clds.exception.sdc.controller.SdcArtifactInstallerException;
+import org.onap.clamp.clds.exception.sdc.controller.SdcControllerException;
+import org.onap.clamp.clds.exception.sdc.controller.SdcDownloadException;
+import org.onap.clamp.clds.sdc.controller.installer.BlueprintArtifact;
+import org.onap.clamp.clds.sdc.controller.installer.CsarHandler;
+import org.onap.clamp.clds.util.LoggingUtils;
+import org.onap.clamp.loop.CsarInstaller;
+import org.onap.sdc.api.IDistributionClient;
+import org.onap.sdc.api.consumer.IComponentDoneStatusMessage;
+import org.onap.sdc.api.consumer.IDistributionStatusMessage;
+import org.onap.sdc.api.consumer.INotificationCallback;
+import org.onap.sdc.api.notification.IArtifactInfo;
+import org.onap.sdc.api.notification.INotificationData;
+import org.onap.sdc.api.results.IDistributionClientDownloadResult;
+import org.onap.sdc.api.results.IDistributionClientResult;
+import org.onap.sdc.impl.DistributionClientFactory;
+import org.onap.sdc.tosca.parser.exceptions.SdcToscaParserException;
+import org.onap.sdc.utils.DistributionActionResultEnum;
+import org.onap.sdc.utils.DistributionStatusEnum;
+
+/**
+ * This class handles one sdc controller defined in the config.
+ */
+public class SdcSingleController {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(SdcSingleController.class);
+ private boolean isSdcClientAutoManaged = false;
+ private CsarInstaller csarInstaller;
+ private ClampProperties refProp;
+ /**
+ * The constant CONFIG_SDC_FOLDER.
+ */
+ public static final String CONFIG_SDC_FOLDER = "sdc.csarFolder";
+ private int nbOfNotificationsOngoing = 0;
+ private SdcSingleControllerStatus controllerStatus = SdcSingleControllerStatus.STOPPED;
+ private SdcSingleControllerConfiguration sdcConfig;
+ private IDistributionClient distributionClient;
+
+ /**
+ * Inner class for Notification callback.
+ */
+ private final class SdcNotificationCallBack implements INotificationCallback {
+
+ private SdcSingleController sdcController;
+
+ /**
+ * Instantiates a new Sdc notification call back.
+ *
+ * @param controller the controller
+ */
+ SdcNotificationCallBack(SdcSingleController controller) {
+ sdcController = controller;
+ }
+
+ /**
+ * This method can be called multiple times at the same moment. The controller
+ * must be thread safe !
+ */
+ @Override
+ public void activateCallback(INotificationData notificationData) {
+ Date startTime = new Date();
+ logger.info("Receive a callback notification in SDC, nb of resources: "
+ + notificationData.getResources().size());
+ sdcController.treatNotification(notificationData);
+ LoggingUtils.setTimeContext(startTime, new Date());
+ LoggingUtils.setResponseContext("0", "SDC Notification received and processed successfully",
+ this.getClass().getName());
+ }
+ }
+
+ /**
+ * Gets nb of notifications ongoing.
+ *
+ * @return the nb of notifications ongoing
+ */
+ public int getNbOfNotificationsOngoing() {
+ return nbOfNotificationsOngoing;
+ }
+
+ private void changeControllerStatusIdle() {
+ if (this.nbOfNotificationsOngoing > 1) {
+ --this.nbOfNotificationsOngoing;
+ } else {
+ this.nbOfNotificationsOngoing = 0;
+ this.controllerStatus = SdcSingleControllerStatus.IDLE;
+ }
+ }
+
+ /**
+ * Change controller status.
+ *
+ * @param newControllerStatus the new controller status
+ */
+ protected final synchronized void changeControllerStatus(SdcSingleControllerStatus newControllerStatus) {
+ switch (newControllerStatus) {
+ case BUSY:
+ ++this.nbOfNotificationsOngoing;
+ this.controllerStatus = newControllerStatus;
+ break;
+ case IDLE:
+ this.changeControllerStatusIdle();
+ break;
+ default:
+ this.controllerStatus = newControllerStatus;
+ break;
+ }
+ }
+
+ /**
+ * Gets controller status.
+ *
+ * @return the controller status
+ */
+ public final synchronized SdcSingleControllerStatus getControllerStatus() {
+ return this.controllerStatus;
+ }
+
+ /**
+ * Instantiates a new Sdc single controller.
+ *
+ * @param clampProp the clamp prop
+ * @param csarInstaller the csar installer
+ * @param sdcSingleConfig the sdc single config
+ * @param distributionClient the distribution client
+ */
+ public SdcSingleController(ClampProperties clampProp, CsarInstaller csarInstaller,
+ SdcSingleControllerConfiguration sdcSingleConfig,
+ IDistributionClient distributionClient) {
+ this.distributionClient = distributionClient;
+ isSdcClientAutoManaged = (distributionClient == null);
+ this.sdcConfig = sdcSingleConfig;
+ this.refProp = clampProp;
+ this.csarInstaller = csarInstaller;
+ }
+
+ /**
+ * This method initializes the SDC Controller and the SDC Client.
+ *
+ * @throws SdcControllerException It throws an exception if the SDC Client
+ * cannot be instantiated or if an init attempt
+ * is done when already initialized
+ */
+ public void initSdc() throws SdcControllerException {
+ logger.info("Attempt to initialize the SDC Controller: " + sdcConfig.getSdcControllerName());
+ if (this.getControllerStatus() != SdcSingleControllerStatus.STOPPED) {
+ throw new SdcControllerException("The controller is already initialized, call the closeSDC method first");
+ }
+ if (distributionClient == null) {
+ distributionClient = DistributionClientFactory.createDistributionClient();
+ }
+ IDistributionClientResult result = distributionClient.init(sdcConfig, new SdcNotificationCallBack(this));
+ if (!result.getDistributionActionResult().equals(DistributionActionResultEnum.SUCCESS)) {
+ logger.error("SDC distribution client init failed with reason:" + result.getDistributionMessageResult());
+ this.changeControllerStatus(SdcSingleControllerStatus.STOPPED);
+ throw new SdcControllerException("Initialization of the SDC Controller failed with reason: "
+ + result.getDistributionMessageResult());
+ }
+ logger.info("SDC Controller successfully initialized: " + sdcConfig.getSdcControllerName());
+ logger.info("Attempt to start the SDC Controller: " + sdcConfig.getSdcControllerName());
+ result = this.distributionClient.start();
+ if (!result.getDistributionActionResult().equals(DistributionActionResultEnum.SUCCESS)) {
+ logger.error("SDC distribution client start failed with reason:" + result.getDistributionMessageResult());
+ this.changeControllerStatus(SdcSingleControllerStatus.STOPPED);
+ throw new SdcControllerException(
+ "Startup of the SDC Controller failed with reason: " + result.getDistributionMessageResult());
+ }
+ logger.info("SDC Controller successfully started: " + sdcConfig.getSdcControllerName());
+ this.changeControllerStatus(SdcSingleControllerStatus.IDLE);
+ }
+
+ /**
+ * This method closes the SDC Controller and the SDC Client.
+ *
+ * @throws SdcControllerException It throws an exception if the SDC Client
+ * cannot be closed because it's currently BUSY
+ * in processing notifications.
+ */
+ public void closeSdc() throws SdcControllerException {
+ if (this.getControllerStatus() == SdcSingleControllerStatus.BUSY) {
+ throw new SdcControllerException("Cannot close the SDC controller as it's currently in BUSY state");
+ }
+ if (this.distributionClient != null) {
+ this.distributionClient.stop();
+ // If auto managed we can set it to Null, SdcController controls it.
+ // In the other case the client of this class has specified it, so
+ // we can't reset it
+ if (isSdcClientAutoManaged) {
+ // Next init will initialize it with a new SDC Client
+ this.distributionClient = null;
+ }
+ }
+ this.changeControllerStatus(SdcSingleControllerStatus.STOPPED);
+ }
+
+ private void sendAllNotificationForCsarHandler(INotificationData notificationData, CsarHandler csar,
+ NotificationType notificationType,
+ DistributionStatusEnum distributionStatus, String errorMessage) {
+ if (csar != null) {
+ // Notify for the CSAR
+ this.sendSdcNotification(notificationType, csar.getArtifactElement().getArtifactURL(),
+ sdcConfig.getConsumerID(), notificationData.getDistributionID(), distributionStatus, errorMessage,
+ System.currentTimeMillis());
+ // Notify for all VF resources found
+ for (Entry<String, BlueprintArtifact> blueprint : csar.getMapOfBlueprints().entrySet()) {
+ // Normally always 1 artifact in resource for Clamp as we
+ // specified
+ // only VF_METADATA type
+ this.sendSdcNotification(notificationType,
+ blueprint.getValue().getResourceAttached().getArtifacts().get(0).getArtifactURL(),
+ sdcConfig.getConsumerID(), notificationData.getDistributionID(), distributionStatus,
+ errorMessage, System.currentTimeMillis());
+ }
+ } else {
+ this.sendSdcNotification(notificationType, null, sdcConfig.getConsumerID(),
+ notificationData.getDistributionID(), distributionStatus, errorMessage, System.currentTimeMillis());
+ }
+ }
+
+ /**
+ * This method processes the notification received from Sdc.
+ *
+ * @param notificationData The INotificationData
+ */
+ public void treatNotification(INotificationData notificationData) {
+ CsarHandler csar = null;
+ try {
+ // wait for a random time, so that 2 running Clamp will not treat
+ // the same Notification at the same time
+ Thread.sleep(ThreadLocalRandom.current().nextInt(1, 10) * 1000L);
+ logger.info("Notification received for service UUID:" + notificationData.getServiceUUID());
+ this.changeControllerStatus(SdcSingleControllerStatus.BUSY);
+ csar = new CsarHandler(notificationData, this.sdcConfig.getSdcControllerName(),
+ refProp.getStringValue(CONFIG_SDC_FOLDER));
+ csar.save(downloadTheArtifact(csar.getArtifactElement()));
+ if (csarInstaller.isCsarAlreadyDeployed(csar)) {
+ sendAllNotificationForCsarHandler(notificationData, csar, NotificationType.DOWNLOAD,
+ DistributionStatusEnum.ALREADY_DOWNLOADED, null);
+ sendAllNotificationForCsarHandler(notificationData, csar, NotificationType.DEPLOY,
+ DistributionStatusEnum.ALREADY_DEPLOYED, null);
+ } else {
+ sendAllNotificationForCsarHandler(notificationData, csar, NotificationType.DOWNLOAD,
+ DistributionStatusEnum.DOWNLOAD_OK, null);
+ csarInstaller.installTheCsar(csar);
+ sendAllNotificationForCsarHandler(notificationData, csar, NotificationType.DEPLOY,
+ DistributionStatusEnum.DEPLOY_OK, null);
+ }
+ this.sendComponentStatus(notificationData, DistributionStatusEnum.COMPONENT_DONE_OK, null);
+ } catch (SdcArtifactInstallerException | SdcToscaParserException e) {
+ logger.error("SdcArtifactInstallerException exception caught during the notification processing", e);
+ sendAllNotificationForCsarHandler(notificationData, csar, NotificationType.DEPLOY,
+ DistributionStatusEnum.DEPLOY_ERROR, e.getMessage());
+ this.sendComponentStatus(notificationData, DistributionStatusEnum.COMPONENT_DONE_ERROR, e.getMessage());
+ } catch (SdcDownloadException | CsarHandlerException e) {
+ logger.error("SdcDownloadException exception caught during the notification processing", e);
+ sendAllNotificationForCsarHandler(notificationData, csar, NotificationType.DOWNLOAD,
+ DistributionStatusEnum.DOWNLOAD_ERROR, e.getMessage());
+ this.sendComponentStatus(notificationData, DistributionStatusEnum.COMPONENT_DONE_ERROR, e.getMessage());
+ } catch (InterruptedException e) {
+ logger.error("Interrupt exception caught during the notification processing", e);
+ sendAllNotificationForCsarHandler(notificationData, csar, NotificationType.DEPLOY,
+ DistributionStatusEnum.DEPLOY_ERROR, e.getMessage());
+ this.sendComponentStatus(notificationData, DistributionStatusEnum.COMPONENT_DONE_ERROR, e.getMessage());
+ Thread.currentThread().interrupt();
+ } catch (BlueprintParserException e) {
+ logger.error("BlueprintParser exception caught during the notification processing", e);
+ sendAllNotificationForCsarHandler(notificationData, csar, NotificationType.DEPLOY,
+ DistributionStatusEnum.DEPLOY_ERROR, e.getMessage());
+ this.sendComponentStatus(notificationData, DistributionStatusEnum.COMPONENT_DONE_ERROR, e.getMessage());
+ } catch (RuntimeException e) {
+ logger.error("Unexpected exception caught during the notification processing", e);
+ sendAllNotificationForCsarHandler(notificationData, csar, NotificationType.DEPLOY,
+ DistributionStatusEnum.DEPLOY_ERROR, e.getMessage());
+ this.sendComponentStatus(notificationData, DistributionStatusEnum.COMPONENT_DONE_ERROR, e.getMessage());
+ } finally {
+ this.changeControllerStatus(SdcSingleControllerStatus.IDLE);
+ }
+ }
+
+ private enum NotificationType {
+ /**
+ * Download notification type.
+ */
+ DOWNLOAD,
+ /**
+ * Deploy notification type.
+ */
+ DEPLOY
+ }
+
+ private IDistributionClientDownloadResult downloadTheArtifact(IArtifactInfo artifact) throws SdcDownloadException {
+ logger.info("Trying to download the artifact : " + artifact.getArtifactURL() + " UUID: "
+ + artifact.getArtifactUUID());
+ IDistributionClientDownloadResult downloadResult;
+ try {
+ downloadResult = distributionClient.download(artifact);
+ if (null == downloadResult) {
+ logger.info("downloadResult is Null for: " + artifact.getArtifactUUID());
+ return null;
+ }
+ } catch (RuntimeException e) {
+ throw new SdcDownloadException("Exception caught when downloading the artifact", e);
+ }
+ if (DistributionActionResultEnum.SUCCESS.equals(downloadResult.getDistributionActionResult())) {
+ logger.info("Successfully downloaded the artifact " + artifact.getArtifactURL() + " UUID "
+ + artifact.getArtifactUUID() + "Size of payload " + downloadResult.getArtifactPayload().length);
+ } else {
+ throw new SdcDownloadException("Artifact " + artifact.getArtifactName()
+ + " could not be downloaded from SDC URL " + artifact.getArtifactURL() + " UUID "
+ + artifact.getArtifactUUID() + ")" + System.lineSeparator() + "Error message is "
+ + downloadResult.getDistributionMessageResult() + System.lineSeparator());
+ }
+ return downloadResult;
+ }
+
+ private void sendSdcNotification(NotificationType notificationType, String artifactUrl, String consumerId,
+ String distributionId, DistributionStatusEnum status, String errorReason,
+ long timestamp) {
+ String event = "Sending " + notificationType.name() + "(" + status.name() + ")"
+ + " notification to SDC for artifact:" + artifactUrl;
+ if (errorReason != null) {
+ event = event + "(" + errorReason + ")";
+ }
+ logger.info(event);
+ String action = "";
+ try {
+ IDistributionStatusMessage message = new DistributionStatusMessage(artifactUrl, consumerId, distributionId,
+ status, timestamp);
+ switch (notificationType) {
+ case DOWNLOAD:
+ this.sendDownloadStatus(message, errorReason);
+ action = "sendDownloadStatus";
+ break;
+ case DEPLOY:
+ this.sendDeploymentStatus(message, errorReason);
+ action = "sendDeploymentdStatus";
+ break;
+ default:
+ break;
+ }
+ } catch (RuntimeException e) {
+ logger.warn("Unable to send the SDC Notification (" + action + ") due to an exception", e);
+ }
+ logger.info("SDC Notification sent successfully(" + action + ")");
+ }
+
+ private void sendComponentStatus(INotificationData notificationData, DistributionStatusEnum status,
+ String errorReason) {
+ try {
+ IComponentDoneStatusMessage message = new IComponentDoneStatusMessage() {
+
+ @Override public String getDistributionID() {
+ return notificationData.getDistributionID();
+ }
+
+ @Override public String getConsumerID() {
+ return sdcConfig.getConsumerID();
+ }
+
+ @Override public long getTimestamp() {
+ return System.currentTimeMillis();
+ }
+
+ @Override public DistributionStatusEnum getStatus() {
+ return status;
+ }
+
+ @Override public String getComponentName() {
+ return sdcConfig.getUser();
+ }
+ };
+
+ if (errorReason != null) {
+ this.distributionClient.sendComponentDoneStatus(message, errorReason);
+ } else {
+ this.distributionClient.sendComponentDoneStatus(message);
+ }
+ } catch (RuntimeException e) {
+ logger.warn("Unable to send the SDC Notification (" + status.name() + ") due to an exception", e);
+ }
+ logger.info("SDC Notification sent successfully(" + status.name() + ")");
+ }
+
+ private void sendDownloadStatus(IDistributionStatusMessage message, String errorReason) {
+ if (errorReason != null) {
+ this.distributionClient.sendDownloadStatus(message, errorReason);
+ } else {
+ this.distributionClient.sendDownloadStatus(message);
+ }
+ }
+
+ private void sendDeploymentStatus(IDistributionStatusMessage message, String errorReason) {
+ if (errorReason != null) {
+ this.distributionClient.sendDeploymentStatus(message, errorReason);
+ } else {
+ this.distributionClient.sendDeploymentStatus(message);
+ }
+ }
+}