[rhq] Branch 'feature/cassandra-backend' - 2 commits - modules/enterprise modules/plugins
by Jay Shaughnessy
modules/enterprise/server/plugins/alertdef-rhq/src/main/java/org/rhq/enterprise/server/plugins/alertdef/AlertDefinitionServerPluginComponent.java | 55 ++++--
modules/plugins/jmx/pom.xml | 7
modules/plugins/jmx/src/main/java/org/rhq/plugins/jmx/MBeanResourceComponent.java | 51 +++++
modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml | 6
modules/plugins/jmx/src/test/java/org/rhq/plugins/jmx/test/JMXPluginTest.java | 86 ++++------
5 files changed, 133 insertions(+), 72 deletions(-)
New commits:
commit 60861793babe07efc23f457e432f73fbb0f7ea52
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed May 29 10:46:05 2013 -0400
Use new JMX plugin metric "VM Memory System:Heap usage Percentage" to provide
a factory installed alert template for an RHQ storage node. The actual
numbers probably need tweeking, currently its HUP > 75% with 10 of 15 dampening.
TODO: lower the collection interval to 1 minute for the relevant metric.
diff --git a/modules/enterprise/server/plugins/alertdef-rhq/src/main/java/org/rhq/enterprise/server/plugins/alertdef/AlertDefinitionServerPluginComponent.java b/modules/enterprise/server/plugins/alertdef-rhq/src/main/java/org/rhq/enterprise/server/plugins/alertdef/AlertDefinitionServerPluginComponent.java
index ce14f17..8704203 100644
--- a/modules/enterprise/server/plugins/alertdef-rhq/src/main/java/org/rhq/enterprise/server/plugins/alertdef/AlertDefinitionServerPluginComponent.java
+++ b/modules/enterprise/server/plugins/alertdef-rhq/src/main/java/org/rhq/enterprise/server/plugins/alertdef/AlertDefinitionServerPluginComponent.java
@@ -27,8 +27,8 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.alert.AlertCondition;
import org.rhq.core.domain.alert.AlertConditionCategory;
-import org.rhq.core.domain.alert.AlertConditionOperator;
import org.rhq.core.domain.alert.AlertDampening;
+import org.rhq.core.domain.alert.AlertDampening.TimeUnits;
import org.rhq.core.domain.alert.AlertDefinition;
import org.rhq.core.domain.alert.AlertPriority;
import org.rhq.core.domain.alert.BooleanExpression;
@@ -38,8 +38,10 @@ import org.rhq.core.domain.configuration.PropertyMap;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.criteria.AlertDefinitionCriteria;
import org.rhq.core.domain.criteria.ResourceTypeCriteria;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.enterprise.server.alert.AlertDefinitionManagerLocal;
+import org.rhq.enterprise.server.alert.AlertTemplateManagerLocal;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.plugin.pc.ControlFacet;
import org.rhq.enterprise.server.plugin.pc.ControlResults;
@@ -58,17 +60,17 @@ public class AlertDefinitionServerPluginComponent implements ServerPluginCompone
private final Log log = LogFactory.getLog(AlertDefinitionServerPluginComponent.class);
static private final List<InjectedTemplate> injectedTemplates;
- static private final InjectedTemplate testTemplate;
+ static private final InjectedTemplate storageNodeHighHeapTemplate;
static {
- testTemplate = new InjectedTemplate( //
- "RHQAgent", //
- "RHQ Agent", //
- "TestTemplate", //
- "A test template injection");
+ storageNodeHighHeapTemplate = new InjectedTemplate(
+ "RHQStorage", //
+ "VM Memory System", //
+ "StorageNodeHighHeapTemplate", //
+ "An alert template to notify users of excessive heap use by an RHQ Storage Node. When fired please see documentation for the proper corrective action.");
injectedTemplates = new ArrayList<InjectedTemplate>();
- injectedTemplates.add(testTemplate);
+ injectedTemplates.add(storageNodeHighHeapTemplate);
}
private ServerPluginContext context;
@@ -177,6 +179,7 @@ public class AlertDefinitionServerPluginComponent implements ServerPluginCompone
ResourceTypeCriteria rtc = new ResourceTypeCriteria();
rtc.addFilterPluginName(injectedAlertDef.getPluginName());
rtc.addFilterName(injectedAlertDef.getResourceTypeName());
+ rtc.fetchMetricDefinitions(true);
List<ResourceType> resourceTypes = typeManager.findResourceTypesByCriteria(subjectManager.getOverlord(), rtc);
if (resourceTypes.isEmpty()) {
@@ -206,8 +209,8 @@ public class AlertDefinitionServerPluginComponent implements ServerPluginCompone
int newAlertDefId = 0;
- if (testTemplate.equals(injectedAlertDef)) {
- newAlertDefId = injectTestTemplate(resourceType);
+ if (storageNodeHighHeapTemplate.equals(injectedAlertDef)) {
+ newAlertDefId = injectStorageNodeHighHeapTemplate(resourceType);
}
adc.addFilterId(newAlertDefId);
@@ -218,27 +221,41 @@ public class AlertDefinitionServerPluginComponent implements ServerPluginCompone
return result;
}
- private int injectTestTemplate(ResourceType resourceType) {
- AlertDefinitionManagerLocal alertDefManager = LookupUtil.getAlertDefinitionManager();
+ private int injectStorageNodeHighHeapTemplate(ResourceType resourceType) {
+ AlertTemplateManagerLocal alertTemplateManager = LookupUtil.getAlertTemplateManager();
SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
AlertDefinition newTemplate = new AlertDefinition();
- newTemplate.setName(testTemplate.getName());
+ newTemplate.setName(storageNodeHighHeapTemplate.getName());
newTemplate.setResourceType(resourceType);
newTemplate.setPriority(AlertPriority.MEDIUM);
- newTemplate.setAlertDampening(new AlertDampening(AlertDampening.Category.NONE));
newTemplate.setConditionExpression(BooleanExpression.ANY);
newTemplate.setRecoveryId(0);
newTemplate.setEnabled(true);
AlertCondition ac = new AlertCondition();
- ac.setCategory(AlertConditionCategory.AVAILABILITY);
- ac.setName(AlertConditionOperator.AVAIL_GOES_DOWN.name());
-
+ ac.setCategory(AlertConditionCategory.THRESHOLD);
+ ac.setComparator(">");
+ ac.setThreshold(0.75D);
+ for (MeasurementDefinition d : resourceType.getMetricDefinitions()) {
+ if ("Calculated.HeapUsagePercentage".equals(d.getName())) {
+ ac.setMeasurementDefinition(d);
+ ac.setName(d.getDisplayName());
+ break;
+ }
+ }
+ assert null != ac.getMeasurementDefinition() : "Did not find expected measurement definition [Calculated.HeapUsagePercentage] for "
+ + resourceType;
newTemplate.addCondition(ac);
- int newTemplateId = alertDefManager.createAlertDefinitionInNewTransaction(subjectManager.getOverlord(),
- newTemplate, null, true);
+ AlertDampening dampener = new AlertDampening(AlertDampening.Category.PARTIAL_COUNT);
+ dampener.setPeriod(15);
+ dampener.setPeriodUnits(TimeUnits.MINUTES);
+ dampener.setValue(10);
+ newTemplate.setAlertDampening(dampener);
+
+ int newTemplateId = alertTemplateManager.createAlertTemplate(subjectManager.getOverlord(), newTemplate,
+ resourceType.getId());
return newTemplateId;
}
commit 756d7ee25ba8526e1b70a874fdaa24340be6e8f5
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed May 29 10:42:47 2013 -0400
Add new JMX metric for "VM Memory System:Heap Usage Percentage". This
provides a way to monitor/alert actual memory consumption as it is calculated
as HeapUsage/HeapCommitted.
Re-enable JMXPluginTest, as it seems to be working (at least on
my box, hopefully on jenkins as well). Also, add test of new metric.
diff --git a/modules/plugins/jmx/pom.xml b/modules/plugins/jmx/pom.xml
index 1e17e7c..864f675 100644
--- a/modules/plugins/jmx/pom.xml
+++ b/modules/plugins/jmx/pom.xml
@@ -120,13 +120,6 @@
</goals>
<configuration>
<skip>${maven.test.skip}</skip>
- <excludes>
- <!--
- Disabled to due a NPE that the test hits in vmUtility.attachToVirtualMachine on line 107 which
- may be due to this Sigar bug, https://jira.hyperic.com/browse/SIGAR-231.
- -->
- <exclude>**/JMXPluginTest.java</exclude>
- </excludes>
<excludedGroups>${rhq.testng.excludedGroups}</excludedGroups>
<useSystemClassLoader>true</useSystemClassLoader>
<argLine>${jacoco.integration-test.args} -Dorg.hyperic.sigar.path=${basedir}/target/itest/lib</argLine>
diff --git a/modules/plugins/jmx/src/main/java/org/rhq/plugins/jmx/MBeanResourceComponent.java b/modules/plugins/jmx/src/main/java/org/rhq/plugins/jmx/MBeanResourceComponent.java
index 5637c2d..c0be3d4 100644
--- a/modules/plugins/jmx/src/main/java/org/rhq/plugins/jmx/MBeanResourceComponent.java
+++ b/modules/plugins/jmx/src/main/java/org/rhq/plugins/jmx/MBeanResourceComponent.java
@@ -89,6 +89,8 @@ public class MBeanResourceComponent<T extends JMXComponent<?>> implements Measur
private static final Pattern PROPERTY_PATTERN = Pattern.compile("^\\{(?:\\{([^\\}]*)\\})?([^\\}]*)\\}$");
private static final Pattern TEMPLATE_PATTERN = Pattern.compile("%([^%]+)%");
+ private static final String CALCULATED_METRIC_HEAP_USAGE_PERCENTAGE = "Calculated.HeapUsagePercentage";
+
// these two should be private - subclasses need to override the getter/setter/load methods to affect these
/**
* @deprecated do not use this - use {@link #getEmsBean()} instead
@@ -262,10 +264,13 @@ public class MBeanResourceComponent<T extends JMXComponent<?>> implements Measur
* @param bean the EmsBean on which to collect the metrics
*/
protected void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> requests, EmsBean bean) {
- // First we split the requests into their respective beans
+ // First we split the requests into their respective beans, and handle calculated values
Set<MeasurementScheduleRequest> defaultBeanRequests = new HashSet<MeasurementScheduleRequest>();
Map<String, Set<MeasurementScheduleRequest>> beansMap = new HashMap<String, Set<MeasurementScheduleRequest>>();
for (MeasurementScheduleRequest request : requests) {
+ if (getCalculatedProperty(report, request, bean)) {
+ continue;
+ }
Matcher m = PROPERTY_PATTERN.matcher(request.getName());
if (m.matches() && (m.group(1) != null)) {
// Custom bean
@@ -295,6 +300,50 @@ public class MBeanResourceComponent<T extends JMXComponent<?>> implements Measur
}
}
+ private boolean getCalculatedProperty(MeasurementReport report, MeasurementScheduleRequest request, EmsBean bean) {
+ boolean result = false;
+ String metricName = request.getName();
+
+ if (CALCULATED_METRIC_HEAP_USAGE_PERCENTAGE.equals(request.getName())) {
+ result = true;
+
+ MeasurementReport calculationPropsReport = new MeasurementReport();
+ Set<MeasurementScheduleRequest> calculationPropsSchedules = new HashSet(2);
+
+ MeasurementScheduleRequest heapUsedRequest = new MeasurementScheduleRequest(0, "{HeapMemoryUsage.used}",
+ 0L, true, DataType.MEASUREMENT);
+ MeasurementScheduleRequest heapComittedRequest = new MeasurementScheduleRequest(0,
+ "{HeapMemoryUsage.committed}", 0L, true, DataType.MEASUREMENT);
+ calculationPropsSchedules.add(heapUsedRequest);
+ calculationPropsSchedules.add(heapComittedRequest);
+
+ getBeanProperties(calculationPropsReport, bean, calculationPropsSchedules);
+ Set<MeasurementDataNumeric> values = calculationPropsReport.getNumericData();
+ Double heapUsed = Double.NaN;
+ Double heapCommitted = Double.NaN;
+ if (null != values && values.size() == 2) {
+ for (MeasurementDataNumeric v : values) {
+ if (v.getName().equals("{HeapMemoryUsage.used}")) {
+ heapUsed = v.getValue();
+ } else {
+ heapCommitted = v.getValue();
+ }
+ }
+ }
+
+ Double value = Double.NaN;
+ try {
+ value = heapUsed / heapCommitted;
+ } catch (Throwable t) {
+ // leave as NaN
+ }
+
+ report.addData(new MeasurementDataNumeric(request, value));
+ }
+
+ return result;
+ }
+
protected String transformBeanName(String beanTemplate) {
Matcher m = TEMPLATE_PATTERN.matcher(beanTemplate);
diff --git a/modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml
index 76572a3..9bf9e1c 100644
--- a/modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml
@@ -250,6 +250,12 @@
property="{HeapMemoryUsage.used}"
description="Current heap memory usage"
units="bytes"/>
+ <!-- Heap Usage Percentage is calculated and is not an mbean property -->
+ <metric displayName="Heap Usage Percentage"
+ property="Calculated.HeapUsagePercentage"
+ displayType="summary"
+ description="Current heap memory usage as percentage of committed heap"
+ units="percentage"/>
<metric displayName="Heap Committed"
property="{HeapMemoryUsage.committed}"
displayType="summary"
diff --git a/modules/plugins/jmx/src/test/java/org/rhq/plugins/jmx/test/JMXPluginTest.java b/modules/plugins/jmx/src/test/java/org/rhq/plugins/jmx/test/JMXPluginTest.java
index 6fb39d6..151f99e 100644
--- a/modules/plugins/jmx/src/test/java/org/rhq/plugins/jmx/test/JMXPluginTest.java
+++ b/modules/plugins/jmx/src/test/java/org/rhq/plugins/jmx/test/JMXPluginTest.java
@@ -83,7 +83,7 @@ public class JMXPluginTest {
private static final String EXPLICIT_RESOURCE_KEY2 = "foo2";
private List<Process> testServerJvms = new ArrayList<Process>();
-
+
private InventoryManager inventoryManager;
@BeforeSuite
@@ -98,8 +98,8 @@ public class JMXPluginTest {
// + EXPLICIT_RESOURCE_KEY1));
this.testServerJvms.add(startTestServerJvm("-Dcom.sun.management.jmxremote.port=" + JMX_REMOTING_PORT2,
- "-Dcom.sun.management.jmxremote.ssl=false", "-Dcom.sun.management.jmxremote.authenticate=false",
- "-D" + JMXDiscoveryComponent.SYSPROP_RHQ_RESOURCE_KEY + "=" + EXPLICIT_RESOURCE_KEY2));
+ "-Dcom.sun.management.jmxremote.ssl=false", "-Dcom.sun.management.jmxremote.authenticate=false", "-D"
+ + JMXDiscoveryComponent.SYSPROP_RHQ_RESOURCE_KEY + "=" + EXPLICIT_RESOURCE_KEY2));
// Give them time to fully start.
Thread.sleep(3000);
@@ -113,7 +113,8 @@ public class JMXPluginTest {
PluginContainer.getInstance().setConfiguration(pcConfig);
PluginContainer.getInstance().initialize();
- Set<String> pluginNames = PluginContainer.getInstance().getPluginManager().getMetadataManager().getPluginNames();
+ Set<String> pluginNames = PluginContainer.getInstance().getPluginManager().getMetadataManager()
+ .getPluginNames();
System.out.println("PC started with plugins " + pluginNames + ".");
this.inventoryManager = PluginContainer.getInstance().getInventoryManager();
@@ -135,8 +136,8 @@ public class JMXPluginTest {
args.add("target/test-classes");
args.addAll(Arrays.asList(jvmArgs));
args.add(TestProgram.class.getName());
-
- ProcessBuilder processBuilder = new ProcessBuilder(args);
+
+ ProcessBuilder processBuilder = new ProcessBuilder(args);
processBuilder.redirectErrorStream(true);
Process process = processBuilder.start();
@@ -144,17 +145,17 @@ public class JMXPluginTest {
Thread outputReaderThread = new Thread(outputReader);
outputReaderThread.setDaemon(true);
outputReaderThread.start();
-
+
return process;
}
@AfterSuite
- public void stop() {
+ public void stop() {
PluginContainer.getInstance().shutdown();
-
+
for (Process process : this.testServerJvms) {
process.destroy();
- }
+ }
}
@Test
@@ -184,24 +185,24 @@ public class JMXPluginTest {
System.out.println(" * " + jmxServer);
JvmResourceKey key = JvmResourceKey.valueOf(jmxServer.getResourceKey());
switch (key.getType()) {
- case Explicit:
- if (key.getExplicitValue().equals(EXPLICIT_RESOURCE_KEY1)) {
- assert key.getMainClassName().equals(TestProgram.class.getName());
- foundExplicitKey1Server = true;
- } else if (key.getExplicitValue().equals(EXPLICIT_RESOURCE_KEY2)) {
- assert key.getMainClassName().equals(TestProgram.class.getName());
- foundExplicitKey2Server = true;
- }
- break;
- case JmxRemotingPort:
- if (key.getMainClassName().equals(TestProgram.class.getName()) &&
- key.getJmxRemotingPort().equals(JMX_REMOTING_PORT1)) {
- assert key.getMainClassName().equals(TestProgram.class.getName());
- foundJmxRemotingServer = true;
- }
- break;
- default:
- throw new IllegalStateException("Unsupported key type: " + key.getType());
+ case Explicit:
+ if (key.getExplicitValue().equals(EXPLICIT_RESOURCE_KEY1)) {
+ assert key.getMainClassName().equals(TestProgram.class.getName());
+ foundExplicitKey1Server = true;
+ } else if (key.getExplicitValue().equals(EXPLICIT_RESOURCE_KEY2)) {
+ assert key.getMainClassName().equals(TestProgram.class.getName());
+ foundExplicitKey2Server = true;
+ }
+ break;
+ case JmxRemotingPort:
+ if (key.getMainClassName().equals(TestProgram.class.getName())
+ && key.getJmxRemotingPort().equals(JMX_REMOTING_PORT1)) {
+ assert key.getMainClassName().equals(TestProgram.class.getName());
+ foundJmxRemotingServer = true;
+ }
+ break;
+ default:
+ throw new IllegalStateException("Unsupported key type: " + key.getType());
}
}
assert foundJmxRemotingServer : "JMX Remoting server not found.";
@@ -210,16 +211,7 @@ public class JMXPluginTest {
assert foundExplicitKey2Server : "JMX Remoting + explicit key server not found.";
}
- /**
- * This test is currently disabled because we hit a NPE in
- * JvmUtility.attachToVirtualMachine on line 107 where,
- *
- * process.getCredentialsName().getUser();
- *
- * is called. Looks like the NPE is coming from the call to getUser() at the end and
- * it might be due to this Sigar bug, https://jira.hyperic.com/browse/SIGAR-231.
- */
- @Test(dependsOnMethods = "testServerDiscovery", enabled = false)
+ @Test(dependsOnMethods = "testServerDiscovery")
public void testServiceDiscovery() throws Exception {
InventoryReport report = PluginContainer.getInstance().getInventoryManager().executeServiceScanImmediately();
assert report != null;
@@ -228,7 +220,7 @@ public class JMXPluginTest {
assert platform != null;
Set<Resource> jmxServers = getChildResourcesOfType(platform, new ResourceType(SERVER_TYPE_NAME, PLUGIN_NAME,
- ResourceCategory.SERVER, null));
+ ResourceCategory.SERVER, null));
for (Resource jmxServer : jmxServers) {
Set<Resource> childResources = jmxServer.getChildResources();
@@ -255,12 +247,16 @@ public class JMXPluginTest {
Set<MeasurementScheduleRequest> metricList = new HashSet<MeasurementScheduleRequest>();
metricList.add(new MeasurementScheduleRequest(1, "FreePhysicalMemorySize", 1000, true,
DataType.MEASUREMENT));
+ if ("VM Memory System".equals(service.getResourceType().getName())) {
+ metricList.add(new MeasurementScheduleRequest(2, "Calculated.HeapUsagePercentage", 1000, true,
+ DataType.MEASUREMENT));
+ }
MeasurementReport report = new MeasurementReport();
if (serviceComponent.getAvailability().equals(AvailabilityType.UP)) {
((MeasurementFacet) serviceComponent).getValues(report, metricList);
for (MeasurementData value : report.getNumericData()) {
- System.out.println(value.getValue() + ":" + service.getName());
+ System.out.println(value.getValue() + ":" + value.getName());
}
}
}
@@ -280,7 +276,7 @@ public class JMXPluginTest {
.getResourceComponent(service);
Object result = ((OperationFacet) serviceComponent).invokeOperation("findMonitorDeadlockedThreads",
- new Configuration());
+ new Configuration());
System.out.println("Result of operation test was: " + result);
}
}
@@ -328,8 +324,8 @@ public class JMXPluginTest {
Set<Resource> results = new HashSet<Resource>();
for (Resource resource : childResources) {
ResourceType childResourceType = resource.getResourceType();
- if (childResourceType.getPlugin().equals(resourceType.getPlugin()) &&
- childResourceType.getName().equals(resourceType.getName())) {
+ if (childResourceType.getPlugin().equals(resourceType.getPlugin())
+ && childResourceType.getName().equals(resourceType.getName())) {
results.add(resource);
}
}
@@ -360,7 +356,7 @@ public class JMXPluginTest {
public static class TestProgram implements Runnable {
long started = System.currentTimeMillis();
- public static void main(String[] args) {
+ public static void main(String[] args) {
final ServerSocket serverSocket;
try {
serverSocket = new ServerSocket(0);
@@ -372,7 +368,7 @@ public class JMXPluginTest {
String jvmName = runtimeMXBean.getName();
int atIndex = jvmName.indexOf('@');
String pid = (atIndex != -1) ? jvmName.substring(0, atIndex) : "?";
-
+
System.out.println("Test server JVM with pid [" + pid + "] listening on port ["
+ serverSocket.getLocalPort() + "]...");
Runnable runnable = new Runnable() {
10 years, 11 months
[rhq] modules/enterprise
by Jiri Kremser
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/DurationItem.java | 28 +++-------
1 file changed, 10 insertions(+), 18 deletions(-)
New commits:
commit 2eef3b4fcd05fc1b248ab3c95fbc115e3758079d
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Wed May 29 13:48:05 2013 +0200
[BZ 967542] - UI shows confusing units when editing Availability Duration alert condition type
Now if user iserts e.g. 90 mins and reopens the dialog, it won't display
1.5 hours anymore, but 90 mins as expected.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/DurationItem.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/DurationItem.java
index 104b84c..6c41897 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/DurationItem.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/DurationItem.java
@@ -38,6 +38,7 @@ import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
import com.smartgwt.client.widgets.form.validator.IntegerRangeValidator;
import org.rhq.core.domain.measurement.MeasurementUnits;
+import org.rhq.core.domain.measurement.composite.MeasurementNumericValueAndUnits;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.Messages;
import org.rhq.enterprise.gui.coregui.client.util.FormUtility;
@@ -238,26 +239,17 @@ public class DurationItem extends CanvasItem {
this.form.setValue(FIELD_VALUE, formattedOutput);
setValue(formattedOutput);
} else {
- String valueWithUnits = MeasurementConverterClient.format((double) longValue,
- MeasurementUnits.MILLISECONDS, true);
- String[] chunks = valueWithUnits.split(" ");
- String value = chunks[0];
- if (value.endsWith(".0")) {
- value = value.substring(0, value.indexOf(".0"));
+ MeasurementNumericValueAndUnits valueWithUnits;
+ if (longValue % HOUR_IN_MILLIS == 0) {
+ valueWithUnits = MeasurementConverterClient.fit((double) longValue, MeasurementUnits.MILLISECONDS,
+ MeasurementUnits.HOURS, MeasurementUnits.HOURS);
+ } else {
+ valueWithUnits = MeasurementConverterClient.fit((double) longValue, MeasurementUnits.MILLISECONDS,
+ MeasurementUnits.MINUTES, MeasurementUnits.MINUTES);
}
- this.form.setValue(FIELD_VALUE, value);
- String units = chunks[1];
SelectItem unitsItem = (SelectItem) this.form.getItem(FIELD_UNITS);
- if (MeasurementConverterClient.getMeasurementUnitAbbreviation(MeasurementUnits.SECONDS).equals(units)) {
- unitsItem.setValue(TimeUnit.SECONDS.name().toLowerCase());
- } else if (MeasurementConverterClient.getMeasurementUnitAbbreviation(MeasurementUnits.MINUTES)
- .equals(units)) {
- unitsItem.setValue(TimeUnit.MINUTES.name().toLowerCase());
- } else if (MeasurementConverterClient.getMeasurementUnitAbbreviation(MeasurementUnits.HOURS).equals(units)) {
- unitsItem.setValue(TimeUnit.HOURS.name().toLowerCase());
- } else if (MeasurementConverterClient.getMeasurementUnitAbbreviation(MeasurementUnits.DAYS).equals(units)) {
- unitsItem.setValue(TimeUnit.DAYS.name().toLowerCase());
- }
+ this.form.setValue(FIELD_VALUE, valueWithUnits.getValue().intValue());
+ unitsItem.setValue(valueWithUnits.getUnits().name().toLowerCase());
}
}
10 years, 11 months
[rhq] Branch 'feature/cassandra-backend' - modules/common
by John Sanda
modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/SchemaManager.java | 21 +++++-----
1 file changed, 11 insertions(+), 10 deletions(-)
New commits:
commit e15a13e8909a9b0d19ab81b680984bca8cf4eec1
Author: John Sanda <jsanda(a)redhat.com>
Date: Tue May 28 21:50:36 2013 -0400
do not update the system_auth keyspace replication_factor during schema creation
It makes more sense to update the RF from the server after nodes are committed
into invetory and managed because updating the RF needs to be followed up by a
reead repair on each node to make sure the changes propagate.
diff --git a/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/SchemaManager.java b/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/SchemaManager.java
index c03dc58..b888db0 100644
--- a/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/SchemaManager.java
+++ b/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/SchemaManager.java
@@ -58,6 +58,8 @@ public class SchemaManager {
private List<StorageNode> nodes = new ArrayList<StorageNode>();
+ private Integer systemAuthRF = null;
+
public SchemaManager(String username, String password, String... nodes) {
try {
this.username = username;
@@ -118,17 +120,13 @@ public class SchemaManager {
int replicationFactor = 1;
if (nodes.size() == 1) {
- log.debug("Setting replication_factor to 1 for rhq keyspace since this is a single node cluster.");
replicationFactor = 1;
} else if (nodes.size() < 4) {
- log.debug("Setting replication_factor to 2 for rhq keyspace since this is a " + nodes.size() +
- " node cluster");
replicationFactor = 2;
} else {
- log.debug("Setting replication_factor to 3 for rhq keyspace since this is a " + nodes.size() +
- " node cluster");
replicationFactor = 3;
}
+ log.debug("Setting replication_factor to " + replicationFactor + " for rhq keyspace");
session.execute("CREATE KEYSPACE rhq WITH replication = {'class': 'SimpleStrategy', " +
"'replication_factor': " + replicationFactor + "};");
@@ -194,11 +192,14 @@ public class SchemaManager {
}
try {
- log.debug("Setting system_auth keyspace replication_factor to " + nodes.size());
- session.execute(
- "ALTER KEYSPACE system_auth WITH replication = " +
- "{'class' : 'SimpleStrategy', 'replication_factor' : " + nodes.size() + "};"
- );
+ // Update the system_auth RF from server code. That makes more sense since we
+ // need run repair on each node after the schema change.
+
+// log.debug("Setting system_auth keyspace replication_factor to " + nodes.size());
+// session.execute(
+// "ALTER KEYSPACE system_auth WITH replication = " +
+// "{'class' : 'SimpleStrategy', 'replication_factor' : " + nodes.size() + "};"
+// );
log.debug("Creating table raw_metrics");
session.execute(
10 years, 11 months
[rhq] Branch 'feature/cassandra-backend' - modules/common
by John Sanda
modules/common/cassandra-installer/src/main/java/org/rhq/storage/installer/StorageInstaller.java | 4 ++++
1 file changed, 4 insertions(+)
New commits:
commit ac2a3440e9033c8ea44ce8e69b949519e8e881ae
Author: John Sanda <jsanda(a)redhat.com>
Date: Tue May 28 17:25:23 2013 -0400
use out of box default of 128 for native_transport_max_threads
diff --git a/modules/common/cassandra-installer/src/main/java/org/rhq/storage/installer/StorageInstaller.java b/modules/common/cassandra-installer/src/main/java/org/rhq/storage/installer/StorageInstaller.java
index b205aae..2e9684d 100644
--- a/modules/common/cassandra-installer/src/main/java/org/rhq/storage/installer/StorageInstaller.java
+++ b/modules/common/cassandra-installer/src/main/java/org/rhq/storage/installer/StorageInstaller.java
@@ -241,6 +241,10 @@ public class StorageInstaller {
deploymentOptions.setStoragePort(getPort(cmdLine, "storage-port", storagePort));
deploymentOptions.setSslStoragePort(getPort(cmdLine, "ssl-storage-port", sslStoragePort));
+ // The out of box default for native_transport_max_threads is 128. We default
+ // to 64 for dev/test environments so we need to update it here.
+ deploymentOptions.setNativeTransportMaxThreads(128);
+
if (cmdLine.hasOption("heap-size")) {
deploymentOptions.setHeapSize(cmdLine.getOptionValue("heap-size"));
}
10 years, 11 months
[rhq] Branch 'feature/cassandra-backend' - modules/enterprise
by John Sanda
modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/MetricsBaselineCalculatorTest.java | 19 +++++++---
1 file changed, 14 insertions(+), 5 deletions(-)
New commits:
commit 7953b700f9a6133d1a7ffe25b37521ed4f6e2825
Author: John Sanda <jsanda(a)redhat.com>
Date: Tue May 28 17:00:30 2013 -0400
re-applying test failure fixes that were lost during last rebase
diff --git a/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/MetricsBaselineCalculatorTest.java b/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/MetricsBaselineCalculatorTest.java
index 734a006..ab4bd03 100644
--- a/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/MetricsBaselineCalculatorTest.java
+++ b/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/MetricsBaselineCalculatorTest.java
@@ -27,6 +27,8 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import static org.rhq.test.AssertUtils.assertPropertiesMatch;
+import static org.testng.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
@@ -75,7 +77,7 @@ public class MetricsBaselineCalculatorTest {
.withArguments(eq(mockSession), eq(metricsConfiguration)).thenReturn(mockMetricsDAO);
when(mockMetricsDAO.findAggregatedSimpleOneHourMetric(eq(1), eq(0),
- eq(1))).thenReturn(new ArrayList<AggregateSimpleNumericMetric>());
+ eq(1))).thenReturn(new ArrayList<AggregateSimpleNumericMetric>());
MeasurementSchedule mockSchedule = mock(MeasurementSchedule.class);
when(mockSchedule.getId()).thenReturn(0);
@@ -88,13 +90,20 @@ public class MetricsBaselineCalculatorTest {
List<MeasurementBaseline> result = objectUnderTest.calculateBaselines(Arrays.asList(mockSchedule), 0, 1);
//verify the results (Assert and mock verification)
- Assert.assertEquals(result.size(), 0);
+ assertEquals(result.size(), 1, "Expected to get back one baseline");
+ MeasurementBaseline expected = new MeasurementBaseline();
+ expected.setSchedule(mockSchedule);
+ expected.setMax(Double.NaN);
+ expected.setMin(Double.NaN);
+ expected.setMean(Double.NaN);
+
+ assertPropertiesMatch("", expected, result.get(0), "computeTime");
+
verify(mockMetricsDAO, times(1)).findAggregatedSimpleOneHourMetric(any(Integer.class), any(Integer.class),
any(Integer.class));
verifyNoMoreInteractions(mockMetricsDAO);
verify(mockSchedule, times(1)).getId();
- verifyNoMoreInteractions(mockSchedule);
}
@Test
@@ -177,7 +186,7 @@ public class MetricsBaselineCalculatorTest {
eq(expectedStartTime), eq(expectedEndTime));
verifyNoMoreInteractions(mockMetricsDAO);
- verify(mockSchedule, times(1)).getId();
+ verify(mockSchedule, times(2)).getId();
verify(mockSchedule, times(1)).setBaseline(eq(baselineResult));
verifyNoMoreInteractions(mockSchedule);
}
@@ -238,7 +247,7 @@ public class MetricsBaselineCalculatorTest {
eq(expectedStartTime), eq(expectedEndTime));
verifyNoMoreInteractions(mockMetricsDAO);
- verify(mockSchedule, times(1)).getId();
+ verify(mockSchedule, times(2)).getId();
verify(mockSchedule, times(1)).setBaseline(eq(baselineResult));
verifyNoMoreInteractions(mockSchedule);
}
10 years, 11 months
[rhq] Branch 'feature/cassandra-backend' - 18 commits - .classpath etc/rhq-ircBot modules/core modules/enterprise modules/integration-tests modules/plugins
by John Sanda
.classpath | 1
etc/rhq-ircBot/pom.xml | 15
etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBot.java | 270 ++-----
etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java | 375 ++++++++++
etc/rhq-ircBot/src/main/resources/org/rhq/etc/ircbot/cacerts.jks |binary
etc/rhq-ircBot/src/main/resources/org/rhq/etc/ircbot/rhq-ircbot.properties | 2
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java | 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/AlertDefinitionTemplateTypeView.java | 11
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/DriftDefinitionTemplateTypeView.java | 11
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/IgnoreResourceTypesView.java | 7
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/MetricTemplateTypeView.java | 11
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/ResourceTypeTreeNodeBuilder.java | 153 +++-
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties | 87 +-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java | 188 ++---
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java | 36
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertHandlerBean.java | 27
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/EventHandlerBean.java | 75 +-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/GroupHandlerBean.java | 20
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java | 25
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java | 71 -
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/Link.java | 16
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/PagingCollection.java | 97 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/ResourceWithType.java | 20
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java | 86 +-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryRunner.java | 4
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AbstractBase.java | 9
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AlertTest.java | 84 ++
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ContentTest.java | 37
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/EventTest.java | 129 +++
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/GroupTest.java | 44 +
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java | 144 +++
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/UserTest.java | 4
modules/plugins/jboss-as-7/pom.xml | 1
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java | 51 +
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java | 43 +
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/ServerPluginConfiguration.java | 19
modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml | 22
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractJBossAS7PluginTest.java | 33
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/DomainServerComponentTest.java | 17
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/ManagedServerTest.java | 19
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/StandaloneServerComponentTest.java | 24
41 files changed, 1754 insertions(+), 536 deletions(-)
New commits:
commit 25fc2183e12a10367f95bbbc8243883a9ab1e593
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri May 24 23:29:46 2013 -0400
remove use of method not supported by GWT
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java
index d8552de..f398020 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java
@@ -179,7 +179,7 @@ public abstract class Criteria implements Serializable, BaseCriteria {
this.sortId = sortId;
} else {
- throw new UnsupportedOperationException("ID sort is not supported by " + this.getClass().getSimpleName());
+ throw new UnsupportedOperationException("ID sort is not supported by supported by this class");
}
}
@@ -188,7 +188,7 @@ public abstract class Criteria implements Serializable, BaseCriteria {
this.filterId = filterId;
} else {
- throw new UnsupportedOperationException("ID filter is not supported by " + this.getClass().getSimpleName());
+ throw new UnsupportedOperationException("ID filter is not supported by this class");
}
}
@@ -197,7 +197,7 @@ public abstract class Criteria implements Serializable, BaseCriteria {
this.filterIds = CriteriaUtils.getListIgnoringNulls(filterIds);
} else {
- throw new UnsupportedOperationException("IDS filter is not supported by " + this.getClass().getSimpleName());
+ throw new UnsupportedOperationException("IDS filter is not supported by this class");
}
}
commit 3aa9038620e4aa08b4aef4f42a026b3cbeaba096
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri May 24 19:45:41 2013 -0400
Bug 966665
- Criteria queries with paging and sorting on non unique fields may return same item on different pages
All paged criteria queries now apply ID as the least significant
ordering field (see exceptions below). Since ID is unique, this ensures
that queries for pages always return the same ordering of rows.
ID will not be automatically appended as an ordering field if:
- the paging is unlimited (i.e. no pagesize, all rows returned)
- the Criteria class does not support an ID sort
- the caller has set the Criteria class instance to not support the ID sort
- ID is already specified as an ordering field
- the max number of ordering fields has already been set (3)
Note that CriteriaQuery has had its support for implicit ID sorting removed,
as the new mechanism, which moves support to the CriteriaQueryGenerator,
replaces it.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java
index e224fca..d8552de 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java
@@ -179,7 +179,7 @@ public abstract class Criteria implements Serializable, BaseCriteria {
this.sortId = sortId;
} else {
- throw new UnsupportedOperationException("ID sort is not supported by this class");
+ throw new UnsupportedOperationException("ID sort is not supported by " + this.getClass().getSimpleName());
}
}
@@ -188,7 +188,7 @@ public abstract class Criteria implements Serializable, BaseCriteria {
this.filterId = filterId;
} else {
- throw new UnsupportedOperationException("ID filter is not supported by this class");
+ throw new UnsupportedOperationException("ID filter is not supported by " + this.getClass().getSimpleName());
}
}
@@ -197,7 +197,7 @@ public abstract class Criteria implements Serializable, BaseCriteria {
this.filterIds = CriteriaUtils.getListIgnoringNulls(filterIds);
} else {
- throw new UnsupportedOperationException("IDS filter is not supported by this class");
+ throw new UnsupportedOperationException("IDS filter is not supported by " + this.getClass().getSimpleName());
}
}
commit c8a43459e8eb7773a6fb58cabd2d069fd5c62b9b
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Fri May 24 23:56:54 2013 +0200
Bug 920214 - [as7] add async avail check support to AS7 plugin
Only applies to server level resource (Standalone, Domain and Managed servers)
diff --git a/modules/plugins/jboss-as-7/pom.xml b/modules/plugins/jboss-as-7/pom.xml
index 5f538b7..d85e7e3 100644
--- a/modules/plugins/jboss-as-7/pom.xml
+++ b/modules/plugins/jboss-as-7/pom.xml
@@ -617,6 +617,7 @@
<!--<include>org/rhq/modules/plugins/jbossas7/itest/standalone/InterruptibleOperationsTest.java</include>-->
<!--<include>org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentTest.java</include>-->
<!--<include>org/rhq/modules/plugins/jbossas7/itest/domain/DomainServerComponentTest.java</include>-->
+ <!--<include>org/rhq/modules/plugins/jbossas7/itest/domain/ManagedServerTest.java</include>-->
<!--<include>org/rhq/modules/plugins/jbossas7/itest/domain/SecurityModuleOptionsTest.java</include>-->
<!--<include>org/rhq/modules/plugins/jbossas7/itest/nonpc/ManagementConnectionPersistenceTest.java</include>-->
</includes>
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java
index b80a39a..5d540fd 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java
@@ -16,6 +16,7 @@
* 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.modules.plugins.jbossas7;
import java.io.File;
@@ -40,6 +41,8 @@ import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.measurement.MeasurementDataTrait;
import org.rhq.core.domain.measurement.MeasurementReport;
import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
+import org.rhq.core.pluginapi.availability.AvailabilityCollectorRunnable;
+import org.rhq.core.pluginapi.availability.AvailabilityFacet;
import org.rhq.core.pluginapi.event.log.LogFileEventResourceComponentHelper;
import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
@@ -81,7 +84,8 @@ public abstract class BaseServerComponent<T extends ResourceComponent<?>> extend
private LogFileEventResourceComponentHelper logFileEventDelegate;
private StartScriptConfiguration startScriptConfig;
private ServerPluginConfiguration serverPluginConfig;
- private AvailabilityType lastAvail;
+ private AvailabilityType previousAvailabilityType;
+ private AvailabilityCollectorRunnable availabilityCollector;
@Override
public void start(ResourceContext<T> resourceContext) throws InvalidPluginConfigurationException, Exception {
@@ -89,38 +93,69 @@ public abstract class BaseServerComponent<T extends ResourceComponent<?>> extend
serverPluginConfig = new ServerPluginConfiguration(pluginConfiguration);
connection = ASConnection.newInstanceForServerPluginConfiguration(serverPluginConfig);
+ // The availabilityCollector is still null at this point. So this call will always perform a real availability
+ // check and throw InvalidPluginConfigurationException as needed.
getAvailability();
logFileEventDelegate = new LogFileEventResourceComponentHelper(context);
logFileEventDelegate.startLogFileEventPollers();
startScriptConfig = new StartScriptConfiguration(pluginConfiguration);
+
+ Integer availabilityCheckPeriod = null;
+ try {
+ availabilityCheckPeriod = serverPluginConfig.getAvailabilityCheckPeriod();
+ } catch (NumberFormatException e) {
+ log.error("Avail check period config prop was not a valid number. Cause: " + e);
+ }
+ if (availabilityCheckPeriod != null) {
+ long availCheckMillis = availabilityCheckPeriod * 1000L;
+ this.availabilityCollector = resourceContext.getAvailabilityContext().createAvailabilityCollectorRunnable(
+ new AvailabilityFacet() {
+ public AvailabilityType getAvailability() {
+ return getAvailabilityNow();
+ }
+ }, availCheckMillis);
+ this.availabilityCollector.start();
+ }
}
@Override
public void stop() {
logFileEventDelegate.stopLogFileEventPollers();
- lastAvail = null;
+ previousAvailabilityType = null;
+ if (this.availabilityCollector != null) {
+ this.availabilityCollector.stop();
+ this.availabilityCollector = null;
+ }
}
@Override
public AvailabilityType getAvailability() {
- AvailabilityType avail;
+ if (this.availabilityCollector != null) {
+ return this.availabilityCollector.getLastKnownAvailability();
+ } else {
+ return getAvailabilityNow();
+ }
+ }
+
+ private AvailabilityType getAvailabilityNow() {
+ AvailabilityType availabilityType;
try {
readAttribute("launch-type");
- avail = AvailabilityType.UP;
+ availabilityType = AvailabilityType.UP;
} catch (Exception e) {
- avail = AvailabilityType.DOWN;
+ availabilityType = AvailabilityType.DOWN;
}
try {
- if ((avail == AvailabilityType.UP) && (lastAvail != AvailabilityType.UP)) {
+ if ((availabilityType == AvailabilityType.UP) && (previousAvailabilityType != AvailabilityType.UP)) {
validateServerAttributes();
log.info(getResourceDescription() + " has just come UP.");
}
} finally {
- lastAvail = avail;
+ previousAvailabilityType = availabilityType;
}
- return avail;
+ return availabilityType;
}
private void validateServerAttributes() throws InvalidPluginConfigurationException {
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java
index e7fcd5b..4f0ea36 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2011 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,11 +13,14 @@
* 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.
+ * 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.modules.plugins.jbossas7;
+import static org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration.Property.AVAIL_CHECK_PERIOD_CONFIG_PROP;
+
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
@@ -30,6 +33,8 @@ import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.measurement.MeasurementDataTrait;
import org.rhq.core.domain.measurement.MeasurementReport;
import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
+import org.rhq.core.pluginapi.availability.AvailabilityCollectorRunnable;
+import org.rhq.core.pluginapi.availability.AvailabilityFacet;
import org.rhq.core.pluginapi.event.log.LogFileEventResourceComponentHelper;
import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.pluginapi.inventory.ResourceContext;
@@ -51,6 +56,7 @@ public class ManagedASComponent extends BaseComponent<HostControllerComponent<?>
private static final String MANAGED_SERVER_TYPE_NAME = "Managed Server";
private LogFileEventResourceComponentHelper logFileEventDelegate;
+ private AvailabilityCollectorRunnable availabilityCollector;
@Override
public void start(ResourceContext<HostControllerComponent<?>> hostControllerComponentResourceContext)
@@ -59,13 +65,34 @@ public class ManagedASComponent extends BaseComponent<HostControllerComponent<?>
logFileEventDelegate = new LogFileEventResourceComponentHelper(context);
logFileEventDelegate.startLogFileEventPollers();
+
+ Integer availabilityCheckPeriod = null;
+ try {
+ availabilityCheckPeriod = pluginConfiguration.getSimple(AVAIL_CHECK_PERIOD_CONFIG_PROP).getIntegerValue();
+ } catch (NumberFormatException e) {
+ log.error("Avail check period config prop was not a valid number. Cause: " + e);
+ }
+ if (availabilityCheckPeriod != null) {
+ long availCheckMillis = availabilityCheckPeriod * 1000L;
+ this.availabilityCollector = hostControllerComponentResourceContext.getAvailabilityContext()
+ .createAvailabilityCollectorRunnable(new AvailabilityFacet() {
+ public AvailabilityType getAvailability() {
+ return getAvailabilityNow();
+ }
+ }, availCheckMillis);
+ this.availabilityCollector.start();
+ }
+
}
@Override
public void stop() {
super.stop();
-
logFileEventDelegate.stopLogFileEventPollers();
+ if (this.availabilityCollector != null) {
+ this.availabilityCollector.stop();
+ this.availabilityCollector = null;
+ }
}
/**
@@ -76,6 +103,14 @@ public class ManagedASComponent extends BaseComponent<HostControllerComponent<?>
*/
@Override
public AvailabilityType getAvailability() {
+ if (this.availabilityCollector != null) {
+ return this.availabilityCollector.getLastKnownAvailability();
+ } else {
+ return getAvailabilityNow();
+ }
+ }
+
+ private AvailabilityType getAvailabilityNow() {
if (context.getResourceType().getName().equals(MANAGED_SERVER_TYPE_NAME)) {
Address theAddress = new Address();
String host = pluginConfiguration.getSimpleValue("domainHost", "local");
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/ServerPluginConfiguration.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/ServerPluginConfiguration.java
index 1433c17..3832ed2 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/ServerPluginConfiguration.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/ServerPluginConfiguration.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,14 +13,16 @@
* 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.
+ * 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.modules.plugins.jbossas7.helper;
import java.io.File;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.modules.plugins.jbossas7.JBossProductType;
/**
@@ -43,6 +45,7 @@ public class ServerPluginConfiguration {
public static final String LOG_DIR = "logDir";
public static final String PRODUCT_TYPE = "productType";
public static final String HOST_CONFIG_FILE = "hostConfigFile";
+ public static final String AVAIL_CHECK_PERIOD_CONFIG_PROP = "availabilityCheckPeriod";
}
private Configuration pluginConfig;
@@ -143,4 +146,14 @@ public class ServerPluginConfiguration {
hostConfigFile.toString() : null);
}
+ public Integer getAvailabilityCheckPeriod() {
+ PropertySimple propertySimple = this.pluginConfig.getSimple(Property.AVAIL_CHECK_PERIOD_CONFIG_PROP);
+ return propertySimple == null ? null : propertySimple.getIntegerValue();
+ }
+
+ public void setAvailabilityCheckPeriod(Integer availabilityCheckPeriod) {
+ this.pluginConfig.setSimpleValue(Property.AVAIL_CHECK_PERIOD_CONFIG_PROP,
+ availabilityCheckPeriod == null ? null : availabilityCheckPeriod.toString());
+ }
+
}
diff --git a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
index ad22370..7213acd 100644
--- a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
@@ -82,6 +82,17 @@
</c:list-property>
</c:group>
'>
+
+ <!ENTITY availabilityCheckPeriod '
+ <c:simple-property name="availabilityCheckPeriod"
+ description="The amount of time, in seconds, that must elapse between availability checks to see if the server is up. If set, the availability checks will be performed asynchronously thus allowing slow-responding servers to avoid being falsely reported as down. Minimum value is 60 seconds."
+ units="seconds" required="false" type="integer">
+ <c:constraint>
+ <c:integer-constraint minimum="60"/>
+ </c:constraint>
+ </c:simple-property>
+'>
+
<!ENTITY serverKindMetrics '
<metric property="_skm:release-codename" dataType="trait" displayName="Server Code Name"/>
<metric property="_skm:release-version" dataType="trait" displayName="Server Version"/>
@@ -862,6 +873,10 @@
&startScriptPluginConfigGroup;
&logSources;
+
+ <c:group name="advanced" displayName="Advanced" hiddenByDefault="true">
+ &availabilityCheckPeriod;
+ </c:group>
</plugin-configuration>
<process-scan name="HostController" query="process|basename|match=^java.*,arg|org.jboss.as.host-controller|match=.*"/>
@@ -1173,6 +1188,10 @@
&startScriptPluginConfigGroup;
&logSources;
+
+ <c:group name="advanced" displayName="Advanced" hiddenByDefault="true">
+ &availabilityCheckPeriod;
+ </c:group>
</plugin-configuration>
<process-scan name="StandaloneAS" query="process|basename|match=^java.*,arg|org.jboss.as.standalone|match=.*"/>
@@ -1621,6 +1640,9 @@
<plugin-configuration>
<c:simple-property name="path" readOnly="true"/>
&logSources;
+ <c:group name="advanced" displayName="Advanced" hiddenByDefault="true">
+ &availabilityCheckPeriod;
+ </c:group>
</plugin-configuration>
<operation name="start" description="Start this server instance." displayName="Start">
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractJBossAS7PluginTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractJBossAS7PluginTest.java
index 43e6e06..8c61c8e 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractJBossAS7PluginTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractJBossAS7PluginTest.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,11 +13,14 @@
* 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.
+ * 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.modules.plugins.jbossas7.itest;
+import static org.rhq.core.domain.measurement.AvailabilityType.UP;
+import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.util.Set;
@@ -31,8 +34,10 @@ import org.rhq.core.domain.util.ResourceFilter;
import org.rhq.core.domain.util.ResourceUtility;
import org.rhq.core.domain.util.TypeAndKeyResourceFilter;
import org.rhq.core.pc.inventory.InventoryManager;
+import org.rhq.core.pc.inventory.ResourceContainer;
import org.rhq.core.plugin.testutil.AbstractAgentPluginTest;
import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration;
import org.rhq.modules.plugins.jbossas7.itest.domain.DomainServerComponentTest;
import org.rhq.modules.plugins.jbossas7.itest.standalone.StandaloneServerComponentTest;
import org.rhq.test.arquillian.AfterDiscovery;
@@ -152,4 +157,26 @@ public abstract class AbstractJBossAS7PluginTest extends AbstractAgentPluginTest
return serverResource;
}
+ protected void testAsynchronousAvailabilityCheck(Resource resource) throws Exception {
+ // Activate asynchronous availability checking
+ ServerPluginConfiguration serverPluginConfig = new ServerPluginConfiguration(resource.getPluginConfiguration());
+ int availabilityCheckPeriod = 65;
+ serverPluginConfig.setAvailabilityCheckPeriod(availabilityCheckPeriod);
+ restartResourceComponent(resource);
+
+ Thread.sleep((3 * availabilityCheckPeriod * 1000L) / 2);
+ assertEquals(getAvailability(resource), UP);
+
+ // Deactivate asynchronous availability checking as subsequent tests may rely on immediate availabilty checking
+ serverPluginConfig.setAvailabilityCheckPeriod(null);
+ restartResourceComponent(resource);
+ }
+
+ private void restartResourceComponent(Resource resource) throws PluginContainerException {
+ InventoryManager inventoryManager = this.pluginContainer.getInventoryManager();
+ inventoryManager.deactivateResource(resource);
+ ResourceContainer serverContainer = inventoryManager.getResourceContainer(resource);
+ inventoryManager.activateResource(resource, serverContainer, true);
+ }
+
}
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/DomainServerComponentTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/DomainServerComponentTest.java
index 4effd50..91ece92 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/DomainServerComponentTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/DomainServerComponentTest.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,9 +13,10 @@
* 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.
+ * 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.modules.plugins.jbossas7.itest.domain;
import java.io.File;
@@ -76,14 +77,20 @@ public class DomainServerComponentTest extends AbstractServerComponentTest {
testServerAttributeValidation();
}
+ @Test(priority = 1002)
+ public void testDomainServerAsynchronousAvailabilityCheck() throws Exception {
+ testAsynchronousAvailabilityCheck(getServerResource());
+ }
+
+
// ******************************* METRICS ******************************* //
- @Test(priority = 1002, enabled = true)
+ @Test(priority = 1003, enabled = true)
public void testDomainReleaseVersionTrait() throws Exception {
super.testReleaseVersionTrait();
}
// ******************************* OPERATIONS ******************************* //
- @Test(priority = 1003, enabled = true)
+ @Test(priority = 1004, enabled = true)
public void testDomainServerShutdownAndStartOperations() throws Exception {
super.testShutdownAndStartOperations();
}
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/ManagedServerTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/ManagedServerTest.java
index 3f9f101..42bab08 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/ManagedServerTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/ManagedServerTest.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2012 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,11 +13,14 @@
* 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.
+ * 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.modules.plugins.jbossas7.itest.domain;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
import org.testng.annotations.Test;
import org.rhq.core.clientapi.agent.PluginContainerException;
@@ -32,9 +35,6 @@ import org.rhq.core.pc.inventory.InventoryManager;
import org.rhq.modules.plugins.jbossas7.itest.AbstractJBossAS7PluginTest;
import org.rhq.test.arquillian.RunDiscovery;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-
/**
* Test dealing with managed servers
* @author Heiko W. Rupp
@@ -45,7 +45,7 @@ public class ManagedServerTest extends AbstractJBossAS7PluginTest {
public static final ResourceType RESOURCE_TYPE = new ResourceType("Managed Server", PLUGIN_NAME, ResourceCategory.SERVER, null);
private static final String RESOURCE_KEY = "master/server-one";
- @Test(priority = 1020, groups = "discovery", enabled = false)
+ @Test(priority = 1020, groups = "discovery", enabled = true)
@RunDiscovery(discoverServices = true, discoverServers = true)
public void runDiscovery() throws Exception {
Resource platform = this.pluginContainer.getInventoryManager().getPlatform();
@@ -93,6 +93,11 @@ public class ManagedServerTest extends AbstractJBossAS7PluginTest {
assertEquals(avail, AvailabilityType.UP);
}
+ @Test(priority = 1022)
+ public void testManagedServerAsynchronousAvailabilityCheck() throws Exception {
+ testAsynchronousAvailabilityCheck(getResource());
+ }
+
private Resource getResource() {
InventoryManager im = pluginContainer.getInventoryManager();
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/StandaloneServerComponentTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/StandaloneServerComponentTest.java
index 9845b03..8446345 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/StandaloneServerComponentTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/StandaloneServerComponentTest.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,11 +13,14 @@
* 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.
+ * 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.modules.plugins.jbossas7.itest.standalone;
+import static org.rhq.core.domain.measurement.AvailabilityType.UP;
+import static org.testng.Assert.assertEquals;
+
import java.io.File;
import java.util.Arrays;
import java.util.List;
@@ -38,8 +41,6 @@ import org.rhq.core.domain.resource.ResourceType;
import org.rhq.modules.plugins.jbossas7.itest.AbstractServerComponentTest;
import org.rhq.test.arquillian.RunDiscovery;
-import static org.testng.Assert.assertEquals;
-
/**
* Test discovery and facets of the "JBossAS7 Standalone Server" Resource type.
*
@@ -105,20 +106,20 @@ public class StandaloneServerComponentTest extends AbstractServerComponentTest {
}
// TODO: Re-enable once fixed.
- @Test(priority = 5, dependsOnMethods = "testStandaloneServerShutdownAndStartOperations", enabled = false)
+ @Test(priority = 6, dependsOnMethods = "testStandaloneServerShutdownAndStartOperations", enabled = false)
public void testRestartOperation() throws Exception {
// First make sure the server is up.
AvailabilityType avail = getAvailability(getServerResource());
- assertEquals(avail, AvailabilityType.UP);
+ assertEquals(avail, UP);
// Make sure the server is back up.
// TODO (ips): Check that the server is a different process now.
invokeOperationAndAssertSuccess(getServerResource(), RESTART_OPERATION_NAME, null);
avail = getAvailability(getServerResource());
- assertEquals(avail, AvailabilityType.UP);
+ assertEquals(avail, UP);
}
- @Test(priority = 6, enabled = true)
+ @Test(priority = 7, enabled = true)
public void testSystemPropertiesSettings() throws Exception {
Configuration config = loadResourceConfiguration(getServerResource());
@@ -152,6 +153,11 @@ public class StandaloneServerComponentTest extends AbstractServerComponentTest {
}
+ @Test(priority = 8)
+ public void testStandaloneServerAsynchronousAvailabilityCheck() throws Exception {
+ testAsynchronousAvailabilityCheck(getServerResource());
+ }
+
protected String getExpectedStartScriptFileName() {
return (File.separatorChar == '/') ? "standalone.sh" : "standalone.bat";
}
commit 7c02c5d0cf53dbd9829eeba1edea57735b3d1b80
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri May 24 16:43:50 2013 +0200
[BZ 965833 - Potential bug in join/fetch/avoidance code]
It is now possible to lazily fetch fields defined in super classes.
The avoidance of the join-fetch with limits exposed a missing feature that
was present in the code from the day one. It would be failing if the
criteria query was used to fetch a custom object (i.e. not the primary
persistent class of the criteria object) using an "altered projection" and
a fetch would be set on a field defined in a super class of the persistent
class of the criteria object. Only by chance this has never happened
before, because we don't use the altered projections on the criteria
queries that often.
Now that we lazily fetch fields much more often (to avoid join fetch
with limits) this is a problem even in cases without an altered projection.
The fix is fortunately very simple - we need to also search the
superclasses of the criteria's persistent class when looking for a field
to lazily fetch.
The possibility of fields being present in super-classes was taken into
account on other places in the CriteriaQueryGenerator class, too.
Documentation on the getJoinFetchFields() and alterProjection() was
enhanced to hopefully better explain the conditions underwhich you can
combine fetching and altered projection together.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
index 6ed7074..574fe73 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
@@ -343,7 +343,7 @@ public final class CriteriaQueryGenerator {
} else {
if (this.projection == null) {
/*
- * if not altering the projection, join fetching can be using
+ * if not altering the projection, join fetching can be used
* to retrieve the associated instance in the same SELECT
*
* We further avoid a JOIN FETCH when executing queries with limits.
@@ -664,14 +664,9 @@ public final class CriteriaQueryGenerator {
}
private boolean isPersistentBag(String fieldName) {
- try {
- Class<?> persistentClass = criteria.getPersistentClass();
- Field field = persistentClass.getDeclaredField(fieldName);
+ Field field = findField(fieldName);
- return isAList(field) && !field.isAnnotationPresent(IndexColumn.class);
- } catch (NoSuchFieldException e) {
- return false;
- }
+ return field != null && isAList(field) && !field.isAnnotationPresent(IndexColumn.class);
}
private boolean isAList(Field field) {
@@ -690,23 +685,40 @@ public final class CriteriaQueryGenerator {
}
private void addPersistentBag(String fieldName) {
- try {
- Field field = criteria.getPersistentClass().getDeclaredField(fieldName);
- persistentBagFields.add(field);
- } catch (NoSuchFieldException e) {
- LOG.warn("Failed to add persistent bag collection on class [" + criteria.getPersistentClass().getName() +"]: ", e);
+ Field f = findField(fieldName);
+ if (f == null) {
+ LOG.warn(
+ "Failed to add persistent bag collection [" + fieldName + "] on class [" + criteria.getPersistentClass().getName() +
+ "]. There doesn't seem to be a field of that name on the class or any of its superclasses.");
+ } else {
+ persistentBagFields.add(f);
}
}
private void addJoinFetch(String fieldName) {
- try {
- Field field = criteria.getPersistentClass().getDeclaredField(fieldName);
- joinFetchFields.add(field);
- } catch (NoSuchFieldException e) {
- LOG.warn("Failed to add join fetch field on class [" + criteria.getPersistentClass().getName() + "]: ", e);
+ Field f = findField(fieldName);
+ if (f == null) {
+ LOG.warn(
+ "Failed to add join fetch field [" + fieldName + "] on class [" + criteria.getPersistentClass().getName() +
+ "]. There doesn't seem to be a field of that name on the class or any of its superclasses.");
+ } else {
+ joinFetchFields.add(f);
}
}
+ private Field findField(String fieldName) {
+ Class<?> cls = criteria.getPersistentClass();
+ while (cls != null) {
+ try {
+ return cls.getDeclaredField(fieldName);
+ } catch (NoSuchFieldException e) {
+ cls = cls.getSuperclass();
+ }
+ }
+
+ return null;
+ }
+
/**
* <strong>Note:</strong> This method should only be called after {@link #getQueryString(boolean)}} because it is
* that method where the persistentBagFields property is initialized.
@@ -718,6 +730,21 @@ public final class CriteriaQueryGenerator {
return persistentBagFields;
}
+ /**
+ * <strong>Note:</strong> This method should only be called after {@link #getQueryString(boolean)}} because it is
+ * that method where the persistentBagFields property is initialized.
+ * <p/>
+ * The elements of the returned list are a (sub)set of the fields that the criteria object specified to be fetched
+ * (using the fetchXXX() methods). If the {@link CriteriaQueryRunner} is not set to automatically fetch all the
+ * fields, you need to manually initialize these fields by for example using
+ * {@link CriteriaQueryRunner#initFetchFields(Object)} method on each of the results.
+ *
+ * @see #alterProjection(String) <code>alterProjection(String)</code> for special attention you need to make when
+ * mixing fetching fields and altered projection.
+ *
+ * @return Returns a list of fields from the persistent class to which the criteria class corresponds. The fields in
+ * the list are fields specified by the criteria to be fetched (using the fetchXXX() methods).
+ */
public List<Field> getJoinFetchFields() {
return joinFetchFields;
}
@@ -728,8 +755,11 @@ public final class CriteriaQueryGenerator {
* only affect the ResultSet for the data query, not the count query.
* <p/>
* If you are projecting a composite object that does not directly extend the entity your Criteria object
- * represents, then you will need to manually initialize the persistent bags using the methods exposed on
- * {@link CriteriaQueryRunner}
+ * represents, then you will need to manually initialize the persistent bags and fetch fields using the
+ * {@link CriteriaQueryRunner#initFetchFields(Object)} method for each object in the results (for which you need
+ * to instantiate the {@link CriteriaQueryRunner} with automatic fetching switched OFF). <b>Note</b> that this will
+ * NOT work on the composite object itself. You need to pass an instance of the entity class to the
+ *{@link CriteriaQueryRunner#initFetchFields(Object)} method.
*/
public void alterProjection(String projection) {
this.projection = projection;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryRunner.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryRunner.java
index a788fb0..73292be 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryRunner.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryRunner.java
@@ -129,9 +129,7 @@ public class CriteriaQueryRunner<T> {
public void initFetchFields(Object entity) {
initPersistentBags(entity);
- if (queryGenerator.isProjectionAltered()) {
- initJoinFetchFields(entity);
- }
+ initJoinFetchFields(entity);
}
private void initPersistentBags(Object entity) {
commit fac3ef60a530ed847beb42ad47dc73969db2bc2f
Author: Libor Zoubek <lzoubek(a)jezzovo.net>
Date: Fri May 24 16:45:08 2013 +0200
rhq-Bot: only devs can send private echo command to bot
diff --git a/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java
index 1960f1d..a7b3e78 100644
--- a/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java
+++ b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java
@@ -209,8 +209,12 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
String message = privateMessageEvent.getMessage();
Matcher echoMatcher = ECHO_PATTERN.matcher(message);
if (echoMatcher.matches()) {
- String echoMessage = echoMatcher.group(1);
- bot.sendMessage(this.channel, echoMessage);
+ if (!JON_DEVS.contains(privateMessageEvent.getUser().getNick())) {
+ privateMessageEvent.respond("You're not my master, I am your master, go away");
+ } else {
+ String echoMessage = echoMatcher.group(1);
+ bot.sendMessage(this.channel, echoMessage);
+ }
} else if (message.equalsIgnoreCase(Command.PREFIX + "listrenames")) {
//Generate a list of renames in the form of old1 changed to new1, old2 changed to new2, etc
StringBuilder users = new StringBuilder();
commit 72f1a6865bc6807f8da21cd9b5299c5fc77f9d17
Author: Libor Zoubek <lzoubek(a)jezzovo.net>
Date: Fri May 24 16:40:57 2013 +0200
ircBot: improved recognition of commands
Bot now recognizes commands only when in the beginning of message or if you
highlight bot's nick and command is the very first word (like rhq-bot:
!help)
diff --git a/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java
index cd6d43a..1960f1d 100644
--- a/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java
+++ b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java
@@ -61,7 +61,7 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
SUPPORT,
WIKI("Our wiki is available from https://docs.jboss.org/author/display/RHQ/Home", true);
- public static final char PREFIX = '!';
+ public static final String PREFIX = "!";
private final String staticRespond;
private final boolean includeInHelp;
@@ -106,7 +106,7 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
this.channel = channel;
isRedHatChannel = "irc.devel.redhat.com".equals(channel);
StringBuilder commandRegExp = new StringBuilder();
- commandRegExp.append("(?i)\\").append(Command.PREFIX).append("[ ]*(");
+ commandRegExp.append("^(?i)[ ]*").append(Command.PREFIX).append("(");
for (Command command : Command.values()) {
commandRegExp.append(command.name()).append('|');
}
@@ -173,6 +173,11 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
bot.sendMessage(event.getChannel(), event.getUser().getNick() + ": " + response);
}
+ if (message.startsWith(event.getBot().getNick())) {
+ // someone asked bot directly, we have to remove that from message
+ message = message.substring(event.getBot().getNick().length());
+ message = message.replaceFirst("[^ ]*", "");
+ }
// react to commands included in the messages
Matcher commandMatcher = commandPattern.matcher(message);
while (commandMatcher.find()) {
commit 4d8f18d7f266c520094c2e0b855f2f6ec53864ae
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Fri May 24 11:14:44 2013 +0200
Add some translations
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties
index 829ffcc..f02eace 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties
@@ -10,25 +10,25 @@
#
###################################
##avail_chart_down_label = DOWN
-##avail_chart_title_label = Availability
+avail_chart_title_label = Verfügbarkeit
##avail_chart_up_label = UP
-##chart_date_label = Date
+chart_date_label = Datum
##chart_down_label = Down
##chart_time_label = Start
-##chart_unknown_label = Unknown
-##chart_no_data_label = No Data
-##chart_title_avg_label = Avg
-##chart_title_min_label = Min
-##chart_title_peak_label = Max
-##chart_hover_availability_label = Availability
-##chart_hover_availability_type_warn = MIXED
-##chart_hover_date_format = %m/%d/%y
+chart_unknown_label = Unbekannt
+chart_no_data_label = Keine Daten vorhanden
+chart_title_avg_label = Durchschn.
+chart_title_min_label = Min
+chart_title_peak_label = Max
+chart_hover_availability_label = Verfügbarkeit
+chart_hover_availability_type_warn = Gemischt
+chart_hover_date_format = %d.%m.%y
##chart_hover_time_format = %I:%M:%S %p
-##chart_ie_not_supported = Charting is not available for this browser.
-##chart_hover_start_label = Start
-##chart_hover_end_label = End
+chart_ie_not_supported = Charting ist bei diesem Browser nicht unterstützt
+chart_hover_start_label = Start
+chart_hover_end_label = Ende
##chart_hover_period_label = Period
-##chart_hover_bar_label = Duration
+chart_hover_bar_label = Dauer
common_alert_high = HOCH
common_alert_low = NIEDRIG
common_alert_medium = MITTEL
@@ -68,7 +68,7 @@ common_button_schedule = Planen
common_button_search = Suchen
common_button_set = Setzen
common_button_showDetails = Details anzeigen...
-##common_button_unignore = Unignore
+common_button_unignore = Ignorieren aufheben
common_button_uninventory = Aus dem Inventar löschen
common_calendar_april_short = Apr
common_calendar_august_short = Aug
@@ -91,7 +91,7 @@ common_label_filters = Filter
common_label_hour = Stunde
common_label_item = Eintrag
common_label_items = Einträge
-##common_label_link = Link
+common_label_link = Link
common_label_month = Monat
common_label_none = keine
common_label_none2 = keines
@@ -128,7 +128,7 @@ common_status_nochange = Keine Änderung
common_status_partial = partiell
common_status_success = Erfolg
common_status_unknown = Unbekannt
-##common_title_acknowledged = Acknowledged
+common_title_acknowledged = Bestätigt
common_title_add_column = Spalte hinzufügen
common_title_add_portlet = Portlet hinzufügen
common_title_address = Adresse
@@ -418,7 +418,7 @@ favorites_recentlyViewed = Kürzlich angesehen
favorites_resources = Gemerkte Ressourcen
filter_from_date = Von
filter_to_date = Bis
-##group_tree_groupOfResourceType = Group of [{0}]
+group_tree_groupOfResourceType = Gruppe von [{0}]
group_tree_partialClusterTooltip = {0} der {1} Gruppenmitglieder haben eine ''{2}'' Ressource
util_disambiguationReportDecorator_pluginSuffix = ({0} Plugin)
util_errorHandler_nullException = Exception war null
@@ -441,8 +441,8 @@ view_adminConfig_agentPlugins = Agent Plugins
view_adminConfig_alertDefTemplates = Vorlagen für Alarmdefinitionen
view_adminConfig_downloads = Downloads
view_adminConfig_driftDefTemplates = Vorlagen für Dritf-Definitionen
-##view_adminConfig_ignoreResourceTypes = Ignored Resource Types
-##view_adminConfig_ignoreResourceTypes_changeTitle = Change?
+view_adminConfig_ignoreResourceTypes = Ignorierte Ressource Typen
+view_adminConfig_ignoreResourceTypes_changeTitle = Ändern?
##view_adminConfig_ignoreResourceTypes_confirmIgnore = Are you sure you want to ignore the resource type [{0}]? You will no longer be able to import resources of this type and any resources of this type that are already in inventory will be uninventoried and you can no longer manage them.
##view_adminConfig_ignoreResourceTypes_confirmUnignore = Are you sure you want to unignore the resource type [{0}]? Any resources of this type that exist in your managed environment will be able to be discovered and inventoried.
##view_adminConfig_ignoreResourceTypes_failure = Failed to set the ignore flag on the selected resource type.
@@ -456,7 +456,7 @@ view_adminConfig_systemSettings = Systemeinstellungen
view_adminContent_contentSources = Quellen für Inhalte
view_adminRoles_assignedGroups = Zugewiesene Ressourcen-Gruppen
view_adminRoles_assignedSubjects = Zugewisene Benutzer
-##view_adminRoles_failCreateRoleWithExistingName = Failed to create role with existing name [{0}]. Please use another name.
+view_adminRoles_failCreateRoleWithExistingName = Konnte die Rolle mit dem existierenden Namen [{0}] nicht anlegen. Bitte wählen Sie einen anderen Namen.
view_adminRoles_failLdap = Konnte nicht ermitteln, ob LDAP konfiguriert ist - gehe von keiner LDAP-Konfiguration aus.
view_adminRoles_failLdapGroups = Konnte de LDAP-Gruppen nicht laden. Annahme ist, dass es keine gibt.
view_adminRoles_failLdapGroupsRole = Konnte die LDAP-Gruppen für die Rolle nicht laden.
@@ -526,23 +526,23 @@ view_adminTemplates_pluginTemplates = Vorlagen für Plugins Plugins
view_adminTemplates_servers = Server
view_adminTemplates_userTemplates = Nutzers-spezifische Vorlagen
view_adminTopology_affinityGroups = Affinitätsgruppen
-##view_adminTopology_affinityGroups_agentCount = Agent Count
-##view_adminTopology_affinityGroups_agentsInThisGroup = Agents in This Group
+view_adminTopology_affinityGroups_agentCount = Anzahl Agenten
+view_adminTopology_affinityGroups_agentsInThisGroup = Agenten in dieser Gruppe
##view_adminTopology_affinityGroups_agentsNotPartOfAnAffinityGroup = Agents not Part of an Affinity Group
##view_adminTopology_affinityGroups_agetnMembers = Agent Members
-##view_adminTopology_affinityGroups_createNew = Create New
+view_adminTopology_affinityGroups_createNew = Neu anlegen
##view_adminTopology_affinityGroups_details = Affinity Group Details
-##view_adminTopology_affinityGroups_removeSelected = Remove Selected
-##view_adminTopology_affinityGroups_serverCount = Server Count
+view_adminTopology_affinityGroups_removeSelected = Ausgewählte entfernen
+view_adminTopology_affinityGroups_serverCount = Anzahl Server
##view_adminTopology_affinityGroups_serverMembers = Server Members
-##view_adminTopology_agentDetail_address = Address
+view_adminTopology_agentDetail_address = Adresse
##view_adminTopology_agentDetail_agentFailoverList = Agent Failover List
-##view_adminTopology_agentDetail_currentServer = Current Server
+view_adminTopology_agentDetail_currentServer = Aktueller Server
##view_adminTopology_agentDetail_token = Token
##view_adminTopology_agent_agentBindAddress = Agent Bind Address
##view_adminTopology_agent_agentBindPort = Agent Bind Port
-##view_adminTopology_agent_agentName = Agent Name
-##view_adminTopology_agent_connectedServer = Connected Server
+view_adminTopology_agent_agentName = Name des Agenten
+view_adminTopology_agent_connectedServer = Verbundener Server
##view_adminTopology_agent_delete_confirm = This will deregister the selected agents and uninventory their corresponding platforms and all other resources associated with them. There is no way to undo this action. Are you sure you want to do this?
##view_adminTopology_agent_lastAvailabilityPing = Last Availability Ping
##view_adminTopology_agent_lastAvailabilityReport = Last Availability Report
@@ -592,7 +592,7 @@ view_adminTopology_partitionEvents = Partitionierungs-Ereignisse
##view_adminTopology_partitionEventsDetail_eventDetails = Event Details
##view_adminTopology_partitionEventsDetail_eventExecutionTime = Event Execution Time
##view_adminTopology_partitionEventsDetail_eventType = Event Type
-##view_adminTopology_partitionEvents_details = Details
+view_adminTopology_partitionEvents_details = Details
##view_adminTopology_partitionEvents_detailsFilter = Details Filter
##view_adminTopology_partitionEvents_execStatusFilter = Execution Status Filter
##view_adminTopology_partitionEvents_execTime = Execution Time
@@ -600,7 +600,7 @@ view_adminTopology_partitionEvents = Partitionierungs-Ereignisse
##view_adminTopology_partitionEvents_forceRepartition = Force Repartition
##view_adminTopology_partitionEvents_initiatedBy = Initiated By
##view_adminTopology_partitionEvents_purgeAll = Purge All
-##view_adminTopology_partitionEvents_type = Type
+view_adminTopology_partitionEvents_type = Typ
##view_adminTopology_partitionEvents_typeFilter = Type Filter
view_adminTopology_remoteAgentInstall = Installation entfernter Agenten
##view_adminTopology_serverDetail_connectedAgents = Connected Agents
@@ -610,7 +610,7 @@ view_adminTopology_remoteAgentInstall = Installation entfernter Agenten
##view_adminTopology_server_agentCount = Agent Count
##view_adminTopology_server_endpointAddress = Endpoint Address
##view_adminTopology_server_lastUpdateTime = Last Update Time
-##view_adminTopology_server_mode = Mode
+view_adminTopology_server_mode = Modus
##view_adminTopology_server_nonSecurePort = Nonsecure Port
##view_adminTopology_server_removeSelected = Remove Selected
##view_adminTopology_server_securePort = Secure Port
@@ -726,15 +726,16 @@ view_admin_systemSettings_serverDetails_dbName = Produktname der Datenbank
view_admin_systemSettings_serverDetails_dbUrl = URL der Datenbankverbindung
view_admin_systemSettings_serverDetails_dbVersion = Produktversion der Datenbank
view_admin_systemSettings_serverDetails_installDir = Installationsverzeichnis des Servers
-##view_admin_systemSettings_serverDetails_productName = Product Name
-##view_admin_systemSettings_serverDetails_serverName = Server Name
+view_admin_systemSettings_serverDetails_nextRotation = Nächste Rotation der Metrik-Tabellen
+view_admin_systemSettings_serverDetails_productName = Produktname
+view_admin_systemSettings_serverDetails_serverName = Servername
view_admin_systemSettings_serverDetails_time = Lokale Zeit des Servers
view_admin_systemSettings_serverDetails_tz = Zeitzone des Servers
view_admin_topology = Topologie
view_alert_common_tab_conditions = Bedingungen
view_alert_common_tab_conditions_expression = Alarm auslösen wenn
##view_alert_common_tab_conditions_expression_tooltip = Determines if ANY or ALL of the conditions must evaluate to true in order for the entire condition set to be considered true.
-##view_alert_common_tab_conditions_modalEdit_title = Edit Condition
+view_alert_common_tab_conditions_modalEdit_title = Bedingungen ändern
view_alert_common_tab_conditions_modal_title = Bedingung hinzufügen
view_alert_common_tab_conditions_recovery_disabled = Dieser Alarm hat seine Definition deaktiviert.
view_alert_common_tab_conditions_recovery_enabled = Ausgelöst, dass ''{0}'' wieder aktiviert wurde
@@ -881,7 +882,7 @@ view_alert_definition_condition_editor_option_metric_trait_change = Änderung de
view_alert_definition_condition_editor_option_operation = Ausführung der Operation
view_alert_definition_condition_editor_option_resource_configuration = Änderung der Konfiguration der Ressource
##view_alert_definition_condition_editor_resource_configuration_tooltip = This condition is triggered when the resource configuration changes.
-##view_alert_definition_editCondition = Edit Condition
+view_alert_definition_editCondition = Bedingungen ändern
view_alert_definition_for_group = Gruppendefinition ansehen
view_alert_definition_for_type = Vorlage ansehen
view_alert_definition_notification_cliScript_editor_anotherUser = Anderer Benutzer
@@ -890,7 +891,7 @@ view_alert_definition_notification_cliScript_editor_script = Skript
view_alert_definition_notification_cliScript_editor_thisUser = Aktueller Benutzer
view_alert_definition_notification_editor_delete_confirm = Sind Sie sicher, dass sie die ausgewählten Alarm-Benachrichtigungen löschen wollen?
view_alert_definition_notification_editor_field_configuration = Konfiguration
-##view_alert_definition_notification_editor_field_configuration_loadFailed = Failed to get notification configuration preview
+view_alert_definition_notification_editor_field_configuration_loadFailed = Konte die Vorschau der Benachrichtigung nicht laden
view_alert_definition_notification_editor_field_configuration_not_loaded = Unbekannt
view_alert_definition_notification_editor_field_sender = Sender
view_alert_definition_notification_editor_loadFailed = Kann die Alarm-Sender nicht laden
@@ -944,7 +945,7 @@ view_alert_definitions_disable_success = Es wurden {0} Alarm-Definitionen erfolg
view_alert_definitions_enable_confirm = Die ausgewählten Alarm-Definitionen aktivieren?
view_alert_definitions_enable_failure = Konnte die ausgewählten Alarm-Definitionen nicht aktivieren
view_alert_definitions_enable_success = Es wurden {0} Alarm-Definitionen erfolgreich aktiviert
-##view_alert_definitions_leaveUnsaved = Do you want to save the modified alert definition?
+view_alert_definitions_leaveUnsaved = Möchten Sie die geänderte Alarm-Definition speichern?
view_alert_definitions_loadFailed = Konnte die Daten für die Alarm-Definitionen nicht laden
view_alert_definitions_loadFailed_single = Konnte die Daten für die Alarm-Definition mit der id {0}
view_alert_definitions_table_title_group = Alarm-Definitionen für Gruppen
@@ -1182,7 +1183,7 @@ view_bundle_version_backToBundle = Zurück zum Bundle
##view_bundle_version_deleteSuccessful = You successfully deleted the bundle version [{0}]
##view_bundle_version_loadFailure = Failed to load bundle version
view_bundle_versions = Versionen
-##view_charts_time_axis_label = Time
+view_charts_time_axis_label = Zeit
view_configCompare_comparingConfigs = Konfigurationen vergleichen
##view_configCompare_configCompare = Configuration Comparison
view_configEdit_addItem = Eintrag zur Liste hinzufügen
@@ -1481,13 +1482,13 @@ view_inventory_groups_children = Kinder
##view_inventory_groups_deleteSuccessful = You have successfully deleted the selected resource groups
##view_inventory_groups_descendants = Descendants
##view_inventory_groups_loadFailed = Failed to load group composite data
-##view_inventory_ignoredResources = Ignored Resources
+view_inventory_ignoredResources = Ignorierte Ressourcen
view_inventory_mixed = gemischt
view_inventory_platforms = Platformen
view_inventory_problemGroups = Gruppen mit Problemen
##view_inventory_resource_loadFailed = Resource with id [{0}] does not exist or is not accessible
-##view_inventory_resources_deleteConfirm = Are you sure you want to delete the selected resources?
-##view_inventory_resources_deleteFailed = Failed to delete the selected resources
+view_inventory_resources_deleteConfirm = Sind Sie sicher, dass Sie die ausgewählten Ressourcen löschen wollen?
+view_inventory_resources_deleteFailed = Löschen der ausgewählten Ressourcen ist fehlgeschlagen
##view_inventory_resources_deleteSuccessful = A request to perform the resource deletion has been submitted successfully to the agent(s).
##view_inventory_resources_disableSuccessful = You have successfully disabled the selected resources and their children, [{0}] resources.
##view_inventory_resources_ignoreConfirm = Are you sure you want the selected resources to be ignored? They will no longer show up in inventory.
commit 465b01615c5654ab4e6481f5c977c0c6af4cd05a
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu May 23 22:38:18 2013 +0200
Bit of cleanup and testing of alert->ack and alert->purge
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java
index 92d2499..224ab3f 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java
@@ -25,12 +25,9 @@ package org.rhq.enterprise.server.rest;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URI;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -251,89 +248,8 @@ public class AbstractRestBean {
return result;
}
- protected void putResourceToCache(Resource res) {
- putToCache(res.getId(), Resource.class, res);
- CacheKey callerKey = new CacheKey("rhq.rest.caller", caller.getId());
- try {
- Set<Integer> visibleResources = (Set<Integer>) cache.get(callerKey);
-
- if (null == visibleResources) {
- visibleResources = new HashSet<Integer>();
- }
-
- visibleResources.add(res.getId());
- cache.put(callerKey, visibleResources);
-
- Map<Integer, Integer> childParentMap = (Map<Integer, Integer>) cache.get(META_KEY);
-
- if (null == childParentMap) {
- childParentMap = new HashMap<Integer, Integer>();
- }
- int pid = res.getParentResource() == null ? 0 : res.getParentResource().getId();
- childParentMap.put(res.getId(), pid);
- cache.put(META_KEY, childParentMap);
-
- } catch (Exception e) {
- log.warn(e.getMessage());
- }
- }
-
- protected List<Resource> getResourcesFromCacheByParentId(int pid) {
- List<Integer> candidateIds = new ArrayList<Integer>();
- List<Resource> ret = new ArrayList<Resource>();
-
- // First determine candidate children
- Map<Integer, Integer> childParentMap = (Map<Integer, Integer>) cache.get(META_KEY);
-
- if (null != childParentMap) {
- try {
- for (Map.Entry<Integer, Integer> entry : childParentMap.entrySet()) {
- if (entry.getValue() == pid)
- candidateIds.add(entry.getKey());
- }
- // then see if the current user can see them
- CacheKey callerKey = new CacheKey("rhq.rest.caller", caller.getId());
- Set<Integer> visibleResources = (Set<Integer>) cache.get(callerKey);
- Iterator<Integer> iter = candidateIds.iterator();
- while (iter.hasNext()) {
- Integer resId = iter.next();
- if (!visibleResources.contains(resId)) {
- iter.remove();
- }
- }
-
- // Last but not least, get the resources and return them
- for (Integer resId : candidateIds) {
- ret.add(getFromCache(resId, Resource.class));
- }
- } catch (Exception e) {
- log.warn(e.getMessage());
- }
-
- }
- return ret;
- }
-
- protected Resource getResourceFromCache(int resourceid) {
-
- Resource res = null;
- // check if the current user can see the resource
- CacheKey callerKey = new CacheKey("rhq.rest.caller", caller.getId());
- Set<Integer> visibleResources = (Set<Integer>) cache.get(callerKey);
- if (null != visibleResources) {
- try {
- if (visibleResources.contains(resourceid)) {
- res = getFromCache(resourceid, Resource.class);
- }
- } catch (Exception e) {
- log.warn(e.getMessage());
- }
- }
-
- return res;
- }
/**
* Remove an item from the cache
@@ -393,6 +309,7 @@ public class AbstractRestBean {
uriBuilder.path("/resource/{id}/children");
uri = uriBuilder.build(res.getId());
link = new Link("children", uri.toString());
+ rwt.addLink(link);
uriBuilder = uriInfo.getBaseUriBuilder();
uriBuilder.path("/resource/{id}/alerts");
uri = uriBuilder.build(res.getId());
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AlertTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AlertTest.java
index acbb492..355adcd 100644
--- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AlertTest.java
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AlertTest.java
@@ -1434,6 +1434,8 @@ public class AlertTest extends AbstractBase {
int definitionId = createEmptyAlertDefinition(true);
+ int alertId;
+
// Now add a condition
try {
@@ -1481,7 +1483,7 @@ public class AlertTest extends AbstractBase {
// wait a little
Thread.sleep(5000);
- int alertId =
+ alertId =
given()
.header(acceptJson)
.queryParam("definitionId",definitionId)
@@ -1543,9 +1545,32 @@ public class AlertTest extends AbstractBase {
.when()
.get("/resource/{resourceId}/alerts");
+ if (alertId>0) {
+ // Acknowledge the alert
+ given()
+ .header(acceptWrappedJson)
+ .pathParam("id", alertId)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .put("/alert/{id}");
+
+ Thread.sleep(500);
+
+ // purge the alert
+ given()
+ .header(acceptJson)
+ .pathParam("id", alertId)
+ .expect()
+ .statusCode(204)
+ .log().ifError()
+ .when()
+ .delete("/alert/{id}");
+ }
}
-
finally {
+
// delete the definition again
cleanupDefinition(definitionId);
}
commit d6d8dd1c10aaf17a6fcc9fd17898ce4111cc8c9c
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Thu May 23 22:21:32 2013 +0200
rhq irc bot: disabling the !pto and !support commands on Freenode channel
diff --git a/etc/rhq-ircBot/pom.xml b/etc/rhq-ircBot/pom.xml
index 6e66187..a6ab873 100644
--- a/etc/rhq-ircBot/pom.xml
+++ b/etc/rhq-ircBot/pom.xml
@@ -8,7 +8,7 @@
<groupId>org.rhq.etc</groupId>
<artifactId>rhq-ircbot</artifactId>
- <version>1.0</version>
+ <version>1.1</version>
<packaging>jar</packaging>
<name>RHQ IRC Bot</name>
diff --git a/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java
index 8a7e578..cd6d43a 100644
--- a/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java
+++ b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java
@@ -93,6 +93,7 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
private final String server;
private final String channel;
+ private final boolean isRedHatChannel;
private String docspaceLogin;
private String docspacePassword;
private BugzillaConnector bzConnector = new BugzillaConnector();
@@ -103,6 +104,7 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
public RhqIrcBotListener(String server, String channel) {
this.server = server;
this.channel = channel;
+ isRedHatChannel = "irc.devel.redhat.com".equals(channel);
StringBuilder commandRegExp = new StringBuilder();
commandRegExp.append("(?i)\\").append(Command.PREFIX).append("[ ]*(");
for (Command command : Command.values()) {
@@ -176,7 +178,9 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
while (commandMatcher.find()) {
Command command = Command.valueOf(commandMatcher.group(1).toUpperCase());
String response = prepareResponseForCommand(command);
- bot.sendMessage(event.getChannel(), event.getUser().getNick() + ": " + response);
+ if (response != null) {
+ bot.sendMessage(event.getChannel(), event.getUser().getNick() + ": " + response);
+ }
}
// ping JON devs
@@ -215,9 +219,12 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
// react to commands included in the messages
Matcher commandMatcher = commandPattern.matcher(message);
while (commandMatcher.find()) {
+ isCommand = true;
Command command = Command.valueOf(commandMatcher.group(1).toUpperCase());
String response = prepareResponseForCommand(command);
- bot.sendMessage(privateMessageEvent.getUser(), response);
+ if (response != null) {
+ bot.sendMessage(privateMessageEvent.getUser(), response);
+ }
}
if (!isCommand) {
bot.sendMessage(privateMessageEvent.getUser(), "Hi, I am " + bot.getFinger() + ".\n"
@@ -271,8 +278,10 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
}
switch (command) {
case SUPPORT:
+ if (isRedHatChannel)
return whoIsOnSupport(SUPPORT_LINK);
case PTO:
+ if (isRedHatChannel)
return whoIsOnPto(PTO_LINK);
default:
System.err.println("Unknown command:" + command);
commit 09e5eb1428516134cf8b96cd166817c15d8cafa8
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu May 23 15:04:09 2013 -0400
BZ 962841 962845 fix the resource type admin pages to support types with multiple parents (i.e. types with <runs-inside>)
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/AlertDefinitionTemplateTypeView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/AlertDefinitionTemplateTypeView.java
index 9b4027e..4f790a1 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/AlertDefinitionTemplateTypeView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/AlertDefinitionTemplateTypeView.java
@@ -197,14 +197,19 @@ public class AlertDefinitionTemplateTypeView extends ResourceTypeTreeView {
}
public static class TreeNode extends ResourceTypeTreeNode {
-
public TreeNode(ResourceTypeTemplateCountComposite composite, String plugin) {
-
super(composite, plugin);
-
setAttribute(ATTR_ENABLED_TEMPLATES, composite.getEnabledAlertCount());
setAttribute(ATTR_DISABLED_TEMPLATES, composite.getDisabledAlertCount());
}
+
+ @Override
+ public ResourceTypeTreeNode copy() {
+ ResourceTypeTreeNode dup = super.copy();
+ dup.setAttribute(ATTR_ENABLED_TEMPLATES, this.getAttributeAsLong(ATTR_ENABLED_TEMPLATES));
+ dup.setAttribute(ATTR_DISABLED_TEMPLATES, this.getAttributeAsLong(ATTR_DISABLED_TEMPLATES));
+ return dup;
+ }
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/DriftDefinitionTemplateTypeView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/DriftDefinitionTemplateTypeView.java
index 143c475..ebb2d9d 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/DriftDefinitionTemplateTypeView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/DriftDefinitionTemplateTypeView.java
@@ -211,11 +211,8 @@ public class DriftDefinitionTemplateTypeView extends ResourceTypeTreeView {
}
public static class TreeNode extends ResourceTypeTreeNode {
-
public TreeNode(ResourceTypeTemplateCountComposite composite, String plugin) {
-
super(composite, plugin);
-
setAttribute(ATTR_PLUGIN_TEMPLATES, composite.getPluginDriftTemplates());
setAttribute(ATTR_USER_TEMPLATES, composite.getUserDriftTemplates());
// If the type has no plugin templates then drift monitoring is not enabled for the type
@@ -223,6 +220,14 @@ public class DriftDefinitionTemplateTypeView extends ResourceTypeTreeView {
setAttribute(ATTRIB_EDIT, ImageManager.getEditDisabledIcon());
}
}
+
+ @Override
+ public ResourceTypeTreeNode copy() {
+ ResourceTypeTreeNode dup = super.copy();
+ dup.setAttribute(ATTR_PLUGIN_TEMPLATES, this.getAttributeAsLong(ATTR_PLUGIN_TEMPLATES));
+ dup.setAttribute(ATTR_USER_TEMPLATES, this.getAttributeAsLong(ATTR_USER_TEMPLATES));
+ return dup;
+ }
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/IgnoreResourceTypesView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/IgnoreResourceTypesView.java
index 246a71e..91a4ca2 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/IgnoreResourceTypesView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/IgnoreResourceTypesView.java
@@ -182,6 +182,13 @@ public class IgnoreResourceTypesView extends ResourceTypeTreeView {
super(composite, plugin);
setAttribute(ATTR_ENABLED, ImageManager.getAvailabilityIcon(!composite.getType().isIgnored()));
}
+
+ @Override
+ public ResourceTypeTreeNode copy() {
+ ResourceTypeTreeNode dup = super.copy();
+ dup.setAttribute(ATTR_ENABLED, this.getAttribute(ATTR_ENABLED));
+ return dup;
+ }
}
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/MetricTemplateTypeView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/MetricTemplateTypeView.java
index 19c53d2..e4aa4fe 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/MetricTemplateTypeView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/MetricTemplateTypeView.java
@@ -170,11 +170,8 @@ public class MetricTemplateTypeView extends ResourceTypeTreeView {
}
public static class TreeNode extends ResourceTypeTreeNode {
-
public TreeNode(ResourceTypeTemplateCountComposite composite, String plugin) {
-
super(composite, plugin);
-
setAttribute(ATTR_ENABLED_TEMPLATES, composite.getEnabledMetricCount());
setAttribute(ATTR_DISABLED_TEMPLATES, composite.getDisabledMetricCount());
// If the type has no metrics then metric templates are enabled for the type
@@ -182,6 +179,14 @@ public class MetricTemplateTypeView extends ResourceTypeTreeView {
setAttribute(ATTRIB_EDIT, ImageManager.getEditDisabledIcon());
}
}
+
+ @Override
+ public ResourceTypeTreeNode copy() {
+ ResourceTypeTreeNode dup = super.copy();
+ dup.setAttribute(ATTR_ENABLED_TEMPLATES, this.getAttributeAsLong(ATTR_ENABLED_TEMPLATES));
+ dup.setAttribute(ATTR_DISABLED_TEMPLATES, this.getAttributeAsLong(ATTR_DISABLED_TEMPLATES));
+ return dup;
+ }
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/ResourceTypeTreeNodeBuilder.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/ResourceTypeTreeNodeBuilder.java
index 72563c2..e90f398 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/ResourceTypeTreeNodeBuilder.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/ResourceTypeTreeNodeBuilder.java
@@ -18,11 +18,14 @@
*/
package org.rhq.enterprise.gui.coregui.client.admin.templates;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.types.TreeModelType;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.tree.Tree;
@@ -48,7 +51,7 @@ public abstract class ResourceTypeTreeNodeBuilder {
static private final Messages MSG = CoreGUI.getMessages();
public static final String ATTRIB_ID = "id";
- public static final String ATTRIB_PARENT_ID = "parentId";
+ public static final String ATTRIB_CHILDREN = "children";
public static final String ATTRIB_NAME = "name";
public static final String ATTRIB_PLUGIN = "plugin";
public static final String ATTRIB_CATEGORY = "category";
@@ -67,13 +70,18 @@ public abstract class ResourceTypeTreeNodeBuilder {
@Override
public void onSuccess(Map<Integer, ResourceTypeTemplateCountComposite> result) {
+ // result contains all of our resource types, including the parent hierarchy
HashSet<ResourceTypeListGridRecord> platformsRecords;
HashSet<ResourceTypeListGridRecord> platformServicesRecords;
- HashSet<ResourceTypeTreeNode> treeNodes;
+ HashMap<Integer, ResourceTypeTreeNode> serversNodes; // all server nodes (top level and below)
+ HashSet<Integer> topServers; // those servers that are at the root of the tree
+ HashMap<Integer, ArrayList<Integer>> childrenGraph; // defines the children of all server nodes
platformsRecords = new HashSet<ResourceTypeListGridRecord>();
platformServicesRecords = new HashSet<ResourceTypeListGridRecord>();
- treeNodes = new HashSet<ResourceTypeTreeNode>();
+ serversNodes = new HashMap<Integer, ResourceTypeTreeNode>();
+ topServers = new HashSet<Integer>();
+ childrenGraph = new HashMap<Integer, ArrayList<Integer>>();
for (ResourceTypeTemplateCountComposite composite : result.values()) {
ResourceType type = composite.getType();
@@ -84,7 +92,9 @@ public abstract class ResourceTypeTreeNodeBuilder {
platformsRecords.add(getGridRecordInstance(composite));
} else {
// no parents but not a platform - these are our top-level servers
- treeNodes.add(getTreeNodeInstance(composite, type.getPlugin()));
+ ResourceTypeTreeNode node = getTreeNodeInstance(composite, type.getPlugin());
+ topServers.add(node.getResourceTypeId());
+ serversNodes.put(node.getResourceTypeId(), node);
}
} else {
// has parents; if all the direct parents are top level platforms
@@ -106,22 +116,37 @@ public abstract class ResourceTypeTreeNodeBuilder {
if (isPlatformService) {
platformServicesRecords.add(getGridRecordInstance(composite));
-
} else {
- // in some cases, a top level server is limited to which platforms it can run on.
- // therefore, the parents will not be null/empty (as would be the case if the top level
+ // In some cases, a top level server is limited to which platforms it can run on.
+ // Therefore, the parents will not be null/empty (as would be the case if the top level
// server can run on ALL platforms), but instead it will have the subset of platforms
- // the type is valid on. But its the same type - so we only want to show it once. Therefore,
- // once we see a parent that is a top level platform, we don't add the type again for other
- // top level platforms. That's what gotPlatform boolean tracks.
+ // the type is valid on. But its the same type - so we only want to show it once.
+ // This is what gotPlatform tracks - whether we saw a parent platform or not.
+ //
+ // But we also have the case where a server type can run inside multiple parent server types.
+ // We want to show these under all their parents to make it easier for the user to find them.
boolean gotPlatform = false;
for (ResourceType parentType : type.getParentResourceTypes()) {
- boolean isPlatform = (parentType.getCategory() == ResourceCategory.PLATFORM && isEmpty(parentType
+ boolean isParentAPlatform = (parentType.getCategory() == ResourceCategory.PLATFORM && isEmpty(parentType
.getParentResourceTypes()));
- if (!isPlatform || !gotPlatform) {
- treeNodes.add(getTreeNodeInstance(composite, String.valueOf(parentType.getId())));
+ if (!isParentAPlatform || !gotPlatform) {
+ int parentId = parentType.getId();
+ String parentIdString = String.valueOf(parentId);
+ ResourceTypeTreeNode node = getTreeNodeInstance(composite, parentIdString);
+ serversNodes.put(node.getResourceTypeId(), node);
+ if (isParentAPlatform) {
+ topServers.add(node.getResourceTypeId());
+ } else {
+ // we are a child to other type, add it to the list of children
+ ArrayList<Integer> childList = childrenGraph.get(parentId);
+ if (childList == null) {
+ childList = new ArrayList<Integer>();
+ childrenGraph.put(parentId, childList);
+ }
+ childList.add(node.getResourceTypeId());
+ }
}
- if (isPlatform) {
+ if (isParentAPlatform) {
gotPlatform = true;
}
}
@@ -129,14 +154,50 @@ public abstract class ResourceTypeTreeNodeBuilder {
}
}
+ // now set up our UI components to show the data
+ platformsGrid.setSortField(ATTRIB_NAME);
+ platformServicesGrid.setSortField(ATTRIB_NAME);
+ serversGrid.setSortField(ATTRIB_NAME);
+
platformsGrid.setData(platformsRecords.toArray(new ListGridRecord[platformsRecords.size()]));
platformServicesGrid.setData(platformServicesRecords
.toArray(new ListGridRecord[platformServicesRecords.size()]));
- Tree tree = serversGrid.getTree();
- if (tree != null) {
- TreeNode[] treeNodeArray = treeNodes.toArray(new TreeNode[treeNodes.size()]);
- tree.linkNodes(treeNodeArray);
+ Tree tree = new Tree();
+ tree.setModelType(TreeModelType.CHILDREN);
+ tree.setChildrenProperty(ATTRIB_CHILDREN);
+ TreeNode rootNode = new TreeNode("0");
+ tree.setRoot(rootNode);
+
+ for (Integer topServerId : topServers) {
+ ResourceTypeTreeNode topServerNode = serversNodes.get(topServerId);
+ topServerNode = topServerNode.copy();
+ fillHierarchy(topServerNode, serversNodes, childrenGraph);
+ tree.add(topServerNode, rootNode);
}
+ serversGrid.setData(tree);
+ }
+
+ private void fillHierarchy(ResourceTypeTreeNode node,
+ HashMap<Integer, ResourceTypeTreeNode> serversNodes,
+ HashMap<Integer, ArrayList<Integer>> childrenGraph) {
+
+ if (node.getChildren().length > 0) {
+ return; // we've already populated this node's children before; nothing to do
+ }
+
+ ArrayList<Integer> childrenIds = childrenGraph.get(node.getResourceTypeId());
+ if (childrenIds != null) {
+ for (Integer childrenId : childrenIds) {
+ ResourceTypeTreeNode childNode = serversNodes.get(childrenId);
+ if (childNode != null) { // this should never be null, but this let's us continue if we have a bug
+ childNode = childNode.copy();
+ fillHierarchy(childNode, serversNodes, childrenGraph);
+ node.addChild(childNode);
+ }
+ }
+ }
+
+ return;
}
@Override
@@ -184,25 +245,63 @@ public abstract class ResourceTypeTreeNodeBuilder {
public static class ResourceTypeTreeNode extends TreeNode {
- private String id;
+ private int id;
private String parentId;
+ private TreeNode[] children;
+
+ private ResourceTypeTreeNode() {
+ // for use by copy() method
+ }
protected ResourceTypeTreeNode(ResourceTypeTemplateCountComposite composite, String parentId) {
ResourceType resourceType = composite.getType();
- String id = String.valueOf(resourceType.getId());
- setID(id);
- this.id = id;
-
- setParentID(parentId);
+ this.id = resourceType.getId();
this.parentId = parentId;
setAttribute(ATTRIB_ID, id);
- setAttribute(ATTRIB_PARENT_ID, parentId);
setAttribute(ATTRIB_NAME, resourceType.getName());
setAttribute(ATTRIB_PLUGIN, resourceType.getPlugin());
setAttribute(ATTRIB_CATEGORY, resourceType.getCategory().name());
setAttribute(ATTRIB_EDIT, ImageManager.getEditIcon());
+ setChildren(new TreeNode[0]);
+ }
+
+ public int getResourceTypeId() {
+ return this.id;
+ }
+
+ public TreeNode[] getChildren() {
+ return this.children;
+ }
+
+ @Override
+ public void setChildren(TreeNode[] children) {
+ this.children = children;
+ super.setChildren(children);
+ }
+
+ public void addChild(TreeNode newChild) {
+ TreeNode[] newChildren = new TreeNode[this.children.length + 1];
+ System.arraycopy(this.children, 0, newChildren, 0, this.children.length);
+ newChildren[this.children.length] = newChild;
+ setChildren(newChildren);
+ }
+
+ // clone this object and return it - subclasses should override this to copy their own attributes
+ public ResourceTypeTreeNode copy() {
+ ResourceTypeTreeNode dup = new ResourceTypeTreeNode();
+ dup.id = this.id;
+ dup.parentId = this.parentId;
+ dup.children = this.children;
+
+ dup.setAttribute(ATTRIB_ID, this.getAttributeAsInt(ATTRIB_ID));
+ dup.setAttribute(ATTRIB_NAME, this.getAttribute(ATTRIB_NAME));
+ dup.setAttribute(ATTRIB_PLUGIN, this.getAttribute(ATTRIB_PLUGIN));
+ dup.setAttribute(ATTRIB_CATEGORY, this.getAttribute(ATTRIB_CATEGORY));
+ dup.setAttribute(ATTRIB_EDIT, this.getAttribute(ATTRIB_EDIT));
+
+ return dup;
}
@Override
@@ -216,7 +315,7 @@ public abstract class ResourceTypeTreeNodeBuilder {
ResourceTypeTreeNode that = (ResourceTypeTreeNode) o;
- if (!this.id.equals(that.id)) {
+ if (this.id != that.id) {
return false;
}
if (this.parentId == null) {
@@ -228,7 +327,7 @@ public abstract class ResourceTypeTreeNodeBuilder {
@Override
public int hashCode() {
int result = 31;
- result = result * id.hashCode();
+ result = result * id;
result = result + (parentId != null ? parentId.hashCode() : 0);
return result;
}
commit bfaacc85ad6550e3cc7678d5a430562222aa46d1
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu May 23 20:40:21 2013 +0200
BZ use explicit paging fields, as there is no default. In the specific case, the 'name' field was not unique and thus 'random within the resources with the same name'
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java
index 4ceae82..305d867 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java
@@ -79,6 +79,7 @@ import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.core.domain.util.PageList;
+import org.rhq.core.domain.util.PageOrdering;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.alert.AlertConditionManagerLocal;
import org.rhq.enterprise.server.alert.AlertDefinitionManagerLocal;
@@ -148,11 +149,11 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean {
public Response listAlertDefinitions(
@ApiParam(value = "Page number") @QueryParam("page") Integer page,
@ApiParam(value = "Page size") @DefaultValue("20") @QueryParam("ps") int pageSize,
- @ApiParam(value = "Limit to status, UNUSED AT THE MOMENT ") @QueryParam("status") String status, // TODO
@Context HttpHeaders headers,
@Context UriInfo uriInfo) {
AlertDefinitionCriteria criteria = new AlertDefinitionCriteria();
+ criteria.addSortId(PageOrdering.ASC);
if (page!=null) {
criteria.setPaging(page,pageSize);
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/EventHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/EventHandlerBean.java
index fd8a835..4f4d6b4 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/EventHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/EventHandlerBean.java
@@ -62,6 +62,7 @@ import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
+import org.rhq.core.domain.util.PageOrdering;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.event.EventManagerLocal;
import org.rhq.enterprise.server.rest.domain.EventDefinitionRest;
@@ -243,6 +244,7 @@ public class EventHandlerBean extends AbstractRestBean {
EventSource source = findEventSourceById(sourceId);
EventCriteria criteria = new EventCriteria();
+ criteria.addSortId(PageOrdering.ASC);
criteria.addFilterSourceId(source.getId());
if (startTime>0) {
criteria.addFilterStartTime(startTime);
@@ -291,6 +293,8 @@ public class EventHandlerBean extends AbstractRestBean {
}
EventCriteria criteria = new EventCriteria();
+ criteria.addSortId(PageOrdering.ASC);
+
criteria.addFilterResourceId(resourceId);
if (startTime>0) {
criteria.addFilterStartTime(startTime);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/GroupHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/GroupHandlerBean.java
index d65a850..006c8a0 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/GroupHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/GroupHandlerBean.java
@@ -27,8 +27,6 @@ import java.util.Set;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
@@ -67,6 +65,7 @@ import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.group.GroupDefinition;
import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.core.domain.util.PageList;
+import org.rhq.core.domain.util.PageOrdering;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.resource.ResourceManagerLocal;
import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
@@ -105,9 +104,6 @@ public class GroupHandlerBean extends AbstractRestBean {
@EJB
GroupDefinitionManagerLocal definitionManager;
- @PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME)
- EntityManager em;
-
@GZIP
@GET
@@ -119,6 +115,8 @@ public class GroupHandlerBean extends AbstractRestBean {
@Context HttpHeaders headers, @Context UriInfo uriInfo) {
ResourceGroupCriteria criteria = new ResourceGroupCriteria();
+ criteria.addSortId(PageOrdering.ASC);
+
if (q!=null) {
criteria.addFilterName(q);
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java
index 81d490b..d46850c 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java
@@ -401,12 +401,12 @@ public class OperationsHandlerBean extends AbstractRestBean {
@Context HttpHeaders httpHeaders) {
ResourceOperationHistoryCriteria criteria = new ResourceOperationHistoryCriteria();
+ criteria.addSortStartTime(PageOrdering.ASC);
if (resourceId>0) {
criteria.addFilterResourceIds(resourceId);
}
if (page!=null) {
criteria.setPaging(page,pageSize);
- criteria.addSortStartTime(PageOrdering.ASC);
}
criteria.addSortEndTime(PageOrdering.DESC);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java
index 0c3a7cd..332dfbc 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java
@@ -188,6 +188,8 @@ public class ResourceHandlerBean extends AbstractRestBean {
@Context UriInfo uriInfo) {
ResourceCriteria criteria = new ResourceCriteria();
+ criteria.addSortName(PageOrdering.ASC);
+ criteria.addSortId(PageOrdering.ASC);
if (!status.toLowerCase().equals("all")) {
try {
criteria.addFilterInventoryStatus(InventoryStatus.valueOf(status.toUpperCase()));
@@ -206,7 +208,6 @@ public class ResourceHandlerBean extends AbstractRestBean {
}
if (page!=null) {
criteria.setPaging(page,pageSize);
- criteria.addSortName(PageOrdering.ASC);
}
PageList<Resource> ret = resMgr.findResourcesByCriteria(caller,criteria);
@@ -232,6 +233,7 @@ public class ResourceHandlerBean extends AbstractRestBean {
else {
pc = PageControl.getUnlimitedInstance();
}
+ pc.setPrimarySort("id",PageOrdering.ASC);
PageList<Resource> ret = resMgr.findResourcesByCategory(caller, ResourceCategory.PLATFORM,
InventoryStatus.COMMITTED, pc);
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java
index cd103ca..900ab10 100644
--- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java
@@ -24,11 +24,16 @@ package org.rhq.modules.integrationTests.restApi;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.path.json.JsonPath;
import com.jayway.restassured.path.xml.XmlPath;
import com.jayway.restassured.path.xml.element.Node;
import com.jayway.restassured.response.Response;
+import com.jayway.restassured.response.ResponseBody;
import org.apache.http.HttpStatus;
import org.junit.Test;
@@ -73,8 +78,8 @@ public class ResourcesTest extends AbstractBase {
.contentType(ContentType.JSON)
.log().everything()
.body("links.self", notNullValue())
- .body("resourceId",is(_platformId))
- .body("typeId",is(_platformTypeId))
+ .body("resourceId", is(_platformId))
+ .body("typeId", is(_platformTypeId))
.body("parentId",is(0))
.when()
.get("/resource/{id}");
@@ -94,8 +99,8 @@ public class ResourcesTest extends AbstractBase {
.contentType(WRAPPED_JSON)
.log().everything()
.body("links.self", notNullValue())
- .body("resourceId",is(_platformId))
- .body("typeId",is(_platformTypeId))
+ .body("resourceId", is(_platformId))
+ .body("typeId", is(_platformTypeId))
.body("parentId",is(0))
.when()
.get("/resource/{id}");
@@ -277,13 +282,50 @@ public class ResourcesTest extends AbstractBase {
.statusCode(200)
.log().everything()
// .header("Link", allOf(containsString("page=2"), containsString("current")))
- .header("Link",not(containsString("prev")))
+ .header("Link", not(containsString("prev")))
.body("links.self", notNullValue())
.when()
.get("/resource");
}
@Test
+ public void testGetResourcesWithPagingAndUniquenessCheck() throws Exception {
+
+ int currentPage = 0;
+ Set<Integer> seen = new HashSet<Integer>();
+
+ for(;;) {
+ JsonPath path =
+ given()
+ .header("Accept", "application/vnd.rhq.wrapped+json")
+ .with()
+ .queryParam("page", currentPage)
+ .queryParam("ps", 5) // Unusually small to provoke having more than 1 page
+ .queryParam("status","COMMITTED")
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .get("/resource")
+ .jsonPath();
+
+ List<Integer> ids = path.getList("data.resourceId");
+
+ for (Integer id : ids ) {
+ assert !seen.contains(id);
+ seen.add(id);
+ }
+
+ currentPage++;
+ if (currentPage > path.getInt("lastPage")) {
+ break;
+ }
+ System.out.print("+");
+ }
+ System.out.println();
+ }
+
+ @Test
public void testGetResourcesWithPagingAndWrapping() throws Exception {
given()
@@ -314,7 +356,7 @@ public class ResourcesTest extends AbstractBase {
.log().ifError()
.body("links.self", notNullValue())
.header("Link", not(containsString("prev=")))
- .header("Link", anyOf(containsString("current"),containsString("last")))
+ .header("Link", anyOf(containsString("current"), containsString("last")))
.when().get("/resource/platforms");
}
commit c7bbdd9881024389cc755fdc5d39441d91265084
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu May 23 15:14:23 2013 +0200
Support paging in the body with the appropriate media type
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java
index 5652f9f..92d2499 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java
@@ -448,14 +448,14 @@ public class AbstractRestBean {
uriBuilder = uriInfo.getRequestUriBuilder(); // adds ?q, ?ps and ?category if needed
uriBuilder.replaceQueryParam("page",nextPage);
- builder.header("Link",new Link("next",uriBuilder.build().toString()));
+ builder.header("Link",new Link("next",uriBuilder.build().toString()).rfc5988String());
}
if (page>0) {
int prevPage = page -1;
uriBuilder = uriInfo.getRequestUriBuilder(); // adds ?q, ?ps and ?category if needed
uriBuilder.replaceQueryParam("page",prevPage);
- builder.header("Link", new Link("prev",uriBuilder.build().toString()));
+ builder.header("Link", new Link("prev",uriBuilder.build().toString()).rfc5988String());
}
// A link to the last page
@@ -463,12 +463,12 @@ public class AbstractRestBean {
int lastPage = resultList.getTotalSize() / pc.getPageSize();
uriBuilder = uriInfo.getRequestUriBuilder(); // adds ?q, ?ps and ?category if needed
uriBuilder.replaceQueryParam("page",lastPage);
- builder.header("Link", new Link("last",uriBuilder.build().toString()));
+ builder.header("Link", new Link("last",uriBuilder.build().toString()).rfc5988String());
}
// A link to the current page
uriBuilder = uriInfo.getRequestUriBuilder(); // adds ?q, ?ps and ?category if needed
- builder.header("Link", new Link("current",uriBuilder.build().toString()));
+ builder.header("Link", new Link("current",uriBuilder.build().toString()).rfc5988String());
// Create a total size header
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/Link.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/Link.java
index 129ccfa..6eecf3e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/Link.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/Link.java
@@ -59,4 +59,20 @@ public class Link {
href + "; " +
"rel='" + rel + '\'' ;
}
+
+ /**
+ * Return the link in the format of RFC 5988 Web Linking.
+ *
+ * See <a href="http://tools.ietf.org/html/rfc5988#page-7">RFC 5988 Web Linking</a>
+ * @return String that contains the link with href and rel
+ */
+ public String rfc5988String() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("<")
+ .append(href)
+ .append(">; rel=\"")
+ .append(rel)
+ .append("\"");
+ return builder.toString();
+ }
}
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/EventTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/EventTest.java
index 40ae7b0..75be637 100644
--- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/EventTest.java
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/EventTest.java
@@ -366,13 +366,13 @@ public class EventTest extends AbstractBase {
Headers headers = response.getHeaders();
int found = 0;
for (String link: headers.getValues("Link")) {
- if (link.contains("rel='last'"))
+ if (link.contains("rel=\"last\""))
found++;
- if (link.contains("rel='prev'"))
+ if (link.contains("rel=\"prev\""))
found++;
- if (link.contains("rel='current'"))
+ if (link.contains("rel=\"current\""))
found++;
- assert !link.contains("rel='next");
+ assert !link.contains("rel=\"next\"");
}
assert found == 3;
commit 96456eba09abfac383a5725204c334c6fe31be07
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed May 22 22:37:33 2013 +0200
Support paging in the body with the appropriate media type
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java
index 8e4a826..5652f9f 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java
@@ -26,6 +26,7 @@ import java.io.IOException;
import java.io.StringWriter;
import java.net.URI;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -35,7 +36,9 @@ import java.util.Set;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
+import javax.ws.rs.Produces;
import javax.ws.rs.core.CacheControl;
+import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
@@ -66,6 +69,7 @@ import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal;
import org.rhq.enterprise.server.rest.domain.GroupRest;
import org.rhq.enterprise.server.rest.domain.Link;
import org.rhq.enterprise.server.rest.domain.MetricSchedule;
+import org.rhq.enterprise.server.rest.domain.PagingCollection;
import org.rhq.enterprise.server.rest.domain.ResourceWithType;
/**
@@ -77,12 +81,16 @@ import org.rhq.enterprise.server.rest.domain.ResourceWithType;
* @author Heiko W. Rupp
* @author Jay Shaughnessy
*/
+(a)Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML,MediaType.TEXT_HTML,"application/vnd.rhq.wrapped+json"})
@javax.annotation.Resource(name = "ISPN", mappedName = "java:jboss/infinispan/rhq")
@SuppressWarnings("unchecked")
public class AbstractRestBean {
protected Log log = LogFactory.getLog(getClass().getName());
+ protected final MediaType wrappedCollectionJsonType = new MediaType("application","vnd.rhq.wrapped+json");
+ protected final String wrappedCollectionJson = "application/vnd.rhq.wrapped+json";
+
private static final CacheKey META_KEY = new CacheKey("rhq.rest.resourceMeta", 0);
@javax.annotation.Resource( name = "ISPN")
@@ -468,6 +476,52 @@ public class AbstractRestBean {
}
/**
+ * Wrap the passed collection #resultList in an object with paging information
+ * @param builder ResonseBuilder to add the entity to
+ * @param uriInfo UriInfo to construct paging links
+ * @param originalList The original list to obtain the paging info from
+ * @param resultList The list of result items
+ */
+ protected void wrapForPaging(Response.ResponseBuilder builder, UriInfo uriInfo, final PageList<?> originalList, final Collection resultList) {
+
+ PagingCollection pColl = new PagingCollection(resultList);
+ pColl.setTotalSize(originalList.getTotalSize());
+ PageControl pageControl = originalList.getPageControl();
+ pColl.setPageSize(pageControl.getPageSize());
+ int page = pageControl.getPageNumber();
+ pColl.setCurrentPage(page);
+ pColl.setLastPage(originalList.getTotalSize()/pageControl.getPageSize());
+
+ UriBuilder uriBuilder;
+ if (originalList.getTotalSize() > (page +1 ) * pageControl.getPageSize()) {
+ int nextPage = page +1;
+ uriBuilder = uriInfo.getRequestUriBuilder(); // adds ?q, ?ps and ?category if needed
+ uriBuilder.replaceQueryParam("page",nextPage);
+ pColl.addLink(new Link("next",uriBuilder.build().toString()));
+ }
+ if (page > 0) {
+ int prevPage = page -1;
+ uriBuilder = uriInfo.getRequestUriBuilder(); // adds ?q, ?ps and ?category if needed
+ uriBuilder.replaceQueryParam("page",prevPage);
+ pColl.addLink(new Link("prev",uriBuilder.build().toString()));
+ }
+
+ // A link to the last page
+ if (!pageControl.isUnlimited()) {
+ int lastPage = originalList.getTotalSize() / pageControl.getPageSize();
+ uriBuilder = uriInfo.getRequestUriBuilder(); // adds ?q, ?ps and ?category if needed
+ uriBuilder.replaceQueryParam("page",lastPage);
+ pColl.addLink( new Link("last",uriBuilder.build().toString()));
+ }
+
+ // A link to the current page
+ uriBuilder = uriInfo.getRequestUriBuilder(); // adds ?q, ?ps and ?category if needed
+ pColl.addLink(new Link("current",uriBuilder.build().toString()));
+
+ builder.entity(pColl);
+ }
+
+ /**
* Fetch the group with the passed id
*
* @param groupId id of the resource group
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java
index 6ea3d03..4ceae82 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java
@@ -46,6 +46,7 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.GenericEntity;
+import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
@@ -98,7 +99,6 @@ import org.rhq.enterprise.server.rest.domain.Link;
* AlertHandlerBean
* @author Heiko W. Rupp
*/
-@Produces({"application/json","application/xml","text/plain"})
@Path("/alert")
@Api(value = "Deal with Alert Definitions",description = "This api deals with alert definitions. Everything " +
" is purely experimental at the moment and can change without notice at any time.")
@@ -149,6 +149,7 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean {
@ApiParam(value = "Page number") @QueryParam("page") Integer page,
@ApiParam(value = "Page size") @DefaultValue("20") @QueryParam("ps") int pageSize,
@ApiParam(value = "Limit to status, UNUSED AT THE MOMENT ") @QueryParam("status") String status, // TODO
+ @Context HttpHeaders headers,
@Context UriInfo uriInfo) {
AlertDefinitionCriteria criteria = new AlertDefinitionCriteria();
@@ -163,10 +164,17 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean {
ret.add(adr);
}
- Response.ResponseBuilder builder = Response.ok(ret);
- createPagingHeader(builder,uriInfo,defs);
+ Response.ResponseBuilder builder = Response.ok();
- // TODO media type etc
+ MediaType mediaType = headers.getAcceptableMediaTypes().get(0);
+ builder.type(mediaType);
+
+ if (mediaType.equals(wrappedCollectionJsonType)) {
+ wrapForPaging(builder,uriInfo,defs,ret);
+ } else {
+ createPagingHeader(builder,uriInfo,defs);
+ builder.entity(ret); // TODO generic entity for XML
+ }
return builder.build();
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertHandlerBean.java
index 5da3fb9..5c6a06f 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertHandlerBean.java
@@ -32,7 +32,6 @@ import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.EntityTag;
@@ -72,7 +71,6 @@ import org.rhq.enterprise.server.rest.domain.*;
* Deal with alert related stuff
* @author Heiko W. Rupp
*/
-@Produces({"application/json","application/xml","text/html"})
@Path("/alert")
@Api(value = "Deal with Alerts",description = "This api deals with alerts that have fired.")
@Stateless
@@ -148,17 +146,22 @@ public class AlertHandlerBean extends AbstractRestBean {
}
MediaType type = headers.getAcceptableMediaTypes().get(0);
- Response.ResponseBuilder builder;
+ Response.ResponseBuilder builder = Response.ok();
+ builder.type(type);
if (type.equals(MediaType.TEXT_HTML_TYPE)) {
- builder = Response.ok(renderTemplate("listAlerts.ftl",ret),type);
+ builder.entity(renderTemplate("listAlerts.ftl",ret));
} else {
- GenericEntity<List<AlertRest>> entity = new GenericEntity<List<AlertRest>>(ret) {};
- builder = Response.ok(entity);
+ if (type.equals(wrappedCollectionJsonType)) {
+ wrapForPaging(builder,uriInfo,alerts,ret);
+ }
+ else {
+ GenericEntity<List<AlertRest>> entity = new GenericEntity<List<AlertRest>>(ret) {};
+ builder.entity(entity);
+ createPagingHeader(builder,uriInfo,alerts);
+ }
}
- createPagingHeader(builder,uriInfo,alerts);
-
return builder.build();
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/EventHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/EventHandlerBean.java
index 7402550..fd8a835 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/EventHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/EventHandlerBean.java
@@ -37,13 +37,11 @@ import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
@@ -76,7 +74,6 @@ import org.rhq.enterprise.server.rest.domain.EventSourceRest;
*/
@Path("/event")
@Api("Api that deals with Events (e.g snmp traps, logfile lines)")
-(a)Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML,MediaType.TEXT_HTML})
@Stateless
@Interceptors(SetCallerInterceptor.class)
public class EventHandlerBean extends AbstractRestBean {
@@ -348,17 +345,20 @@ public class EventHandlerBean extends AbstractRestBean {
}
MediaType mediaType = headers.getAcceptableMediaTypes().get(0);
- Response.ResponseBuilder builder;
+ Response.ResponseBuilder builder = Response.ok();
+ builder.type(mediaType);
if (mediaType.equals(MediaType.APPLICATION_XML_TYPE)) {
GenericEntity<List<EventRest>> list = new GenericEntity<List<EventRest>>(restEvents) {};
- builder = Response.ok(list, mediaType);
+ builder.entity(list);
+ createPagingHeader(builder,uriInfo,eventList);
+ } else if (mediaType.equals(MediaType.APPLICATION_JSON_TYPE)) {
+ builder.entity(restEvents);
+ createPagingHeader(builder,uriInfo,eventList);
}
- else {
- builder = Response.ok(restEvents, mediaType);
+ else {
+ wrapForPaging(builder,uriInfo,eventList,restEvents);
}
- createPagingHeader(builder,uriInfo,eventList);
-
return builder;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/GroupHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/GroupHandlerBean.java
index be2419b..d65a850 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/GroupHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/GroupHandlerBean.java
@@ -37,7 +37,6 @@ import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.GenericEntity;
@@ -93,7 +92,6 @@ import org.rhq.enterprise.server.rest.domain.ResourceWithType;
@Interceptors(SetCallerInterceptor.class)
@Path("/group")
@Api(value="Deal with groups and DynaGroups", description = "Api that deals with resource groups and group definitions")
-(a)Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML,MediaType.TEXT_HTML})
public class GroupHandlerBean extends AbstractRestBean {
private final Log log = LogFactory.getLog(GroupHandlerBean.class);
@@ -142,12 +140,15 @@ public class GroupHandlerBean extends AbstractRestBean {
if (mediaType.equals(MediaType.TEXT_HTML_TYPE)) {
builder.entity(renderTemplate("listGroup", list));
}
+ else if (mediaType.equals(wrappedCollectionJsonType)) {
+ wrapForPaging(builder,uriInfo,groups,list);
+ }
else {
GenericEntity<List<GroupRest>> ret = new GenericEntity<List<GroupRest>>(list) {};
builder.entity(ret);
+ createPagingHeader(builder,uriInfo,groups);
}
- createPagingHeader(builder,uriInfo,groups);
return builder.build();
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java
index e32ea03..81d490b 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java
@@ -420,16 +420,19 @@ public class OperationsHandlerBean extends AbstractRestBean {
}
MediaType mediaType = httpHeaders.getAcceptableMediaTypes().get(0);
- Response.ResponseBuilder builder;
+ Response.ResponseBuilder builder = Response.ok();
+ builder.type(mediaType);
+
if (mediaType.equals(MediaType.TEXT_HTML_TYPE)) {
- builder = Response.ok(renderTemplate("listOperationHistory.ftl", result));
+ builder.entity(renderTemplate("listOperationHistory.ftl", result));
+ } else if (mediaType.equals(wrappedCollectionJsonType)) {
+ wrapForPaging(builder,uriInfo,histories,result);
} else {
GenericEntity<List<OperationHistoryRest>> res = new GenericEntity<List<OperationHistoryRest>>(result) {};
- builder = Response.ok(res);
+ builder.entity(res);
+ createPagingHeader(builder,uriInfo,histories);
}
- createPagingHeader(builder,uriInfo,histories);
-
return builder.build();
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java
index a783ac8..0c3a7cd 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java
@@ -114,7 +114,6 @@ import org.rhq.enterprise.server.rest.helper.ConfigurationHelper;
* Class that deals with getting data about resources
* @author Heiko W. Rupp
*/
-(a)Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML,MediaType.TEXT_HTML})
@Path("/resource")
@Api(value="Resource related", description = "This endpoint deals with individual resources, not resource groups")
@Interceptors(SetCallerInterceptor.class)
@@ -263,15 +262,19 @@ public class ResourceHandlerBean extends AbstractRestBean {
Response.ResponseBuilder builder = Response.ok();
builder.type(mediaType);
- createPagingHeader(builder,uriInfo,resources);
if (mediaType.equals(MediaType.TEXT_HTML_TYPE)) {
builder.entity(renderTemplate("listResourceWithType", rwtList));
} else {
- GenericEntity<List<ResourceWithType>> list = new GenericEntity<List<ResourceWithType>>(rwtList) {
+ if (mediaType.equals(wrappedCollectionJsonType)) {
+ wrapForPaging(builder,uriInfo,resources,rwtList);
+ } else {
+ GenericEntity<List<ResourceWithType>> list = new GenericEntity<List<ResourceWithType>>(rwtList) {
};
- builder.entity(list);
+ builder.entity(list);
+ createPagingHeader(builder,uriInfo,resources);
+ }
}
return builder;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/PagingCollection.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/PagingCollection.java
new file mode 100644
index 0000000..4a0f892
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/PagingCollection.java
@@ -0,0 +1,97 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2013 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+package org.rhq.enterprise.server.rest.domain;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * A wrapper for collections with paging entries
+ * @author Heiko W. Rupp
+ */
+@XmlRootElement
+public class PagingCollection<T> {
+
+ Collection<T> data;
+ int pageSize;
+ int currentPage;
+ int lastPage;
+ int totalSize;
+ List<Link> links = new ArrayList<Link>();
+
+ public PagingCollection(Collection<T> data) {
+ this.data = data;
+ }
+
+ public int getCurrentPage() {
+ return currentPage;
+ }
+
+ public void setCurrentPage(int currentPage) {
+ this.currentPage = currentPage;
+ }
+
+ public Collection<T> getData() {
+ return data;
+ }
+
+ public void setData(Collection<T> data) {
+ this.data = data;
+ }
+
+ public int getLastPage() {
+ return lastPage;
+ }
+
+ public void setLastPage(int lastPage) {
+ this.lastPage = lastPage;
+ }
+
+ public int getPageSize() {
+ return pageSize;
+ }
+
+ public void setPageSize(int pageSize) {
+ this.pageSize = pageSize;
+ }
+
+ public int getTotalSize() {
+ return totalSize;
+ }
+
+ public void setTotalSize(int totalSize) {
+ this.totalSize = totalSize;
+ }
+
+ public List<Link> getLinks() {
+ return links;
+ }
+
+ public void setLinks(List<Link> links) {
+ this.links = links;
+ }
+
+ public void addLink(Link link) {
+ links.add(link);
+ }
+}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationHelperTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationHelperTest.java
index 7e20630..3a7e961 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationHelperTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationHelperTest.java
@@ -703,7 +703,7 @@ public class ConfigurationHelperTest {
}
- @Test
+ @Test(enabled = false)
public void testConfigToMapComplexMapWithBadSetupLenient() throws Exception {
Configuration config = new Configuration();
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AbstractBase.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AbstractBase.java
index ae4e81d..fd154ef 100644
--- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AbstractBase.java
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AbstractBase.java
@@ -40,6 +40,7 @@ import static com.jayway.restassured.RestAssured.given;
public abstract class AbstractBase {
static final String APPLICATION_JSON = "application/json";
+ static final String WRAPPED_JSON = "application/vnd.rhq.wrapped+json";
private static final String APPLICATION_XML = "application/xml";
private static final String TEXT_CSV = "text/csv";
private static final String TEXT_HTML = "text/html";
@@ -48,6 +49,7 @@ public abstract class AbstractBase {
static Header acceptXml = new Header("Accept", APPLICATION_XML);
static Header acceptHtml = new Header("Accept", TEXT_HTML);
static Header acceptCsv = new Header("Accept", TEXT_CSV);
+ static Header acceptWrappedJson = new Header("Accept",WRAPPED_JSON);
int _platformId ;
int _platformTypeId;
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AlertTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AlertTest.java
index e02a723..acbb492 100644
--- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AlertTest.java
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AlertTest.java
@@ -39,6 +39,7 @@ import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.emptyIterable;
import static org.hamcrest.Matchers.instanceOf;
@@ -116,6 +117,22 @@ public class AlertTest extends AbstractBase {
.get("/alert");
}
+ @Test
+ public void testListAlertsWithPagingAndWrapped() throws Exception {
+
+ given()
+ .header(acceptWrappedJson)
+ .queryParam("ps", 2)
+ .queryParam("page", 0)
+ .expect()
+ .statusCode(200)
+ .header("Link", nullValue())
+ .body("totalSize", notNullValue())
+ .log().ifError()
+ .when()
+ .get("/alert");
+ }
+
@Test
public void testGetAlertCountJson() throws Exception {
@@ -192,6 +209,21 @@ public class AlertTest extends AbstractBase {
}
@Test
+ public void testListAllAlertDefinitionsWithWrapping() throws Exception {
+
+ given()
+ .header(acceptWrappedJson)
+ .log().everything()
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .body("currentPage", Matchers.notNullValue())
+ .body("totalSize", Matchers.notNullValue())
+ .when()
+ .get("/alert/definitions");
+ }
+
+ @Test
public void testRedirectForDefinition() throws Exception {
given()
.header(acceptJson)
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ContentTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ContentTest.java
index 3515fac..ebd72c0 100644
--- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ContentTest.java
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ContentTest.java
@@ -306,13 +306,13 @@ public class ContentTest extends AbstractBase {
.as(List.class);
if (resources!=null && resources.size()>0) {
- int resourceId = resources.get(0).getResourceId();
+ int resourceId = (Integer) ((Map < String,Object>)resources.get(0)).get("resourceId");
given()
.pathParam("id", resourceId)
.queryParam("physical", "true") // Also remove target on the EAP instance
.expect()
- .statusCode(200)
+ .statusCode(204)
.when()
.delete("/resource/{id}");
}
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/GroupTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/GroupTest.java
index a4ef048..ef575d1 100644
--- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/GroupTest.java
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/GroupTest.java
@@ -35,6 +35,8 @@ import org.rhq.modules.integrationTests.restApi.d.GroupDef;
import static com.jayway.restassured.RestAssured.expect;
import static com.jayway.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.iterableWithSize;
@@ -69,17 +71,37 @@ public class GroupTest extends AbstractBase {
@Test
public void testGetGroups() throws Exception {
- expect().statusCode(200)
- .when().get("/group");
+ expect()
+ .statusCode(200)
+ .when()
+ .get("/group");
}
@Test
public void testGetGroupsWithPaging() throws Exception {
given()
+ .header(acceptJson)
+ .queryParam("page",0)
+ .queryParam("ps",2)
+ .expect()
+ .statusCode(200)
+ .header("Link", notNullValue())
+ .when()
+ .get("/group");
+ }
+
+ @Test
+ public void testGetGroupsWithPagingWrapped() throws Exception {
+ given()
+ .header(acceptWrappedJson)
.queryParam("page",0)
.queryParam("ps",2)
.expect()
.statusCode(200)
+ .log().ifError()
+ .header("Link",nullValue())
+ .body("pageSize",is(2))
+ .body("currentPage",is(0))
.when()
.get("/group");
}
@@ -87,10 +109,11 @@ public class GroupTest extends AbstractBase {
@Test
public void testGetGroupsQuery() throws Exception {
given()
- .queryParam("q","lala")
+ .queryParam("q", "lala")
.expect()
- .statusCode(200)
- .when().get("/group");
+ .statusCode(200)
+ .when()
+ .get("/group");
}
@Test
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java
index b66d9b5..cd103ca 100644
--- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java
@@ -82,6 +82,27 @@ public class ResourcesTest extends AbstractBase {
}
@Test
+ public void testGetPlatformJsonWrapping() {
+
+ // Actually this object should not be wrapped
+ // as it is no list
+ given()
+ .header(acceptWrappedJson)
+ .pathParam("id",_platformId)
+ .expect()
+ .statusCode(200)
+ .contentType(WRAPPED_JSON)
+ .log().everything()
+ .body("links.self", notNullValue())
+ .body("resourceId",is(_platformId))
+ .body("typeId",is(_platformTypeId))
+ .body("parentId",is(0))
+ .when()
+ .get("/resource/{id}");
+
+ }
+
+ @Test
public void testGetPlatformAndTypeJson() {
Integer typeId =
@@ -258,7 +279,26 @@ public class ResourcesTest extends AbstractBase {
// .header("Link", allOf(containsString("page=2"), containsString("current")))
.header("Link",not(containsString("prev")))
.body("links.self", notNullValue())
- .when().get("/resource");
+ .when()
+ .get("/resource");
+ }
+
+ @Test
+ public void testGetResourcesWithPagingAndWrapping() throws Exception {
+
+ given()
+ .header("Accept", "application/vnd.rhq.wrapped+json")
+ .with()
+ .queryParam("page", 1)
+ .queryParam("ps", 2) // Unusually small to provoke having more than 1 page
+ .queryParam("category", "service")
+ .expect()
+ .statusCode(200)
+ .log().everything()
+ .body("pageSize",is(2))
+ .body("currentPage",is(1))
+ .when()
+ .get("/resource");
}
@Test
commit c253f4d2f4fb3ef3a588f1582a022cc21f5790b9
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Wed May 22 19:36:09 2013 +0200
Improvements to RHQ irc bot. New set of commands is now supported.
diff --git a/etc/rhq-ircBot/pom.xml b/etc/rhq-ircBot/pom.xml
index 40b6952..6e66187 100644
--- a/etc/rhq-ircBot/pom.xml
+++ b/etc/rhq-ircBot/pom.xml
@@ -41,7 +41,7 @@
<dependency>
<groupId>org.pircbotx</groupId>
<artifactId>pircbotx</artifactId>
- <version>1.7</version>
+ <version>1.9</version>
</dependency>
<dependency>
@@ -50,6 +50,17 @@
<version>2.0</version>
</dependency>
+ <dependency>
+ <groupId>org.jsoup</groupId>
+ <artifactId>jsoup</artifactId>
+ <version>1.7.2</version>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>1.4</version>
+ </dependency>
</dependencies>
<build>
diff --git a/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBot.java b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBot.java
index ce7535f..7e8f563 100644
--- a/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBot.java
+++ b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBot.java
@@ -1,163 +1,63 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2013 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.etc.ircbot;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import com.j2bugzilla.base.Bug;
-import com.j2bugzilla.base.BugzillaConnector;
-import com.j2bugzilla.base.BugzillaException;
-import com.j2bugzilla.rpc.GetBug;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.util.Properties;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
-import org.apache.xmlrpc.XmlRpcException;
import org.pircbotx.PircBotX;
-import org.pircbotx.User;
-import org.pircbotx.hooks.Listener;
-import org.pircbotx.hooks.ListenerAdapter;
-import org.pircbotx.hooks.events.DisconnectEvent;
-import org.pircbotx.hooks.events.MessageEvent;
-import org.pircbotx.hooks.events.PrivateMessageEvent;
/**
- * An IRC bot for doing helpful stuff on the Freenode #rhq channel.
+ * @author Jirka Kremser
*
- * @author Ian Springer
*/
-public class RhqIrcBot extends ListenerAdapter {
-
- private static final Pattern BUG_PATTERN = Pattern.compile("(?i)(bz|bug)[ ]*(\\d{6,7})");
- private static final Pattern ECHO_PATTERN = Pattern.compile("(?i)echo[ ]+(.+)");
-
- private static final Set<String> JON_DEVS = new HashSet<String>();
- static {
- JON_DEVS.add("ccrouch");
- JON_DEVS.add("ips");
- JON_DEVS.add("jkremser");
- JON_DEVS.add("jsanda");
- JON_DEVS.add("jshaughn");
- JON_DEVS.add("lkrejci");
- JON_DEVS.add("mazz");
- JON_DEVS.add("mtho11");
- JON_DEVS.add("pilhuhn");
- JON_DEVS.add("spinder");
- JON_DEVS.add("stefan_n");
- }
-
- private String server;
- private String channel;
- private BugzillaConnector bzConnector = new BugzillaConnector();
- private Map<Integer, Long> bugLogTimestamps = new HashMap<Integer, Long>();
-
- public RhqIrcBot(String server, String channel) {
- this.server = server;
- this.channel = channel;
- }
-
- @Override
- public void onMessage(MessageEvent event) throws Exception {
- PircBotX bot = event.getBot();
- if (!bot.getNick().equals(bot.getName())) {
- bot.changeNick(bot.getName());
- }
-
- String message = event.getMessage();
- Matcher bugMatcher = BUG_PATTERN.matcher(message);
- while (bugMatcher.find()) {
- int bugId = Integer.valueOf(bugMatcher.group(2));
- GetBug getBug = new GetBug(bugId);
- try {
- bzConnector.executeMethod(getBug);
- } catch (Exception e) {
- bzConnector = new BugzillaConnector();
- bzConnector.connectTo("https://bugzilla.redhat.com");
- try {
- bzConnector.executeMethod(getBug);
- } catch (BugzillaException e1) {
- //e1.printStackTrace();
- Throwable cause = e1.getCause();
- String details = (cause instanceof XmlRpcException) ? cause.getMessage() : e1.getMessage();
- bot.sendMessage(event.getChannel(), "Failed to access BZ " + bugId + ": " + details);
- continue;
- }
- }
- Bug bug = getBug.getBug();
- if (bug != null) {
- String product = bug.getProduct();
- if (product.equals("RHQ Project")) {
- product = "RHQ";
- } else if (product.equals("JBoss Operations Network")) {
- product = "JON";
- }
- Long timestamp = bugLogTimestamps.get(bugId);
- if ((timestamp == null) || ((System.currentTimeMillis() - timestamp) > (5 * 60 * 1000L))) {
- bot.sendMessage(event.getChannel(), "BZ " + bugId + " [product=" + product
- + ", priority=" + bug.getPriority() + ", status=" + bug.getStatus() + "] "
- + bug.getSummary() + " [ https://bugzilla.redhat.com/" + bugId + " ]");
- }
- bugLogTimestamps.put(bugId, System.currentTimeMillis());
- } else {
- bot.sendMessage(event.getChannel(), "BZ " + bugId + " does not exist.");
- }
- }
-
- if (message.matches(".*\\b(jon-team|jboss-on-team)\\b.*")) {
- Set<User> users = bot.getUsers(event.getChannel());
- StringBuilder presentJonDevs = new StringBuilder();
- for (User user : users) {
- String nick = user.getNick();
- if (JON_DEVS.contains(nick) && !nick.equals(event.getUser().getNick())) {
- presentJonDevs.append(nick).append(' ');
- }
- }
- bot.sendMessage(event.getChannel(), presentJonDevs + ": see message from "
- + event.getUser().getNick() + " above");
- }
+public class RhqIrcBot extends PircBotX {
+
+ private static final String TRUSTSTORE_NAME = "cacerts.jks";
+
+ public RhqIrcBot(RhqIrcBotListener rhqBot) {
+ setName("rhq-bot");
+ setVersion("1.1");
+ setFinger("RHQ IRC bot (source code in RHQ git under etc/rhq-ircBot/)");
+
+ setVerbose(true);
+ setAutoNickChange(true);
+
+ getListenerManager().addListener(rhqBot);
+ setSocketTimeout(1 * 60 * 1000); // 1 minute
}
-
- @Override
- public void onPrivateMessage(PrivateMessageEvent privateMessageEvent) throws Exception {
- PircBotX bot = privateMessageEvent.getBot();
- String message = privateMessageEvent.getMessage();
- Matcher echoMatcher = ECHO_PATTERN.matcher(message);
- if (echoMatcher.matches()) {
- String echoMessage = echoMatcher.group(1);
- bot.sendMessage(this.channel, echoMessage);
- } else {
- bot.sendMessage(privateMessageEvent.getUser(), "Hi, I am " + bot.getFinger() + ".");
- }
- // TODO: Implement a HELP command.
- }
-
- @Override
- public void onDisconnect(DisconnectEvent disconnectEvent) throws Exception {
- boolean connected = false;
- while (!connected) {
- Thread.sleep(60 * 1000L); // 1 minute
- try {
- PircBotX newBot = createBot(this);
- newBot.connect(this.server);
- newBot.joinChannel(this.channel);
-
- connected = true;
- } catch (Exception e) {
- System.err.println("Failed to reconnect to " + disconnectEvent.getBot().getServer() + " IRC server: " + e);
- }
- }
-
- // Try to clean up the old bot, so it can release any memory, sockets, etc. it's using.
- PircBotX oldBot = disconnectEvent.getBot();
- Set<Listener> oldListeners = new HashSet<Listener>(oldBot.getListenerManager().getListeners());
- for (Listener oldListener : oldListeners) {
- oldBot.getListenerManager().removeListener(oldListener);
- }
- }
-
+
public static void main(String[] args) throws Exception {
- if (args.length != 2) {
- System.err.println("Usage: RhqIrcBot IRC_SERVER IRC_CHANNEL");
+ if (args.length != 2 && args.length != 3) {
+ System.err.println("Usage: RhqIrcBot IRC_SERVER IRC_CHANNEL [rhq-ircBot.properties]");
System.err.println(" e.g.: RhqIrcBot irc.freenode.net '#rhq'");
System.exit(1);
}
@@ -167,26 +67,62 @@ public class RhqIrcBot extends ListenerAdapter {
channel = '#' + channel;
}
- RhqIrcBot rhqBot = new RhqIrcBot(server, channel);
+ RhqIrcBotListener rhqBotListener = new RhqIrcBotListener(server, channel);
+ if (args.length == 3) {
+ File propertyFile = new File(args[2]);
+ if (!propertyFile.exists()) {
+ System.err.println("Provided property file [" + args[2] + "] does not exist");
+ System.exit(2);
+ }
+ Properties properties = new Properties();
+ FileInputStream fis = new FileInputStream(propertyFile);
+ properties.load(fis);
+ String docspaceLogin = properties.getProperty("docspace_login");
+ String docspacePassword = properties.getProperty("docspace_password");
+ if (docspaceLogin == null || docspaceLogin.isEmpty() || docspacePassword == null || docspacePassword.isEmpty()) {
+ System.err.println("The property format has bad format");
+ System.err.println("It must contain following key-value pairs\n");
+ System.err.println("docspace_login=X");
+ System.err.println("docspace_password=Y");
+ System.exit(3);
+ }
+ fis.close();
+
+ setupTrustStore();
+
+ rhqBotListener.setDocspaceLogin(docspaceLogin);
+ rhqBotListener.setDocspacePassword(docspacePassword);
+ }
- PircBotX bot = createBot(rhqBot);
+ PircBotX bot = new RhqIrcBot(rhqBotListener);
bot.connect(server);
bot.joinChannel(channel);
}
-
- private static PircBotX createBot(RhqIrcBot rhqBot) {
- PircBotX bot = new PircBotX();
-
- bot.setName("rhq-bot");
- bot.setVersion("1.0");
- bot.setFinger("RHQ IRC bot (source code in RHQ git under etc/rhq-ircBot/)");
-
- bot.setVerbose(true);
- bot.setAutoNickChange(true);
-
- bot.getListenerManager().addListener(rhqBot);
- bot.setSocketTimeout(1 * 60 * 1000); // 1 minute
- return bot;
+
+ private static void setupTrustStore() {
+ TrustManagerFactory trustManagerFactory;
+ try {
+ trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ KeyStore keystore;
+ keystore = KeyStore.getInstance(KeyStore.getDefaultType());
+ InputStream keystoreStream = RhqIrcBot.class.getResourceAsStream(TRUSTSTORE_NAME);
+ keystore.load(keystoreStream, "rhqirc".toCharArray());
+ trustManagerFactory.init(keystore);
+ TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
+ SSLContext ctx = SSLContext.getInstance("SSL");
+ ctx.init(null, trustManagers, null);
+
+ SSLContext.setDefault(ctx);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ } catch (KeyStoreException e) {
+ e.printStackTrace();
+ } catch (CertificateException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (KeyManagementException e) {
+ e.printStackTrace();
+ }
}
-
}
diff --git a/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java
new file mode 100644
index 0000000..8a7e578
--- /dev/null
+++ b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java
@@ -0,0 +1,357 @@
+package org.rhq.etc.ircbot;
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.j2bugzilla.base.Bug;
+import com.j2bugzilla.base.BugzillaConnector;
+import com.j2bugzilla.base.BugzillaException;
+import com.j2bugzilla.rpc.GetBug;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.xmlrpc.XmlRpcException;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+import org.pircbotx.PircBotX;
+import org.pircbotx.User;
+import org.pircbotx.hooks.Listener;
+import org.pircbotx.hooks.ListenerAdapter;
+import org.pircbotx.hooks.events.DisconnectEvent;
+import org.pircbotx.hooks.events.MessageEvent;
+import org.pircbotx.hooks.events.NickChangeEvent;
+import org.pircbotx.hooks.events.PrivateMessageEvent;
+
+/**
+ * An IRC bot for doing helpful stuff on the Freenode #rhq channel.
+ *
+ * @author Ian Springer
+ * @author Jiri Kremser
+ */
+public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
+
+ private static final Pattern BUG_PATTERN = Pattern.compile("(?i)(bz|bug)[ ]*(\\d{6,7})");
+ private static final Pattern COMMIT_PATTERN = Pattern.compile("(?i)(\\!commit|cm)[ ]*([0-9a-f]{3,40})");
+ private static final Pattern ECHO_PATTERN = Pattern.compile("(?i)echo[ ]+(.+)");
+ private static final String SUPPORT_LINK = "https://docspace.corp.redhat.com/docs/DOC-124477";
+ private static final String COMMIT_LINK = "https://git.fedorahosted.org/cgit/rhq/rhq.git/commit/?id=%s";
+ private static final String PTO_LINK = "https://mail.corp.redhat.com/home/ccrouch@redhat.com/JBoss%20ON%20OOO?fmt...";
+ private static final DateFormat monthFormat = new SimpleDateFormat("MMM");
+ private static final DateFormat dayInMonthFormat = new SimpleDateFormat("d");
+
+ private static enum Command {
+
+ FORUM("Our forum is available from https://community.jboss.org/en/rhq?view=discussions", true),
+ HELP("You can use one of the following commands: ", true),
+ LISTS("Feel free to enroll to the user list https://lists.fedorahosted.org/mailman/listinfo/rhq-users"
+ + " or the devel list https://lists.fedorahosted.org/mailman/listinfo/rhq-devel", true),
+ LOGS("IRC logs are available from http://transcripts.jboss.org/channel/irc.freenode.org/%23rhq/index.html", true),
+ PTO,
+ SOURCE("The code could be viewed/cloned on https://github.com/rhq-project or https://git.fedorahosted.org/cgit/rhq/rhq.git/", true),
+ SUPPORT,
+ WIKI("Our wiki is available from https://docs.jboss.org/author/display/RHQ/Home", true);
+
+ public static final char PREFIX = '!';
+ private final String staticRespond;
+ private final boolean includeInHelp;
+
+ Command(String staticRespond, boolean includeInHelp) {
+ this.staticRespond = staticRespond;
+ this.includeInHelp = includeInHelp;
+ }
+
+ Command() {
+ this(null, false);
+ }
+ }
+
+ private static final Set<String> JON_DEVS = new HashSet<String>();
+ static {
+ JON_DEVS.add("ccrouch");
+ JON_DEVS.add("ips");
+ JON_DEVS.add("jkremser");
+ JON_DEVS.add("jsanda");
+ JON_DEVS.add("jshaughn");
+ JON_DEVS.add("lkrejci");
+ JON_DEVS.add("mazz");
+ JON_DEVS.add("mtho11");
+ JON_DEVS.add("pilhuhn");
+ JON_DEVS.add("spinder");
+ JON_DEVS.add("stefan_n");
+ JON_DEVS.add("tsegismont");
+ }
+
+ private final String server;
+ private final String channel;
+ private String docspaceLogin;
+ private String docspacePassword;
+ private BugzillaConnector bzConnector = new BugzillaConnector();
+ private final Map<Integer, Long> bugLogTimestamps = new HashMap<Integer, Long>();
+ private final Map<String, String> names = new HashMap<String, String>();
+ private final Pattern commandPattern;
+
+ public RhqIrcBotListener(String server, String channel) {
+ this.server = server;
+ this.channel = channel;
+ StringBuilder commandRegExp = new StringBuilder();
+ commandRegExp.append("(?i)\\").append(Command.PREFIX).append("[ ]*(");
+ for (Command command : Command.values()) {
+ commandRegExp.append(command.name()).append('|');
+ }
+ commandRegExp.deleteCharAt(commandRegExp.length() - 1);
+ commandRegExp.append(')');
+ commandPattern = Pattern.compile(commandRegExp.toString());
+ }
+
+ @Override
+ public void onMessage(MessageEvent<RhqIrcBot> event) throws Exception {
+ PircBotX bot = event.getBot();
+ if (!bot.getNick().equals(bot.getName())) {
+ bot.changeNick(bot.getName());
+ }
+
+ // react to BZs in the messages
+ String message = event.getMessage();
+ Matcher bugMatcher = BUG_PATTERN.matcher(message);
+ while (bugMatcher.find()) {
+ int bugId = Integer.valueOf(bugMatcher.group(2));
+ GetBug getBug = new GetBug(bugId);
+ try {
+ bzConnector.executeMethod(getBug);
+ } catch (Exception e) {
+ bzConnector = new BugzillaConnector();
+ bzConnector.connectTo("https://bugzilla.redhat.com");
+ try {
+ bzConnector.executeMethod(getBug);
+ } catch (BugzillaException e1) {
+ //e1.printStackTrace();
+ Throwable cause = e1.getCause();
+ String details = (cause instanceof XmlRpcException) ? cause.getMessage() : e1.getMessage();
+ bot.sendMessage(event.getChannel(), "Failed to access BZ " + bugId + ": " + details);
+ continue;
+ }
+ }
+ Bug bug = getBug.getBug();
+ if (bug != null) {
+ String product = bug.getProduct();
+ if (product.equals("RHQ Project")) {
+ product = "RHQ";
+ } else if (product.equals("JBoss Operations Network")) {
+ product = "JON";
+ }
+ Long timestamp = bugLogTimestamps.get(bugId);
+ if ((timestamp == null) || ((System.currentTimeMillis() - timestamp) > (5 * 60 * 1000L))) {
+ bot.sendMessage(
+ event.getChannel(),
+ "BZ " + bugId + " [product=" + product + ", priority=" + bug.getPriority() + ", status="
+ + bug.getStatus() + "] " + bug.getSummary() + " [ https://bugzilla.redhat.com/" + bugId
+ + " ]");
+ }
+ bugLogTimestamps.put(bugId, System.currentTimeMillis());
+ } else {
+ bot.sendMessage(event.getChannel(), "BZ " + bugId + " does not exist.");
+ }
+ }
+
+ // react to the commit hashs included in the messages
+ Matcher commitMatcher = COMMIT_PATTERN.matcher(message);
+ while (commitMatcher.find()) {
+ String shaHash = commitMatcher.group(2);
+ String response = String.format(COMMIT_LINK, shaHash);
+ bot.sendMessage(event.getChannel(), event.getUser().getNick() + ": " + response);
+ }
+
+ // react to commands included in the messages
+ Matcher commandMatcher = commandPattern.matcher(message);
+ while (commandMatcher.find()) {
+ Command command = Command.valueOf(commandMatcher.group(1).toUpperCase());
+ String response = prepareResponseForCommand(command);
+ bot.sendMessage(event.getChannel(), event.getUser().getNick() + ": " + response);
+ }
+
+ // ping JON devs
+ if (message.matches(".*\\b(jon-team|jboss-on-team)\\b.*")) {
+ Set<User> users = bot.getUsers(event.getChannel());
+ StringBuilder presentJonDevs = new StringBuilder();
+ for (User user : users) {
+ String nick = user.getNick();
+ if (JON_DEVS.contains(nick) && !nick.equals(event.getUser().getNick())) {
+ presentJonDevs.append(nick).append(' ');
+ }
+ }
+ bot.sendMessage(event.getChannel(), presentJonDevs + ": see message from " + event.getUser().getNick()
+ + " above");
+ }
+ }
+
+ @Override
+ public void onPrivateMessage(PrivateMessageEvent<RhqIrcBot> privateMessageEvent) throws Exception {
+ PircBotX bot = privateMessageEvent.getBot();
+ String message = privateMessageEvent.getMessage();
+ Matcher echoMatcher = ECHO_PATTERN.matcher(message);
+ if (echoMatcher.matches()) {
+ String echoMessage = echoMatcher.group(1);
+ bot.sendMessage(this.channel, echoMessage);
+ } else if (message.equalsIgnoreCase(Command.PREFIX + "listrenames")) {
+ //Generate a list of renames in the form of old1 changed to new1, old2 changed to new2, etc
+ StringBuilder users = new StringBuilder();
+ for (Map.Entry<String, String> curUser : names.entrySet()) {
+ users.append(curUser.getKey()).append(" changed to ").append(curUser.getValue()).append(", ");
+ }
+ String usersString = users.substring(0, users.length() - 3);
+ privateMessageEvent.respond("Renamed users: " + usersString);
+ } else {
+ boolean isCommand = false;
+ // react to commands included in the messages
+ Matcher commandMatcher = commandPattern.matcher(message);
+ while (commandMatcher.find()) {
+ Command command = Command.valueOf(commandMatcher.group(1).toUpperCase());
+ String response = prepareResponseForCommand(command);
+ bot.sendMessage(privateMessageEvent.getUser(), response);
+ }
+ if (!isCommand) {
+ bot.sendMessage(privateMessageEvent.getUser(), "Hi, I am " + bot.getFinger() + ".\n"
+ + prepareResponseForCommand(Command.HELP));
+ }
+ }
+ }
+
+ @Override
+ public void onDisconnect(DisconnectEvent<RhqIrcBot> disconnectEvent) throws Exception {
+ boolean connected = false;
+ while (!connected) {
+ Thread.sleep(60 * 1000L); // 1 minute
+ try {
+ PircBotX newBot = new RhqIrcBot(this);
+ newBot.connect(this.server);
+ newBot.joinChannel(this.channel);
+
+ connected = true;
+ } catch (Exception e) {
+ System.err.println("Failed to reconnect to " + disconnectEvent.getBot().getServer() + " IRC server: "
+ + e);
+ }
+ }
+
+ // Try to clean up the old bot, so it can release any memory, sockets, etc. it's using.
+ PircBotX oldBot = disconnectEvent.getBot();
+ Set<Listener> oldListeners = new HashSet<Listener>(oldBot.getListenerManager().getListeners());
+ for (Listener oldListener : oldListeners) {
+ oldBot.getListenerManager().removeListener(oldListener);
+ }
+ }
+
+ @Override
+ public void onNickChange(NickChangeEvent<RhqIrcBot> event) throws Exception {
+ //Store the result
+ names.put(event.getOldNick(), event.getNewNick());
+ }
+
+ private String prepareResponseForCommand(Command command) {
+ if (command.staticRespond != null) {
+ String response = command.staticRespond;
+ if (command == Command.HELP) {
+ for (Command com : Command.values()) {
+ if (com.includeInHelp) {
+ response += Command.PREFIX + com.toString().toLowerCase() + " ";
+ }
+ }
+ }
+ return response;
+ }
+ switch (command) {
+ case SUPPORT:
+ return whoIsOnSupport(SUPPORT_LINK);
+ case PTO:
+ return whoIsOnPto(PTO_LINK);
+ default:
+ System.err.println("Unknown command:" + command);
+ break;
+ }
+ return null;
+ }
+
+ private String whoIsOnSupport(String link) {
+ if (docspaceLogin == null || docspaceLogin.isEmpty() || docspacePassword == null || docspacePassword.isEmpty()) {
+ return "This command is not supported.";
+ }
+ String month = monthFormat.format(new Date());
+ String dayInMonth = dayInMonthFormat.format(new Date());
+ int dayInMonthInt = Integer.parseInt(dayInMonth);
+ try {
+ boolean monthFound = false;
+ String login = docspaceLogin + ":" + docspacePassword;
+ String base64login = new String(Base64.encodeBase64(login.getBytes()));
+ Document doc = Jsoup.connect(link).header("Authorization", "Basic " + base64login).get();
+ Elements cells = doc.select("tr td");
+ for (Element cell : cells) {
+ String cellText = cell.text().toLowerCase();
+ if (cellText.startsWith(month.toLowerCase())) {
+ monthFound = true;
+ if (cellText.substring(cellText.length() - 1, cellText.length()).equals(dayInMonth)) {
+ return cell.firstElementSibling().text() + " is on support this week";
+ }
+ continue;
+ }
+ if (monthFound && cellText.equals(dayInMonth)) {
+ return cell.firstElementSibling().text() + " is on support this week";
+ } else if (monthFound) {
+ if (cell.equals(cell.firstElementSibling()) || cell.equals(cell.lastElementSibling())) {
+ continue; //the first row with name or the last row with a comment
+ }
+ int day = -1;
+ try {
+ day = Integer.parseInt(cellText);
+ if (day > dayInMonthInt) {
+ return cell.parent().previousElementSibling().child(0).text() + " is on support this week";
+ }
+ } catch (NumberFormatException nfe) {
+ break; // next month
+ }
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ // fallback solution if SSL is not set correctly
+ String randomDevel = JON_DEVS.toArray(new String[JON_DEVS.size()])[new Random().nextInt(JON_DEVS.size())];
+ return "404 Developer Not Found, selecting randomly " + randomDevel + ". Check the " + SUPPORT_LINK;
+ }
+
+ private static String whoIsOnPto(String link) {
+ String month = monthFormat.format(new Date());
+ String dayInMonth = dayInMonthFormat.format(new Date());
+ try {
+ String onPto = "";
+ Document doc = Jsoup.connect(link).ignoreContentType(true).get();
+ Elements dates = doc.getElementsContainingOwnText(dayInMonth + " " + month);
+ for (Element date : dates) {
+ onPto += date.firstElementSibling().text() + ", ";
+ }
+ if (!onPto.isEmpty()) {
+ return onPto.substring(0, onPto.length() - 2);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return "noone is on PTO today";
+ }
+
+ public void setDocspaceLogin(String docspaceLogin) {
+ this.docspaceLogin = docspaceLogin;
+ }
+
+ public void setDocspacePassword(String docspacePassword) {
+ this.docspacePassword = docspacePassword;
+ }
+}
diff --git a/etc/rhq-ircBot/src/main/resources/org/rhq/etc/ircbot/cacerts.jks b/etc/rhq-ircBot/src/main/resources/org/rhq/etc/ircbot/cacerts.jks
new file mode 100644
index 0000000..3d73cbc
Binary files /dev/null and b/etc/rhq-ircBot/src/main/resources/org/rhq/etc/ircbot/cacerts.jks differ
diff --git a/etc/rhq-ircBot/src/main/resources/org/rhq/etc/ircbot/rhq-ircbot.properties b/etc/rhq-ircBot/src/main/resources/org/rhq/etc/ircbot/rhq-ircbot.properties
new file mode 100644
index 0000000..25e325c
--- /dev/null
+++ b/etc/rhq-ircBot/src/main/resources/org/rhq/etc/ircbot/rhq-ircbot.properties
@@ -0,0 +1,2 @@
+docspace_login=
+docspace_password=
commit 9e8ad4a6e486943bbdac74e3c5fe7524a0a1cb03
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed May 22 14:12:32 2013 +0200
Enable paging on (some) endpoints that return lists
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java
index 0038099..8e4a826 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java
@@ -59,6 +59,8 @@ import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.group.GroupCategory;
import org.rhq.core.domain.resource.group.ResourceGroup;
+import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.resource.ResourceManagerLocal;
import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal;
import org.rhq.enterprise.server.rest.domain.GroupRest;
@@ -419,6 +421,53 @@ public class AbstractRestBean {
}
/**
+ * Create the paging headers for collections and attach them to the passed builder. Those are represented as
+ * <i>Link:</i> http headers that carry the URL for the pages and the respective relation.
+ * <br/>In addition a <i>X-total-size</i> header is created that contains the whole collection size.
+ * @param builder The ResponseBuilder that receives the headers
+ * @param uriInfo The uriInfo of the incoming request to build the urls
+ * @param resultList The collection with its paging information
+ */
+ protected void createPagingHeader(final Response.ResponseBuilder builder, final UriInfo uriInfo, final PageList<?> resultList) {
+
+ UriBuilder uriBuilder;
+
+ PageControl pc = resultList.getPageControl();
+ int page = pc.getPageNumber();
+
+ if (resultList.getTotalSize()> (pc.getPageNumber() +1 ) * pc.getPageSize()) {
+ int nextPage = page+1;
+ uriBuilder = uriInfo.getRequestUriBuilder(); // adds ?q, ?ps and ?category if needed
+ uriBuilder.replaceQueryParam("page",nextPage);
+
+ builder.header("Link",new Link("next",uriBuilder.build().toString()));
+ }
+
+ if (page>0) {
+ int prevPage = page -1;
+ uriBuilder = uriInfo.getRequestUriBuilder(); // adds ?q, ?ps and ?category if needed
+ uriBuilder.replaceQueryParam("page",prevPage);
+ builder.header("Link", new Link("prev",uriBuilder.build().toString()));
+ }
+
+ // A link to the last page
+ if (!pc.isUnlimited()) {
+ int lastPage = resultList.getTotalSize() / pc.getPageSize();
+ uriBuilder = uriInfo.getRequestUriBuilder(); // adds ?q, ?ps and ?category if needed
+ uriBuilder.replaceQueryParam("page",lastPage);
+ builder.header("Link", new Link("last",uriBuilder.build().toString()));
+ }
+
+ // A link to the current page
+ uriBuilder = uriInfo.getRequestUriBuilder(); // adds ?q, ?ps and ?category if needed
+ builder.header("Link", new Link("current",uriBuilder.build().toString()));
+
+
+ // Create a total size header
+ builder.header("X-collection-size",resultList.getTotalSize());
+ }
+
+ /**
* Fetch the group with the passed id
*
* @param groupId id of the resource group
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java
index d203cd3..6ea3d03 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java
@@ -77,6 +77,7 @@ import org.rhq.core.domain.criteria.AlertDefinitionCriteria;
import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.group.ResourceGroup;
+import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.alert.AlertConditionManagerLocal;
import org.rhq.enterprise.server.alert.AlertDefinitionManagerLocal;
@@ -143,21 +144,31 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean {
@GZIP
@GET
@Path("/definitions")
- @ApiOperation("List all Alert Definition")
- public List<AlertDefinitionRest> listAlertDefinitions(
- @ApiParam(value = "Page number", defaultValue = "0") @QueryParam("page") int page,
- @ApiParam(value = "Limit to status, UNUSED AT THE MOMENT ") @QueryParam("status") String status,
+ @ApiOperation(value = "List all Alert Definition", responseClass = "AlertDefinitionRest", multiValueResponse = true)
+ public Response listAlertDefinitions(
+ @ApiParam(value = "Page number") @QueryParam("page") Integer page,
+ @ApiParam(value = "Page size") @DefaultValue("20") @QueryParam("ps") int pageSize,
+ @ApiParam(value = "Limit to status, UNUSED AT THE MOMENT ") @QueryParam("status") String status, // TODO
@Context UriInfo uriInfo) {
AlertDefinitionCriteria criteria = new AlertDefinitionCriteria();
- criteria.setPaging(page,20); // TODO add link to next page
- List<AlertDefinition> defs = alertDefinitionManager.findAlertDefinitionsByCriteria(caller, criteria);
+ if (page!=null) {
+ criteria.setPaging(page,pageSize);
+ }
+
+ PageList<AlertDefinition> defs = alertDefinitionManager.findAlertDefinitionsByCriteria(caller, criteria);
List<AlertDefinitionRest> ret = new ArrayList<AlertDefinitionRest>(defs.size());
for (AlertDefinition def : defs) {
AlertDefinitionRest adr = definitionToDomain(def, false, uriInfo);
ret.add(adr);
}
- return ret;
+
+ Response.ResponseBuilder builder = Response.ok(ret);
+ createPagingHeader(builder,uriInfo,defs);
+
+ // TODO media type etc
+
+ return builder.build();
}
@GET
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertHandlerBean.java
index 4c80bd1..5da3fb9 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertHandlerBean.java
@@ -90,10 +90,10 @@ public class AlertHandlerBean extends AbstractRestBean {
@ApiErrors({
@ApiError(code = 406, reason = "There are 'resourceId' and 'definitionId' passed as query parameters"),
@ApiError(code = 406, reason = "Page size was 0"),
- @ApiError(code = 406, reason = "Page number was < 1")
+ @ApiError(code = 406, reason = "Page number was < 0")
})
public Response listAlerts(
- @ApiParam(value = "Page number") @QueryParam("page") @DefaultValue("1") int page,
+ @ApiParam(value = "Page number") @QueryParam("page") @DefaultValue("0") int page,
@ApiParam(value = "Page size; use -1 for 'unlimited'") @QueryParam("size") @DefaultValue("100")int size,
@ApiParam(value = "Limit to priority", allowableValues = "High, Medium, Low, All") @DefaultValue("All") @QueryParam("prio") String prio,
@ApiParam(value = "Should full resources and definitions be sent") @QueryParam("slim") @DefaultValue("false") boolean slim,
@@ -108,7 +108,7 @@ public class AlertHandlerBean extends AbstractRestBean {
if (size==0) {
throw new BadArgumentException("size","Must not be 0");
}
- if (page<1) {
+ if (page<0) {
throw new BadArgumentException("page","Must be >=1");
}
@@ -120,7 +120,7 @@ public class AlertHandlerBean extends AbstractRestBean {
criteria.setPageControl(pageControl);
}
else {
- criteria.setPaging(page-1, size); // TODO implement linking to next page
+ criteria.setPaging(page, size);
}
if (since!=null) {
@@ -157,6 +157,8 @@ public class AlertHandlerBean extends AbstractRestBean {
builder = Response.ok(entity);
}
+ createPagingHeader(builder,uriInfo,alerts);
+
return builder.build();
}
@@ -306,7 +308,7 @@ public class AlertHandlerBean extends AbstractRestBean {
@DELETE
@Path("/{id}")
- @ApiOperation(value = "Remove the alert from the lit of alerts")
+ @ApiOperation(value = "Remove the alert from the list of alerts")
public void purgeAlert(@ApiParam(value = "Id of the alert to remove") @PathParam("id") int id) {
alertManager.deleteAlerts(caller, new int[]{id});
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/EventHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/EventHandlerBean.java
index becb680..7402550 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/EventHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/EventHandlerBean.java
@@ -32,6 +32,7 @@ import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
@@ -44,6 +45,7 @@ import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiError;
@@ -61,6 +63,7 @@ import org.rhq.core.domain.event.EventSource;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.event.EventManagerLocal;
import org.rhq.enterprise.server.rest.domain.EventDefinitionRest;
@@ -227,9 +230,19 @@ public class EventHandlerBean extends AbstractRestBean {
@QueryParam("endTime") long endTime,
@ApiParam(value="Select the severity to display. Default is to show all",
allowableValues = "DEBUG, INFO, WARN, ERROR, FATAL") @QueryParam("severity") String severity,
- @Context Request request,
+ @ApiParam("Page size for paging") @QueryParam("ps") @DefaultValue("20") int pageSize,
+ @ApiParam("Page for paging, 0-based") @QueryParam("page") Integer page,
+ @Context UriInfo uriInfo,
@Context HttpHeaders headers) {
+ if (severity!=null) {
+ try {
+ EventSeverity.valueOf(severity.toUpperCase());
+ } catch (Exception e) {
+ throw new BadArgumentException("severity",severity + " is bad. Allowed values are DEBUG, INFO, WARN, ERROR, FATAL");
+ }
+ }
+
EventSource source = findEventSourceById(sourceId);
EventCriteria criteria = new EventCriteria();
@@ -240,13 +253,19 @@ public class EventHandlerBean extends AbstractRestBean {
if (endTime>0) {
criteria.addFilterEndTime(endTime);
}
- if (startTime==0 && endTime==0) {
+ if (page!=null) {
+ criteria.setPaging(page,pageSize);
+ }
+ else if (startTime==0 && endTime==0) {
PageControl pageControl = new PageControl();
pageControl.setPageSize(200);
criteria.setPageControl(pageControl);
}
+ if (severity!=null) {
+ criteria.addFilterSeverities(EventSeverity.valueOf(severity.toUpperCase()));
+ }
- Response.ResponseBuilder builder = getEventsAsBuilderForCriteria(headers, criteria);
+ Response.ResponseBuilder builder = getEventsAsBuilderForCriteria(headers, criteria, uriInfo);
return builder.build();
}
@@ -259,10 +278,21 @@ public class EventHandlerBean extends AbstractRestBean {
public Response getEventsForResource(@PathParam("id") int resourceId,
@QueryParam("startTime") long startTime,
@QueryParam("endTime") long endTime,
- @QueryParam("severity") String severity,
- @Context Request request,
+ @ApiParam("Page size for paging") @QueryParam("ps") @DefaultValue("20") int pageSize,
+ @ApiParam("Page for paging, 0-based") @QueryParam("page") Integer page,
+ @ApiParam(value="Select the severity to display. Default is to show all",
+ allowableValues = "DEBUG, INFO, WARN, ERROR, FATAL") @QueryParam("severity") String severity,
+ @Context UriInfo uriInfo,
@Context HttpHeaders headers) {
+ if (severity!=null) {
+ try {
+ EventSeverity.valueOf(severity.toUpperCase());
+ } catch (Exception e) {
+ throw new BadArgumentException("severity",severity + " is bad. Allowed values are DEBUG, INFO, WARN, ERROR, FATAL");
+ }
+ }
+
EventCriteria criteria = new EventCriteria();
criteria.addFilterResourceId(resourceId);
if (startTime>0) {
@@ -271,13 +301,19 @@ public class EventHandlerBean extends AbstractRestBean {
if (endTime>0) {
criteria.addFilterEndTime(endTime);
}
- if (startTime==0 && endTime==0) {
+ if (page!=null) {
+ criteria.setPaging(page,pageSize);
+ }
+ else if (startTime==0 && endTime==0) {
PageControl pageControl = new PageControl();
pageControl.setPageSize(200);
criteria.setPageControl(pageControl);
}
+ if (severity!=null) {
+ criteria.addFilterSeverities(EventSeverity.valueOf(severity.toUpperCase()));
+ }
- Response.ResponseBuilder builder = getEventsAsBuilderForCriteria(headers, criteria);
+ Response.ResponseBuilder builder = getEventsAsBuilderForCriteria(headers, criteria, uriInfo);
return builder.build();
@@ -304,8 +340,8 @@ public class EventHandlerBean extends AbstractRestBean {
}
- private Response.ResponseBuilder getEventsAsBuilderForCriteria(HttpHeaders headers, EventCriteria criteria) {
- List<Event> eventList = eventManager.findEventsByCriteria(caller, criteria);
+ private Response.ResponseBuilder getEventsAsBuilderForCriteria(HttpHeaders headers, EventCriteria criteria, UriInfo uriInfo) {
+ PageList<Event> eventList = eventManager.findEventsByCriteria(caller, criteria);
List<EventRest> restEvents = new ArrayList<EventRest>(eventList.size());
for (Event event : eventList) {
restEvents.add(convertEvent(event));
@@ -320,6 +356,9 @@ public class EventHandlerBean extends AbstractRestBean {
else {
builder = Response.ok(restEvents, mediaType);
}
+
+ createPagingHeader(builder,uriInfo,eventList);
+
return builder;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/GroupHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/GroupHandlerBean.java
index 6791bdf..be2419b 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/GroupHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/GroupHandlerBean.java
@@ -116,12 +116,17 @@ public class GroupHandlerBean extends AbstractRestBean {
@Path("/")
@ApiOperation(value = "List all groups", multiValueResponse = true, responseClass = "GroupRest")
public Response getGroups(@ApiParam("String to search in the group name") @QueryParam("q") String q,
+ @ApiParam("Page size for paging") @QueryParam("ps") @DefaultValue("20") int pageSize,
+ @ApiParam("Page for paging, 0-based") @QueryParam("page") Integer page,
@Context HttpHeaders headers, @Context UriInfo uriInfo) {
ResourceGroupCriteria criteria = new ResourceGroupCriteria();
if (q!=null) {
criteria.addFilterName(q);
}
+ if (page!=null) {
+ criteria.setPaging(page,pageSize);
+ }
PageList<ResourceGroup> groups = resourceGroupManager.findResourceGroupsByCriteria(caller, criteria);
@@ -142,6 +147,8 @@ public class GroupHandlerBean extends AbstractRestBean {
builder.entity(ret);
}
+ createPagingHeader(builder,uriInfo,groups);
+
return builder.build();
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java
index 8bc2cb9..e32ea03 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/OperationsHandlerBean.java
@@ -29,6 +29,7 @@ import javax.ejb.Stateless;
import javax.interceptor.Interceptors;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
@@ -353,7 +354,6 @@ public class OperationsHandlerBean extends AbstractRestBean {
public Response outcome(
@ApiParam("Name of the submitted job.") @PathParam("id") String jobName,
@Context UriInfo uriInfo,
- @Context Request request,
@Context HttpHeaders httpHeaders) {
MediaType mediaType = httpHeaders.getAcceptableMediaTypes().get(0);
@@ -395,21 +395,26 @@ public class OperationsHandlerBean extends AbstractRestBean {
@Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML,MediaType.TEXT_HTML})
public Response listHistory(
@ApiParam("Id of a resource to limit to") @QueryParam("resourceId") int resourceId,
+ @ApiParam("Page size for paging") @QueryParam("ps") @DefaultValue("20") int pageSize,
+ @ApiParam("Page for paging, 0-based") @QueryParam("page") Integer page,
@Context UriInfo uriInfo,
- @Context Request request,
@Context HttpHeaders httpHeaders) {
ResourceOperationHistoryCriteria criteria = new ResourceOperationHistoryCriteria();
if (resourceId>0) {
criteria.addFilterResourceIds(resourceId);
}
+ if (page!=null) {
+ criteria.setPaging(page,pageSize);
+ criteria.addSortStartTime(PageOrdering.ASC);
+ }
criteria.addSortEndTime(PageOrdering.DESC);
- PageList<ResourceOperationHistory> list = opsManager.findResourceOperationHistoriesByCriteria(caller, criteria);
+ PageList<ResourceOperationHistory> histories = opsManager.findResourceOperationHistoriesByCriteria(caller, criteria);
List<OperationHistoryRest> result = new ArrayList<OperationHistoryRest>();
- for (ResourceOperationHistory roh : list) {
+ for (ResourceOperationHistory roh : histories) {
OperationHistoryRest historyRest = historyToHistoryRest(roh,uriInfo);
result.add(historyRest);
}
@@ -422,6 +427,9 @@ public class OperationsHandlerBean extends AbstractRestBean {
GenericEntity<List<OperationHistoryRest>> res = new GenericEntity<List<OperationHistoryRest>>(result) {};
builder = Response.ok(res);
}
+
+ createPagingHeader(builder,uriInfo,histories);
+
return builder.build();
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java
index 70cc588..a783ac8 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java
@@ -211,7 +211,7 @@ public class ResourceHandlerBean extends AbstractRestBean {
}
PageList<Resource> ret = resMgr.findResourcesByCriteria(caller,criteria);
- Response.ResponseBuilder builder = getResponseBuilderForResourceList(headers,uriInfo,ret, page, pageSize);
+ Response.ResponseBuilder builder = getResponseBuilderForResourceList(headers,uriInfo,ret);
return builder.build();
}
@@ -221,13 +221,22 @@ public class ResourceHandlerBean extends AbstractRestBean {
@Path("/platforms")
@Cache(isPrivate = true,maxAge = 300)
@ApiOperation(value = "List all platforms in the system", multiValueResponse = true, responseClass = "ResourceWithType")
- public Response getPlatforms(@Context HttpHeaders headers,
- @Context UriInfo uriInfo) {
+ public Response getPlatforms(
+ @ApiParam("Page size for paging") @QueryParam("ps") @DefaultValue("20") int pageSize,
+ @ApiParam("Page for paging, 0-based") @QueryParam("page") Integer page,
+ @Context HttpHeaders headers, @Context UriInfo uriInfo) {
+
+ PageControl pc;
+ if (page!=null) {
+ pc = new PageControl(page,pageSize);
+ }
+ else {
+ pc = PageControl.getUnlimitedInstance();
+ }
- PageControl pc = new PageControl();
PageList<Resource> ret = resMgr.findResourcesByCategory(caller, ResourceCategory.PLATFORM,
InventoryStatus.COMMITTED, pc);
- Response.ResponseBuilder builder = getResponseBuilderForResourceList(headers, uriInfo, ret, null, 20);
+ Response.ResponseBuilder builder = getResponseBuilderForResourceList(headers, uriInfo, ret);
return builder.build();
}
@@ -239,13 +248,10 @@ public class ResourceHandlerBean extends AbstractRestBean {
* @param headers HttpHeaders from the request
* @param uriInfo Uri from the request
* @param resources List of resources
- * @param page Page of pageSize. If null, paging is ignored
- * @param pageSize number of elements on a page
* @return An initialized ResponseBuilder
*/
private Response.ResponseBuilder getResponseBuilderForResourceList(HttpHeaders headers, UriInfo uriInfo,
- PageList<Resource> resources, Integer page,
- int pageSize) {
+ PageList<Resource> resources) {
List<ResourceWithType> rwtList = new ArrayList<ResourceWithType>(resources.size());
for (Resource r : resources) {
putToCache(r.getId(), Resource.class, r);
@@ -256,25 +262,8 @@ public class ResourceHandlerBean extends AbstractRestBean {
MediaType mediaType = headers.getAcceptableMediaTypes().get(0);
Response.ResponseBuilder builder = Response.ok();
builder.type(mediaType);
- UriBuilder uriBuilder;
- if (page!=null) {
- // TODO look a the page control and check if there is a next page at all
- if (resources.getTotalSize()> page*pageSize) {
- int nextPage = page+1;
- uriBuilder = uriInfo.getRequestUriBuilder(); // adds ?q, ?ps and ?category if needed
- uriBuilder.replaceQueryParam("page",nextPage);
-
- builder.header("Link",new Link("next",uriBuilder.build().toString()));
- }
-
- if (page>1) {
- int prevPage = page -1;
- uriBuilder = uriInfo.getRequestUriBuilder(); // adds ?q, ?ps and ?category if needed
- uriBuilder.replaceQueryParam("page",prevPage);
- builder.header("prev",uriBuilder.build().toString());
- }
- }
+ createPagingHeader(builder,uriInfo,resources);
if (mediaType.equals(MediaType.TEXT_HTML_TYPE)) {
builder.entity(renderTemplate("listResourceWithType", rwtList));
@@ -294,7 +283,7 @@ public class ResourceHandlerBean extends AbstractRestBean {
@ApiError(code = 404, reason = NO_RESOURCE_FOR_ID)
public ResourceWithChildren getHierarchy(@ApiParam("Id of the resource to start with") @PathParam("id")int baseResourceId) {
// TODO optimize to do less recursion
- Resource start = obtainResource(baseResourceId);
+ Resource start = fetchResource(baseResourceId);
return getHierarchy(start);
}
@@ -425,7 +414,7 @@ public class ResourceHandlerBean extends AbstractRestBean {
if (avail.getResourceId() != resourceId)
throw new IllegalArgumentException("Resource Ids do not match");
- Resource resource = obtainResource(resourceId);
+ Resource resource = fetchResource(resourceId);
AvailabilityType at;
at = AvailabilityType.valueOf(avail.getType());
@@ -541,15 +530,6 @@ public class ResourceHandlerBean extends AbstractRestBean {
}
- private Resource obtainResource(int resourceId) {
- Resource resource = resMgr.getResource(caller, resourceId);
- if (resource == null) {
- resource = resMgr.getResource(caller, resourceId);
- if (resource != null)
- putToCache(resourceId, Resource.class, resource);
- }
- return resource;
- }
@GZIP
@AddLinks
@@ -565,7 +545,7 @@ public class ResourceHandlerBean extends AbstractRestBean {
criteria.addFilterResourceIds(resourceId);
- List<Alert> alerts = alertManager.findAlertsByCriteria(caller, criteria);
+ PageList<Alert> alerts = alertManager.findAlertsByCriteria(caller, criteria);
List<Link> links = new ArrayList<Link>(alerts.size());
for (Alert al : alerts) {
Link link = new Link();
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationHelperTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationHelperTest.java
index 3a7e961..7e20630 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationHelperTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationHelperTest.java
@@ -703,7 +703,7 @@ public class ConfigurationHelperTest {
}
- @Test(enabled = false)
+ @Test
public void testConfigToMapComplexMapWithBadSetupLenient() throws Exception {
Configuration config = new Configuration();
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AlertTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AlertTest.java
index fca0f50..e02a723 100644
--- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AlertTest.java
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AlertTest.java
@@ -23,6 +23,7 @@ import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.path.xml.XmlPath;
import com.jayway.restassured.response.Response;
+import org.hamcrest.Matchers;
import org.junit.Test;
import org.rhq.modules.integrationTests.restApi.d.AlertCondition;
@@ -34,7 +35,10 @@ import org.rhq.modules.integrationTests.restApi.d.Group;
import static com.jayway.restassured.RestAssured.delete;
import static com.jayway.restassured.RestAssured.expect;
import static com.jayway.restassured.RestAssured.given;
+import static org.hamcrest.CoreMatchers.anyOf;
+import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.emptyIterable;
import static org.hamcrest.Matchers.instanceOf;
@@ -54,6 +58,7 @@ public class AlertTest extends AbstractBase {
.header(acceptJson)
.expect()
.statusCode(200)
+ .log().ifError()
.when()
.get("/alert");
@@ -66,6 +71,7 @@ public class AlertTest extends AbstractBase {
.header(acceptXml)
.expect()
.statusCode(200)
+ .log().ifError()
.when()
.get("/alert");
}
@@ -95,6 +101,23 @@ public class AlertTest extends AbstractBase {
}
@Test
+ public void testListAlertsWithPaging() throws Exception {
+
+ given()
+ .header(acceptJson)
+ .queryParam("ps", 2)
+ .queryParam("page", 0)
+ .expect()
+ .statusCode(200)
+ .header("Link", anyOf(containsString("current"), Matchers.containsString("last")))
+ .header("X-collection-size", notNullValue())
+ .log().ifError()
+ .when()
+ .get("/alert");
+ }
+
+
+ @Test
public void testGetAlertCountJson() throws Exception {
given()
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/EventTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/EventTest.java
index 2e74181..40ae7b0 100644
--- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/EventTest.java
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/EventTest.java
@@ -23,13 +23,17 @@ import java.util.List;
import java.util.Map;
import com.jayway.restassured.http.ContentType;
+import com.jayway.restassured.response.Headers;
import com.jayway.restassured.response.Response;
+import org.hamcrest.CoreMatchers;
import org.junit.Test;
import org.rhq.modules.integrationTests.restApi.d.Event;
import org.rhq.modules.integrationTests.restApi.d.EventSource;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.not;
import static com.jayway.restassured.RestAssured.given;
/**
@@ -261,6 +265,131 @@ public class EventTest extends AbstractBase {
}
@Test
+ public void testAddGetEventOnSourceWithPaging() throws Exception {
+
+ EventSource es = new EventSource();
+ es.setResourceId(_platformId);
+ es.setName("Event Log"); // Name of the event definition
+ es.setLocation("-x-test-location");
+
+ Response response =
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .pathParam("id",_platformId)
+ .body(es)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .post("/event/{id}/sources");
+
+ EventSource eventSource = response.as(EventSource.class);
+
+ long now = System.currentTimeMillis();
+ try {
+
+ // Add an event
+ Event event = new Event(eventSource.getId(),now,"Li la lu 1:->");
+ Event event1 = new Event(eventSource.getId(),now,"Li la lu 2:->");
+ Event event2 = new Event(eventSource.getId(),now,"Li la lu 3:->");
+ Event event3 = new Event(eventSource.getId(),now,"Li la lu 4:->");
+ List<Event> events = new ArrayList<Event>(4);
+ events.add(event);
+ events.add(event1);
+ events.add(event2);
+ events.add(event3);
+
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .pathParam("id",eventSource.getId())
+ .body(events)
+ .expect()
+ .statusCode(204) // no content returned
+ .log().ifError()
+ .when()
+ .post("/event/source/{id}/events");
+
+
+ // and retrieve it again from the event source
+ response =
+ given()
+ .header(acceptJson)
+ .pathParam("id", eventSource.getId())
+ .queryParam("startTime",now - 10)
+ .queryParam("endTime",now + 10)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .header("X-collection-size", CoreMatchers.is("4"))
+ .when()
+ .get("/event/source/{id}/events");
+ List list = response.as(List.class);
+ assert list.size()>0;
+
+ // Get the list of events from the resource
+ response =
+ given()
+ .header(acceptJson)
+ .pathParam("id", _platformId)
+ .queryParam("startTime",now - 10)
+ .queryParam("endTime",now + 10)
+ .queryParam("page",0)
+ .queryParam("ps",2)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .header("X-collection-size", CoreMatchers.is("4"))
+ .header("Link",not(containsString("prev")))
+ .when()
+ .get("/event/{id}/events");
+ list = response.as(List.class);
+ assert list.size()==2;
+
+ response =
+ given()
+ .header(acceptJson)
+ .pathParam("id", _platformId)
+ .queryParam("startTime",now - 10)
+ .queryParam("endTime",now + 10)
+ .queryParam("page",1)
+ .queryParam("ps",2)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .header("X-collection-size", CoreMatchers.is("4"))
+ .header("Link",not(containsString("next")))
+ .when()
+ .get("/event/{id}/events");
+
+ Headers headers = response.getHeaders();
+ int found = 0;
+ for (String link: headers.getValues("Link")) {
+ if (link.contains("rel='last'"))
+ found++;
+ if (link.contains("rel='prev'"))
+ found++;
+ if (link.contains("rel='current'"))
+ found++;
+ assert !link.contains("rel='next");
+ }
+ assert found == 3;
+
+ }
+ finally {
+
+ // Delete the source again
+ given()
+ .pathParam("id", eventSource.getId())
+ .expect()
+ .statusCode(204)
+ .when()
+ .delete("/event/source/{id}");
+ }
+ }
+
+ @Test
public void testDeleteUnknownSource() throws Exception {
given()
.pathParam("id", 123)
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/GroupTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/GroupTest.java
index 05bae96..a4ef048 100644
--- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/GroupTest.java
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/GroupTest.java
@@ -74,6 +74,17 @@ public class GroupTest extends AbstractBase {
}
@Test
+ public void testGetGroupsWithPaging() throws Exception {
+ given()
+ .queryParam("page",0)
+ .queryParam("ps",2)
+ .expect()
+ .statusCode(200)
+ .when()
+ .get("/group");
+ }
+
+ @Test
public void testGetGroupsQuery() throws Exception {
given()
.queryParam("q","lala")
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java
index 23480a0..b66d9b5 100644
--- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java
@@ -44,6 +44,8 @@ import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.Matchers.anyOf;
+import static org.hamcrest.Matchers.not;
/**
* Test the resources part
@@ -242,7 +244,7 @@ public class ResourcesTest extends AbstractBase {
}
@Test
- public void testPaging() throws Exception {
+ public void testGetResourcesWithPaging() throws Exception {
given()
.header("Accept", "application/json")
@@ -252,12 +254,31 @@ public class ResourcesTest extends AbstractBase {
.queryParam("category", "service")
.expect()
.statusCode(200)
- .header("Link", containsString("page=2"))
+ .log().everything()
+ // .header("Link", allOf(containsString("page=2"), containsString("current")))
+ .header("Link",not(containsString("prev")))
.body("links.self", notNullValue())
.when().get("/resource");
}
@Test
+ public void testGetPlatformsWithPaging() throws Exception {
+
+ given()
+ .header("Accept", "application/json")
+ .with()
+ .queryParam("page", 0)
+ .queryParam("ps", 5)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .body("links.self", notNullValue())
+ .header("Link", not(containsString("prev=")))
+ .header("Link", anyOf(containsString("current"),containsString("last")))
+ .when().get("/resource/platforms");
+ }
+
+ @Test
public void testGetPlatformXml() {
assert _platformId!=0 : "Setup did not run or was no success";
commit 83313b3c1d93ed5ae481ab1603a940223c9ab199
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue May 21 22:10:26 2013 +0200
BZ 962853 - make getRresourceId return an int instead of a string.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/ResourceWithType.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/ResourceWithType.java
index 703e897..8273737 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/ResourceWithType.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/ResourceWithType.java
@@ -25,19 +25,11 @@ package org.rhq.enterprise.server.rest.domain;
import java.util.ArrayList;
import java.util.List;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementRef;
-import javax.xml.bind.annotation.XmlID;
import javax.xml.bind.annotation.XmlRootElement;
import com.wordnik.swagger.annotations.ApiClass;
import com.wordnik.swagger.annotations.ApiProperty;
-import org.jboss.resteasy.spi.touri.URITemplate;
-
/**
* A (partial) resource with some type information
* @author Heiko W. Rupp
@@ -69,7 +61,6 @@ public class ResourceWithType {
}
@ApiProperty("Name of the resource")
- @XmlElement
public String getResourceName() {
return resourceName;
}
@@ -79,17 +70,15 @@ public class ResourceWithType {
}
@ApiProperty("ID of the resource")
- @XmlID
- public String getResourceId() {
- return String.valueOf(resourceId);
+ public int getResourceId() {
+ return resourceId;
}
public void setResourceId(int resourceId) {
this.resourceId = resourceId;
}
- @ApiProperty("Name of the resource type of teh resource")
- @XmlElement
+ @ApiProperty("Name of the resource type of the resource")
public String getTypeName() {
return typeName;
}
@@ -99,7 +88,6 @@ public class ResourceWithType {
}
@ApiProperty("Id of the resource type of the resource")
- @XmlElement
public Integer getTypeId() {
return typeId;
}
@@ -109,7 +97,6 @@ public class ResourceWithType {
}
@ApiProperty("Name of the plugin defining the resource type")
- @XmlElement
public String getPluginName() {
return pluginName;
}
@@ -136,7 +123,6 @@ public class ResourceWithType {
this.status = status;
}
- @XmlElementRef
public List<Link> getLinks() {
return links;
}
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AbstractBase.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AbstractBase.java
index 9f6a02b..ae4e81d 100644
--- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AbstractBase.java
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AbstractBase.java
@@ -98,8 +98,7 @@ public abstract class AbstractBase {
if (res!=null && res.get(0)!=null) {
- String tmp = ((Map <String,String>)res.get(0)).get("resourceId");
- int pid =Integer.valueOf(tmp);
+ Integer pid = ((Map <String,Integer>)res.get(0)).get("resourceId");
given()
.pathParam("id", pid)
@@ -125,9 +124,9 @@ public abstract class AbstractBase {
assert res != null;
for (Object entry : res) {
if (entry instanceof Map) {
- Map<String,String> map = (Map<String, String>) entry;
+ Map<String,Object> map = (Map<String, Object>) entry;
if (!map.get("resourceName").equals(REST_TEST_DUMMY)) {
- return Integer.valueOf(map.get("resourceId"));
+ return (Integer)map.get("resourceId");
}
}
}
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ContentTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ContentTest.java
index 7e3f45a..3515fac 100644
--- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ContentTest.java
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ContentTest.java
@@ -30,6 +30,7 @@ import com.jayway.restassured.response.Response;
import org.junit.Test;
import org.rhq.modules.integrationTests.restApi.d.CreateCBRRequest;
+import org.rhq.modules.integrationTests.restApi.d.Resource;
import static com.jayway.restassured.RestAssured.given;
import static org.hamcrest.Matchers.*;
@@ -41,6 +42,8 @@ import static org.hamcrest.Matchers.isOneOf;
*/
public class ContentTest extends AbstractBase {
+ private static final String DEPLOYED_WAR_NAME = "test-simple.war";
+
@Test
public void testUpload() throws Exception {
@@ -144,6 +147,8 @@ public class ContentTest extends AbstractBase {
@Test
public void testCreatePackageBasedResource() throws Exception {
+ wipeWarArchiveIfNecessary();
+
InputStream in =
getClass().getClassLoader().getResourceAsStream("test-simple.war");
@@ -187,7 +192,7 @@ public class ContentTest extends AbstractBase {
assert resources.size()>0;
- int as7Id = Integer.valueOf((String)resources.get(0).get("resourceId"));
+ int as7Id = (Integer)resources.get(0).get("resourceId");
int createdResourceId=-1;
// create child of eap6 as deployment
@@ -203,7 +208,7 @@ public class ContentTest extends AbstractBase {
// set plugin config (path) and deploy config (runtime-name)
resource.getPluginConfig().put("path","deployment");
- resource.getResourceConfig().put("runtimeName","test-simple.war");
+ resource.getResourceConfig().put("runtimeName", DEPLOYED_WAR_NAME);
Response response =
given()
@@ -285,6 +290,34 @@ public class ContentTest extends AbstractBase {
}
+
+ private void wipeWarArchiveIfNecessary() {
+
+ @SuppressWarnings("unchecked")
+ List<Resource> resources =
+ given()
+ .queryParam("q",DEPLOYED_WAR_NAME)
+ .queryParam("category", "SERVICE")
+ .header(acceptJson)
+ .expect()
+ .log().everything()
+ .when()
+ .get("/resource")
+ .as(List.class);
+
+ if (resources!=null && resources.size()>0) {
+ int resourceId = resources.get(0).getResourceId();
+
+ given()
+ .pathParam("id", resourceId)
+ .queryParam("physical", "true") // Also remove target on the EAP instance
+ .expect()
+ .statusCode(200)
+ .when()
+ .delete("/resource/{id}");
+ }
+ }
+
@Test
public void testCreateCBRBadHandle() throws Exception {
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java
index cc9558b..23480a0 100644
--- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java
@@ -69,8 +69,11 @@ public class ResourcesTest extends AbstractBase {
.expect()
.statusCode(200)
.contentType(ContentType.JSON)
- .log().ifError()
+ .log().everything()
.body("links.self", notNullValue())
+ .body("resourceId",is(_platformId))
+ .body("typeId",is(_platformTypeId))
+ .body("parentId",is(0))
.when()
.get("/resource/{id}");
@@ -101,9 +104,9 @@ public class ResourcesTest extends AbstractBase {
.log().everything()
.expect()
.statusCode(200)
- .body("id",is(typeId))
- .body("name",is("Linux"))
- .body("pluginName",is("Platforms"))
+ .body("id", is(typeId))
+ .body("name", is("Linux"))
+ .body("pluginName", is("Platforms"))
.log().everything()
.when()
.get("/resource/type/{typeId}");
@@ -187,7 +190,7 @@ public class ResourcesTest extends AbstractBase {
given()
.header("Accept", "application/json")
.with()
- .queryParam("status","NeW")
+ .queryParam("status", "NeW")
.expect()
.statusCode(200)
.when()
@@ -203,7 +206,7 @@ public class ResourcesTest extends AbstractBase {
.header("Accept", "application/json")
.with()
.queryParam("q", platformName)
- .queryParam("status","Frobnitz")
+ .queryParam("status", "Frobnitz")
.queryParam("category", "platform")
.expect()
.statusCode(406)
@@ -322,6 +325,26 @@ public class ResourcesTest extends AbstractBase {
}
@Test
+ public void testCreatePlatformJson() throws Exception {
+
+ Resource resource = new Resource();
+ resource.setResourceName("dummy-test");
+ resource.setTypeName("Linux");
+
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .body(resource)
+ .expect()
+ .statusCode(201)
+ .log().everything()
+ .body("resourceId",instanceOf(Number.class))
+ .when()
+ .post("/resource/platforms");
+
+ }
+
+ @Test
public void testCreatePlatformWithBadType() throws Exception {
Resource resource = new Resource();
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/UserTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/UserTest.java
index ea78d09..e7e1b9e 100644
--- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/UserTest.java
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/UserTest.java
@@ -94,7 +94,7 @@ public class UserTest extends AbstractBase {
.when()
.get("/user/favorites/resource");
JsonPath jp = r.jsonPath();
- assert jp.getList("resourceId").contains(String.valueOf(_platformId));
+ assert jp.getList("resourceId").contains(_platformId);
}
finally {
given()
@@ -131,7 +131,7 @@ public class UserTest extends AbstractBase {
.when()
.get("/user/favorites/resource");
JsonPath jp = r.jsonPath();
- assert jp.getList("resourceId").contains(String.valueOf(_platformId));
+ assert jp.getList("resourceId").contains(_platformId);
}
finally {
given()
commit 9428e4d5b27f53ec659b65a9056c7cbe56475ab1
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue May 21 21:45:23 2013 +0200
Print the failing class along with the failed field.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
index 4bb7e33..6ed7074 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
@@ -67,8 +67,8 @@ public final class CriteriaQueryGenerator {
private static final Log LOG = LogFactory.getLog(CriteriaQueryGenerator.class);
public enum AuthorizationTokenType {
- RESOURCE, // specifies the resource alias to join on for standard res-group-role-subject authorization checking
- GROUP; // specifies the group alias to join on for standard group-role-subject authorization checking
+ RESOURCE, // specifies the resource alias to join on for standard res-group-role-subject authorization checking
+ GROUP; // specifies the group alias to join on for standard group-role-subject authorization checking
}
private Criteria criteria;
@@ -333,8 +333,8 @@ public final class CriteriaQueryGenerator {
results.append("FROM ").append(className).append(' ').append(alias).append(NL);
if (countQuery == false) {
- /*
- * don't fetch in the count query to avoid: "query specified join fetching,
+ /*
+ * don't fetch in the count query to avoid: "query specified join fetching,
* but the owner of the fetched association was not present in the select list"
*/
for (String fetchField : getFetchFields(criteria)) {
@@ -383,7 +383,7 @@ public final class CriteriaQueryGenerator {
/*
* do not prefix the alias when:
- *
+ *
* 1) if the suffix is numerical, which allows us to sort by column ordinal
* 2) if the user wants full control and has explicitly chosen to disable alias prepending
*/
@@ -655,7 +655,7 @@ public final class CriteriaQueryGenerator {
} catch (RuntimeException re) {
LOG.error("Could not get JPQL translation for '" + searchExpression + "': "
+ ThrowableUtil.getAllMessages(re, true));
- throw re; // don't wrap exceptions that are already RuntimeExceptions in another RuntimeException
+ throw re; // don't wrap exceptions that are already RuntimeExceptions in another RuntimeException
} catch (Exception e) {
LOG.error("Could not get JPQL translation for '" + searchExpression + "': "
+ ThrowableUtil.getAllMessages(e, true));
@@ -694,7 +694,7 @@ public final class CriteriaQueryGenerator {
Field field = criteria.getPersistentClass().getDeclaredField(fieldName);
persistentBagFields.add(field);
} catch (NoSuchFieldException e) {
- LOG.warn("Failed to add persistent bag collection.", e);
+ LOG.warn("Failed to add persistent bag collection on class [" + criteria.getPersistentClass().getName() +"]: ", e);
}
}
@@ -703,7 +703,7 @@ public final class CriteriaQueryGenerator {
Field field = criteria.getPersistentClass().getDeclaredField(fieldName);
joinFetchFields.add(field);
} catch (NoSuchFieldException e) {
- LOG.warn("Failed to add join fetch field.", e);
+ LOG.warn("Failed to add join fetch field on class [" + criteria.getPersistentClass().getName() + "]: ", e);
}
}
@@ -741,7 +741,7 @@ public final class CriteriaQueryGenerator {
/**
* The groupBy clause can be set if and only if the projection is altered. The passed argument should not be
- * prefixed with 'group by'; that part of the query will be auto-generated if the argument is non-null. The
+ * prefixed with 'group by'; that part of the query will be auto-generated if the argument is non-null. The
* new projection must follow standard rules as they apply to statements with groupBy clauses.
*/
public void setGroupByClause(String groupByClause) {
@@ -753,7 +753,7 @@ public final class CriteriaQueryGenerator {
/**
* The having clause can be set if and only if the groupBy clause is set. The passed argument should not be
- * prefixed with 'having'; that part of the query will be auto-generated if the argument is non-null. The
+ * prefixed with 'having'; that part of the query will be auto-generated if the argument is non-null. The
* having clause must follow standard rules as they apply to statements with groupBy clauses.
*/
public void setHavingClause(String havingClause) {
commit 60a5c9d59afe3af57135d55240f099e0d7943a63
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue May 21 15:06:55 2013 -0400
add jboss logging to eclipse classpath
diff --git a/.classpath b/.classpath
index 2bd1e82..ccd357e 100644
--- a/.classpath
+++ b/.classpath
@@ -248,6 +248,7 @@
<classpathentry exported="true" kind="var" path="M2_REPO/commons-beanutils/commons-beanutils/1.7.0/commons-beanutils-1.7.0.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/taglibs/standard/1.1.2/standard-1.1.2.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/jboss-common-core/2.2.17.GA/jboss-common-core-2.2.17.GA.jar"/>
+ <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/logging/jboss-logging/3.1.2.GA/jboss-logging-3.1.2.GA.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/javax/servlet/jstl/1.1.2/jstl-1.1.2.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/struts-menu/struts-menu/2.3/struts-menu-2.3.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/junit/junit/3.8.2/junit-3.8.2.jar"/>
10 years, 11 months
[rhq] modules/common modules/enterprise
by mazz
modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/CoreJBossASClient.java | 21 ++++++++++
modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerServiceImpl.java | 3 +
2 files changed, 24 insertions(+)
New commits:
commit 2e3f2b2e2f8db3894fea0777508e79e4bf3817cd
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue May 28 14:32:14 2013 -0400
BZ 967990 the installer now turns off the admin console
diff --git a/modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/CoreJBossASClient.java b/modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/CoreJBossASClient.java
index 8cef6e1..eaf6f66 100644
--- a/modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/CoreJBossASClient.java
+++ b/modules/common/jboss-as-dmr-client/src/main/java/org/rhq/common/jbossas/client/controller/CoreJBossASClient.java
@@ -40,12 +40,33 @@ public class CoreJBossASClient extends JBossASClient {
public static final String SCANNER = "scanner";
public static final String EXTENSION = "extension";
public static final String MODULE = "module";
+ public static final String CORE_SERVICE_MGMT = "management";
+ public static final String MGMT_INTERFACE = "management-interface";
+ public static final String MGMT_INTERFACE_HTTP = "http-interface";
public CoreJBossASClient(ModelControllerClient client) {
super(client);
}
/**
+ * Allows the caller to turn on or off complete access for the app server's admin console.
+ *
+ * @param enableFlag true if the admin console enabled and visible; false if you want to prohibit all access to the admin console
+ * @throws Exception
+ */
+ public void setEnableAdminConsole(boolean enableFlag) throws Exception {
+ // /core-service=management/management-interface=http-interface/:write-attribute(name=console-enabled,value=false)
+ final Address address = Address.root()
+ .add(CORE_SERVICE, CORE_SERVICE_MGMT, MGMT_INTERFACE, MGMT_INTERFACE_HTTP);
+ final ModelNode req = createWriteAttributeRequest("console-enabled", Boolean.toString(enableFlag), address);
+ final ModelNode response = execute(req);
+ if (!isSuccess(response)) {
+ throw new FailureException(response);
+ }
+ return;
+ }
+
+ /**
* Given a string with possible ${x} expressions in it, this will resolve that expression
* using system property values that are set within the AS JVM itself. If the string
* to resolve has no expressions, or has no expressions that are resolveable, the expression
diff --git a/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerServiceImpl.java b/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerServiceImpl.java
index 0b9c078..bb42d4a 100644
--- a/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerServiceImpl.java
+++ b/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerServiceImpl.java
@@ -1034,6 +1034,9 @@ public class InstallerServiceImpl implements InstallerService {
// we don't want to the JBossAS welcome screen; turn it off
new WebJBossASClient(mcc).setEnableWelcomeRoot(false);
+ // we don't want users to access the admin console
+ new CoreJBossASClient(mcc).setEnableAdminConsole(false);
+
} catch (Exception e) {
log("deployServices failed", e);
throw new Exception("Failed to deploy services: " + ThrowableUtil.getAllMessages(e));
10 years, 11 months
[rhq] modules/enterprise
by Jiri Kremser
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/ConditionEditor.java | 3
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SingleAlertDefinitionView.java | 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/DurationItem.java | 39 ++++++++--
3 files changed, 35 insertions(+), 9 deletions(-)
New commits:
commit 57333dd7c4a683fe39bfcf68ea706cbfa6feded9
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Tue May 28 18:40:38 2013 +0200
[BZ 967542] - UI shows confusing units when editing Availability Duration alert condition type
I improved the DurationItem component to use internally the SelectItem
instead of ComboBoxItem. When using ComboBoxItem, it was possible to
write to the combobox and this is something that shouldn't happen in
this component because the unit types should be fixed. The DurationItem
is also used from the operation tab view, but no reggression was
introduced by this commit in this view.
Modifying also the DurationItem.setAndFormatValue() to populate the time correctly when
!isReadOnly.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/ConditionEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/ConditionEditor.java
index 8fe6d4b..0a2627c 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/ConditionEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/ConditionEditor.java
@@ -65,7 +65,6 @@ import org.rhq.enterprise.gui.coregui.client.components.form.DurationItem;
import org.rhq.enterprise.gui.coregui.client.components.form.NumberWithUnitsValidator;
import org.rhq.enterprise.gui.coregui.client.components.form.SortedSelectItem;
import org.rhq.enterprise.gui.coregui.client.components.form.TimeUnit;
-import org.rhq.enterprise.gui.coregui.client.components.form.UnitType;
import org.rhq.enterprise.gui.coregui.client.util.enhanced.EnhancedVLayout;
import org.rhq.enterprise.gui.coregui.client.util.measurement.MeasurementParser;
import org.rhq.enterprise.gui.coregui.client.util.message.Message;
@@ -959,7 +958,7 @@ public class ConditionEditor extends EnhancedVLayout {
durationValue.setTooltip(MSG.view_alert_definition_condition_editor_availabilityDuration_tooltip_duration());
durationValue.setHoverWidth(200);
if (editMode) {
- durationValue.setValue(Integer.parseInt(existingCondition.getOption()), UnitType.TIME);
+ durationValue.setAndFormatValue(Integer.parseInt(existingCondition.getOption()) * 1000L);
}
durationValue.setShowIfCondition(ifFunc);
formItems.add(durationValue);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SingleAlertDefinitionView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SingleAlertDefinitionView.java
index 25742f5..e24d1b4 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SingleAlertDefinitionView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SingleAlertDefinitionView.java
@@ -211,6 +211,8 @@ public class SingleAlertDefinitionView extends EnhancedVLayout {
public void execute(Boolean value) {
if (value) {
save();
+ } else {
+ unregisterHandler();
}
}
});
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/DurationItem.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/DurationItem.java
index 633188a..104b84c 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/DurationItem.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/DurationItem.java
@@ -29,17 +29,19 @@ import java.util.TreeSet;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.CanvasItem;
-import com.smartgwt.client.widgets.form.fields.ComboBoxItem;
import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.IntegerItem;
+import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.StaticTextItem;
import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
import com.smartgwt.client.widgets.form.validator.IntegerRangeValidator;
+import org.rhq.core.domain.measurement.MeasurementUnits;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.Messages;
import org.rhq.enterprise.gui.coregui.client.util.FormUtility;
+import org.rhq.enterprise.gui.coregui.client.util.MeasurementConverterClient;
import org.rhq.enterprise.gui.coregui.client.util.TypeConversionUtility;
/**
@@ -142,7 +144,7 @@ public class DurationItem extends CanvasItem {
}
});
- ComboBoxItem unitsItem = new ComboBoxItem(FIELD_UNITS);
+ SelectItem unitsItem = new SelectItem(FIELD_UNITS);
unitsItem.setShowTitle(false);
LinkedHashMap<String, String> valueMap = new LinkedHashMap<String, String>();
@@ -230,10 +232,33 @@ public class DurationItem extends CanvasItem {
if (longValue < 0) {
throw new IllegalArgumentException("negative time period " + longValue);
}
- String formattedOutput = formatMilliseconds(longValue);
- this.unitType = UnitType.TIME;
- this.form.setValue(FIELD_VALUE, formattedOutput);
- setValue(formattedOutput);
+ if (isReadOnly) {
+ String formattedOutput = formatMilliseconds(longValue);
+ this.unitType = UnitType.TIME;
+ this.form.setValue(FIELD_VALUE, formattedOutput);
+ setValue(formattedOutput);
+ } else {
+ String valueWithUnits = MeasurementConverterClient.format((double) longValue,
+ MeasurementUnits.MILLISECONDS, true);
+ String[] chunks = valueWithUnits.split(" ");
+ String value = chunks[0];
+ if (value.endsWith(".0")) {
+ value = value.substring(0, value.indexOf(".0"));
+ }
+ this.form.setValue(FIELD_VALUE, value);
+ String units = chunks[1];
+ SelectItem unitsItem = (SelectItem) this.form.getItem(FIELD_UNITS);
+ if (MeasurementConverterClient.getMeasurementUnitAbbreviation(MeasurementUnits.SECONDS).equals(units)) {
+ unitsItem.setValue(TimeUnit.SECONDS.name().toLowerCase());
+ } else if (MeasurementConverterClient.getMeasurementUnitAbbreviation(MeasurementUnits.MINUTES)
+ .equals(units)) {
+ unitsItem.setValue(TimeUnit.MINUTES.name().toLowerCase());
+ } else if (MeasurementConverterClient.getMeasurementUnitAbbreviation(MeasurementUnits.HOURS).equals(units)) {
+ unitsItem.setValue(TimeUnit.HOURS.name().toLowerCase());
+ } else if (MeasurementConverterClient.getMeasurementUnitAbbreviation(MeasurementUnits.DAYS).equals(units)) {
+ unitsItem.setValue(TimeUnit.DAYS.name().toLowerCase());
+ }
+ }
}
/**
@@ -474,7 +499,7 @@ public class DurationItem extends CanvasItem {
}
private TimeUnit getInputTimeUnit() {
- ComboBoxItem unitsItem = (ComboBoxItem) this.form.getItem(FIELD_UNITS);
+ SelectItem unitsItem = (SelectItem) this.form.getItem(FIELD_UNITS);
String unitString = unitsItem.getValueAsString(); // this will always be non-null
TimeUnit unit;
try {
10 years, 11 months
[rhq] modules/enterprise
by Jay Shaughnessy
modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/MeasurementScheduleManagerTest.java | 9 +++++++--
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementScheduleManagerBean.java | 8 +++++---
2 files changed, 12 insertions(+), 5 deletions(-)
New commits:
commit ecb57a4e3e147e18b000388a2baec312c31c7bf2
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue May 28 12:36:26 2013 -0400
Make sure sub-queries used for updates do not include implicit
paging/sorting.
Also, make a small change to test cleanup in related test class.
Note: Fix by lkrejci
diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/MeasurementScheduleManagerTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/MeasurementScheduleManagerTest.java
index 9febeb8..24bcc84 100644
--- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/MeasurementScheduleManagerTest.java
+++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/MeasurementScheduleManagerTest.java
@@ -342,10 +342,15 @@ public class MeasurementScheduleManagerTest extends AbstractMeasurementScheduleM
try {
if (null != em) {
em.flush();
- getTransactionManager().commit();
}
} catch (Throwable t) {
-
+ // best effort
+ }
+ try {
+ getTransactionManager().commit();
+ } catch (Throwable t) {
+ // best effort
}
}
+
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementScheduleManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementScheduleManagerBean.java
index 2e4eeda..d53a037 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementScheduleManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementScheduleManagerBean.java
@@ -820,6 +820,7 @@ public class MeasurementScheduleManagerBean implements MeasurementScheduleManage
*/
private void markResources(EntityContext context, int agentId) {
ResourceCriteria criteria = new ResourceCriteria();
+ criteria.clearPaging(); //important to avoid setting the ordering in the generated query
if (context.type == EntityContext.Type.Resource) {
criteria.addFilterId(context.resourceId);
} else if (context.type == EntityContext.Type.ResourceGroup) {
@@ -832,7 +833,7 @@ public class MeasurementScheduleManagerBean implements MeasurementScheduleManage
try {
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
- ;
+
generator.alterProjection("resource.id");
String resourceSubQuery = generator.getParameterReplacedQuery(false);
@@ -848,7 +849,7 @@ public class MeasurementScheduleManagerBean implements MeasurementScheduleManage
markResourceQuery.setParameter("now", System.currentTimeMillis());
int affectedRows = markResourceQuery.executeUpdate();
if (log.isDebugEnabled()) {
- log.debug("Marked " + affectedRows + " for future measurement scheudle update");
+ log.debug("Marked " + affectedRows + " for future measurement schedule update");
}
} catch (Throwable t) {
log.error("Could not notify agents of updates", t);
@@ -877,6 +878,7 @@ public class MeasurementScheduleManagerBean implements MeasurementScheduleManage
}
MeasurementScheduleCriteria criteria = new MeasurementScheduleCriteria();
+ criteria.clearPaging(); //important to avoid setting the ordering in the generated query
if (context.type == EntityContext.Type.Resource) {
criteria.addFilterResourceId(context.resourceId);
} else if (context.type == EntityContext.Type.ResourceGroup) {
@@ -1607,4 +1609,4 @@ public class MeasurementScheduleManagerBean implements MeasurementScheduleManage
// }
// }
-}
+}
\ No newline at end of file
10 years, 11 months
[rhq] modules/enterprise
by Thomas Segismont
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftDefinitionEditView.java | 10 ++++---
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftDefinitionTemplateEditView.java | 10 ++++---
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/configuration/GroupResourceConfigurationEditView.java | 10 ++++---
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/GroupPluginConfigurationEditView.java | 10 ++++---
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java | 10 ++++---
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java | 10 ++++---
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/configuration/TestConfigurationView.java | 13 +++++-----
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/configuration/TestGroupConfigurationView.java | 13 +++++-----
8 files changed, 50 insertions(+), 36 deletions(-)
New commits:
commit 2f15379bb357495c558b05fb271e247fa1681d01
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Tue May 28 17:36:13 2013 +0200
Bug 885686 - Tomcat web application configuration form allows save without Config File required field
It's not a Tomcat specific issue. We had a problem in *EditView classes: the check to enable/disable the save button was only based on the invalid properties set having been changed. Now it also looks at the set being empty or not.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftDefinitionEditView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftDefinitionEditView.java
index c7604c4..a428a22 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftDefinitionEditView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftDefinitionEditView.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2011 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,8 +13,8 @@
* 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.
+ * 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.enterprise.gui.coregui.client.drift;
@@ -190,8 +190,10 @@ public class DriftDefinitionEditView extends EnhancedVLayout implements Property
.toString()), Message.Severity.Error, EnumSet.of(Message.Option.Transient, Message.Option.Sticky));
}
messageCenter.notify(message);
- } else {
+ } else if (event.getInvalidPropertyNames().isEmpty()) {
this.saveButton.enable();
+ } else {
+ this.saveButton.disable();
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftDefinitionTemplateEditView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftDefinitionTemplateEditView.java
index dd69993..0ccc445 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftDefinitionTemplateEditView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/drift/DriftDefinitionTemplateEditView.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2011 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,8 +13,8 @@
* 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.
+ * 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.enterprise.gui.coregui.client.drift;
@@ -178,8 +178,10 @@ public class DriftDefinitionTemplateEditView extends EnhancedVLayout implements
.toString()), Message.Severity.Error, EnumSet.of(Message.Option.Transient, Message.Option.Sticky));
}
messageCenter.notify(message);
- } else {
+ } else if (event.getInvalidPropertyNames().isEmpty()) {
this.saveButton.enable();
+ } else {
+ this.saveButton.disable();
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/configuration/GroupResourceConfigurationEditView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/configuration/GroupResourceConfigurationEditView.java
index 55ac8fd..d0c440f 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/configuration/GroupResourceConfigurationEditView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/configuration/GroupResourceConfigurationEditView.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,8 +13,8 @@
* 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.
+ * 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.enterprise.gui.coregui.client.inventory.groups.detail.configuration;
@@ -261,8 +261,10 @@ public class GroupResourceConfigurationEditView extends EnhancedVLayout implemen
Message.Severity.Error, EnumSet.of(Message.Option.Transient, Message.Option.Sticky));
}
messageCenter.notify(message);
- } else {
+ } else if (event.getInvalidPropertyNames().isEmpty()) {
this.saveButton.enable();
+ } else {
+ this.saveButton.disable();
}
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/GroupPluginConfigurationEditView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/GroupPluginConfigurationEditView.java
index b6e892f..8680cc4 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/GroupPluginConfigurationEditView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/GroupPluginConfigurationEditView.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,8 +13,8 @@
* 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.
+ * 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.enterprise.gui.coregui.client.inventory.groups.detail.inventory;
@@ -256,8 +256,10 @@ public class GroupPluginConfigurationEditView extends EnhancedVLayout implements
Message.Severity.Error, EnumSet.of(Message.Option.Transient, Message.Option.Sticky));
}
messageCenter.notify(message);
- } else {
+ } else if (event.getInvalidPropertyNames().isEmpty()) {
this.saveButton.enable();
+ } else {
+ this.saveButton.disable();
}
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java
index ae7fde1..e3b119c 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2011 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,8 +13,8 @@
* 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.
+ * 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.enterprise.gui.coregui.client.inventory.resource.detail.configuration;
@@ -222,8 +222,10 @@ public class ResourceConfigurationEditView extends EnhancedVLayout implements Pr
.toString()), Message.Severity.Error, EnumSet.of(Message.Option.Transient, Message.Option.Sticky));
}
messageCenter.notify(message);
- } else {
+ } else if (event.getInvalidPropertyNames().isEmpty()) {
this.saveButton.enable();
+ } else {
+ this.saveButton.disable();
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java
index fd374eb..63245a2 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,8 +13,8 @@
* 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.
+ * 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.enterprise.gui.coregui.client.inventory.resource.detail.inventory;
@@ -171,8 +171,10 @@ public class PluginConfigurationEditView extends EnhancedVLayout implements Prop
Message.Option.Sticky));
}
messageCenter.notify(message);
- } else {
+ } else if (event.getInvalidPropertyNames().isEmpty()) {
this.saveButton.enable();
+ } else {
+ this.saveButton.disable();
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/configuration/TestConfigurationView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/configuration/TestConfigurationView.java
index 128a540..bdbe026 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/configuration/TestConfigurationView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/configuration/TestConfigurationView.java
@@ -1,8 +1,7 @@
/*
* RHQ Management Platform
- * Copyright 2010-2011, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
+ * Copyright (C) 2005-2013 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
@@ -14,8 +13,8 @@
* 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.
+ * 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.enterprise.gui.coregui.client.test.configuration;
@@ -111,8 +110,10 @@ public class TestConfigurationView extends EnhancedVLayout implements PropertyVa
EnumSet.of(Message.Option.Transient, Message.Option.Sticky));
}
messageCenter.notify(message);
- } else {
+ } else if (event.getInvalidPropertyNames().isEmpty()) {
this.saveButton.enable();
+ } else {
+ this.saveButton.disable();
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/configuration/TestGroupConfigurationView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/configuration/TestGroupConfigurationView.java
index 483e71c..00da718 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/configuration/TestGroupConfigurationView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/configuration/TestGroupConfigurationView.java
@@ -1,8 +1,7 @@
/*
* RHQ Management Platform
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
+ * Copyright (C) 2005-2013 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
@@ -14,8 +13,8 @@
* 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.
+ * 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.enterprise.gui.coregui.client.test.configuration;
@@ -112,8 +111,10 @@ public class TestGroupConfigurationView extends EnhancedVLayout implements Prope
EnumSet.of(Message.Option.Transient, Message.Option.Sticky));
}
messageCenter.notify(message);
- } else {
+ } else if (event.getInvalidPropertyNames().isEmpty()) {
this.saveButton.enable();
+ } else {
+ this.saveButton.disable();
}
}
10 years, 11 months