package alien4cloud.deployment.matching.services.location;
import alien4cloud.model.orchestrators.ArtifactSupport;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.alien4cloud.tosca.model.types.AbstractInstantiableToscaType;
import org.alien4cloud.tosca.model.types.ArtifactType;
import org.alien4cloud.tosca.model.definitions.Interface;
import org.alien4cloud.tosca.model.definitions.Operation;
import org.alien4cloud.tosca.model.templates.AbstractTemplate;
import org.alien4cloud.tosca.model.templates.NodeTemplate;
import org.alien4cloud.tosca.model.templates.RelationshipTemplate;
import alien4cloud.tosca.ToscaUtils;
import org.springframework.stereotype.Component;
/**
* LocationMatch Elector based on supported artifacts. Checks if the artifacts of a given {@link NodeTemplate} are supported by the location's orchestrator.
*
*/
@Component
public class LocationMatchNodesArtifactsElector {
/**
* Perform matching of the given match context to ensure that a given node template's implementation artifact types are indeed suported by the ones of the
* context location match.
*
* @param matchContext
* @return
*/
public boolean isEligible(LocationMatchNodeFilter.NodeMatchContext matchContext) {
boolean isEligible = true;
if (matchContext.getTemplate() == null) {
return isEligible;
}
// first check the node interfaces operations artifacts are supported
isEligible = isEligible(matchContext.getTemplate(), matchContext);
if (isEligible) {
// then check relationships interfaces
isEligible = areRelationshipsArtifactSupported(matchContext);
}
return isEligible;
}
private boolean isEligible(AbstractTemplate template, LocationMatchNodeFilter.NodeMatchContext matchContext) {
if (template == null) {
return true;
}
ArtifactSupport artifactSupport = matchContext.getArtifactSupport();
// if no supported artifact defined, then return true
if (artifactSupport == null || ArrayUtils.isEmpty(artifactSupport.getTypes())) {
return true;
}
String[] supportedArtifacts = artifactSupport.getTypes();
AbstractInstantiableToscaType indexedArtifactToscaElement = matchContext.getElement(AbstractInstantiableToscaType.class, template.getType());
if (MapUtils.isNotEmpty(indexedArtifactToscaElement.getInterfaces())) {
for (Interface interfaz : indexedArtifactToscaElement.getInterfaces().values()) {
for (Operation operation : interfaz.getOperations().values()) {
if (operation.getImplementationArtifact() != null) {
String artifactTypeString = operation.getImplementationArtifact().getArtifactType();
ArtifactType artifactType = matchContext.getElement(ArtifactType.class, artifactTypeString);
// stop the checking once one artifactType is not supported
if (!isFromOneOfTypes(supportedArtifacts, artifactType)) {
return false;
}
}
}
}
}
return true;
}
private boolean isFromOneOfTypes(String[] supportedArtifacts, ArtifactType artifactType) {
for (String supportedArtifact : supportedArtifacts) {
if (ToscaUtils.isFromType(supportedArtifact, artifactType)) {
return true;
}
}
return false;
}
private boolean areRelationshipsArtifactSupported(LocationMatchNodeFilter.NodeMatchContext matchContext) {
if (MapUtils.isNotEmpty(matchContext.getTemplate().getRelationships())) {
for (RelationshipTemplate relTemplate : matchContext.getTemplate().getRelationships().values()) {
if (!isEligible(relTemplate, matchContext)) {
return false;
}
}
}
return true;
}
}