/* * Copyright (C) 2008 Universidade Federal de Campina Grande * * This file is part of OurGrid. * * OurGrid 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. * * 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 Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ package org.ourgrid.worker.business.controller; import static org.ourgrid.worker.WorkerConstants.ENV_PLAYPEN; import static org.ourgrid.worker.WorkerConstants.ENV_STORAGE; import java.util.List; import java.util.Map; import java.util.concurrent.Future; import org.ourgrid.common.executor.ExecutorHandle; import org.ourgrid.common.interfaces.to.GridProcessErrorTypes; import org.ourgrid.common.internal.IResponseTO; import org.ourgrid.common.internal.response.LoggerResponseTO; import org.ourgrid.reqtrace.Req; import org.ourgrid.worker.WorkerConstants; import org.ourgrid.worker.business.dao.EnvironmentDAO; import org.ourgrid.worker.business.dao.ExecutionDAO; import org.ourgrid.worker.business.dao.WorkAccountingDAO; import org.ourgrid.worker.business.dao.WorkerDAOFactory; import org.ourgrid.worker.business.dao.WorkerStatusDAO; import org.ourgrid.worker.business.messages.ExecutionControllerMessages; import org.ourgrid.worker.communication.dao.FutureDAO; import org.ourgrid.worker.response.CancelBeginAllocationActionResponseTO; import org.ourgrid.worker.response.CancelExecutionActionResponseTO; import org.ourgrid.worker.response.ErrorOcurredMessageHandleResponseTO; import org.ourgrid.worker.response.ExecutorKillCommandResponseTO; import org.ourgrid.worker.response.ExecutorKillPreparingAllocationResponseTO; import org.ourgrid.worker.response.ExecutorShutdownResponseTO; import org.ourgrid.worker.response.SubmitExecutionActionResponseTO; import org.ourgrid.worker.response.SubmitPrepareAllocationActionResponseTO; public class ExecutionController { private static ExecutionController instance = null; @Req("REQ084") public static synchronized ExecutionController getInstance() { if (instance == null) { instance = new ExecutionController(); } return instance; } public void beginAllocation(List<IResponseTO> responses) { responses.add(new LoggerResponseTO(ExecutionControllerMessages. getPrepareAllocationActionStartedMessage(), LoggerResponseTO.DEBUG)); WorkerStatusDAO workerStatusDAO = WorkerDAOFactory.getInstance().getWorkerStatusDAO(); workerStatusDAO.setPreparingAllocationState(true); submitBeginAllocationAction(responses); } private void submitBeginAllocationAction(List<IResponseTO> responses) { SubmitPrepareAllocationActionResponseTO to = new SubmitPrepareAllocationActionResponseTO(); responses.add(to); } @Req("REQ084") public void scheduleCommand(long requestID, Map<String, String> envVars, String command, String senderPublicKey, List<IResponseTO> responses, boolean isExecutionClientDeployed) { ExecutionDAO executionDAO = WorkerDAOFactory.getInstance().getExecutionDAO(); WorkerStatusDAO workerStatusDAO = WorkerDAOFactory.getInstance().getWorkerStatusDAO(); EnvironmentDAO environmentDAO = WorkerDAOFactory.getInstance().getEnvironmentDAO(); WorkAccountingDAO accountingDAO = WorkerDAOFactory.getInstance().getWorkAccountingDAO(); envVars.put(WorkerConstants.ENV_PLAYPEN, environmentDAO.getPlaypenDir()); envVars.put(WorkerConstants.ENV_STORAGE, environmentDAO.getStorageDir()); if (executionDAO.getCurrentHandle() == null && !executionDAO.isExecutionFinished()) { if (workerStatusDAO.isAllocatedForRemotePeer()) { accountingDAO.getCurrentWorkAccounting().startCPUTiming(); } submitExecutionAction(envVars, command, responses); responses.add(new LoggerResponseTO(ExecutionControllerMessages.getScheduleExecutionMessage(command, requestID, envVars, senderPublicKey), LoggerResponseTO.INFO)); } else { responses.add(new LoggerResponseTO(ExecutionControllerMessages.getConcurrentExecutionMethod(requestID, command, envVars), LoggerResponseTO.ERROR)); String consumerAddress = WorkerDAOFactory.getInstance().getWorkerStatusDAO().getConsumerAddress(); ErrorOcurredMessageHandleResponseTO to = new ErrorOcurredMessageHandleResponseTO( new GridProcessError(GridProcessErrorTypes.CONCURRENT_RUNNING), consumerAddress); responses.add(to); } } public String solvePlaypenAndStorage(String command, List<IResponseTO> responses) { if (command != null) { String newCommand = command; String playpenDir = getPlaypenDir(responses); if (playpenDir != null) { newCommand = newCommand.replace( "$" + ENV_PLAYPEN, playpenDir); } String storageDir = getStorageDir(responses); if (storageDir != null) { newCommand = newCommand.replace( "$" + ENV_STORAGE, storageDir); } return newCommand; } return command; } public void cancelActiveExecution(List<IResponseTO> responses, boolean interruptWorking, boolean cancelPreparingAllocation) { if (interruptWorking) { ExecutionDAO executionDAO = WorkerDAOFactory.getInstance().getExecutionDAO(); ExecutorHandle currentHandle = executionDAO.getCurrentHandle(); if (currentHandle != null) { responses.add(new CancelExecutionActionResponseTO()); executionDAO.setCurrentHandle(null); ExecutorKillCommandResponseTO executorKillCommandResponseTO = new ExecutorKillCommandResponseTO(); executorKillCommandResponseTO.setHandle(currentHandle); responses.add(executorKillCommandResponseTO); } if (cancelPreparingAllocation) { if (hasActivePreparingAllocation()) { cancelPreparingAllocationExecution(responses); executionDAO.setExecutingKillPreparingAllocation(true); ExecutorKillPreparingAllocationResponseTO executorKillPreparingAllocationResponseTO = new ExecutorKillPreparingAllocationResponseTO(); responses.add(executorKillPreparingAllocationResponseTO); } else { shutdown(responses); } } } } private boolean hasActivePreparingAllocation() { FutureDAO futureDAO = WorkerDAOFactory.getInstance().getFutureDAO(); Future<?> beginAllocationFuture = futureDAO.getBeginAllocationFuture(); return beginAllocationFuture != null && !beginAllocationFuture.isDone(); } public void executionFinish(boolean success) { ExecutionDAO executionDAO = WorkerDAOFactory.getInstance().getExecutionDAO(); executionDAO.setCurrentHandle(null); executionDAO.setExecutionFinished(success); } public void executionIsRunning(ExecutorHandle handle) { WorkerDAOFactory.getInstance().getExecutionDAO().setCurrentHandle(handle); } @Req("REQ084") private void submitExecutionAction(Map<String, String> envVars, String command, List<IResponseTO> responses) { SubmitExecutionActionResponseTO to = new SubmitExecutionActionResponseTO(); to.setCommand(command); to.setEnvVars(envVars); responses.add(to); } private String getPlaypenDir(List<IResponseTO> responses) { return WorkerDAOFactory.getInstance().getEnvironmentDAO().getPlaypenDir(); } private String getStorageDir(List<IResponseTO> responses) { return WorkerDAOFactory.getInstance().getEnvironmentDAO().getStorageDir(); } private void cancelPreparingAllocationExecution(List<IResponseTO> responses) { responses.add(new LoggerResponseTO(ExecutionControllerMessages. getPrepareAllocationActionCancelledMessage(), LoggerResponseTO.DEBUG)); responses.add(new CancelBeginAllocationActionResponseTO()); } /** * Adds to the responses list the ExecutorShutdownResponseTO, which will shutdown * the worker executor and the virtual machine * @param responses */ public void shutdown(List<IResponseTO> responses) { responses.add(new LoggerResponseTO(ExecutionControllerMessages.getShutdowningExecutorMessage(), LoggerResponseTO.DEBUG)); ExecutorShutdownResponseTO executorShutdownResponseTO = new ExecutorShutdownResponseTO(); responses.add(executorShutdownResponseTO); } }