2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.be.components.distribution.engine;
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.List;
27 import java.util.concurrent.atomic.AtomicBoolean;
28 import java.util.regex.Matcher;
29 import java.util.regex.Pattern;
31 import javax.annotation.PostConstruct;
32 import javax.annotation.PreDestroy;
34 import org.openecomp.sdc.be.config.BeEcompErrorManager;
35 import org.openecomp.sdc.be.config.ConfigurationManager;
36 import org.openecomp.sdc.be.config.DistributionEngineConfiguration;
37 import org.openecomp.sdc.be.impl.ComponentsUtils;
38 import org.openecomp.sdc.be.model.Service;
39 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
40 import org.openecomp.sdc.common.config.EcompErrorName;
41 import org.openecomp.sdc.common.util.YamlToObjectConverter;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44 import org.springframework.stereotype.Component;
46 import fj.data.Either;
48 @Component("distributionEngine")
49 public class DistributionEngine implements IDistributionEngine {
51 public static final Pattern FQDN_PATTERN = Pattern.compile("^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])(\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]))*(:[0-9]{2,4})*$", Pattern.CASE_INSENSITIVE);
53 public static void main(String[] args) {
55 List<String> servers = new ArrayList<>();
57 servers.add("uebsb91kcdc.it.att.com:3904");
58 servers.add("uebsb91kcdc.it.att.com:3904");
59 servers.add("uebsb91kcdc.it.att.com:3904");
61 YamlToObjectConverter converter = new YamlToObjectConverter();
62 DistributionEngineConfiguration distributionEngineConfiguration = converter.convert("src/test/resources/config/catalog-be/distribEngine1/distribution-engine-configuration.yaml", DistributionEngineConfiguration.class);
64 DistributionEngineInitTask distributionEngineInitTask = new DistributionEngineInitTask(2l, distributionEngineConfiguration, "PROD", new AtomicBoolean(false), null, null);
65 distributionEngineInitTask.startTask();
69 @javax.annotation.Resource
70 private ComponentsUtils componentUtils;
72 @javax.annotation.Resource
73 private DistributionNotificationSender distributionNotificationSender;
75 @javax.annotation.Resource
76 private ServiceDistributionArtifactsBuilder serviceDistributionArtifactsBuilder;
78 @javax.annotation.Resource
79 private DistributionEngineClusterHealth distributionEngineClusterHealth;
81 private static Logger logger = LoggerFactory.getLogger(DistributionEngine.class.getName());
83 private Map<String, DistributionEngineInitTask> envNamePerInitTask = new HashMap<String, DistributionEngineInitTask>();
84 private Map<String, DistributionEnginePollingTask> envNamePerPollingTask = new HashMap<String, DistributionEnginePollingTask>();
86 private Map<String, AtomicBoolean> envNamePerStatus = new HashMap<String, AtomicBoolean>();
89 public boolean isActive() {
91 if (true == envNamePerInitTask.isEmpty()) {
95 for (DistributionEngineInitTask task : envNamePerInitTask.values()) {
96 boolean active = task.isActive();
97 if (active == false) {
105 private void init() {
107 logger.trace("Enter init method of DistributionEngine");
109 DistributionEngineConfiguration distributionEngineConfiguration = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration();
111 boolean startDistributionEngine = distributionEngineConfiguration.isStartDistributionEngine();
112 logger.debug("Distribution engine activation parameter is {}", startDistributionEngine);
113 if (false == startDistributionEngine) {
114 logger.info("The disribution engine is disabled");
116 this.distributionEngineClusterHealth.setHealthCheckUebIsDisabled();
121 boolean isValidConfig = validateConfiguration(distributionEngineConfiguration);
123 if (false == isValidConfig) {
124 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUebSystemError, DistributionEngineInitTask.INIT_DISTRIBUTION_ENGINE_FLOW, "validate distribution configuration in init phase");
125 BeEcompErrorManager.getInstance().logBeUebSystemError(DistributionEngineInitTask.INIT_DISTRIBUTION_ENGINE_FLOW, "validate distribution configuration in init phase");
127 this.distributionEngineClusterHealth.setHealthCheckUebConfigurationError();
131 List<String> environments = distributionEngineConfiguration.getEnvironments();
133 for (String envName : environments) {
135 DistributionEnginePollingTask distributionEnginePollingTask = new DistributionEnginePollingTask(distributionEngineConfiguration, envName, componentUtils, distributionEngineClusterHealth);
137 logger.debug("Init task for environment {}", envName);
139 AtomicBoolean status = new AtomicBoolean(false);
140 envNamePerStatus.put(envName, status);
141 DistributionEngineInitTask distributionEngineInitTask = new DistributionEngineInitTask(0l, distributionEngineConfiguration, envName, status, componentUtils, distributionEnginePollingTask);
142 distributionEngineInitTask.startTask();
143 envNamePerInitTask.put(envName, distributionEngineInitTask);
144 envNamePerPollingTask.put(envName, distributionEnginePollingTask);
147 logger.debug("Init UEB health check");
148 distributionEngineClusterHealth.startHealthCheckTask(envNamePerStatus);
150 logger.trace("Exit init method of DistributionEngine");
155 public void shutdown() {
156 logger.info("distribution engine shutdown - start");
157 if (envNamePerInitTask != null) {
158 for (DistributionEngineInitTask task : envNamePerInitTask.values()) {
162 if (envNamePerPollingTask != null) {
163 for (DistributionEnginePollingTask task : envNamePerPollingTask.values()) {
171 * validate mandatory configuration parameters received
173 * @param deConfiguration
176 protected boolean validateConfiguration(DistributionEngineConfiguration deConfiguration) {
178 String methodName = new Object() {
179 }.getClass().getEnclosingMethod().getName();
181 boolean result = true;
182 result = isValidServers(deConfiguration.getUebServers(), methodName, "uebServers") && result;
183 result = isValidParam(deConfiguration.getEnvironments(), methodName, "environments") && result;
184 result = isValidParam(deConfiguration.getUebPublicKey(), methodName, "uebPublicKey") && result;
185 result = isValidParam(deConfiguration.getUebSecretKey(), methodName, "uebSecretKey") && result;
186 result = isValidParam(deConfiguration.getDistributionNotifTopicName(), methodName, "distributionNotifTopicName") && result;
187 result = isValidParam(deConfiguration.getDistributionStatusTopicName(), methodName, "distributionStatusTopicName") && result;
188 result = isValidObject(deConfiguration.getCreateTopic(), methodName, "createTopic") && result;
189 result = isValidObject(deConfiguration.getDistributionStatusTopic(), methodName, "distributionStatusTopic") && result;
190 result = isValidObject(deConfiguration.getInitMaxIntervalSec(), methodName, "initMaxIntervalSec") && result;
191 result = isValidObject(deConfiguration.getInitRetryIntervalSec(), methodName, "initRetryIntervalSec") && result;
192 result = isValidParam(deConfiguration.getDistributionStatusTopic().getConsumerId(), methodName, "consumerId") && result;
193 result = isValidParam(deConfiguration.getDistributionStatusTopic().getConsumerGroup(), methodName, "consumerGroup") && result;
194 result = isValidObject(deConfiguration.getDistributionStatusTopic().getFetchTimeSec(), methodName, "fetchTimeSec") && result;
195 result = isValidObject(deConfiguration.getDistributionStatusTopic().getPollingIntervalSec(), methodName, "pollingIntervalSec") && result;
200 private boolean isValidServers(List<String> uebServers, String methodName, String paramName) {
202 if (uebServers == null || uebServers.size() == 0) {
203 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeMissingConfigurationError, methodName, paramName);
204 BeEcompErrorManager.getInstance().logBeMissingConfigurationError(methodName, paramName);
208 if (uebServers.size() < 2) {
209 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeConfigurationInvalidListSizeError, methodName, paramName, "2");
210 BeEcompErrorManager.getInstance().logBeConfigurationInvalidListSizeError(methodName, paramName, 2);
214 for (String serverFqdn : uebServers) {
215 if (false == isValidFqdn(serverFqdn)) {
216 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidConfigurationError, methodName, paramName, serverFqdn);
217 BeEcompErrorManager.getInstance().logBeInvalidConfigurationError(methodName, paramName, serverFqdn);
225 private boolean isValidFqdn(String serverFqdn) {
228 Matcher matcher = FQDN_PATTERN.matcher(serverFqdn);
229 return matcher.matches();
231 } catch (Exception e) {
232 logger.debug("Failed to match value of address {}", serverFqdn, e);
238 private boolean isEmptyParam(String param) {
240 if (param == null || true == param.isEmpty()) {
247 private boolean isValidParam(String paramValue, String methodName, String paramName) {
249 if (isEmptyParam(paramValue)) {
250 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeMissingConfigurationError, methodName, paramName);
251 BeEcompErrorManager.getInstance().logBeMissingConfigurationError(methodName, paramName);
258 private boolean isValidParam(List<String> paramValue, String methodName, String paramName) {
260 if (isEmptyList(paramValue)) {
261 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeMissingConfigurationError, methodName, paramName);
262 BeEcompErrorManager.getInstance().logBeMissingConfigurationError(methodName, paramName);
269 private boolean isValidObject(Object paramValue, String methodName, String paramName) {
271 if (paramValue == null) {
272 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeMissingConfigurationError, methodName, paramName);
273 BeEcompErrorManager.getInstance().logBeMissingConfigurationError(methodName, paramName);
280 private boolean isEmptyList(List<String> list) {
281 if (list == null || true == list.isEmpty()) {
287 private String getEnvironmentErrorDescription(StorageOperationStatus status) {
290 case DISTR_ENVIRONMENT_NOT_AVAILABLE:
291 return "environment is unavailable";
292 case DISTR_ENVIRONMENT_NOT_FOUND:
293 return "environment is not configured in our system";
294 case DISTR_ENVIRONMENT_SENT_IS_INVALID:
295 return "environment name is invalid";
303 public StorageOperationStatus isEnvironmentAvailable(String envName) {
305 if (envName == null || true == envName.isEmpty()) {
307 return StorageOperationStatus.DISTR_ENVIRONMENT_SENT_IS_INVALID;
310 AtomicBoolean status = envNamePerStatus.get(envName);
311 if (status == null) {
312 return StorageOperationStatus.DISTR_ENVIRONMENT_NOT_FOUND;
315 if (false == status.get()) {
316 return StorageOperationStatus.DISTR_ENVIRONMENT_NOT_AVAILABLE;
318 return StorageOperationStatus.OK;
321 public StorageOperationStatus isEnvironmentAvailable() {
323 String envName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
325 return isEnvironmentAvailable(envName);
329 public void disableEnvironment(String envName) {
330 // TODO disable tasks
331 AtomicBoolean status = envNamePerStatus.get(envName);
336 public StorageOperationStatus notifyService(String distributionId, Service service, INotificationData notificationData, String envName, String userId, String modifierName) {
338 logger.debug("Received notify service request. distributionId = {}, serviceUuid = {} serviceUid = {}, envName = {}, userId = {}, modifierName {}", distributionId, service.getUUID(), service.getUniqueId(), envName, userId, modifierName);
340 DistributionEngineConfiguration deConfiguration = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration();
342 String distributionNotifTopicName = deConfiguration.getDistributionNotifTopicName();
343 String topicName = DistributionEngineInitTask.buildTopicName(distributionNotifTopicName, envName);
345 StorageOperationStatus sendNotification = distributionNotificationSender.sendNotification(topicName, distributionId, deConfiguration, envName, notificationData, service, userId, modifierName);
347 logger.debug("Finish notifyService. status is {}", sendNotification);
349 return sendNotification;
353 public Either<INotificationData, StorageOperationStatus> isReadyForDistribution(Service service, String distributionId, String envName) {
354 StorageOperationStatus status = isEnvironmentAvailable(envName);
355 if (status != StorageOperationStatus.OK) {
356 String envErrorDec = getEnvironmentErrorDescription(status);
357 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDistributionEngineSystemError, DistributionNotificationSender.DISTRIBUTION_NOTIFICATION_SENDING,
358 "Environment name " + envName + " is not available. Reason : " + envErrorDec);
359 BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(DistributionNotificationSender.DISTRIBUTION_NOTIFICATION_SENDING, "Environment name " + envName + " is not available. Reason : " + envErrorDec);
360 return Either.right(status);
363 Either<Boolean, StorageOperationStatus> isServiceContainsDeploymentArtifactsStatus = serviceDistributionArtifactsBuilder.isServiceContainsDeploymentArtifacts(service);
364 if (isServiceContainsDeploymentArtifactsStatus.isRight()) {
365 StorageOperationStatus operationStatus = isServiceContainsDeploymentArtifactsStatus.right().value();
366 return Either.right(operationStatus);
368 Boolean isDeploymentArtifactExists = isServiceContainsDeploymentArtifactsStatus.left().value();
369 if (isDeploymentArtifactExists == null || isDeploymentArtifactExists.booleanValue() == false) {
370 return Either.right(StorageOperationStatus.DISTR_ARTIFACT_NOT_FOUND);
374 INotificationData value = serviceDistributionArtifactsBuilder.buildResourceInstanceForDistribution(service, distributionId);
375 value = serviceDistributionArtifactsBuilder.buildServiceForDistribution(value, service);
377 return Either.left(value);