/**
* Copyright (c) 2009--2012 Red Hat, Inc.
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
* implied, including the implied warranties of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
* along with this software; if not, see
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* Red Hat trademarks are not licensed under GPLv2. No permission is
* granted to use or replicate Red Hat trademarks that are incorporated
* in this software or its documentation.
*/
package com.redhat.rhn.manager.ssm;
import com.redhat.rhn.common.db.datasource.DataResult;
import com.redhat.rhn.common.db.datasource.ModeFactory;
import com.redhat.rhn.common.db.datasource.SelectMode;
import com.redhat.rhn.common.db.datasource.WriteMode;
import com.redhat.rhn.common.localization.LocalizationService;
import com.redhat.rhn.domain.user.User;
import com.redhat.rhn.frontend.dto.OperationDetailsDto;
import com.redhat.rhn.manager.BaseManager;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Handles the tracking of SSM asynchronous operations, providing functionality for
* the creation, update, and retrieval of the data.
*
* @version $Revision$
*/
public class SsmOperationManager extends BaseManager {
/**
* Private constructor to enforce static nature of the class.
*/
private SsmOperationManager() {
}
/**
* Returns a list of all operations for the given user, regardless of their status.
*
* @param user operations returned only for this user; cannot be <code>null</code>
* @return list of maps containing the data describing each operation
*/
public static DataResult<OperationDetailsDto> allOperations(User user) {
if (user == null) {
throw new IllegalArgumentException("user cannot be null");
}
SelectMode m = ModeFactory.getMode("ssm_operation_queries", "find_all_operations");
Map<String, Object> params = new HashMap<String, Object>(1);
params.put("user_id", user.getId());
DataResult result = m.execute(params);
return result;
}
/**
* Returns a list of all operations for the given user that are currently executing.
*
* @param user operations returned only for this user; cannot be <code>null</code>
* @return list of maps containing the data describing each matching operation
*/
public static DataResult<OperationDetailsDto> inProgressOperations(User user) {
if (user == null) {
throw new IllegalArgumentException("user cannot be null");
}
SelectMode m =
ModeFactory.getMode("ssm_operation_queries", "find_operations_with_status");
Map<String, Object> params = new HashMap<String, Object>(2);
params.put("user_id", user.getId());
params.put("status", SsmOperationStatus.IN_PROGRESS.getText());
DataResult result = m.execute(params);
return result;
}
/**
* Returns a list of all operations for the given user that have completed.
*
* @param user operations returned only for this user; cannot be <code>null</code>
* @return list of maps containing the data describing each matching operation
*/
public static DataResult<OperationDetailsDto> completedOperations(User user) {
if (user == null) {
throw new IllegalArgumentException("user cannot be null");
}
SelectMode m =
ModeFactory.getMode("ssm_operation_queries", "find_operations_with_status");
Map<String, Object> params = new HashMap<String, Object>(2);
params.put("user_id", user.getId());
params.put("status", SsmOperationStatus.COMPLETED.getText());
DataResult result = m.execute(params);
return result;
}
/**
* Returns the details of the given operation.
*
* @param user verifies that the user isn't trying to load someone else's
* operation; cannot be <code>null</code>
* @param operationId database ID of the operation to load
* @return OperationsDto given an operation id or null.
*/
public static OperationDetailsDto findOperationById(User user, long operationId) {
if (user == null) {
throw new IllegalArgumentException("user cannot be null");
}
SelectMode m = ModeFactory.getMode("ssm_operation_queries", "find_operation_by_id");
Map<String, Object> params = new HashMap<String, Object>(2);
params.put("user_id", user.getId());
params.put("op_id", operationId);
DataResult<OperationDetailsDto> result = m.execute(params);
if (!result.isEmpty()) {
return result.get(0);
}
return null;
}
/**
* Creates a new operation, defaulting the status to "in progress".
* <p/>
* For efficiency, this call assumes the following:
* <ul>
* <li>The set of servers that are taking place in the operation are already in the
* database as an RhnSet (the name of set is passed into this call).</li>
* <li>The server ID is stored in the first element (i.e. "element" in the set table).
* </ul>
* <p/>
* This should be a safe assumption since, at very least, if all servers are taking
* place in the operation they are already in the SSM RhnSet. If only a subset
* is needed, a nested select can be used to drop them into a new set, preventing
* the need to have another insert per server for this call.
*
* @param user user under which to associate the operation; cannot be
* <code>null</code>
* @param messageId message id of operation description; cannot be <code>null</code>
* @param rhnSetLabel references a RhnSet with the server IDs to associate with the
* new operation; if this is <code>null</code> no mappings will
* be created at this time
* @return the id of the created operation
*/
public static long createOperation(User user, String messageId,
String rhnSetLabel) {
if (user == null) {
throw new IllegalArgumentException("user cannot be null");
}
if (messageId == null) {
throw new IllegalArgumentException("description cannot be null");
}
SelectMode selectMode;
WriteMode writeMode;
Map<String, Object> params = new HashMap<String, Object>();
// Select the operation ID manually from the sequence so we can add the mappings
// from the operation to the servers
selectMode = ModeFactory.getMode("ssm_operation_queries", "get_seq_nextval");
DataResult nextValResult = selectMode.execute(params);
Map<String, Object> nextValMap = (Map<String, Object>) nextValResult.get(0);
long operationId = (Long) nextValMap.get("nextval");
// Add the operation data
writeMode = ModeFactory.getWriteMode("ssm_operation_queries", "create_operation");
params.clear();
params.put("op_id", operationId);
params.put("user_id", user.getId());
params.put("description", LocalizationService.getInstance().getMessage(messageId));
params.put("status", SsmOperationStatus.IN_PROGRESS.getText());
writeMode.executeUpdate(params);
// Add the server/operation mappings
if (rhnSetLabel != null) {
associateServersWithOperation(operationId, user.getId(), rhnSetLabel);
}
return operationId;
}
/**
* Indicates the operation has completed, updating its status to indicate this.
*
* @param user verifies that the user isn't trying to load someone else's
* operation; cannot be <code>null</code>
* @param operationId database ID of the operation to update
*/
public static void completeOperation(User user, long operationId) {
if (user == null) {
throw new IllegalArgumentException("user cannot be null");
}
WriteMode m =
ModeFactory.getWriteMode("ssm_operation_queries", "update_status");
Map<String, Object> params = new HashMap<String, Object>(3);
params.put("user_id", user.getId());
params.put("op_id", operationId);
params.put("status", SsmOperationStatus.COMPLETED.getText());
m.executeUpdate(params);
}
/**
* Returns a list of servers that took part in the given SSM operation.
*
* @param operationId operation for which to return the server IDs
* @return list of maps, one per server ID, where each map contains a single
* entry (key: server_id) containing the server ID
*/
public static DataResult findServerDataForOperation(long operationId) {
SelectMode m = ModeFactory.getMode("ssm_operation_queries",
"find_server_data_for_operation_id");
Map<String, Object> params = new HashMap<String, Object>(1);
params.put("op_id", operationId);
// list of maps of server_id -> <id>
DataResult result = m.execute(params);
return result;
}
/**
* Associates an operation with a group of servers against which it was run, where
* the servers are found in an RhnSet. The IDs for these servers must be stored in
* the "element" field of the RhnSet.
*
* @param operationId identifies an existing operation to associate with servers
* @param userId identifies the user performing the operation
* @param setLabel identifies the set in which to find server IDs
*/
public static void associateServersWithOperation(long operationId, long userId,
String setLabel) {
WriteMode writeMode =
ModeFactory.getWriteMode("ssm_operation_queries", "map_servers_to_operation");
Map<String, Object> params = new HashMap<String, Object>(3);
params.put("op_id", operationId);
params.put("user_id", userId);
params.put("set_label", setLabel);
writeMode.executeUpdate(params);
}
/**
* Associates an operation with a group of servers against which it was run, where
* a list of server ids are passed in
* @param operationId identifies an existing operation to associate with servers
* @param userId identifies the user performing the operation
* @param sidsIn the list server ids
*/
public static void associateServersWithOperation(long operationId, long userId,
List<Long> sidsIn) {
WriteMode writeMode =
ModeFactory.getWriteMode("ssm_operation_queries",
"map_sids_to_operation");
Map<String, Object> params = new HashMap<String, Object>(2);
params.put("op_id", operationId);
params.put("user_id", userId);
writeMode.executeUpdate(params, sidsIn);
}
/**
* Updates an association between an operation and a server adding a note.
* @param operationId identifies an existing operation
* @param serverId identifies the server on which the operation failed
* @param note note to be added
*/
public static void addNoteToOperationOnServer(long operationId, long serverId,
String note) {
WriteMode writeMode = ModeFactory.getWriteMode("ssm_operation_queries",
"add_note_to_operation_on_server");
Map<String, Object> params = new HashMap<String, Object>();
params.put("op_id", operationId);
params.put("server_id", serverId);
params.put("note", note);
writeMode.executeUpdate(params);
}
}