/* * ProActive Parallel Suite(TM): * The Open Source library for parallel and distributed * Workflows & Scheduling, Orchestration, Cloud Automation * and Big Data Analysis on Enterprise Grids & Clouds. * * Copyright (c) 2007 - 2017 ActiveEon * Contact: contact@activeeon.com * * This library is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation: version 3 of * the License. * * This program 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * If needed, contact us to obtain a release under GPL Version 2 or 3 * or a different license than the AGPL. */ package org.ow2.proactive.resourcemanager.nodesource.policy; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Locale; import java.util.Timer; import java.util.TimerTask; import org.objectweb.proactive.Body; import org.objectweb.proactive.InitActive; import org.objectweb.proactive.api.PAActiveObject; import org.objectweb.proactive.core.util.wrapper.BooleanWrapper; import org.objectweb.proactive.extensions.annotation.ActiveObject; import org.ow2.proactive.resourcemanager.authentication.Client; import org.ow2.proactive.resourcemanager.exception.RMException; import org.ow2.proactive.resourcemanager.nodesource.common.Configurable; /** * * Allocated nodes for specified time slot: from "acquire time" to "release time" with specified period. * Remove nodes preemptively if "preemptive" parameter is set to true. <br> * If period is zero then acquisition will be performed once. <br> * * NOTE: difference between acquire and release time have to be bigger than time required * to nodes all acquisition. Period have to be enough to release all nodes. * */ @ActiveObject public class TimeSlotPolicy extends NodeSourcePolicy implements InitActive { /** * Timer task acquired all node from infrastructure */ private class AcquireTask extends TimerTask { @Override public void run() { synchronized (timer) { acquireAllNodes(); } } } /** * Timer task released all node from infrastructure */ private class ReleaseTask extends TimerTask { @Override public void run() { synchronized (timer) { // security trick thisStub.removeAllNodes(preemptive); } } } /** Date formatter */ public static transient DateFormat dateFormat = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.FULL, new Locale("en")); /** Timer used for tasks scheduling */ private transient Timer timer = new Timer("TimeSlotPolicy Timer", true); /** * Initial time for nodes acquisition */ @Configurable private String acquireTime = dateFormat.format(getDate(System.currentTimeMillis())); /** * Initial time for nodes releasing */ @Configurable private String releaseTime = dateFormat.format(getDate(System.currentTimeMillis() + 1 * 60 * 60 * 1000 /* 1 hour */)); /** * Period in milliseconds between nodes acquisition/releasing iterations */ @Configurable(description = "ms (1 day by default)") private Long period = new Long(24 * 60 * 60 * 1000); /** * The way of nodes removing */ @Configurable private boolean preemptive = true; /** * Active object stub */ private TimeSlotPolicy thisStub; /** * Proactive default constructor */ public TimeSlotPolicy() { } /** * Configure a policy with given parameters. * @param policyParameters parameters defined by user */ @Override public BooleanWrapper configure(Object... policyParameters) { super.configure(policyParameters); try { int index = 2; acquireTime = policyParameters[index++].toString(); releaseTime = policyParameters[index++].toString(); // validation of date parameters dateFormat.parse(acquireTime); dateFormat.parse(releaseTime); if (policyParameters[index++].toString().length() > 0) { period = Long.parseLong(policyParameters[index - 1].toString()); if (period < 0) { throw new RMException("Period cannot be less than zero"); } } else { period = new Long(0); } preemptive = Boolean.parseBoolean(policyParameters[index++].toString()); } catch (Throwable t) { throw new IllegalArgumentException(t); } return new BooleanWrapper(true); } /** * Initializes stub to this active object */ public void initActivity(Body body) { thisStub = (TimeSlotPolicy) PAActiveObject.getStubOnThis(); } /** * Activates the policy. Schedules acquire/release tasks with specified period. */ @Override public BooleanWrapper activate() { try { if (period > 0) { info("Scheduling periodic nodes acquision"); timer.scheduleAtFixedRate(new AcquireTask(), dateFormat.parse(acquireTime), period); timer.scheduleAtFixedRate(new ReleaseTask(), dateFormat.parse(releaseTime), period); } else { info("Scheduling non periodic nodes acquision"); timer.schedule(new AcquireTask(), dateFormat.parse(acquireTime)); timer.schedule(new ReleaseTask(), dateFormat.parse(releaseTime)); } } catch (ParseException e) { return new BooleanWrapper(false); } return new BooleanWrapper(true); } /** * Shutdown the policy and clears the timer. */ @Override public void shutdown(Client initiator) { synchronized (timer) { timer.cancel(); } super.shutdown(initiator); } /** * Converts ms to Date object */ private Date getDate(long millis) { Calendar c = Calendar.getInstance(); c.setTimeInMillis(millis); return c.getTime(); } /** * Policy description for UI * @return policy description */ @Override public String getDescription() { return "Acquires and releases nodes at specified time."; } /** * Policy string representation. */ @Override public String toString() { return super.toString() + " [Acquire Time: " + acquireTime + " Release Time: " + releaseTime + " Period: " + period + " ms]"; } }