/** * This file is part of CloudML [ http://cloudml.org ] * * Copyright (C) 2012 - SINTEF ICT * Contact: Franck Chauvel <franck.chauvel@sintef.no> * * Module: root * * CloudML is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * CloudML is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with CloudML. If not, see * <http://www.gnu.org/licenses/>. */ package org.cloudml.indicators; import eu.diversify.trio.core.requirements.Requirement; import java.util.LinkedList; import java.util.List; import org.cloudml.core.*; import static eu.diversify.trio.core.requirements.Factory.nothing; import static eu.diversify.trio.core.requirements.Factory.require; /** * Compute the all the "possible" dependencies of a given component. * * Possible dependencies include, for each required port instance, the * disjunction between all the existing compliant provided ports in the model. */ public class AllPossibleDependencies implements DependencyExtractor { @Override public Requirement from(ComponentInstance<?> component) { requireValidComponent(component); Requirement requirements = nothing(); if (component.isInternal()) { final InternalComponentInstance internalInstance = component.asInternal(); for (RequiredPortInstance eachDependency: internalInstance.getRequiredPorts()) { requirements = requirements.and(anyMatchingProvider(eachDependency)); } requirements = requirements.and(anyMatchingHost(internalInstance)); } return requirements; } private void requireValidComponent(ComponentInstance<?> componentInstance) throws IllegalArgumentException { if (componentInstance == null) { throw new IllegalArgumentException("Unable to extract requirement from 'null'"); } } /** * Compute the disjunction of all possible host that matches the given * component * * @param component the internal component whose candidate hosts are needed. * * @return a disjunction (OR) between all candidates hosts */ private Requirement anyMatchingHost(final InternalComponentInstance component) { assert component != null: "Unable to find hosts for 'null'"; Requirement disjunction = nothing().not(); for (ComponentInstance<?> eachHost: findAllCandidateHosts(component)) { disjunction = disjunction.or(require(eachHost.getName())); } assert disjunction != null: "Should never return null"; return disjunction; } /** * Build a disjunction between all the providers that can meet the * requirements of the given requiredPort * * @param dependency the dependency that must satisfied * @return a disjunction (i.e., logical or) between all the service * providers that satisfies the given dependencies. */ private Requirement anyMatchingProvider(RequiredPortInstance dependency) { assert dependency != null: "Unable to find service providers for 'null'"; Requirement disjunction = nothing().not(); for (ComponentInstance<?> eachProvider: findAllCandidateProviders(dependency)) { disjunction = disjunction.or(require(eachProvider.getName())); } assert disjunction != null: "Should never return null"; return disjunction; } /** * Find all the component that can be used as service providers for the * given required port * * @param requiredPort the port for which a provider is needed * @return the list of candidates service providers */ private List<ComponentInstance<?>> findAllCandidateProviders(RequiredPortInstance requiredPort) { assert requiredPort != null: "Unable to find service providers for 'null'"; final List<ComponentInstance<?>> candidates = new LinkedList<ComponentInstance<?>>(); final Deployment deployment = requiredPort.getDeployment(); for (Relationship eachRelationship: deployment.getRelationships()) { if (eachRelationship.getRequiredEnd().equals(requiredPort.getType())) { final ProvidedPort serverType = eachRelationship.getProvidedEnd(); for (ComponentInstance<?> eachComponent: deployment.getComponentInstances()) { if (eachComponent.getType().canProvide(serverType)) { candidates.add(eachComponent); } } } } return candidates; } /** * Find all the components that can possibly host the given internal * component instance * * @param component the component that needs a host * @return the list of components that can be host */ private List<ComponentInstance<?>> findAllCandidateHosts(InternalComponentInstance component) { assert component != null: "Unable to find host for 'null'"; final List<ComponentInstance<?>> candidates = new LinkedList<ComponentInstance<?>>(); for (ComponentInstance<?> eachComponent: component.getDeployment().getComponentInstances()) { if (eachComponent.canHost(component.getType())) { candidates.add(eachComponent); } } return candidates; } }