/* * Copyright (c) 2010 Ecole des Mines de Nantes. * * This file is part of Entropy. * * Entropy 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. * * Entropy 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 Entropy. If not, see <http://www.gnu.org/licenses/>. */ package entropy.vjob; import entropy.configuration.Configuration; import entropy.configuration.DefaultManagedElementSet; import entropy.configuration.ManagedElementSet; import entropy.configuration.Node; import entropy.configuration.VirtualMachine; import entropy.plan.choco.ReconfigurationProblem; import entropy.plan.choco.actionModel.slice.Slice; /** * A constraint to assign a set of virtual machines to a single node. * * @author Fabien Hermenier */ public class Gather implements PlacementConstraint { /** * The involved VMs. */ private VJobSet<VirtualMachine> vms; /** * Make a new constraint. * * @param vms A non-empty set of virtual machines */ public Gather(VJobSet<VirtualMachine> vms) { this.vms = vms; } /** * Get the virtual machines involved in the constraint. * * @return a set of VMs. Should not be empty */ @Override public ExplodedSet<VirtualMachine> getAllVirtualMachines() { return this.vms.flatten(); } /** * Get the set of virtual machines involved in the constraint. * * @return a set of VMs, should not be empty */ public VJobSet<VirtualMachine> getVirtualMachines() { return this.vms; } @Override public ExplodedSet<Node> getNodes() { return new ExplodedSet<Node>(); } @Override public String toString() { StringBuilder buffer = new StringBuilder(); buffer.append("gather(").append(vms.pretty()).append(")"); return buffer.toString(); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } Gather that = (Gather) o; return getAllVirtualMachines().equals(that.getAllVirtualMachines()); } @Override public int hashCode() { return getAllVirtualMachines().hashCode(); } @Override public void inject(ReconfigurationProblem core) { //Get only the future running VMs ManagedElementSet<VirtualMachine> runnings = new DefaultManagedElementSet<VirtualMachine>(getAllVirtualMachines()); runnings.retainAll(core.getFutureRunnings()); VJob.logger.debug(this + " only consider " + runnings); for (int i = 0; i < runnings.size(); i++) { for (int j = 0; j < i; j++) { Slice t1 = core.getAssociatedAction(runnings.get(i)).getDemandingSlice(); Slice t2 = core.getAssociatedAction(runnings.get(j)).getDemandingSlice(); core.post(core.eq(t1.hoster(), t2.hoster())); } } } /** * Check that the constraint is satified in a configuration. * * @param cfg the configuration to check * @return true if the running VMs are hosted on the same node */ @Override public boolean isSatisfied(Configuration cfg) { if (getAllVirtualMachines().size() == 0) { VJob.logger.debug("No virtual machines was specified"); return true; } Node usedNode = null; for (VirtualMachine vm : getAllVirtualMachines()) { if (cfg.isRunning(vm)) { Node n = cfg.getLocation(vm); if (usedNode == null) { usedNode = n; } else if (!n.equals(usedNode)) { return false; } } } return true; } /** * Get VMs that seems to be misplaced. * If all the VMs are not running on the same node, all the VMs * are considered as misplaced as the node that they were supposed * to be hosted on is not guarantee to be known at 100%. */ @Override public ExplodedSet<VirtualMachine> getMisPlaced(Configuration cfg) { if (!isSatisfied(cfg)) { return getAllVirtualMachines(); } return new ExplodedSet<VirtualMachine>(); } }