/* * RHQ Management Platform * Copyright (C) 2005-2008 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.enterprise.server.operation; import java.util.Date; import java.util.List; import org.apache.commons.logging.LogFactory; import org.quartz.Job; import org.quartz.JobDetail; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.criteria.ResourceOperationHistoryCriteria; import org.rhq.core.domain.operation.GroupOperationHistory; import org.rhq.core.domain.operation.JobId; import org.rhq.core.domain.operation.OperationDefinition; import org.rhq.core.domain.operation.ResourceOperationHistory; import org.rhq.core.domain.operation.ScheduleJobId; import org.rhq.core.domain.operation.bean.ResourceOperationSchedule; import org.rhq.enterprise.server.auth.SubjectManagerLocal; import org.rhq.enterprise.server.util.LookupUtil; public abstract class OperationJob implements Job { public static final String DATAMAP_STRING_OPERATION_NAME = "operationName"; public static final String DATAMAP_STRING_OPERATION_DISPLAY_NAME = "operationDisplayName"; public static final String DATAMAP_INT_PARAMETERS_ID = "parametersId"; // the configuration ID public static final String DATAMAP_INT_SUBJECT_ID = "subjectId"; // id of the associated OperationScheduleEntity - may be null for jobs created prior to upgrading to RHQ 4.0 public static final String DATAMAP_INT_ENTITY_ID = "entityId"; /** * For security purposes, we need to provide a subject with a valid login session. This creates such a subject by * logging in as the given user and returning the subject with a valid session. A new session is created * each time this is called unless <code>reattach</code> is <code>true</code>, in which case if a session * already exists, it will be refreshed - only if a session doesn't exist will a new one be created. * * @param user the user whose needs a valid session assigned to it - the session ID will be assigned to this object * @param reattach if the user already has a session, reattach to it rather than creating a new session * @return the user with a valid session associated with it * * @throws Exception * @see SubjectManagerLocal#loginUnauthenticated(String) */ protected Subject getUserWithSession(Subject user, boolean reattach) throws Exception { SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager(); Subject subject = null; if (reattach && user.getSessionId() != null) { try { subject = subjectManager.getSubjectBySessionId(user.getSessionId()); } catch (Exception e) { // session either doesn't exist or has timed out - fall thru to create a new session } } if (subject == null) { subject = subjectManager.loginUnauthenticated(user.getName()); user.setSessionId(subject.getSessionId()); // we update the passed in object so the caller can use it as well } return subject; } protected void updateOperationScheduleEntity(JobDetail jobDetail, Date nextFireTime, OperationManagerLocal operationManager) { try { String jobName = jobDetail.getName(); String jobGroup = jobDetail.getGroup(); ScheduleJobId jobId = new ScheduleJobId(jobName, jobGroup); if (nextFireTime == null) { operationManager.deleteOperationScheduleEntity(jobId); } else { operationManager.updateOperationScheduleEntity(jobId, nextFireTime.getTime()); } } catch (Exception e) { // do not abort the execution of the job, just log an error // this schedule entity is just a tracking entity and if it fails to update or delete // its not a fatal error. But this is still bad - it means we'll have a row that either // exists but shouldn't or has an old next fire time (and queries relying on it will not // produce proper results). But again, this should not effect the actual operation invocation. LogFactory.getLog(OperationJob.class).error("Failed to update schedule entity for job: " + jobDetail, e); } } protected ResourceOperationHistory createOperationHistory(String jobName, String jobGroup, ResourceOperationSchedule schedule, GroupOperationHistory groupHistory, OperationManagerLocal operationManager) { // we need the operation definition to fill in the history item OperationDefinition op; op = operationManager.getSupportedResourceOperation(schedule.getSubject(), schedule.getResource().getId(), schedule.getOperationName(), false); // first we need to create an INPROGRESS history item Configuration parameters = schedule.getParameters(); if (parameters != null) { parameters = parameters.deepCopy(false); // we need a copy to avoid constraint violations upon delete } ResourceOperationHistory history; history = new ResourceOperationHistory(jobName, jobGroup, schedule.getSubject().getName(), op, parameters, schedule.getResource(), groupHistory); // persist the results of the initial create ResourceOperationHistory persisted; persisted = (ResourceOperationHistory) operationManager.updateOperationHistory(schedule.getSubject(), history); history.setId(persisted.getId()); // we need this - this enables the server to successfully update the group history later return persisted; } /** * @return This returns all optional data and should be suitable for modification and subsequent update. */ protected ResourceOperationHistory findOperationHistory(String name, String group, OperationManagerLocal operationManager, ResourceOperationSchedule schedule) { JobId jobId = new JobId(name, group); ResourceOperationHistoryCriteria criteria = new ResourceOperationHistoryCriteria(); criteria.addFilterJobId(jobId); criteria.fetchOperationDefinition(true); criteria.fetchParameters(true); criteria.fetchResults(true); ResourceOperationHistory history; List<ResourceOperationHistory> list = operationManager.findResourceOperationHistoriesByCriteria( schedule.getSubject(), criteria); if (list == null || list.isEmpty()) { return null; } history = list.get(0); return history; } }