[rhq] modules/core
by mazz
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java | 30 +++++++++-
1 file changed, 27 insertions(+), 3 deletions(-)
New commits:
commit d5564f3562ee960115cc533f029521000c870f45
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Dec 19 12:39:24 2012 -0500
[BZ 887411] don't uninventory everything just because we commited some top level server
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 473b0d0..eaca661 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -1087,7 +1087,24 @@ public class InventoryManager extends AgentService implements ContainerService,
return true;
}
+ /**
+ * Performs a sync so that resources passed in are reflected in the agent's inventory.
+ * This assumes the resource sync infos passed in represent the full inventory tree.
+ *
+ * @param syncInfo information on all resources in the entire inventory tree
+ */
private void synchInventory(ResourceSyncInfo syncInfo) {
+ synchInventory(syncInfo, false);
+ }
+
+ /**
+ * Performs a sync so that resources passed in are reflected in the agent's inventory.
+ *
+ * @param syncInfo the resources' sync data
+ * @param partialInventory if true, syncInfo represents only a partial inventory.
+ * if false, syncInfo represents the full inventory tree of all resources
+ */
+ private void synchInventory(ResourceSyncInfo syncInfo, boolean partialInventory) {
log.info("Syncing local inventory with Server inventory...");
long startTime = System.currentTimeMillis();
Set<Resource> syncedResources = new LinkedHashSet<Resource>();
@@ -1099,7 +1116,12 @@ public class InventoryManager extends AgentService implements ContainerService,
// rhq-980 Adding agent-side logging to report any unexpected synch failure.
try {
- getAllUuids(syncInfo, allServerSideUuids);
+ // don't bother doing this if we are processing a partial inventory.
+ // allServerSideUuids is only ever used to purge obsolete resources, but we don't
+ // do that for partial inventories, so we don't need to prepare that collection for partials.
+ if (!partialInventory) {
+ getAllUuids(syncInfo, allServerSideUuids);
+ }
log.debug("Processing Server sync info...");
processSyncInfo(syncInfo, syncedResources, unknownResourceIds, modifiedResourceIds, deletedResourceIds,
@@ -1113,7 +1135,9 @@ public class InventoryManager extends AgentService implements ContainerService,
mergeUnknownResources(unknownResourceIds);
mergeModifiedResources(modifiedResourceIds);
- purgeObsoleteResources(allServerSideUuids);
+ if (!partialInventory) {
+ purgeObsoleteResources(allServerSideUuids);
+ }
postProcessNewlyCommittedResources(newlyCommittedResources);
if (log.isDebugEnabled()) {
if (!deletedResourceIds.isEmpty()) {
@@ -2188,7 +2212,7 @@ public class InventoryManager extends AgentService implements ContainerService,
+ "] and its descendants...");
// Get the latest resource data rooted at the given id.
- synchInventory(syncInfo);
+ synchInventory(syncInfo, true); // this method assumes we only get a single resource and its children (BZ 887411)
performServiceScan(syncInfo.getId()); // NOTE: This will block (the initial scan blocks).
}
11 years, 4 months
[rhq] 2 commits - modules/enterprise
by Jay Shaughnessy
modules/enterprise/server/itests-2/pom.xml | 52 ++++++----
modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java | 5
2 files changed, 38 insertions(+), 19 deletions(-)
New commits:
commit a06a6ff899355823a42c3e79ac70a82510fddbe2
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Dec 19 10:45:43 2012 -0500
Try forcing ojdbc driver resolution usinbg the local repo since it
can't always be found in profile-defined repositories.
diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java
index dd46a29..e038fe0 100644
--- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java
+++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java
@@ -341,6 +341,11 @@ public abstract class AbstractEJB3Test extends Arquillian {
// If we're running oracle we need to include the OJDBC driver because dbunit needs it. Note that we need
// add it explicitly even though it is a provided module used by the datasource.
if (!Boolean.valueOf(System.getProperty("rhq.skip.oracle"))) {
+ // in proxy situations (like Jenkins) shrinkwrap won't be able to find repositories defined in
+ // settings.xml profiles. We know at this point the driver is in the local repo, try going offline
+ // at this point to force local repo resolution since the oracle driver is not in public repos.
+ // see http://stackoverflow.com/questions/6291146/arquillian-shrinkwrap-mavendep...
+ resolver.goOffline();
dependencies.addAll(resolver.artifact("com.oracle:ojdbc6:jar:" + System.getProperty("rhq.ojdbc.version"))
.resolveAs(JavaArchive.class));
}
commit becf9e4f40c63b8c3a6b1d6aea7122fa9eab67ab
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Dec 18 14:28:03 2012 -0500
Avoid the unzipping if it is already unzipped. It takes time for unzip to
actually do all of the file compares just to know it doesn't need to add
anything.
diff --git a/modules/enterprise/server/itests-2/pom.xml b/modules/enterprise/server/itests-2/pom.xml
index 5811fef..db60c86 100644
--- a/modules/enterprise/server/itests-2/pom.xml
+++ b/modules/enterprise/server/itests-2/pom.xml
@@ -26,8 +26,8 @@
<jboss.vm.args>-Xmx700m -XX:MaxPermSize=200m -Djava.security.manager
-Djava.security.policy==${jboss.unzip.location}/security.policy</jboss.vm.args>
<jboss.vm.args.debug></jboss.vm.args.debug> <!-- -Ditest.debug can override this, see below -->
- <!-- These properties guide which datasources are used for integration tests. Only one should be true.
- The default is Postgres, specify -Pitest.oracle to use Oracle -->
+ <!-- These properties guide which datasources are used for integration tests. Only one should be true. The default is
+ Postgres, specify -Pitest.oracle to use Oracle -->
<skip.postgres>false</skip.postgres>
<skip.oracle>true</skip.oracle>
</properties>
@@ -96,12 +96,12 @@
</dependency>
<dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-arquillian-suite-extension</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-arquillian-suite-extension</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
</dependency>
-
+
<dependency>
<groupId>org.rhq</groupId>
<artifactId>rhq-core-domain</artifactId>
@@ -231,15 +231,30 @@
<id>prepare Standalone XML</id>
<phase>process-test-resources</phase>
<configuration>
- <target>
- <echo>Unzipping JBossAS ${jboss.version} found at ${jboss.zip}</echo>
- <unzip src="${jboss.zip}" dest="${jboss.unzip.location}/.." />
- <echo>JBossAS ${jboss.version} should now be at: ${jboss.unzip.location}</echo>
-
- <echo>Copying security policy to JBossAS</echo>
- <copy file="${project.build.directory}/test-classes/security.policy" tofile="${jboss.unzip.location}/security.policy" />
-
+ <tasks>
+ <taskdef resource="net/sf/antcontrib/antcontrib.properties" />
<property name="jboss.conf" location="${jboss.unzip.location}/standalone/configuration/standalone.xml" />
+ <property name="jboss.conf.safe" location="${jboss.conf}.safe" />
+ <if>
+ <available file="${jboss.unzip.location}" />
+ <then>
+ <echo>Skipping unzipping JBossAS ${jboss.version}, it is already unzipped</echo>
+ <echo>Restoring safe copy of standalone.xml for pending test additions</echo>
+ <copy file="${jboss.conf.safe}" tofile="${jboss.conf}" overwrite="true" />
+ </then>
+ <else>
+ <echo>Unzipping JBossAS ${jboss.version} found at ${jboss.zip}</echo>
+ <unzip src="${jboss.zip}" dest="${jboss.unzip.location}/.." />
+ <echo>JBossAS ${jboss.version} should now be at: ${jboss.unzip.location}</echo>
+
+ <echo>Copying security policy to JBossAS</echo>
+ <copy file="${project.build.directory}/test-classes/security.policy" tofile="${jboss.unzip.location}/security.policy" />
+
+ <echo>Saving copy of standalone.xml</echo>
+ <copy file="${jboss.conf}" tofile="${jboss.conf.safe}" />
+ </else>
+ </if>
+
<echo>Will now add test configuration to JBossAS config file: ${jboss.conf}</echo>
<replace file="${jboss.conf}">
@@ -460,8 +475,7 @@
</dependencies>
</module>
]]></echo>
-
- </target>
+ </tasks>
</configuration>
<goals>
<goal>run</goal>
@@ -703,8 +717,8 @@
</properties>
<dependencies>
- <!-- The provided scope in the root pom is not sufficient, we need this fo shrinkwrap to resolve
- dependency and add the jar to the deployment. -->
+ <!-- The provided scope in the root pom is not sufficient, we need this fo shrinkwrap to resolve dependency and add
+ the jar to the deployment. -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
11 years, 4 months
[rhq] Branch 'release/jon3.1.x' - modules/enterprise
by John Sanda
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBeanTest.java | 47 +++++++---
1 file changed, 36 insertions(+), 11 deletions(-)
New commits:
commit 8623993dd46785e359383c0cc54dc51c168d0c96
Author: John Sanda <jsanda(a)redhat.com>
Date: Wed Dec 19 10:00:20 2012 -0500
fixing a few issues with test failures
Test clean was failing because we were not purging the resource from the db.
The uuid constant in the test class did not match the one actually used.
When setting the uuid, Resource pads it out to 36 characters.
The other issue involves dealing with decimal precision. I have added a
function to use up to 4 decimal places.
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBeanTest.java
index cbbbdaf..b40efbe 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBeanTest.java
@@ -31,10 +31,14 @@ import static org.rhq.core.domain.measurement.NumericType.DYNAMIC;
import static org.rhq.core.domain.resource.ResourceCategory.SERVER;
import static org.rhq.test.AssertUtils.assertPropertiesMatch;
+import java.math.BigDecimal;
+import java.math.MathContext;
+import java.math.RoundingMode;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
+import java.text.DecimalFormat;
import java.util.Collections;
import java.util.List;
@@ -91,7 +95,7 @@ public class MeasurementDataManagerBeanTest extends AbstractEJB3Test {
private final String RESOURCE_NAME = getClass().getName() + "_NAME";
- private final String RESOURCE_UUID = getClass().getSimpleName() + "_UUID";
+ private final String RESOURCE_UUID = "MeasurementDataManagerBeanTest_UUID ";
private ResourceType resourceType;
@@ -114,7 +118,7 @@ public class MeasurementDataManagerBeanTest extends AbstractEJB3Test {
insertDummyReport();
}
- @AfterMethod
+ @AfterMethod(alwaysRun = true)
public void tearDown() {
purgeDB();
}
@@ -146,17 +150,17 @@ public class MeasurementDataManagerBeanTest extends AbstractEJB3Test {
assertEquals("Expected to get back 60 data points.", buckets.getNumDataPoints(), actualData.size());
MeasurementDataNumericHighLowComposite expectedBucket0Data = new MeasurementDataNumericHighLowComposite(
- buckets.get(0), (1.1 + 2.2 + 3.3) / 3, 3.3, 1.1);
+ buckets.get(0), divide(1.1 + 2.2 + 3.3, 3), 3.3, 1.1);
MeasurementDataNumericHighLowComposite expectedBucket59Data = new MeasurementDataNumericHighLowComposite(
- buckets.get(59), (4.4 + 5.5 + 6.6) / 3, 6.6, 4.4);
+ buckets.get(59), divide(4.4 + 5.5 + 6.6, 3), 6.6, 4.4);
MeasurementDataNumericHighLowComposite expectedBucket29Data = new MeasurementDataNumericHighLowComposite(
buckets.get(29), Double.NaN, Double.NaN, Double.NaN);
- assertPropertiesMatch("The data for bucket 0 does not match the expected values.", expectedBucket0Data,
+ assertMeasurementDataMatches("The data for bucket 0 does not match the expected values.", expectedBucket0Data,
actualData.get(0));
- assertPropertiesMatch("The data for bucket 59 does not match the expected values.", expectedBucket59Data,
+ assertMeasurementDataMatches("The data for bucket 59 does not match the expected values.", expectedBucket59Data,
actualData.get(59));
- assertPropertiesMatch("The data for bucket 29 does not match the expected values.", expectedBucket29Data,
+ assertMeasurementDataMatches("The data for bucket 29 does not match the expected values.", expectedBucket29Data,
actualData.get(29));
}
@@ -191,16 +195,38 @@ public class MeasurementDataManagerBeanTest extends AbstractEJB3Test {
assertEquals("Expected to get back 60 data points.", buckets.getNumDataPoints(), actualData.size());
MeasurementDataNumericHighLowComposite expectedBucket0Data = new MeasurementDataNumericHighLowComposite(
- buckets.get(0), (2.0 + 5.0 + 3.0) / 3, 6.0, 1.0);
+ buckets.get(0), divide(2.0 + 5.0 + 3.0, 3), 6.0, 1.0);
MeasurementDataNumericHighLowComposite expectedBucket59Data = new MeasurementDataNumericHighLowComposite(
- buckets.get(59), (5.0 + 5.0 + 3.0) / 3, 9.0, 2.0);
+ buckets.get(59), divide(5.0 + 5.0 + 3.0, 3), 9.0, 2.0);
- assertPropertiesMatch("The data for bucket 0 does not match the expected values.", expectedBucket0Data,
+ assertMeasurementDataMatches("The data for bucket 0 does not match the expected values.", expectedBucket0Data,
actualData.get(0));
assertPropertiesMatch("The data for bucket 59 does not match the expected values.", expectedBucket59Data,
actualData.get(59));
}
+ private void assertMeasurementDataMatches(String msg, MeasurementDataNumericHighLowComposite expected,
+ MeasurementDataNumericHighLowComposite actual) {
+
+ if (Double.isNaN(expected.getValue())) {
+ assertPropertiesMatch(msg, expected, actual);
+ } else {
+ assertPropertiesMatch(msg, expected, actual, "value");
+
+ DecimalFormat df = new DecimalFormat("#########0.0000");
+ MathContext context = new MathContext(16, RoundingMode.CEILING);
+ BigDecimal expectedValue = new BigDecimal(df.format(expected.getValue()), context);
+ BigDecimal actualValue = new BigDecimal(df.format(actual.getValue()), context);
+
+ assertEquals(msg + " - The average value does not match.", expectedValue, actualValue);
+ }
+ }
+
+ private double divide(double dividend, int divisor) {
+ return new BigDecimal(Double.toString(dividend)).divide(new BigDecimal(Integer.toString(divisor)),
+ MathContext.DECIMAL64).doubleValue();
+ }
+
private void createInventory() throws Exception {
purgeDB();
executeInTransaction(new TransactionCallback() {
@@ -287,7 +313,6 @@ public class MeasurementDataManagerBeanTest extends AbstractEJB3Test {
.setParameter("key", RESOURCE_KEY)
.setParameter("uuid", RESOURCE_UUID)
.executeUpdate();
- em.flush();
}
private void deleteMeasurementSchedules(EntityManager em) {
11 years, 4 months
[rhq] Changes to 'tsegismont/as7plugin-httpclient'
by Thomas Segismont
New branch 'tsegismont/as7plugin-httpclient' available with the following commits:
commit 5e55b9ab5713e5d958f1c128a7fc331afa03c602
Author: Thomas SEGISMONT <tsegismo(a)redhat.com>
Date: Wed Dec 19 00:55:25 2012 +0100
AS7 plugin: add httpclient dependency
commit a3cfaeb5e529b843dfeaad13f234cd5c56dabe74
Author: Thomas SEGISMONT <tsegismo(a)redhat.com>
Date: Tue Dec 18 17:56:46 2012 +0100
Add common property for commons-httpclient version and update POMs
11 years, 4 months
[rhq] Changes to 'jkremser/ha-jsf-to-gwt-rewrite+token'
by Jiri Kremser
New branch 'jkremser/ha-jsf-to-gwt-rewrite+token' available with the following commits:
commit 9dec5476b28339c455262ae066d742be5edffef8
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Mon Dec 17 21:27:04 2012 +0100
[BZ 888016 - RFE: Purging the agent's security token from UI] Icon for purging the token added to UI, as well as the new method in SLSB. Handling the situation when agent is without a valid token in the DB when agent tries to register.
commit e3c531c1f52ef4298b0e5d29a044765cc97c8ac7
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Tue Dec 18 17:12:46 2012 +0100
Assigning the agent to the affinity group; some refactoring (renaming AgentNodeDatasource -> AgentDatasource, AgentNodeDatasourceField -> AgentDatasourceField)
commit 9c52b1e5e5e75f65acad0fcd250da92914d7435c
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Tue Dec 18 17:10:43 2012 +0100
AgentCriteria and Agent finder have been added
commit 6ad56994db007039324ad2d6462636546e4e1ce1
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Fri Dec 14 19:35:46 2012 +0100
ServerCriteria and Server finder have been added
commit 134d6f6984e69dc06b105a3024f30f947c8f498a
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Fri Dec 14 15:21:53 2012 +0100
Revert "exposing the CloudManagerBean via CLI"
This reverts commit 60c1d42fa5750ef5d1829e97b6b15323501bc3f2.
commit 756bac150c6f31e4dd5a60c9f519226fff7f28c1
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Fri Dec 14 14:43:33 2012 +0100
adding comment
commit 2ecf112a35453de2ab40aa4c091aff039c73f26c
Merge: 829bede e794a37
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Fri Dec 14 13:30:23 2012 +0100
Merge branch 'master' into jkremser/ha-jsf-to-gwt-rewrite
11 years, 4 months
[rhq] modules/enterprise modules/integration-tests
by Heiko W. Rupp
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/OperationDefinitionRest.java | 4
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/OperationsTest.java | 248 ++++++++++
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Operation.java | 129 +++++
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/OperationHistory.java | 108 ++++
4 files changed, 486 insertions(+), 3 deletions(-)
New commits:
commit 245fb391a81fe6a3c5c7331bb6c683fce63a7530
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Dec 18 17:10:41 2012 +0100
Add tests for the operations part of the rest-api
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/OperationDefinitionRest.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/OperationDefinitionRest.java
index 2f5055c..f84149e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/OperationDefinitionRest.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/OperationDefinitionRest.java
@@ -1,9 +1,7 @@
package org.rhq.enterprise.server.rest.domain;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
@@ -15,7 +13,7 @@ import com.wordnik.swagger.annotations.ApiProperty;
* @author Heiko W. Rupp
*/
@ApiClass(value = "The template from which operations are created")
-@XmlRootElement
+@XmlRootElement(name = "operationDefinition")
public class OperationDefinitionRest {
public OperationDefinitionRest() {
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/OperationsTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/OperationsTest.java
new file mode 100644
index 0000000..72d40c9
--- /dev/null
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/OperationsTest.java
@@ -0,0 +1,248 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 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.modules.integrationTests.restApi;
+
+import java.util.List;
+import java.util.Map;
+
+import com.jayway.restassured.http.ContentType;
+import com.jayway.restassured.response.Response;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.rhq.modules.integrationTests.restApi.d.Operation;
+
+import static com.jayway.restassured.RestAssured.expect;
+import static com.jayway.restassured.RestAssured.get;
+import static com.jayway.restassured.RestAssured.given;
+import static org.hamcrest.core.Is.is;
+
+/**
+ * Test the operations part of the rest api
+ * @author Heiko W. Rupp
+ */
+public class OperationsTest extends AbstractBase {
+
+ private int definitionId;
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp(); // Junit does not call that for us
+ Response r =
+ given()
+ .header(acceptJson)
+ .queryParam("resourceId",10001)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .get("/operation/definitions");
+
+ definitionId = -1;
+ List<Map<String,Object>> list = r.as(List.class);
+ for (Map<String,Object> map : list) {
+ if (map.get("name").equals("discovery"))
+ definitionId = (Integer) map.get("id");
+ }
+
+ assert definitionId !=-1 : "No discovery operation found";
+ }
+
+ @Test
+ public void testGetDefinitionById() throws Exception {
+
+ // Now retrieve that definition by id
+
+ given()
+ .header(acceptJson)
+ .pathParam("did",definitionId)
+ .expect()
+ .statusCode(200)
+ .body("name",is("discovery"))
+ .when()
+ .get("/operation/definition/{did}");
+
+ }
+
+ @Test
+ public void testCreateDraftOperation() throws Exception {
+
+ Operation draft =
+ given()
+ .header(acceptJson)
+ .pathParam("definitionId",definitionId)
+ .queryParam("resourceId",10001)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .post("/operation/definition/{definitionId}")
+ .as(Operation.class);
+
+ assert draft != null;
+ assert draft.getDefinitionId() == definitionId;
+
+ int draftId = draft.getId();
+
+ // check if we can retrieve one single draft
+
+ Operation op = get("/operation/" + draftId).as(Operation.class);
+ assert op !=null;
+ assert op.equals(draft);
+
+ }
+
+ @Test
+ public void testCreateAndUpdateDraftOperation() throws Exception {
+
+ Operation draft =
+ given()
+ .header(acceptJson)
+ .pathParam("definitionId",definitionId)
+ .queryParam("resourceId",10001)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .post("/operation/definition/{definitionId}")
+ .as(Operation.class);
+
+ assert draft != null;
+ assert draft.getDefinitionId() == definitionId;
+
+ int draftId = draft.getId();
+ draft.getParams().put("detailed",true);
+
+ try {
+ given()
+ .contentType(ContentType.JSON)
+ .pathParam("id", draftId)
+ .body(draft)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .put("/operation/{id}");
+ } finally {
+ // delete the draft again
+ expect()
+ .statusCode(204)
+ .when()
+ .delete("/operation/" + draftId);
+ }
+
+
+ }
+
+ @Test
+ public void testCreateDraftOperationAndScheduleExecution() throws Exception {
+
+ Operation draft =
+ given()
+ .header(acceptJson)
+ .pathParam("definitionId",definitionId)
+ .queryParam("resourceId",10001)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .post("/operation/definition/{definitionId}")
+ .as(Operation.class);
+
+ assert draft != null;
+ assert draft.getDefinitionId() == definitionId;
+
+ int draftId = draft.getId();
+
+ draft.setReadyToSubmit(true);
+ draft.getParams().put("detailed", true);
+
+ // update to schedule
+ Operation scheduled =
+ given()
+ .contentType(ContentType.JSON)
+ .pathParam("id",draftId)
+ .body(draft)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .put("/operation/{id}")
+ .as(Operation.class);
+
+ System.out.println(scheduled);
+ String history = null;
+ List<Map<String,Object>> links = scheduled.getLinks();
+ for (Map<String,Object> link : links) {
+ if (link.get("rel").equals("history"))
+ history = (String) link.get("href");
+ }
+ assert history != null;
+
+ String historyId = history.substring(history.lastIndexOf("/")+1);
+ try {
+ Thread.sleep(5000); // we need to wait a little as the execution may take time
+
+ given()
+ .pathParam("hid",historyId)
+ .expect()
+ .statusCode(200)
+ .log().everything()
+ .when()
+ .get("/operation/history/{hid}");
+
+ // See if we also find it when we are looking for histories on the resource
+ Response response =
+ given()
+ .queryParam("resourceId",10001)
+ .header(acceptJson)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .get("/operation/history");
+
+ // compare
+ List<Map<String,Object>> list = response.as(List.class);
+ boolean found = false;
+ for (Map<String,Object> map : list) {
+ if (map.get("jobId").equals(historyId)) {
+ found = true;
+ }
+ }
+ assert found;
+
+ } finally {
+
+ // Delete the history item
+ given()
+ .pathParam("hid",historyId)
+ .expect()
+ .statusCode(204)
+ .log().ifError()
+ .when()
+ .delete("/operation/history/{hid}");
+
+ }
+
+ }
+
+}
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Operation.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Operation.java
new file mode 100644
index 0000000..54a1505
--- /dev/null
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Operation.java
@@ -0,0 +1,129 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 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.modules.integrationTests.restApi.d;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An operation for testing
+ * @author Heiko W. Rupp
+ */
+public class Operation {
+
+ int id;
+ String name;
+ boolean readyToSubmit;
+ int resourceId;
+ int definitionId;
+ Map<String,Object> params = new HashMap<String, Object>();
+ List<Map<String,Object>> links;
+
+ public Operation() {
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public boolean isReadyToSubmit() {
+ return readyToSubmit;
+ }
+
+ public void setReadyToSubmit(boolean readyToSubmit) {
+ this.readyToSubmit = readyToSubmit;
+ }
+
+ public int getResourceId() {
+ return resourceId;
+ }
+
+ public void setResourceId(int resourceId) {
+ this.resourceId = resourceId;
+ }
+
+ public int getDefinitionId() {
+ return definitionId;
+ }
+
+ public void setDefinitionId(int definitionId) {
+ this.definitionId = definitionId;
+ }
+
+ public Map<String, Object> getParams() {
+ return params;
+ }
+
+ public void setParams(Map<String, Object> params) {
+ this.params = params;
+ }
+
+ public List<Map<String, Object>> getLinks() {
+ return links;
+ }
+
+ public void setLinks(List<Map<String, Object>> links) {
+ this.links = links;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Operation operation = (Operation) o;
+
+ if (definitionId != operation.definitionId) return false;
+ if (id != operation.id) return false;
+ if (readyToSubmit != operation.readyToSubmit) return false;
+ if (resourceId != operation.resourceId) return false;
+ if (links != null ? !links.equals(operation.links) : operation.links != null) return false;
+ if (!name.equals(operation.name)) return false;
+ if (params != null ? !params.equals(operation.params) : operation.params != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = id;
+ result = 31 * result + name.hashCode();
+ result = 31 * result + (readyToSubmit ? 1 : 0);
+ result = 31 * result + resourceId;
+ result = 31 * result + definitionId;
+ result = 31 * result + (params != null ? params.hashCode() : 0);
+ result = 31 * result + (links != null ? links.hashCode() : 0);
+ return result;
+ }
+}
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/OperationHistory.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/OperationHistory.java
new file mode 100644
index 0000000..fa0af5c
--- /dev/null
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/OperationHistory.java
@@ -0,0 +1,108 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 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.modules.integrationTests.restApi.d;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An operationhistory item for testing
+ * @author Heiko W. Rupp
+ */
+public class OperationHistory {
+
+ String operationName;
+ String resourceName;
+ long lastModified;
+ String status;
+ String errorMessage;
+ String jobId;
+
+ Map<String,Object> result = new HashMap<String, Object>();
+ List<Object> links;
+
+ public OperationHistory() {
+ }
+
+ public String getOperationName() {
+ return operationName;
+ }
+
+ public void setOperationName(String operationName) {
+ this.operationName = operationName;
+ }
+
+ public String getResourceName() {
+ return resourceName;
+ }
+
+ public void setResourceName(String resourceName) {
+ this.resourceName = resourceName;
+ }
+
+ public long getLastModified() {
+ return lastModified;
+ }
+
+ public void setLastModified(long lastModified) {
+ this.lastModified = lastModified;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+ public String getJobId() {
+ return jobId;
+ }
+
+ public void setJobId(String jobId) {
+ this.jobId = jobId;
+ }
+
+ public Map<String, Object> getResult() {
+ return result;
+ }
+
+ public void setResult(Map<String, Object> result) {
+ this.result = result;
+ }
+
+ public List<Object> getLinks() {
+ return links;
+ }
+
+ public void setLinks(List<Object> links) {
+ this.links = links;
+ }
+}
11 years, 4 months
[rhq] Branch 'release/jon3.1.x' - modules/enterprise
by John Sanda
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBeanTest.java | 1 +
1 file changed, 1 insertion(+)
New commits:
commit 0ecbebbf556353cd4b5aadef7e9e62e9a09ffcc0
Author: John Sanda <jsanda(a)redhat.com>
Date: Tue Dec 18 10:29:17 2012 -0500
trying to resolve oracle test failure
We are hitting a constraint violation when attemtping to delete the agent
record, even though we have already executed a statement to delete the
resource. Adding call to EntityManager.flush after deleting the resource to
ensure that the resource deletion is performed prior to deleting the agent.
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBeanTest.java
index 96a72ed..cbbbdaf 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBeanTest.java
@@ -287,6 +287,7 @@ public class MeasurementDataManagerBeanTest extends AbstractEJB3Test {
.setParameter("key", RESOURCE_KEY)
.setParameter("uuid", RESOURCE_UUID)
.executeUpdate();
+ em.flush();
}
private void deleteMeasurementSchedules(EntityManager em) {
11 years, 4 months
[rhq] modules/enterprise
by Jay Shaughnessy
modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/AvailabilityManagerTest.java | 229 ++++++++--
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/AvailabilityManagerBean.java | 62 ++
2 files changed, 242 insertions(+), 49 deletions(-)
New commits:
commit 3605ce3398557277d8ddf4deb3ffaa83337b7c58
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Dec 18 10:06:59 2012 -0500
[Bug 884338 (not a fix) - Agent's availability report is ignored due to bogus stale resource error]
I failed to reproduce this issue but:
- Add some better logging and some attempted repair code for this situation
- Add a couple more tests
diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/AvailabilityManagerTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/AvailabilityManagerTest.java
index f180036..ff1193d 100644
--- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/AvailabilityManagerTest.java
+++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/test/AvailabilityManagerTest.java
@@ -24,7 +24,6 @@ import java.util.Date;
import java.util.List;
import java.util.Random;
-import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.transaction.Status;
@@ -37,6 +36,7 @@ import org.rhq.core.domain.measurement.Availability;
import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.measurement.ResourceAvailability;
import org.rhq.core.domain.resource.Agent;
+import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceType;
@@ -117,7 +117,6 @@ public class AvailabilityManagerTest extends AbstractEJB3Test {
if (additionalResources != null) {
getTransactionManager().begin();
- EntityManager em = getEntityManager();
for (Resource res : additionalResources) {
Resource res2 = em.find(Resource.class, res.getId());
@@ -130,7 +129,6 @@ public class AvailabilityManagerTest extends AbstractEJB3Test {
if (theResourceType != null) {
getTransactionManager().begin();
- EntityManager em = getEntityManager();
em.remove(em.find(ResourceType.class, theResourceType.getId()));
theResourceType = null;
@@ -159,7 +157,7 @@ public class AvailabilityManagerTest extends AbstractEJB3Test {
beginTx();
try {
- setupResource(em);
+ setupResource();
commitAndClose();
Availability aThen = new Availability(theResource, then, UP);
@@ -211,7 +209,7 @@ public class AvailabilityManagerTest extends AbstractEJB3Test {
beginTx();
try {
- setupResource(em);
+ setupResource();
commitAndClose();
Availability aThen = new Availability(theResource, then, UP);
@@ -278,7 +276,7 @@ public class AvailabilityManagerTest extends AbstractEJB3Test {
List<AvailabilityPoint> availPoints;
Availability avail;
- setupResource(em);
+ setupResource();
// platform: UNKNOWN(0) -->
commitAndClose();
@@ -430,7 +428,7 @@ public class AvailabilityManagerTest extends AbstractEJB3Test {
beginTx();
try {
- setupResource(em);
+ setupResource();
commitAndClose();
@@ -460,7 +458,7 @@ public class AvailabilityManagerTest extends AbstractEJB3Test {
beginTx();
try {
- setupResource(em);
+ setupResource();
commitAndClose();
@@ -490,7 +488,7 @@ public class AvailabilityManagerTest extends AbstractEJB3Test {
try {
prepareForTestAgents();
- setupResource(em);
+ setupResource();
commitAndClose();
@@ -561,13 +559,13 @@ public class AvailabilityManagerTest extends AbstractEJB3Test {
try {
prepareForTestAgents();
- setupResource(em); // setup theResource
+ setupResource(); // setup theResource
allResources.add(theResource);
// now create a bunch more resources
for (int i = 0; i < 99; i++) {
- allResources.add(setupAnotherResource(em, i, theResource));
+ allResources.add(setupAnotherResource(i, theResource));
}
em.flush();
@@ -736,7 +734,7 @@ public class AvailabilityManagerTest extends AbstractEJB3Test {
beginTx();
try {
- setupResource(em); // inserts initial UNKNOWN Availability at epoch
+ setupResource(); // inserts initial UNKNOWN Availability at epoch
commitAndClose();
@@ -823,7 +821,7 @@ public class AvailabilityManagerTest extends AbstractEJB3Test {
beginTx();
try {
- setupResource(em);
+ setupResource();
commitAndClose();
@@ -884,7 +882,7 @@ public class AvailabilityManagerTest extends AbstractEJB3Test {
try {
Availability avail;
- setupResource(em);
+ setupResource();
commitAndClose();
@@ -972,11 +970,11 @@ public class AvailabilityManagerTest extends AbstractEJB3Test {
Availability avail;
AvailabilityReport report;
- setupResource(em);
+ setupResource();
commitAndClose();
- long allAvailCount = setUpAvailabilities(em);
+ long allAvailCount = setUpAvailabilities();
// we now have 1:00 UP, 1:20 DOWN, 1:40 UP
Subject overlord = LookupUtil.getSubjectManager().getOverlord();
@@ -1050,11 +1048,10 @@ public class AvailabilityManagerTest extends AbstractEJB3Test {
Availability avail;
AvailabilityReport report;
- setupResource(em);
+ setupResource();
commitAndClose();
-
- long allAvailCount = setUpAvailabilities(em);
+ long allAvailCount = setUpAvailabilities();
// we now have 1:00 UP, 1:20 DOWN, 1:40 UP
Subject overlord = LookupUtil.getSubjectManager().getOverlord();
@@ -1121,19 +1118,174 @@ public class AvailabilityManagerTest extends AbstractEJB3Test {
}
}
+ /**
+ * This was an attempt to get the behavior of this bug but it didn't. This inserts duplicate avail records, which
+ * should be discarded.
+ */
+ @Test(enabled = ENABLE_TESTS)
+ public void testBZ884338_1() throws Exception {
+ beginTx();
+
+ try {
+ Availability avail;
+ AvailabilityReport report;
+
+ setupResource();
+ commitAndClose();
+
+ long allAvailCount = setUpAvailabilities();
+ assertTrue("should have >= 3 avail records", 3 <= allAvailCount);
+ List<Availability> avails = getResourceAvailabilities(theResource);
+ // there is always the UNKNOWN period starting at epoch, plus the three created in setup
+ assertEquals(avails.toString(), 4, avails.size());
+
+ // we now have 1:00 UP, 1:20 DOWN, 1:40 UP
+ avail = availabilityManager.getCurrentAvailabilityForResource(overlord, theResource.getId());
+ assert avail.getAvailabilityType() == UP;
+
+ // insert a duplicate current 1:40 UP and an out-of-order 1:20 DOWN, these should be ignored
+ Long currentStartTime = avail.getStartTime();
+ long newStartTime = currentStartTime;
+ avail = new Availability(theResource, newStartTime, UP);
+ report = new AvailabilityReport(false, theAgent.getName());
+ report.addAvailability(avail);
+
+ newStartTime = (currentStartTime - (20 * 60 * 1000L));
+ avail = new Availability(theResource, newStartTime, DOWN);
+ report = new AvailabilityReport(false, theAgent.getName());
+ report.addAvailability(avail);
+
+ Thread.sleep(1000);
+ availabilityManager.mergeAvailabilityReport(report);
+
+ // the agent should have been updated, but no new rows in availability were added
+ Agent agent = LookupUtil.getAgentManager().getAgentByName(theAgent.getName());
+ Date lastReport = new Date(agent.getLastAvailabilityReport());
+ assert lastReport != null;
+ assertEquals(allAvailCount, countAvailabilitiesInDB().longValue());
+ avails = getResourceAvailabilities(theResource);
+ assertEquals(avails.toString(), 4, avails.size());
+
+ // avail start times should be unchanged 0, 1:00 (UP), 1:20(DOWN), 1:40(UP)
+ avail = avails.get(0); // 0..1:00
+ assertTrue(avail.toString(), Math.abs(avail.getStartTime() - 0L) < 1000L);
+ assertEquals(avail.toString(), AvailabilityType.UNKNOWN, avail.getAvailabilityType());
+ assertTrue(avail.toString(), Math.abs(avail.getEndTime() - avails.get(1).getStartTime()) < 1000L);
+ avail = avails.get(1); // 1:00..1:20
+ assertTrue(avail.toString(), Math.abs(currentStartTime - (avail.getStartTime() + (40 * 60 * 1000))) < 1000L);
+ assertEquals(avail.toString(), AvailabilityType.UP, avail.getAvailabilityType());
+ assertTrue(avail.toString(), Math.abs(avail.getEndTime() - avails.get(2).getStartTime()) < 1000L);
+ avail = avails.get(2); // 1:20..1:40
+ assertTrue(avail.toString(), Math.abs(currentStartTime - (avail.getStartTime() + (20 * 60 * 1000))) < 1000L);
+ assertEquals(avail.toString(), AvailabilityType.DOWN, avail.getAvailabilityType());
+ assertTrue(avail.toString(), Math.abs(avail.getEndTime() - avails.get(3).getStartTime()) < 1000L);
+ avail = avails.get(3); // 1:40
+ assertTrue(avail.toString(), Math.abs(currentStartTime - avail.getStartTime()) < 1000L);
+ assertEquals(avail.toString(), AvailabilityType.UP, avail.getAvailabilityType());
+ assertEquals(avail.toString(), avail.getEndTime(), null);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw e;
+ } finally {
+ if (Status.STATUS_ACTIVE == getTransactionManager().getStatus()) {
+ getTransactionManager().rollback();
+ }
+ }
+ }
+
+ /**
+ * Still can't reproduce the bug but this test tries to validate the repair code we have in case we detect
+ * the problem.
+ */
+ @Test(enabled = ENABLE_TESTS)
+ public void testBZ884338_2() throws Exception {
+ beginTx();
+
+ try {
+ Availability avail;
+ AvailabilityReport report;
+
+ setupResource();
+
+ commitAndClose();
+
+ long allAvailCount = setUpAvailabilities();
+ assertTrue("should have >= 3 avail records", 3 <= allAvailCount);
+ List<Availability> avails = getResourceAvailabilities(theResource);
+ // there is always the UNKNOWN period starting at epoch, plus the three created in setup
+ assertEquals(avails.toString(), 4, avails.size());
+
+ // we now have 1:00 UP, 1:20 DOWN, 1:40 UP
+ avail = availabilityManager.getCurrentAvailabilityForResource(overlord, theResource.getId());
+
+ beginTx();
+
+ avail = em.find(Availability.class, avail.getId());
+ assert avail.getAvailabilityType() == UP;
+
+ // mess things up by assigning an end time to the latest avail record.
+ Long currentStartTime = avail.getStartTime();
+
+ Long nonNullEndTime = currentStartTime + 1000L;
+ avail.setEndTime(nonNullEndTime);
+ avail = em.merge(avail);
+
+ commitAndClose();
+
+ // try to insert new avail, this should trigger the repair code
+ long newStartTime = (currentStartTime + (5 * 60 * 1000L));
+ avail = new Availability(theResource, newStartTime, DOWN);
+ report = new AvailabilityReport(false, theAgent.getName());
+ report.addAvailability(avail);
+
+ Thread.sleep(1000);
+ availabilityManager.mergeAvailabilityReport(report);
+
+ avails = getResourceAvailabilities(theResource);
+ assertEquals(avails.toString(), 4, avails.size());
+
+ // avail start times should now be 0, 1:00 (UP), 1:10(DOWN), 1:40(UP)
+ avail = avails.get(0); // 0..1:00
+ assertTrue(avail.toString(), Math.abs(avail.getStartTime() - 0L) < 1000L);
+ assertEquals(avail.toString(), AvailabilityType.UNKNOWN, avail.getAvailabilityType());
+ assertTrue(avail.toString(), Math.abs(avail.getEndTime() - avails.get(1).getStartTime()) < 1000L);
+ avail = avails.get(1); // 1:00..1:20
+ assertTrue(avail.toString(), Math.abs(currentStartTime - (avail.getStartTime() + (40 * 60 * 1000))) < 1000L);
+ assertEquals(avail.toString(), AvailabilityType.UP, avail.getAvailabilityType());
+ assertTrue(avail.toString(), Math.abs(avail.getEndTime() - avails.get(2).getStartTime()) < 1000L);
+ avail = avails.get(2); // 1:20..1:40
+ assertTrue(avail.toString(), Math.abs(currentStartTime - (avail.getStartTime() + (20 * 60 * 1000))) < 1000L);
+ assertEquals(avail.toString(), AvailabilityType.DOWN, avail.getAvailabilityType());
+ assertTrue(avail.toString(), Math.abs(avail.getEndTime() - avails.get(3).getStartTime()) < 1000L);
+ avail = avails.get(3); // 1:40
+ assertTrue(avail.toString(), Math.abs(currentStartTime - avail.getStartTime()) < 1000L);
+ assertEquals(avail.toString(), AvailabilityType.UP, avail.getAvailabilityType());
+ assertEquals(avail.toString(), null, avail.getEndTime()); // THIS IS THE CHANGE
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw e;
+ } finally {
+ if (Status.STATUS_ACTIVE == getTransactionManager().getStatus()) {
+ getTransactionManager().rollback();
+ }
+ }
+ }
+
@Test(enabled = ENABLE_TESTS)
public void testMergeReportPerformance() throws Exception {
beginTx();
List<Resource> allResources = new ArrayList<Resource>();
try {
- setupResource(em); // setup theResource
+ setupResource(); // setup theResource
allResources.add(theResource);
// now create a bunch more resources
for (int i = 0; i < 100; i++) {
- allResources.add(setupAnotherResource(em, i, theResource));
+ allResources.add(setupAnotherResource(i, theResource));
}
em.flush();
@@ -1260,8 +1412,6 @@ public class AvailabilityManagerTest extends AbstractEJB3Test {
/**
* See how many rows we have in the availability table
*
- * @param em EntityManager to use
- *
* @return the rowcount
*
* @throws Exception
@@ -1277,22 +1427,36 @@ public class AvailabilityManagerTest extends AbstractEJB3Test {
}
/**
- * Just set up a resource where we can attach the availabilities to
+ * See how many rows we have in the availability table
*
- * @param em The EntityManager to use
+ * @return the rowcount
+ *
+ * @throws Exception
+ */
+ private List<Availability> getResourceAvailabilities(Resource r) throws Exception {
+ AvailabilityCriteria c = new AvailabilityCriteria();
+ c.addFilterResourceId(r.getId());
+ c.addSortStartTime(PageOrdering.ASC);
+ return availabilityManager.findAvailabilityByCriteria(overlord, c);
+ }
+
+ /**
+ * Just set up a resource where we can attach the availabilities to
*
* @return A Resource ready to use
*/
- private Resource setupResource(EntityManager em) {
- theAgent = new Agent("testagent", "localhost", 1234, "", "randomToken");
+ private Resource setupResource() {
+ String prefix = this.getClass().getSimpleName() + "_";
+ theAgent = new Agent(prefix + "agent", "localhost", 1234, "", "randomToken");
em.persist(theAgent);
- theResourceType = new ResourceType("test-plat", "test-plugin", ResourceCategory.PLATFORM, null);
+ theResourceType = new ResourceType(prefix + "type", prefix + "plugin", ResourceCategory.PLATFORM, null);
em.persist(theResourceType);
- theResource = new Resource("test-platform-key", "test-platform-name", theResourceType);
+ theResource = new Resource(prefix + "resourceKey", prefix + "resourceName", theResourceType);
theResource.setUuid("" + new Random().nextInt());
theResource.setAgent(theAgent);
+ theResource.setInventoryStatus(InventoryStatus.COMMITTED);
em.persist(theResource);
em.flush();
@@ -1303,12 +1467,11 @@ public class AvailabilityManagerTest extends AbstractEJB3Test {
* Set up another unique resource that will be related to <code>theAgent</code>. The resource will be of type <code>
* theResourceType</code>.
*
- * @param em The EntityManager to use
* @param uniqueNumber used to define a unique key for the resource
*
* @return A Resource ready to use
*/
- private Resource setupAnotherResource(EntityManager em, int uniqueNumber, Resource parentResource) {
+ private Resource setupAnotherResource(int uniqueNumber, Resource parentResource) {
Resource newResource;
newResource = new Resource("test-platform-key-" + uniqueNumber, "test-platform-name-" + uniqueNumber,
@@ -1326,13 +1489,11 @@ public class AvailabilityManagerTest extends AbstractEJB3Test {
* Set up an availability scenario where we set up availability for one hour, split it in the middle and have 20min
* up, 20min down, 20min up starting at 1:00am.
*
- * @param em An EntityManager to use
- *
* @return total number of availability records in the DB after we've added ours
*
* @throws Exception
*/
- private long setUpAvailabilities(EntityManager em) throws Exception {
+ private long setUpAvailabilities() throws Exception {
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.set(Calendar.HOUR, 1);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/AvailabilityManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/AvailabilityManagerBean.java
index 05dd802..31f1040 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/AvailabilityManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/AvailabilityManagerBean.java
@@ -46,6 +46,7 @@ import org.rhq.core.domain.discovery.AvailabilityReport;
import org.rhq.core.domain.measurement.Availability;
import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.measurement.ResourceAvailability;
+import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.composite.ResourceIdWithAvailabilityComposite;
import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite;
@@ -556,9 +557,41 @@ public class AvailabilityManagerBean implements AvailabilityManagerLocal, Availa
} catch (NoResultException nre) {
// This should not happen unless the Resource in the report is stale, which can happen in certain
// sync scenarios. A Resource is given its initial Availability/ResourceAvailability when it is
- // persisted so it is guaranteed to have Availability, so, the Resource must not exist.
- log.info("Skipping mergeAvailabilityReport() for stale resource [" + reported.getResource()
- + "]. These messages should go away after the next agent synchronization with the server.");
+ // persisted so it is guaranteed to have Availability, so, the Resource must not exist. At least
+ // it must not exist in my utopian view of the world. Let's just make sure...
+ Resource attachedResource = (Resource) entityManager.find(Resource.class, reported.getResource()
+ .getId());
+ if (null == attachedResource) {
+ // expected case
+ log.info("Skipping mergeAvailabilityReport() for stale resource [" + reported.getResource()
+ + "]. These messages should go away after the next agent synchronization with the server.");
+
+ } else if (InventoryStatus.COMMITTED == attachedResource.getInventoryStatus()) {
+ // this should not happen, it means the resource exists but has no latest Availability
+ // record (i.e. sendTime == null). Try to correct the situation.
+ log.warn("Resource [" + reported.getResource()
+ + "] has no latest availability record (i.e. no endtime) - will attempt to repair.\n"
+ + report.toString(false));
+ try {
+ List<Availability> attachedAvails = attachedResource.getAvailability();
+ if (attachedAvails.isEmpty()) {
+ attachedResource.initCurrentAvailability();
+ entityManager.merge(attachedResource);
+
+ } else {
+ Availability attachedLastAvail = attachedAvails.get(attachedAvails.size() - 1);
+ attachedLastAvail.setEndTime(null);
+ entityManager.merge(attachedLastAvail);
+ }
+
+ // ask the agent for a full report so as to ensure we are in sync with agent
+ askForFullReport = true;
+
+ } catch (Throwable t) {
+ log.warn("Unable to repair latest availablity for Resource [" + reported.getResource()
+ + "]", t);
+ }
+ }
} catch (NonUniqueResultException nure) {
// This condition should never happen. In my world of la-la land, I've done everything
@@ -661,7 +694,7 @@ public class AvailabilityManagerBean implements AvailabilityManagerLocal, Availa
public void updateAgentResourceAvailabilities(int agentId, AvailabilityType platformAvailType,
AvailabilityType childAvailType) {
- platformAvailType = (null == platformAvailType) ? AvailabilityType.UNKNOWN : platformAvailType;
+ platformAvailType = (null == platformAvailType) ? AvailabilityType.DOWN : platformAvailType;
childAvailType = (null == childAvailType) ? AvailabilityType.UNKNOWN : childAvailType;
// get the platform resource if not already at platformAvailType (since this is the one
@@ -681,17 +714,8 @@ public class AvailabilityManagerBean implements AvailabilityManagerLocal, Availa
query.setParameter("disabled", AvailabilityType.DISABLED);
List<ResourceIdWithAvailabilityComposite> resourcesWithStatus = query.getResultList();
- // The above queries only return resources if they have at least one row in Availability.
- // This may be a problem in the future, and may need to be fixed.
- // If a resource has 0 rows of availability, then it is by definition "unknown". If,
- // availabilityType is null, we don't have to do anything since the unknown state hasn't changed.
- // If this method is told to set all agent resources to something of other than unknown (null)
- // availability, then we may need to completely rethink the query we do above so it returns composite
- // objects for all resources, even those that have 0 rows of availability. Remember though, that once
- // we get an availability report from an agent, a resource will have at least 1 availability row. So,
- // a resource should rarely have 0 avail rows; if it does, it normally gets one within a minute
- // (since the agent sends avail reports every 60 seconds or so by default). So this problem might not
- // be as bad as first thought.
+ // The above queries only return resources if they have at least one row in Availability. This should
+ // not be a problem since a new Resource gets an initial UNKNOWN Availability record at persist-time.
if (log.isDebugEnabled()) {
log.debug("Agent #[" + agentId + "] is going to have [" + resourcesWithStatus.size()
@@ -815,6 +839,14 @@ public class AvailabilityManagerBean implements AvailabilityManagerLocal, Availa
}
return;
+
+ } catch (NonUniqueResultException nure) {
+ // This should not happen but can happen if the startTime exactly matches an existing start time. In
+ // this case assume we have somehow been passed a duplicate report, and ignore the entry.
+ log.warn("Resource [" + toInsert.getResource()
+ + "] received a duplicate Availability. It is being ignored: " + toInsert);
+
+ return;
}
// If we are inserting the same availability type, the first one can just continue
11 years, 4 months
[rhq] modules/enterprise modules/integration-tests
by Heiko W. Rupp
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AbstractRestBean.java | 26
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertHandlerBean.java | 2
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/CustomExceptionMapper.java | 5
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/EventHandlerBean.java | 42
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/GroupHandlerBean.java | 64 -
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java | 18
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/ResourceHandlerBean.java | 101 +-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/RootHandlerBean.java | 3
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/UserHandlerBean.java | 159 +++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/Baseline.java | 24
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/EventDefinitionRest.java | 74 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/Link.java | 7
modules/integration-tests/pom.xml | 8
modules/integration-tests/rest-api/pom.xml | 28
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AbstractBase.java | 48 +
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/EventTest.java | 223 ++++
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/GetStatusTest.java | 78 -
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/GroupTest.java | 469 ++++++++++
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/MetricsTest.java | 361 +++++++
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/ResourcesTest.java | 276 ++++-
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/RootURITest.java | 112 ++
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/StatusTest.java | 93 +
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/UserTest.java | 158 +++
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Baseline.java | 107 ++
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Event.java | 85 +
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/EventSource.java | 116 ++
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Group.java | 65 +
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/GroupDef.java | 76 +
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/MDataPoint.java | 91 +
modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Schedule.java | 61 +
30 files changed, 2742 insertions(+), 238 deletions(-)
New commits:
commit f908a455b968de7826667f5b1a0628290dcda537
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Dec 18 10:23:53 2012 +0100
Add tests for the REST-Api endpoints and fix some issues in the API.
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 1e8b99f..6e7f1de 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
@@ -57,6 +57,7 @@ import org.rhq.core.domain.resource.group.GroupCategory;
import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.enterprise.server.resource.ResourceManagerLocal;
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.ResourceWithType;
@@ -426,6 +427,31 @@ public class AbstractRestBean {
return resourceGroup;
}
+ protected GroupRest fillGroup(ResourceGroup group, UriInfo uriInfo) {
+
+ GroupRest gr = new GroupRest(group.getName());
+ gr.setId(group.getId());
+ gr.setCategory(group.getGroupCategory());
+ gr.setRecursive(group.isRecursive());
+ if (group.getGroupDefinition()!=null)
+ gr.setDynaGroupDefinitionId(group.getGroupDefinition().getId());
+ gr.setExplicitCount(group.getExplicitResources().size());
+ gr.setImplicitCount(group.getImplicitResources().size());
+ UriBuilder uriBuilder = uriInfo.getBaseUriBuilder();
+ uriBuilder.path("/group/{id}");
+ URI uri = uriBuilder.build(group.getId());
+ Link link = new Link("edit",uri.toASCIIString());
+ gr.getLinks().add(link);
+
+ uriBuilder = uriInfo.getBaseUriBuilder();
+ uriBuilder.path("/group/{id}/metricDefinitions");
+ uri = uriBuilder.build(group.getId());
+ link = new Link("metricDefinitions",uri.toASCIIString());
+ gr.getLinks().add(link);
+
+ return gr;
+ }
+
private static class CacheKey {
private String namespace;
private int id;
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 9e3b41a..9835b58 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
@@ -93,7 +93,7 @@ public class AlertHandlerBean extends AbstractRestBean {
@Path("/")
@ApiOperation(value = "List all alerts", multiValueResponse = true, responseClass = "List<AlertRest>")
public Response listAlerts(
- @ApiParam(value = "Page number", defaultValue = "0") @QueryParam("page") int page,
+ @ApiParam(value = "Page number", defaultValue = "1") @QueryParam("page") int page,
@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,
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/CustomExceptionMapper.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/CustomExceptionMapper.java
index 5d5671f..f0ffdb4 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/CustomExceptionMapper.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/CustomExceptionMapper.java
@@ -30,6 +30,7 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.enterprise.server.authz.PermissionException;
import org.rhq.enterprise.server.resource.ResourceNotFoundException;
+import org.rhq.enterprise.server.resource.group.ResourceGroupNotFoundException;
import org.rhq.enterprise.server.rest.domain.RHQErrorWrapper;
/**
@@ -57,8 +58,12 @@ public class CustomExceptionMapper implements ExceptionMapper<Exception> {
status =Response.Status.NOT_FOUND;
else if (cause instanceof ResourceNotFoundException)
status = Response.Status.NOT_FOUND;
+ else if (cause instanceof ResourceGroupNotFoundException)
+ status = Response.Status.NOT_FOUND;
else if (cause instanceof ParameterMissingException)
status = Response.Status.NOT_ACCEPTABLE;
+ else if (cause instanceof IllegalArgumentException)
+ status = Response.Status.NOT_ACCEPTABLE;
else if (cause instanceof PermissionException)
status = Response.Status.FORBIDDEN;
else
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 ad1b7b0..3d7abe0 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
@@ -16,7 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
package org.rhq.enterprise.server.rest;
import java.util.ArrayList;
@@ -62,6 +61,7 @@ import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageControl;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.event.EventManagerLocal;
+import org.rhq.enterprise.server.rest.domain.EventDefinitionRest;
import org.rhq.enterprise.server.rest.domain.EventRest;
import org.rhq.enterprise.server.rest.domain.EventSourceRest;
@@ -112,6 +112,40 @@ public class EventHandlerBean extends AbstractRestBean {
}
@GET
+ @Path("/{id}/definitions")
+ @ApiOperation(value = "List the defined event source definitions for the resource", responseClass = "EventDefintionRest", multiValueResponse = true)
+ public Response listEventDefinitionsForResource(@ApiParam("id of the resource") @PathParam("id") int resourceId,
+ @Context Request request,
+ @Context HttpHeaders headers) {
+
+ Resource res = fetchResource(resourceId);
+ ResourceType resourceType = res.getResourceType();
+ em.refresh(resourceType);
+ Set<EventDefinition> eventDefinitions = resourceType.getEventDefinitions();
+
+ List<EventDefinitionRest> definitionsRest = new ArrayList<EventDefinitionRest>(eventDefinitions.size());
+ for (EventDefinition source : eventDefinitions) {
+ EventDefinitionRest esr = new EventDefinitionRest();
+ esr.setDescription(source.getDescription());
+ esr.setId(source.getId());
+ esr.setDisplayName(source.getDisplayName());
+ esr.setName(source.getName());
+ definitionsRest.add(esr);
+ }
+
+ Response.ResponseBuilder builder;
+ MediaType mediaType = headers.getAcceptableMediaTypes().get(0);
+ if (mediaType.equals(MediaType.APPLICATION_XML_TYPE)) {
+ GenericEntity<List<EventDefinitionRest>> list = new GenericEntity<List<EventDefinitionRest>>(definitionsRest) {};
+ builder = Response.ok(list, mediaType);
+ }
+ else {
+ builder = Response.ok(definitionsRest, mediaType);
+ }
+ return builder.build();
+ }
+
+ @GET
@Path("/source/{id}")
@ApiOperation(value = "Retrieve the event source with the passed id", responseClass = "EventSourceRest")
public EventSourceRest getEventSource(@ApiParam("Id of the source to retrieve") @PathParam("id") int sourceId) {
@@ -127,7 +161,7 @@ public class EventHandlerBean extends AbstractRestBean {
@ApiOperation("Add a new event source for a resource. This can e.g. be a different logfile. " +
"The source.name must match an existing definition fo this resource. " +
"If an event source for the definition name and resource with the same location already exists, no new source is created. " +
- "NOTE: An Event source added this way will not sow up in the connection properties.")
+ "NOTE: An Event source added this way will not show up in the connection properties.")
public EventSourceRest addEventSource(@ApiParam("id of the resource") @PathParam("id") int resourceId,
EventSourceRest esr) {
@@ -177,8 +211,8 @@ public class EventHandlerBean extends AbstractRestBean {
}
@GET @GZIP
- @Path("/source/{id}/events")
- @ApiOperation(value = "List the events for the event source with the passed id. If no time range is given, the last 200 entries will be displayed",
+ @Path("/source/{id}/events")
+ @ApiOperation(value = "List the events for the event source with the passed id. If no time range is given, the last 200 entries will be displayed",
responseClass = "EventRest", multiValueResponse = true)
public Response getEventsForSource(@PathParam("id") int sourceId,
@QueryParam("startTime") long 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 9f0ed9f..59739b1 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
@@ -54,6 +54,7 @@ import com.wordnik.swagger.annotations.ApiParam;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jboss.resteasy.annotations.Form;
import org.jboss.resteasy.annotations.GZIP;
import org.jboss.resteasy.annotations.cache.Cache;
@@ -114,7 +115,7 @@ public class GroupHandlerBean extends AbstractRestBean {
if (q!=null) {
criteria.addFilterName(q);
}
- List<ResourceGroup> groups = resourceGroupManager.findResourceGroupsByCriteria(caller,criteria);
+ List<ResourceGroup> groups = resourceGroupManager.findResourceGroupsByCriteria(caller, criteria);
List<GroupRest> list = new ArrayList<GroupRest>(groups.size());
for (ResourceGroup group : groups) {
@@ -177,14 +178,13 @@ public class GroupHandlerBean extends AbstractRestBean {
resourceType = resourceTypeManager.getResourceTypeById(caller,group.getResourceTypeId());
newGroup.setResourceType(resourceType);
} catch (ResourceTypeNotFoundException e) {
- e.printStackTrace(); // TODO: Customise this generated block
throw new StuffNotFoundException("ResourceType with id " + group.getResourceTypeId());
}
}
Response.ResponseBuilder builder;
try {
- newGroup = resourceGroupManager.createResourceGroup(caller,newGroup);
+ newGroup = resourceGroupManager.createResourceGroup(caller, newGroup);
UriBuilder uriBuilder = uriInfo.getBaseUriBuilder();
uriBuilder.path("/group/{id}");
URI uri = uriBuilder.build(newGroup.getId());
@@ -200,7 +200,7 @@ public class GroupHandlerBean extends AbstractRestBean {
@PUT
@Path("{id}")
- @ApiOperation(value = "Update the passed group")
+ @ApiOperation(value = "Update the passed group. Currently only name change is supported")
public Response updateGroup(@ApiParam(value = "Id of the group to update") @PathParam("id") int id,
@ApiParam(value = "New version of the group") GroupRest in,
@Context HttpHeaders headers,
@@ -304,7 +304,7 @@ public class GroupHandlerBean extends AbstractRestBean {
@Context HttpHeaders headers, @Context UriInfo uriInfo) {
ResourceGroup resourceGroup = fetchGroup(id, false);
- Resource res = resourceManager.getResource(caller,resourceId);
+ Resource res = resourceManager.getResource(caller, resourceId);
if (res==null)
throw new StuffNotFoundException("Resource with id " + resourceId);
@@ -351,31 +351,6 @@ public class GroupHandlerBean extends AbstractRestBean {
return builder.build();
}
- private GroupRest fillGroup(ResourceGroup group, UriInfo uriInfo) {
-
- GroupRest gr = new GroupRest(group.getName());
- gr.setId(group.getId());
- gr.setCategory(group.getGroupCategory());
- gr.setRecursive(group.isRecursive());
- if (group.getGroupDefinition()!=null)
- gr.setDynaGroupDefinitionId(group.getGroupDefinition().getId());
- gr.setExplicitCount(group.getExplicitResources().size());
- gr.setImplicitCount(group.getImplicitResources().size());
- UriBuilder uriBuilder = uriInfo.getBaseUriBuilder();
- uriBuilder.path("/group/{id}");
- URI uri = uriBuilder.build(group.getId());
- Link link = new Link("edit",uri.toASCIIString());
- gr.getLinks().add(link);
-
- uriBuilder = uriInfo.getBaseUriBuilder();
- uriBuilder.path("/group/{id}/metricDefinitions");
- uri = uriBuilder.build(group.getId());
- link = new Link("metricDefinitions",uri.toASCIIString());
- gr.getLinks().add(link);
-
- return gr;
- }
-
@GZIP
@GET
@Path("/definitions")
@@ -523,9 +498,11 @@ public class GroupHandlerBean extends AbstractRestBean {
} catch (GroupDefinitionAlreadyExistsException e) {
builder =Response.status(Response.Status.CONFLICT);
+ builder.entity(e.getMessage());
} catch (GroupDefinitionCreateException e) {
e.printStackTrace(); // TODO: Customise this generated block
- builder = Response.status(Response.Status.INTERNAL_SERVER_ERROR);
+ builder = Response.status(Response.Status.NOT_ACCEPTABLE);
+ builder.entity(e.getMessage());
}
return builder.build();
}
@@ -533,10 +510,11 @@ public class GroupHandlerBean extends AbstractRestBean {
@PUT
@Path("/definition/{id}")
@Consumes({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
- @ApiOperation("Update an existing GroupDefinition")
+ @ApiOperation("Update an existing GroupDefinition or recalculate it if the query param 'recalculate' is set to true")
public Response updateGroupDefinition(@ApiParam("Id fo the definition to update") @PathParam("id") int definitionId,
@ApiParam("If true, trigger a re-calculation") @QueryParam( "recalculate")
- @DefaultValue("false") boolean recalculate, GroupDefinitionRest definition,
+ @DefaultValue("false") boolean recalculate,
+ GroupDefinitionRest definition, // TODO mark as optional?
@Context HttpHeaders headers,
@Context UriInfo uriInfo) {
@@ -549,6 +527,19 @@ public class GroupHandlerBean extends AbstractRestBean {
Response.ResponseBuilder builder = null;
+ if (recalculate) {
+ try {
+ definitionManager.calculateGroupMembership(caller,gd.getId());
+ builder = Response.noContent();
+ } catch (Exception e) {
+ builder = Response.status(Response.Status.NOT_ACCEPTABLE);
+ builder.entity(e.getLocalizedMessage());
+ }
+ return builder.build();
+ }
+
+ // Not recalculation, but an update
+
if (!definition.getName().isEmpty())
gd.setName(definition.getName());
gd.setDescription(definition.getDescription());
@@ -566,18 +557,11 @@ public class GroupHandlerBean extends AbstractRestBean {
try {
definitionManager.updateGroupDefinition(caller,gd);
} catch (Exception e) {
- e.printStackTrace(); // TODO: Customise this generated block
builder = Response.status(Response.Status.NOT_ACCEPTABLE);
builder.entity(e.getLocalizedMessage());
return builder.build();
}
- if (recalculate) {
- try {
- definitionManager.calculateGroupMembership(caller,gd.getId());
- } catch (Exception e) {
- }
- }
try {
// Re-fetch, as groups may have changed
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java
index b927acf..115452d 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java
@@ -747,14 +747,20 @@ public class MetricHandlerBean extends AbstractRestBean {
@Path("data/{scheduleId}/baseline")
@Consumes({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
@ApiOperation(value = "Set a new baseline for the schedule")
- @ApiError(code = 404, reason = NO_SCHEDULE_FOR_ID)
- public void setBaseline(@ApiParam("Id of the schedule") @PathParam("scheduleId") int scheduleId,
- Baseline baseline, HttpHeaders headers, @Context UriInfo uriInfo) {
+ @ApiErrors({
+ @ApiError(code = 404, reason = NO_SCHEDULE_FOR_ID),
+ @ApiError(code = 406 ,reason = "Baseline data is incorrect")
+ })
+ public Response setBaseline(@ApiParam("Id of the schedule") @PathParam("scheduleId") int scheduleId,
+ Baseline baseline, @Context HttpHeaders headers, @Context UriInfo uriInfo) {
MeasurementSchedule schedule = obtainSchedule(scheduleId, false, DataType.MEASUREMENT);
// little bit of sanity checking
- if (baseline.getMin()>baseline.getMean() || baseline.getMean()>baseline.getMax() || baseline.getMin()>baseline.getMax())
- throw new IllegalArgumentException("Baseline not correct. it should be min<=mean<=max");
+ if (baseline.getMin()>baseline.getMean() || baseline.getMean()>baseline.getMax() || baseline.getMin()>baseline.getMax()) {
+ Response.ResponseBuilder builder = Response.status(Response.Status.NOT_ACCEPTABLE);
+ builder.entity("Baseline not correct. it should be min<=mean<=max");
+ return builder.build();
+ }
MeasurementBaseline mBase = schedule.getBaseline();
if (mBase == null) {
@@ -770,6 +776,8 @@ public class MetricHandlerBean extends AbstractRestBean {
scheduleManager.updateSchedule(caller,schedule);
+ return Response.created(uriInfo.getRequestUriBuilder().build()).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 98b2e6e..22d8111 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
@@ -33,6 +33,7 @@ import javax.ejb.Stateless;
import javax.interceptor.Interceptors;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
+import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
@@ -51,6 +52,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
+import com.arjuna.ats.internal.jdbc.drivers.modifiers.list;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiError;
import com.wordnik.swagger.annotations.ApiOperation;
@@ -77,6 +79,7 @@ import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceCategory;
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.alert.AlertManagerLocal;
@@ -115,11 +118,10 @@ public class ResourceHandlerBean extends AbstractRestBean {
private EntityManager entityManager;
@GET
- @Path("/{id}")
+ @Path("/{id:\\d+}")
@Cache(isPrivate = true,maxAge = 120)
@ApiOperation(value = "Retrieve a single resource", responseClass = "ResourceWithType")
@ApiError(code = 404, reason = NO_RESOURCE_FOR_ID)
-
public Response getResource(@ApiParam("Id of the resource to retrieve") @PathParam("id") int id,
@Context Request request, @Context HttpHeaders headers,
@Context UriInfo uriInfo) {
@@ -151,15 +153,27 @@ public class ResourceHandlerBean extends AbstractRestBean {
@GET @GZIP
@Path("/")
- @ApiOperation(value = "Search for resources by the given search string", responseClass = "ResourceWithType")
+ @ApiOperation(value = "Search for resources by the given search string, possibly limited by category and paged", responseClass = "ResourceWithType")
public Response getResourcesByQuery(@ApiParam("String to search in the resource name") @QueryParam("q") String q,
+ @ApiParam("Limit to category (PLATFORM, SERVER, SERVICE") @QueryParam("category") String category,
+ @ApiParam("Page size for paging") @QueryParam("ps") @DefaultValue("20") int pageSize,
+ @ApiParam("Page for paging") @QueryParam("page") Integer page,
@Context HttpHeaders headers,
@Context UriInfo uriInfo) {
ResourceCriteria criteria = new ResourceCriteria();
- criteria.addFilterName(q);
- List<Resource> ret = resMgr.findResourcesByCriteria(caller,criteria);
+ if (q!=null) {
+ criteria.addFilterName(q);
+ }
+ if (category!=null) {
+ criteria.addFilterResourceCategories(ResourceCategory.valueOf(category.toUpperCase()));
+ }
+ if (page!=null) {
+ criteria.setPaging(page,pageSize);
+ criteria.addSortName(PageOrdering.ASC);
+ }
+ PageList<Resource> ret = resMgr.findResourcesByCriteria(caller,criteria);
- Response.ResponseBuilder builder = getResponseBuilderForResourceList(headers,uriInfo,ret);
+ Response.ResponseBuilder builder = getResponseBuilderForResourceList(headers,uriInfo,ret, page, pageSize);
return builder.build();
}
@@ -173,22 +187,27 @@ public class ResourceHandlerBean extends AbstractRestBean {
@Context UriInfo uriInfo) {
PageControl pc = new PageControl();
- List<Resource> ret = resMgr.findResourcesByCategory(caller, ResourceCategory.PLATFORM,
+ PageList<Resource> ret = resMgr.findResourcesByCategory(caller, ResourceCategory.PLATFORM,
InventoryStatus.COMMITTED, pc);
- Response.ResponseBuilder builder = getResponseBuilderForResourceList(headers, uriInfo, ret);
+ Response.ResponseBuilder builder = getResponseBuilderForResourceList(headers, uriInfo, ret, null, 20);
return builder.build();
}
/**
* Translate the passed list of resources into a response according to the acceptable mime types etc.
+ *
+ *
* @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 numer of elements on a page
* @return An initialized ResponseBuilder
*/
private Response.ResponseBuilder getResponseBuilderForResourceList(HttpHeaders headers, UriInfo uriInfo,
- List<Resource> resources) {
+ PageList<Resource> resources, Integer page,
+ int pageSize) {
List<ResourceWithType> rwtList = new ArrayList<ResourceWithType>(resources.size());
for (Resource r : resources) {
putToCache(r.getId(), Resource.class, r);
@@ -197,14 +216,35 @@ public class ResourceHandlerBean extends AbstractRestBean {
}
// What media type does the user request?
MediaType mediaType = headers.getAcceptableMediaTypes().get(0);
- Response.ResponseBuilder builder;
+ 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());
+ }
+ }
if (mediaType.equals(MediaType.TEXT_HTML_TYPE)) {
- builder = Response.ok(renderTemplate("listResourceWithType", rwtList), mediaType);
+ builder.entity(renderTemplate("listResourceWithType", rwtList));
+
} else {
GenericEntity<List<ResourceWithType>> list = new GenericEntity<List<ResourceWithType>>(rwtList) {
};
- builder = Response.ok(list);
+ builder.entity(list);
}
return builder;
}
@@ -453,7 +493,7 @@ public class ResourceHandlerBean extends AbstractRestBean {
}
private Resource obtainResource(int resourceId) {
- Resource resource = getFromCache(resourceId, Resource.class);
+ Resource resource = resMgr.getResource(caller,resourceId);
if (resource == null) {
resource = resMgr.getResource(caller, resourceId);
if (resource != null)
@@ -487,7 +527,6 @@ public class ResourceHandlerBean extends AbstractRestBean {
"via a normal RHQ agent")
@POST
@Path("platform/{name}")
-
public Response createPlatform(
@ApiParam(value = "Name of the platform") @PathParam("name") String name,
@ApiParam(value = "Type of the platform", allowableValues = "Linux,Windows,... TODO") StringValue typeValue,
@@ -510,8 +549,8 @@ public class ResourceHandlerBean extends AbstractRestBean {
URI uri = uriBuilder.build(r.getId());
- javax.ws.rs.core.Response.ResponseBuilder builder = Response.ok(rwt);
- builder.location(uri);
+ Response.ResponseBuilder builder = Response.created(uri);
+ builder.entity(rwt);
return builder.build();
}
@@ -541,7 +580,7 @@ public class ResourceHandlerBean extends AbstractRestBean {
uriBuilder.path("/resource/{id}");
URI uri = uriBuilder.build(platform.getId());
- javax.ws.rs.core.Response.ResponseBuilder builder = Response.created(uri);
+ Response.ResponseBuilder builder = Response.created(uri);
builder.entity(rwt);
return builder.build();
@@ -587,21 +626,18 @@ public class ResourceHandlerBean extends AbstractRestBean {
Resource r = resMgr.getResourceByParentAndKey(caller,null,resourceKey,plugin,typeName);
if (r!=null) {
- // platform exists - return it
+ // resource exists - return it
ResourceWithType rwt = fillRWT(r,uriInfo);
UriBuilder uriBuilder = uriInfo.getBaseUriBuilder();
uriBuilder.path("/resource/{id}");
URI uri = uriBuilder.build(r.getId());
-
- javax.ws.rs.core.Response.ResponseBuilder builder = Response.ok(rwt);
- builder.location(uri);
+ Response.ResponseBuilder builder = Response.created(uri);
+ builder.entity(rwt);
return builder.build();
-
}
-
Resource res = new Resource(resourceKey,name,resType);
res.setUuid(resourceKey);
res.setAgent(parent.getAgent());
@@ -616,15 +652,30 @@ public class ResourceHandlerBean extends AbstractRestBean {
ResourceWithType rwt = fillRWT(res,uriInfo);
- javax.ws.rs.core.Response.ResponseBuilder builder = Response.ok(rwt);
+ UriBuilder uriBuilder = uriInfo.getBaseUriBuilder();
+ uriBuilder.path("/resource/{id}");
+ URI uri = uriBuilder.build(res.getId());
+
+ Response.ResponseBuilder builder = Response.created(uri);
+ builder.entity(rwt);
return builder.build();
} catch (ResourceAlreadyExistsException e) {
throw new IllegalArgumentException(e);
}
+ }
+ @DELETE
+ @Path("/{id}")
+ @ApiOperation("Remove a resource from inventory")
+ public Response uninventoryOrDeleteResource(
+ @PathParam("id") int resourceId
+ /*,@DefaultValue("false") @QueryParam("physical") boolean delete*/) {
- }
+ resMgr.uninventoryResource(caller,resourceId);
+
+ return Response.status(Response.Status.NO_CONTENT).build();
+ }
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/RootHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/RootHandlerBean.java
index 8d2f130..7998294 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/RootHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/RootHandlerBean.java
@@ -53,7 +53,7 @@ public class RootHandlerBean extends AbstractRestBean {
"dynaGroups","group/definitions",
"alerts","alert",
"status","status",
- "favoriteResource","user/favorites/resource",
+ "favoriteResources","user/favorites/resource",
"operationHistory","operation/history",
"self",""
};
@@ -87,6 +87,7 @@ public class RootHandlerBean extends AbstractRestBean {
} else if (mediaType.equals(MediaType.APPLICATION_XML_TYPE)) {
target += ".xml";
} else {
+ log.error("Unknown media type " + mediaType);
throw new WebApplicationException(Response.Status.NOT_ACCEPTABLE);
}
Link link = new Link(rel,target);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/UserHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/UserHandlerBean.java
index bdd613e..a0f1177 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/UserHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/UserHandlerBean.java
@@ -27,6 +27,8 @@ import java.util.TreeSet;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
@@ -53,9 +55,13 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.group.ResourceGroup;
+import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.resource.ResourceManagerLocal;
import org.rhq.enterprise.server.resource.ResourceNotFoundException;
+import org.rhq.enterprise.server.resource.group.ResourceGroupNotFoundException;
+import org.rhq.enterprise.server.rest.domain.GroupRest;
import org.rhq.enterprise.server.rest.domain.ResourceWithType;
import org.rhq.enterprise.server.rest.domain.UserRest;
@@ -90,6 +96,10 @@ public class UserHandlerBean extends AbstractRestBean {
@EJB
ResourceManagerLocal resourceManager;
+ @PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME)
+ private EntityManager entityManager;
+
+
@GZIP
@GET
@Path("favorites/resource")
@@ -102,10 +112,19 @@ public class UserHandlerBean extends AbstractRestBean {
MediaType mediaType = httpHeaders.getAcceptableMediaTypes().get(0);
for (Integer id : favIds) {
try {
- Resource res = resourceManager.getResource(caller,id);
+ /*
+ * In theory we should not have any bad resource ids in favorites, but ...
+ * First check if the resource exists, as otherwise resourceManager.getResource()
+ * throws an exception that seems to kill the transaction and backend connection
+ * See https://bugzilla.redhat.com/show_bug.cgi?id=886850
+ */
+ Resource res = entityManager.find(Resource.class,id);
+ if (res!=null) {
+ res = resourceManager.getResource(caller,id);
- ResourceWithType rwt = fillRWT(res,uriInfo);
- ret.add(rwt);
+ ResourceWithType rwt = fillRWT(res,uriInfo);
+ ret.add(rwt);
+ }
}
catch (Exception e) {
if (e.getCause()!=null && e.getCause() instanceof ResourceNotFoundException)
@@ -127,16 +146,82 @@ public class UserHandlerBean extends AbstractRestBean {
}
+ @GZIP
+ @GET
+ @Path("favorites/group")
+ @ApiOperation(value = "Return a list of favorite groups of the caller", multiValueResponse = true, responseClass = "GroupRest")
+ public Response getGroupFavorites(@Context UriInfo uriInfo, @Context HttpHeaders httpHeaders) {
+
+ Set<Integer> favIds = getGroupIdsForFavorites();
+ List<GroupRest> ret = new ArrayList<GroupRest>();
+
+ MediaType mediaType = httpHeaders.getAcceptableMediaTypes().get(0);
+ for (Integer id : favIds) {
+ try {
+ /*
+ * In theory we should not have any bad group ids in favorites, but ...
+ * First check if the group exists, as otherwise resourceGroupManager.getResourceGroup()
+ * throws an exception that seems to kill the transaction and backend connection
+ * See https://bugzilla.redhat.com/show_bug.cgi?id=886850
+ */
+ ResourceGroup res = entityManager.find(ResourceGroup.class,id);
+ if (res!=null) {
+ res = resourceGroupManager.getResourceGroup(caller, id);
+
+ GroupRest rwt = fillGroup(res, uriInfo);
+ ret.add(rwt);
+ }
+ }
+ catch (Exception e) {
+ if (e.getCause()!=null && e.getCause() instanceof ResourceGroupNotFoundException)
+ log.debug("Favorite group with id "+ id + " not found - not returning to the user");
+ else
+ log.warn("Retrieving group with id " + id + " failed: " + e.getLocalizedMessage());
+ }
+ }
+ Response.ResponseBuilder builder;
+ if (mediaType.equals(MediaType.TEXT_HTML_TYPE)) {
+ builder = Response.ok(renderTemplate("listGroup", ret), mediaType);
+ } else {
+ GenericEntity<List<GroupRest>> list = new GenericEntity<List<GroupRest>>(ret) {
+ };
+ builder = Response.ok(list);
+ }
+
+ return builder.build();
+
+ }
+
@PUT
@Path("favorites/resource/{id}")
@ApiOperation(value = "Add a resource as favorite for the caller")
public void addFavoriteResource(@ApiParam(name = "id", value = "Id of the resource")
- @PathParam("id") int id) {
+ @PathParam("id") int resourceId) {
+
+ // Check if the resource exists and throw an error if not
+ fetchResource(resourceId);
+
Set<Integer> favIds = getResourceIdsForFavorites();
- if (!favIds.contains(id)) {
- favIds.add(id);
- updateFavorites(favIds);
+ if (!favIds.contains(resourceId)) {
+ favIds.add(resourceId);
+ updateResourceFavorites(favIds);
+ }
+ }
+
+ @PUT
+ @Path("favorites/group/{id}")
+ @ApiOperation(value = "Add a group as favorite for the caller")
+ public void addFavoriteResourceGroup(@ApiParam(name = "id", value = "Id of the group")
+ @PathParam("id") int groupId) {
+
+ // Check if the resource exists and throw an error if not
+ fetchGroup(groupId, false);
+
+ Set<Integer> favIds = getGroupIdsForFavorites();
+ if (!favIds.contains(groupId)) {
+ favIds.add(groupId);
+ updateGroupFavorites(favIds);
}
}
@@ -148,9 +233,20 @@ public class UserHandlerBean extends AbstractRestBean {
Set<Integer> favIds = getResourceIdsForFavorites();
if (favIds.contains(id)) {
favIds.remove(id);
- updateFavorites(favIds);
+ updateResourceFavorites(favIds);
}
+ }
+ @DELETE
+ @Path("favorites/group/{id}")
+ @ApiOperation(value="Remove a group from favorites")
+ public void removeResourceGroupFromFavorites(@ApiParam(name="id", value = "Id of the group")
+ @PathParam("id") int id) {
+ Set<Integer> favIds = getGroupIdsForFavorites();
+ if (favIds.contains(id)) {
+ favIds.remove(id);
+ updateGroupFavorites(favIds);
+ }
}
@GET
@@ -182,15 +278,9 @@ public class UserHandlerBean extends AbstractRestBean {
return builder.build();
}
- private void updateFavorites(Set<Integer> favIds) {
+ private void updateResourceFavorites(Set<Integer> favIds) {
Configuration conf = caller.getUserConfiguration();
- StringBuilder builder = new StringBuilder();
- Iterator<Integer> iter = favIds.iterator();
- while (iter.hasNext()) {
- builder.append(iter.next());
- if (iter.hasNext())
- builder.append('|');
- }
+ StringBuilder builder = buildFavStringFromSet(favIds);
PropertySimple prop = conf.getSimple(RESOURCE_HEALTH_RESOURCES);
if (prop==null) {
conf.put(new PropertySimple(RESOURCE_HEALTH_RESOURCES,builder.toString()));
@@ -201,9 +291,35 @@ public class UserHandlerBean extends AbstractRestBean {
subjectManager.updateSubject(caller,caller);
}
+
+ private void updateGroupFavorites(Set<Integer> favIds) {
+ Configuration conf = caller.getUserConfiguration();
+ StringBuilder builder = buildFavStringFromSet(favIds);
+ PropertySimple prop = conf.getSimple(GROUP_HEALTH_GROUPS);
+ if (prop==null) {
+ conf.put(new PropertySimple(GROUP_HEALTH_GROUPS,builder.toString()));
+ } else {
+ prop.setStringValue(builder.toString());
+ }
+ caller.setUserConfiguration(conf);
+ subjectManager.updateSubject(caller,caller);
+ }
+
private Set<Integer> getResourceIdsForFavorites() {
Configuration conf = caller.getUserConfiguration();
String favsString = conf.getSimpleValue(RESOURCE_HEALTH_RESOURCES,"");
+ Set<Integer> favIds = getIdsFromFavString(favsString);
+ return favIds;
+ }
+
+ private Set<Integer> getGroupIdsForFavorites() {
+ Configuration conf = caller.getUserConfiguration();
+ String favsString = conf.getSimpleValue(GROUP_HEALTH_GROUPS,"");
+ Set<Integer> favIds = getIdsFromFavString(favsString);
+ return favIds;
+ }
+
+ private Set<Integer> getIdsFromFavString(String favsString) {
Set<Integer> favIds = new TreeSet<Integer>();
if (!favsString.isEmpty()) {
String[] favStringArray = favsString.split("\\|");
@@ -214,4 +330,15 @@ public class UserHandlerBean extends AbstractRestBean {
return favIds;
}
+ private StringBuilder buildFavStringFromSet(Set<Integer> favIds) {
+ StringBuilder builder = new StringBuilder();
+ Iterator<Integer> iter = favIds.iterator();
+ while (iter.hasNext()) {
+ builder.append(iter.next());
+ if (iter.hasNext())
+ builder.append('|');
+ }
+ return builder;
+ }
+
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/Baseline.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/Baseline.java
index 69623fb..ad5e43c 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/Baseline.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/Baseline.java
@@ -1,3 +1,25 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
package org.rhq.enterprise.server.rest.domain;
import javax.xml.bind.annotation.XmlRootElement;
@@ -9,7 +31,7 @@ import com.wordnik.swagger.annotations.ApiProperty;
* A baseline
* @author Heiko W. Rupp
*/
-@ApiClass("Representation of a metic baseline/-band")
+@ApiClass("Representation of a metric baseline/-band")
@XmlRootElement
public class Baseline {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/EventDefinitionRest.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/EventDefinitionRest.java
new file mode 100644
index 0000000..3154042
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/EventDefinitionRest.java
@@ -0,0 +1,74 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.enterprise.server.rest.domain;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import com.wordnik.swagger.annotations.ApiClass;
+import com.wordnik.swagger.annotations.ApiProperty;
+
+/**
+ * An Event definition
+ * @author Heiko W. Rupp
+ */
+@ApiClass(value = "An Event definition", description = "You can retrieve an EventDefinition and with its name create new EventSources for that resource")
+@XmlRootElement
+public class EventDefinitionRest {
+
+ int id;
+ String name;
+ String displayName;
+ String description;
+
+ public EventDefinitionRest() {
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ @ApiProperty("The name of the definition, used to create EventSources")
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public void setDisplayName(String displayName) {
+ this.displayName = displayName;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+}
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 3287750..a00e270 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
@@ -48,9 +48,8 @@ public class Link {
@Override
public String toString() {
- return "Link{" +
- "rel='" + rel + '\'' +
- ", href='" + href + '\'' +
- '}';
+ return
+ href + "; " +
+ "rel='" + rel + '\'' ;
}
}
diff --git a/modules/integration-tests/pom.xml b/modules/integration-tests/pom.xml
index 95d947a..4c31380 100644
--- a/modules/integration-tests/pom.xml
+++ b/modules/integration-tests/pom.xml
@@ -40,15 +40,15 @@
<name>integration.tests</name>
</property>
</activation>
-
+
<modules>
<module>apache-plugin-test</module>
<module>jndi-access</module>
<!--<module>mod_cluster-plugin-test</module>-->
- <!--<module>rest-api</module>-->
+ <module>rest-api</module>
</modules>
</profile>
-
+
<profile>
<id>code-coverage</id>
<activation>
@@ -62,7 +62,7 @@
<!--<module>mod_cluster-plugin-test</module>-->
<!--<module>rest-api</module>-->
</modules>
- </profile>
+ </profile>
</profiles>
diff --git a/modules/integration-tests/rest-api/pom.xml b/modules/integration-tests/rest-api/pom.xml
index a2e25f5..3ba07c4 100644
--- a/modules/integration-tests/rest-api/pom.xml
+++ b/modules/integration-tests/rest-api/pom.xml
@@ -18,6 +18,8 @@
<properties>
<surefire-plugin.version>2.10</surefire-plugin.version>
+ <jackson.version>1.9.5</jackson.version>
+ <rest-assured.version>1.7.2</rest-assured.version>
</properties>
<build>
@@ -39,18 +41,32 @@
</build>
<dependencies>
- <dependency>
- <groupId>com.restfuse</groupId>
- <artifactId>com.eclipsesource.restfuse</artifactId>
- <version>1.0.0</version>
+ <dependency>
+ <groupId>com.jayway.restassured</groupId>
+ <artifactId>rest-assured</artifactId>
+ <version>${rest-assured.version}</version>
<scope>test</scope>
- </dependency>
- <dependency>
+ </dependency>
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-core-asl</artifactId>
+ <version>${jackson.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-mapper-asl</artifactId>
+ <version>${jackson.version}</version>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
</project>
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
new file mode 100644
index 0000000..3dd20e2
--- /dev/null
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/AbstractBase.java
@@ -0,0 +1,48 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 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.modules.integrationTests.restApi;
+
+import com.jayway.restassured.RestAssured;
+import com.jayway.restassured.response.Header;
+
+import org.junit.Before;
+
+import static com.jayway.restassured.RestAssured.basic;
+
+/**
+ * Common setup for the tests
+ * @author Heiko W. Rupp
+ */
+public abstract class AbstractBase {
+
+ static final String APPLICATION_JSON = "application/json";
+ private static final String APPLICATION_XML = "application/xml";
+ static Header acceptJson = new Header("Accept", APPLICATION_JSON);
+ static Header acceptXml = new Header("Accept", APPLICATION_XML);
+
+ @Before
+ public void setUp() throws Exception {
+
+ RestAssured.baseURI = "http://" + System.getProperty("rest.server","localhost") ;
+ RestAssured.port = 7080;
+ RestAssured.basePath = "/rest/";
+ RestAssured.authentication = basic("rhqadmin","rhqadmin");
+
+ }
+}
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
new file mode 100644
index 0000000..697d6f0
--- /dev/null
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/EventTest.java
@@ -0,0 +1,223 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 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.modules.integrationTests.restApi;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import com.jayway.restassured.http.ContentType;
+import com.jayway.restassured.response.Response;
+
+import org.junit.Test;
+
+import org.rhq.modules.integrationTests.restApi.d.Event;
+import org.rhq.modules.integrationTests.restApi.d.EventSource;
+
+import static com.jayway.restassured.RestAssured.given;
+
+/**
+ * Test the event endpoints of the REST api
+ * @author Heiko W. Rupp
+ */
+public class EventTest extends AbstractBase {
+
+ @Test
+ public void testGetSourcesForResource() throws Exception {
+
+ given()
+ .header(acceptJson)
+ .pathParam("id",10001)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .get("/event/{id}/sources");
+
+ }
+
+ @Test
+ public void testGetDefinitionsForResource() throws Exception {
+
+ given()
+ .header(acceptJson)
+ .pathParam("id",10001)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .get("/event/{id}/definitions");
+
+ }
+
+ @Test
+ public void testAddGetDeleteEventSource() throws Exception {
+
+ EventSource es = new EventSource();
+ es.setResourceId(10001);
+ es.setName("Event Log"); // Name of the event definition
+ es.setLocation("-x-test-location");
+
+ Response response =
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .pathParam("id",10001)
+ .body(es)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .post("/event/{id}/sources");
+
+ EventSource result = response.as(EventSource.class);
+
+ try {
+
+ // Directly find our generated source
+
+ response =
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .pathParam("id",result.getId())
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .get("/event/source/{id}");
+
+ EventSource ev2 = response.as(EventSource.class);
+ assert result.equals(ev2);
+
+ // Search in the list for the resource
+ response =
+ given()
+ .header(acceptJson)
+ .pathParam("id",10001)
+ .expect()
+ .statusCode(200)
+ .when()
+ .get("/event/{id}/sources");
+
+ List<Map<String,Object>> listOfMaps = response.as(List.class);
+ boolean found = false;
+ for (Map<String,Object> map: listOfMaps) {
+ if (map.get("id").equals(result.getId()) && map.get("name").equals(result.getName()))
+ found=true;
+ }
+ assert found;
+ }
+ finally {
+
+ // Delete the source again
+ given()
+ .pathParam("id", result.getId())
+ .expect()
+ .statusCode(200)
+ .when()
+ .delete("/event/source/{id}");
+ }
+ }
+ @Test
+ public void testAddGetEventOnSource() throws Exception {
+
+ EventSource es = new EventSource();
+ es.setResourceId(10001);
+ es.setName("Event Log"); // Name of the event definition
+ es.setLocation("-x-test-location");
+
+ Response response =
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .pathParam("id",10001)
+ .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 :->");
+ List<Event> events = new ArrayList<Event>(1);
+ events.add(event);
+
+ 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()
+ .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", 10001)
+ .queryParam("startTime",now - 10)
+ .queryParam("endTime",now + 10)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .get("/event/{id}/events");
+ list = response.as(List.class);
+ assert list.size()>0;
+
+
+ }
+ finally {
+
+ // Delete the source again
+ given()
+ .pathParam("id", eventSource.getId())
+ .expect()
+ .statusCode(200)
+ .when()
+ .delete("/event/source/{id}");
+ }
+ }
+}
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/GetStatusTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/GetStatusTest.java
deleted file mode 100644
index 570e2bf..0000000
--- a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/GetStatusTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2012 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License and the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.rhq.modules.integrationTests.restApi;
-
-
-import com.eclipsesource.restfuse.AuthenticationType;
-import com.eclipsesource.restfuse.Destination;
-import com.eclipsesource.restfuse.HttpJUnitRunner;
-import com.eclipsesource.restfuse.Method;
-import com.eclipsesource.restfuse.Response;
-import com.eclipsesource.restfuse.annotation.Authentication;
-import com.eclipsesource.restfuse.annotation.Context;
-import com.eclipsesource.restfuse.annotation.HttpTest;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Test the status part of the API
- */
-(a)RunWith(HttpJUnitRunner.class)
-public class GetStatusTest {
-
-
-
- @Rule
- public Destination destination = new Destination("http://" + System.getProperty("rest.server","localhost") + ":7080/rest");
-
- @Context
- private Response response;
-
-
- @Test
- @HttpTest( method = Method.GET, path = "/status" )
- public void testAuthRequired() {
- com.eclipsesource.restfuse.Assert.assertUnauthorized(response);
- }
-
-
- @Test
- @HttpTest( method = Method.GET, path = "/status" ,authentications =
- @Authentication(type = AuthenticationType.BASIC, user = "rhqadmin", password = "rhqadmin")
- )
- public void testAuthRhqadmin() {
- com.eclipsesource.restfuse.Assert.assertOk(response);
- }
-
- @Test
- @HttpTest( method = Method.GET, path = "/status" ,authentications =
- @Authentication(type = AuthenticationType.BASIC, user = "user", password = "name23")
- )
- public void testAuthRestricted() {
- com.eclipsesource.restfuse.Assert.assertUnauthorized(response);
- }
-
-
-}
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
new file mode 100644
index 0000000..2194281
--- /dev/null
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/GroupTest.java
@@ -0,0 +1,469 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 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.modules.integrationTests.restApi;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.jayway.restassured.http.ContentType;
+import com.jayway.restassured.path.json.JsonPath;
+import com.jayway.restassured.response.Response;
+
+import org.apache.http.HttpStatus;
+import org.junit.Test;
+
+import org.rhq.modules.integrationTests.restApi.d.Group;
+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.is;
+
+/**
+ * Test group related stuff
+ * @author Heiko W. Rupp
+ */
+public class GroupTest extends AbstractBase {
+
+ @Test
+ public void testGetGroups() throws Exception {
+ expect().statusCode(200)
+ .when().get("/group");
+ }
+
+ @Test
+ public void testGetGroupsQuery() throws Exception {
+ given()
+ .queryParam("q","lala")
+ .expect()
+ .statusCode(200)
+ .when().get("/group");
+ }
+
+ @Test
+ public void testCreateGroupAndRemove() throws Exception {
+ Group group = new Group("-x-test-group");
+
+ // create the group
+ Response created =
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .body(group)
+ .expect()
+ .statusCode(HttpStatus.SC_CREATED)
+ .log().ifError()
+ .when()
+ .post("/group");
+
+ // Determine location from response
+ // and compare id with the found group below
+ String location = created.header("Location");
+ int createdId = Integer.parseInt(location.substring(location.lastIndexOf("/")+1));
+
+ // Search for it
+ Response response =
+ given()
+ .queryParam("q", "-x-test-group")
+ .expect()
+ .statusCode(200)
+ .when()
+ .get("/group");
+
+ JsonPath jsonPath = response.jsonPath();
+ assert jsonPath.get("[0].name").equals("-x-test-group"); // [0] as the query returns a list
+ int groupId = jsonPath.get("[0].id");
+ assert groupId == createdId;
+
+ // delete the group again
+ given()
+ .pathParam("id",groupId)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .delete("/group/{id}");
+
+ }
+
+ @Test
+ public void testUpdateGroup() throws Exception {
+ Group group = new Group("-x-test-group");
+
+ // Generate the group
+ Response response =
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .body(group)
+ .expect()
+ .statusCode(HttpStatus.SC_CREATED)
+ .log().ifError()
+ .when()
+ .post("/group");
+
+ String location = response.header("Location");
+ int id = Integer.parseInt(location.substring(location.lastIndexOf("/")+1));
+
+ try {
+ group.setName("-x-test-2");
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .body(group)
+ .pathParam("id",id)
+ .expect()
+ .statusCode(HttpStatus.SC_OK)
+ .log().ifError()
+ .when()
+ .put("/group/{id}");
+ }
+ finally {
+ // delete the group
+ given()
+ .pathParam("id", id)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .delete("/group/{id}");
+ }
+ }
+
+ @Test
+ public void testAddResourceToGroup() throws Exception {
+ Group group = new Group("-x-test-group");
+
+ // Generate the group
+ Response response =
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .body(group)
+ .expect()
+ .statusCode(HttpStatus.SC_CREATED)
+ .log().ifError()
+ .when()
+ .post("/group");
+
+ String location = response.header("Location");
+ int id = Integer.parseInt(location.substring(location.lastIndexOf("/")+1));
+
+ try {
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .body(group)
+ .pathParam("id",id)
+ .pathParam("resourceId",10001)
+ .expect()
+ .statusCode(HttpStatus.SC_OK)
+ .log().ifError()
+ .when()
+ .put("/group/{id}/resource/{resourceId}");
+ }
+ finally {
+ // delete the group
+ given()
+ .pathParam("id",id)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .delete("/group/{id}");
+ }
+ }
+
+ @Test
+ public void testAddNonExistingResourceToGroup() throws Exception {
+ Group group = new Group("-x-test-group");
+
+ // Generate the group
+ Response response =
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .body(group)
+ .expect()
+ .statusCode(HttpStatus.SC_CREATED)
+ .log().ifError()
+ .when()
+ .post("/group");
+
+ String location = response.header("Location");
+ int id = Integer.parseInt(location.substring(location.lastIndexOf("/")+1));
+
+ try {
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .body(group)
+ .pathParam("id",id)
+ .pathParam("resourceId",1)
+ .expect()
+ .statusCode(HttpStatus.SC_NOT_FOUND)
+ .log().ifError()
+ .when()
+ .put("/group/{id}/resource/{resourceId}");
+ }
+ finally {
+ // delete the group
+ given()
+ .pathParam("id",id)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .delete("/group/{id}");
+ }
+ }
+
+ @Test
+ public void testRemoveResourceFromGroup() throws Exception {
+ Group group = new Group("-x-test-group");
+
+ // Generate the group
+ Response response =
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .body(group)
+ .expect()
+ .statusCode(HttpStatus.SC_CREATED)
+ .log().ifError()
+ .when()
+ .post("/group");
+
+ String location = response.header("Location");
+ int id = Integer.parseInt(location.substring(location.lastIndexOf("/")+1));
+
+ try {
+ // Add a resource to the group
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .body(group)
+ .pathParam("id",id)
+ .pathParam("resourceId",10001)
+ .expect()
+ .statusCode(HttpStatus.SC_OK)
+ .log().ifError()
+ .when()
+ .put("/group/{id}/resource/{resourceId}");
+
+ // and remove it again
+ given()
+ .header(acceptJson)
+ .pathParam("id",id)
+ .pathParam("resourceId",10001)
+ .expect()
+ .statusCode(HttpStatus.SC_OK)
+ .log().ifError()
+ .when()
+ .delete("/group/{id}/resource/{resourceId}");
+
+ }
+ finally {
+ // delete the group
+ given()
+ .pathParam("id",id)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .delete("/group/{id}");
+ }
+ }
+
+ @Test
+ public void testGetMetricDefinitionsForGroup() throws Exception {
+ Group group = new Group("-x-test-group");
+ group.setCategory("COMPATIBLE");
+ group.setResourceTypeId(10001);
+
+ // Generate the group
+ Response response =
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .body(group)
+ .log().everything()
+ .expect()
+ .statusCode(HttpStatus.SC_CREATED)
+ .log().ifError()
+ .when()
+ .post("/group");
+
+ String location = response.header("Location");
+ int id = Integer.parseInt(location.substring(location.lastIndexOf("/")+1));
+
+ try {
+ response =
+ given()
+ .header(acceptJson)
+ .pathParam("id",id)
+ .expect()
+ .statusCode(HttpStatus.SC_OK)
+ .log().ifError()
+ .when()
+ .get("/group/{id}/metricDefinitions");
+
+ }
+ finally {
+ // delete the group
+ given()
+ .pathParam("id",id)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .delete("/group/{id}");
+ }
+ }
+
+ @Test
+ public void testGetGroupDefinitions() throws Exception {
+
+ expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .get("/group/definitions");
+ }
+
+ @Test
+ public void testCreateRetrieveDeleteDefinition() throws Exception {
+
+ GroupDef gd = new GroupDef("-x-test-def");
+ gd.setDescription("Just testing");
+ List<String> list = new ArrayList<String>();
+ list.add("groupby resource");
+ list.add("resource.name");
+ gd.setExpression(list);
+
+ Response response =
+ given()
+ .contentType(ContentType.JSON)
+ .header("Accept","application/json")
+ .body(gd)
+ .expect()
+ .statusCode(201)
+ .log().ifError()
+ .when()
+ .post("/group/definitions");
+
+
+ String location = response.getHeader("Location");
+ int defintionId = Integer.parseInt(location.substring(location.lastIndexOf("/")+1));
+
+ try {
+ // retrieve by id
+ given()
+ .pathParam("id", defintionId)
+ .expect()
+ .statusCode(200)
+ .when()
+ .get("/group/definition/{id}");
+
+ // retrieve by query
+ Response resp =
+ given()
+ .queryParam("q", "-x-test-def")
+ .expect()
+ .statusCode(200)
+ .body("name", hasItem("-x-test-def"))
+ .log().ifError()
+ .when()
+ .get("/group/definitions");
+ } finally {
+
+ // remove the definition again
+ expect()
+ .statusCode(204)
+ .when()
+ .delete("/group/definition/" + defintionId);
+ }
+
+ }
+
+ @Test
+ public void testCreateUpdateRecalcDeleteDefinition() throws Exception {
+
+ GroupDef gd = new GroupDef("-x-test-def2");
+ gd.setDescription("Just testing");
+ List<String> list = new ArrayList<String>();
+ list.add("groupby resource.trait[partitionName]");
+ list.add("resource.type.plugin = JBossAS");
+ list.add("resource.type.name = JBossAS Server");
+ gd.setExpression(list);
+
+ Response response =
+ given()
+ .contentType(ContentType.JSON)
+ .header("Accept","application/json")
+ .body(gd)
+ .expect()
+ .statusCode(201)
+ .log().ifError()
+ .when()
+ .post("/group/definitions");
+
+
+ String location = response.getHeader("Location");
+ int defintionId = Integer.parseInt(location.substring(location.lastIndexOf("/")+1));
+
+ try {
+ gd.setDescription("Hulla");
+ list = new ArrayList<String>(1);
+ list.add("groupby resource.pluginConfiguration[productType]");
+ gd.setExpression(list);
+
+ given()
+ .contentType(ContentType.JSON)
+ .header("Accept", "application/json")
+ .body(gd)
+ .pathParam("id", defintionId)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .put("/group/definition/{id}");
+
+ given()
+ .contentType(ContentType.JSON)
+ .header("Accept","application/json")
+ .body(gd) // needs to be supplied as dummy
+ .pathParam("id", defintionId)
+ .queryParam("recalculate",true)
+ .expect()
+ .statusCode(204)
+ .log().ifError()
+ .when()
+ .put("/group/definition/{id}");
+ }
+ finally {
+
+ expect()
+ .statusCode(204)
+ .when()
+ .delete("/group/definition/" + defintionId);
+ }
+ }
+}
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/MetricsTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/MetricsTest.java
new file mode 100644
index 0000000..28fa806
--- /dev/null
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/MetricsTest.java
@@ -0,0 +1,361 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 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.modules.integrationTests.restApi;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import com.jayway.restassured.http.ContentType;
+import com.jayway.restassured.path.json.JsonPath;
+import com.jayway.restassured.response.Response;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.rhq.modules.integrationTests.restApi.d.Baseline;
+import org.rhq.modules.integrationTests.restApi.d.MDataPoint;
+import org.rhq.modules.integrationTests.restApi.d.Schedule;
+
+import static com.jayway.restassured.RestAssured.given;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+
+/**
+ * Test stuff related to metrics
+ * @author Heiko W. Rupp
+ */
+public class MetricsTest extends AbstractBase {
+
+ private int numericScheduleId;
+ private long defaultInterval;
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();// is not called by junit before this one
+
+ // Determine a schedule id for the common cases
+ Response r =
+ given()
+ .header(acceptJson)
+ .queryParam("type", "metric")
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .get("/resource/10001/schedules");
+
+ JsonPath jp = r.jsonPath();
+ numericScheduleId = jp.getInt("[0].scheduleId");
+ defaultInterval = jp.getLong("[0].collectionInterval");
+ }
+
+ @Test
+ public void testGetScheduleById() throws Exception {
+
+ given()
+ .header(acceptJson)
+ .pathParam("id", numericScheduleId)
+ .expect()
+ .statusCode(200)
+ .body("scheduleId", containsString("" + numericScheduleId))
+ .log().ifError()
+ .when()
+ .get("/metric/schedule/{id}");
+
+ }
+
+ @Test
+ public void testPutGetRawData() throws Exception {
+
+ long now = System.currentTimeMillis();
+
+ MDataPoint dataPoint = new MDataPoint();
+ dataPoint.setScheduleId(numericScheduleId);
+ dataPoint.setTimeStamp(now);
+ dataPoint.setValue(1.5);
+
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .pathParam("id", numericScheduleId)
+ .pathParam("timestamp",now)
+ .body(dataPoint)
+ .expect()
+ .statusCode(201)
+ .log().ifError()
+ .when()
+ .put("/metric/data/{id}/raw/{timestamp}");
+
+ Response response =
+ given()
+ .header(acceptJson)
+ .pathParam("id", numericScheduleId)
+ .queryParam("startTime",now - 10)
+ .queryParam("endTime",now + 10)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .get("/metric/data/{id}/raw");
+
+ List<Map<String,Object>> list = response.as(List.class);
+ assert list.size()>0;
+
+ boolean found = false;
+ for (Map<String, Object> map : list) {
+ MDataPoint mp = new MDataPoint(map);
+ if (mp.equals(dataPoint))
+ found = true;
+ }
+ assert found;
+
+ }
+
+ @Test
+ public void testPostGetRawData() throws Exception {
+
+ long now = System.currentTimeMillis();
+
+ MDataPoint dataPoint = new MDataPoint();
+ dataPoint.setScheduleId(numericScheduleId);
+ dataPoint.setTimeStamp(now);
+ dataPoint.setValue(1.5);
+ List<MDataPoint> points = new ArrayList<MDataPoint>(1);
+ points.add(dataPoint);
+
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .body(points)
+ .expect()
+ .statusCode(204)
+ .log().ifError()
+ .when()
+ .post("/metric/data/raw");
+
+ Response response =
+ given()
+ .header(acceptJson)
+ .pathParam("id", numericScheduleId)
+ // no start and end time -> last 8h of data
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .get("/metric/data/{id}/raw");
+
+ List<Map<String,Object>> list = response.as(List.class);
+ assert list.size()>0 : "No data retrieved";
+
+ boolean found = false;
+ for (Map<String, Object> map : list) {
+ MDataPoint mp = new MDataPoint(map);
+ if (mp.equals(dataPoint))
+ found = true;
+ }
+ assert found;
+
+ }
+
+ @Test
+ public void testUpdateSchedule() throws Exception {
+
+ Schedule schedule = new Schedule();
+ schedule.setCollectionInterval(1234567);
+ schedule.setEnabled(true);
+
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .pathParam("id", numericScheduleId)
+ .body(schedule)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .put("/metric/schedule/{id}");
+
+ // reset to original interval
+
+ schedule.setCollectionInterval(defaultInterval);
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .pathParam("id", numericScheduleId)
+ .body(schedule)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .put("/metric/schedule/{id}");
+
+ }
+
+ @Test
+ public void testAddGetTrait() throws Exception {
+ // Determine a trait schedule
+ Response r =
+ given()
+ .header(acceptJson)
+ .queryParam("type", "trait")
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .get("/resource/10001/schedules");
+
+ JsonPath jp = r.jsonPath();
+ int tsId = jp.getInt("[0].scheduleId");
+
+ String trait = "{\"value\":\"Hello World!\" }";
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .body(trait)
+ .pathParam("id",tsId)
+ .expect()
+ .statusCode(200) // TODO 201 ?
+ .log().ifError()
+ .when()
+ .put("/metric/data/{id}/trait");
+
+ given()
+ .header(acceptJson)
+ .pathParam("id",tsId)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .body("value",is("Hello World!"))
+ .when()
+ .get("/metric/data/{id}/trait");
+
+ }
+
+ @Test
+ public void testSetGetBaseline() throws Exception {
+
+ long now = System.currentTimeMillis();
+
+ Baseline baseline = new Baseline(0.0,2.0,1.0,now);
+
+ given()
+ .contentType(ContentType.XML)
+ .header(acceptJson)
+ .body(baseline)
+ .pathParam("sid", numericScheduleId)
+ .expect()
+ .statusCode(201)
+ .log().ifError()
+ .when()
+ .put("/metric/data/{sid}/baseline");
+
+ Baseline result =
+ given()
+ .header(acceptJson)
+ .pathParam("sid",numericScheduleId)
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .get("/metric/data/{sid}/baseline")
+ .as(Baseline.class);
+
+ assert result.equals(baseline);
+ }
+
+ @Test
+ public void testSetBadBaseline() throws Exception {
+
+ long now = System.currentTimeMillis();
+
+ Baseline baseline = new Baseline(10.0,1.0,2.0,now);
+
+ given()
+ .contentType(ContentType.JSON)
+ .header(acceptJson)
+ .body(baseline)
+ .pathParam("sid", numericScheduleId)
+ .expect()
+ .statusCode(406)
+ .log().ifError()
+ .when()
+ .put("/metric/data/{sid}/baseline");
+ }
+
+ @Test
+ public void testGetAggregate() throws Exception {
+
+ long now = System.currentTimeMillis();
+
+ Response r =
+ given()
+ .header(acceptJson)
+ .pathParam("scheduleId", numericScheduleId)
+ .expect()
+ .statusCode(200)
+ .body("scheduleId", is(numericScheduleId))
+ .body("numDataPoints", is(60))
+ .log().ifError()
+ .when()
+ .get("/metric/data/{scheduleId}");
+
+ Map map = r.as(Map.class);
+ List<MDataPoint> points = (List<MDataPoint>) map.get("dataPoints");
+ assert points.size()==60;
+
+ }
+
+// @Test Not yet - see https://bugzilla.redhat.com/show_bug.cgi?id=835647 TODO
+ public void testGetAggregate120Points() throws Exception {
+
+ long now = System.currentTimeMillis();
+
+ Response r =
+ given()
+ .header(acceptJson)
+ .pathParam("scheduleId", numericScheduleId)
+ .queryParam("dataPoints",120)
+ .expect()
+ .statusCode(200)
+ .body("scheduleId", is(numericScheduleId))
+ .body("numDataPoints", is(120))
+ .log().ifError()
+ .when()
+ .get("/metric/data/{scheduleId}");
+
+ Map map = r.as(Map.class);
+ List<MDataPoint> points = (List<MDataPoint>) map.get("dataPoints");
+ assert points.size()==120;
+
+ }
+ @Test
+ public void testGetAggregateMinusOnePoints() throws Exception {
+
+ given()
+ .header(acceptJson)
+ .pathParam("scheduleId", numericScheduleId)
+ .queryParam("dataPoints",-1)
+ .expect()
+ .statusCode(406)
+ .when()
+ .get("/metric/data/{scheduleId}");
+ }
+}
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 ca63c32..f6164ba 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
@@ -22,83 +22,253 @@
*/
package org.rhq.modules.integrationTests.restApi;
-import com.eclipsesource.restfuse.AuthenticationType;
-import com.eclipsesource.restfuse.Destination;
-import com.eclipsesource.restfuse.HttpJUnitRunner;
-import com.eclipsesource.restfuse.Method;
-import com.eclipsesource.restfuse.Response;
-import com.eclipsesource.restfuse.annotation.Authentication;
-import com.eclipsesource.restfuse.annotation.Context;
-import com.eclipsesource.restfuse.annotation.Header;
-import com.eclipsesource.restfuse.annotation.HttpTest;
-
-import org.junit.Rule;
+
+import com.jayway.restassured.http.ContentType;
+import com.jayway.restassured.path.json.JsonPath;
+import com.jayway.restassured.response.Response;
+
+import org.apache.http.HttpStatus;
+import org.hamcrest.CoreMatchers;
import org.junit.Test;
-import org.junit.runner.RunWith;
-import static junit.framework.Assert.assertTrue;
+import static com.jayway.restassured.RestAssured.expect;
+import static com.jayway.restassured.RestAssured.get;
+import static com.jayway.restassured.RestAssured.given;
+import static com.jayway.restassured.RestAssured.with;
+import static org.hamcrest.CoreMatchers.containsString;
/**
* Test the resources part
* @author Heiko W. Rupp
*/
-(a)RunWith(HttpJUnitRunner.class)
-public class ResourcesTest {
+public class ResourcesTest extends AbstractBase {
- @Rule
- public Destination destination = new Destination("http://" + System.getProperty("rest.server","localhost") + ":7080/rest");
+ @Test
+ public void testPlatformsPresent() {
+ expect()
+ .statusCode(200)
+ .body("links[0].rel", CoreMatchers.hasItem("self"))
+ .when()
+ .get("/resource/platforms.json");
+ }
- @Context
- private Response response;
+ @Test
+ public void testGetPlatformJson() {
+ given()
+ .header("Accept","application/json")
+ .expect()
+ .statusCode(200)
+ .contentType(ContentType.JSON)
+ .body("links.rel", CoreMatchers.hasItem("self"))
+ .when()
+ .get("/resource/10001");
- @HttpTest( method = Method.GET, path = "/resource/platforms" )
- public void testAuthRequired() {
- com.eclipsesource.restfuse.Assert.assertUnauthorized(response);
}
- @HttpTest( method = Method.GET, path = "/resource/platforms",authentications =
- @Authentication(type = AuthenticationType.BASIC, user = "rhqadmin", password = "rhqadmin")
- )
- public void testPlatformsPresent() {
- com.eclipsesource.restfuse.Assert.assertOk(response);
- assertTrue(response.hasBody());
+ @Test
+ public void testResourceQuery() throws Exception {
+ String json = get("/resource/platforms.json").asString();
+ String platformName = JsonPath.with(json).get("[0].resourceName");
+
+ given()
+ .header("Accept","application/json")
+ .with()
+ .queryParam("q",platformName)
+ .queryParam("category","platform")
+ .expect()
+ .statusCode(200)
+ .body("links[0].rel", CoreMatchers.hasItem("self"))
+ .when()
+ .get("/resource");
}
- @HttpTest( method = Method.GET, path = "/resource/10001",authentications =
- @Authentication(type = AuthenticationType.BASIC, user = "rhqadmin", password = "rhqadmin"),
- headers = {@Header(name = "Accept",value ="application/json")}
- )
- public void testGetPlatformJson() {
- com.eclipsesource.restfuse.Assert.assertOk(response);
- assertTrue(response.hasBody());
+ @Test
+ public void testResourceQueryCategory() throws Exception {
+
+ with()
+ .queryParam("category","PlAtForM")
+ .expect()
+ .statusCode(200)
+ .when()
+ .get("/resource");
+
+
+ with()
+ .queryParam("category","SeRvEr")
+ .expect()
+ .statusCode(200)
+ .when()
+ .get("/resource");
+
+
+ with()
+ .queryParam("category", "seRVice")
+ .expect()
+ .statusCode(200)
+ .when()
+ .get("/resource");
+ }
+
+ @Test
+ public void testPaging() throws Exception {
+
+ given()
+ .header("Accept", "application/json")
+ .with()
+ .queryParam("page", 1)
+ .queryParam("ps", 2) // Unusually small to provoke having more than 1 page
+ .queryParam("category", "service")
+ .expect()
+ .statusCode(200)
+ .header("Link", containsString("page=2"))
+ .body("links[0].rel", CoreMatchers.hasItem("self"))
+ .when().get("/resource");
}
- @HttpTest( method = Method.GET, path = "/resource/10001",authentications =
- @Authentication(type = AuthenticationType.BASIC, user = "rhqadmin", password = "rhqadmin"),
- headers = {@Header(name = "Accept",value ="application/xml")}
- )
+ @Test
public void testGetPlatformXml() {
- com.eclipsesource.restfuse.Assert.assertOk(response);
- assertTrue(response.hasBody());
+ given()
+ .header("Accept","application/xml")
+ .expect()
+ .statusCode(200)
+ .contentType(ContentType.XML)
+ .when()
+ .get("/resource/10001");
}
- @HttpTest( method = Method.GET, path = "/resource/10001/schedules",authentications =
- @Authentication(type = AuthenticationType.BASIC, user = "rhqadmin", password = "rhqadmin"),
- headers = {@Header(name = "Accept",value ="application/json")}
- )
+ @Test
public void testGetPlatformSchedules() {
- com.eclipsesource.restfuse.Assert.assertOk(response);
- assertTrue(response.hasBody());
+ given()
+ .header("Accept","application/json")
+ .expect()
+ .statusCode(200)
+ .when()
+ .get("/resource/10001/schedules");
}
- @HttpTest( method = Method.GET, path = "/resource/10001/children",authentications =
- @Authentication(type = AuthenticationType.BASIC, user = "rhqadmin", password = "rhqadmin"),
- headers = {@Header(name = "Accept",value ="application/json")}
- )
+ @Test
public void testGetPlatformChildren() {
- com.eclipsesource.restfuse.Assert.assertOk(response);
- assertTrue(response.hasBody());
+ given()
+ .header("Accept","application/json")
+ .expect()
+ .statusCode(200)
+ .when()
+ .get("/resource/10001/children");
}
+ @Test
+ public void testCreatePlatform() throws Exception {
+
+ given().body("{\"value\":\"Linux\"}")
+ .header("Content-Type","application/json")
+ .header("Accept","application/json")
+ .expect().statusCode(201)
+ .when().post("/resource/platform/api-test-dummy");
+ }
+
+ @Test
+ public void testCreatePlatformAndRemove() throws Exception {
+
+ Response response =
+ with().body("{\"value\":\"Linux\"}")
+ .header("Content-Type","application/json")
+ .header("Accept","application/json")
+ .expect().statusCode(201)
+ .when().post("/resource/platform/api-test-dummy").andReturn();
+
+ String platformId = response.jsonPath().getString("resourceId");
+
+ given().pathParam("id",platformId)
+ .expect().statusCode(HttpStatus.SC_NO_CONTENT)
+ .when().delete("/resource/{id}");
+ }
+
+ @Test
+ public void testCreatePlatformWithChildAndRemove() throws Exception {
+
+ Response response =
+ with().body("{\"value\":\"Linux\"}")
+ .header("Content-Type","application/json")
+ .header("Accept","application/json")
+ .expect()
+ .statusCode(201)
+ .when()
+ .post("/resource/platform/api-test-dummy");
+
+ String platformId = response.jsonPath().getString("resourceId");
+
+ try {
+ Response child =
+ with().body("{\"value\":\"CPU\"}") // Type of new resource
+ .header("Content-Type", "application/json")
+ .header("Accept", "application/json")
+ .pathParam("name", "test")
+ .queryParam("plugin", "Platforms")
+ .queryParam("parentId", platformId)
+ .expect()
+ .statusCode(201)
+ .log().ifError()
+ .when().post("/resource/{name}").andReturn();
+ }
+ finally {
+ given().pathParam("id",platformId)
+ .expect().statusCode(HttpStatus.SC_NO_CONTENT)
+ .when().delete("/resource/{id}");
+ }
+ }
+
+ @Test
+ public void testAlertsForResource() throws Exception {
+ given()
+ .header("Accept","application/json")
+ .expect().statusCode(200)
+ .when().get("/resource/10001/alerts");
+ }
+
+ @Test
+ public void testSchedulesForResource() throws Exception {
+ given()
+ .header("Accept","application/json")
+ .expect().statusCode(200)
+ .when().get("/resource/10001/schedules");
+ }
+
+ @Test
+ public void testAvailabilityForResource() throws Exception {
+ given()
+ .header("Accept", "application/json")
+ .expect().statusCode(200)
+ .when().get("/resource/10001/availability");
+ }
+
+ @Test
+ public void testAvailabilityHistoryForResource() throws Exception {
+ given()
+ .header("Accept", "application/json")
+ .expect().statusCode(200)
+ .when().get("/resource/10001/availability/history");
+ }
+
+ @Test
+ public void testUpdateAvailablity() throws Exception {
+ long now = System.currentTimeMillis()-100;
+ given().body("{\"since\":" + now + ",\"type\":\"DISABLED\",\"resourceId\":10001}")
+ .header("Content-Type","application/json")
+ .header("Accept","application/json")
+ .pathParam("id",10001)
+ .expect()
+ .statusCode(HttpStatus.SC_NO_CONTENT)
+ .log().ifError()
+ .when().put("/resource/{id}/availability");
+
+ Response response = given()
+ .header("Accept", "application/json")
+ .expect().statusCode(200)
+ .when().get("/resource/10001/availability");
+
+ String currentType = response.jsonPath().get("type");
+ assert currentType.equals("DISABLED"); // TODO small window where an agent may have sent an update
+
+ }
}
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/RootURITest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/RootURITest.java
new file mode 100644
index 0000000..35111f0
--- /dev/null
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/RootURITest.java
@@ -0,0 +1,112 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 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.modules.integrationTests.restApi;
+
+import java.util.List;
+import java.util.Map;
+
+import com.jayway.restassured.path.json.JsonPath;
+
+import org.junit.Test;
+
+import static com.jayway.restassured.RestAssured.expect;
+import static com.jayway.restassured.RestAssured.get;
+import static com.jayway.restassured.RestAssured.given;
+
+/**
+ * Test the / resource (http://localhost:7080/rest/ )
+ * @author Heiko W. Rupp
+ */
+public class RootURITest extends AbstractBase {
+
+ @Test
+ public void testRootPresent() throws Exception {
+
+ given().header("Accept","text/html")
+ .expect().statusCode(200)
+ .when().get("/");
+
+ given().header("Accept","text/html")
+ .expect().statusCode(200)
+ .when().get("/index");
+
+ given().header("Accept","application/json")
+ .expect().statusCode(200)
+ .when().get("/");
+
+ given().header("Accept","application/json")
+ .expect().statusCode(200)
+ .when().get("/index");
+
+ expect().statusCode(200)
+ .when().get("/.json");
+
+ expect().statusCode(200)
+ .when().get("/.xml");
+
+ expect().statusCode(200)
+ .when().get("/.html");
+
+ expect().statusCode(200)
+ .when().get("/index.json");
+
+ expect().statusCode(200)
+ .when().get("/index.xml");
+
+ expect().statusCode(200)
+ .when().get("/index.html");
+
+ }
+
+ @Test
+ public void testLinksInRoot() throws Exception {
+
+ String json = get("/index.json").asString();
+ List<Map<String,String>> links = JsonPath.with(json).getList(""); // with() already returns the list
+
+ assert links != null;
+ assert links.size()>0;
+
+ String[] mediaTypes = {"text/html","application/xml","application/json"};
+
+ for (Map<String,String> link : links) {
+ String href= link.get("href");
+
+ for (String mediaType : mediaTypes) {
+ given().header("Accept",mediaType)
+ .expect().statusCode(200)
+ .log().ifError()
+ .when().get(href);
+ }
+ }
+ }
+
+ @Test
+ public void testJsonPWrapping() throws Exception {
+
+ String json = get("/index.json").asString();
+ assert !json.startsWith("foo(");
+
+ String jsonp = get("/index.json?jsonp=foo").asString();
+ assert jsonp.startsWith("foo(");
+ String jp2 = "foo(" + json+ ");";
+ assert jsonp.equals(jp2);
+
+ }
+}
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/StatusTest.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/StatusTest.java
new file mode 100644
index 0000000..073a56a
--- /dev/null
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/StatusTest.java
@@ -0,0 +1,93 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.modules.integrationTests.restApi;
+
+
+import static com.jayway.restassured.RestAssured.*;
+
+import org.junit.Test;
+
+/**
+ * Test the status part of the API
+ */
+public class StatusTest extends AbstractBase{
+
+
+ @Test
+ public void testAuthRequired() {
+ given()
+ .auth().none()
+ .expect()
+ .statusCode(401)
+ .when()
+ .get("/status");
+ }
+
+
+ @Test
+ public void testAuthRhqadmin() {
+ expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .get("/status");
+
+ given()
+ .header("Accept","text/html")
+ .expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .get("/status");
+
+ given().header("Accept","application/json")
+ .expect().statusCode(200)
+ .when().get("/status");
+
+ given().header("Accept","application/xml")
+ .expect().statusCode(200)
+ .when().get("/status");
+
+ }
+
+ @Test
+ public void testAuthRestricted() {
+ given()
+ .auth().basic("user","name23")
+ .expect()
+ .statusCode(401)
+ .when()
+ .get("/rest/status"); // Wrong url does not matter, as the access is checked before hitting the rest api
+ }
+
+ @Test
+ public void testServerOpMode() throws Exception {
+
+ expect()
+ .statusCode(200)
+ .log().ifError()
+ .when()
+ .get("/status/server");
+
+ }
+}
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
new file mode 100644
index 0000000..07e2f29
--- /dev/null
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/UserTest.java
@@ -0,0 +1,158 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 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.modules.integrationTests.restApi;
+
+import com.jayway.restassured.http.ContentType;
+import com.jayway.restassured.path.json.JsonPath;
+import com.jayway.restassured.response.Response;
+
+import org.apache.http.HttpStatus;
+import org.junit.Test;
+
+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;
+
+/**
+ * Test user related functionality of the rest api
+ * @author Heiko W. Rupp
+ */
+public class UserTest extends AbstractBase {
+
+ @Test
+ public void testGetFavoritesResources() throws Exception {
+
+ expect().statusCode(200)
+ .log().ifError()
+ .when().get("/user/favorites/resource");
+ }
+
+ @Test
+ public void testGetFavoriteGroups() throws Exception {
+
+ expect().statusCode(200)
+ .log().ifError()
+ .when().get("/user/favorites/group");
+ }
+
+ @Test
+ public void testAddRemoveFavoriteResources() throws Exception {
+
+ expect().statusCode(204)
+ .when().put("/user/favorites/resource/10001");
+
+ try {
+ Response r =
+ expect()
+ .statusCode(200)
+ .when()
+ .get("/user/favorites/resource");
+ JsonPath jp = r.jsonPath();
+ assert jp.getList("resourceId").contains("10001");
+ }
+ finally {
+ expect()
+ .statusCode(204)
+ .when().delete("/user/favorites/resource/10001");
+ }
+ }
+
+ @Test
+ public void testAddRemoveFavoriteGroup() throws Exception {
+ Group group = new Group("-x-test-group-user");
+
+ // create a group
+ Response created =
+ given()
+ .header(acceptJson)
+ .contentType(ContentType.JSON)
+ .body(group)
+ .expect()
+ .statusCode(HttpStatus.SC_CREATED)
+ .log().ifError()
+ .when()
+ .post("/group");
+
+ String location = created.header("Location");
+ int groupId = Integer.parseInt(location.substring(location.lastIndexOf("/")+1));
+
+ try {
+ given()
+ .header("Accept", "application/json")
+ .contentType(ContentType.XML)
+ .pathParam("id", groupId)
+ .expect()
+ .statusCode(204)
+ .when()
+ .put("/user/favorites/group/{id}");
+
+ Response r =
+ given()
+ .header("Accept", "application/json")
+ .expect()
+ .statusCode(200)
+ .when()
+ .get("/user/favorites/group");
+// JsonPath jp = r.jsonPath(); // TODO enable as soon as JsonPath syntax is known
+// assert jp.getList("$[].id").contains(""+groupId);
+ }
+ finally {
+ given()
+ .pathParam("id",groupId)
+ .expect()
+ .statusCode(204)
+ .when()
+ .delete("/user/favorites/group/{id}");
+
+ delete("/group/" + groupId);
+ }
+ }
+
+ @Test
+ public void testAddNonExistingResource() throws Exception {
+
+ expect()
+ .statusCode(404)
+ .when()
+ .put("/user/favorites/resource/1"); // RHQ resource ids are > 10k
+ }
+
+ @Test
+ public void testAddNonExistingGroup() throws Exception {
+
+ expect()
+ .statusCode(404)
+ .log().everything()
+ .when()
+ .put("/user/favorites/group/1"); // RHQ group ids are > 10k
+ }
+
+ @Test
+ public void testGetUserInfo() throws Exception {
+ given()
+ .pathParam("id","rhqadmin")
+ .expect()
+ .statusCode(200)
+ .when()
+ .get("/user/{id}");
+
+ }
+}
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Baseline.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Baseline.java
new file mode 100644
index 0000000..f596e96
--- /dev/null
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Baseline.java
@@ -0,0 +1,107 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.modules.integrationTests.restApi.d;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * A metric baseline
+ * @author Heiko W. Rupp
+ */
+@XmlRootElement
+public class Baseline {
+
+ double min;
+ double max;
+ double mean;
+ long computeTime;
+
+ public Baseline() {
+ }
+
+ public Baseline(double min, double max, double mean, long computeTime) {
+ this.min = min;
+ this.max = max;
+ this.mean = mean;
+ this.computeTime = computeTime;
+ }
+
+ public double getMin() {
+ return min;
+ }
+
+ public void setMin(double min) {
+ this.min = min;
+ }
+
+ public double getMax() {
+ return max;
+ }
+
+ public void setMax(double max) {
+ this.max = max;
+ }
+
+ public double getMean() {
+ return mean;
+ }
+
+ public void setMean(double mean) {
+ this.mean = mean;
+ }
+
+ public long getComputeTime() {
+ return computeTime;
+ }
+
+ public void setComputeTime(long computeTime) {
+ this.computeTime = computeTime;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Baseline baseline = (Baseline) o;
+
+ if (Double.compare(baseline.max, max) != 0) return false;
+ if (Double.compare(baseline.mean, mean) != 0) return false;
+ if (Double.compare(baseline.min, min) != 0) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result;
+ long temp;
+ temp = min != +0.0d ? Double.doubleToLongBits(min) : 0L;
+ result = (int) (temp ^ (temp >>> 32));
+ temp = max != +0.0d ? Double.doubleToLongBits(max) : 0L;
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = mean != +0.0d ? Double.doubleToLongBits(mean) : 0L;
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+}
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Event.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Event.java
new file mode 100644
index 0000000..89adef2
--- /dev/null
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Event.java
@@ -0,0 +1,85 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.modules.integrationTests.restApi.d;
+
+/**
+ * An Event for testing
+ * @author Heiko W. Rupp
+ */
+public class Event {
+
+ int id;
+ String detail;
+ int sourceId;
+ long timestamp;
+ String severity = "INFO";
+
+ public Event() {
+ }
+
+ public Event(int sourceId, long timestamp, String detail) {
+ this.detail = detail;
+ this.sourceId = sourceId;
+ this.timestamp = timestamp;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getDetail() {
+ return detail;
+ }
+
+ public void setDetail(String detail) {
+ this.detail = detail;
+ }
+
+ public int getSourceId() {
+ return sourceId;
+ }
+
+ public void setSourceId(int sourceId) {
+ this.sourceId = sourceId;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public String getSeverity() {
+ return severity;
+ }
+
+ public void setSeverity(String severity) {
+ this.severity = severity;
+ }
+}
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/EventSource.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/EventSource.java
new file mode 100644
index 0000000..9ba191d
--- /dev/null
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/EventSource.java
@@ -0,0 +1,116 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.modules.integrationTests.restApi.d;
+
+/**
+ * EventSource for testing
+ * @author Heiko W. Rupp
+ */
+public class EventSource {
+
+ int id;
+ String name;
+ String location;
+ int resourceId;
+ String displayName;
+ String description;
+
+ public EventSource() {
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public void setLocation(String location) {
+ this.location = location;
+ }
+
+ public int getResourceId() {
+ return resourceId;
+ }
+
+ public void setResourceId(int resourceId) {
+ this.resourceId = resourceId;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public void setDisplayName(String displayName) {
+ this.displayName = displayName;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ EventSource that = (EventSource) o;
+
+ if (id != that.id) return false;
+ if (resourceId != that.resourceId) return false;
+ if (description != null ? !description.equals(that.description) : that.description != null) return false;
+ if (displayName != null ? !displayName.equals(that.displayName) : that.displayName != null) return false;
+ if (!location.equals(that.location)) return false;
+ if (!name.equals(that.name)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = id;
+ result = 31 * result + name.hashCode();
+ result = 31 * result + location.hashCode();
+ result = 31 * result + resourceId;
+ result = 31 * result + (displayName != null ? displayName.hashCode() : 0);
+ result = 31 * result + (description != null ? description.hashCode() : 0);
+ return result;
+ }
+}
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Group.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Group.java
new file mode 100644
index 0000000..d576f4e
--- /dev/null
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Group.java
@@ -0,0 +1,65 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.modules.integrationTests.restApi.d;
+
+/**
+ * A group for testing
+ * @author Heiko W. Rupp
+ */
+public class Group {
+
+ String name;
+ String category = "MIXED";
+ Integer resourceTypeId;
+
+ public Group() {
+ }
+
+ public Group(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ public Integer getResourceTypeId() {
+ return resourceTypeId;
+ }
+
+ public void setResourceTypeId(Integer resourceTypeId) {
+ this.resourceTypeId = resourceTypeId;
+ }
+}
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/GroupDef.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/GroupDef.java
new file mode 100644
index 0000000..16bfda3
--- /dev/null
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/GroupDef.java
@@ -0,0 +1,76 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.modules.integrationTests.restApi.d;
+
+import java.util.List;
+
+/**
+ * A Group definition for testing
+ * @author Heiko W. Rupp
+ */
+public class GroupDef {
+
+ private int id;
+ private String name;
+ private String description;
+ private List<String> expression;
+
+ public GroupDef() {
+ }
+
+ public GroupDef(String name) {
+ this.name = name;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public List<String> getExpression() {
+ return expression;
+ }
+
+ public void setExpression(List<String> expression) {
+ this.expression = expression;
+ }
+}
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/MDataPoint.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/MDataPoint.java
new file mode 100644
index 0000000..f42155d
--- /dev/null
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/MDataPoint.java
@@ -0,0 +1,91 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.modules.integrationTests.restApi.d;
+
+import java.util.Map;
+
+/**
+ * A numeric data point for testing
+ * @author Heiko W. Rupp
+ */
+public class MDataPoint {
+
+ long timeStamp;
+ Double value;
+ private int scheduleId;
+
+ public MDataPoint() {
+ }
+
+ public MDataPoint(Map<String,Object> in) {
+ timeStamp = (Long) in.get("timeStamp");
+ value = (Double) in.get("value");
+ scheduleId = (Integer)in.get("scheduleId");
+ }
+
+ public long getTimeStamp() {
+ return timeStamp;
+ }
+
+ public void setTimeStamp(long timeStamp) {
+ this.timeStamp = timeStamp;
+ }
+
+ public Double getValue() {
+ return value;
+ }
+
+ public void setValue(Double value) {
+ this.value = value;
+ }
+
+ public int getScheduleId() {
+ return scheduleId;
+ }
+
+ public void setScheduleId(int scheduleId) {
+ this.scheduleId = scheduleId;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ MDataPoint that = (MDataPoint) o;
+
+ if (scheduleId != that.scheduleId) return false;
+ if (timeStamp != that.timeStamp) return false;
+ if (value != null ? !value.equals(that.value) : that.value != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = (int) (timeStamp ^ (timeStamp >>> 32));
+ result = 31 * result + (value != null ? value.hashCode() : 0);
+ result = 31 * result + scheduleId;
+ return result;
+ }
+}
diff --git a/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Schedule.java b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Schedule.java
new file mode 100644
index 0000000..be7344d
--- /dev/null
+++ b/modules/integration-tests/rest-api/src/test/java/org/rhq/modules/integrationTests/restApi/d/Schedule.java
@@ -0,0 +1,61 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2012 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.modules.integrationTests.restApi.d;
+
+/**
+ * A metric schedule for testing
+ * @author Heiko W. Rupp
+ */
+public class Schedule {
+
+ private int scheduleId;
+ private boolean enabled;
+ private long collectionInterval;
+
+ public Schedule() {
+ }
+
+ public int getScheduleId() {
+ return scheduleId;
+ }
+
+ public void setScheduleId(int scheduleId) {
+ this.scheduleId = scheduleId;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public long getCollectionInterval() {
+ return collectionInterval;
+ }
+
+ public void setCollectionInterval(long collectionInterval) {
+ this.collectionInterval = collectionInterval;
+ }
+}
11 years, 4 months
[rhq] Branch 'feature/cassandra-backend' - modules/enterprise
by snegrea
modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsDAO.java | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
New commits:
commit 586e38d05b4be5d64860b330b7db529a70c0ae4d
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Mon Dec 17 17:07:28 2012 -0600
The statement binder needs explicit conversion to string otherwise enum value is used to create the statement.
diff --git a/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsDAO.java b/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsDAO.java
index 9c5285f..5a6b6a6 100644
--- a/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsDAO.java
+++ b/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsDAO.java
@@ -342,7 +342,7 @@ public class MetricsDAO {
public List<MetricsIndexEntry> findMetricsIndexEntries(MetricsTable table) {
try {
PreparedStatement statement = session.prepare(METRICS_INDEX_QUERY);
- BoundStatement boundStatement = statement.bind(table);
+ BoundStatement boundStatement = statement.bind(table.toString());
ResultSet resultSet = session.execute(boundStatement);
List<MetricsIndexEntry> indexEntries = new ArrayList<MetricsIndexEntry>();
ResultSetMapper<MetricsIndexEntry> resultSetMapper = new MetricsIndexResultSetMapper(table);
@@ -362,7 +362,8 @@ public class MetricsDAO {
try {
PreparedStatement statement = session.prepare(UPDATE_METRICS_INDEX);
for (Integer scheduleId : updates.keySet()) {
- BoundStatement boundStatement = statement.bind(table, updates.get(scheduleId).toDate(), scheduleId,
+ BoundStatement boundStatement = statement.bind(table.toString(), updates.get(scheduleId).toDate(),
+ scheduleId,
false);
session.execute(boundStatement);
}
11 years, 4 months