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;
+ }
+}