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@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 - */ -@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 */ -@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; + } +}
rhq-commits@lists.fedorahosted.org