package alien4cloud.deployment.matching.services.location; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.annotation.Resource; import javax.inject.Inject; import org.alien4cloud.tosca.catalog.index.IToscaTypeSearchService; import org.alien4cloud.tosca.model.templates.NodeTemplate; import org.alien4cloud.tosca.model.templates.Topology; import org.alien4cloud.tosca.model.types.AbstractToscaType; import org.springframework.stereotype.Component; import com.google.common.collect.Maps; import alien4cloud.model.deployment.matching.ILocationMatch; import alien4cloud.model.orchestrators.ArtifactSupport; import alien4cloud.orchestrators.plugin.IOrchestratorPluginFactory; import alien4cloud.orchestrators.services.OrchestratorService; import lombok.Getter; @Component public class LocationMatchNodeFilter extends AbstractLocationMatchFilterWithElector { @Resource private IToscaTypeSearchService toscaTypeSearchService; @Resource private OrchestratorService orchestratorService; @Inject private LocationMatchNodesArtifactsElector artifactsElector; @Override public void filter(List<ILocationMatch> toFilter, Topology topology) { // create a context to keep requested tosca elements. NodeMatchContext nodeMatchContext = new NodeMatchContext(); nodeMatchContext.topology = topology; for (Entry<String, NodeTemplate> entry : topology.getNodeTemplates().entrySet()) { nodeMatchContext.template = entry.getValue(); for (Iterator<ILocationMatch> it = toFilter.iterator(); it.hasNext();) { nodeMatchContext.locationMatch = it.next(); if (!artifactsElector.isEligible(nodeMatchContext)) { it.remove(); } } } } /** * Context to match a node against a location. */ @Getter public class NodeMatchContext { private Map<String, Map<String, AbstractToscaType>> toscaTypesCache = Maps.newHashMap(); private Topology topology; private NodeTemplate template; private ILocationMatch locationMatch; /** * Get an element from the local-cache or from ES. * * @param elementClass The class of the element to look for. * @param elementId The id of the element to look for. * @param <T> The type of element. * @return The requested element. */ public <T extends AbstractToscaType> T getElement(Class<T> elementClass, String elementId) { String elementType = elementClass.getSimpleName(); Map<String, AbstractToscaType> typeElements = toscaTypesCache.get(elementType); if (typeElements == null) { typeElements = new HashMap<>(); toscaTypesCache.put(elementType, typeElements); } else { // find in local-cache T element = (T) typeElements.get(elementId); if (element != null) { return element; } } T element = toscaTypeSearchService.getRequiredElementInDependencies(elementClass, elementId, topology.getDependencies()); typeElements.put(elementId, element); return element; } public ArtifactSupport getArtifactSupport() { IOrchestratorPluginFactory orchestratorFactory = orchestratorService.getPluginFactory(locationMatch.getOrchestrator()); return orchestratorFactory.getArtifactSupport(); } } }