package alien4cloud.deployment;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import alien4cloud.exception.NotFoundException;
import org.alien4cloud.tosca.model.definitions.PropertyDefinition;
import alien4cloud.model.deployment.DeploymentTopology;
import alien4cloud.orchestrators.services.OrchestratorDeploymentService;
import alien4cloud.topology.task.PropertiesTask;
import alien4cloud.topology.task.TaskCode;
import alien4cloud.topology.task.TaskLevel;
import alien4cloud.tosca.properties.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException;
import alien4cloud.tosca.properties.constraints.exception.ConstraintViolationException;
import alien4cloud.utils.services.ConstraintPropertyService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
/**
* Perform validation of a topology before deployment.
*/
@Service
@Slf4j
public class OrchestratorPropertiesValidationService {
@Inject
private OrchestratorDeploymentService orchestratorDeploymentService;
@Inject
private ConstraintPropertyService constraintPropertyService;
public PropertiesTask validate(DeploymentTopology deploymentTopology) {
if (StringUtils.isBlank(deploymentTopology.getOrchestratorId())) {
return null;
}
Map<String, PropertyDefinition> deploymentProperties = orchestratorDeploymentService.getDeploymentPropertyDefinitions(deploymentTopology
.getOrchestratorId());
if (MapUtils.isEmpty(deploymentProperties)) {
return null;
}
Map<String, String> properties = deploymentTopology.getProviderDeploymentProperties();
if (properties == null) {
properties = Maps.newHashMap();
}
PropertiesTask task = null;
List<String> required = Lists.newArrayList();
for (Entry<String, PropertyDefinition> entry : deploymentProperties.entrySet()) {
if (entry.getValue().isRequired()) {
String value = properties.get(entry.getKey());
if (StringUtils.isBlank(value)) {
required.add(entry.getKey());
}
}
}
if (CollectionUtils.isNotEmpty(required)) {
task = new PropertiesTask(Maps.<TaskLevel, List<String>> newHashMap());
task.setCode(TaskCode.ORCHESTRATOR_PROPERTY);
task.getProperties().put(TaskLevel.REQUIRED, required);
}
return task;
}
public void checkConstraints(String orchestratorId, Map<String, String> properties) throws ConstraintValueDoNotMatchPropertyTypeException,
ConstraintViolationException {
if (StringUtils.isBlank(orchestratorId) || MapUtils.isEmpty(properties)) {
return;
}
Map<String, PropertyDefinition> deploymentPropertyDefinitions = orchestratorDeploymentService.getDeploymentPropertyDefinitions(orchestratorId);
if (MapUtils.isEmpty(deploymentPropertyDefinitions)) {
throw new NotFoundException("No properties are defined for this orchestrator");
}
for (Entry<String, String> propertyEntry : properties.entrySet()) {
PropertyDefinition propertyDefinition = deploymentPropertyDefinitions.get(propertyEntry.getKey());
if (propertyDefinition == null) {
throw new NotFoundException("property <" + propertyEntry.getKey() + "> is not defined for this orchestrator");
}
if (propertyDefinition.getConstraints() != null) {
constraintPropertyService.checkSimplePropertyConstraint(propertyEntry.getKey(), propertyEntry.getValue(), propertyDefinition);
}
}
}
}