etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java | 1
modules/core/domain/src/main/java/org/rhq/core/domain/resource/Agent.java | 7
modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentManagement.java | 10
modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentManagementMBean.java | 5
modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/admin/topology/AgentDetailView.java | 141 +++++++++-
modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/gwt/TopologyGWTService.java | 8
modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/server/gwt/TopologyGWTServiceImpl.java | 9
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/TopologyManagerBean.java | 16 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/TopologyManagerLocal.java | 12
modules/plugins/rhq-agent/src/main/resources/META-INF/rhq-plugin.xml | 1
10 files changed, 207 insertions(+), 3 deletions(-)
New commits:
commit 3b2ad9a91b31451fb2ec9b223f7daa2e9716c941
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Thu Feb 27 19:47:06 2014 +0100
[BZ 1065680] - Agent admin page should list the installed plugins - Implementing new method on TopologyManagerBean for obtaining the corresponding resource id for an agent instance. If there is such an id, web UI runs the "retrieveAllPluginInfo" operation and displays its result in the agent admin UI (on the agent detail page). So the assumption here is that the agent has already imported the RHQ Agent resource.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Agent.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Agent.java
index 186c968..4cbbb09 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Agent.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Agent.java
@@ -62,6 +62,12 @@ import org.rhq.core.domain.cloud.Server;
@NamedQuery(name = Agent.QUERY_REMOVE_SERVER_REFERENCE, query = "UPDATE Agent a SET a.server.id = NULL WHERE a.server.id = :serverId "),
@NamedQuery(name = Agent.QUERY_COUNT_ALL, query = "SELECT count(a.id) FROM Agent a"),
@NamedQuery(name = Agent.QUERY_FIND_RESOURCE_IDS_FOR_AGENT, query = "SELECT r.id FROM Resource r WHERE r.agent.id = :agentId"),
+ @NamedQuery(name = Agent.QUERY_FIND_AGENT_RESOURCE_ID_AGENT_ID, query = "" //
+ + "SELECT r.id " //
+ + "FROM Resource r " //
+ + "WHERE r.resourceType.name = 'RHQ Agent' " //
+ + "AND r.inventoryStatus = 'COMMITTED'" //
+ + "AND r.agent.id = :agentId"),
@NamedQuery(name = Agent.QUERY_FIND_RESOURCE_IDS_WITH_AGENTS_BY_RESOURCE_IDS, query = "" //
+ "SELECT new org.rhq.core.domain.resource.composite.ResourceIdWithAgentComposite(r.id, r.agent) " //
+ " FROM Resource r " //
@@ -163,6 +169,7 @@ public class Agent implements Serializable {
public static final String QUERY_FIND_BY_SERVER = "Agent.findByServer";
public static final String QUERY_COUNT_ALL = "Agent.countAll";
public static final String QUERY_FIND_RESOURCE_IDS_FOR_AGENT = "Agent.findResourceIdsForAgent";
+ public static final String QUERY_FIND_AGENT_RESOURCE_ID_AGENT_ID = "Agent.findAgentResourceIdByAgentId";
public static final String QUERY_FIND_RESOURCE_IDS_WITH_AGENTS_BY_RESOURCE_IDS = "Agent.findResourceIdsWithAgentsByResourceIds";
public static final String QUERY_FIND_ALL_SUSPECT_AGENTS = "Agent.findAllSuspectAgents";
public static final String QUERY_FIND_BY_AFFINITY_GROUP = "Agent.findByAffinityGroup";
diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentManagement.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentManagement.java
index 11eb3e3..72f3422 100644
--- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentManagement.java
+++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentManagement.java
@@ -168,7 +168,10 @@ public class AgentManagement implements AgentManagementMBean, MBeanRegistration
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
PluginUpdate updater = getPluginUpdateObject();
plugins = updater.getCurrentPluginFiles();
-
+ PluginContainerConfiguration pcConfig = m_agent.getConfiguration().getPluginContainerConfiguration();
+ List<String> enabledPlugins = pcConfig.getEnabledPlugins();
+ List<String> disabledPlugins = pcConfig.getDisabledPlugins();
+
PropertyList list = new PropertyList("plugins".intern());
info.getComplexResults().put(list);
@@ -192,6 +195,11 @@ public class AgentManagement implements AgentManagementMBean, MBeanRegistration
map.put(new PropertySimple(PLUGIN_INFO_PATH, plugin.getAbsoluteFile()));
map.put(new PropertySimple(PLUGIN_INFO_TIMESTAMP, new Date(plugin.lastModified())));
map.put(new PropertySimple(PLUGIN_INFO_SIZE, plugin.length()));
+ // plugin is either whitelisted or the white list is empty
+ boolean isEnabled = enabledPlugins.isEmpty() || enabledPlugins.contains(pluginName);
+ // ..and is not on the black list
+ isEnabled &= !disabledPlugins.contains(pluginName);
+ map.put(new PropertySimple(PLUGIN_INFO_ENABLED, isEnabled));
try {
map.put(new PropertySimple(PLUGIN_INFO_MD5, MessageDigestGenerator.getDigestString(plugin)));
diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentManagementMBean.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentManagementMBean.java
index 9ba53b4..c6093f3 100644
--- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentManagementMBean.java
+++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentManagementMBean.java
@@ -81,6 +81,11 @@ public interface AgentManagementMBean {
* Identifies the filesize of a plugin.
*/
String PLUGIN_INFO_SIZE = "size";
+
+ /**
+ * Identifies whether the plugin is currently being used by the agent
+ */
+ String PLUGIN_INFO_ENABLED = "enabled";
/**
* Identifies the MD5 of a plugin.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/admin/topology/AgentDetailView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/admin/topology/AgentDetailView.java
index 5db839c..c614f1c 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/admin/topology/AgentDetailView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/admin/topology/AgentDetailView.java
@@ -31,19 +31,32 @@ import static org.rhq.coregui.client.admin.topology.AgentDatasourceField.FIELD_S
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.Overflow;
+import com.smartgwt.client.types.VerticalAlignment;
import com.smartgwt.client.types.VisibilityMode;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Img;
+import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.StaticTextItem;
import com.smartgwt.client.widgets.layout.SectionStack;
import com.smartgwt.client.widgets.layout.SectionStackSection;
import org.rhq.core.domain.cloud.AffinityGroup;
+import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.criteria.AgentCriteria;
+import org.rhq.core.domain.criteria.ResourceOperationHistoryCriteria;
+import org.rhq.core.domain.operation.OperationDefinition;
+import org.rhq.core.domain.operation.OperationRequestStatus;
+import org.rhq.core.domain.operation.ResourceOperationHistory;
import org.rhq.core.domain.resource.Agent;
import org.rhq.core.domain.util.PageList;
+import org.rhq.core.domain.util.PageOrdering;
import org.rhq.coregui.client.CoreGUI;
import org.rhq.coregui.client.LinkManager;
+import org.rhq.coregui.client.admin.AgentPluginTableView;
+import org.rhq.coregui.client.components.configuration.ConfigurationEditor;
import org.rhq.coregui.client.components.table.TimestampCellFormatter;
import org.rhq.coregui.client.gwt.GWTServiceLookup;
import org.rhq.coregui.client.util.StringUtility;
@@ -58,10 +71,15 @@ public class AgentDetailView extends EnhancedVLayout {
private final int agentId;
- private static final int SECTION_COUNT = 2;
+ private static final int SECTION_COUNT = 3;
+ private static final String LOADING_ICON = "ajax-loader.gif";
private final SectionStack sectionStack;
private SectionStackSection detailsSection = null;
private SectionStackSection failoverListSection = null;
+ private SectionStackSection agentPluginsSection = null;
+ private volatile boolean waitingForPlugins = false;
+ private EnhancedVLayout pluginsSection;
+ private Img loading;
private volatile int initSectionCount = 0;
@@ -95,6 +113,24 @@ public class AgentDetailView extends EnhancedVLayout {
}
prepareDetailsSection(sectionStack, agents.get(0));
prepareFailoverListSection(sectionStack, agents.get(0));
+
+ GWTServiceLookup.getTopologyService().getResourceIdOfAgent(agentId, new AsyncCallback<Integer>() {
+ public void onSuccess(final Integer resourceId) {
+ if (resourceId != null) {
+ prepareAgentPluginsSection(sectionStack, resourceId);
+ loadPlugins(resourceId);
+ } else {
+ initSectionCount = SECTION_COUNT;
+ }
+ }
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError(
+ MSG.view_adminTopology_message_fetchAgentFail(String.valueOf(agentId)) + " "
+ + caught.getMessage(), caught);
+ initSectionCount = SECTION_COUNT;
+ }
+ });
+
}
public void onFailure(Throwable caught) {
@@ -127,7 +163,10 @@ public class AgentDetailView extends EnhancedVLayout {
if (null != failoverListSection) {
sectionStack.addSection(failoverListSection);
}
-
+ if (null != agentPluginsSection) {
+ sectionStack.addSection(agentPluginsSection);
+ }
+
addMember(sectionStack);
markForRedraw();
@@ -153,6 +192,48 @@ public class AgentDetailView extends EnhancedVLayout {
++initSectionCount;
return;
}
+
+ private void prepareAgentPluginsSection(SectionStack stack, int resourceId) {
+ SectionStackSection section = new SectionStackSection(MSG.view_adminConfig_agentPlugins());
+ section.setExpanded(false);
+ loading = new Img(LOADING_ICON, 16, 16);
+ loading.setValign(VerticalAlignment.CENTER);
+ loading.setAlign(Alignment.CENTER);
+ pluginsSection = new EnhancedVLayout();
+ pluginsSection.addMember(loading);
+ section.setItems(pluginsSection);
+ agentPluginsSection = section;
+ ++initSectionCount;
+ return;
+ }
+
+
+ protected Canvas buildResultsSection(ResourceOperationHistory operationHistory) {
+ OperationRequestStatus status = operationHistory.getStatus();
+ if (status == OperationRequestStatus.SUCCESS || status == OperationRequestStatus.FAILURE) {
+ EnhancedVLayout resultsSection = new EnhancedVLayout();
+
+ OperationDefinition operationDefinition = operationHistory.getOperationDefinition();
+ ConfigurationDefinition resultsConfigurationDefinition = operationDefinition
+ .getResultsConfigurationDefinition();
+ if (resultsConfigurationDefinition != null
+ && !resultsConfigurationDefinition.getPropertyDefinitions().isEmpty()) {
+ ConfigurationEditor editor = new ConfigurationEditor(
+ operationDefinition.getResultsConfigurationDefinition(), operationHistory.getResults());
+ editor.setPreserveTextFormatting(true);
+ editor.setReadOnly(true);
+ resultsSection.addMember(editor);
+ } else {
+ Label noResultsLabel = new Label(MSG.view_operationHistoryDetails_noResults());
+ noResultsLabel.setHeight(17);
+ resultsSection.addMember(noResultsLabel);
+ }
+
+ return resultsSection;
+ } else {
+ return null;
+ }
+ }
private void prepareDetailsSection(SectionStack stack, Agent agent) {
final DynamicForm form = new DynamicForm();
@@ -222,4 +303,60 @@ public class AgentDetailView extends EnhancedVLayout {
detailsSection = section;
++initSectionCount;
}
+
+
+ private void loadPlugins(final int resourceId) {
+ if (waitingForPlugins) {
+ return;
+ }
+ waitingForPlugins = true;
+ GWTServiceLookup.getOperationService().scheduleResourceOperation(resourceId, "retrieveAllPluginInfo", null,
+ "Run by RHQ Server", 0, new AsyncCallback<Void>() {
+
+ @Override
+ public void onFailure(Throwable caught) {
+ waitingForPlugins = false;
+ }
+
+ @Override
+ public void onSuccess(Void result) {
+ waitingForPlugins = false;
+ final ResourceOperationHistoryCriteria criteria = new ResourceOperationHistoryCriteria();
+ criteria.addFilterResourceIds(resourceId);
+ criteria.addFilterOperationName("retrieveAllPluginInfo");
+ criteria.addSortEndTime(PageOrdering.DESC);
+ criteria.fetchResults(true);
+ new Timer() {
+ @Override
+ public void run() {
+ GWTServiceLookup.getOperationService().findResourceOperationHistoriesByCriteria(criteria,
+ new AsyncCallback<PageList<ResourceOperationHistory>>() {
+
+ @Override
+ public void onFailure(Throwable caught) {
+ waitingForPlugins = false;
+ }
+
+ @Override
+ public void onSuccess(PageList<ResourceOperationHistory> result) {
+ if (!result.isEmpty()) {
+ ResourceOperationHistory opHistory = result.get(0);
+ if (opHistory.getStatus() == OperationRequestStatus.SUCCESS
+ || opHistory.getStatus() == OperationRequestStatus.FAILURE) {
+ pluginsSection.removeMembers(pluginsSection.getMembers());
+ pluginsSection.addMember(buildResultsSection(opHistory));
+ pluginsSection.markForRedraw();
+ waitingForPlugins = false;
+ } else if (opHistory.getStatus() == OperationRequestStatus.INPROGRESS) {
+ schedule(1000);
+ }
+ }
+ }
+ });
+ }
+
+ }.schedule(700);
+ }
+ });
+ }
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/gwt/TopologyGWTService.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/gwt/TopologyGWTService.java
index 2547a19..8565070 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/gwt/TopologyGWTService.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/gwt/TopologyGWTService.java
@@ -235,4 +235,12 @@ public interface TopologyGWTService extends RemoteService {
*/
void removeAgentsFromGroup(Integer[] agentIds) throws RuntimeException;
+ /**
+ * Returns the id of managed reource representing this agent instance
+ *
+ * @param agentId an id of <code>Agent</code> instance
+ * @return id of the associated resource <code>null</code> if there is no associated resource
+ * @throws RuntimeException
+ */
+ Integer getResourceIdOfAgent(int agentId) throws RuntimeException;
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/server/gwt/TopologyGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/server/gwt/TopologyGWTServiceImpl.java
index baeb312..90b4b0b 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/server/gwt/TopologyGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/server/gwt/TopologyGWTServiceImpl.java
@@ -268,4 +268,13 @@ public class TopologyGWTServiceImpl extends AbstractGWTServiceImpl implements To
throw getExceptionToThrowToClient(t);
}
}
+
+ @Override
+ public Integer getResourceIdOfAgent(int agentId) throws RuntimeException {
+ try {
+ return topologyManager.getResourceIdOfAgent(getSessionSubject(), agentId);
+ } catch (Throwable t) {
+ throw getExceptionToThrowToClient(t);
+ }
+ }
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/TopologyManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/TopologyManagerBean.java
index c4225de..8c945ea 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/TopologyManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/TopologyManagerBean.java
@@ -26,6 +26,7 @@ import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
+import javax.persistence.TypedQuery;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -336,4 +337,19 @@ public class TopologyManagerBean implements TopologyManagerLocal {
CriteriaQueryRunner<Server> runner = new CriteriaQueryRunner<Server>(criteria, generator, entityManager);
return runner.execute();
}
+
+ @RequiredPermissions({ @RequiredPermission(Permission.MANAGE_SETTINGS),
+ @RequiredPermission(Permission.MANAGE_INVENTORY) })
+ public Integer getResourceIdOfAgent(Subject subject, int agentId) {
+ TypedQuery<Integer> query = entityManager.<Integer> createNamedQuery(
+ Agent.QUERY_FIND_AGENT_RESOURCE_ID_AGENT_ID, Integer.class);
+ query.setParameter("agentId", agentId);
+
+ try {
+ Integer resourceId = query.getSingleResult();
+ return resourceId;
+ } catch (NoResultException nre) {
+ return null;
+ }
+ }
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/TopologyManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/TopologyManagerLocal.java
index 11b9f95..c5e3c6e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/TopologyManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/TopologyManagerLocal.java
@@ -163,4 +163,16 @@ public interface TopologyManagerLocal {
* @return list of servers
*/
PageList<Server> findServersByCriteria(Subject subject, ServerCriteria criteria);
+
+
+ /**
+ * Returns the id of managed reource representing this agent instance
+ *
+ * the subject needs to have MANAGE_INVENTORY and MANAGE_SETTINGS permissions.
+ *
+ * @param subject caller
+ * @param agentId an id of <code>Agent</code> instance
+ * @return id of the associated resource <code>null</code> if there is no associated resource
+ */
+ Integer getResourceIdOfAgent(Subject subject, int agentId);
}
diff --git a/modules/plugins/rhq-agent/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/rhq-agent/src/main/resources/META-INF/rhq-plugin.xml
index b8ca439..f0b4cc7 100644
--- a/modules/plugins/rhq-agent/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/rhq-agent/src/main/resources/META-INF/rhq-plugin.xml
@@ -99,6 +99,7 @@
<c:simple-property name="timestamp" description="Last time the plugin was updated" />
<c:simple-property name="size" description="Size of the plugin file" />
<c:simple-property name="md5" description="MD5 of the plugin file" />
+ <c:simple-property name="enabled" type="boolean" description="Identifies whether the plugin is enabled on the agent" />
</c:map-property>
</c:list-property>
</results>
commit a0dcf786728aaca8720f631674dd5e5cad7a4d3f
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Wed Feb 26 15:43:47 2014 +0100
Adding Libor to !jon-team irc bot command.
diff --git a/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java
index ed74576..e40e83f 100644
--- a/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java
+++ b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java
@@ -77,6 +77,7 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
JON_DEVS.add("jsanda");
JON_DEVS.add("jshaughn");
JON_DEVS.add("lkrejci");
+ JON_DEVS.add("lzoubek");
JON_DEVS.add("mazz");
JON_DEVS.add("mtho11");
JON_DEVS.add("pilhuhn");