[rhq] 13 commits - modules/enterprise
by jharris
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertUIBean.java | 30 -
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/subsystem/SubsystemAlertDefinitionUIBean.java | 88 +++
modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listConditions.xhtml | 3
modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/viewAlert.xhtml | 4
modules/enterprise/gui/portal-war/src/main/webapp/rhq/subsystem/alertDefinitions.xhtml | 12
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java | 6
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java | 7
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java | 9
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/AlertTokenReplacer.java | 231 ++++++++++
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java | 39 +
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java | 10
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java | 90 +++
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java | 83 +++
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenClass.java | 20
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacer.java | 178 -------
modules/enterprise/server/plugins/alert-operations/src/main/token2confluence.xsl | 28 +
modules/enterprise/server/plugins/alert-operations/src/test/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacementTest.java | 72 ++-
modules/enterprise/server/plugins/alert-operations/tokens.xml | 137 +++++
18 files changed, 786 insertions(+), 261 deletions(-)
New commits:
commit d882f2088e1f27d64376550e1b984cf33fcd2923
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Mar 2 15:04:05 2010 +0100
Prevent NPE
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
index e5684d2..c3eda0e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
@@ -2129,7 +2129,8 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
resourceId = parent.getId();
}
parent = getParentResource(resourceId);
- int parentId = parent.getId();
+ if (parent==null)
+ break;
if (parent.getResourceType().getCategory().equals(ResourceCategory.PLATFORM)){
resource = parent;
parent = null;
@@ -2177,7 +2178,7 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
//we can't assume the ordering of the provided results and the disambiguation query results
//will be the same.
-
+
//this list contains the resulting reports in the same order as the original results
List<MutableDisambiguationReport<T>> reports = new ArrayList<MutableDisambiguationReport<T>>(results.size());
@@ -2267,7 +2268,7 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
String parentName = (String) parentsResult[2 * i + 2];
parents.add(new ResourceParentFlyweight(parentId, parentName));
}
-
+
//update all the reports that correspond to this resourceId
for(MutableDisambiguationReport<T> report : reportsByResourceId.get(resourceId)) {
report.typeName = typeName;
@@ -2282,7 +2283,7 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
for (MutableDisambiguationReport<T> report : reports) {
resolution.add(report.getReport());
}
-
+
return new ResourceNamesDisambiguationResult<T>(resolution, typeResolutionNeeded, parentResolutionNeeded,
pluginResolutionNeeded);
}
commit 53f788862170e0bd8e837d4da6996d3fdff796da
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Mar 2 11:40:09 2010 +0100
Move to a better place in the file hierarchy
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/token2confluence.xsl b/modules/enterprise/server/plugins/alert-operations/src/main/token2confluence.xsl
new file mode 100644
index 0000000..1d1a2d9
--- /dev/null
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/token2confluence.xsl
@@ -0,0 +1,28 @@
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:output method="text" indent="no" xml:space="default"/>
+ <xsl:strip-space elements="*"/>
+
+ <xsl:template match="/">
+h2. Tokens for alert-operations sender
+
+Those tokens can be used in operation definition properties like
+'tokenclass.token' e.g. "alert.id" or "resource.name"
+ <xsl:apply-templates />
+ </xsl:template>
+
+ <xsl:template match="tokenClass">
+h3. *Token Class '<xsl:value-of select="@name"/>'* <xsl:value-of select="@description"/>
+ <xsl:apply-templates >
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
+ </xsl:template>
+
+ <xsl:template match="token">
+* *<xsl:value-of select="@name"/>*: _<xsl:value-of select="descr"/>_<xsl:text/>
+ </xsl:template>
+
+ <xsl:template match="fullName"/>
+ <xsl:template match="descr"/>
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl b/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl
deleted file mode 100644
index 1d1a2d9..0000000
--- a/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl
+++ /dev/null
@@ -1,28 +0,0 @@
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-
- <xsl:output method="text" indent="no" xml:space="default"/>
- <xsl:strip-space elements="*"/>
-
- <xsl:template match="/">
-h2. Tokens for alert-operations sender
-
-Those tokens can be used in operation definition properties like
-'tokenclass.token' e.g. "alert.id" or "resource.name"
- <xsl:apply-templates />
- </xsl:template>
-
- <xsl:template match="tokenClass">
-h3. *Token Class '<xsl:value-of select="@name"/>'* <xsl:value-of select="@description"/>
- <xsl:apply-templates >
- <xsl:sort select="@name"/>
- </xsl:apply-templates>
- </xsl:template>
-
- <xsl:template match="token">
-* *<xsl:value-of select="@name"/>*: _<xsl:value-of select="descr"/>_<xsl:text/>
- </xsl:template>
-
- <xsl:template match="fullName"/>
- <xsl:template match="descr"/>
-
-</xsl:stylesheet>
\ No newline at end of file
commit 00727947b1936074c04a13d0d6c4d34ab1233e60
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Mar 2 11:39:41 2010 +0100
Add an option to specify an output file.
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
index 7b2d7ff..a51f2fb 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
@@ -18,6 +18,11 @@
*/
package org.rhq.enterprise.server.plugins.alertOperations;
+import java.io.BufferedOutputStream;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
import java.util.EnumSet;
import java.util.Set;
@@ -35,9 +40,20 @@ public class PrintTokens {
public static void main(String[] args) throws Exception {
+ OutputStream out;
+ if (args.length==0)
+ out = new BufferedOutputStream(System.out);
+ else {
+ File file = new File(args[0]);
+ System.err.println("writing to " + file.getAbsolutePath());
+ out = new BufferedOutputStream(new FileOutputStream(file));
+ }
+
String text = createTokenDescription();
- System.out.println(text);
+ out.write(text.getBytes());
+ out.flush();
+ out.close();
}
/**
commit ada3ff33262675a7fd00298f078608aae0559a2e
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Mar 2 10:03:24 2010 +0100
Optimization of the style sheet
diff --git a/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl b/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl
index 8a2b14f..1d1a2d9 100644
--- a/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl
+++ b/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl
@@ -1,19 +1,25 @@
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="no" xml:space="default"/>
+ <xsl:strip-space elements="*"/>
<xsl:template match="/">
h2. Tokens for alert-operations sender
+
+Those tokens can be used in operation definition properties like
+'tokenclass.token' e.g. "alert.id" or "resource.name"
<xsl:apply-templates />
</xsl:template>
<xsl:template match="tokenClass">
-h3. *<xsl:value-of select="@name"/>*: <xsl:value-of select="@description"/>
- <xsl:apply-templates/>
+h3. *Token Class '<xsl:value-of select="@name"/>'* <xsl:value-of select="@description"/>
+ <xsl:apply-templates >
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
</xsl:template>
<xsl:template match="token">
-* *<xsl:value-of select="@name"/>*: _<xsl:value-of select="descr"/>_
+* *<xsl:value-of select="@name"/>*: _<xsl:value-of select="descr"/>_<xsl:text/>
</xsl:template>
<xsl:template match="fullName"/>
commit a197c85ba3abdcf2e5bc6cf45a21f292f90ee6d3
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Mar 1 22:20:25 2010 +0100
Fix generated xml, provide a list of tokens and a way to translate them to confluence markup.
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
index 79ff62e..7b2d7ff 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
@@ -58,7 +58,7 @@ public class PrintTokens {
Set<Token> tokens = Token.getByTokenClass(tc);
for (Token token : tokens) {
builder.append(" <token name=\"").append(token.getName()).append(CLOSE);
- builder.append(" <fullName>").append(token.getText()).append(CLOSE);
+ builder.append(" <fullName>").append(token.getText()).append("</fullName>\n");
builder.append(" <descr>").append(token.getDescription()).append("</descr>\n");
builder.append(" </token>\n");
diff --git a/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl b/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl
new file mode 100644
index 0000000..8a2b14f
--- /dev/null
+++ b/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl
@@ -0,0 +1,22 @@
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:output method="text" indent="no" xml:space="default"/>
+
+ <xsl:template match="/">
+h2. Tokens for alert-operations sender
+ <xsl:apply-templates />
+ </xsl:template>
+
+ <xsl:template match="tokenClass">
+h3. *<xsl:value-of select="@name"/>*: <xsl:value-of select="@description"/>
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="token">
+* *<xsl:value-of select="@name"/>*: _<xsl:value-of select="descr"/>_
+ </xsl:template>
+
+ <xsl:template match="fullName"/>
+ <xsl:template match="descr"/>
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/modules/enterprise/server/plugins/alert-operations/tokens.xml b/modules/enterprise/server/plugins/alert-operations/tokens.xml
new file mode 100644
index 0000000..2c29789
--- /dev/null
+++ b/modules/enterprise/server/plugins/alert-operations/tokens.xml
@@ -0,0 +1,137 @@
+<!-- this file was generated from the Token + TokenClass enums via PrintTokens tool -->
+<tokenClasses>
+ <tokenClass name="alert" description="Information about the alert itself">
+ <token name="willBeDisabled">
+ <fullName>alert.willBeDisabled</fullName>
+ <descr>Will the alert definition be disabled after firing?</descr>
+ </token>
+ <token name="id">
+ <fullName>alert.id</fullName>
+ <descr>The id of this particular alert</descr>
+ </token>
+ <token name="url">
+ <fullName>alert.url</fullName>
+ <descr>Url to the alert details page</descr>
+ </token>
+ <token name="name">
+ <fullName>alert.name</fullName>
+ <descr>Name from the defining alert definition</descr>
+ </token>
+ <token name="priority">
+ <fullName>alert.priority</fullName>
+ <descr>Priority of this alert</descr>
+ </token>
+ <token name="description">
+ <fullName>alert.description</fullName>
+ <descr>Description of this alert</descr>
+ </token>
+ <token name="firedAt">
+ <fullName>alert.firedAt</fullName>
+ <descr>Time the alert fired</descr>
+ </token>
+ <token name="conditions">
+ <fullName>alert.conditions</fullName>
+ <descr>A text representation of the conditions that led to this alert</descr>
+ </token>
+ <token name="willRecover">
+ <fullName>alert.willRecover</fullName>
+ <descr>?? TODO</descr>
+ </token>
+ </tokenClass>
+ <tokenClass name="resource" description="Information about the resource that triggered the alert">
+ <token name="id">
+ <fullName>resource.id</fullName>
+ <descr>Id of the resource</descr>
+ </token>
+ <token name="platformType">
+ <fullName>resource.platformType</fullName>
+ <descr>Type of the platform the resource is on</descr>
+ </token>
+ <token name="platformName">
+ <fullName>resource.platformName</fullName>
+ <descr>Name of the platform the resource is on</descr>
+ </token>
+ <token name="typeName">
+ <fullName>resource.typeName</fullName>
+ <descr>Resource type name</descr>
+ </token>
+ <token name="name">
+ <fullName>resource.name</fullName>
+ <descr>Name of the resource</descr>
+ </token>
+ <token name="platformId">
+ <fullName>resource.platformId</fullName>
+ <descr>Id of the platform the resource is on</descr>
+ </token>
+ <token name="parentName">
+ <fullName>resource.parentName</fullName>
+ <descr>Name of the parent resource</descr>
+ </token>
+ <token name="parentId">
+ <fullName>resource.parentId</fullName>
+ <descr>Id of the parent resource</descr>
+ </token>
+ <token name="typeId">
+ <fullName>resource.typeId</fullName>
+ <descr>Resource type id</descr>
+ </token>
+ </tokenClass>
+ <tokenClass name="targetResource" description="Information about the resource the alert is fired on ">
+ <token name="parentId">
+ <fullName>targetResource.parentId</fullName>
+ <descr>Id of the target's parent resource</descr>
+ </token>
+ <token name="platformName">
+ <fullName>targetResource.platformName</fullName>
+ <descr>Name of the platform the target resource is on</descr>
+ </token>
+ <token name="platformId">
+ <fullName>targetResource.platformId</fullName>
+ <descr>Id of the platform the target resource is on</descr>
+ </token>
+ <token name="parentName">
+ <fullName>targetResource.parentName</fullName>
+ <descr>Name of the target's parent resource</descr>
+ </token>
+ <token name="typeId">
+ <fullName>targetResource.typeId</fullName>
+ <descr>Resource type of the target resource id</descr>
+ </token>
+ <token name="platformType">
+ <fullName>targetResource.platformType</fullName>
+ <descr>Type of the platform the target resource is on</descr>
+ </token>
+ <token name="name">
+ <fullName>targetResource.name</fullName>
+ <descr>Name of the target resource</descr>
+ </token>
+ <token name="id">
+ <fullName>targetResource.id</fullName>
+ <descr>Id of the target resource</descr>
+ </token>
+ <token name="typeName">
+ <fullName>targetResource.typeName</fullName>
+ <descr>Resource type name of the target resource</descr>
+ </token>
+ </tokenClass>
+ <tokenClass name="operation" description="Information about the triggered operation">
+ <token name="id">
+ <fullName>operation.id</fullName>
+ <descr>Id of the operation fired</descr>
+ </token>
+ <token name="name">
+ <fullName>operation.name</fullName>
+ <descr>Name of the operation fired</descr>
+ </token>
+ </tokenClass>
+ <tokenClass name="test" description="Just some dummies for internal testing purposes">
+ <token name="echo">
+ <fullName>test.echo</fullName>
+ <descr>Echo the input</descr>
+ </token>
+ <token name="fix">
+ <fullName>test.fix</fullName>
+ <descr>Return a fixed string</descr>
+ </token>
+ </tokenClass>
+</tokenClasses>
commit 653e41c57c1fb6facc52ba3d22c20259f9717141
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Mar 1 21:47:17 2010 +0100
Support more tokens
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/AlertTokenReplacer.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/AlertTokenReplacer.java
new file mode 100644
index 0000000..e8c61dd
--- /dev/null
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/AlertTokenReplacer.java
@@ -0,0 +1,231 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.plugins.alertOperations;
+
+import java.util.Date;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.alert.Alert;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.operation.OperationDefinition;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.enterprise.server.alert.AlertManagerLocal;
+import org.rhq.enterprise.server.resource.ResourceManagerLocal;
+import org.rhq.enterprise.server.util.LookupUtil;
+
+/**
+ * Helper to replace tokens by their values
+ * @author Heiko W. Rupp
+ */
+public class AlertTokenReplacer {
+
+ private final Log log = LogFactory.getLog(AlertTokenReplacer.class);
+ public static final String NOT_YET_IMPLEMENTED = " - not yet implemented -";
+ protected static final String THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG = "TheQuickBrownFoxJumpsOverTheLazyDOg";
+ private Alert alert;
+ private Pattern pattern;
+ private OperationDefinition operationDefinition;
+ private Resource targetResource;
+
+ public AlertTokenReplacer(Alert alert, OperationDefinition operationDefinition, Resource targetResource) {
+ this.alert = alert;
+ this.operationDefinition = operationDefinition;
+ pattern = Pattern.compile("<%\\s*([a-z]+\\.[a-z0-9]+)\\s*%>");
+ }
+
+ /**
+ * Replace all tokens on the input line. If no tokens are found the input is returned.
+ * Tokens have the form '<i><% class.sub %></i>'
+ * @param input a line of text
+ * @return input with tokens replaced.
+ * @see org.rhq.enterprise.server.plugins.alertOperations.Token
+ * @see org.rhq.enterprise.server.plugins.alertOperations.TokenClass
+ */
+ public String replaceTokens(String input) {
+
+ String work = input;
+ Matcher matcher = pattern.matcher(work);
+ if (!matcher.find()) {
+ log.warn("No tokens found in " + input);
+ return input;
+ }
+ matcher.reset();
+
+ do {
+ matcher = pattern.matcher(work);
+ if (!matcher.find()) {
+ break;
+ }
+ String replacement = replaceToken(matcher.group(1) );
+ String s = matcher.replaceFirst(replacement);
+ work = s;
+
+ } while (true);
+
+ return work;
+ }
+
+
+
+ /**
+ * Replace the token string passed (without the token delimiters ) with the actual value
+ * @param tokenString Input like alert.id
+ * @return replacement string or the input if the token was not valid.
+ */
+ public String replaceToken(String tokenString) {
+
+ // Ok, we have at least one token. Now split the tokenString and loop over the tokens
+
+ if (!tokenString.contains("."))
+ return tokenString;
+
+ String tmp = tokenString.substring(0, tokenString.indexOf("."));
+ TokenClass tc = TokenClass.getByText(tmp);
+ if (tc==null) {
+ log.warn("Unknown token class in [" + tokenString + "], not replacing tokens");
+ return tokenString;
+ }
+
+ Token token = Token.getByText(tokenString);
+ if (token == null) {
+ log.warn("No known token found in [" + tokenString + "], not replacing token");
+ return tokenString;
+ }
+ String ret = null;
+ switch (tc) {
+ case ALERT:
+ ret = replaceAlertToken(token,alert);
+ break;
+ case RESOURCE:
+ ret = replaceResourceToken(token,alert.getAlertDefinition().getResource());
+ break;
+ case TARGET_RESOURCE:
+ // Create a "pseudo" token to feed it into the plain resource replacement code
+ String text = "resource." + token.getName();
+ Token tok = Token.getByText(text);
+ ret = replaceResourceToken(tok, targetResource);
+ break;
+ case OPERATION:
+ ret = replaceOperationToken(token);
+ break;
+ case TEST:
+ switch (token) {
+ case TEST_ECHO:
+ ret = tokenString;
+ break;
+ case TEST_FIX:
+ ret = THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG;
+ break;
+ default:
+ ret = NOT_YET_IMPLEMENTED;
+ }
+ break;
+ }
+ return ret;
+ }
+
+ private String replaceAlertToken(Token token, Alert alert) {
+
+ AlertManagerLocal mgr = LookupUtil.getAlertManager();
+
+ switch (token) {
+ case ALERT_ID:
+ return String.valueOf(alert.getId());
+ case ALERT_FIRE_TIME:
+ return new Date(alert.getCtime()).toString(); // TODO use a specific impl here?
+ case ALERT_WILL_RECOVER:
+ return String.valueOf(alert.getAlertDefinition().getWillRecover());
+ case ALERT_WILL_DISABLE:
+ return String.valueOf(mgr.willDefinitionBeDisabled(alert));
+ case ALERT_DEF_NAME:
+ return alert.getAlertDefinition().getName();
+ case ALERT_DEF_DESC:
+ return alert.getAlertDefinition().getDescription();
+ case ALERT_DEF_PRIO:
+ return alert.getAlertDefinition().getPriority().getName();
+ case ALERT_URL:
+ return mgr.prettyPrintAlertURL(alert);
+ case ALERT_CONDITIONS:
+ return mgr.prettyPrintAlertConditions(alert,false);
+
+
+ default:
+ return NOT_YET_IMPLEMENTED;
+ }
+
+ }
+
+ private String replaceResourceToken(Token token, Resource resource) {
+
+ ResourceManagerLocal mgr = LookupUtil.getResourceManager();
+ Subject overlord = LookupUtil.getSubjectManager().getOverlord();
+ Resource parent;
+ Resource platform = mgr.getPlaformOfResource(overlord,resource.getId());
+
+ switch (token) {
+ case RESOURCE_ID:
+ return String.valueOf(resource.getId());
+ case RESOURCE_NAME:
+ return resource.getName();
+ case RESOURCE_PARENT_ID:
+ parent = mgr.getParentResource(resource.getId());
+ if (parent==null)
+ return "0";
+ else
+ return String.valueOf(parent.getId());
+ case RESOURCE_PARENT_NAME:
+ parent = mgr.getParentResource(resource.getId());
+ if (parent==null)
+ return "0";
+ else
+ return String.valueOf(parent.getId());
+ case RESOURCE_TYPE_ID:
+ return String.valueOf(resource.getResourceType().getId());
+ case RESOURCE_TYPE_NAME:
+ return resource.getResourceType().getName();
+ case RESOURCE_PLATFORM_ID:
+ return String.valueOf(platform.getId());
+ case RESOURCE_PLATFORM_NAME:
+ return platform.getName();
+ case RESOURCE_PLATFORM_TYPE:
+ return platform.getResourceType().getName();
+
+ default:
+ return NOT_YET_IMPLEMENTED;
+ }
+ }
+
+ private String replaceOperationToken(Token token) {
+
+ switch (token) {
+ case OPERATION_ID:
+ return String.valueOf(operationDefinition.getId());
+ case OPERATION_NAME:
+ return operationDefinition.getName();
+
+
+ default:
+ return NOT_YET_IMPLEMENTED;
+ }
+ }
+}
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
index 4f6c88e..635085a 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
@@ -78,9 +78,11 @@ public class OperationsSender extends AlertSender {
Subject subject = LookupUtil.getSubjectManager().getOverlord(); // TODO get real subject
List<OperationDefinition> opdefs = opMgr.findSupportedResourceOperations(subject,resourceId,false);
- for (OperationDefinition opdef : opdefs ) {
- if (opdef.getId() == opId) {
- opName = opdef.getName();
+ OperationDefinition opDef = null;
+ for (OperationDefinition tmp : opdefs ) {
+ if (tmp.getId() == opId) {
+ opName = tmp.getName();
+ opDef = tmp;
break;
}
}
@@ -110,7 +112,7 @@ public class OperationsSender extends AlertSender {
if (parameters!=null && tokenMode.equals(INTERPRETED)) {
Map<String,PropertySimple> propsMap = parameters.getSimpleProperties();
if (!propsMap.isEmpty()) {
- TokenReplacer tr = new TokenReplacer(alert);
+ AlertTokenReplacer tr = new AlertTokenReplacer(alert, opDef, null);
for (PropertySimple prop : propsMap.values()) {
String tmp = prop.getStringValue();
tmp = tr.replaceTokens(tmp);
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
index 78ac850..79ff62e 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
@@ -35,6 +35,17 @@ public class PrintTokens {
public static void main(String[] args) throws Exception {
+ String text = createTokenDescription();
+
+ System.out.println(text);
+ }
+
+ /**
+ * Do the work and return an xml structure that lists available token classes and
+ * tokens along with their descriptions.
+ * @return String with an XML representation of the available tokens
+ */
+ public static String createTokenDescription() {
EnumSet<TokenClass> tokenClasses = EnumSet.allOf(TokenClass.class);
StringBuilder builder = new StringBuilder("<tokenClasses>\n");
@@ -58,7 +69,6 @@ public class PrintTokens {
}
builder.append("</tokenClasses>\n");
-
- System.out.println(builder.toString());
+ return builder.toString();
}
}
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java
index e665bd4..2d810f0 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java
@@ -43,11 +43,25 @@ public enum Token {
// resource that triggered the alert related tokens
RESOURCE_ID(TokenClass.RESOURCE, "id", "Id of the resource"),
RESOURCE_NAME(TokenClass.RESOURCE, "name", "Name of the resource"),
+ RESOURCE_PARENT_ID(TokenClass.RESOURCE, "parentId", "Id of the parent resource"),
+ RESOURCE_PARENT_NAME(TokenClass.RESOURCE, "parentName", "Name of the parent resource"),
+ RESOURCE_TYPE_ID(TokenClass.RESOURCE,"typeId","Resource type id"),
+ RESOURCE_TYPE_NAME(TokenClass.RESOURCE,"typeName","Resource type name"),
+ RESOURCE_PLATFORM_ID(TokenClass.RESOURCE,"platformId", "Id of the platform the resource is on"),
+ RESOURCE_PLATFORM_NAME(TokenClass.RESOURCE,"platformName", "Name of the platform the resource is on"),
+ RESOURCE_PLATFORM_TYPE(TokenClass.RESOURCE,"platformType", "Type of the platform the resource is on"),
// resource the operation is run on related tokens
TRESOURCE_ID(TokenClass.TARGET_RESOURCE, "id","Id of the target resource"),
TRESOURCE_NAME(TokenClass.TARGET_RESOURCE, "name", "Name of the target resource"),
+ TRESOURCE_PARENT_ID(TokenClass.TARGET_RESOURCE, "parentId", "Id of the target's parent resource"),
+ TRESOURCE_PARENT_NAME(TokenClass.TARGET_RESOURCE, "parentName", "Name of the target's parent resource"),
+ TRESOURCE_TYPE_ID(TokenClass.TARGET_RESOURCE,"typeId","Resource type of the target resource id"),
+ TRESOURCE_TYPE_NAME(TokenClass.TARGET_RESOURCE,"typeName","Resource type name of the target resource"),
+ TRESOURCE_PLATFORM_ID(TokenClass.TARGET_RESOURCE,"platformId", "Id of the platform the target resource is on"),
+ TRESOURCE_PLATFORM_NAME(TokenClass.TARGET_RESOURCE,"platformName", "Name of the platform the target resource is on"),
+ TRESOURCE_PLATFORM_TYPE(TokenClass.TARGET_RESOURCE,"platformType", "Type of the platform the target resource is on"),
// Information about the fired operation
@@ -56,9 +70,7 @@ public enum Token {
// only for testing
TEST_ECHO(TokenClass.TEST,"echo", "Echo the input"),
- TEST_FIX(TokenClass.TEST,"fix", "Return a fixed string")
-
- ;
+ TEST_FIX(TokenClass.TEST,"fix", "Return a fixed string");
private TokenClass tc;
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacer.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacer.java
deleted file mode 100644
index 0b230b4..0000000
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacer.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2010 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.plugins.alertOperations;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.rhq.core.domain.alert.Alert;
-import org.rhq.core.domain.resource.Resource;
-
-/**
- * Helper to replace tokens by their values
- * @author Heiko W. Rupp
- */
-public class TokenReplacer {
-
- private final Log log = LogFactory.getLog(TokenReplacer.class);
- private static final String NOT_YET_IMPLEMENTED = " - not yet implemented -";
- protected static final String THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG = "TheQuickBrownFoxJumpsOverTheLazyDOg";
- private Alert alert;
- private Pattern pattern;
-
- public TokenReplacer(Alert alert) {
- this.alert = alert;
- pattern = Pattern.compile("<%\\s*([a-z]+\\.[a-z0-9]+)\\s*%>");
- }
-
- /**
- * Replace all tokens on the input line. If no tokens are found the input is returned.
- * Tokens have the form '<i><% class.sub %></i>'
- * @param input a line of text
- * @return input with tokens replaced.
- * @see org.rhq.enterprise.server.plugins.alertOperations.Token
- * @see org.rhq.enterprise.server.plugins.alertOperations.TokenClass
- */
- public String replaceTokens(String input) {
-
- String work = input;
- Matcher matcher = pattern.matcher(work);
- if (!matcher.find()) {
- log.warn("No tokens found in " + input);
- return input;
- }
- matcher.reset();
-
- do {
-// System.out.println(input);
- matcher = pattern.matcher(work);
- if (!matcher.find()) {
- break;
- }
-// System.out.println(matcher.regionStart() + ":" + matcher.regionEnd() + input.substring(matcher.regionStart(),matcher.regionEnd()));
-// System.out.println(matcher.group(1));
- String replacement = replaceToken(matcher.group(1) );
- String s = matcher.replaceFirst(replacement);
-// System.out.println(s);
- work = s;
-
-// System.out.println("----");
- } while (true);
-
- return work;
- }
-
-
-
- /**
- * Replace the token string passed (without the token delimiters ) with the actual value
- * @param tokenString Input like alert.id
- * @return replacement string or the input if the token was not valid.
- */
- public String replaceToken(String tokenString) {
-
- // Ok, we have at least one token. Now split the tokenString and loop over the tokens
-
- if (!tokenString.contains("."))
- return tokenString;
-
- String tmp = tokenString.substring(0, tokenString.indexOf("."));
- TokenClass tc = TokenClass.getByText(tmp);
- if (tc==null) {
- log.warn("Unknown token class in [" + tokenString + "], not replacing tokens");
- return tokenString;
- }
-
- Token token = Token.getByText(tokenString);
- if (token == null) {
- log.warn("No known token found in [" + tokenString + "], not replacing token");
- return tokenString;
- }
- String ret = null;
- switch (tc) {
- case ALERT:
- ret = replaceAlertToken(token,alert);
- break;
- case RESOURCE:
- ret = replaceResourceToken(token,alert.getAlertDefinition().getResource());
- break;
- case TARGET_RESOURCE:
- Resource resource = null; // TODO
- ret = replaceTargetResourceToken(token, resource);
- break;
- case TEST:
- switch (token) {
- case TEST_ECHO:
- ret = tokenString;
- break;
- case TEST_FIX:
- ret = THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG;
- break;
- default:
- ret = NOT_YET_IMPLEMENTED;
- }
- break;
- }
- return ret;
- }
-
- private String replaceAlertToken(Token token, Alert alert) {
-
- switch (token) {
- case ALERT_ID:
- return String.valueOf(alert.getId());
- case ALERT_URL:
- return NOT_YET_IMPLEMENTED;
-
- default:
- return NOT_YET_IMPLEMENTED;
- }
-
- }
-
- private String replaceResourceToken(Token token, Resource resource) {
-
- switch (token) {
- case RESOURCE_ID:
- return String.valueOf(resource.getId());
- case RESOURCE_NAME:
- return resource.getName();
-
- default:
- return NOT_YET_IMPLEMENTED;
- }
- }
-
- private String replaceTargetResourceToken(Token token, Resource resource) {
-
- switch (token) {
- case TRESOURCE_ID:
- return String.valueOf(resource.getId());
- case TRESOURCE_NAME:
- return resource.getName();
-
- default:
- return NOT_YET_IMPLEMENTED;
- }
- }
-
-}
diff --git a/modules/enterprise/server/plugins/alert-operations/src/test/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacementTest.java b/modules/enterprise/server/plugins/alert-operations/src/test/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacementTest.java
index f41fc85..cf6c48d 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/test/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacementTest.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/test/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacementTest.java
@@ -18,12 +18,15 @@
*/
package org.rhq.enterprise.server.plugins.alertOperations;
+import java.util.EnumSet;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.testng.annotations.Test;
import org.rhq.core.domain.alert.Alert;
import org.rhq.core.domain.alert.AlertDefinition;
+import org.rhq.core.domain.operation.OperationDefinition;
import org.rhq.core.domain.resource.Resource;
/**
@@ -42,17 +45,18 @@ public class TokenReplacementTest {
public void testSimpleReplacement() throws Exception {
Alert al = new Alert();
- TokenReplacer tr = new TokenReplacer(al);
+ AlertTokenReplacer tr = new AlertTokenReplacer(al, null, null);
String res = tr.replaceToken("test.fix");
assert res != null;
- assert res.equals(TokenReplacer.THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG);
+ assert res.equals(AlertTokenReplacer.THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG);
res = tr.replaceToken(TEST_ECHO);
assert res != null;
assert res.equals(TEST_ECHO);
+/*
res = tr.replaceToken("alert.id");
assert res != null;
assert res.equals("0");
@@ -62,18 +66,19 @@ public class TokenReplacementTest {
AlertDefinition def = new AlertDefinition();
def.setResource(r);
al = new Alert(def, System.currentTimeMillis());
- tr = new TokenReplacer(al);
+ tr = new AlertTokenReplacer(al, null, null);
res = tr.replaceToken("resource.id");
assert "1234".equals(res);
res = tr.replaceToken("resource.name");
assert "A resource".equals(res);
+*/
}
public void testInvalidTokenString() {
Alert al = new Alert();
- TokenReplacer tr = new TokenReplacer(al);
+ AlertTokenReplacer tr = new AlertTokenReplacer(al, null, null);
String res = tr.replaceToken(FOO_BAR);
@@ -93,13 +98,13 @@ public class TokenReplacementTest {
public void testFullTokenSimple() {
Alert al = new Alert();
- TokenReplacer tr = new TokenReplacer(al);
+ AlertTokenReplacer tr = new AlertTokenReplacer(al, null, null);
String res = tr.replaceTokens("<%test.fix%>");
assert res != null;
assert !res.equals("<%test.fix%>") : "Res was " + res;
- assert res.equals(TokenReplacer.THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG);
+ assert res.equals(AlertTokenReplacer.THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG);
String TF2 = "<% test.fix %>";
res = tr.replaceTokens(TF2);
@@ -120,16 +125,67 @@ public class TokenReplacementTest {
assert res != null;
assert res.equals(FOO_BAR) : "Res was " + res;
+/*
Resource r = new Resource(1234);
r.setName("A resource");
AlertDefinition def = new AlertDefinition();
def.setResource(r);
al = new Alert(def, System.currentTimeMillis());
- tr = new TokenReplacer(al);
+ tr = new AlertTokenReplacer(al, null, null);
res = tr.replaceTokens("<% test.fix%><%resource.id%>");
assert res!=null;
- assert res.equals(TokenReplacer.THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG+"1234");
+ assert res.equals(AlertTokenReplacer.THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG+"1234");
+*/
+ }
+
+ public void testOperationTokens() {
+ Resource r = new Resource(1234);
+ AlertDefinition def = new AlertDefinition();
+ def.setResource(r);
+ Alert al = new Alert(def, System.currentTimeMillis());
+
+ AlertTokenReplacer tr;
+ OperationDefinition opDef = new OperationDefinition(123,"helloOps",null,"This is a test",0,"Just testing");
+ tr = new AlertTokenReplacer(al,opDef, null);
+ String res = tr.replaceTokens("<%operation.id%>");
+ assert res!=null;
+ assert res.equals("123") : "Result is " + res;
+ res = tr.replaceTokens("<%operation.name%>");
+ assert res!=null;
+ assert res.equals("helloOps");
+ }
+
+ public void testTokenPrinter() {
+
+ String result = PrintTokens.createTokenDescription();
+ assert result != null;
+ assert !result.isEmpty();
+ assert result.contains("<token ");
}
+/*
+ public void testReplaceAllTokens() {
+
+ EnumSet<Token> tokens = EnumSet.allOf(Token.class);
+
+ Resource r = new Resource(1234);
+ AlertDefinition def = new AlertDefinition();
+ def.setResource(r);
+ Alert al = new Alert(def, System.currentTimeMillis());
+
+ AlertTokenReplacer tr;
+ OperationDefinition opDef = new OperationDefinition(123,"helloOps",null,"This is a test",0,"Just testing");
+ tr = new AlertTokenReplacer(al,opDef, null);
+
+ for (Token token : tokens) {
+
+ String input = "<%" + token.getText() + "%>";
+ String res = tr.replaceTokens(input);
+ assert res != null;
+ assert !res.isEmpty();
+ assert !res.equals(AlertTokenReplacer.NOT_YET_IMPLEMENTED) : "Replacement for token [" + token.getText() + "] is not implemented";
+ }
+ }
+*/
}
commit 15ff7e397d9a01af13937c7d806679918e2dda7d
Author: Justin Harris <jharris(a)redhat.com>
Date: Mon Mar 1 11:26:37 2010 -0500
BZ 568796 - Changing input length on metric baseline % field.
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listConditions.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listConditions.xhtml
index 2000efd..668d175 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listConditions.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listConditions.xhtml
@@ -372,7 +372,8 @@
converter="#{metricPercentConverter}"
required="true"
requiredMessage="#{alertMessages.percentRange}"
- validatorMessage="#{alertMessages.percentRange}">
+ validatorMessage="#{alertMessages.percentRange}"
+ size="6">
<f:validateDoubleRange minimum="0.0" maximum="1000.0" />
</h:inputText>
<h:outputLabel for="metricBaselinePercent" value=" #{messages['alert.config.props.CB.Content.Percent']} " />
commit dd92239d4a43a1ae899353f3268857de832ead3e
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Mar 1 14:04:55 2010 +0100
Provide token descriptions and a way to get a full list of tokens defined.
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
new file mode 100644
index 0000000..78ac850
--- /dev/null
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
@@ -0,0 +1,64 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.plugins.alertOperations;
+
+import java.util.EnumSet;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Print the available tokens to stdout, for documentation generation purposes
+ * @author Heiko W. Rupp
+ */
+public class PrintTokens {
+
+ private final Log log = LogFactory.getLog(PrintTokens.class);
+ private static final String CLOSE = "\">\n";
+
+ public static void main(String[] args) throws Exception {
+
+ EnumSet<TokenClass> tokenClasses = EnumSet.allOf(TokenClass.class);
+
+ StringBuilder builder = new StringBuilder("<tokenClasses>\n");
+
+ for (TokenClass tc : tokenClasses ) {
+ builder.append(" <tokenClass name=\"").append(tc.getText()).
+ append("\"").append(" description=\"").append(tc.getDescription()).
+ append(CLOSE);
+
+ Set<Token> tokens = Token.getByTokenClass(tc);
+ for (Token token : tokens) {
+ builder.append(" <token name=\"").append(token.getName()).append(CLOSE);
+ builder.append(" <fullName>").append(token.getText()).append(CLOSE);
+ builder.append(" <descr>").append(token.getDescription()).append("</descr>\n");
+ builder.append(" </token>\n");
+
+ }
+
+ builder.append(" </tokenClass>\n");
+
+ }
+
+ builder.append("</tokenClasses>\n");
+
+ System.out.println(builder.toString());
+ }
+}
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java
index bcd7570..e665bd4 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java
@@ -19,39 +19,59 @@
package org.rhq.enterprise.server.plugins.alertOperations;
import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Set;
/**
- * Tokens that can be replaced in
+ * Tokens that can be replaced in operation parameters
* @author Heiko W. Rupp
*/
public enum Token {
// Alert related tokens
- ALERT_ID(TokenClass.ALERT, "id"),
- ALERT_URL(TokenClass.ALERT, "url"),
+ ALERT_ID(TokenClass.ALERT, "id","The id of this particular alert"),
+ ALERT_URL(TokenClass.ALERT, "url","Url to the alert details page"),
+ ALERT_FIRE_TIME(TokenClass.ALERT, "firedAt","Time the alert fired"),
+ ALERT_WILL_RECOVER(TokenClass.ALERT,"willRecover","?? TODO"),
+ ALERT_CONDITIONS(TokenClass.ALERT,"conditions","A text representation of the conditions that led to this alert"),
+ ALERT_DEF_NAME(TokenClass.ALERT,"name","Name from the defining alert definition"),
+ ALERT_DEF_DESC(TokenClass.ALERT,"description","Description of this alert"),
+ ALERT_DEF_PRIO(TokenClass.ALERT,"priority", "Priority of this alert"),
+ ALERT_WILL_DISABLE(TokenClass.ALERT,"willBeDisabled","Will the alert definition be disabled after firing?"),
+
// resource that triggered the alert related tokens
- RESOURCE_ID(TokenClass.RESOURCE, "id"),
- RESOURCE_NAME(TokenClass.RESOURCE, "name"),
+ RESOURCE_ID(TokenClass.RESOURCE, "id", "Id of the resource"),
+ RESOURCE_NAME(TokenClass.RESOURCE, "name", "Name of the resource"),
// resource the operation is run on related tokens
- TRESOURCE_ID(TokenClass.TARGET_RESOURCE, "id"),
- TRESOURCE_NAME(TokenClass.TARGET_RESOURCE, "name"),
+ TRESOURCE_ID(TokenClass.TARGET_RESOURCE, "id","Id of the target resource"),
+ TRESOURCE_NAME(TokenClass.TARGET_RESOURCE, "name", "Name of the target resource"),
+
+ // Information about the fired operation
+ OPERATION_ID(TokenClass.OPERATION,"id","Id of the operation fired"),
+ OPERATION_NAME(TokenClass.OPERATION,"name","Name of the operation fired"),
// only for testing
- TEST_ECHO(TokenClass.TEST,"echo"),
- TEST_FIX(TokenClass.TEST,"fix")
+ TEST_ECHO(TokenClass.TEST,"echo", "Echo the input"),
+ TEST_FIX(TokenClass.TEST,"fix", "Return a fixed string")
;
+ private TokenClass tc;
+ private String name;
private String text;
+ private String description;
- private Token(TokenClass tc, String text) {
+ private Token(TokenClass tc, String name, String description) {
- this.text = tc.getText() + "." + text;
+ this.tc = tc;
+ this.name = name;
+ this.text = tc.getText() + "." + name;
+ this.description = description;
}
/**
@@ -69,4 +89,29 @@ public enum Token {
}
return null;
}
+
+ public static Set<Token> getByTokenClass(TokenClass tokenClass) {
+
+ Set<Token> tokens = new HashSet<Token>();
+
+ EnumSet<Token> es = EnumSet.allOf(Token.class);
+ for (Token t : es) {
+ if (t.tc == tokenClass)
+ tokens.add(t);
+ }
+
+ return tokens;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public String getDescription() {
+ return description;
+ }
}
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenClass.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenClass.java
index 5125a72..16cb240 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenClass.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenClass.java
@@ -26,22 +26,30 @@ import java.util.EnumSet;
*/
public enum TokenClass {
- ALERT("alert"),
- RESOURCE("resource"),
- TARGET_RESOURCE("targetResource"),
- TEST("test");
+ ALERT("alert","Information about the alert itself"),
+ RESOURCE("resource","Information about the resource that triggered the alert"),
+ TARGET_RESOURCE("targetResource","Information about the resource the alert is fired on "),
+ OPERATION("operation","Information about the triggered operation"),
+ //
+ TEST("test","Just some dummies for internal testing purposes");
private String text;
+ private String description;
- private TokenClass(String text) {
+ private TokenClass(String text,String description) {
this.text = text;
+ this.description = description;
}
public String getText() {
return text;
}
- /**
+ public String getDescription() {
+ return description;
+ }
+
+ /**
* Return the tokenclass that matches the input text or null if not found.
* The token delimiters need to be already stripped from the input
* @param input a token text like <i>alert</i>, which would return the
commit ac9103aaf2c5c999bd6f1d940ff0159072b2cbad
Merge: 79afeae... 6278e70...
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Mar 1 10:47:39 2010 +0100
Merge branch 'master' into alertPlugin
commit 79afeae9fab3bcf14508792f0007c1c773934e36
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Mar 1 10:46:53 2010 +0100
Provide a way to initialize the backing bean after it got created and the alertParameters got injected.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java
index 0896c6e..ccb5d7d 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java
@@ -288,6 +288,12 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc
Configuration config2 = config.deepCopy(true);
bean.setAlertParameters(config2);
+ try {
+ bean.internalInit();
+ }
+ catch (Throwable t ) {
+ LOG.error("getBackinBean, calling backingBean.internalInit() resulted in " + t.getMessage());
+ }
}
}
return bean;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java
index e4b2d20..12312f2 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java
@@ -40,6 +40,13 @@ public class CustomAlertSenderBackingBean {
public void setAlertParameters(Configuration alertParameters) {
this.alertParameters = alertParameters;
}
+
+ /**
+ * This method is called after constructing the bean and injecting the
+ * #alertParameters
+ */
+ public void internalInit() {}
+
/**
* This method is called when the alert notification that uses this backing bean
* is removed, so that the backing bean can do some cleanup work
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
index 98fa0e9..dc41f01 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
@@ -67,19 +67,32 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
log.info("new " + hashCode());
}
- @Create
- public void init() {
- log.info("init");
+ @Override
+ public void internalInit() {
+/* log.info("internalInit");
+ try {
+ getResId();
+ getResourceName();
+ obtainOperationIds();
+ getOperationId();
+ lookupConfiguration();
+ }
+ catch (Throwable t) {
+ t.printStackTrace();
+ }*/
}
+
@Override
public void internalCleanup() {
+ log.info("internalCleanup");
PropertySimple parameterConfigProp = alertParameters.getSimple(OperationsSender.PARAMETERS_CONFIG);
if (parameterConfigProp!=null) {
Integer paramId = parameterConfigProp.getIntegerValue();
if (paramId!=null) {
ConfigurationManagerLocal cmgr = LookupUtil.getConfigurationManager();
cmgr.deleteConfigurations(Arrays.asList(paramId));
+ cleanProperty(alertParameters,OperationsSender.PARAMETERS_CONFIG);
}
}
}
@@ -92,6 +105,8 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
persistProperty(alertParameters, OperationsSender.RESOURCE_ID,resId);
cleanProperty(alertParameters,OperationsSender.OPERATION_ID);
cleanProperty(alertParameters,OperationsSender.USABLE);
+ operationIds = new HashMap<String,Integer>(); // Clean out operations dropdown
+ operationId = null;
}
@@ -116,25 +131,25 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
private void lookupConfiguration() {
-// log.info("getCD: " + configurationDefinition);
try {
// Subject subject = EnterpriseFacesContextUtility.getSubject();
Subject subject = LookupUtil.getSubjectManager().getOverlord(); // TODO replace with real subject
-// int operationId = Integer.valueOf(FacesContextUtility.getRequiredRequestParameter("opId"));
OperationManagerLocal opMan = LookupUtil.getOperationManager();
obtainOperationIds();
- OperationDefinition operationDefinition = opMan.getOperationDefinition(subject, operationId);
- configurationDefinition = operationDefinition.getParametersConfigurationDefinition();
+ if (operationId!=null) {
+ OperationDefinition operationDefinition = opMan.getOperationDefinition(subject, operationId);
+ configurationDefinition = operationDefinition.getParametersConfigurationDefinition();
- // call a SLSB method to get around lazy initialization of configDefs and configTemplates
- ConfigurationManagerLocal configurationManager = LookupUtil.getConfigurationManager();
- configuration = configurationManager.getConfigurationFromDefaultTemplate(configurationDefinition);
-// Configuration newConfiguration = configuration.deepCopy(false);
-log.info("gConfig: " + configuration + ", " + configuration.hashCode() + ", " + configuration.getSimpleValue("detailedDiscovery","-unset-"));
+ // call a SLSB method to get around lazy initialization of configDefs and configTemplates
+ ConfigurationManagerLocal configurationManager = LookupUtil.getConfigurationManager();
+ configuration = configurationManager.getConfigurationFromDefaultTemplate(configurationDefinition);
+ // Configuration newConfiguration = configuration.deepCopy(false);
+ log.info("lookupConfiguration: " + configuration + ", " + configuration.hashCode() );
+ }
} catch (Exception e) {
e.printStackTrace();
}
commit f944f3d58c4d7719ea075429faa1dc938737ecf1
Author: James Livingston <jlivings(a)redhat.com>
Date: Fri Feb 26 10:53:48 2010 +0100
BZ 560859 - Add mechanism to enable/disable alert definitions for multiple resources
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/subsystem/SubsystemAlertDefinitionUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/subsystem/SubsystemAlertDefinitionUIBean.java
index 5831f3e..2e8d49c 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/subsystem/SubsystemAlertDefinitionUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/subsystem/SubsystemAlertDefinitionUIBean.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
+ * Copyright (C) 2005-2010 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -73,13 +73,13 @@ public class SubsystemAlertDefinitionUIBean extends SubsystemView {
private SelectItem[] categoryFilterItems;
private IntExtractor<AlertDefinitionComposite> RESOURCE_ID_EXTRACTOR = new IntExtractor<AlertDefinitionComposite>() {
-
+
public int extract(AlertDefinitionComposite object) {
Resource resource = object.getAlertDefinition().getResource();
return resource == null ? 0 : resource.getId();
}
};
-
+
public SubsystemAlertDefinitionUIBean() {
datePattern = EnterpriseFacesContextUtility.getWebUser().getWebPreferences().getDateTimeDisplayPreferences()
.getDateTimeFormatTrigger();
@@ -178,6 +178,84 @@ public class SubsystemAlertDefinitionUIBean extends SubsystemView {
return "success";
}
+ public String disableSelected() {
+ Integer[] selected = getSelectedItems();
+
+ try {
+ Subject subject = getSubject();
+
+ List<Integer> resourceDefinitions = new ArrayList<Integer>();
+ List<Integer> groupDefinitions = new ArrayList<Integer>();
+ List<Integer> typeDefinitions = new ArrayList<Integer>();
+
+ for (Integer definitionId : selected) {
+ if (alertDefinitionManager.isTemplate(definitionId)) {
+ typeDefinitions.add(definitionId);
+ } else if (alertDefinitionManager.isGroupAlertDefinition(definitionId)) {
+ groupDefinitions.add(definitionId);
+ } else {
+ resourceDefinitions.add(definitionId);
+ }
+ }
+
+ // delete resources first
+ alertDefinitionManager.disableAlertDefinitions(subject, resourceDefinitions
+ .toArray(new Integer[resourceDefinitions.size()]));
+
+ // then delete templates and group alert defs, which are both tolerant of missing child definitions
+ groupAlertDefinitionManager.disableGroupAlertDefinitions(subject, groupDefinitions
+ .toArray(new Integer[groupDefinitions.size()]));
+ alertTemplateManager.removeAlertTemplates(subject, typeDefinitions.toArray(new Integer[typeDefinitions
+ .size()]));
+
+ FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Disable selected alert definitions.");
+ } catch (Exception e) {
+ FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Failed to disable selected alert definitions.",
+ e);
+ }
+
+ return "success";
+ }
+
+ public String enableSelected() {
+ Integer[] selected = getSelectedItems();
+
+ try {
+ Subject subject = getSubject();
+
+ List<Integer> resourceDefinitions = new ArrayList<Integer>();
+ List<Integer> groupDefinitions = new ArrayList<Integer>();
+ List<Integer> typeDefinitions = new ArrayList<Integer>();
+
+ for (Integer definitionId : selected) {
+ if (alertDefinitionManager.isTemplate(definitionId)) {
+ typeDefinitions.add(definitionId);
+ } else if (alertDefinitionManager.isGroupAlertDefinition(definitionId)) {
+ groupDefinitions.add(definitionId);
+ } else {
+ resourceDefinitions.add(definitionId);
+ }
+ }
+
+ // delete resources first
+ alertDefinitionManager.enableAlertDefinitions(subject, resourceDefinitions
+ .toArray(new Integer[resourceDefinitions.size()]));
+
+ // then delete templates and group alert defs, which are both tolerant of missing child definitions
+ groupAlertDefinitionManager.enableGroupAlertDefinitions(subject, groupDefinitions
+ .toArray(new Integer[groupDefinitions.size()]));
+ alertTemplateManager.removeAlertTemplates(subject, typeDefinitions.toArray(new Integer[typeDefinitions
+ .size()]));
+
+ FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Enable selected alert definitions.");
+ } catch (Exception e) {
+ FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Failed to enable selected alert definitions.",
+ e);
+ }
+
+ return "success";
+ }
+
@Override
public DataModel getDataModel() {
if (dataModel == null) {
@@ -229,7 +307,7 @@ public class SubsystemAlertDefinitionUIBean extends SubsystemView {
protected IntExtractor<AlertDefinitionComposite> getResourceIdExtractor() {
return RESOURCE_ID_EXTRACTOR;
}
-
+
private void getDataFromRequest() {
SubsystemAlertDefinitionUIBean outer = SubsystemAlertDefinitionUIBean.this;
outer.resourceFilter = FacesContextUtility.getOptionalRequestParameter(FORM_PREFIX + "resourceFilter");
@@ -255,4 +333,4 @@ public class SubsystemAlertDefinitionUIBean extends SubsystemView {
return null;
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/subsystem/alertDefinitions.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/subsystem/alertDefinitions.xhtml
index 2cc9a52..a1caee7 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/subsystem/alertDefinitions.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/subsystem/alertDefinitions.xhtml
@@ -189,7 +189,7 @@
<f:param name="ad" value="#{item.original.alertDefinition.parentId}"/>
<h:outputText value="View Template" />
</h:outputLink>
-
+
<h:outputLink value="/alerts/Config.do" rendered="#{not empty item.original.alertDefinition.groupAlertDefinition}">
<f:param name="mode" value="viewRoles"/>
<f:param name="groupId" value="#{item.original.alertDefinition.groupAlertDefinition.resourceGroup.id}"/>
@@ -197,8 +197,8 @@
<f:param name="ad" value="#{item.original.alertDefinition.groupAlertDefinition.id}"/>
<h:outputText value="View Group Definition" />
</h:outputLink>
-
- <h:outputText value="N/A"
+
+ <h:outputText value="N/A"
rendered="#{item.original.alertDefinition.parentId eq 0 and empty item.original.alertDefinition.groupAlertDefinition}" />
</rich:column>
@@ -208,6 +208,12 @@
<onc:selectCommandButton action="#{SubsystemAlertDefinitionUIBean.deleteSelected}"
value="DELETE SELECTED" target="selectedItems" styleClass="on-pager-button buttonsmall"
rendered="#{GlobalPermissionsUIBean.superuser}" />
+ <onc:selectCommandButton action="#{SubsystemAlertDefinitionUIBean.disableSelected}"
+ value="DISABLE SELECTED" target="selectedItems" styleClass="on-pager-button buttonsmall"
+ rendered="#{GlobalPermissionsUIBean.superuser}" />
+ <onc:selectCommandButton action="#{SubsystemAlertDefinitionUIBean.enableSelected}"
+ value="ENABLE SELECTED" target="selectedItems" styleClass="on-pager-button buttonsmall"
+ rendered="#{GlobalPermissionsUIBean.superuser}" />
<ui:param name="paginationDataTableName" value="alertDefinitionDataTable"/>
<ui:param name="paginationDataModel" value="#{alertDefinitionDataModel}"/>
commit c06cf9c470abf7d8c1bfff7b9969ce68de607105
Author: Justin Harris <jharris(a)redhat.com>
Date: Thu Feb 25 16:28:03 2010 -0500
BZ 562816 - Fixed lazy init excepion by going through entity manager directly instead of using the alert definition manager.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertUIBean.java
index f3d97c3..b0d92d4 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertUIBean.java
@@ -22,21 +22,15 @@ package org.rhq.enterprise.gui.alert;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
+import javax.persistence.EntityManager;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.In;
-import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.faces.FacesMessages;
-import org.jboss.seam.log.Log;
import org.rhq.core.domain.alert.AlertCondition;
import org.rhq.core.domain.alert.AlertDampening;
import org.rhq.core.domain.alert.AlertDefinition;
-import org.rhq.core.domain.auth.Subject;
-import org.rhq.enterprise.server.alert.AlertDefinitionManagerLocal;
-import org.rhq.enterprise.server.alert.AlertDefinitionUpdateException;
-import org.rhq.enterprise.server.alert.InvalidAlertDefinitionException;
/**
*
@@ -46,18 +40,12 @@ import org.rhq.enterprise.server.alert.InvalidAlertDefinitionException;
@Name("alertUIBean")
public class AlertUIBean implements Serializable {
- @Logger
- private Log log;
- @In("#{webUser.subject}")
- private Subject subject;
- @In
- private FacesMessages facesMessages;
@In
private AlertDescriber alertDescriber;
@In
- private AlertDefinitionManagerLocal alertDefinitionManager;
- @In
private AlertDefinition alertDefinition;
+ @In
+ private EntityManager entityManager;
private List<String> alertConditions;
private String alertDampening;
@@ -78,16 +66,8 @@ public class AlertUIBean implements Serializable {
}
public String saveAlertDefinition() {
- try {
- alertDefinitionManager.updateAlertDefinition(this.subject,
- this.alertDefinition.getId(), this.alertDefinition, false);
- } catch (InvalidAlertDefinitionException e) {
- facesMessages.add("There was an error finding the requested alert definition.");
- log.error("Invalid alert definition: " + this.alertDefinition.toSimpleString(), e);
- } catch (AlertDefinitionUpdateException e) {
- facesMessages.add("There was an error updating the definition for " + this.alertDefinition.getName());
- log.error("Error updating alert definition: " + this.alertDefinition.toSimpleString(), e);
- }
+ AlertDefinition def = entityManager.merge(this.alertDefinition);
+ entityManager.persist(def);
return null;
}
commit 2a18d950b525c722a947803b158bc885d82ecec6
Author: Justin Harris <jharris(a)redhat.com>
Date: Thu Feb 25 12:24:48 2010 -0500
Changing ui:composition to ui:decorate to get page title working properly.
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/viewAlert.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/viewAlert.xhtml
index 2e9cc8b..eec04d4 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/viewAlert.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/viewAlert.xhtml
@@ -27,7 +27,7 @@
</c:otherwise>
</c:choose>
- <ui:composition template="/rhq/layout/main.xhtml">
+ <ui:decorate template="/rhq/layout/main.xhtml">
<ui:param name="pageTitle" value="#{title}"/>
@@ -272,5 +272,5 @@
</rich:modalPanel>
</ui:define>
- </ui:composition>
+ </ui:decorate>
</html>
14 years, 2 months
[rhq] Branch 'alertPlugin' - 4 commits - modules/enterprise
by Heiko W. Rupp
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java | 9 +--
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java | 18 ++++++
modules/enterprise/server/plugins/alert-operations/src/main/token2confluence.xsl | 28 ++++++++++
modules/enterprise/server/plugins/alert-operations/token2confluence.xsl | 22 -------
4 files changed, 50 insertions(+), 27 deletions(-)
New commits:
commit d882f2088e1f27d64376550e1b984cf33fcd2923
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Mar 2 15:04:05 2010 +0100
Prevent NPE
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
index e5684d2..c3eda0e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
@@ -2129,7 +2129,8 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
resourceId = parent.getId();
}
parent = getParentResource(resourceId);
- int parentId = parent.getId();
+ if (parent==null)
+ break;
if (parent.getResourceType().getCategory().equals(ResourceCategory.PLATFORM)){
resource = parent;
parent = null;
@@ -2177,7 +2178,7 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
//we can't assume the ordering of the provided results and the disambiguation query results
//will be the same.
-
+
//this list contains the resulting reports in the same order as the original results
List<MutableDisambiguationReport<T>> reports = new ArrayList<MutableDisambiguationReport<T>>(results.size());
@@ -2267,7 +2268,7 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
String parentName = (String) parentsResult[2 * i + 2];
parents.add(new ResourceParentFlyweight(parentId, parentName));
}
-
+
//update all the reports that correspond to this resourceId
for(MutableDisambiguationReport<T> report : reportsByResourceId.get(resourceId)) {
report.typeName = typeName;
@@ -2282,7 +2283,7 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
for (MutableDisambiguationReport<T> report : reports) {
resolution.add(report.getReport());
}
-
+
return new ResourceNamesDisambiguationResult<T>(resolution, typeResolutionNeeded, parentResolutionNeeded,
pluginResolutionNeeded);
}
commit 53f788862170e0bd8e837d4da6996d3fdff796da
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Mar 2 11:40:09 2010 +0100
Move to a better place in the file hierarchy
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/token2confluence.xsl b/modules/enterprise/server/plugins/alert-operations/src/main/token2confluence.xsl
new file mode 100644
index 0000000..1d1a2d9
--- /dev/null
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/token2confluence.xsl
@@ -0,0 +1,28 @@
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:output method="text" indent="no" xml:space="default"/>
+ <xsl:strip-space elements="*"/>
+
+ <xsl:template match="/">
+h2. Tokens for alert-operations sender
+
+Those tokens can be used in operation definition properties like
+'tokenclass.token' e.g. "alert.id" or "resource.name"
+ <xsl:apply-templates />
+ </xsl:template>
+
+ <xsl:template match="tokenClass">
+h3. *Token Class '<xsl:value-of select="@name"/>'* <xsl:value-of select="@description"/>
+ <xsl:apply-templates >
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
+ </xsl:template>
+
+ <xsl:template match="token">
+* *<xsl:value-of select="@name"/>*: _<xsl:value-of select="descr"/>_<xsl:text/>
+ </xsl:template>
+
+ <xsl:template match="fullName"/>
+ <xsl:template match="descr"/>
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl b/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl
deleted file mode 100644
index 1d1a2d9..0000000
--- a/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl
+++ /dev/null
@@ -1,28 +0,0 @@
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-
- <xsl:output method="text" indent="no" xml:space="default"/>
- <xsl:strip-space elements="*"/>
-
- <xsl:template match="/">
-h2. Tokens for alert-operations sender
-
-Those tokens can be used in operation definition properties like
-'tokenclass.token' e.g. "alert.id" or "resource.name"
- <xsl:apply-templates />
- </xsl:template>
-
- <xsl:template match="tokenClass">
-h3. *Token Class '<xsl:value-of select="@name"/>'* <xsl:value-of select="@description"/>
- <xsl:apply-templates >
- <xsl:sort select="@name"/>
- </xsl:apply-templates>
- </xsl:template>
-
- <xsl:template match="token">
-* *<xsl:value-of select="@name"/>*: _<xsl:value-of select="descr"/>_<xsl:text/>
- </xsl:template>
-
- <xsl:template match="fullName"/>
- <xsl:template match="descr"/>
-
-</xsl:stylesheet>
\ No newline at end of file
commit 00727947b1936074c04a13d0d6c4d34ab1233e60
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Mar 2 11:39:41 2010 +0100
Add an option to specify an output file.
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
index 7b2d7ff..a51f2fb 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
@@ -18,6 +18,11 @@
*/
package org.rhq.enterprise.server.plugins.alertOperations;
+import java.io.BufferedOutputStream;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
import java.util.EnumSet;
import java.util.Set;
@@ -35,9 +40,20 @@ public class PrintTokens {
public static void main(String[] args) throws Exception {
+ OutputStream out;
+ if (args.length==0)
+ out = new BufferedOutputStream(System.out);
+ else {
+ File file = new File(args[0]);
+ System.err.println("writing to " + file.getAbsolutePath());
+ out = new BufferedOutputStream(new FileOutputStream(file));
+ }
+
String text = createTokenDescription();
- System.out.println(text);
+ out.write(text.getBytes());
+ out.flush();
+ out.close();
}
/**
commit ada3ff33262675a7fd00298f078608aae0559a2e
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Mar 2 10:03:24 2010 +0100
Optimization of the style sheet
diff --git a/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl b/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl
index 8a2b14f..1d1a2d9 100644
--- a/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl
+++ b/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl
@@ -1,19 +1,25 @@
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="no" xml:space="default"/>
+ <xsl:strip-space elements="*"/>
<xsl:template match="/">
h2. Tokens for alert-operations sender
+
+Those tokens can be used in operation definition properties like
+'tokenclass.token' e.g. "alert.id" or "resource.name"
<xsl:apply-templates />
</xsl:template>
<xsl:template match="tokenClass">
-h3. *<xsl:value-of select="@name"/>*: <xsl:value-of select="@description"/>
- <xsl:apply-templates/>
+h3. *Token Class '<xsl:value-of select="@name"/>'* <xsl:value-of select="@description"/>
+ <xsl:apply-templates >
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
</xsl:template>
<xsl:template match="token">
-* *<xsl:value-of select="@name"/>*: _<xsl:value-of select="descr"/>_
+* *<xsl:value-of select="@name"/>*: _<xsl:value-of select="descr"/>_<xsl:text/>
</xsl:template>
<xsl:template match="fullName"/>
14 years, 2 months
[rhq] Branch 'bundle' - modules/common modules/enterprise
by mazz
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java | 7 +
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java | 38 +++---
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java | 37 ++++++
modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java | 59 ++++++++--
modules/enterprise/server/plugins/filetemplate-bundle/src/main/java/org/rhq/enterprise/server/plugins/filetemplate/BundleServerPluginComponent.java | 18 ++-
5 files changed, 128 insertions(+), 31 deletions(-)
New commits:
commit dd4632701533ece8302da44595ef1dc6c2a1fdd4
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Mar 1 17:12:54 2010 -0500
start parsing replacement variables
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
index 029222b..26d1b82 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
@@ -26,6 +26,10 @@ package org.rhq.bundle.filetemplate.recipe;
import gnu.getopt.Getopt;
import gnu.getopt.LongOpt;
+/**
+ * @deprecated I think this command will not be used - probably should delete it
+ * @author mazz
+ */
public class ConfigdefRecipeCommand implements RecipeCommand {
public String getName() {
@@ -67,7 +71,8 @@ public class ConfigdefRecipeCommand implements RecipeCommand {
throw new IllegalArgumentException("Missing the -f argument to indicate what the config def filename is");
}
- context.setConfigurationDefinitionFilename(filename);
+ // TODO: what to do? can I delete this command entirely?
+
return;
}
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
index 92c204e..c895107 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
@@ -24,7 +24,9 @@
package org.rhq.bundle.filetemplate.recipe;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
/**
* Contains information that is gleened from a recipe after it is parsed.
@@ -34,13 +36,13 @@ import java.util.Map;
public class RecipeContext {
private final String recipe;
- private String configurationDefinitionFilename;
- private Map<String, String> deployFiles;
+ private final Map<String, String> deployFiles;
+ private final Set<String> replacementVariables;
public RecipeContext(String recipe) {
this.recipe = recipe;
- this.configurationDefinitionFilename = null;
this.deployFiles = new HashMap<String, String>();
+ this.replacementVariables = new HashSet<String>();
}
/**
@@ -49,21 +51,7 @@ public class RecipeContext {
* @return the actual recipe text
*/
public String getRecipe() {
- return recipe;
- }
-
- /**
- * A recipe can have an optional configuration definition file associated with it.
- * If this returns non-<code>null</code>, it refers to this configuration definition file.
- *
- * @return config def filename
- */
- public String getConfigurationDefinitionFilename() {
- return configurationDefinitionFilename;
- }
-
- public void setConfigurationDefinitionFilename(String filename) {
- this.configurationDefinitionFilename = filename;
+ return this.recipe;
}
/**
@@ -79,4 +67,18 @@ public class RecipeContext {
public void addDeployFile(String filename, String directory) {
this.deployFiles.put(filename, directory);
}
+
+ /**
+ * The names of all replacement variables that are found in the recipe.
+ *
+ * @return the replacement variables
+ */
+ public Set<String> getReplacementVariables() {
+ return this.replacementVariables;
+ }
+
+ public void addReplacementVariables(Set<String> replacementVariables) {
+ this.replacementVariables.addAll(replacementVariables);
+ }
+
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
index b52e807..df797f4 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
@@ -30,8 +30,12 @@ import java.io.StreamTokenizer;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Parses the file template recipe.
@@ -42,6 +46,12 @@ import java.util.Map;
public class RecipeParser {
private Map<String, RecipeCommand> recipeCommands;
+ // note that we use the same as the core util's template engine
+ // the native system replacement variable prefix is used by the agent-side fact variable names
+ private final Pattern replacementVariableDeclarationPattern = Pattern.compile("<%\\s*(\\w+\\.?)+\\s*%>");
+ private final Pattern replacementVariableNamePattern = Pattern.compile("(\\w+\\.?)+");
+ private final String systemReplacementVariablePrefix = "rhq.system.";
+
public RecipeParser() {
setupRecipeCommands();
}
@@ -74,7 +84,13 @@ public class RecipeParser {
throw new Exception("Unknown command in recipe: " + commandName);
}
+ Set<String> replacementVars = getReplacementVariables(line);
+ if (replacementVars != null) {
+ context.addReplacementVariables(replacementVars);
+ }
+
recipeCommand.parse(context, arguments);
+
return;
}
@@ -90,6 +106,27 @@ public class RecipeParser {
}
}
+ private Set<String> getReplacementVariables(String cmdLine) {
+ Set<String> replacementVariables = null;
+ Matcher matcher = this.replacementVariableDeclarationPattern.matcher(cmdLine);
+ while (matcher.find()) {
+ String replacementDeclaration = matcher.group();
+ Matcher matcherInner = this.replacementVariableNamePattern.matcher(replacementDeclaration);
+ if (!matcherInner.find()) {
+ throw new IllegalArgumentException("Bad replacement declaration [" + replacementDeclaration + "]");
+ }
+ String replacementVariable = matcherInner.group();
+ if (!replacementVariable.startsWith(this.systemReplacementVariablePrefix)) {
+ if (replacementVariables == null) {
+ replacementVariables = new HashSet<String>(1);
+ }
+ replacementVariables.add(replacementVariable);
+ }
+ }
+
+ return replacementVariables;
+ }
+
private String[] splitCommandLine(String cmdLine) {
ByteArrayInputStream in = new ByteArrayInputStream(cmdLine.getBytes());
StreamTokenizer strtok = new StreamTokenizer(new InputStreamReader(in));
diff --git a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
index d573072..7d58b88 100644
--- a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
+++ b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
@@ -23,6 +23,8 @@
package org.rhq.bundle.filetemplate.recipe;
+import java.util.Map;
+
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -35,14 +37,49 @@ public class RecipeParserTest {
cleanRecipe();
}
+ public void testSimpleRecipeReplacementVariables() throws Exception {
+ addRecipeCommand("# <% ignored.inside.comment %>");
+ addRecipeCommand("deploy -f jboss.tar -d \"<% opt.dir %>/jboss\"");
+ addRecipeCommand("deploy -f tomcat.tar -d <%opt.dir%>/tomcat");
+ addRecipeCommand("deploy -f jboss.zip -d <%rhq.system.hostname%>/opt/tomcat"); // this is ignored, its an agent fact variable
+ RecipeParser parser = new RecipeParser();
+ RecipeContext context = parser.parseRecipe(getRecipe());
+ Map<String, String> files = context.getDeployFiles();
+ assert files.containsKey("jboss.tar") : files;
+ assert files.get("jboss.tar").equals("<% opt.dir %>/jboss") : files;
+ assert files.containsKey("tomcat.tar") : files;
+ assert files.get("tomcat.tar").equals("<%opt.dir%>/tomcat") : files;
+ assert files.containsKey("jboss.zip") : files;
+ assert files.get("jboss.zip").equals("<%rhq.system.hostname%>/opt/tomcat") : files;
+ assert context.getReplacementVariables().contains("opt.dir") : context.getReplacementVariables();
+ assert context.getReplacementVariables().size() == 1 : context.getReplacementVariables();
+ }
+
public void testSimpleRecipe() throws Exception {
addRecipeCommand("deploy -f jboss.tar -d /opt/jboss");
- addRecipeCommand("configdef -f config.xml");
+ addRecipeCommand("deploy -f tomcat.tar -d /opt/tomcat");
+ RecipeParser parser = new RecipeParser();
+ RecipeContext context = parser.parseRecipe(getRecipe());
+ Map<String, String> files = context.getDeployFiles();
+ assert files.containsKey("jboss.tar") : files;
+ assert files.get("jboss.tar").equals("/opt/jboss") : files;
+ assert files.containsKey("tomcat.tar") : files;
+ assert files.get("tomcat.tar").equals("/opt/tomcat") : files;
+ }
+
+ public void testSimpleRecipeWithQuotes() throws Exception {
+ addRecipeCommand("deploy -f jboss1.zip -d \"/opt/jboss1\"");
+ addRecipeCommand("deploy -f jboss.tar --directory='/opt/jboss'");
+ addRecipeCommand("deploy -f tomcat.tar \"--directory=/opt/tomcat\"");
RecipeParser parser = new RecipeParser();
RecipeContext context = parser.parseRecipe(getRecipe());
- assert context.getConfigurationDefinitionFilename().equals("config.xml");
- assert context.getDeployFiles().containsKey("jboss.tar");
- assert context.getDeployFiles().get("jboss.tar").equals("/opt/jboss");
+ Map<String, String> files = context.getDeployFiles();
+ assert files.containsKey("jboss1.zip") : files;
+ assert files.get("jboss1.zip").equals("/opt/jboss1") : files;
+ assert files.containsKey("jboss.tar") : files;
+ assert files.get("jboss.tar").equals("'/opt/jboss'") : files;
+ assert files.containsKey("tomcat.tar") : files;
+ assert files.get("tomcat.tar").equals("/opt/tomcat") : files;
}
public void testSimpleRecipeError() throws Exception {
@@ -57,11 +94,11 @@ public class RecipeParserTest {
}
cleanRecipe();
- addRecipeCommand("configdef");
+ addRecipeCommand("deploy -d /opt/jboss");
try {
parser.parseRecipe(getRecipe());
- assert false : "This should have failed - need to provide a -f to the configdef command";
+ assert false : "This should have failed - need to provide a -f to the deploy command";
} catch (Exception ok) {
// to be expected
}
@@ -75,16 +112,18 @@ public class RecipeParserTest {
addRecipeCommand("");
addRecipeCommand("#");
addRecipeCommand("### comment here");
- addRecipeCommand("configdef -f config.xml");
+ addRecipeCommand("deploy -f tomcat.tar -d /opt/tomcat");
addRecipeCommand("");
addRecipeCommand("#");
addRecipeCommand("### comment here");
addRecipeCommand("");
RecipeParser parser = new RecipeParser();
RecipeContext context = parser.parseRecipe(getRecipe());
- assert context.getConfigurationDefinitionFilename().equals("config.xml");
- assert context.getDeployFiles().containsKey("jboss.tar");
- assert context.getDeployFiles().get("jboss.tar").equals("/opt/jboss");
+ Map<String, String> files = context.getDeployFiles();
+ assert files.containsKey("jboss.tar") : files;
+ assert files.get("jboss.tar").equals("/opt/jboss") : files;
+ assert files.containsKey("tomcat.tar") : files;
+ assert files.get("tomcat.tar").equals("/opt/tomcat") : files;
}
private void cleanRecipe() {
diff --git a/modules/enterprise/server/plugins/filetemplate-bundle/src/main/java/org/rhq/enterprise/server/plugins/filetemplate/BundleServerPluginComponent.java b/modules/enterprise/server/plugins/filetemplate-bundle/src/main/java/org/rhq/enterprise/server/plugins/filetemplate/BundleServerPluginComponent.java
index a67fc1a..147f2a5 100644
--- a/modules/enterprise/server/plugins/filetemplate-bundle/src/main/java/org/rhq/enterprise/server/plugins/filetemplate/BundleServerPluginComponent.java
+++ b/modules/enterprise/server/plugins/filetemplate-bundle/src/main/java/org/rhq/enterprise/server/plugins/filetemplate/BundleServerPluginComponent.java
@@ -19,6 +19,8 @@
package org.rhq.enterprise.server.plugins.filetemplate;
+import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
@@ -29,6 +31,8 @@ import org.rhq.bundle.filetemplate.recipe.RecipeParser;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
+import org.rhq.core.domain.configuration.definition.PropertySimpleType;
import org.rhq.enterprise.server.bundle.RecipeParseResults;
import org.rhq.enterprise.server.plugin.pc.ControlFacet;
import org.rhq.enterprise.server.plugin.pc.ControlResults;
@@ -68,9 +72,19 @@ public class BundleServerPluginComponent implements ServerPluginComponent, Bundl
RecipeParser parser = new RecipeParser();
RecipeContext parserContext = parser.parseRecipe(recipe);
- // TODO convert the context into the proper data that the parse results wants
+ Set<String> bundleFileNames = new HashSet<String>();
+ Map<String, String> deployFiles = deployFiles = parserContext.getDeployFiles();
+ bundleFileNames.addAll(deployFiles.keySet());
+
ConfigurationDefinition configDef = null;
- Set<String> bundleFileNames = null;
+ if (parserContext.getReplacementVariables() != null) {
+ configDef = new ConfigurationDefinition("replacementVariables", null);
+ for (String replacementVar : parserContext.getReplacementVariables()) {
+ PropertyDefinitionSimple prop = new PropertyDefinitionSimple(replacementVar, null, false,
+ PropertySimpleType.STRING);
+ configDef.put(prop);
+ }
+ }
RecipeParseResults results = new RecipeParseResults(configDef, bundleFileNames);
return results;
14 years, 2 months
[rhq] Branch 'alertPlugin' - 2 commits - modules/enterprise
by Heiko W. Rupp
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/AlertTokenReplacer.java | 231 ++++++++++
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java | 10
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java | 16
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java | 18
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacer.java | 178 -------
modules/enterprise/server/plugins/alert-operations/src/test/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacementTest.java | 72 ++-
modules/enterprise/server/plugins/alert-operations/token2confluence.xsl | 22
modules/enterprise/server/plugins/alert-operations/tokens.xml | 137 +++++
8 files changed, 488 insertions(+), 196 deletions(-)
New commits:
commit a197c85ba3abdcf2e5bc6cf45a21f292f90ee6d3
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Mar 1 22:20:25 2010 +0100
Fix generated xml, provide a list of tokens and a way to translate them to confluence markup.
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
index 79ff62e..7b2d7ff 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
@@ -58,7 +58,7 @@ public class PrintTokens {
Set<Token> tokens = Token.getByTokenClass(tc);
for (Token token : tokens) {
builder.append(" <token name=\"").append(token.getName()).append(CLOSE);
- builder.append(" <fullName>").append(token.getText()).append(CLOSE);
+ builder.append(" <fullName>").append(token.getText()).append("</fullName>\n");
builder.append(" <descr>").append(token.getDescription()).append("</descr>\n");
builder.append(" </token>\n");
diff --git a/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl b/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl
new file mode 100644
index 0000000..8a2b14f
--- /dev/null
+++ b/modules/enterprise/server/plugins/alert-operations/token2confluence.xsl
@@ -0,0 +1,22 @@
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:output method="text" indent="no" xml:space="default"/>
+
+ <xsl:template match="/">
+h2. Tokens for alert-operations sender
+ <xsl:apply-templates />
+ </xsl:template>
+
+ <xsl:template match="tokenClass">
+h3. *<xsl:value-of select="@name"/>*: <xsl:value-of select="@description"/>
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="token">
+* *<xsl:value-of select="@name"/>*: _<xsl:value-of select="descr"/>_
+ </xsl:template>
+
+ <xsl:template match="fullName"/>
+ <xsl:template match="descr"/>
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/modules/enterprise/server/plugins/alert-operations/tokens.xml b/modules/enterprise/server/plugins/alert-operations/tokens.xml
new file mode 100644
index 0000000..2c29789
--- /dev/null
+++ b/modules/enterprise/server/plugins/alert-operations/tokens.xml
@@ -0,0 +1,137 @@
+<!-- this file was generated from the Token + TokenClass enums via PrintTokens tool -->
+<tokenClasses>
+ <tokenClass name="alert" description="Information about the alert itself">
+ <token name="willBeDisabled">
+ <fullName>alert.willBeDisabled</fullName>
+ <descr>Will the alert definition be disabled after firing?</descr>
+ </token>
+ <token name="id">
+ <fullName>alert.id</fullName>
+ <descr>The id of this particular alert</descr>
+ </token>
+ <token name="url">
+ <fullName>alert.url</fullName>
+ <descr>Url to the alert details page</descr>
+ </token>
+ <token name="name">
+ <fullName>alert.name</fullName>
+ <descr>Name from the defining alert definition</descr>
+ </token>
+ <token name="priority">
+ <fullName>alert.priority</fullName>
+ <descr>Priority of this alert</descr>
+ </token>
+ <token name="description">
+ <fullName>alert.description</fullName>
+ <descr>Description of this alert</descr>
+ </token>
+ <token name="firedAt">
+ <fullName>alert.firedAt</fullName>
+ <descr>Time the alert fired</descr>
+ </token>
+ <token name="conditions">
+ <fullName>alert.conditions</fullName>
+ <descr>A text representation of the conditions that led to this alert</descr>
+ </token>
+ <token name="willRecover">
+ <fullName>alert.willRecover</fullName>
+ <descr>?? TODO</descr>
+ </token>
+ </tokenClass>
+ <tokenClass name="resource" description="Information about the resource that triggered the alert">
+ <token name="id">
+ <fullName>resource.id</fullName>
+ <descr>Id of the resource</descr>
+ </token>
+ <token name="platformType">
+ <fullName>resource.platformType</fullName>
+ <descr>Type of the platform the resource is on</descr>
+ </token>
+ <token name="platformName">
+ <fullName>resource.platformName</fullName>
+ <descr>Name of the platform the resource is on</descr>
+ </token>
+ <token name="typeName">
+ <fullName>resource.typeName</fullName>
+ <descr>Resource type name</descr>
+ </token>
+ <token name="name">
+ <fullName>resource.name</fullName>
+ <descr>Name of the resource</descr>
+ </token>
+ <token name="platformId">
+ <fullName>resource.platformId</fullName>
+ <descr>Id of the platform the resource is on</descr>
+ </token>
+ <token name="parentName">
+ <fullName>resource.parentName</fullName>
+ <descr>Name of the parent resource</descr>
+ </token>
+ <token name="parentId">
+ <fullName>resource.parentId</fullName>
+ <descr>Id of the parent resource</descr>
+ </token>
+ <token name="typeId">
+ <fullName>resource.typeId</fullName>
+ <descr>Resource type id</descr>
+ </token>
+ </tokenClass>
+ <tokenClass name="targetResource" description="Information about the resource the alert is fired on ">
+ <token name="parentId">
+ <fullName>targetResource.parentId</fullName>
+ <descr>Id of the target's parent resource</descr>
+ </token>
+ <token name="platformName">
+ <fullName>targetResource.platformName</fullName>
+ <descr>Name of the platform the target resource is on</descr>
+ </token>
+ <token name="platformId">
+ <fullName>targetResource.platformId</fullName>
+ <descr>Id of the platform the target resource is on</descr>
+ </token>
+ <token name="parentName">
+ <fullName>targetResource.parentName</fullName>
+ <descr>Name of the target's parent resource</descr>
+ </token>
+ <token name="typeId">
+ <fullName>targetResource.typeId</fullName>
+ <descr>Resource type of the target resource id</descr>
+ </token>
+ <token name="platformType">
+ <fullName>targetResource.platformType</fullName>
+ <descr>Type of the platform the target resource is on</descr>
+ </token>
+ <token name="name">
+ <fullName>targetResource.name</fullName>
+ <descr>Name of the target resource</descr>
+ </token>
+ <token name="id">
+ <fullName>targetResource.id</fullName>
+ <descr>Id of the target resource</descr>
+ </token>
+ <token name="typeName">
+ <fullName>targetResource.typeName</fullName>
+ <descr>Resource type name of the target resource</descr>
+ </token>
+ </tokenClass>
+ <tokenClass name="operation" description="Information about the triggered operation">
+ <token name="id">
+ <fullName>operation.id</fullName>
+ <descr>Id of the operation fired</descr>
+ </token>
+ <token name="name">
+ <fullName>operation.name</fullName>
+ <descr>Name of the operation fired</descr>
+ </token>
+ </tokenClass>
+ <tokenClass name="test" description="Just some dummies for internal testing purposes">
+ <token name="echo">
+ <fullName>test.echo</fullName>
+ <descr>Echo the input</descr>
+ </token>
+ <token name="fix">
+ <fullName>test.fix</fullName>
+ <descr>Return a fixed string</descr>
+ </token>
+ </tokenClass>
+</tokenClasses>
commit 653e41c57c1fb6facc52ba3d22c20259f9717141
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Mar 1 21:47:17 2010 +0100
Support more tokens
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/AlertTokenReplacer.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/AlertTokenReplacer.java
new file mode 100644
index 0000000..e8c61dd
--- /dev/null
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/AlertTokenReplacer.java
@@ -0,0 +1,231 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.plugins.alertOperations;
+
+import java.util.Date;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.alert.Alert;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.operation.OperationDefinition;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.enterprise.server.alert.AlertManagerLocal;
+import org.rhq.enterprise.server.resource.ResourceManagerLocal;
+import org.rhq.enterprise.server.util.LookupUtil;
+
+/**
+ * Helper to replace tokens by their values
+ * @author Heiko W. Rupp
+ */
+public class AlertTokenReplacer {
+
+ private final Log log = LogFactory.getLog(AlertTokenReplacer.class);
+ public static final String NOT_YET_IMPLEMENTED = " - not yet implemented -";
+ protected static final String THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG = "TheQuickBrownFoxJumpsOverTheLazyDOg";
+ private Alert alert;
+ private Pattern pattern;
+ private OperationDefinition operationDefinition;
+ private Resource targetResource;
+
+ public AlertTokenReplacer(Alert alert, OperationDefinition operationDefinition, Resource targetResource) {
+ this.alert = alert;
+ this.operationDefinition = operationDefinition;
+ pattern = Pattern.compile("<%\\s*([a-z]+\\.[a-z0-9]+)\\s*%>");
+ }
+
+ /**
+ * Replace all tokens on the input line. If no tokens are found the input is returned.
+ * Tokens have the form '<i><% class.sub %></i>'
+ * @param input a line of text
+ * @return input with tokens replaced.
+ * @see org.rhq.enterprise.server.plugins.alertOperations.Token
+ * @see org.rhq.enterprise.server.plugins.alertOperations.TokenClass
+ */
+ public String replaceTokens(String input) {
+
+ String work = input;
+ Matcher matcher = pattern.matcher(work);
+ if (!matcher.find()) {
+ log.warn("No tokens found in " + input);
+ return input;
+ }
+ matcher.reset();
+
+ do {
+ matcher = pattern.matcher(work);
+ if (!matcher.find()) {
+ break;
+ }
+ String replacement = replaceToken(matcher.group(1) );
+ String s = matcher.replaceFirst(replacement);
+ work = s;
+
+ } while (true);
+
+ return work;
+ }
+
+
+
+ /**
+ * Replace the token string passed (without the token delimiters ) with the actual value
+ * @param tokenString Input like alert.id
+ * @return replacement string or the input if the token was not valid.
+ */
+ public String replaceToken(String tokenString) {
+
+ // Ok, we have at least one token. Now split the tokenString and loop over the tokens
+
+ if (!tokenString.contains("."))
+ return tokenString;
+
+ String tmp = tokenString.substring(0, tokenString.indexOf("."));
+ TokenClass tc = TokenClass.getByText(tmp);
+ if (tc==null) {
+ log.warn("Unknown token class in [" + tokenString + "], not replacing tokens");
+ return tokenString;
+ }
+
+ Token token = Token.getByText(tokenString);
+ if (token == null) {
+ log.warn("No known token found in [" + tokenString + "], not replacing token");
+ return tokenString;
+ }
+ String ret = null;
+ switch (tc) {
+ case ALERT:
+ ret = replaceAlertToken(token,alert);
+ break;
+ case RESOURCE:
+ ret = replaceResourceToken(token,alert.getAlertDefinition().getResource());
+ break;
+ case TARGET_RESOURCE:
+ // Create a "pseudo" token to feed it into the plain resource replacement code
+ String text = "resource." + token.getName();
+ Token tok = Token.getByText(text);
+ ret = replaceResourceToken(tok, targetResource);
+ break;
+ case OPERATION:
+ ret = replaceOperationToken(token);
+ break;
+ case TEST:
+ switch (token) {
+ case TEST_ECHO:
+ ret = tokenString;
+ break;
+ case TEST_FIX:
+ ret = THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG;
+ break;
+ default:
+ ret = NOT_YET_IMPLEMENTED;
+ }
+ break;
+ }
+ return ret;
+ }
+
+ private String replaceAlertToken(Token token, Alert alert) {
+
+ AlertManagerLocal mgr = LookupUtil.getAlertManager();
+
+ switch (token) {
+ case ALERT_ID:
+ return String.valueOf(alert.getId());
+ case ALERT_FIRE_TIME:
+ return new Date(alert.getCtime()).toString(); // TODO use a specific impl here?
+ case ALERT_WILL_RECOVER:
+ return String.valueOf(alert.getAlertDefinition().getWillRecover());
+ case ALERT_WILL_DISABLE:
+ return String.valueOf(mgr.willDefinitionBeDisabled(alert));
+ case ALERT_DEF_NAME:
+ return alert.getAlertDefinition().getName();
+ case ALERT_DEF_DESC:
+ return alert.getAlertDefinition().getDescription();
+ case ALERT_DEF_PRIO:
+ return alert.getAlertDefinition().getPriority().getName();
+ case ALERT_URL:
+ return mgr.prettyPrintAlertURL(alert);
+ case ALERT_CONDITIONS:
+ return mgr.prettyPrintAlertConditions(alert,false);
+
+
+ default:
+ return NOT_YET_IMPLEMENTED;
+ }
+
+ }
+
+ private String replaceResourceToken(Token token, Resource resource) {
+
+ ResourceManagerLocal mgr = LookupUtil.getResourceManager();
+ Subject overlord = LookupUtil.getSubjectManager().getOverlord();
+ Resource parent;
+ Resource platform = mgr.getPlaformOfResource(overlord,resource.getId());
+
+ switch (token) {
+ case RESOURCE_ID:
+ return String.valueOf(resource.getId());
+ case RESOURCE_NAME:
+ return resource.getName();
+ case RESOURCE_PARENT_ID:
+ parent = mgr.getParentResource(resource.getId());
+ if (parent==null)
+ return "0";
+ else
+ return String.valueOf(parent.getId());
+ case RESOURCE_PARENT_NAME:
+ parent = mgr.getParentResource(resource.getId());
+ if (parent==null)
+ return "0";
+ else
+ return String.valueOf(parent.getId());
+ case RESOURCE_TYPE_ID:
+ return String.valueOf(resource.getResourceType().getId());
+ case RESOURCE_TYPE_NAME:
+ return resource.getResourceType().getName();
+ case RESOURCE_PLATFORM_ID:
+ return String.valueOf(platform.getId());
+ case RESOURCE_PLATFORM_NAME:
+ return platform.getName();
+ case RESOURCE_PLATFORM_TYPE:
+ return platform.getResourceType().getName();
+
+ default:
+ return NOT_YET_IMPLEMENTED;
+ }
+ }
+
+ private String replaceOperationToken(Token token) {
+
+ switch (token) {
+ case OPERATION_ID:
+ return String.valueOf(operationDefinition.getId());
+ case OPERATION_NAME:
+ return operationDefinition.getName();
+
+
+ default:
+ return NOT_YET_IMPLEMENTED;
+ }
+ }
+}
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
index 4f6c88e..635085a 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
@@ -78,9 +78,11 @@ public class OperationsSender extends AlertSender {
Subject subject = LookupUtil.getSubjectManager().getOverlord(); // TODO get real subject
List<OperationDefinition> opdefs = opMgr.findSupportedResourceOperations(subject,resourceId,false);
- for (OperationDefinition opdef : opdefs ) {
- if (opdef.getId() == opId) {
- opName = opdef.getName();
+ OperationDefinition opDef = null;
+ for (OperationDefinition tmp : opdefs ) {
+ if (tmp.getId() == opId) {
+ opName = tmp.getName();
+ opDef = tmp;
break;
}
}
@@ -110,7 +112,7 @@ public class OperationsSender extends AlertSender {
if (parameters!=null && tokenMode.equals(INTERPRETED)) {
Map<String,PropertySimple> propsMap = parameters.getSimpleProperties();
if (!propsMap.isEmpty()) {
- TokenReplacer tr = new TokenReplacer(alert);
+ AlertTokenReplacer tr = new AlertTokenReplacer(alert, opDef, null);
for (PropertySimple prop : propsMap.values()) {
String tmp = prop.getStringValue();
tmp = tr.replaceTokens(tmp);
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
index 78ac850..79ff62e 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/PrintTokens.java
@@ -35,6 +35,17 @@ public class PrintTokens {
public static void main(String[] args) throws Exception {
+ String text = createTokenDescription();
+
+ System.out.println(text);
+ }
+
+ /**
+ * Do the work and return an xml structure that lists available token classes and
+ * tokens along with their descriptions.
+ * @return String with an XML representation of the available tokens
+ */
+ public static String createTokenDescription() {
EnumSet<TokenClass> tokenClasses = EnumSet.allOf(TokenClass.class);
StringBuilder builder = new StringBuilder("<tokenClasses>\n");
@@ -58,7 +69,6 @@ public class PrintTokens {
}
builder.append("</tokenClasses>\n");
-
- System.out.println(builder.toString());
+ return builder.toString();
}
}
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java
index e665bd4..2d810f0 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java
@@ -43,11 +43,25 @@ public enum Token {
// resource that triggered the alert related tokens
RESOURCE_ID(TokenClass.RESOURCE, "id", "Id of the resource"),
RESOURCE_NAME(TokenClass.RESOURCE, "name", "Name of the resource"),
+ RESOURCE_PARENT_ID(TokenClass.RESOURCE, "parentId", "Id of the parent resource"),
+ RESOURCE_PARENT_NAME(TokenClass.RESOURCE, "parentName", "Name of the parent resource"),
+ RESOURCE_TYPE_ID(TokenClass.RESOURCE,"typeId","Resource type id"),
+ RESOURCE_TYPE_NAME(TokenClass.RESOURCE,"typeName","Resource type name"),
+ RESOURCE_PLATFORM_ID(TokenClass.RESOURCE,"platformId", "Id of the platform the resource is on"),
+ RESOURCE_PLATFORM_NAME(TokenClass.RESOURCE,"platformName", "Name of the platform the resource is on"),
+ RESOURCE_PLATFORM_TYPE(TokenClass.RESOURCE,"platformType", "Type of the platform the resource is on"),
// resource the operation is run on related tokens
TRESOURCE_ID(TokenClass.TARGET_RESOURCE, "id","Id of the target resource"),
TRESOURCE_NAME(TokenClass.TARGET_RESOURCE, "name", "Name of the target resource"),
+ TRESOURCE_PARENT_ID(TokenClass.TARGET_RESOURCE, "parentId", "Id of the target's parent resource"),
+ TRESOURCE_PARENT_NAME(TokenClass.TARGET_RESOURCE, "parentName", "Name of the target's parent resource"),
+ TRESOURCE_TYPE_ID(TokenClass.TARGET_RESOURCE,"typeId","Resource type of the target resource id"),
+ TRESOURCE_TYPE_NAME(TokenClass.TARGET_RESOURCE,"typeName","Resource type name of the target resource"),
+ TRESOURCE_PLATFORM_ID(TokenClass.TARGET_RESOURCE,"platformId", "Id of the platform the target resource is on"),
+ TRESOURCE_PLATFORM_NAME(TokenClass.TARGET_RESOURCE,"platformName", "Name of the platform the target resource is on"),
+ TRESOURCE_PLATFORM_TYPE(TokenClass.TARGET_RESOURCE,"platformType", "Type of the platform the target resource is on"),
// Information about the fired operation
@@ -56,9 +70,7 @@ public enum Token {
// only for testing
TEST_ECHO(TokenClass.TEST,"echo", "Echo the input"),
- TEST_FIX(TokenClass.TEST,"fix", "Return a fixed string")
-
- ;
+ TEST_FIX(TokenClass.TEST,"fix", "Return a fixed string");
private TokenClass tc;
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacer.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacer.java
deleted file mode 100644
index 0b230b4..0000000
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacer.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2010 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.plugins.alertOperations;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.rhq.core.domain.alert.Alert;
-import org.rhq.core.domain.resource.Resource;
-
-/**
- * Helper to replace tokens by their values
- * @author Heiko W. Rupp
- */
-public class TokenReplacer {
-
- private final Log log = LogFactory.getLog(TokenReplacer.class);
- private static final String NOT_YET_IMPLEMENTED = " - not yet implemented -";
- protected static final String THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG = "TheQuickBrownFoxJumpsOverTheLazyDOg";
- private Alert alert;
- private Pattern pattern;
-
- public TokenReplacer(Alert alert) {
- this.alert = alert;
- pattern = Pattern.compile("<%\\s*([a-z]+\\.[a-z0-9]+)\\s*%>");
- }
-
- /**
- * Replace all tokens on the input line. If no tokens are found the input is returned.
- * Tokens have the form '<i><% class.sub %></i>'
- * @param input a line of text
- * @return input with tokens replaced.
- * @see org.rhq.enterprise.server.plugins.alertOperations.Token
- * @see org.rhq.enterprise.server.plugins.alertOperations.TokenClass
- */
- public String replaceTokens(String input) {
-
- String work = input;
- Matcher matcher = pattern.matcher(work);
- if (!matcher.find()) {
- log.warn("No tokens found in " + input);
- return input;
- }
- matcher.reset();
-
- do {
-// System.out.println(input);
- matcher = pattern.matcher(work);
- if (!matcher.find()) {
- break;
- }
-// System.out.println(matcher.regionStart() + ":" + matcher.regionEnd() + input.substring(matcher.regionStart(),matcher.regionEnd()));
-// System.out.println(matcher.group(1));
- String replacement = replaceToken(matcher.group(1) );
- String s = matcher.replaceFirst(replacement);
-// System.out.println(s);
- work = s;
-
-// System.out.println("----");
- } while (true);
-
- return work;
- }
-
-
-
- /**
- * Replace the token string passed (without the token delimiters ) with the actual value
- * @param tokenString Input like alert.id
- * @return replacement string or the input if the token was not valid.
- */
- public String replaceToken(String tokenString) {
-
- // Ok, we have at least one token. Now split the tokenString and loop over the tokens
-
- if (!tokenString.contains("."))
- return tokenString;
-
- String tmp = tokenString.substring(0, tokenString.indexOf("."));
- TokenClass tc = TokenClass.getByText(tmp);
- if (tc==null) {
- log.warn("Unknown token class in [" + tokenString + "], not replacing tokens");
- return tokenString;
- }
-
- Token token = Token.getByText(tokenString);
- if (token == null) {
- log.warn("No known token found in [" + tokenString + "], not replacing token");
- return tokenString;
- }
- String ret = null;
- switch (tc) {
- case ALERT:
- ret = replaceAlertToken(token,alert);
- break;
- case RESOURCE:
- ret = replaceResourceToken(token,alert.getAlertDefinition().getResource());
- break;
- case TARGET_RESOURCE:
- Resource resource = null; // TODO
- ret = replaceTargetResourceToken(token, resource);
- break;
- case TEST:
- switch (token) {
- case TEST_ECHO:
- ret = tokenString;
- break;
- case TEST_FIX:
- ret = THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG;
- break;
- default:
- ret = NOT_YET_IMPLEMENTED;
- }
- break;
- }
- return ret;
- }
-
- private String replaceAlertToken(Token token, Alert alert) {
-
- switch (token) {
- case ALERT_ID:
- return String.valueOf(alert.getId());
- case ALERT_URL:
- return NOT_YET_IMPLEMENTED;
-
- default:
- return NOT_YET_IMPLEMENTED;
- }
-
- }
-
- private String replaceResourceToken(Token token, Resource resource) {
-
- switch (token) {
- case RESOURCE_ID:
- return String.valueOf(resource.getId());
- case RESOURCE_NAME:
- return resource.getName();
-
- default:
- return NOT_YET_IMPLEMENTED;
- }
- }
-
- private String replaceTargetResourceToken(Token token, Resource resource) {
-
- switch (token) {
- case TRESOURCE_ID:
- return String.valueOf(resource.getId());
- case TRESOURCE_NAME:
- return resource.getName();
-
- default:
- return NOT_YET_IMPLEMENTED;
- }
- }
-
-}
diff --git a/modules/enterprise/server/plugins/alert-operations/src/test/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacementTest.java b/modules/enterprise/server/plugins/alert-operations/src/test/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacementTest.java
index f41fc85..cf6c48d 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/test/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacementTest.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/test/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacementTest.java
@@ -18,12 +18,15 @@
*/
package org.rhq.enterprise.server.plugins.alertOperations;
+import java.util.EnumSet;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.testng.annotations.Test;
import org.rhq.core.domain.alert.Alert;
import org.rhq.core.domain.alert.AlertDefinition;
+import org.rhq.core.domain.operation.OperationDefinition;
import org.rhq.core.domain.resource.Resource;
/**
@@ -42,17 +45,18 @@ public class TokenReplacementTest {
public void testSimpleReplacement() throws Exception {
Alert al = new Alert();
- TokenReplacer tr = new TokenReplacer(al);
+ AlertTokenReplacer tr = new AlertTokenReplacer(al, null, null);
String res = tr.replaceToken("test.fix");
assert res != null;
- assert res.equals(TokenReplacer.THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG);
+ assert res.equals(AlertTokenReplacer.THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG);
res = tr.replaceToken(TEST_ECHO);
assert res != null;
assert res.equals(TEST_ECHO);
+/*
res = tr.replaceToken("alert.id");
assert res != null;
assert res.equals("0");
@@ -62,18 +66,19 @@ public class TokenReplacementTest {
AlertDefinition def = new AlertDefinition();
def.setResource(r);
al = new Alert(def, System.currentTimeMillis());
- tr = new TokenReplacer(al);
+ tr = new AlertTokenReplacer(al, null, null);
res = tr.replaceToken("resource.id");
assert "1234".equals(res);
res = tr.replaceToken("resource.name");
assert "A resource".equals(res);
+*/
}
public void testInvalidTokenString() {
Alert al = new Alert();
- TokenReplacer tr = new TokenReplacer(al);
+ AlertTokenReplacer tr = new AlertTokenReplacer(al, null, null);
String res = tr.replaceToken(FOO_BAR);
@@ -93,13 +98,13 @@ public class TokenReplacementTest {
public void testFullTokenSimple() {
Alert al = new Alert();
- TokenReplacer tr = new TokenReplacer(al);
+ AlertTokenReplacer tr = new AlertTokenReplacer(al, null, null);
String res = tr.replaceTokens("<%test.fix%>");
assert res != null;
assert !res.equals("<%test.fix%>") : "Res was " + res;
- assert res.equals(TokenReplacer.THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG);
+ assert res.equals(AlertTokenReplacer.THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG);
String TF2 = "<% test.fix %>";
res = tr.replaceTokens(TF2);
@@ -120,16 +125,67 @@ public class TokenReplacementTest {
assert res != null;
assert res.equals(FOO_BAR) : "Res was " + res;
+/*
Resource r = new Resource(1234);
r.setName("A resource");
AlertDefinition def = new AlertDefinition();
def.setResource(r);
al = new Alert(def, System.currentTimeMillis());
- tr = new TokenReplacer(al);
+ tr = new AlertTokenReplacer(al, null, null);
res = tr.replaceTokens("<% test.fix%><%resource.id%>");
assert res!=null;
- assert res.equals(TokenReplacer.THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG+"1234");
+ assert res.equals(AlertTokenReplacer.THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG+"1234");
+*/
+ }
+
+ public void testOperationTokens() {
+ Resource r = new Resource(1234);
+ AlertDefinition def = new AlertDefinition();
+ def.setResource(r);
+ Alert al = new Alert(def, System.currentTimeMillis());
+
+ AlertTokenReplacer tr;
+ OperationDefinition opDef = new OperationDefinition(123,"helloOps",null,"This is a test",0,"Just testing");
+ tr = new AlertTokenReplacer(al,opDef, null);
+ String res = tr.replaceTokens("<%operation.id%>");
+ assert res!=null;
+ assert res.equals("123") : "Result is " + res;
+ res = tr.replaceTokens("<%operation.name%>");
+ assert res!=null;
+ assert res.equals("helloOps");
+ }
+
+ public void testTokenPrinter() {
+
+ String result = PrintTokens.createTokenDescription();
+ assert result != null;
+ assert !result.isEmpty();
+ assert result.contains("<token ");
}
+/*
+ public void testReplaceAllTokens() {
+
+ EnumSet<Token> tokens = EnumSet.allOf(Token.class);
+
+ Resource r = new Resource(1234);
+ AlertDefinition def = new AlertDefinition();
+ def.setResource(r);
+ Alert al = new Alert(def, System.currentTimeMillis());
+
+ AlertTokenReplacer tr;
+ OperationDefinition opDef = new OperationDefinition(123,"helloOps",null,"This is a test",0,"Just testing");
+ tr = new AlertTokenReplacer(al,opDef, null);
+
+ for (Token token : tokens) {
+
+ String input = "<%" + token.getText() + "%>";
+ String res = tr.replaceTokens(input);
+ assert res != null;
+ assert !res.isEmpty();
+ assert !res.equals(AlertTokenReplacer.NOT_YET_IMPLEMENTED) : "Replacement for token [" + token.getText() + "] is not implemented";
+ }
+ }
+*/
}
14 years, 2 months
[rhq] Branch 'raw-config' - modules/enterprise
by Adam Young
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ResourceConfigurationViewer.java | 12 +++++-----
1 file changed, 6 insertions(+), 6 deletions(-)
New commits:
commit 9fc4ed87c4f3b7e518cf983bb329993e90857a45
Author: Adam Young <ayoung(a)redhat.com>
Date: Mon Mar 1 16:18:06 2010 -0500
Added annotation that was mission in import.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ResourceConfigurationViewer.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ResourceConfigurationViewer.java
index 94b798b..05395ac 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ResourceConfigurationViewer.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ResourceConfigurationViewer.java
@@ -40,6 +40,7 @@ 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.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.AbstractResourceConfigurationUpdate;
@@ -147,13 +148,12 @@ public class ResourceConfigurationViewer {
ConfigurationManagerLocal configurationManager = LookupUtil.getConfigurationManager();
if (configId != null && usingPreviousVersion) {
- AbstractResourceConfigurationUpdate configurationUpdate =
- configurationManager.getResourceConfigurationUpdate(subject, configId);
+ AbstractResourceConfigurationUpdate configurationUpdate = configurationManager
+ .getResourceConfigurationUpdate(subject, configId);
resourceConfiguration = (configurationUpdate != null) ? configurationUpdate.getConfiguration() : null;
- }
- else {
- AbstractResourceConfigurationUpdate configurationUpdate =
- configurationManager.getLatestResourceConfigurationUpdate(subject, resourceId);
+ } else {
+ AbstractResourceConfigurationUpdate configurationUpdate = configurationManager
+ .getLatestResourceConfigurationUpdate(subject, resourceId);
resourceConfiguration = (configurationUpdate != null) ? configurationUpdate.getConfiguration() : null;
}
14 years, 2 months
[rhq] Branch 'raw-config' - 2 commits - modules/core modules/enterprise
by Adam Young
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java | 50 +-
modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ConfigurationValidationException.java | 39 ++
modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java | 41 +-
modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java | 29 -
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java | 186 ++++++----
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ResourceConfigurationEditor.java | 67 ++-
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ResourceConfigurationViewer.java | 71 +--
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/navigation/resource/ResourceSelectUIBean.java | 30 -
modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ResourceClientProxy.java | 108 ++---
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java | 34 -
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java | 137 -------
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java | 27 -
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java | 7
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java | 12
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java | 7
15 files changed, 406 insertions(+), 439 deletions(-)
New commits:
commit 140ad56fb391875220bbbbee377678bb0f1f4dec
Author: Adam Young <ayoung(a)redhat.com>
Date: Mon Mar 1 15:53:30 2010 -0500
Cleaning up the exception logic of Validate.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java
index cd5011f..3673a62 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/configuration/ConfigurationAgentService.java
@@ -1,30 +1,31 @@
- /*
- * 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, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
- *
- * 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 and the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
+/*
+ * 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, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * 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 and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
package org.rhq.core.clientapi.agent.configuration;
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.ConfigurationValidationException;
/**
* Interface to the plugin container for triggering configuration operations on the plugin's resources.
@@ -99,7 +100,6 @@ public interface ConfigurationAgentService {
Configuration merge(Configuration configuration, int resourceId, boolean fromStructured)
throws PluginContainerException;
-
/**
* If the <code>fromStructured</code> flag is <code>true</code>, then the s
* Configuration.properties</code>) is merged into the latest raw configura
@@ -118,7 +118,9 @@ public interface ConfigurationAgentService {
* If validation fails, it returns the configuration object with embedded messages
* @throws PluginContainerException
* @throws PluginContainerException if a runtime or plugin error occurs.
+ * @throws ConfigurationValidationException
*/
- Configuration validate(Configuration configuration, int resourceId, boolean isStructured) throws PluginContainerException;
+ void validate(Configuration configuration, int resourceId, boolean isStructured)
+ throws ConfigurationValidationException;
}
\ No newline at end of file
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ConfigurationValidationException.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ConfigurationValidationException.java
new file mode 100644
index 0000000..03628b7
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ConfigurationValidationException.java
@@ -0,0 +1,39 @@
+/*
+ * 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.core.domain.configuration;
+
+import java.util.Collections;
+import java.util.Map;
+
+public class ConfigurationValidationException extends RuntimeException {
+ private static final long serialVersionUID = -6924768743906659205L;
+
+ /**
+ * For Raw config, the key is the path to the raw config file
+ * For structured, the key is simply "structured"
+ * In the future, the key will be the same as the value returned from
+ * org.rhq.core.domain.configuration.Configuration.get(string)
+ */
+ public final Map<String, String> errors;
+
+ public ConfigurationValidationException(String reason, Map<String, String> errors) {
+ super(reason);
+ this.errors = Collections.unmodifiableMap(errors);
+ }
+}
\ No newline at end of file
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java
index b73cc65..15d3c2d 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java
@@ -22,7 +22,9 @@
*/
package org.rhq.core.pc.configuration;
+import java.util.HashMap;
import java.util.LinkedList;
+import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.Callable;
@@ -40,6 +42,7 @@ import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest;
import org.rhq.core.clientapi.server.configuration.ConfigurationServerService;
import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.ConfigurationValidationException;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.RawConfiguration;
import org.rhq.core.domain.resource.ResourceType;
@@ -53,9 +56,6 @@ import org.rhq.core.pc.util.FacetLockType;
import org.rhq.core.pc.util.LoggingThreadFactory;
import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet;
-import org.rhq.core.system.SystemInfoFactory;
-
-import org.rhq.core.util.exception.WrappedRemotingException;
/**
* Manages configuration of all resources across all plugins.
@@ -328,36 +328,47 @@ public class ConfigurationManager extends AgentService implements ContainerServi
return null;
}
- public Configuration validate(Configuration configuration, int resourceId, boolean isStructured)
- throws PluginContainerException {
+ public void validate(Configuration configuration, int resourceId, boolean isStructured)
+ throws ConfigurationValidationException {
boolean success = true;
boolean daemonOnly = true;
boolean onlyIfStarted = true;
- ResourceConfigurationFacet facet = componentService.getComponent(resourceId, ResourceConfigurationFacet.class,
- FacetLockType.READ, FACET_METHOD_TIMEOUT, daemonOnly, onlyIfStarted);
+ ResourceConfigurationFacet facet;
+ try {
+ facet = componentService.getComponent(resourceId, ResourceConfigurationFacet.class, FacetLockType.READ,
+ FACET_METHOD_TIMEOUT, daemonOnly, onlyIfStarted);
+ } catch (PluginContainerException e1) {
+ Map<String, String> errors = new HashMap<String, String>();
+ errors.put("structured", e1.getMessage());
+ throw new ConfigurationValidationException(e1.getMessage(), errors);
+ }
if (isStructured) {
try {
facet.validateStructuredConfiguration(configuration);
- } catch (IllegalArgumentException e) {
- success = false;
} catch (Throwable t) {
- throw new PluginContainerException(t.getMessage(), t);
+ Map<String, String> errors = new HashMap<String, String>();
+ errors.put("structured", t.getMessage());
+ throw new ConfigurationValidationException(t.getMessage(), errors);
}
} else {
+ Map<String, String> errors = null;
+
for (RawConfiguration rawConfiguration : configuration.getRawConfigurations()) {
try {
facet.validateRawConfiguration(rawConfiguration);
} catch (IllegalArgumentException e) {
- success = false;
+ if (errors == null) {
+ errors = new HashMap<String, String>();
+ }
+ errors.put(rawConfiguration.getPath(), e.getMessage());
rawConfiguration.errorMessage = e.getMessage();
- } catch (Throwable t) {
- success = false;
- rawConfiguration.errorMessage = t.getMessage();
}
}
+ if (errors != null) {
+ throw new ConfigurationValidationException("validation of raw configs failed", errors);
+ }
}
- return success ? null: configuration;
}
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java
index 6c74811..ad49994 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/configuration/ConfigurationManagerTest.java
@@ -23,13 +23,23 @@
package org.rhq.core.pc.configuration;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Set;
+import java.util.concurrent.ScheduledExecutorService;
+
import org.hamcrest.Matcher;
import org.jmock.Expectations;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest;
-import org.rhq.core.clientapi.agent.configuration.ConfigurationValidationException;
import org.rhq.core.clientapi.server.configuration.ConfigurationServerService;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.ConfigurationValidationException;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.RawConfiguration;
import org.rhq.core.domain.resource.ResourceType;
@@ -38,15 +48,6 @@ import org.rhq.core.pc.ServerServices;
import org.rhq.core.pc.util.FacetLockType;
import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet;
import org.rhq.test.jmock.PropertyMatcher;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import java.util.Set;
-import java.util.concurrent.ScheduledExecutorService;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
public class ConfigurationManagerTest extends ConfigManagementTest {
@@ -324,12 +325,11 @@ public class ConfigurationManagerTest extends ConfigManagementTest {
try {
configurationMgr.validate(configuration, resourceId, false);
assertTrue(false);
- } catch (PluginContainerException exception) {
+ } catch (ConfigurationValidationException exception) {
//SUCCESS
}
}
-
@Test
public void catchExceptionThrownByFailedValidationOfStructuredConfigs() throws Exception {
@@ -355,14 +355,11 @@ public class ConfigurationManagerTest extends ConfigManagementTest {
try {
configurationMgr.validate(configuration, resourceId, true);
assertTrue(false);
- } catch (PluginContainerException exception) {
+ } catch (ConfigurationValidationException exception) {
//SUCCESS
}
}
-
-
-
@Test
public void mergingRawsIntoStructuredShouldIgnoreNull() throws Exception {
Configuration config = new Configuration();
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java
index b5d9c14..4f2e104 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ExistingResourceConfigurationUIBean.java
@@ -18,17 +18,32 @@
*/
package org.rhq.enterprise.gui.configuration.resource;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+
+import javax.faces.application.FacesMessage;
+import javax.faces.event.ValueChangeEvent;
+import javax.servlet.http.HttpServletResponse;
+
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.jboss.seam.annotations.Create;
-import org.jboss.seam.annotations.Out;
import org.jetbrains.annotations.Nullable;
+import org.richfaces.model.UploadItem;
+
+import org.jboss.seam.annotations.Create;
-import org.rhq.core.clientapi.agent.configuration.ConfigurationValidationException;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.AbstractResourceConfigurationUpdate;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.ConfigurationValidationException;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.RawConfiguration;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
@@ -39,22 +54,9 @@ import org.rhq.enterprise.gui.common.upload.FileUploadUIBean;
import org.rhq.enterprise.gui.configuration.AbstractConfigurationUIBean;
import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility;
import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal;
+import org.rhq.enterprise.server.configuration.ConfigurationUpdateStillInProgressException;
+import org.rhq.enterprise.server.resource.ResourceNotFoundException;
import org.rhq.enterprise.server.util.LookupUtil;
-import org.richfaces.model.UploadItem;
-
-import javax.ejb.EJBException;
-import javax.faces.application.FacesMessage;
-import javax.faces.event.ValueChangeEvent;
-import javax.servlet.http.HttpServletResponse;
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.TreeMap;
// This class is temporarily decleared in components.xml since it is declared under two names - ViewUIBean and
// UIBean. This class is undergoing some refactoring and part of that will include declaring the @Name and @Scope
@@ -73,7 +75,7 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI
// @Out
private Collection<RawConfigDirectory> rawConfigDirectories;
-// @Out
+ // @Out
private FileUploadUIBean fileUploader = new FileUploadUIBean();
private String modalEditorContents;
@@ -139,18 +141,28 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI
}
public String switchToRaw() {
- Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration(
- EnterpriseFacesContextUtility.getSubject(), getResourceId(), getConfiguration(), true);
+ Configuration configuration;
+ try {
+ configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration(
+ EnterpriseFacesContextUtility.getSubject(), getResourceId(), getConfiguration(), true);
- setConfiguration(configuration);
+ setConfiguration(configuration);
- for (RawConfiguration raw : configuration.getRawConfigurations()) {
- getRaws().put(raw.getPath(), raw);
+ for (RawConfiguration raw : configuration.getRawConfigurations()) {
+ getRaws().put(raw.getPath(), raw);
+ }
+ current = null;
+ setConfiguration(configuration);
+ updateModifiedCache();
+ mode = RAW_MODE;
+
+ } catch (ResourceNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (ConfigurationValidationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
}
- current = null;
- setConfiguration(configuration);
- updateModifiedCache();
- mode = RAW_MODE;
return null;
}
@@ -166,27 +178,37 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI
}
public String switchToStructured() {
- Configuration configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration(
- EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), false);
+ Configuration configuration;
+ try {
+ configuration = LookupUtil.getConfigurationManager().translateResourceConfiguration(
+ EnterpriseFacesContextUtility.getSubject(), getResourceId(), getMergedConfiguration(), false);
- for (Property property : configuration.getAllProperties().values()) {
- property.setConfiguration(configuration);
- }
+ for (Property property : configuration.getAllProperties().values()) {
+ property.setConfiguration(configuration);
+ }
- for (RawConfiguration raw : configuration.getRawConfigurations()) {
- getRaws().put(raw.getPath(), raw);
+ for (RawConfiguration raw : configuration.getRawConfigurations()) {
+ getRaws().put(raw.getPath(), raw);
+ setConfiguration(configuration);
+ }
+ current = null;
setConfiguration(configuration);
- }
- current = null;
- setConfiguration(configuration);
- for (RawConfiguration raw : configuration.getRawConfigurations()) {
- System.out.println(raw.getPath() + " -\n" + (new String(raw.getContents())) + "\n");
- }
+ for (RawConfiguration raw : configuration.getRawConfigurations()) {
+ System.out.println(raw.getPath() + " -\n" + (new String(raw.getContents())) + "\n");
+ }
- updateModifiedCache();
+ updateModifiedCache();
- mode = STRUCTURED_MODE;
+ mode = STRUCTURED_MODE;
+
+ } catch (ResourceNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (ConfigurationValidationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
return null;
}
@@ -208,39 +230,46 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI
Configuration mergedConfiguration = null;
ConfigurationMaskingUtility.unmaskConfiguration(getConfiguration(), getConfigurationDefinition());
int resourceId = EnterpriseFacesContextUtility.getResource().getId();
-
+
mergedConfiguration = getMergedConfiguration();
- AbstractResourceConfigurationUpdate updateRequest = this.configurationManager
- .updateStructuredOrRawConfiguration(EnterpriseFacesContextUtility.getSubject(), resourceId,
- mergedConfiguration, fromStructured);
- if (updateRequest != null) {
- switch (updateRequest.getStatus()) {
- case SUCCESS:
- case INPROGRESS:
- FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Configuration update request with id "
- + updateRequest.getId() + " has been sent to the Agent.");
- clearConfiguration();
- return SUCCESS_OUTCOME;
- case FAILURE:
- FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Configuration update request with id "
- + updateRequest.getId() + " failed.", updateRequest.getErrorMessage());
-
- if (null != mergedConfiguration) {
- for (RawConfiguration raw : mergedConfiguration.getRawConfigurations()) {
- String message = raw.errorMessage;
- if (message != null) {
- FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, raw.getPath(), message);
+ try {
+ AbstractResourceConfigurationUpdate updateRequest = this.configurationManager
+ .updateStructuredOrRawConfiguration(EnterpriseFacesContextUtility.getSubject(), resourceId,
+ mergedConfiguration, fromStructured);
+ if (updateRequest != null) {
+ switch (updateRequest.getStatus()) {
+ case SUCCESS:
+ case INPROGRESS:
+ FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Configuration update request with id "
+ + updateRequest.getId() + " has been sent to the Agent.");
+ clearConfiguration();
+ return SUCCESS_OUTCOME;
+ case FAILURE:
+ FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Configuration update request with id "
+ + updateRequest.getId() + " failed.", updateRequest.getErrorMessage());
+
+ if (null != mergedConfiguration) {
+ for (RawConfiguration raw : mergedConfiguration.getRawConfigurations()) {
+ String message = raw.errorMessage;
+ if (message != null) {
+ FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, raw.getPath(), message);
+ }
}
}
- }
- return FAILURE_OUTCOME;
- case NOCHANGE:
- FacesContextUtility.addMessage(FacesMessage.SEVERITY_WARN,
- "No changes were made to the configuration, so " + "no update request has been sent to the Agent.");
- clearConfiguration();
- return SUCCESS_OUTCOME;
+ return FAILURE_OUTCOME;
+ case NOCHANGE:
+ FacesContextUtility.addMessage(FacesMessage.SEVERITY_WARN,
+ "No changes were made to the configuration, so "
+ + "no update request has been sent to the Agent.");
+ clearConfiguration();
+ return SUCCESS_OUTCOME;
+ }
+ }
+ } catch (ConfigurationValidationException e) {
+ for (String key : e.errors.keySet()) {
+ FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, key, e.errors.get(key));
}
}
return FAILURE_OUTCOME;
@@ -297,8 +326,19 @@ public class ExistingResourceConfigurationUIBean extends AbstractConfigurationUI
public String commit() {
Subject subject = EnterpriseFacesContextUtility.getSubject();
- LookupUtil.getConfigurationManager().updateResourceConfiguration(subject, getResourceId(),
- getMergedConfiguration());
+ try {
+ LookupUtil.getConfigurationManager().updateResourceConfiguration(subject, getResourceId(),
+ getMergedConfiguration());
+ } catch (ResourceNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (ConfigurationUpdateStillInProgressException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (org.rhq.core.domain.configuration.ConfigurationValidationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
return "/rhq/resource/configuration/view.xhtml?id=" + getResourceId();
}
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ResourceConfigurationEditor.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ResourceConfigurationEditor.java
index fb500b7..c10bd22 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ResourceConfigurationEditor.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ResourceConfigurationEditor.java
@@ -23,27 +23,30 @@
package org.rhq.enterprise.gui.configuration.resource;
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.ejb.EJBException;
+import javax.faces.application.FacesMessage;
+
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Observer;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.web.RequestParameter;
+
import org.rhq.core.domain.configuration.AbstractResourceConfigurationUpdate;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.ConfigurationValidationException;
import org.rhq.core.domain.configuration.RawConfiguration;
import org.rhq.core.gui.configuration.ConfigurationMaskingUtility;
import org.rhq.core.gui.util.FacesContextUtility;
import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal;
+import org.rhq.enterprise.server.configuration.ConfigurationUpdateStillInProgressException;
+import org.rhq.enterprise.server.resource.ResourceNotFoundException;
import org.rhq.enterprise.server.util.LookupUtil;
-import org.richfaces.model.UploadItem;
-
-import javax.ejb.EJBException;
-import javax.faces.application.FacesMessage;
-import java.io.Serializable;
-import java.util.HashSet;
-import java.util.Set;
-
@Name("configurationEditor")
@Scope(ScopeType.CONVERSATION)
public class ResourceConfigurationEditor extends ResourceConfigurationViewer implements Serializable {
@@ -67,7 +70,7 @@ public class ResourceConfigurationEditor extends ResourceConfigurationViewer imp
}
@Override
- protected void changeToRawTab() {
+ protected void changeToRawTab() throws ResourceNotFoundException, ConfigurationValidationException {
resourceConfiguration = translateToRaw();
for (RawConfiguration raw : resourceConfiguration.getRawConfigurations()) {
RawConfigUIBean uiBean = findRawConfigUIBeanByPath(raw.getPath());
@@ -75,25 +78,33 @@ public class ResourceConfigurationEditor extends ResourceConfigurationViewer imp
}
}
- private Configuration translateToRaw() {
+ private Configuration translateToRaw() throws ResourceNotFoundException, ConfigurationValidationException {
ConfigurationManagerLocal configurationMgr = LookupUtil.getConfigurationManager();
return configurationMgr.translateResourceConfiguration(loggedInUser.getSubject(), resourceId,
resourceConfiguration, STRUCTURED_MODE);
}
@Override
- protected void changeToStructuredTab() {
+ protected void changeToStructuredTab() throws ResourceNotFoundException, ConfigurationValidationException {
+
resourceConfiguration = translateToStructured();
+
for (RawConfiguration raw : resourceConfiguration.getRawConfigurations()) {
RawConfigUIBean uiBean = findRawConfigUIBeanByPath(raw.getPath());
uiBean.setRawConfiguration(raw);
+ if ((raw.errorMessage != null) && (!raw.errorMessage.equals(""))) {
+ FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, raw.errorMessage);
+ }
+
}
}
- private Configuration translateToStructured() {
+ private Configuration translateToStructured() throws ResourceNotFoundException, ConfigurationValidationException {
ConfigurationManagerLocal configurationMgr = LookupUtil.getConfigurationManager();
+
return configurationMgr.translateResourceConfiguration(loggedInUser.getSubject(), resourceId,
resourceConfiguration, RAW_MODE);
+
}
@Observer("rawConfigUpdate")
@@ -144,7 +155,8 @@ public class ResourceConfigurationEditor extends ResourceConfigurationViewer imp
return isRawSupported() || isStructuredAndRawSupported();
}
- public String updateConfiguration() {
+ public String updateConfiguration() throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException,
+ ConfigurationValidationException {
ConfigurationManagerLocal configurationMgr = LookupUtil.getConfigurationManager();
ConfigurationMaskingUtility.unmaskConfiguration(resourceConfiguration, resourceConfigurationDefinition);
@@ -154,11 +166,10 @@ public class ResourceConfigurationEditor extends ResourceConfigurationViewer imp
if (isStructuredAndRawSupported()) {
updateRequest = configurationMgr.updateStructuredOrRawConfiguration(loggedInUser.getSubject(),
- resourceId, resourceConfiguration, isStructuredMode());
- }
- else {
- updateRequest = configurationMgr.updateResourceConfiguration(loggedInUser.getSubject(),
- resourceId, resourceConfiguration);
+ resourceId, resourceConfiguration, isStructuredMode());
+ } else {
+ updateRequest = configurationMgr.updateResourceConfiguration(loggedInUser.getSubject(), resourceId,
+ resourceConfiguration);
}
clearErrors();
@@ -173,12 +184,12 @@ public class ResourceConfigurationEditor extends ResourceConfigurationViewer imp
case FAILURE:
FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Configuration update request with id "
+ updateRequest.getId() + " failed.", updateRequest.getErrorMessage());
-// for (RawConfiguration raw : resourceConfiguration.getRawConfigurations()) {
-// String message = raw.errorMessage;
-// if (message != null) {
-// FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, raw.getPath(), message);
-// }
-// }
+ // for (RawConfiguration raw : resourceConfiguration.getRawConfigurations()) {
+ // String message = raw.errorMessage;
+ // if (message != null) {
+ // FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, raw.getPath(), message);
+ // }
+ // }
copyErrorMessages(updateRequest);
return "failure";
@@ -218,10 +229,10 @@ public class ResourceConfigurationEditor extends ResourceConfigurationViewer imp
rawUIBean.setErrorMessage(updatedRaw.errorMessage);
}
-// RawConfiguration raw = findRawConfigurationByPath(updatedRaw.getPath());
-// if (raw != null) {
-// raw.errorMessage = updatedRaw.errorMessage;
-// }
+ // RawConfiguration raw = findRawConfigurationByPath(updatedRaw.getPath());
+ // if (raw != null) {
+ // raw.errorMessage = updatedRaw.errorMessage;
+ // }
}
}
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ResourceConfigurationViewer.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ResourceConfigurationViewer.java
index 8224134..94b798b 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ResourceConfigurationViewer.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/resource/ResourceConfigurationViewer.java
@@ -23,12 +23,28 @@
package org.rhq.enterprise.gui.configuration.resource;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.TreeMap;
+
+import javax.faces.application.FacesMessage;
+import javax.faces.event.ValueChangeEvent;
+import javax.servlet.http.HttpServletResponse;
+
import org.jboss.seam.ScopeType;
-import org.jboss.seam.annotations.*;
-import org.jboss.seam.annotations.web.RequestParameter;
+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.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.AbstractResourceConfigurationUpdate;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.ConfigurationValidationException;
import org.rhq.core.domain.configuration.RawConfiguration;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.configuration.definition.ConfigurationFormat;
@@ -37,16 +53,9 @@ import org.rhq.core.gui.util.FacesContextUtility;
import org.rhq.enterprise.gui.legacy.WebUser;
import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility;
import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal;
+import org.rhq.enterprise.server.resource.ResourceNotFoundException;
import org.rhq.enterprise.server.util.LookupUtil;
-import javax.faces.application.FacesMessage;
-import javax.faces.event.ValueChangeEvent;
-import javax.servlet.http.HttpServletResponse;
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.*;
-
@Name("configurationViewer")
@Scope(ScopeType.PAGE)
public class ResourceConfigurationViewer {
@@ -95,12 +104,12 @@ public class ResourceConfigurationViewer {
*/
public void initialize() {
resourceId = FacesContextUtility.getRequiredRequestParameter("id", Integer.class);
-
+
loadResourceConfigurationDefinition();
if (resourceConfigurationDefinition == null) {
- FacesContextUtility.addMessage(FacesMessage.SEVERITY_WARN,
- "This resource does not expose a configuration.");
+ FacesContextUtility
+ .addMessage(FacesMessage.SEVERITY_WARN, "This resource does not expose a configuration.");
return;
}
@@ -129,7 +138,7 @@ public class ResourceConfigurationViewer {
ConfigurationManagerLocal configurationManager = LookupUtil.getConfigurationManager();
resourceConfigurationDefinition = configurationManager.getResourceConfigurationDefinitionForResourceType(
- loggedInUser.getSubject(), resourceTypeId);
+ loggedInUser.getSubject(), resourceTypeId);
}
private void loadResourceConfiguration() {
@@ -157,8 +166,7 @@ public class ResourceConfigurationViewer {
protected void initRawConfigDirectories() {
if (isRawSupported() || isStructuredAndRawSupported()) {
initConfigDirectories();
- }
- else {
+ } else {
rawConfigDirectories = Collections.emptyList();
}
}
@@ -197,13 +205,11 @@ public class ResourceConfigurationViewer {
private void initMode() {
if (isStructuredSupported()) {
mode = STRUCTURED_MODE;
- }
- else if (isRawMode()) {
+ } else if (isRawMode()) {
mode = RAW_MODE;
- }
- else { // else structured and raw is supported and (at least for now) we will just start
- mode = STRUCTURED_MODE; // the user off in structured mode. We may at some later point want to add logic
- // to remember what mode the user should start in.
+ } else { // else structured and raw is supported and (at least for now) we will just start
+ mode = STRUCTURED_MODE; // the user off in structured mode. We may at some later point want to add logic
+ // to remember what mode the user should start in.
}
}
@@ -239,7 +245,7 @@ public class ResourceConfigurationViewer {
// however this property is read and its value applied to the modalEditor component before the mode is updated.
//
// jsanda - 02/10/2010
-
+
return isRawSupported() || isStructuredAndRawSupported();
}
@@ -269,27 +275,25 @@ public class ResourceConfigurationViewer {
public void setSelectedTab(String tab) {
if (tab.equals("structuredTab")) {
mode = STRUCTURED_MODE;
- }
- else {
+ } else {
mode = RAW_MODE;
}
}
- public void changeTabs(ValueChangeEvent event) {
+ public void changeTabs(ValueChangeEvent event) throws ResourceNotFoundException, ConfigurationValidationException {
if (event.getNewValue().equals("rawTab")) {
mode = RAW_MODE;
changeToRawTab();
- }
- else if (event.getNewValue().equals("structuredTab")) {
+ } else if (event.getNewValue().equals("structuredTab")) {
mode = STRUCTURED_MODE;
changeToStructuredTab();
}
}
- protected void changeToRawTab() {
+ protected void changeToRawTab() throws ResourceNotFoundException, ConfigurationValidationException {
}
- protected void changeToStructuredTab() {
+ protected void changeToStructuredTab() throws ResourceNotFoundException, ConfigurationValidationException {
}
public void select(String path) {
@@ -340,9 +344,8 @@ public class ResourceConfigurationViewer {
FacesContextUtility.getFacesContext().responseComplete();
return null;
- }
- catch (IOException e) {
-// log.error("Failed to complete download request for " + getCurrentPath(), e);
+ } catch (IOException e) {
+ // log.error("Failed to complete download request for " + getCurrentPath(), e);
throw new RuntimeException(e);
}
}
@@ -354,5 +357,5 @@ public class ResourceConfigurationViewer {
public String getModalEditorContents() {
return selectedRawUIBean.getContents();
}
-
+
}
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/navigation/resource/ResourceSelectUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/navigation/resource/ResourceSelectUIBean.java
index 6672fbe..e25960b 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/navigation/resource/ResourceSelectUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/navigation/resource/ResourceSelectUIBean.java
@@ -28,7 +28,6 @@ import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.composite.DisambiguationReport;
import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceNamesDisambiguationResult;
-import org.rhq.core.domain.resource.composite.ResourceParentFlyweight;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.util.IntExtractor;
import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility;
@@ -47,28 +46,30 @@ public class ResourceSelectUIBean {
private String searchString;
private Log log = LogFactory.getLog(this.getClass());
-
+
private static final IntExtractor<ResourceComposite> RESOURCE_ID_EXTRACTOR = new IntExtractor<ResourceComposite>() {
public int extract(ResourceComposite resource) {
return resource.getResource().getId();
}
};
-
+
public static class DisambiguationReportWrapper extends DisambiguationReport<ResourceComposite> {
private static final long serialVersionUID = 1L;
-
+
private boolean typeResolutionNeeded;
private boolean parentResolutionNeeded;
private boolean pluginResolutionNeeded;
-
+
/**
* @param original
* @param parents
* @param resourceTypeName
* @param resourceTypePluginName
*/
- public DisambiguationReportWrapper(DisambiguationReport<ResourceComposite> report, boolean typeResolutionNeeded, boolean parentResolutionNeeded, boolean pluginResolutionNeeded) {
- super(report.getOriginal(), report.getParents(), report.getResourceTypeName(), report.getResourceTypePluginName());
+ public DisambiguationReportWrapper(DisambiguationReport<ResourceComposite> report,
+ boolean typeResolutionNeeded, boolean parentResolutionNeeded, boolean pluginResolutionNeeded) {
+ super(report.getOriginal(), report.getParents(), report.getResourceTypeName(), report
+ .getResourceTypePluginName());
this.typeResolutionNeeded = typeResolutionNeeded;
this.parentResolutionNeeded = parentResolutionNeeded;
this.pluginResolutionNeeded = pluginResolutionNeeded;
@@ -86,7 +87,7 @@ public class ResourceSelectUIBean {
return pluginResolutionNeeded;
}
}
-
+
public Resource getResource() {
return resource;
}
@@ -113,24 +114,27 @@ public class ResourceSelectUIBean {
result = resourceManager.findResourceComposites(EnterpriseFacesContextUtility.getSubject(), null, null, null,
null, pref, true, pc);
+ if (result.size() == 0) {
+ return new ArrayList<DisambiguationReportWrapper>();
+ }
+
return wrap(resourceManager.disambiguate(result, false, RESOURCE_ID_EXTRACTOR));
}
-
+
private List<DisambiguationReportWrapper> wrap(ResourceNamesDisambiguationResult<ResourceComposite> result) {
List<DisambiguationReportWrapper> ret = new ArrayList<DisambiguationReportWrapper>();
if (result == null) {
return ret;
}
-
+
boolean typeRes = result.isTypeResolutionNeeded();
boolean parentRes = result.isParentResolutionNeeded();
boolean pluginRes = result.isPluginResolutionNeeded();
-
-
+
for (DisambiguationReport<ResourceComposite> r : result.getResolution()) {
ret.add(new DisambiguationReportWrapper(r, typeRes, parentRes, pluginRes));
}
-
+
return ret;
}
}
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ResourceClientProxy.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ResourceClientProxy.java
index 3342ef1..7f993ff 100644
--- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ResourceClientProxy.java
+++ b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/proxy/ResourceClientProxy.java
@@ -18,37 +18,23 @@
*/
package org.rhq.enterprise.client.proxy;
-import java.lang.reflect.InvocationTargetException;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import javassist.CannotCompileException;
-import javassist.ClassPool;
-import javassist.CtClass;
-import javassist.CtMethod;
-import javassist.CtNewMethod;
-import javassist.NotFoundException;
-import javassist.bytecode.ParameterAnnotationsAttribute;
-import javassist.bytecode.annotation.Annotation;
-import javassist.bytecode.annotation.StringMemberValue;
import javassist.util.proxy.MethodHandler;
-import javassist.util.proxy.ProxyFactory;
-
-import javax.jws.WebParam;
import org.rhq.core.domain.configuration.Configuration;
-import org.rhq.core.domain.configuration.ResourceConfigurationUpdate;
+import org.rhq.core.domain.configuration.ConfigurationValidationException;
import org.rhq.core.domain.configuration.PluginConfigurationUpdate;
+import org.rhq.core.domain.configuration.ResourceConfigurationUpdate;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.content.InstalledPackage;
import org.rhq.core.domain.content.PackageType;
@@ -68,19 +54,20 @@ 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.Resource;
-import org.rhq.core.domain.resource.ResourceCreationDataType;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.domain.util.PageOrdering;
import org.rhq.core.domain.util.Summary;
-import org.rhq.enterprise.client.RemoteClient;
import org.rhq.enterprise.client.ClientMain;
-import org.rhq.enterprise.client.utility.LazyLoadScenario;
-import org.rhq.enterprise.client.utility.ShortOutput;
+import org.rhq.enterprise.client.RemoteClient;
import org.rhq.enterprise.client.utility.ConfigurationClassBuilder;
+import org.rhq.enterprise.client.utility.LazyLoadScenario;
import org.rhq.enterprise.client.utility.ScriptUtil;
+import org.rhq.enterprise.client.utility.ShortOutput;
+import org.rhq.enterprise.server.configuration.ConfigurationUpdateStillInProgressException;
import org.rhq.enterprise.server.content.ContentManagerRemote;
import org.rhq.enterprise.server.operation.ResourceOperationSchedule;
+import org.rhq.enterprise.server.resource.ResourceNotFoundException;
import org.rhq.enterprise.server.resource.ResourceTypeNotFoundException;
/**
@@ -369,6 +356,7 @@ public class ResourceClientProxy {
public String toString() {
return getName();
}
+
public String getShortOutput() {
return getDisplayValue();
}
@@ -461,18 +449,16 @@ public class ResourceClientProxy {
}
public PluginConfigurationUpdate updatePluginConfiguration(Configuration configuration) {
- PluginConfigurationUpdate update =
- remoteClient.getConfigurationManagerRemote().updatePluginConfiguration(
- remoteClient.getSubject(),
- resourceClientProxy.getId(),
- configuration);
+ PluginConfigurationUpdate update = remoteClient.getConfigurationManagerRemote().updatePluginConfiguration(
+ remoteClient.getSubject(), resourceClientProxy.getId(), configuration);
return update;
}
public void editPluginConfiguration() {
ConfigurationEditor editor = new ConfigurationEditor(resourceClientProxy.client);
- Configuration config = editor.editConfiguration(getPluginConfigurationDefinition(), getPluginConfiguration());
+ Configuration config = editor.editConfiguration(getPluginConfigurationDefinition(),
+ getPluginConfiguration());
if (config != null) {
updatePluginConfiguration(config);
}
@@ -480,7 +466,8 @@ public class ResourceClientProxy {
public void editResourceConfiguration() {
ConfigurationEditor editor = new ConfigurationEditor(resourceClientProxy.client);
- Configuration config = editor.editConfiguration(getResourceConfigurationDefinition(), getResourceConfiguration());
+ Configuration config = editor.editConfiguration(getResourceConfigurationDefinition(),
+ getResourceConfiguration());
if (config != null) {
updateResourceConfiguration(config);
}
@@ -499,11 +486,21 @@ public class ResourceClientProxy {
}
public ResourceConfigurationUpdate updateResourceConfiguration(Configuration configuration) {
- ResourceConfigurationUpdate update =
- remoteClient.getConfigurationManagerRemote().updateResourceConfiguration(
- remoteClient.getSubject(),
- resourceClientProxy.getId(),
- configuration);
+ ResourceConfigurationUpdate update = null;
+
+ try {
+ update = remoteClient.getConfigurationManagerRemote().updateResourceConfiguration(
+ remoteClient.getSubject(), resourceClientProxy.getId(), configuration);
+ } catch (ResourceNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (ConfigurationUpdateStillInProgressException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (ConfigurationValidationException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
return update;
@@ -511,7 +508,8 @@ public class ResourceClientProxy {
public InstalledPackage getBackingContent() {
- return remoteClient.getContentManagerRemote().getBackingPackageForResource(remoteClient.getSubject(), resourceClientProxy.resourceId);
+ return remoteClient.getContentManagerRemote().getBackingPackageForResource(remoteClient.getSubject(),
+ resourceClientProxy.resourceId);
}
public void updateBackingContent(String filename) {
@@ -523,15 +521,13 @@ public class ResourceClientProxy {
throw new IllegalArgumentException("File expected, found directory: " + file.getAbsolutePath());
}
-
InstalledPackage oldPackage = getBackingContent();
-
String oldVersion = oldPackage.getPackageVersion().getVersion();
String newVersion = "1.0";
if (oldVersion != null && oldVersion.length() != 0) {
String[] parts = oldVersion.split("[^a-zA-Z0-9]");
- String lastPart = parts[parts.length-1];
+ String lastPart = parts[parts.length - 1];
try {
int lastNumber = Integer.parseInt(lastPart);
newVersion = oldVersion.substring(0, oldVersion.length() - lastPart.length()) + (lastNumber + 1);
@@ -542,21 +538,13 @@ public class ResourceClientProxy {
byte[] fileContents = new ScriptUtil(null).getFileBytes(filename);
+ PackageVersion pv = remoteClient.getContentManagerRemote().createPackageVersion(remoteClient.getSubject(),
+ oldPackage.getPackageVersion().getGeneralPackage().getName(),
+ oldPackage.getPackageVersion().getGeneralPackage().getPackageType().getId(), newVersion,
+ oldPackage.getPackageVersion().getArchitecture().getId(), fileContents);
- PackageVersion pv =
- remoteClient.getContentManagerRemote().createPackageVersion(
- remoteClient.getSubject(),
- oldPackage.getPackageVersion().getGeneralPackage().getName(),
- oldPackage.getPackageVersion().getGeneralPackage().getPackageType().getId(),
- newVersion,
- oldPackage.getPackageVersion().getArchitecture().getId(),
- fileContents);
-
- remoteClient.getContentManagerRemote().deployPackages(
- remoteClient.getSubject(),
- new int[] { resourceClientProxy.getId()},
- new int[] {pv.getId()});
-
+ remoteClient.getContentManagerRemote().deployPackages(remoteClient.getSubject(),
+ new int[] { resourceClientProxy.getId() }, new int[] { pv.getId() });
}
@@ -564,14 +552,13 @@ public class ResourceClientProxy {
InstalledPackage installedPackage = getBackingContent();
- if (fileName == null )
+ if (fileName == null)
fileName = installedPackage.getPackageVersion().getFileName();
-
+
File file = new File(fileName);
- byte[] data =
- remoteClient.getContentManagerRemote().getPackageBytes(
- remoteClient.getSubject(), resourceClientProxy.resourceId, installedPackage.getId());
+ byte[] data = remoteClient.getContentManagerRemote().getPackageBytes(remoteClient.getSubject(),
+ resourceClientProxy.resourceId, installedPackage.getId());
FileOutputStream fos = new FileOutputStream(file);
fos.write(data);
@@ -581,8 +568,6 @@ public class ResourceClientProxy {
// ------------------------------------------------------------------------------------------------------
-
-
public Object invoke(Object proxy, Method method, Method proceedMethod, Object[] args) throws Throwable {
if (proceedMethod != null) {
@@ -620,7 +605,6 @@ public class ResourceClientProxy {
}
}
-
static String simpleName(String name) {
return decapitalize(name.replaceAll("\\W", ""));
}
@@ -657,10 +641,8 @@ public class ResourceClientProxy {
public InstalledPackage getBackingContent();
-
public void updateBackingContent(String fileName);
-
public void retrieveBackingContent(String fileName) throws IOException;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java
index 9f800c7..71370f2 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java
@@ -55,6 +55,7 @@ import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.configuration.AbstractResourceConfigurationUpdate;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.ConfigurationUpdateStatus;
+import org.rhq.core.domain.configuration.ConfigurationValidationException;
import org.rhq.core.domain.configuration.PluginConfigurationUpdate;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.ResourceConfigurationUpdate;
@@ -976,33 +977,14 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf
public ResourceConfigurationUpdate updateStructuredOrRawConfiguration(Subject subject, int resourceId,
Configuration newConfiguration, boolean fromStructured) throws ResourceNotFoundException,
- ConfigurationUpdateStillInProgressException {
+ ConfigurationUpdateStillInProgressException, ConfigurationValidationException {
Configuration configToUpdate = newConfiguration;
if (isStructuredAndRawSupported(resourceId)) {
configToUpdate = translateResourceConfiguration(subject, resourceId, newConfiguration, fromStructured);
}
- try {
- Configuration invalidConfig = validateResourceConfiguration(subject, resourceId, newConfiguration,
- fromStructured);
- if (null != invalidConfig) {
- Resource resource = resourceManager.getResourceById(subject, resourceId);
- ResourceConfigurationUpdate resourceConfigurationUpdate = new ResourceConfigurationUpdate(resource,
- invalidConfig, subject.getName());
- resourceConfigurationUpdate.setErrorMessage("resource.validation.failed");
- resourceConfigurationUpdate.setStatus(ConfigurationUpdateStatus.FAILURE);
-
- return resourceConfigurationUpdate;
- }
- } catch (PluginContainerException e) {
- Resource resource = resourceManager.getResourceById(subject, resourceId);
- ResourceConfigurationUpdate resourceConfigurationUpdate = new ResourceConfigurationUpdate(resource,
- newConfiguration, subject.getName());
- resourceConfigurationUpdate.setErrorMessage(e.getMessage());
- resourceConfigurationUpdate.setStatus(ConfigurationUpdateStatus.FAILURE);
- return resourceConfigurationUpdate;
- }
+ validateResourceConfiguration(subject, resourceId, newConfiguration, fromStructured);
ResourceConfigurationUpdate newUpdate = configurationManager.persistNewResourceConfigurationUpdateHistory(
subject, resourceId, configToUpdate, ConfigurationUpdateStatus.INPROGRESS, subject.getName(), false);
@@ -1010,8 +992,8 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf
return newUpdate;
}
- private Configuration validateResourceConfiguration(Subject subject, int resourceId, Configuration configuration,
- boolean isStructured) throws PluginContainerException {
+ private void validateResourceConfiguration(Subject subject, int resourceId, Configuration configuration,
+ boolean isStructured) throws ConfigurationValidationException {
Resource resource = entityManager.find(Resource.class, resourceId);
if (resource == null) {
throw new NoResultException("Cannot get live configuration for unknown resource [" + resourceId + "]");
@@ -1023,7 +1005,7 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf
Agent agent = resource.getAgent();
AgentClient agentClient = this.agentManager.getAgentClient(agent);
ConfigurationAgentService configService = agentClient.getConfigurationAgentService();
- return configService.validate(configuration, resourceId, isStructured);
+ configService.validate(configuration, resourceId, isStructured);
}
private boolean isRawSupported(int resourceId) {
@@ -1096,7 +1078,8 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf
}
public void rollbackResourceConfiguration(Subject subject, int resourceId, int configHistoryId)
- throws ConfigurationUpdateException {
+ throws ConfigurationUpdateException, ResourceNotFoundException, ConfigurationUpdateStillInProgressException,
+ ConfigurationValidationException {
ResourceConfigurationUpdate configurationUpdateHistory = entityManager.find(ResourceConfigurationUpdate.class,
configHistoryId);
Configuration configuration = configurationUpdateHistory.getConfiguration();
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java
index 755427c..16764b5 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerLocal.java
@@ -18,18 +18,21 @@
*/
package org.rhq.enterprise.server.configuration;
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+
import org.jetbrains.annotations.Nullable;
import org.quartz.SchedulerException;
-import org.rhq.core.clientapi.agent.PluginContainerException;
-import org.rhq.core.clientapi.agent.configuration.ConfigurationValidationException;
import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.AbstractResourceConfigurationUpdate;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.ConfigurationUpdateStatus;
+import org.rhq.core.domain.configuration.ConfigurationValidationException;
import org.rhq.core.domain.configuration.PluginConfigurationUpdate;
-import org.rhq.core.domain.configuration.RawConfiguration;
import org.rhq.core.domain.configuration.ResourceConfigurationUpdate;
import org.rhq.core.domain.configuration.composite.ConfigurationUpdateComposite;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
@@ -44,11 +47,6 @@ import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.configuration.job.GroupPluginConfigurationUpdateJob;
import org.rhq.enterprise.server.resource.ResourceNotFoundException;
-import javax.ejb.Local;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
/**
* The configuration manager which allows you to request resource configuration changes, view current resource
* configuration and previous update history and view/edit plugin configuration.
@@ -57,7 +55,7 @@ import java.util.Map;
* @author Ian Springer
*/
@Local
-public interface ConfigurationManagerLocal {
+public interface ConfigurationManagerLocal extends ConfigurationManagerRemote {
/**
* Updates the plugin configuration used to connect and communicate with the resource using the information in the
@@ -150,9 +148,13 @@ public interface ConfigurationManagerLocal {
* @param configHistoryId the id of the resource's previous configuration to rollback to
*
* @throws ConfigurationUpdateException if the configHistoryId does not exist
+ * @throws ConfigurationValidationException
+ * @throws ConfigurationUpdateStillInProgressException
+ * @throws ResourceNotFoundException
*/
void rollbackResourceConfiguration(Subject subject, int resourceId, int configHistoryId)
- throws ConfigurationUpdateException;
+ throws ConfigurationUpdateException, ResourceNotFoundException, ConfigurationUpdateStillInProgressException,
+ ConfigurationValidationException;
/**
* For internal use only - do not call this method. This is for
@@ -373,119 +375,4 @@ public interface ConfigurationManagerLocal {
*/
void checkForTimedOutConfigurationUpdateRequests();
- // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- //
- // The following are shared with the Remote Interface
- //
- // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- public GroupPluginConfigurationUpdate getGroupPluginConfigurationUpdate(Subject subject, int configurationUpdateId);
-
- public GroupResourceConfigurationUpdate getGroupResourceConfigurationUpdate(Subject subject,
- int configurationUpdateId);
-
- public Configuration getConfiguration(Subject subject, int configurationId);
-
- /**
- * Get the current plugin configuration for the {@link Resource} with the given id, or <code>null</code> if the
- * resource's plugin configuration is not yet initialized.
- *
- * @param subject the user who wants to see the information
- * @param resourceId a {@link Resource} id
- *
- * @return the current plugin configuration for the {@link Resource} with the given id, or <code>null</code> if the
- * resource's configuration is not yet initialized
- * @throws FetchException TODO
- */
- @Nullable
- Configuration getPluginConfiguration(Subject subject, int resourceId);
-
- /**
- * Get the latest plugin configuration for the {@link Resource} with the given id. Returns the configuration as it
- * is known on the server-side in the database.
- *
- * @param subject the user who wants to see the information
- * @param resourceId a {@link Resource} id
- *
- * @return the current plugin configuration (along with additional information about the configuration) for the
- * {@link Resource} with the given id
- * @throws FetchException TODO
- */
- PluginConfigurationUpdate getLatestPluginConfigurationUpdate(Subject subject, int resourceId);
-
- /**
- * Get the latest resource configuration for the {@link Resource} with the given id, or <code>null</code> if the
- * resource's configuration is not yet initialized and for some reason we can't get its current live configuration
- * (e.g. in the case the agent or resource is down). Returns the configuration as it is known on the server-side in
- * the database. The database will be sync'ed with the live values, if the currently live configuration is actually
- * different than the latest configuration update found in history.
- *
- * @param subject the user who wants to see the information
- * @param resourceId a {@link Resource} id
- *
- * @return the current configuration (along with additional information about the configuration) for the
- * {@link Resource} with the given id, or <code>null</code> if the resource's configuration is not yet
- * initialized and its live configuration could not be determined
- * @throws FetchException TODO
- */
- @Nullable
- ResourceConfigurationUpdate getLatestResourceConfigurationUpdate(Subject subject, int resourceId);
-
- ResourceConfigurationUpdate getLatestResourceConfigurationUpdate(Subject subject, int resourceId,
- boolean fromStructured);
-
- boolean isResourceConfigurationUpdateInProgress(Subject subject, int resourceId);
-
- boolean isGroupResourceConfigurationUpdateInProgress(Subject subject, int groupId);
-
- int scheduleGroupResourceConfigurationUpdate(Subject subject, int compatibleGroupId,
- Map<Integer, Configuration> newResourceConfigurationMap);
-
- /**
- * Updates the plugin configuration used to connect and communicate with the resource. The given <code>
- * newConfiguration</code> is usually a modified version of a configuration returned by
- * {@link #getPluginConfiguration(Subject, int)}.
- *
- * @param subject the user who wants to see the information
- * @param resourceId a {@link Resource} id
- * @param newConfiguration the new plugin configuration
- *
- * @return the plugin configuration update item corresponding to this request
- */
- PluginConfigurationUpdate updatePluginConfiguration(Subject subject, int resourceId, Configuration newConfiguration)
- throws ResourceNotFoundException;
-
- /**
- * This method is called when a user has requested to change the resource configuration for an existing resource. If
- * the user does not have the proper permissions to change the resource's configuration, an exception is thrown.
- *
- * <p>This will not wait for the agent to finish the configuration update. This will return after the request is
- * sent. Once the agent finishes with the request, it will send the completed request information to
- * {@link #completeResourceConfigurationUpdate}.</p>
- *
- * @param subject the user who is requesting the update
- * @param resourceId identifies the resource to be updated
- * @param newConfiguration the resource's desired new configuration
- *
- * @return the resource configuration update item corresponding to this request. null
- * if newConfiguration is equal to the existing configuration.
- */
- @Nullable
- ResourceConfigurationUpdate updateResourceConfiguration(Subject subject, int resourceId,
- Configuration newConfiguration) throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException;
-
- ResourceConfigurationUpdate updateStructuredOrRawConfiguration(Subject subject, int resourceId,
- Configuration newConfiguration, boolean fromStructured) throws ResourceNotFoundException,
- ConfigurationUpdateStillInProgressException;
-
- Configuration getResourceConfiguration(Subject subject, int resourceId);
-
- /**
- * @see ConfigurationManagerRemote#getPackageTypeConfigurationDefinition(Subject,int)
- */
- ConfigurationDefinition getPackageTypeConfigurationDefinition(Subject subject, int packageTypeId);
-
- Configuration translateResourceConfiguration(Subject subject, int resourceId, Configuration configuration,
- boolean fromStructured) throws ResourceNotFoundException, TranslationNotSupportedException;
-
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java
index 74bfdc4..0d7ae1b 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java
@@ -32,6 +32,7 @@ import org.jetbrains.annotations.Nullable;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.AbstractResourceConfigurationUpdate;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.ConfigurationValidationException;
import org.rhq.core.domain.configuration.PluginConfigurationUpdate;
import org.rhq.core.domain.configuration.ResourceConfigurationUpdate;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
@@ -178,12 +179,13 @@ public interface ConfigurationManagerRemote {
@WebParam(name = "resourceId") int resourceId, //
@WebParam(name = "newConfiguration")//
@XmlJavaTypeAdapter(ConfigurationAdapter.class) Configuration newConfiguration)
- throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException;
+ throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException, ConfigurationValidationException;
@WebMethod
ResourceConfigurationUpdate updateStructuredOrRawConfiguration(@WebParam Subject subject, @WebParam int resourceId,
@WebParam @XmlJavaTypeAdapter(ConfigurationAdapter.class) Configuration newConfiguration,
- @WebParam boolean fromStructured) throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException;
+ @WebParam boolean fromStructured) throws ResourceNotFoundException,
+ ConfigurationUpdateStillInProgressException, ConfigurationValidationException;
/**
* Get the currently live resource configuration for the {@link Resource} with the given id. This actually asks for
@@ -262,7 +264,17 @@ public interface ConfigurationManagerRemote {
@WebParam(name = "subject") Subject subject, //
@WebParam(name = "packageTypeId") int packageTypeId);
+ /**
+ *
+ * @param subject
+ * @param resourceId
+ * @param configuration
+ * @param fromStructured
+ * @return
+ * @throws ResourceNotFoundException
+ * @throws ConfigurationValidationException
+ */
Configuration translateResourceConfiguration(Subject subject, int resourceId, Configuration configuration,
- boolean fromStructured) throws ResourceNotFoundException;
+ boolean fromStructured) throws ResourceNotFoundException, ConfigurationValidationException;
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
index a111f46..75ebb67 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
@@ -38,6 +38,7 @@ import org.rhq.core.domain.alert.AlertDefinition;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Role;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.ConfigurationValidationException;
import org.rhq.core.domain.configuration.PluginConfigurationUpdate;
import org.rhq.core.domain.configuration.ResourceConfigurationUpdate;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
@@ -471,13 +472,13 @@ public class WebservicesManagerBean implements WebservicesRemote {
public ResourceConfigurationUpdate updateResourceConfiguration(Subject subject, int resourceId,
@XmlJavaTypeAdapter(ConfigurationAdapter.class) Configuration newConfiguration)
- throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException {
+ throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException, ConfigurationValidationException {
return configurationManager.updateResourceConfiguration(subject, resourceId, newConfiguration);
}
public ResourceConfigurationUpdate updateStructuredOrRawConfiguration(Subject subject, int resourceId,
Configuration newConfiguration, boolean fromStructured) throws ResourceNotFoundException,
- ConfigurationUpdateStillInProgressException {
+ ConfigurationUpdateStillInProgressException, ConfigurationValidationException {
return configurationManager.updateStructuredOrRawConfiguration(subject, resourceId, newConfiguration,
fromStructured);
}
@@ -487,7 +488,7 @@ public class WebservicesManagerBean implements WebservicesRemote {
}
public Configuration translateResourceConfiguration(Subject subject, int resourceId, Configuration configuration,
- boolean fromStructured) throws ResourceNotFoundException {
+ boolean fromStructured) throws ResourceNotFoundException, ConfigurationValidationException {
return configurationManager.translateResourceConfiguration(subject, resourceId, configuration, fromStructured);
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java
index 45164d2..f0a6a64 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java
@@ -23,7 +23,6 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Collection;
import javax.persistence.EntityManager;
@@ -43,10 +42,10 @@ import org.rhq.core.communications.command.annotation.Asynchronous;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.ConfigurationUpdateStatus;
+import org.rhq.core.domain.configuration.ConfigurationValidationException;
import org.rhq.core.domain.configuration.PluginConfigurationUpdate;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.ResourceConfigurationUpdate;
-import org.rhq.core.domain.configuration.RawConfiguration;
import org.rhq.core.domain.configuration.group.GroupPluginConfigurationUpdate;
import org.rhq.core.domain.discovery.AvailabilityReport;
import org.rhq.core.domain.discovery.InventoryReport;
@@ -942,7 +941,7 @@ public class ConfigurationManagerBeanTest extends AbstractEJB3Test {
void delete(Configuration configuration) {
EntityManager entityMgr = getEntityManager();
Configuration managedConfig = entityMgr.find(Configuration.class, configuration.getId());
- entityMgr.remove(managedConfig);
+ entityMgr.remove(managedConfig);
}
private class TestServices implements ConfigurationAgentService, DiscoveryAgentService {
@@ -1087,9 +1086,10 @@ public class ConfigurationManagerBeanTest extends AbstractEJB3Test {
@Asynchronous(guaranteedDelivery = true)
public void synchronizeInventory(ResourceSyncInfo syncInfo) {
}
- public Configuration validate(Configuration configuration, int resourceId, boolean isStructured)
- throws PluginContainerException {
- return null;
+
+ public void validate(Configuration configuration, int resourceId, boolean isStructured)
+ throws ConfigurationValidationException {
+
}
}
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java
index ebeda42..6b3aaf5 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java
@@ -40,6 +40,7 @@ import org.rhq.core.clientapi.agent.support.SupportAgentService;
import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse;
import org.rhq.core.communications.command.annotation.Asynchronous;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.ConfigurationValidationException;
import org.rhq.core.domain.content.transfer.ContentDiscoveryReport;
import org.rhq.core.domain.content.transfer.DeletePackagesRequest;
import org.rhq.core.domain.content.transfer.DeployPackageStep;
@@ -255,8 +256,8 @@ public class TestAgentClient implements AgentClient, ContentAgentService, Resour
return null;
}
- public Configuration validate(Configuration configuration, int resourceId, boolean isStructured)
- throws PluginContainerException {
- return null;
+ public void validate(Configuration configuration, int resourceId, boolean isStructured)
+ throws ConfigurationValidationException {
+ return;
}
}
commit 6ee5caa384239576f8f0d1025083925ff303af35
Author: Adam Young <ayoung(a)redhat.com>
Date: Thu Feb 25 14:24:54 2010 -0500
Removing exception that was tripping up the CLI.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java
index f6fbb95..9f800c7 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java
@@ -24,7 +24,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.Map.Entry;
import javax.ejb.EJB;
import javax.ejb.Stateless;
@@ -993,7 +992,7 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf
invalidConfig, subject.getName());
resourceConfigurationUpdate.setErrorMessage("resource.validation.failed");
resourceConfigurationUpdate.setStatus(ConfigurationUpdateStatus.FAILURE);
-
+
return resourceConfigurationUpdate;
}
} catch (PluginContainerException e) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java
index 4d834fd..74bfdc4 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerRemote.java
@@ -29,7 +29,6 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.jetbrains.annotations.Nullable;
-import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.AbstractResourceConfigurationUpdate;
import org.rhq.core.domain.configuration.Configuration;
@@ -182,13 +181,9 @@ public interface ConfigurationManagerRemote {
throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException;
@WebMethod
- ResourceConfigurationUpdate updateStructuredOrRawConfiguration(
- @WebParam Subject subject,
- @WebParam int resourceId,
- @WebParam
- @XmlJavaTypeAdapter(ConfigurationAdapter.class) Configuration newConfiguration,
- @WebParam boolean fromStructured)
- throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException, PluginContainerException;
+ ResourceConfigurationUpdate updateStructuredOrRawConfiguration(@WebParam Subject subject, @WebParam int resourceId,
+ @WebParam @XmlJavaTypeAdapter(ConfigurationAdapter.class) Configuration newConfiguration,
+ @WebParam boolean fromStructured) throws ResourceNotFoundException, ConfigurationUpdateStillInProgressException;
/**
* Get the currently live resource configuration for the {@link Resource} with the given id. This actually asks for
14 years, 2 months
[rhq] Branch 'gwt' - modules/enterprise
by ips
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java | 18 +++++----
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UnknownViewException.java | 20 +---------
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ViewId.java | 20 ++--------
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ViewRenderer.java | 7 +--
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/AdministrationView.java | 9 +++-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceView.java | 11 +++--
modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css | 2 -
7 files changed, 35 insertions(+), 52 deletions(-)
New commits:
commit 7d3a71a9a988fa6d57d8a90e7790b52cb191fbf1
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Mon Mar 1 16:04:26 2010 -0500
a couple minor tweaks to the history/breadcrumb API
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
index 3ab6790..24dbe6e 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
@@ -177,13 +177,15 @@ public class CoreGUI implements EntryPoint {
ViewRenderer viewRenderer = (ViewRenderer)parentView.getCanvas();
List<Breadcrumb> breadcrumbs = new ArrayList<Breadcrumb>(viewIdNames.size());
try {
- for (String viewIdName : viewIdNames) {
+ for (int i = 0, viewIdNamesSize = viewIdNames.size(); i < viewIdNamesSize; i++) {
+ String viewIdName = viewIdNames.get(i);
Canvas parentCanvas = parentView.getCanvas();
if (parentCanvas != null && parentCanvas instanceof ViewRenderer) {
- viewRenderer = (ViewRenderer)parentCanvas;
+ viewRenderer = (ViewRenderer) parentCanvas;
}
ViewId viewId = new ViewId(viewIdName, parentView.getId());
- parentView = viewRenderer.renderView(parentView, viewId);
+ boolean lastNode = (i == (viewIdNamesSize - 1));
+ parentView = viewRenderer.renderView(viewId, parentView, lastNode);
breadcrumbs.add(parentView.getBreadcrumb());
}
} catch (UnknownViewException e) {
@@ -302,14 +304,14 @@ public class CoreGUI implements EntryPoint {
setHeight100(); // (900);
}
- public View renderView(View parentView, ViewId viewId) throws UnknownViewException {
+ public View renderView(ViewId viewId, View parentView, boolean lastNode) throws UnknownViewException {
String path = viewId.getPath();
Canvas canvas = createContent(path);
- if (canvas != null) {
- setContent(canvas);
- return new View(viewId, canvas);
+ if (canvas == null) {
+ throw new UnknownViewException();
}
- throw new UnknownViewException(viewId);
+ setContent(canvas);
+ return new View(viewId, canvas);
}
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UnknownViewException.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UnknownViewException.java
index 8179b86..d5ff736 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UnknownViewException.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UnknownViewException.java
@@ -24,24 +24,10 @@ package org.rhq.enterprise.gui.coregui.client;
* @author Ian Springer
*/
public class UnknownViewException extends Exception {
- private ViewId viewId;
- private String message;
-
- public UnknownViewException(ViewId viewId) {
- this(viewId, null);
- }
-
- public UnknownViewException(ViewId viewId, String message) {
- this.viewId = viewId;
- this.message = message;
+ public UnknownViewException() {
}
- @Override
- public String getMessage() {
- String message = "Unknown view id [" + this.viewId + "]";
- if (this.message != null) {
- message += ": " + this.message;
- }
- return message;
+ public UnknownViewException(String message) {
+ super(message);
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ViewId.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ViewId.java
index 77c7dd6..9a2406e 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ViewId.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ViewId.java
@@ -18,9 +18,6 @@
*/
package org.rhq.enterprise.gui.coregui.client;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* TODO
*
@@ -56,21 +53,14 @@ public class ViewId {
public String getPath() {
if (this.path == null) {
StringBuilder buffer = new StringBuilder();
- List<String> names = new ArrayList<String>(5);
- ViewId current = this;
- do {
- names.add(0, current.getName());
- current = current.getParent();
- } while (current != null && !current.getName().equals(ROOT_VIEW_ID.getName()));
- boolean first = true;
- for (String name : names) {
- if (first) {
- first = false;
- } else {
+ if (this.parent != null) {
+ String parentPath = this.parent.getPath();
+ buffer.append(parentPath);
+ if (!parentPath.equals(ROOT_VIEW_ID.getPath())) {
buffer.append(PATH_SEPARATOR);
}
- buffer.append(name);
}
+ buffer.append(this.name);
this.path = buffer.toString();
}
return this.path;
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ViewRenderer.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ViewRenderer.java
index f2eb39b..d3f237f 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ViewRenderer.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ViewRenderer.java
@@ -27,10 +27,9 @@ public interface ViewRenderer {
/**
* TODO
*
- * @param parentView
* @param viewId
- * @return
- * @throws UnknownViewException
+ *@param parentView @return
+ * @param lastNode @throws UnknownViewException
*/
- View renderView(View parentView, ViewId viewId) throws UnknownViewException;
+ View renderView(ViewId viewId, View parentView, boolean lastNode) throws UnknownViewException;
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/AdministrationView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/AdministrationView.java
index 455b00e..e8804bd 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/AdministrationView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/AdministrationView.java
@@ -391,12 +391,15 @@ public class AdministrationView extends HLayout implements Presenter, ViewRender
return renderedBreadcrumbs;
}
- public View renderView(View parentView, ViewId viewId) throws UnknownViewException {
- String parentPath = viewId.getParent().getPath();
+ public View renderView(ViewId viewId, View parentView, boolean lastNode) throws UnknownViewException {
+ String parentPath = parentView.getId().getPath();
if (parentPath.equals("Administration")) {
SectionStackSection stackSection = this.sectionStack.getSection(viewId.getName());
if (stackSection != null) {
stackSection.setExpanded(true);
+ if (lastNode) {
+ // TODO: Render some default content for the e.g. Administration/Reports view.
+ }
return new View(viewId, new Breadcrumb(viewId.getName(), false));
}
} else if (parentPath.equals("Administration/Reports")) {
@@ -404,6 +407,6 @@ public class AdministrationView extends HLayout implements Presenter, ViewRender
setContent(canvas);
return new View(viewId, canvas);
}
- throw new UnknownViewException(viewId);
+ throw new UnknownViewException();
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceView.java
index aa1f7a9..048db28 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceView.java
@@ -160,14 +160,17 @@ public class ResourceView extends HLayout implements Presenter, ViewRenderer {
contentCanvas.draw();
}
- public View renderView(View parentView, ViewId viewId) throws UnknownViewException {
- String path = viewId.getPathRelativeTo(parentView.getId());
+ public View renderView(ViewId viewId, View parentView, boolean lastNode) throws UnknownViewException {
+ String parentPath = parentView.getId().getPath();
+ if (!parentPath.equals("Resource")) {
+ throw new UnknownViewException();
+ }
int resourceId;
try {
- resourceId = Integer.parseInt(path);
+ resourceId = Integer.parseInt(viewId.getName());
} catch (NumberFormatException e) {
// not a valid Resource id - nothing for us to do
- throw new UnknownViewException(viewId, "Invalid Resource id [" + path + "]");
+ throw new UnknownViewException("Invalid Resource id [" + viewId + "]");
}
if (this.selectedResource == null || this.selectedResource.getId() != resourceId) {
setSelectedResource(resourceId, viewId);
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
index 2011c8c..4391f58 100644
--- a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
+++ b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
@@ -108,7 +108,7 @@ a:hover {
font-size: 12pt;
font-weight: bold;
text-decoration: none;
- color: darkgray;
+ color: #363636;
}
.SectionHeader {
14 years, 2 months
[rhq] Branch 'bundle' - modules/common modules/enterprise
by mazz
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java | 14 -
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java | 17 +
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java | 37 +++
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java | 29 +-
modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java | 101 ++++++++++
modules/enterprise/server/plugins/filetemplate-bundle/src/main/java/org/rhq/enterprise/server/plugins/filetemplate/BundleServerPluginComponent.java | 2
6 files changed, 180 insertions(+), 20 deletions(-)
New commits:
commit c0c6ae1ec0cfe537d9980b9015b5b757de7ac4d6
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Mar 1 15:10:29 2010 -0500
get configdef and deploy to parse - create unit test - support blank/comment lines
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
index 057d474..029222b 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
@@ -45,11 +45,11 @@ public class ConfigdefRecipeCommand implements RecipeCommand {
switch (code) {
case ':':
case '?': {
- throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ throw new IllegalArgumentException("Bad recipe argument.");
}
case 1: {
- throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ throw new IllegalArgumentException("Bad recipe argument!");
}
case 'f': {
@@ -58,12 +58,16 @@ public class ConfigdefRecipeCommand implements RecipeCommand {
}
default: {
- throw new IllegalArgumentException("Unexpected error in recipe command [" + getName() + "]: " + args);
+ throw new IllegalArgumentException("Unexpected error in recipe command");
}
-
}
}
- // TODO : do something with filename
+ if (filename == null) {
+ throw new IllegalArgumentException("Missing the -f argument to indicate what the config def filename is");
+ }
+
+ context.setConfigurationDefinitionFilename(filename);
+ return;
}
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java
index 145398c..5f14f2f 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java
@@ -47,11 +47,11 @@ public class DeployRecipeCommand implements RecipeCommand {
switch (code) {
case ':':
case '?': {
- throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ throw new IllegalArgumentException("Bad recipe command.");
}
case 1: {
- throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ throw new IllegalArgumentException("Bad recipe command!");
}
case 'f': {
@@ -65,12 +65,21 @@ public class DeployRecipeCommand implements RecipeCommand {
}
default: {
- throw new IllegalArgumentException("Unexpected error in recipe command [" + getName() + "]: " + args);
+ throw new IllegalArgumentException("Unexpected error in recipe command");
}
}
}
- // TODO : do something with filename and directory
+ if (filename == null) {
+ throw new IllegalArgumentException("Did not specify the name of the file to deploy");
+ }
+
+ if (directory == null) {
+ throw new IllegalArgumentException("Did not specify the directory where the file should be deployed");
+ }
+
+ context.addDeployFile(filename, directory);
+ return;
}
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
index da96ceb..92c204e 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
@@ -23,15 +23,24 @@
package org.rhq.bundle.filetemplate.recipe;
+import java.util.HashMap;
+import java.util.Map;
+
/**
+ * Contains information that is gleened from a recipe after it is parsed.
+ *
* @author John Mazzitelli
*/
public class RecipeContext {
private final String recipe;
+ private String configurationDefinitionFilename;
+ private Map<String, String> deployFiles;
public RecipeContext(String recipe) {
this.recipe = recipe;
+ this.configurationDefinitionFilename = null;
+ this.deployFiles = new HashMap<String, String>();
}
/**
@@ -42,4 +51,32 @@ public class RecipeContext {
public String getRecipe() {
return recipe;
}
+
+ /**
+ * A recipe can have an optional configuration definition file associated with it.
+ * If this returns non-<code>null</code>, it refers to this configuration definition file.
+ *
+ * @return config def filename
+ */
+ public String getConfigurationDefinitionFilename() {
+ return configurationDefinitionFilename;
+ }
+
+ public void setConfigurationDefinitionFilename(String filename) {
+ this.configurationDefinitionFilename = filename;
+ }
+
+ /**
+ * Returns all the files that are to be deployed. The key is the bundle file's name, the
+ * value is the directory where the bundle is to be deployed to.
+ *
+ * @return map of all files to be deployed and the location where they are to be deployed
+ */
+ public Map<String, String> getDeployFiles() {
+ return this.deployFiles;
+ }
+
+ public void addDeployFile(String filename, String directory) {
+ this.deployFiles.put(filename, directory);
+ }
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
index ff9b91f..b52e807 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
@@ -52,21 +52,30 @@ public class RecipeParser {
BufferedReader recipeReader = new BufferedReader(new StringReader(recipe));
String line = recipeReader.readLine();
while (line != null) {
- String[] commandLineArray = splitCommandLine(line);
- String commandName = commandLineArray[0];
- String[] arguments = extractArguments(commandLineArray);
+ parseRecipeCommandLine(context, line);
+ line = recipeReader.readLine();
+ }
- RecipeCommand recipeCommand = recipeCommands.get(commandName);
- if (recipeCommand == null) {
- throw new Exception("Unknown command in recipe: " + commandName);
- }
+ return context;
+ }
- recipeCommand.parse(context, arguments);
+ public void parseRecipeCommandLine(RecipeContext context, String line) throws Exception {
+ // ignore blank lines or comment lines that start with #
+ if (line == null || line.trim().length() == 0 || line.startsWith("#")) {
+ return;
+ }
- line = recipeReader.readLine();
+ String[] commandLineArray = splitCommandLine(line);
+ String commandName = commandLineArray[0];
+ String[] arguments = extractArguments(commandLineArray);
+
+ RecipeCommand recipeCommand = recipeCommands.get(commandName);
+ if (recipeCommand == null) {
+ throw new Exception("Unknown command in recipe: " + commandName);
}
- return context;
+ recipeCommand.parse(context, arguments);
+ return;
}
private void setupRecipeCommands() {
diff --git a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
new file mode 100644
index 0000000..d573072
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
@@ -0,0 +1,101 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * 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 and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.bundle.filetemplate.recipe;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+@Test
+public class RecipeParserTest {
+ private StringBuilder recipe;
+
+ @BeforeMethod
+ public void cleanRecipeBeforeMethod() {
+ cleanRecipe();
+ }
+
+ public void testSimpleRecipe() throws Exception {
+ addRecipeCommand("deploy -f jboss.tar -d /opt/jboss");
+ addRecipeCommand("configdef -f config.xml");
+ RecipeParser parser = new RecipeParser();
+ RecipeContext context = parser.parseRecipe(getRecipe());
+ assert context.getConfigurationDefinitionFilename().equals("config.xml");
+ assert context.getDeployFiles().containsKey("jboss.tar");
+ assert context.getDeployFiles().get("jboss.tar").equals("/opt/jboss");
+ }
+
+ public void testSimpleRecipeError() throws Exception {
+ addRecipeCommand("deploy -f jboss.tar");
+ RecipeParser parser = new RecipeParser();
+
+ try {
+ parser.parseRecipe(getRecipe());
+ assert false : "This should have failed - need to provide a -d to the deploy command";
+ } catch (Exception ok) {
+ // to be expected
+ }
+
+ cleanRecipe();
+ addRecipeCommand("configdef");
+
+ try {
+ parser.parseRecipe(getRecipe());
+ assert false : "This should have failed - need to provide a -f to the configdef command";
+ } catch (Exception ok) {
+ // to be expected
+ }
+ }
+
+ public void testSimpleRecipeComments() throws Exception {
+ addRecipeCommand("");
+ addRecipeCommand("#");
+ addRecipeCommand("### comment here");
+ addRecipeCommand("deploy -f jboss.tar -d /opt/jboss");
+ addRecipeCommand("");
+ addRecipeCommand("#");
+ addRecipeCommand("### comment here");
+ addRecipeCommand("configdef -f config.xml");
+ addRecipeCommand("");
+ addRecipeCommand("#");
+ addRecipeCommand("### comment here");
+ addRecipeCommand("");
+ RecipeParser parser = new RecipeParser();
+ RecipeContext context = parser.parseRecipe(getRecipe());
+ assert context.getConfigurationDefinitionFilename().equals("config.xml");
+ assert context.getDeployFiles().containsKey("jboss.tar");
+ assert context.getDeployFiles().get("jboss.tar").equals("/opt/jboss");
+ }
+
+ private void cleanRecipe() {
+ this.recipe = new StringBuilder();
+ }
+
+ private void addRecipeCommand(String commandLine) {
+ this.recipe.append(commandLine).append("\n");
+ }
+
+ private String getRecipe() {
+ return this.recipe.toString();
+ }
+}
diff --git a/modules/enterprise/server/plugins/filetemplate-bundle/src/main/java/org/rhq/enterprise/server/plugins/filetemplate/BundleServerPluginComponent.java b/modules/enterprise/server/plugins/filetemplate-bundle/src/main/java/org/rhq/enterprise/server/plugins/filetemplate/BundleServerPluginComponent.java
index 96f7070..a67fc1a 100644
--- a/modules/enterprise/server/plugins/filetemplate-bundle/src/main/java/org/rhq/enterprise/server/plugins/filetemplate/BundleServerPluginComponent.java
+++ b/modules/enterprise/server/plugins/filetemplate-bundle/src/main/java/org/rhq/enterprise/server/plugins/filetemplate/BundleServerPluginComponent.java
@@ -68,7 +68,7 @@ public class BundleServerPluginComponent implements ServerPluginComponent, Bundl
RecipeParser parser = new RecipeParser();
RecipeContext parserContext = parser.parseRecipe(recipe);
- // TODO convert the context to the results object
+ // TODO convert the context into the proper data that the parse results wants
ConfigurationDefinition configDef = null;
Set<String> bundleFileNames = null;
14 years, 2 months
[rhq] Branch 'alertPlus' - 2 commits - modules/enterprise
by Heiko W. Rupp
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListAlertHistoryUIBean.java | 10
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/ParamConstants.java | 11
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/AlertDefUtil.java | 21 +
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/ConditionBean.java | 76 ++++
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/DefinitionForm.java | 37 +-
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/DefinitionFormPrepareAction.java | 40 ++
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/condition/CallTimeDataConverterValidator.java | 159 ++++++++++
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/condition/ConverterValidatorManager.java | 16 -
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/subsystem/SubsystemAlertHistoryUIBean.java | 12
modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties | 11
modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/DefinitionCondition.jsp | 156 +++++++--
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/AlertConditionCacheManagerBean.java | 9
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/AlertConditionCacheManagerLocal.java | 15
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/internal/AbstractConditionCache.java | 3
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/internal/AgentConditionCache.java | 146 ++++++++-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/internal/AlertConditionCacheCoordinator.java | 46 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/jms/CachedConditionProducerBean.java | 11
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/jms/CachedConditionProducerLocal.java | 6
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/model/AbstractCacheElement.java | 6
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/model/CallTimeDataCacheElement.java | 152 +++++++++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBean.java | 14
21 files changed, 869 insertions(+), 88 deletions(-)
New commits:
commit 99d3e5e1ae37b44344a4bba4dd913eb60e541d18
Author: Frank Brueseke <fbrueseke(a)s-lab.upb.de>
Date: Mon Mar 1 20:50:00 2010 +0100
Allow alerting on call-time data. BZ 535756
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListAlertHistoryUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListAlertHistoryUIBean.java
index 0b6023a..ad6a2d7 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListAlertHistoryUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/ListAlertHistoryUIBean.java
@@ -40,6 +40,7 @@ import org.rhq.core.domain.alert.AlertPriority;
import org.rhq.core.domain.alert.composite.AlertWithLatestConditionLog;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.common.composite.IntegerOptionItem;
+import org.rhq.core.domain.measurement.DataType;
import org.rhq.core.domain.measurement.util.MeasurementConverter;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.util.PageControl;
@@ -114,8 +115,8 @@ public class ListAlertHistoryUIBean extends PagedDataTableUIBean {
public SelectItem[] getAlertDefinitionSelectItems() {
if (alertDefinitionSelectItems == null) {
- List<IntegerOptionItem> optionItems = alertDefinitionManager.findAlertDefinitionOptionItemsForResource(getSubject(),
- getResource().getId());
+ List<IntegerOptionItem> optionItems = alertDefinitionManager.findAlertDefinitionOptionItemsForResource(
+ getSubject(), getResource().getId());
alertDefinitionSelectItems = SelectItemUtils.convertFromListOptionItem(optionItems, true);
}
@@ -267,7 +268,8 @@ public class ListAlertHistoryUIBean extends PagedDataTableUIBean {
String displayText = AlertDefUtil.formatAlertConditionForDisplay(condition, request);
String firedValue = log.getValue();
- if (condition.getMeasurementDefinition() != null) {
+ if (condition.getMeasurementDefinition() != null
+ && !condition.getMeasurementDefinition().getDataType().equals(DataType.CALLTIME)) {
firedValue = MeasurementConverter.format(Double.valueOf(log.getValue()), condition
.getMeasurementDefinition().getUnits(), true);
}
@@ -302,4 +304,4 @@ public class ListAlertHistoryUIBean extends PagedDataTableUIBean {
private String[] getSelectedAlerts() {
return FacesContextUtility.getRequest().getParameterValues("selectedAlerts");
}
-}
\ No newline at end of file
+}
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/ParamConstants.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/ParamConstants.java
index a659e89..d113c15 100755
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/ParamConstants.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/ParamConstants.java
@@ -84,6 +84,15 @@ public interface ParamConstants {
*/
public static final String ALERT_THRESHOLD_COMPARATOR_LT = "<";
+ public static final String CALLTIME_MAX = "MAX";
+ public static final String CALLTIME_MIN = "MIN";
+ public static final String CALLTIME_AVG = "AVG";
+ public static final String CALLTIME_COUNT = "COUNT";
+
+ public static final String CALLTIME_CHANGES = "CH";
+ public static final String CALLTIME_SHRINKS = "LO";
+ public static final String CALLTIME_GROWS = "HI";
+
/**
* The request parameter that specifies the resource type of the autogroup resources of the currently viewed
* resource.
@@ -535,4 +544,4 @@ public interface ParamConstants {
String LIST_NAME_PARAM = "listName";
String LIST_INDEX_PARAM = "listIndex";
-}
\ No newline at end of file
+}
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/AlertDefUtil.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/AlertDefUtil.java
index c22d823..a3fdb84 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/AlertDefUtil.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/AlertDefUtil.java
@@ -35,6 +35,7 @@ import org.rhq.core.domain.alert.AlertDampening;
import org.rhq.core.domain.alert.AlertDefinition;
import org.rhq.core.domain.alert.AlertDefinitionContext;
import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.measurement.DataType;
import org.rhq.core.domain.measurement.MeasurementSchedule;
import org.rhq.core.domain.measurement.MeasurementUnits;
import org.rhq.core.domain.measurement.util.MeasurementConverter;
@@ -104,6 +105,12 @@ public final class AlertDefUtil {
} else if (category == AlertConditionCategory.RESOURCE_CONFIG) {
textValue.append(RequestUtils.message(request, "alert.config.props.CB.Content.ResourceConfiguration"))
.append(' ');
+ } else if (cond.getMeasurementDefinition() != null
+ && cond.getMeasurementDefinition().getDataType().equals(DataType.CALLTIME)) {
+ textValue.append(cond.getMeasurementDefinition().getDisplayName());
+ textValue.append(" (");
+ textValue.append(cond.getOption());
+ textValue.append(") ");
} else {
textValue.append(cond.getName()).append(' ');
}
@@ -135,7 +142,17 @@ public final class AlertDefUtil {
}
} else if (category == AlertConditionCategory.RESOURCE_CONFIG || category == AlertConditionCategory.CHANGE
|| category == AlertConditionCategory.TRAIT) {
- textValue.append(RequestUtils.message(request, "alert.current.list.ValueChanged"));
+ if (cond.getComparator() != null) {
+ textValue.append(RequestUtils.message(request, "common.field.value")).append(' ');
+ textValue.append(RequestUtils.message(request, "alert.config.props.CB.Content.CalltimeOperators."
+ + cond.getComparator()));
+ } else
+ textValue.append(RequestUtils.message(request, "alert.current.list.ValueChanged"));
+ if (cond.getThreshold() != null) {
+ textValue.append(" ").append(RequestUtils.message(request, "alert.config.props.CB.Content.AtLeast"));
+ textValue.append(" ").append(
+ MeasurementConverter.format(cond.getThreshold(), MeasurementUnits.PERCENTAGE, true));
+ }
} else if (category == AlertConditionCategory.EVENT) {
String msgKey = "alert.config.props.CB.EventSeverity";
List<String> args = new ArrayList<String>(2);
@@ -298,4 +315,4 @@ public final class AlertDefUtil {
return "N/A";
}
-}
\ No newline at end of file
+}
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/ConditionBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/ConditionBean.java
index ce09ad9..9d8cbd4 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/ConditionBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/ConditionBean.java
@@ -39,6 +39,14 @@ public final class ConditionBean {
private String metricName;
private String absoluteValue;
private String percentage;
+ private String calltimeComparator;
+ private String ctAbsoluteValue;
+ private String calltimeAbsOption;
+ private String calltimeAbsPattern;
+ private String ctPercentage;
+ private String calltimeChgOp;
+ private String calltimeChgOption;
+ private String calltimeChgPattern;
private String baselineOption;
private String controlAction;
private String controlActionStatus;
@@ -207,6 +215,72 @@ public final class ConditionBean {
this.traitName = traitName;
}
+ public String getCalltimeComparator() {
+ return calltimeComparator;
+ }
+
+ public void setCalltimeComparator(String calltimeComparator) {
+ this.calltimeComparator = calltimeComparator;
+ }
+
+ public String getCtAbsoluteValue() {
+ return ctAbsoluteValue;
+ }
+
+ public void setCtAbsoluteValue(String ctAbsoluteValue) {
+ this.ctAbsoluteValue = ctAbsoluteValue;
+ }
+
+ public String getCalltimeAbsOption() {
+ return calltimeAbsOption;
+ }
+
+ public void setCalltimeAbsOption(String calltimeAbsOption) {
+ this.calltimeAbsOption = calltimeAbsOption;
+ }
+
+ public String getCalltimeAbsPattern() {
+ return calltimeAbsPattern;
+ }
+
+ public void setCalltimeAbsPattern(String calltimeAbsPattern) {
+ if (calltimeAbsPattern != null && !calltimeAbsPattern.trim().equals(""))
+ this.calltimeAbsPattern = calltimeAbsPattern;
+ }
+
+ public String getCtPercentage() {
+ return ctPercentage;
+ }
+
+ public void setCtPercentage(String ctPercentage) {
+ this.ctPercentage = ctPercentage;
+ }
+
+ public String getCalltimeChgOption() {
+ return calltimeChgOption;
+ }
+
+ public void setCalltimeChgOption(String calltimeChgOption) {
+ this.calltimeChgOption = calltimeChgOption;
+ }
+
+ public String getCalltimeChgPattern() {
+ return calltimeChgPattern;
+ }
+
+ public void setCalltimeChgPattern(String calltimeChgPattern) {
+ if (calltimeChgPattern != null && !calltimeChgPattern.trim().equals(""))
+ this.calltimeChgPattern = calltimeChgPattern;
+ }
+
+ public String getCalltimeChgOp() {
+ return calltimeChgOp;
+ }
+
+ public void setCalltimeChgOp(String calltimeChgOp) {
+ this.calltimeChgOp = calltimeChgOp;
+ }
+
public void importProperties(AlertCondition cond, Subject subject) throws Exception {
ConverterValidatorManager.importProperties(subject, cond, this);
}
@@ -218,4 +292,4 @@ public final class ConditionBean {
public boolean validate(HttpServletRequest request, ActionErrors errors, int index) {
return ConverterValidatorManager.validate(this, errors, index);
}
-}
\ No newline at end of file
+}
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/DefinitionForm.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/DefinitionForm.java
index a29da61..fe9764d 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/DefinitionForm.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/DefinitionForm.java
@@ -102,6 +102,7 @@ public final class DefinitionForm extends ResourceForm {
private Collection baselines;
private List<MeasurementDefinition> metrics;
private List<MeasurementDefinition> traits;
+ private List<MeasurementDefinition> calltimeMetrics;
private Collection<Map.Entry<String, Integer>> alertnames;
private Collection<Map.Entry<String, String>> conditionExpressionNames;
private boolean resourceConfigurationSupported;
@@ -137,6 +138,12 @@ public final class DefinitionForm extends ResourceForm {
private static String[] comparators = new String[] { Constants.ALERT_THRESHOLD_COMPARATOR_GT,
Constants.ALERT_THRESHOLD_COMPARATOR_EQ, Constants.ALERT_THRESHOLD_COMPARATOR_LT };
+ private static String[] calltimeOptions = new String[] { Constants.CALLTIME_MAX, Constants.CALLTIME_MIN,
+ Constants.CALLTIME_AVG, Constants.CALLTIME_COUNT };
+
+ private static String[] calltimeOperators = new String[] { Constants.CALLTIME_SHRINKS, Constants.CALLTIME_CHANGES,
+ Constants.CALLTIME_GROWS };
+
// special form handlers
private boolean addingCondition;
private int deletedCondition;
@@ -232,12 +239,6 @@ public final class DefinitionForm extends ResourceForm {
*/
public void setMetricId(int metricId) {
this.metricId = metricId;
-
- // Select default metric
- if (metricId > 0) {
- this.getCondition(0).setMetricId(metricId);
- this.getCondition(0).setTrigger("onMeasurement");
- }
}
public String getMetricName() {
@@ -763,4 +764,28 @@ public final class DefinitionForm extends ResourceForm {
public void setReadOnly(boolean readOnly) {
this.readOnly = readOnly;
}
+
+ public List<MeasurementDefinition> getCalltimeMetrics() {
+ return calltimeMetrics;
+ }
+
+ public void setCalltimeMetrics(List<MeasurementDefinition> calltimeMetrics) {
+ this.calltimeMetrics = calltimeMetrics;
+ }
+
+ public String[] getCalltimeOptions() {
+ return calltimeOptions;
+ }
+
+ public void setCalltimeOptions(String[] calltimeOptions) {
+ DefinitionForm.calltimeOptions = calltimeOptions;
+ }
+
+ public String[] getCalltimeOperators() {
+ return calltimeOperators;
+ }
+
+ public void setCalltimeOperators(String[] calltimeOperators) {
+ DefinitionForm.calltimeOperators = calltimeOperators;
+ }
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/DefinitionFormPrepareAction.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/DefinitionFormPrepareAction.java
index bf20899..ffc4e7c 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/DefinitionFormPrepareAction.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/DefinitionFormPrepareAction.java
@@ -92,11 +92,9 @@ public abstract class DefinitionFormPrepareAction extends TilesAction {
log.trace("defForm.numConditions=" + defForm.getNumConditions());
request.setAttribute("numConditions", defForm.getNumConditions());
- request.setAttribute("showMetrics", defForm.getMetrics().size() > 0);
- request.setAttribute("showTraits", defForm.getTraits().size() > 0);
- request.setAttribute("showResourceConfiguration", defForm.isResourceConfigurationSupported());
- request.setAttribute("showAvailability", defForm.getAvailabilityOptions().length > 0);
- request.setAttribute("showOperations", defForm.getControlActions().size() > 0);
+ // process data types from bottom to top and set the initialise
+ // the top-most "trigger" radio button
+ boolean triggerNotSet = defForm.getCondition(0).getTrigger() == null;
ResourceType type = null;
Subject overlord = LookupUtil.getSubjectManager().getOverlord();
@@ -113,6 +111,32 @@ public abstract class DefinitionFormPrepareAction extends TilesAction {
}
int eventDefinitionCount = LookupUtil.getEventManager().getEventDefinitionCountForResourceType(type.getId());
request.setAttribute("showEvents", eventDefinitionCount > 0);
+ if (eventDefinitionCount > 0 && triggerNotSet)
+ defForm.getCondition(0).setTrigger("onEvent");
+
+ request.setAttribute("showOperations", defForm.getControlActions().size() > 0);
+ if (defForm.getControlActions().size() > 0 && triggerNotSet)
+ defForm.getCondition(0).setTrigger("onOperation");
+
+ request.setAttribute("showAvailability", defForm.getAvailabilityOptions().length > 0);
+ if (defForm.getAvailabilityOptions().length > 0 && triggerNotSet)
+ defForm.getCondition(0).setTrigger("onAvailability");
+
+ request.setAttribute("showResourceConfiguration", defForm.isResourceConfigurationSupported());
+ if (defForm.isResourceConfigurationSupported() && triggerNotSet)
+ defForm.getCondition(0).setTrigger("onResourceConfiguration");
+
+ request.setAttribute("showTraits", defForm.getTraits().size() > 0);
+ if (defForm.getTraits().size() > 0 && triggerNotSet)
+ defForm.getCondition(0).setTrigger("onTrait");
+
+ request.setAttribute("showCalltimeMetrics", defForm.getCalltimeMetrics().size() > 0);
+ if (defForm.getCalltimeMetrics().size() > 0 && triggerNotSet)
+ defForm.getCondition(0).setTrigger("onCallTime");
+
+ request.setAttribute("showMetrics", defForm.getMetrics().size() > 0);
+ if (defForm.getMetrics().size() > 0 && triggerNotSet)
+ defForm.getCondition(0).setTrigger("onMeasurement");
return null;
}
@@ -152,6 +176,9 @@ public abstract class DefinitionFormPrepareAction extends TilesAction {
List<MeasurementDefinition> dataDefinitions = definitionManager.findMeasurementDefinitionsByResourceType(
subject, type.getId(), DataType.MEASUREMENT, null);
+ List<MeasurementDefinition> calltimeDefinitions = definitionManager.findMeasurementDefinitionsByResourceType(
+ subject, type.getId(), DataType.CALLTIME, null);
+
List<MeasurementDefinition> traitDefinitions = definitionManager.findMeasurementDefinitionsByResourceType(
subject, type.getId(), DataType.TRAIT, null);
@@ -184,6 +211,7 @@ public abstract class DefinitionFormPrepareAction extends TilesAction {
}
defForm.setMetrics(dataDefinitions);
+ defForm.setCalltimeMetrics(calltimeDefinitions);
defForm.setTraits(traitDefinitions);
defForm.setBaselines(baselines);
@@ -231,4 +259,4 @@ public abstract class DefinitionFormPrepareAction extends TilesAction {
return list;
}
-}
\ No newline at end of file
+}
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/condition/ConverterValidatorManager.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/condition/ConverterValidatorManager.java
index 3f388a2..d41a3cd 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/condition/ConverterValidatorManager.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/condition/ConverterValidatorManager.java
@@ -23,12 +23,14 @@ import org.apache.struts.action.ActionErrors;
import org.rhq.core.domain.alert.AlertCondition;
import org.rhq.core.domain.alert.AlertConditionCategory;
import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.measurement.DataType;
import org.rhq.enterprise.gui.legacy.action.resource.common.monitor.alerts.config.ConditionBean;
public class ConverterValidatorManager {
private static AvailabilityConverterValidator availabilityConverter;
private static EventsConverterValidator eventsConverter;
private static MeasurementConverterValidator measurementConverter;
+ private static CallTimeDataConverterValidator calltimeConverter;
private static OperationConverterValidator operationConverter;
private static TraitConverterValidator traitConverter;
private static ResourceConfigurationConverterValidator resourceConfigurationConverter;
@@ -37,6 +39,7 @@ public class ConverterValidatorManager {
availabilityConverter = new AvailabilityConverterValidator();
eventsConverter = new EventsConverterValidator();
measurementConverter = new MeasurementConverterValidator();
+ calltimeConverter = new CallTimeDataConverterValidator();
operationConverter = new OperationConverterValidator();
traitConverter = new TraitConverterValidator();
resourceConfigurationConverter = new ResourceConfigurationConverterValidator();
@@ -49,6 +52,8 @@ public class ConverterValidatorManager {
measurementConverter.exportProperties(subject, fromBean, toCondition);
} else if (fromBean.getTrigger().equals(traitConverter.getTriggerName())) {
traitConverter.exportProperties(subject, fromBean, toCondition);
+ } else if (fromBean.getTrigger().equals(calltimeConverter.getTriggerName())) {
+ calltimeConverter.exportProperties(subject, fromBean, toCondition);
} else if (fromBean.getTrigger().equals(eventsConverter.getTriggerName())) {
eventsConverter.exportProperties(subject, fromBean, toCondition);
} else if (fromBean.getTrigger().equals(availabilityConverter.getTriggerName())) {
@@ -70,7 +75,13 @@ public class ConverterValidatorManager {
if ((category == AlertConditionCategory.THRESHOLD) || (category == AlertConditionCategory.BASELINE)
|| (category == AlertConditionCategory.CHANGE)) {
- measurementConverter.importProperties(subject, fromCondition, toBean);
+ DataType measDataType = null;
+ if (fromCondition.getMeasurementDefinition() != null)
+ measDataType = fromCondition.getMeasurementDefinition().getDataType();
+ if (DataType.CALLTIME.equals(measDataType))
+ calltimeConverter.importProperties(subject, fromCondition, toBean);
+ else
+ measurementConverter.importProperties(subject, fromCondition, toBean);
} else if (category == AlertConditionCategory.TRAIT) {
traitConverter.importProperties(subject, fromCondition, toBean);
} else if (category == AlertConditionCategory.EVENT) {
@@ -90,6 +101,8 @@ public class ConverterValidatorManager {
public static boolean validate(ConditionBean bean, ActionErrors errors, int index) {
if (bean.getTrigger().equals(measurementConverter.getTriggerName())) {
return measurementConverter.validate(bean, errors, index);
+ } else if (bean.getTrigger().equals(calltimeConverter.getTriggerName())) {
+ return calltimeConverter.validate(bean, errors, index);
} else if (bean.getTrigger().equals(traitConverter.getTriggerName())) {
return traitConverter.validate(bean, errors, index);
} else if (bean.getTrigger().equals(eventsConverter.getTriggerName())) {
@@ -107,7 +120,6 @@ public class ConverterValidatorManager {
}
public static void setDefaults(ConditionBean bean) {
- bean.setTrigger(measurementConverter.getTriggerName());
bean.setThresholdType(MeasurementConverterValidator.TYPE_ABS);
}
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/subsystem/SubsystemAlertHistoryUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/subsystem/SubsystemAlertHistoryUIBean.java
index 0ad0c7a..3483950 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/subsystem/SubsystemAlertHistoryUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/subsystem/SubsystemAlertHistoryUIBean.java
@@ -33,6 +33,7 @@ import org.rhq.core.domain.alert.AlertConditionCategory;
import org.rhq.core.domain.alert.AlertConditionLog;
import org.rhq.core.domain.alert.composite.AlertHistoryComposite;
import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.measurement.DataType;
import org.rhq.core.domain.measurement.util.MeasurementConverter;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.util.PageControl;
@@ -67,12 +68,12 @@ public class SubsystemAlertHistoryUIBean extends SubsystemView {
private SelectItem[] categoryFilterItems;
private static final IntExtractor<AlertHistoryComposite> RESOURCE_ID_EXTRACTOR = new IntExtractor<AlertHistoryComposite>() {
-
+
public int extract(AlertHistoryComposite object) {
return object.getAlert().getAlertDefinition().getResource().getId();
}
};
-
+
public SubsystemAlertHistoryUIBean() {
datePattern = EnterpriseFacesContextUtility.getWebUser().getWebPreferences().getDateTimeDisplayPreferences()
.getDateTimeFormatTrigger();
@@ -221,7 +222,8 @@ public class SubsystemAlertHistoryUIBean extends SubsystemView {
String displayText = AlertDefUtil.formatAlertConditionForDisplay(condition, request);
String firedValue = log.getValue();
- if (condition.getMeasurementDefinition() != null) {
+ if (condition.getMeasurementDefinition() != null
+ && !condition.getMeasurementDefinition().getDataType().equals(DataType.CALLTIME)) {
firedValue = MeasurementConverter.format(Double.valueOf(log.getValue()), condition
.getMeasurementDefinition().getUnits(), true);
}
@@ -243,7 +245,7 @@ public class SubsystemAlertHistoryUIBean extends SubsystemView {
protected IntExtractor<AlertHistoryComposite> getResourceIdExtractor() {
return RESOURCE_ID_EXTRACTOR;
}
-
+
private void getDataFromRequest() {
SubsystemAlertHistoryUIBean outer = SubsystemAlertHistoryUIBean.this;
outer.resourceFilter = FacesContextUtility.getOptionalRequestParameter(FORM_PREFIX + "resourceFilter");
@@ -269,4 +271,4 @@ public class SubsystemAlertHistoryUIBean extends SubsystemView {
return null;
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties b/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties
index 8132311..bae0844 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties
+++ b/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties
@@ -2055,6 +2055,7 @@ alert.config.props.CB.Content.Filter=Filter notification actions that are define
alert.config.props.CB.ActualValue=Actual Value:
alert.config.props.CB.NoActualValue=Not Available
alert.config.props.CB.Content.Metric=Metric:
+alert.config.props.CB.Content.Calltime=Call-time metric:
alert.config.props.CB.Content.Trait=Trait:
alert.config.props.CB.Content.ResourceConfiguration=Resource Configuration
alert.config.props.CB.Content.CustomProperty=Inventory Property:
@@ -2068,6 +2069,8 @@ alert.config.props.CB.Content.WithStatus=with status:
alert.config.props.CB.Content.Is=is
alert.config.props.CB.Content.AbsoluteValue=(absolute value)
alert.config.props.CB.Content.Changes=value changes
+alert.config.props.CB.Content.AtLeast=by at least
+alert.config.props.CB.Content.CallDestMatches=and call destination matches expression (optional)
alert.config.props.CB.Content.Match=and matches expression (optional):
alert.config.props.CB.Content.Log=Events/Logs Level:
alert.config.props.CB.Content.Recalculate=Recalculate...
@@ -2075,6 +2078,13 @@ alert.config.props.CB.Content.Percent=% of
alert.config.props.CB.Content.Comparator.>= > (Greater than)
alert.config.props.CB.Content.Comparator.<= < (Less than)
alert.config.props.CB.Content.Comparator.\== = (Equal to)
+alert.config.props.CB.Content.CalltimeOptions.MAX=Maximum
+alert.config.props.CB.Content.CalltimeOptions.MIN=Minimum
+alert.config.props.CB.Content.CalltimeOptions.AVG=Average
+alert.config.props.CB.Content.CalltimeOptions.COUNT=Count
+alert.config.props.CB.Content.CalltimeOperators.LO=shrinks
+alert.config.props.CB.Content.CalltimeOperators.CH=changes
+alert.config.props.CB.Content.CalltimeOperators.HI=grows
alert.config.props.CB.Content.ActionFilters=Action Filters:
alert.config.props.CB.Content.Disregard=Disregard operations that are defined for related alerts.
@@ -2195,6 +2205,7 @@ events.alert.AlertNotificationActionTitle=Alert Notification Action
alert.config.error.InvalidEmailAddress=The email addresses {0} has invalid syntax: {1}.
alert.config.error.InvalidEmailAddresses=One or more of the email addresses entered had invalid syntax: {0}.
alert.config.error.NoMetricSelected=You must select a metric for this condition.
+alert.config.error.CalltimePatternError=You must enter a valid Java regular expression.
alert.config.error.NoCustomPropertySelected=You must select an inventory property for this condition.
alert.config.error.NoControlActionSelected=You must select an operation for this condition.
alert.config.error.NoControlActionStatusSelected=You must select an operation status for this condition.
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/DefinitionCondition.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/DefinitionCondition.jsp
index cb76ebe..5ddc201 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/DefinitionCondition.jsp
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/DefinitionCondition.jsp
@@ -17,15 +17,15 @@
<td width="20%" class="BlockLabel">
<b><fmt:message key="alert.config.props.CB.IfCondition"/></b>
</td>
-
+
<c:if test="${showMetrics}" > <!-- begin conditional metric display logic -->
-
+
<logic:messagesPresent property="condition[${i}].metricId"><td width="80%" class="ErrorField"></logic:messagesPresent>
<logic:messagesNotPresent property="condition[${i}].metricId"><td width="80%" class="BlockContent"></logic:messagesNotPresent>
<html:radio property="condition[${i}].trigger" value="onMeasurement"/>
<fmt:message key="alert.config.props.CB.Content.Metric"/>
<c:set var="seldd"><fmt:message key="alert.dropdown.SelectOption"/></c:set>
- <html:select property="condition[${i}].metricId"
+ <html:select property="condition[${i}].metricId"
onchange="javascript:selectMetric('condition[${i}].metricId', 'condition[${i}].metricName');changeDropDown('condition[${i}].metricId', 'condition[${i}].baselineOption', '${seldd}');">
<html:option value="-1" key="alert.dropdown.SelectOption"/>
<html:optionsCollection property="metrics" label="displayName" value="id"/>
@@ -40,14 +40,14 @@
<tr>
<td class="BlockLabel"> </td>
<td class="BlockContent">
-
+
<table width="100%" border="0" cellspacing="0" cellpadding="2">
- <tr>
+ <tr>
<td nowrap="true"><div style="width: 60px; position: relative;"/><html:img page="/images/schedule_return.gif" width="17" height="21" border="0" align="right"/></td>
<logic:messagesPresent property="condition[${i}].absoluteValue"><td width="100%" class="ErrorField"></logic:messagesPresent>
<logic:messagesNotPresent property="condition[${i}].absoluteValue"><td width="100%"></logic:messagesNotPresent>
<html:radio property="condition[${i}].thresholdType" value="absolute"/>
-
+
<fmt:message key="alert.config.props.CB.Content.Is"/>
<html:select property="condition[${i}].absoluteComparator">
<hq:optionMessageList property="comparators" baseKey="alert.config.props.CB.Content.Comparator" filter="true"/>
@@ -58,7 +58,7 @@
</logic:messagesPresent>
</td>
</tr>
- <tr>
+ <tr>
<td> </td>
<logic:messagesPresent property="condition[${i}].percentage"><c:set var="percentageErrs" value="true"/></logic:messagesPresent>
<logic:messagesPresent property="condition[${i}].baselineOption"><c:set var="baselineOptionErrs" value="true"/></logic:messagesPresent>
@@ -86,7 +86,7 @@
var baselineOption = '<c:out value="${NewAlertDefinitionForm.conditions[i].baselineOption}"/>';
changeDropDown('condition[<c:out value="${i}"/>].metricId', 'condition[<c:out value="${i}"/>].baselineOption', '<c:out value="${seldd}"/>', baselineOption);
</script>
- </c:if>
+ </c:if>
<c:if test="${percentageErrs || baselineOptionErrs}">
<span class="ErrorFieldContent">
<c:if test="${percentageErrs}"><br>- <html:errors property="condition[${i}].percentage"/></c:if>
@@ -103,7 +103,98 @@
</td>
</tr>
</table>
-
+
+ </td>
+</tr>
+
+<tr>
+ <td class="BlockLabel"> </td>
+
+</c:if> <!-- end conditional metric display logic -->
+<c:if test="${showCalltimeMetrics}" > <!-- begin conditional call-time metric display logic -->
+
+ <logic:messagesPresent property="condition[${i}].metricId"><td width="80%" class="ErrorField"></logic:messagesPresent>
+ <logic:messagesNotPresent property="condition[${i}].metricId"><td width="80%" class="BlockContent"></logic:messagesNotPresent>
+ <html:radio property="condition[${i}].trigger" value="onCallTime"/>
+ <fmt:message key="alert.config.props.CB.Content.Calltime"/>
+ <c:set var="seldd"><fmt:message key="alert.dropdown.SelectOption"/></c:set>
+ <html:select property="condition[${i}].metricId">
+ <html:option value="-1" key="alert.dropdown.SelectOption"/>
+ <html:optionsCollection property="calltimeMetrics" label="displayName" value="id"/>
+ </html:select>
+ <logic:messagesPresent property="condition[${i}].metricId">
+ <span class="ErrorFieldContent">- <html:errors property="condition[${i}].metricId"/></span>
+ </logic:messagesPresent>
+ </td>
+</tr>
+
+<tr>
+ <td class="BlockLabel"> </td>
+ <td class="BlockContent">
+
+ <table width="100%" border="0" cellspacing="0" cellpadding="2">
+ <tr>
+ <td nowrap="true"><div style="width: 60px; position: relative;"/><html:img page="/images/schedule_return.gif" width="17" height="21" border="0" align="right"/></td>
+ <logic:messagesPresent property="condition[${i}].ctAbsoluteValue"><c:set var="ctAbsValueErrs" value="true"/></logic:messagesPresent>
+ <logic:messagesPresent property="condition[${i}].calltimeAbsPattern"><c:set var="callDestAbsPatternErrs" value="true"/></logic:messagesPresent>
+ <c:choose>
+ <c:when test="${ctAbsValueErrs || callDestAbsPatternErrs}"><td width="100%" class="ErrorField"></c:when>
+ <c:otherwise><td width="100%"></c:otherwise>
+ </c:choose>
+ <logic:messagesPresent property="condition[${i}].calltimeOption"><c:set var="calltimeOptionErrs" value="true"/></logic:messagesPresent>
+ <html:radio property="condition[${i}].thresholdType" value="absolute"/>
+
+ <html:select property="condition[${i}].calltimeAbsOption">
+ <hq:optionMessageList property="calltimeOptions" baseKey="alert.config.props.CB.Content.CalltimeOptions" filter="true"/>
+ </html:select>
+ <fmt:message key="alert.config.props.CB.Content.Is"/>
+ <html:select property="condition[${i}].calltimeComparator">
+ <hq:optionMessageList property="comparators" baseKey="alert.config.props.CB.Content.Comparator" filter="true"/>
+ </html:select>
+ <html:text property="condition[${i}].ctAbsoluteValue" size="8" maxlength="15"/> <fmt:message key="alert.config.props.CB.Content.AbsoluteValue"/>
+ <fmt:message key="alert.config.props.CB.Content.CallDestMatches"/>
+ <html:text property="condition[${i}].calltimeAbsPattern" size="8" maxlength="15"/>
+ <c:if test="${ctAbsValueErrs || callDestAbsPatternErrs}">
+ <span class="ErrorFieldContent">
+ <c:if test="${ctAbsValueErrs}"><br>- <html:errors property="condition[${i}].ctAbsoluteValue"/></c:if>
+ <c:if test="${callDestAbsPatternErrs}"><br>- <html:errors property="condition[${i}].calltimeAbsPattern"/></c:if>
+ </span>
+ </c:if>
+ </td>
+ </tr>
+ <tr>
+ <td> </td>
+ <logic:messagesPresent property="condition[${i}].ctPercentage"><c:set var="ctPercErrs" value="true"/></logic:messagesPresent>
+ <logic:messagesPresent property="condition[${i}].calltimeChgPattern"><c:set var="callDestChgPatternErrs" value="true"/></logic:messagesPresent>
+ <c:choose>
+ <c:when test="${ctPercErrs || callDestChgPatternErrs}"><td width="100%" class="ErrorField"></c:when>
+ <c:otherwise><td width="100%"></c:otherwise>
+ </c:choose>
+ <logic:messagesPresent property="condition[${i}].calltimeOption"><c:set var="calltimeOptionErrs" value="true"/></logic:messagesPresent>
+ <html:radio property="condition[${i}].thresholdType" value="changed"/>
+ <html:select property="condition[${i}].calltimeChgOption">
+ <hq:optionMessageList property="calltimeOptions" baseKey="alert.config.props.CB.Content.CalltimeOptions" filter="true"/>
+ </html:select>
+ <html:select property="condition[${i}].calltimeChgOp">
+ <hq:optionMessageList property="calltimeOperators" baseKey="alert.config.props.CB.Content.CalltimeOperators" filter="true"/>
+ </html:select>
+ <fmt:message key="alert.config.props.CB.Content.AtLeast"/>
+ <html:text property="condition[${i}].ctPercentage" size="6" maxlength="6"/> %
+ <logic:messagesPresent property="condition[${i}].ctPercentage">
+ <br><span class="ErrorFieldContent">- <html:errors property="condition[${i}].percentage"/></span>
+ </logic:messagesPresent>
+ <fmt:message key="alert.config.props.CB.Content.CallDestMatches"/>
+ <html:text property="condition[${i}].calltimeChgPattern" size="8" maxlength="15"/>
+ <c:if test="${ctPercErrs || callDestChgPatternErrs}">
+ <span class="ErrorFieldContent">
+ <c:if test="${ctPercErrs}"><br>- <html:errors property="condition[${i}].ctPercentage"/></c:if>
+ <c:if test="${callDestChgPatternErrs}"><br>- <html:errors property="condition[${i}].calltimeChgPattern"/></c:if>
+ </span>
+ </c:if>
+ </td>
+ </tr>
+ </table>
+
</td>
</tr>
@@ -111,12 +202,13 @@
<td class="BlockLabel"> </td>
</c:if> <!-- end conditional metric display logic -->
+
<c:if test="${showTraits}" > <!-- begin conditional traits display logic -->
-
+
<logic:messagesPresent property="condition[${i}].traitStatus">
<c:set var="traitStatusErrs" value="true"/>
</logic:messagesPresent>
-
+
<c:choose>
<c:when test="${traitStatusErrs}">
<td class="ErrorField">
@@ -125,7 +217,7 @@
<td class="BlockContent">
</c:otherwise>
</c:choose>
-
+
<html:radio property="condition[${i}].trigger" value="onTrait"/>
<fmt:message key="alert.config.props.CB.Content.Trait"/>
<html:select property="condition[${i}].traitId"
@@ -134,28 +226,28 @@
<html:optionsCollection property="traits" label="displayName" value="id"/>
</html:select>
<fmt:message key="alert.config.props.CB.Content.Changes"/>
-
+
<c:if test="${traitStatusErrs}">
<br>
<span class="ErrorFieldContent">- <html:errors property="condition[${i}].traitStatus"/></span>
</c:if>
-
+
<html:hidden property="condition[${i}].traitName"/>
-
+
</td>
</tr>
<tr>
<td class="BlockLabel"> </td>
-
+
</c:if> <!-- end conditional traits display logic -->
<c:if test="${showResourceConfiguration}" > <!-- begin conditional resource config display logic -->
-
+
<logic:messagesPresent property="condition[${i}].resourceConfigurationStatus">
<c:set var="resourceConfigurationStatusErrs" value="true"/>
</logic:messagesPresent>
-
+
<c:choose>
<c:when test="${resourceConfigurationStatusErrs}">
<td class="ErrorField">
@@ -164,7 +256,7 @@
<td class="BlockContent">
</c:otherwise>
</c:choose>
-
+
<html:radio property="condition[${i}].trigger" value="onResourceConfiguration"/>
<fmt:message key="alert.config.props.CB.Content.ResourceConfiguration"/>
<fmt:message key="alert.config.props.CB.Content.Changes"/>
@@ -174,14 +266,14 @@
<tr>
<td class="BlockLabel"> </td>
-
+
</c:if> <!-- end conditional resource config display logic -->
<c:if test="${showAvailability}"> <!-- begin conditional availabilityOptions display logic -->
-
+
<logic:messagesPresent property="condition[${i}].availabilityStatus">
<c:set var="availabilityStatusErrs" value="true"/>
</logic:messagesPresent>
-
+
<c:choose>
<c:when test="${availabilityStatusErrs}">
<td class="ErrorField">
@@ -190,14 +282,14 @@
<td class="BlockContent">
</c:otherwise>
</c:choose>
-
+
<html:radio property="condition[${i}].trigger" value="onAvailability"/>
<fmt:message key="alert.config.props.CB.Content.Availability"/>
<html:select property="condition[${i}].availability">
<html:option value="" key="alert.dropdown.SelectOption"/>
<html:optionsCollection property="availabilityOptions"/>
</html:select>
-
+
<c:if test="${availabilityStatusErrs}">
<br>
<span class="ErrorFieldContent">- <html:errors property="condition[${i}].availabilityStatus"/></span>
@@ -207,10 +299,10 @@
<tr>
<td class="BlockLabel"> </td>
-
+
</c:if> <!-- end conditional availabilityOptions display logic -->
<c:if test="${showOperations}"> <!-- begin conditional controlActions display logic -->
-
+
<logic:messagesPresent property="condition[${i}].controlAction">
<c:set var="controlActionErrs" value="true"/>
</logic:messagesPresent>
@@ -247,10 +339,10 @@
<tr>
<td class="BlockLabel"> </td>
-
+
</c:if> <!-- end conditional controlActions display logic -->
<c:if test="${showEvents}"> <!-- begin conditional events display logic -->
-
+
<logic:messagesPresent property="condition[${i}].eventSeverity">
<c:set var="eventSeverityErrs" value="true"/>
</logic:messagesPresent>
@@ -294,10 +386,10 @@
<tr>
<td class="BlockLabel"> </td>
-</c:if> <!-- end conditional events display logic -->
+</c:if> <!-- end conditional events display logic -->
<td class="BlockContent">
-
+
<html:link href="javascript:document.${formName}.submit()"
onclick="clickRemove('${formName}', '${i}');"
titleKey="alert.config.props.CB.Delete">
@@ -315,11 +407,11 @@
<tr>
<td class="BlockLabel"> </td>
-</c:if> <!-- end conditional events display logic -->
+</c:if> <!-- end conditional events display logic -->
<c:if test="${numConditions != 1}">
<tr>
- <td class="BlockLabel"> </td>
+ <td class="BlockLabel"> </td>
</c:if>
<td class="BlockContent">
<html:hidden property="addingCondition" value="false"/>
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/AlertConditionCacheManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/AlertConditionCacheManagerBean.java
index fd6d8d3..5ca45b3 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/AlertConditionCacheManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/AlertConditionCacheManagerBean.java
@@ -33,6 +33,7 @@ import org.rhq.core.domain.event.Event;
import org.rhq.core.domain.event.EventSource;
import org.rhq.core.domain.measurement.Availability;
import org.rhq.core.domain.measurement.MeasurementData;
+import org.rhq.core.domain.measurement.calltime.CallTimeData;
import org.rhq.core.domain.operation.OperationHistory;
import org.rhq.core.domain.resource.Agent;
import org.rhq.enterprise.server.alert.engine.internal.AlertConditionCacheCoordinator;
@@ -60,6 +61,12 @@ public class AlertConditionCacheManagerBean implements AlertConditionCacheManage
return stats;
}
+ public AlertConditionCacheStats checkConditions(CallTimeData... callTime) {
+ AlertConditionCacheStats stats;
+ stats = AlertConditionCacheCoordinator.getInstance().checkConditions(callTime);
+ return stats;
+ }
+
public AlertConditionCacheStats checkConditions(OperationHistory operationHistory) {
AlertConditionCacheStats stats;
stats = AlertConditionCacheCoordinator.getInstance().checkConditions(operationHistory);
@@ -102,4 +109,4 @@ public class AlertConditionCacheManagerBean implements AlertConditionCacheManage
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/AlertConditionCacheManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/AlertConditionCacheManagerLocal.java
index eaf2a0d..d8d64c4 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/AlertConditionCacheManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/AlertConditionCacheManagerLocal.java
@@ -29,6 +29,7 @@ import org.rhq.core.domain.event.Event;
import org.rhq.core.domain.event.EventSource;
import org.rhq.core.domain.measurement.Availability;
import org.rhq.core.domain.measurement.MeasurementData;
+import org.rhq.core.domain.measurement.calltime.CallTimeData;
import org.rhq.core.domain.operation.OperationHistory;
/**
@@ -49,6 +50,14 @@ public interface AlertConditionCacheManagerLocal {
AlertConditionCacheStats checkConditions(MeasurementData... measurementData);
/**
+ * A MeasurementReport is full of CallTimeData objects. Each of these could potentially match against one of the
+ * cache's conditions. So, each must be checked against it, to see whether it fires against any of the conditions.
+ *
+ * @return the number of conditions that were true against this argument
+ */
+ AlertConditionCacheStats checkConditions(CallTimeData... callTime);
+
+ /**
* Operation history occurs in two distinct phases. The first is when the operation is first triggered. An
* OperationHistory element gets persisted whose status is INPROGRESS. The request is sent down to some agent that
* carries out the requested work. Each agent will send a response back out-of-band and update the operation
@@ -73,7 +82,7 @@ public interface AlertConditionCacheManagerLocal {
/**
* An EventReport is full of Event objects. Each of these could potentially match against one of the cache's
* conditions. So, each must be checked against it, to see whether it fires against any of the conditions.
- *
+ *
* @return the number of conditions that were true against this argument
*/
AlertConditionCacheStats checkConditions(EventSource source, Event... events);
@@ -81,7 +90,7 @@ public interface AlertConditionCacheManagerLocal {
/**
* ResourceConfiguration changes can be made through the UI or on the managed resource. Whenever a new
* ResourceConfigurationUpdate is created, it should be passed to this method
- *
+ *
* @return the number of conditions that were true against this argument
*/
AlertConditionCacheStats checkConditions(ResourceConfigurationUpdate update);
@@ -91,4 +100,4 @@ public interface AlertConditionCacheManagerLocal {
void reloadGlobalCache();
void reloadAllCaches();
-}
\ No newline at end of file
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/internal/AbstractConditionCache.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/internal/AbstractConditionCache.java
index 00f6950..74f59f0 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/internal/AbstractConditionCache.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/internal/AbstractConditionCache.java
@@ -66,7 +66,8 @@ abstract class AbstractConditionCache {
*/
cacheElement.setActive(true); // no harm to always set active (though, technically, STATELESS operators don't need it)
cachedConditionProducer.sendActivateAlertConditionMessage(
- cacheElement.getAlertConditionTriggerId(), timestamp, providedValue, extraParams);
+ cacheElement.getAlertConditionTriggerId(), timestamp, cacheElement
+ .convertValueToString(providedValue), extraParams);
stats.matched++;
} catch (Exception e) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/internal/AgentConditionCache.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/internal/AgentConditionCache.java
index 2e37c34..dc84ae6 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/internal/AgentConditionCache.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/internal/AgentConditionCache.java
@@ -18,10 +18,14 @@
*/
package org.rhq.enterprise.server.alert.engine.internal;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
import org.rhq.core.domain.alert.AlertCondition;
import org.rhq.core.domain.alert.AlertConditionCategory;
@@ -35,9 +39,13 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.event.Event;
import org.rhq.core.domain.event.EventSeverity;
import org.rhq.core.domain.event.EventSource;
+import org.rhq.core.domain.measurement.DataType;
import org.rhq.core.domain.measurement.MeasurementData;
import org.rhq.core.domain.measurement.MeasurementDataNumeric;
import org.rhq.core.domain.measurement.MeasurementDataTrait;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.measurement.calltime.CallTimeData;
+import org.rhq.core.domain.measurement.calltime.CallTimeDataValue;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
@@ -46,12 +54,14 @@ import org.rhq.enterprise.server.alert.engine.AlertConditionCacheStats;
import org.rhq.enterprise.server.alert.engine.internal.AlertConditionCacheCoordinator.Cache;
import org.rhq.enterprise.server.alert.engine.mbean.AlertConditionCacheMonitor;
import org.rhq.enterprise.server.alert.engine.model.AlertConditionOperator;
+import org.rhq.enterprise.server.alert.engine.model.CallTimeDataCacheElement;
import org.rhq.enterprise.server.alert.engine.model.EventCacheElement;
import org.rhq.enterprise.server.alert.engine.model.InvalidCacheElementException;
import org.rhq.enterprise.server.alert.engine.model.MeasurementBaselineCacheElement;
import org.rhq.enterprise.server.alert.engine.model.MeasurementNumericCacheElement;
import org.rhq.enterprise.server.alert.engine.model.MeasurementTraitCacheElement;
import org.rhq.enterprise.server.alert.engine.model.NumericDoubleCacheElement;
+import org.rhq.enterprise.server.alert.engine.model.CallTimeDataCacheElement.CallTimeElementValue;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.common.EntityManagerFacadeLocal;
import org.rhq.enterprise.server.measurement.MeasurementDataManagerLocal;
@@ -64,6 +74,7 @@ class AgentConditionCache extends AbstractConditionCache {
private Map<Integer, List<NumericDoubleCacheElement>> measurementDataCache;
private Map<Integer, List<MeasurementTraitCacheElement>> measurementTraitCache;
+ private Map<Integer, List<CallTimeDataCacheElement>> callTimeCache;
private Map<Integer, List<EventCacheElement>> eventsCache;
private AlertConditionManagerLocal alertConditionManager;
@@ -80,6 +91,7 @@ class AgentConditionCache extends AbstractConditionCache {
measurementDataCache = new HashMap<Integer, List<NumericDoubleCacheElement>>();
measurementTraitCache = new HashMap<Integer, List<MeasurementTraitCacheElement>>();
+ callTimeCache = new HashMap<Integer, List<CallTimeDataCacheElement>>();
eventsCache = new HashMap<Integer, List<EventCacheElement>>();
alertConditionManager = LookupUtil.getAlertConditionManager();
@@ -93,9 +105,9 @@ class AgentConditionCache extends AbstractConditionCache {
/**
* This method is used to do the initial loading from the database for a particular agent. In the high availability
- * infrastructure each server instance in the cloud will only be responsible for monitoring a select number of
+ * infrastructure each server instance in the cloud will only be responsible for monitoring a select number of
* agents at any given point in time. When an agent makes a connection to this server instance, the caches for that
- * agent will be loaded at that time.
+ * agent will be loaded at that time.
*
* @return the number of conditions that re/loaded
*/
@@ -160,20 +172,54 @@ class AgentConditionCache extends AbstractConditionCache {
AlertCondition alertCondition = composite.getCondition();
int alertConditionId = alertCondition.getId(); // auto-unboxing is safe here because as the PK it's guaranteed to be non-null
+ MeasurementDefinition mdef = alertCondition.getMeasurementDefinition();
AlertConditionCategory alertConditionCategory = alertCondition.getCategory();
AlertConditionOperator alertConditionOperator = AlertConditionCacheUtils.getAlertConditionOperator(
alertConditionCategory, alertCondition.getComparator(), alertCondition.getOption());
- if (alertConditionCategory == AlertConditionCategory.BASELINE) {
+ if (mdef != null && mdef.getDataType().equals(DataType.CALLTIME)) { // call-time cases start here
+ if (alertConditionCategory == AlertConditionCategory.CHANGE) {
+ AlertConditionChangesCategoryComposite changesComposite = (AlertConditionChangesCategoryComposite) composite;
+ int scheduleId = changesComposite.getScheduleId();
+
+ try {
+ CallTimeDataCacheElement cacheElement = new CallTimeDataCacheElement(alertConditionOperator,
+ CallTimeElementValue.valueOf(alertCondition.getOption()), alertCondition.getComparator(),
+ alertCondition.getThreshold(), alertConditionId, alertCondition.getName());
+
+ addTo("measurementDataCache", callTimeCache, scheduleId, cacheElement, alertConditionId, stats);
+ } catch (InvalidCacheElementException icee) {
+ log.info("Failed to create NumericDoubleCacheElement with parameters: "
+ + AlertConditionCacheUtils.getCacheElementErrorString(alertConditionId, alertConditionOperator,
+ null, alertCondition.getThreshold()));
+ }
+ } else if (alertConditionCategory == AlertConditionCategory.THRESHOLD) {
+ AlertConditionScheduleCategoryComposite thresholdComposite = (AlertConditionScheduleCategoryComposite) composite;
+
+ try {
+ CallTimeDataCacheElement cacheElement = new CallTimeDataCacheElement(alertConditionOperator,
+ CallTimeElementValue.valueOf(alertCondition.getOption()), null, alertCondition.getThreshold(),
+ alertConditionId, alertCondition.getName());
+
+ addTo("measurementDataCache", callTimeCache, thresholdComposite.getScheduleId(), cacheElement,
+ alertConditionId, stats);
+ } catch (InvalidCacheElementException icee) {
+ log.info("Failed to create NumberDoubleCacheElement with parameters: "
+ + AlertConditionCacheUtils.getCacheElementErrorString(alertConditionId, alertConditionOperator,
+ null, alertCondition.getThreshold()));
+ }
+
+ }// last call-time case
+ } else if (alertConditionCategory == AlertConditionCategory.BASELINE) { // normal cases start here
AlertConditionBaselineCategoryComposite baselineComposite = (AlertConditionBaselineCategoryComposite) composite;
// option status for baseline gets set to "mean", but it's rather useless since the UI
// current doesn't allow alerting off of other baseline properties such as "min" and "max"
Double threshold = alertCondition.getThreshold();
String optionStatus = alertCondition.getOption();
- /*
- * yes, calculatedValue may be null, but that's OK because the match
+ /*
+ * yes, calculatedValue may be null, but that's OK because the match
* method for MeasurementBaselineCacheElement handles nulls just fine
*/
Double calculatedValue = getCalculatedBaselineValue(alertConditionId, baselineComposite, optionStatus,
@@ -212,7 +258,7 @@ class AgentConditionCache extends AbstractConditionCache {
String value = traitsComposite.getValue();
try {
- /*
+ /*
* don't forget special defensive handling to allow for null trait calculation;
* this might happen if a newly committed resource has some alert template applied to
* it for some trait that it has not yet gotten from the agent
@@ -308,6 +354,84 @@ class AgentConditionCache extends AbstractConditionCache {
return stats;
}
+ public AlertConditionCacheStats checkConditions(CallTimeData... callTime) {
+ if ((callTime == null) || (callTime.length == 0)) {
+ return new AlertConditionCacheStats();
+ }
+ AlertConditionCacheStats stats = new AlertConditionCacheStats();
+ HashMap<Integer, HashMap<String, ArrayList<CallTimeDataValue>>> order = produceOrderedCallTimeDataStructure(callTime);
+ for (Integer scheduleId : order.keySet()) {
+ List<? extends CallTimeDataCacheElement> conditionCacheElements = lookupCallTimeDataCacheElements(scheduleId);
+ for (String callDest : order.get(scheduleId).keySet())
+ for (CallTimeDataValue provided : order.get(scheduleId).get(callDest)) {
+ processCacheElements(conditionCacheElements, provided, provided.getBeginTime(), stats, callDest);
+ }
+ }
+ return stats;
+ }
+
+ private HashMap<Integer, HashMap<String, ArrayList<CallTimeDataValue>>> produceOrderedCallTimeDataStructure(
+ CallTimeData... callTime) {
+ long beginTime = 0;
+ if (log.isDebugEnabled())
+ beginTime = System.nanoTime();
+
+ //Insert all CallTimeDataValue in data structure
+ HashMap<Integer, HashMap<String, ArrayList<CallTimeDataValue>>> order = new HashMap<Integer, HashMap<String, ArrayList<CallTimeDataValue>>>();
+ for (CallTimeData ctd : callTime) {
+ if (!order.containsKey(ctd.getScheduleId()))
+ order.put(ctd.getScheduleId(), new HashMap<String, ArrayList<CallTimeDataValue>>());
+
+ HashMap<String, ArrayList<CallTimeDataValue>> partialOrder = order.get(ctd.getScheduleId());
+ for (String callDestination : ctd.getValues().keySet()) {
+ if (!partialOrder.containsKey(callDestination))
+ partialOrder.put(callDestination, new ArrayList<CallTimeDataValue>());
+
+ ArrayList<CallTimeDataValue> list = partialOrder.get(callDestination);
+ list.add(ctd.getValues().get(callDestination));
+ }
+ }
+
+ //sort all lists in the data structure
+ for (HashMap<String, ArrayList<CallTimeDataValue>> topList : order.values())
+ for (ArrayList<CallTimeDataValue> bottomList : topList.values())
+ Collections.sort(bottomList, getCallTimeComparator());
+
+ if (log.isDebugEnabled())
+ log.debug("sorting call-time data during alerting took: "
+ + TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - beginTime) + "ms");
+ return order;
+ }
+
+ private Comparator<CallTimeDataValue> getCallTimeComparator() {
+ return new Comparator<CallTimeDataValue>() {
+ public int compare(CallTimeDataValue arg0, CallTimeDataValue arg1) {
+ if (arg0 == null || arg1 == null)
+ throw new IllegalArgumentException("Call-time data value entries must not be null!");
+
+ if (arg0 == arg1)
+ return 0;
+
+ //differing begin times:
+ if (arg0.getBeginTime() < arg1.getBeginTime())
+ return -1;
+ if (arg0.getBeginTime() > arg1.getBeginTime())
+ return 1;
+
+ // begin time equality:
+ if (arg0.getBeginTime() == arg1.getBeginTime()) {
+ if (arg0.getEndTime() == arg1.getEndTime())
+ return 0;
+ if (arg0.getEndTime() < arg1.getEndTime())
+ return -1;
+ if (arg0.getEndTime() > arg1.getEndTime())
+ return 1;
+ }
+ return Integer.MIN_VALUE;
+ }
+ };
+ }
+
public AlertConditionCacheStats checkConditions(EventSource source, Event... events) {
if ((events == null) || (events.length == 0)) {
return new AlertConditionCacheStats();
@@ -337,6 +461,10 @@ class AgentConditionCache extends AbstractConditionCache {
return measurementDataCache.get(scheduleId); // yup, might be null
}
+ private List<? extends CallTimeDataCacheElement> lookupCallTimeDataCacheElements(int scheduleId) {
+ return callTimeCache.get(scheduleId); // yup, might be null
+ }
+
private List<MeasurementTraitCacheElement> lookupMeasurementTraitCacheElements(int scheduleId) {
return measurementTraitCache.get(scheduleId); // yup, might be null
}
@@ -354,7 +482,7 @@ class AgentConditionCache extends AbstractConditionCache {
+ "]: threshold was null");
}
- // auto-unboxing of threshold is safe here
+ // auto-unboxing of threshold is safe here
Double baselineValue = 0.0;
if (optionStatus == null) {
@@ -386,6 +514,8 @@ class AgentConditionCache extends AbstractConditionCache {
return AlertConditionCacheUtils.getMapListCount(measurementDataCache);
} else if (cache == AlertConditionCacheCoordinator.Cache.MeasurementTraitCache) {
return AlertConditionCacheUtils.getMapListCount(measurementTraitCache);
+ } else if (cache == AlertConditionCacheCoordinator.Cache.CallTimeDataCache) {
+ return AlertConditionCacheUtils.getMapListCount(callTimeCache);
} else if (cache == AlertConditionCacheCoordinator.Cache.EventsCache) {
return AlertConditionCacheUtils.getMapListCount(eventsCache);
} else {
@@ -394,4 +524,4 @@ class AgentConditionCache extends AbstractConditionCache {
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/internal/AlertConditionCacheCoordinator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/internal/AlertConditionCacheCoordinator.java
index 4d13534..340849e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/internal/AlertConditionCacheCoordinator.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/internal/AlertConditionCacheCoordinator.java
@@ -32,6 +32,7 @@ import org.rhq.core.domain.event.Event;
import org.rhq.core.domain.event.EventSource;
import org.rhq.core.domain.measurement.Availability;
import org.rhq.core.domain.measurement.MeasurementData;
+import org.rhq.core.domain.measurement.calltime.CallTimeData;
import org.rhq.core.domain.operation.OperationHistory;
import org.rhq.enterprise.server.alert.engine.AlertConditionCacheStats;
import org.rhq.enterprise.server.alert.engine.model.AbstractCacheElement;
@@ -44,9 +45,9 @@ import org.rhq.enterprise.server.util.LookupUtil;
* reported by an agent, and thus can be perfectly segmented on an agent-by-agent basis. On the other hand,
* the {@link GlobalConditionCache} will maintain {@link AbstractCacheElement}s for data that can either be
* agent-side or server-side initiated.
- *
+ *
* This manager forms a centralized interface through which to interact with the children caches.
- *
+ *
* @author Joseph Marques
*/
public final class AlertConditionCacheCoordinator {
@@ -58,6 +59,7 @@ public final class AlertConditionCacheCoordinator {
public enum Cache {
MeasurementDataCache(Type.Agent), //
MeasurementTraitCache(Type.Agent), //
+ CallTimeDataCache(Type.Agent), //
ResourceOperationCache(Type.Global), //
AvailabilityCache(Type.Global), //
EventsCache(Type.Agent), //
@@ -159,6 +161,37 @@ public final class AlertConditionCacheCoordinator {
return stats;
}
+ public AlertConditionCacheStats checkConditions(CallTimeData... callTime) {
+ if (callTime == null || callTime.length == 0) {
+ return new AlertConditionCacheStats();
+ }
+
+ CallTimeData datum = callTime[0];
+ Integer agentId = getAgentId(datum);
+ if (agentId == null) {
+ log.error("Could not find agent for scheduleId = " + datum.getScheduleId());
+ return new AlertConditionCacheStats();
+ }
+
+ AlertConditionCacheStats stats = null;
+ AgentConditionCache agentCache = null;
+ agentReadWriteLock.readLock().lock();
+ try {
+ agentCache = agentCaches.get(agentId);
+ } catch (Throwable t) {
+ log.error("Error during checkConditions", t); // don't let any exceptions bubble up to the calling SLSB layer
+ } finally {
+ agentReadWriteLock.readLock().unlock();
+ }
+ if (agentCache != null) {
+ stats = agentCache.checkConditions(callTime);
+ } else {
+ stats = new AlertConditionCacheStats();
+ }
+
+ return stats;
+ }
+
public AlertConditionCacheStats checkConditions(OperationHistory operationHistory) {
AlertConditionCacheStats stats = null;
try {
@@ -238,9 +271,16 @@ public final class AlertConditionCacheCoordinator {
return null;
}
+ private Integer getAgentId(CallTimeData ctd) {
+ return getAgentId(ctd.getScheduleId());
+ }
+
private Integer getAgentId(MeasurementData datum) {
+ return getAgentId(datum.getScheduleId());
+ }
+
+ private Integer getAgentId(int scheduleId) {
try {
- int scheduleId = datum.getScheduleId();
Integer agentId = agentManager.getAgentIdByScheduleId(scheduleId);
return agentId;
} catch (Throwable t) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/jms/CachedConditionProducerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/jms/CachedConditionProducerBean.java
index bc901d4..3341af8 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/jms/CachedConditionProducerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/jms/CachedConditionProducerBean.java
@@ -32,14 +32,13 @@ import javax.jms.Session;
import org.rhq.enterprise.server.alert.engine.jms.model.ActiveAlertConditionMessage;
import org.rhq.enterprise.server.alert.engine.jms.model.InactiveAlertConditionMessage;
-import org.rhq.enterprise.server.alert.engine.model.AbstractCacheElement;
/**
* A convenience class that will be used by the AlertConditionCacheManager to send messages to a JMS queue for
* processing. These messages reference alert conditions that have triggered (become true). The contents will be picked
* at on the other end of the non-durable queue by the consumer, which will then create and persist the appropriate log
* message.
- *
+ *
* @author Joseph Marques
*/
@Stateless
@@ -54,8 +53,8 @@ public class CachedConditionProducerBean implements CachedConditionProducerLocal
private Queue alertConditionQueue;
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
- public <T extends AbstractCacheElement<S>, S> void sendActivateAlertConditionMessage(int alertConditionId,
- long timestamp, S value, Object... extraParams) throws JMSException {
+ public void sendActivateAlertConditionMessage(int alertConditionId, long timestamp, String value,
+ Object... extraParams) throws JMSException {
Connection connection = factory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer sender = session.createProducer(alertConditionQueue);
@@ -65,7 +64,7 @@ public class CachedConditionProducerBean implements CachedConditionProducerLocal
* send the string representation of the value for the AbstractCacheElement in the JMS message
*/
ActiveAlertConditionMessage conditionMessage = new ActiveAlertConditionMessage(alertConditionId, timestamp,
- value.toString(), extraParams);
+ value, extraParams);
ObjectMessage message = session.createObjectMessage(conditionMessage);
@@ -89,4 +88,4 @@ public class CachedConditionProducerBean implements CachedConditionProducerLocal
connection.close();
}
-}
\ No newline at end of file
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/jms/CachedConditionProducerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/jms/CachedConditionProducerLocal.java
index d2b4fb5..627e2f7 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/jms/CachedConditionProducerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/jms/CachedConditionProducerLocal.java
@@ -21,8 +21,6 @@ package org.rhq.enterprise.server.alert.engine.jms;
import javax.ejb.Local;
import javax.jms.JMSException;
-import org.rhq.enterprise.server.alert.engine.model.AbstractCacheElement;
-
/**
* @author Joseph Marques
*/
@@ -33,8 +31,8 @@ public interface CachedConditionProducerLocal {
* Send a message to the appropriate JMS destination for processing. This destination handles creating and
* persisting entities corresponding to triggered alert conditions.
*/
- <T extends AbstractCacheElement<S>, S> void sendActivateAlertConditionMessage(int alertConditionId, long timestamp,
- S value, Object... extraParams) throws JMSException;
+ void sendActivateAlertConditionMessage(int alertConditionId, long timestamp, String value, Object... extraParams)
+ throws JMSException;
void sendDeactivateAlertConditionMessage(int alertConditionId, long timestamp) throws JMSException;
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/model/AbstractCacheElement.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/model/AbstractCacheElement.java
index b7aae77..6026aeb 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/model/AbstractCacheElement.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/model/AbstractCacheElement.java
@@ -163,6 +163,10 @@ public abstract class AbstractCacheElement<T> {
return getOperatorSupportsType(alertConditionOperator) == type;
}
+ public String convertValueToString(T providedValue) {
+ return providedValue.toString();
+ }
+
@Override
public String toString() {
String conditionValue = null;
@@ -225,4 +229,4 @@ public abstract class AbstractCacheElement<T> {
return true;
}
-}
\ No newline at end of file
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBean.java
index b1a849e..bf2de38 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBean.java
@@ -63,6 +63,7 @@ import org.rhq.core.domain.measurement.MeasurementDataTrait;
import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.measurement.MeasurementReport;
import org.rhq.core.domain.measurement.MeasurementSchedule;
+import org.rhq.core.domain.measurement.calltime.CallTimeData;
import org.rhq.core.domain.measurement.composite.MeasurementDataNumericHighLowComposite;
import org.rhq.core.domain.resource.Agent;
import org.rhq.core.domain.resource.Resource;
@@ -171,9 +172,9 @@ public class MeasurementDataManagerBean implements MeasurementDataManagerLocal,
long start = System.currentTimeMillis();
// TODO GH: Deal with offset (this is only for situations where the clock doesn't match on the agent)
- /*
+ /*
* even if these methods check for null/empty collections, they cross the EJB boundary and so unnecessarily
- * start transactions. by checking the null/emptiness of a collection here, by only create transactions
+ * start transactions. by checking the null/emptiness of a collection here, by only create transactions
* when real work will be done;
*/
if (report.getNumericData() != null && !report.getNumericData().isEmpty()) {
@@ -184,6 +185,7 @@ public class MeasurementDataManagerBean implements MeasurementDataManagerLocal,
}
if (report.getCallTimeData() != null && !report.getCallTimeData().isEmpty()) {
this.callTimeDataManager.addCallTimeData(report.getCallTimeData());
+ this.notifyAlertConditionCacheManager("mergeMeasurementReport", report.getCallTimeData());
}
long time = System.currentTimeMillis() - start;
@@ -858,4 +860,12 @@ public class MeasurementDataManagerBean implements MeasurementDataManagerLocal,
return result;
}
+
+ private void notifyAlertConditionCacheManager(String callingMethod, Set<CallTimeData> callTime) {
+ AlertConditionCacheStats stats = alertConditionCacheManager.checkConditions(callTime
+ .toArray(new CallTimeData[callTime.size()]));
+
+ if (log.isDebugEnabled())
+ log.debug(callingMethod + ": " + stats.toString());
+ }
}
\ No newline at end of file
commit fef127265c7eca061c27d287f1bf98da37c3be0e
Author: Frank Brueseke <fbrueseke(a)s-lab.upb.de>
Date: Mon Mar 1 20:48:12 2010 +0100
Allow alerting on call-time data. BZ 535756
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/condition/CallTimeDataConverterValidator.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/condition/CallTimeDataConverterValidator.java
new file mode 100644
index 0000000..976ffdc
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/config/condition/CallTimeDataConverterValidator.java
@@ -0,0 +1,159 @@
+package org.rhq.enterprise.gui.legacy.action.resource.common.monitor.alerts.config.condition;
+
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import org.apache.commons.validator.GenericValidator;
+import org.apache.struts.action.ActionErrors;
+import org.apache.struts.action.ActionMessage;
+
+import org.rhq.core.domain.alert.AlertCondition;
+import org.rhq.core.domain.alert.AlertConditionCategory;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.measurement.MeasurementUnits;
+import org.rhq.core.domain.measurement.composite.MeasurementNumericValueAndUnits;
+import org.rhq.core.domain.measurement.util.MeasurementConversionException;
+import org.rhq.core.domain.measurement.util.MeasurementConverter;
+import org.rhq.core.util.NumberUtil;
+import org.rhq.enterprise.gui.legacy.action.resource.common.monitor.alerts.config.ConditionBean;
+import org.rhq.enterprise.server.measurement.MeasurementDefinitionManagerLocal;
+import org.rhq.enterprise.server.util.LookupUtil;
+
+public class CallTimeDataConverterValidator implements ConditionBeanConverterValidator {
+
+ public static final String DOUBLE_REGEX = "[0-9,.]+";
+
+ public static final String TYPE_ABS = "absolute";
+ public static final String TYPE_CHG = "changed";
+
+ private MeasurementDefinitionManagerLocal definitionManager;
+
+ public CallTimeDataConverterValidator() {
+ definitionManager = LookupUtil.getMeasurementDefinitionManager();
+ }
+
+ public void exportProperties(Subject subject, ConditionBean fromBean, AlertCondition toCondition) {
+ MeasurementDefinition definition = definitionManager.getMeasurementDefinition(subject, fromBean.getMetricId());
+ toCondition.setMeasurementDefinition(definition);
+
+ if (fromBean.getThresholdType().equals(TYPE_ABS)) {
+ MeasurementNumericValueAndUnits valueAndUnits = MeasurementConverter.parse(fromBean.getCtAbsoluteValue(),
+ definition.getUnits());
+
+ toCondition.setThreshold(valueAndUnits.getValue());
+ toCondition.setCategory(AlertConditionCategory.THRESHOLD);
+ toCondition.setOption(fromBean.getCalltimeAbsOption());
+ toCondition.setComparator(fromBean.getCalltimeComparator());
+ toCondition.setName(fromBean.getCalltimeAbsPattern());
+
+ } else if (fromBean.getThresholdType().equals(TYPE_CHG)) {
+ MeasurementNumericValueAndUnits percentage = MeasurementConverter.parse(fromBean.getCtPercentage(),
+ MeasurementUnits.PERCENTAGE);
+
+ toCondition.setThreshold(percentage.getValue());
+ toCondition.setCategory(AlertConditionCategory.CHANGE);
+ toCondition.setOption(fromBean.getCalltimeChgOption());
+ toCondition.setName(fromBean.getCalltimeChgPattern());
+ toCondition.setComparator(fromBean.getCalltimeChgOp());
+ }
+ }
+
+ public void importProperties(Subject subject, AlertCondition fromCondition, ConditionBean toBean) {
+ // shared measurement processing
+ MeasurementDefinition definition = fromCondition.getMeasurementDefinition();
+ toBean.setMetricName(definition.getDisplayName());
+ toBean.setMetricId(definition.getId());
+
+ toBean.setTrigger(getTriggerName());
+
+ if (fromCondition.getCategory() == AlertConditionCategory.THRESHOLD) {
+ toBean.setThresholdType(TYPE_ABS);
+ toBean.setCalltimeAbsOption(fromCondition.getOption());
+ toBean.setCalltimeAbsPattern(fromCondition.getName());
+
+ try {
+ // this is coming from the backing store, so
+ String formattedValue = MeasurementConverter.format(fromCondition.getThreshold(),
+ definition.getUnits(), true);
+ toBean.setCtAbsoluteValue(formattedValue);
+ } catch (MeasurementConversionException mce) {
+ toBean.setCtAbsoluteValue("Conversion Error");
+ }
+
+ toBean.setCalltimeComparator(fromCondition.getComparator());
+ toBean.setPercentageComparator(null);
+ } else if (fromCondition.getCategory() == AlertConditionCategory.CHANGE) {
+ toBean.setThresholdType(TYPE_CHG);
+ toBean.setCalltimeChgOption(fromCondition.getOption());
+ toBean.setCalltimeChgPattern(fromCondition.getName());
+ toBean.setCalltimeChgOp(fromCondition.getComparator());
+
+ Double threshold = MeasurementUnits.scaleUp(fromCondition.getThreshold(), MeasurementUnits.PERCENTAGE);
+ toBean.setCtPercentage(MeasurementConverter.format(threshold, MeasurementUnits.NONE, true));
+
+ toBean.setCalltimeComparator(null);
+
+ }
+
+ }
+
+ public boolean validate(ConditionBean bean, ActionErrors errors, int index) {
+ if (bean.getMetricId() <= 0) {
+ // user didn't select a metric
+ ActionMessage err = new ActionMessage("alert.config.error.NoMetricSelected");
+ errors.add("condition[" + index + "].metricId", err);
+ return false;
+ }
+
+ if (bean.getThresholdType().equals(TYPE_ABS)) {
+ if (!GenericValidator.matchRegexp(bean.getCtAbsoluteValue(), DOUBLE_REGEX)) {
+ ActionMessage err = new ActionMessage("errors.double", "AbsoluteValue");
+ errors.add("condition[" + index + "].ctAbsoluteValue", err);
+ return false;
+ } else // double
+ {
+ // do nothing
+ }
+ if (bean.getCalltimeAbsPattern() != null) {
+ try {
+ Pattern p = Pattern.compile(bean.getCalltimeAbsPattern());
+ } catch (PatternSyntaxException e) {
+ ActionMessage err = new ActionMessage("alert.config.error.CalltimePatternError");
+ errors.add("condition[" + index + "].calltimeAbsPattern", err);
+ }
+ }
+ } else if (bean.getThresholdType().equals(TYPE_CHG)) // percentage
+ {
+ if (!GenericValidator.matchRegexp(bean.getCtPercentage(), DOUBLE_REGEX)) {
+ ActionMessage err = new ActionMessage("errors.double", "Percentage");
+ errors.add("condition[" + index + "].ctPercentage", err);
+ return false;
+ } else // double
+ {
+ // 0-100 range
+ double percentage = NumberUtil.stringAsNumber(bean.getCtPercentage()).doubleValue();
+ if (!GenericValidator.isInRange(percentage, 0d, 1000d)) {
+ ActionMessage err = new ActionMessage("errors.range", String.valueOf(percentage), String
+ .valueOf(0d), String.valueOf(1000d));
+ errors.add("condition[" + index + "].ctPercentage", err);
+ return false;
+ }
+ }
+ if (bean.getCalltimeChgPattern() != null) {
+ try {
+ Pattern p = Pattern.compile(bean.getCalltimeChgPattern());
+ } catch (PatternSyntaxException e) {
+ ActionMessage err = new ActionMessage("alert.config.error.CalltimePatternError");
+ errors.add("condition[" + index + "].calltimeChgPattern", err);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ public String getTriggerName() {
+ return "onCallTime";
+ }
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/model/CallTimeDataCacheElement.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/model/CallTimeDataCacheElement.java
new file mode 100644
index 0000000..d013af5
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/model/CallTimeDataCacheElement.java
@@ -0,0 +1,152 @@
+package org.rhq.enterprise.server.alert.engine.model;
+
+import java.text.DateFormat;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Pattern;
+
+import org.rhq.core.domain.measurement.calltime.CallTimeDataValue;
+
+/**
+ *
+ * @author fbrueseke
+ */
+public class CallTimeDataCacheElement extends AbstractCacheElement<CallTimeDataValue> {
+ public enum CallTimeElementValue {
+ MAX, MIN, AVG, COUNT;
+ }
+
+ private enum CalltimeChangeOp {
+ LO //Shrinks
+ , CH //Changes
+ , HI;//Grows
+ }
+
+ private static CallTimeDataValue dummy = new CallTimeDataValue();
+
+ private Double compareValue = null;
+ private CalltimeChangeOp comparator;
+
+ private ConcurrentHashMap<String, CallTimeDataValue> previous = new ConcurrentHashMap<String, CallTimeDataValue>();
+ private Pattern callDestPattern = null;
+
+ private String fixPattern(String regex) {
+ boolean sw = regex.startsWith(".*");
+ boolean ew = regex.endsWith(".*");
+ return (!sw ? ".*" : "") + regex + (!ew ? ".*" : "");
+ }
+
+ public CallTimeDataCacheElement(AlertConditionOperator operator, CallTimeElementValue whichValue,
+ String comparator, Double value, int conditionId, String callDestPattern) {
+ super(operator, whichValue, dummy, conditionId);
+
+ if (value == null)
+ throw new InvalidCacheElementException("Invalid Cache Element: " + "condition with id=" + conditionId + " "
+ + "and operator='" + operator.toString() + "' " + "requires a non-null value");
+
+ if (whichValue == null)
+ throw new InvalidCacheElementException("operator '" + operator.toString() + "'"
+ + " requires an operator option; it can not be null");
+
+ compareValue = value;
+ if (callDestPattern != null)
+ this.callDestPattern = Pattern.compile(fixPattern(callDestPattern));
+ else
+ this.callDestPattern = null;
+
+ if (comparator != null)
+ this.comparator = CalltimeChangeOp.valueOf(comparator);
+ }
+
+ @Override
+ public AlertConditionOperator.Type getOperatorSupportsType(AlertConditionOperator operator) {
+ if ((operator == AlertConditionOperator.GREATER_THAN) || (operator == AlertConditionOperator.EQUALS)
+ || (operator == AlertConditionOperator.LESS_THAN) || (operator == AlertConditionOperator.CHANGES)) {
+ return operator.getDefaultType();
+ }
+
+ return AlertConditionOperator.Type.NONE;
+ }
+
+ @Override
+ public boolean matches(CallTimeDataValue providedValue, Object... extras) {
+
+ if (compareValue == null || compareValue.isNaN() || compareValue.isInfinite()
+ || this.alertConditionOperatorOption == null)
+ return false;
+
+ Double provided = getCallTimeElementValue(providedValue);
+ if (provided == null || provided.isInfinite() || provided.isNaN())
+ return false;
+
+ String key = "";
+ if (extras != null && extras[0] != null)
+ key = (String) extras[0];
+ if (callDestPattern != null && !callDestPattern.matcher(key).matches())
+ return false;
+
+ switch (alertConditionOperator) {
+ case EQUALS:
+ return (compareValue.compareTo(provided) == 0);
+
+ case GREATER_THAN: // threshold < measurement
+ return (compareValue.compareTo(provided) < 0);
+
+ case LESS_THAN: //threshold > measurement
+ return (compareValue.compareTo(provided) > 0);
+
+ case CHANGES:
+ // I assume that CallTimeDataValue objects are delivered to this method in chronological order!
+ if (!previous.containsKey(key)) {
+ previous.put(key, providedValue);
+ return false;
+ }
+
+ CallTimeDataValue previousElem = previous.get(key);
+ double compare = getCallTimeElementValue(previousElem);
+ boolean result = computeChangeResult(provided, compare, comparator);
+ if (log.isTraceEnabled())
+ log.trace("Changes at least " + compareValue + "% [" + result + "]; current:" + providedValue
+ + "; previous:" + previousElem);
+
+ previous.put(key, providedValue);
+ return result;
+ }
+ return false;
+ }
+
+ private boolean computeChangeResult(Double provided, double compare, CalltimeChangeOp op) {
+ switch (op) {
+ case LO:
+ return (provided < compare - compareValue * compare);
+ case CH:
+ return (provided < compare - compareValue * compare || provided > compare + compareValue * compare);
+ case HI:
+ return (provided > compare + compareValue * compare);
+ default:
+ return false;
+ }
+ }
+
+ private Double getCallTimeElementValue(CallTimeDataValue struct) {
+ switch ((CallTimeElementValue) alertConditionOperatorOption) {
+ case MIN:
+ return struct.getMinimum();
+ case MAX:
+ return struct.getMaximum();
+ case AVG:
+ return struct.getTotal() / struct.getCount();
+ case COUNT:
+ return (double) struct.getCount();
+ default:
+ return null;
+ }
+ }
+
+ @Override
+ public String convertValueToString(CallTimeDataValue value) {
+ return "[From:"
+ + DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM).format(value.getBeginTime())
+ + ", To:" + DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM).format(value.getEndTime())
+ + ", " + alertConditionOperatorOption + ":" + getCallTimeElementValue(value) + "]";
+ }
+}
14 years, 2 months