/* * 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 scalabilityTests.framework; import javax.security.auth.login.LoginException; import org.objectweb.proactive.core.ProActiveException; import org.objectweb.proactive.extensions.annotation.ActiveObject; import org.ow2.proactive.authentication.crypto.Credentials; import org.ow2.proactive.scheduler.common.Scheduler; import org.ow2.proactive.scheduler.common.SchedulerAuthenticationInterface; import org.ow2.proactive.scheduler.common.SchedulerConnection; import org.ow2.proactive.scheduler.common.SchedulerEvent; import org.ow2.proactive.scheduler.common.SchedulerEventListener; import org.ow2.proactive.scheduler.common.SchedulerState; import org.ow2.proactive.scheduler.common.exception.SchedulerException; import org.ow2.proactive.scheduler.common.job.JobId; import org.ow2.proactive.scheduler.common.job.JobResult; import scalabilityTests.framework.listeners.SchedulerListenerExposer; /** * * Active Actor which simulates * the behaviour of a Scheduler User * * OBS the parameter is a UserSchedulerInterface; * this would be the defaultParameter's type, and * will only be made available after connectToScheduler() * method was called * * Also, manually setting the parameter of the Action is disabled; * This is because an UserSchedulerInterface has significance only * on the host which performed the login to the Scheduler * * @author fabratu * */ @ActiveObject public abstract class AbstractSchedulerUser<V> extends ActiveActor<Scheduler, V> { // Scheduler info private final String schedulerURL; private final Credentials userCreds; // Scheduler interaction internal state protected Scheduler scheduler = null; // Scheduler listener protected SchedulerListenerExposer slExposer = null; public AbstractSchedulerUser() { this.schedulerURL = null; this.userCreds = null; } public AbstractSchedulerUser(String schedulerURL, Credentials userCreds) { super(); this.schedulerURL = schedulerURL; this.userCreds = userCreds; } public AbstractSchedulerUser(Action<Scheduler, V> defaultAction, String schedulerURL, Credentials userCreds) { super(defaultAction); this.schedulerURL = schedulerURL; this.userCreds = userCreds; } @Override public void doAction() { if (this.scheduler == null) throw new IllegalStateException("The user is not connected to the Scheduler yet. " + "Consider calling the connectToScheduler() method first"); super.doAction(); } @Override public void doAction(Action<Scheduler, V> action) { if (this.scheduler == null) throw new IllegalStateException("The user is not connected to the Scheduler yet. " + "Consider calling the connectToScheduler() method first"); super.doAction(action); } public void connectToScheduler() throws SchedulerException, LoginException { SchedulerAuthenticationInterface auth = SchedulerConnection.join(this.schedulerURL); this.scheduler = auth.login(this.userCreds); this.defaultParameter = this.scheduler; } public void registerListener(boolean getInitialState, boolean myEventsOnly, String listenerClazzName) throws SchedulerException, ProActiveException { try { if (this.scheduler == null) throw new IllegalStateException("The user is not connected to the Scheduler yet. " + "Consider calling the connectToScheduler() method first"); SchedulerEventListener schedulerListener = createEventListener(listenerClazzName); logger.trace("Trying to expose the listener as a remote object"); slExposer = new SchedulerListenerExposer(schedulerListener); SchedulerEventListener schedulerListenerRemoteRef = slExposer.createRemoteReference(); logger.trace("Trying to register the listener to the Scheduler"); // for the moment, listens only to the Jobs-related events SchedulerState initialState = scheduler.addEventListener(schedulerListenerRemoteRef, myEventsOnly, getInitialState, // job-related events SchedulerEvent.JOB_SUBMITTED, SchedulerEvent.JOB_PENDING_TO_RUNNING, SchedulerEvent.JOB_PENDING_TO_FINISHED, SchedulerEvent.JOB_RUNNING_TO_FINISHED, SchedulerEvent.JOB_PAUSED, SchedulerEvent.JOB_RESUMED, SchedulerEvent.JOB_RESTARTED_FROM_ERROR, SchedulerEvent.JOB_CHANGE_PRIORITY, // task-related events SchedulerEvent.TASK_PENDING_TO_RUNNING, SchedulerEvent.TASK_RUNNING_TO_FINISHED, SchedulerEvent.TASK_WAITING_FOR_RESTART, SchedulerEvent.USERS_UPDATE, // Scheduler state related events SchedulerEvent.FROZEN, SchedulerEvent.RESUMED, SchedulerEvent.SHUTDOWN, SchedulerEvent.SHUTTING_DOWN, SchedulerEvent.STARTED, SchedulerEvent.STOPPED, SchedulerEvent.KILLED); if (getInitialState) { logger.info("Initial state of the scheduler is: " + initialState); } } catch (ClassNotFoundException e) { throw new IllegalArgumentException("Class " + listenerClazzName + " is not available on this SchedulerUser's side", e); } catch (InstantiationException e) { throw new IllegalArgumentException("Cannot instantiate listener of type " + listenerClazzName, e); } catch (IllegalAccessException e) { throw new IllegalArgumentException("Cannot instantiate listener of type " + listenerClazzName, e); } } protected abstract SchedulerEventListener createEventListener(String listenerClazzName) throws ClassNotFoundException, InstantiationException, IllegalAccessException; /** * This method just calls the Scheduler's getJobResult * This is needed here, as the UserSchedulerInterface only accepts * requests from the Active Objects that have previously called * one of the authentication methods logAs* */ public JobResult getJobResult(JobId jobId) throws SchedulerException { return this.scheduler.getJobResult(jobId); } public void disconnect() throws SchedulerException { this.scheduler.disconnect(); } @Override public void cleanup() { try { // first, cleanly destroy the listener remote object if (this.slExposer != null) this.slExposer.destroyRemoteReference(); disconnect(); } catch (SchedulerException e) { // we don't care logger.debug("Cannot disconnect() this user from the Scheduler, reason", e); } catch (ProActiveException e) { logger.debug("Cannot unregister the scheduler event listener from the Scheduler, reason:", e); } super.cleanup(); } }