/*
* Embedded Jopr Project
* Copyright (C) 2006-2009 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 Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.jboss.on.embedded.ui;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.faces.application.FacesMessage;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.configuration.definition.ConfigurationTemplate;
import org.rhq.core.domain.operation.OperationDefinition;
import org.rhq.core.domain.operation.OperationHistory;
import org.rhq.core.domain.operation.OperationRequestStatus;
import org.rhq.core.domain.operation.ResourceOperationHistory;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.web.RequestParameter;
import org.jboss.seam.faces.FacesMessages;
import org.jboss.on.embedded.manager.ResourceManager;
import org.jboss.on.embedded.manager.ResourceManagerFactory;
import org.jboss.on.embedded.manager.history.operation.OperationHistoryManager;
/**
* @author Mark Spritzler
* @author Ian Springer
*/
@Name("operationAction")
@Scope(value = ScopeType.CONVERSATION)
public class SingleResourceOperationAction implements Serializable
{
@In
private transient FacesMessages facesMessages;
@In
private OperationHistoryManager historyManager;
@Out(required = false)
private OperationHistory selectedHistory;
@In(create = true)
private CommonActionUtil commonActionUtil;
@Out(required = false)
private Resource currentResource;
@Out(required = false)
private List<OperationDefinition> operations = new ArrayList<OperationDefinition>();
@Out(required = false)
private List<ResourceOperationHistory> operationHistories;
Map<Integer, ResourceOperationHistory> operationHistoryMap = new HashMap<Integer, ResourceOperationHistory>();
@Out(required = false)
private OperationDefinition selectedOperation;
@Out(required = false)
private Configuration selectedOperationParameters;
@RequestParameter
private String selectedOperationName;
@Begin(join = true)
public void initOperationsAndHistory()
{
this.currentResource = this.commonActionUtil.getCurrentResource();
initOperations();
initHistories();
}
/**
* Asynchronously invokes an operation on a Resource.
*
* @return a JSF outcome string
*/
public String invokeOperation()
{
//this.facesMessages.clear();
ResourceType resourceType = getResourceType();
OperationDefinition operationDef = getOperationDefinition(resourceType, this.selectedOperationName);
ConfigurationDefinition paramDef = operationDef.getParametersConfigurationDefinition();
if (paramDef != null && !paramDef.getPropertyDefinitions().isEmpty() && this.selectedOperationParameters == null)
{
initSelectedOperationInfo();
return "missingParams";
}
else
{
OperationHistory newOperationHistory = this.historyManager.addOperationHistory(operationDef.getName(),
this.selectedOperationParameters, this.currentResource, resourceType);
// Null this out as soon as we're done with it, so it won't carry over to the next request.
this.selectedOperationParameters = null;
ResourceManager resourceManager = ResourceManagerFactory.resourceManager();
String jobId = newOperationHistory.getJobId().toString();
try
{
resourceManager.invokeOperation(this.currentResource, operationDef, newOperationHistory.getParameters(),
jobId);
this.facesMessages.add("The #0 operation has been invoked. See the operation history below for the results once the operation has completed.",
operationDef.getDisplayName());
}
catch (RuntimeException e)
{
newOperationHistory.setStatus(OperationRequestStatus.FAILURE);
newOperationHistory.setErrorMessage(e.toString());
this.facesMessages.add(FacesMessage.SEVERITY_FATAL, "Failed to invoke operation: #0", e);
}
initHistories();
// Auto-select the operation history, so its results will be displayed in the
// "Selected Operation History Item" panel.
selectOperationHistory(newOperationHistory.getId());
return "success";
}
}
public void selectOperationHistory(int id)
{
this.selectedHistory = this.getOperationHistory(id);
}
/**
* Makes the last row not have the dotted line.
*
* @param operation Which operation is currently being displayed in that row
* @return styleclass String based on whether is is the last operation in the operations collection.
*/
public String getOperationRowStyleClass(OperationDefinition operation)
{
String styleClass = "";
if (operation != null && operations != null)
{
int rowNumber = operations.indexOf(operation);
if (rowNumber == (operations.size() - 1))
{
styleClass = "controlTriggerPanelLast";
}
}
return styleClass;
}
/**
* Return the CSS style class that should be used for the specified history item.
*
* @param history a history item
* @return name of the style class to return to add to the 'tr' tag
*/
public String getHistoriesTableRowStyleClass(OperationHistory history)
{
@SuppressWarnings({"UnnecessaryLocalVariable"})
String styleClass = (history.equals(this.selectedHistory)) ? "selectedRow" : "";
return styleClass;
}
public ResourceOperationHistory getOperationHistory(int opHistoryId)
{
return this.operationHistoryMap.get(opHistoryId);
}
private ResourceType getResourceType()
{
currentResource = commonActionUtil.getCurrentResource();
//noinspection UnnecessaryLocalVariable
ResourceType resourceType = currentResource.getResourceType();
return resourceType;
}
private void initOperations()
{
ResourceManager resourceManager = ResourceManagerFactory.resourceManager();
operations = resourceManager.getOperationsForResource(currentResource);
}
private void initHistories()
{
Collection<OperationHistory> opHistories = historyManager.getHistoryForResource(currentResource);
if (opHistories != null)
{
this.operationHistories = new ArrayList<ResourceOperationHistory>();
for (OperationHistory opHistory : opHistories)
{
ResourceOperationHistory resourceOpHistory = (ResourceOperationHistory)opHistory;
this.operationHistories.add(resourceOpHistory);
this.operationHistoryMap.put(resourceOpHistory.getId(), resourceOpHistory);
}
Collections.sort(operationHistories, new Comparator<OperationHistory>()
{
public int compare(OperationHistory a, OperationHistory b)
{
Long difference = b.getCreatedTime() - a.getCreatedTime();
if (difference < 0)
{
return -1;
}
else if (difference > 0)
{
return 1;
}
else
{
return 0;
}
}
});
}
else
{
operationHistories = null;
}
}
public Map<Integer, ResourceOperationHistory> getOperationHistoryMap()
{
return operationHistoryMap;
}
private void initSelectedOperationInfo()
{
ResourceType resourceType = getResourceType();
this.selectedOperation = getOperationDefinition(resourceType, this.selectedOperationName);
ConfigurationTemplate defaultTemplate = this.selectedOperation.getParametersConfigurationDefinition().getDefaultTemplate();
if (defaultTemplate != null)
{
this.selectedOperationParameters = defaultTemplate.getConfiguration().deepCopy();
}
else
{
this.selectedOperationParameters = new Configuration();
}
}
private static OperationDefinition getOperationDefinition(ResourceType resourceType, String operationName)
{
Set<OperationDefinition> operationDefs = resourceType.getOperationDefinitions();
for (OperationDefinition operationDef : operationDefs)
{
if (operationDef.getName().equals(operationName))
{
return operationDef;
}
}
return null;
}
}