@GET @Path("/source/{id}") @ApiOperation(value = "Retrieve the event source with the passed id", responseClass = "EventSourceRest") @ApiError(code = 404, reason = "There is no event source with the passed id") public EventSourceRest getEventSource(@ApiParam("Id of the source to retrieve") @PathParam("id") int sourceId) { EventSource source = findEventSourceById(sourceId); EventSourceRest esr = convertEventSource(source); return esr; }
/** * Process a single @ApiError * @param doc XML Document to add * @param ae ApiError annotation to evaluate * @param parent Parent XML element to tack the ApiError data on */ private void processError(Document doc, ApiError ae, Element parent) { if (ae==null) return; Element element = doc.createElement("error"); parent.appendChild(element); element.setAttribute("code", String.valueOf(ae.code())); element.setAttribute("reason",ae.reason()); }
@DELETE @Path("definition/{id}") @ApiOperation(value = "Delete an alert definition", notes = "This operation is by default idempotent, returning 204." + "If you want to check if the definition existed at all, you need to pass the 'validate' query parameter.") @ApiErrors({ @ApiError(code = 204, reason = "Definition was deleted or did not exist with validation not set"), @ApiError(code = 404, reason = "Definition did not exist and validate was set") }) public Response deleteDefinition(@ApiParam("Id of the definition to delete") @PathParam("id") int definitionId, @ApiParam("Validate if the definition exists") @QueryParam("validate") @DefaultValue("false") boolean validate) { int count = alertDefinitionManager.removeAlertDefinitions(caller, new int[]{definitionId}); if (count == 0 && validate) { throw new StuffNotFoundException("Definition with id " + definitionId); } return Response.noContent().build(); }
@DELETE @Path("/{id}") @ApiOperation(value = "Remove the alert from the list of alerts", notes = "This operation is by default idempotent, returning 204." + "If you want to check if the alert existed at all, you need to pass the 'validate' query parameter.") @ApiErrors({ @ApiError(code = 204, reason = "Alert was deleted or did not exist with validation not set"), @ApiError(code = 404, reason = "Alert did not exist and validate was set") }) public Response purgeAlert(@ApiParam(value = "Id of the alert to remove") @PathParam("id") int id, @ApiParam("Validate if the alert exists") @QueryParam("validate") @DefaultValue("false") boolean validate) { int count = alertManager.deleteAlerts(caller, new int[]{id}); if (count == 0 && validate) { throw new StuffNotFoundException("Alert with id " + id); } return Response.noContent().build(); }
@DELETE @Path("/source/{id}") @ApiOperation(value = "Delete the event source with the passed id", notes = "This operation is by default idempotent, returning 204." + "If you want to check if the source existed at all, you need to pass the 'validate' query parameter.") @ApiErrors({ @ApiError(code = 204, reason = "Source was deleted or did not exist with validation not set"), @ApiError(code = 404, reason = "Source did not exist and validate was set") }) public Response deleteEventSource(@ApiParam("Id of the source to delete") @PathParam("id") int sourceId, @ApiParam("Validate if the content exists") @QueryParam("validate") @DefaultValue("false") boolean validate) { EventSource source = em.find(EventSource.class,sourceId); if (source!=null) { em.remove(source); // We have a cascade delete on the events TODO make operation async ? } else { if (validate) { throw new StuffNotFoundException("Event source with id " + sourceId); } } return Response.noContent().build(); }
@GET @Path("notification/{nid}") @ApiOperation("Return a notification definition by its id") @ApiError(code = 404, reason = "No notification with the passed id found") public Response getNotification( @ApiParam("The id of the notification definition to retrieve") @PathParam("nid") int notificationId) { AlertNotification notification = notificationMgr.getAlertNotification(caller,notificationId); if (notification==null) { throw new StuffNotFoundException("No notification with id " + notificationId); } AlertNotificationRest anr = notificationToNotificationRest(notification); return Response.ok(anr).build(); }
@GET @Path("condition/{cid}") @ApiOperation("Retrieve a condition of an alert definition by its condition id") @ApiError(code = 404, reason = "No condition with the passed id exists") public Response getCondition( @ApiParam("The id of the condition to retrieve") @PathParam("cid") int conditionId) { AlertCondition condition = conditionMgr.getAlertConditionById(conditionId); if (condition==null) { throw new StuffNotFoundException("No condition with id " + conditionId); } AlertConditionRest acr = conditionToConditionRest(condition); return Response.ok(acr).build(); }
@GET @GZIP @Path("/{id}/hierarchy") @Produces({"application/json","application/xml"}) @ApiOperation(value = "Retrieve the hierarchy of resources starting with the passed one", multiValueResponse = true, responseClass = "ResourceWithType") @ApiError(code = 404, reason = NO_RESOURCE_FOR_ID) public ResourceWithChildren getHierarchy(@ApiParam("Id of the resource to start with") @PathParam("id")int baseResourceId) { // TODO optimize to do less recursion Resource start = fetchResource(baseResourceId); return getHierarchy(start); }
@GET @Path("/{id}/availability/summary") @ApiError(code = 404, reason = NO_RESOURCE_FOR_ID) @ApiOperation(value = "Return the availability history for the passed resource", responseClass = "AvailabilitySummary", multiValueResponse = false) public Response getAvailabilitySummary( @ApiParam("Id of the resource to query") @PathParam("id") int resourceId, @Context HttpHeaders headers) { fetchResource(resourceId); ResourceAvailabilitySummary summary = resMgr.getAvailabilitySummary(caller,resourceId); AvailabilitySummary as = new AvailabilitySummary(resourceId,summary); Response.ResponseBuilder builder = Response.ok(as); MediaType type = headers.getAcceptableMediaTypes().get(0); builder.type(type); return builder.build(); }
@DELETE @Path("/{handle}") @ApiOperation(value = "Remove the content with the passed handle", notes = "This operation is by default idempotent, returning 204." + "If you want to check if the content existed at all, you need to pass the 'validate' query parameter.") @ApiErrors({ @ApiError(code = 204, reason = "Content was deleted or did not exist with validation not set"), @ApiError(code = 404, reason = "Content did not exist and validate was set") }) public Response removeUploadedContent( @PathParam("handle") String handle, @ApiParam("Validate if the content exists") @QueryParam("validate") @DefaultValue("false") boolean validate) { File content = getFileForHandle(handle); Response.ResponseBuilder builder; if (!content.exists()) { if (validate) { throw new StuffNotFoundException("Content with handle " + handle); } builder = Response.noContent(); } else { boolean deleted = content.delete(); if (deleted) builder = Response.noContent(); else { builder = Response.serverError(); System.err.println("Deletion of " + content.getAbsolutePath() + " failed"); } } return builder.build(); }
@Cache(maxAge = 600) @GET @Path("{id}") @ApiOperation(value = "Return information about the resource type with the passed id",responseClass = "ResourceTypeRest") @ApiError(code = 404, reason = "There is no type with the passed id") public Response getTypeById( @PathParam("id") int resourceTypeId, @Context HttpHeaders headers, @Context UriInfo uriInfo) { ResourceType type; try { type = typeManager.getResourceTypeById(caller,resourceTypeId); } catch (ResourceTypeNotFoundException e) { throw new StuffNotFoundException("Resource type with id " + resourceTypeId); } ResourceTypeRest rtr = resourceTypeToResourceTypeRest(type); MediaType mediaType = headers.getAcceptableMediaTypes().get(0); Response.ResponseBuilder builder = Response.ok(); builder.type(mediaType); builder.entity(rtr); return builder.build(); }
@DELETE @Path("{id}/resource/{resourceId}") @ApiOperation(value = "Remove the resource with the passed id from the group", notes = "This operation is by default idempotent, returning 204" + "even if the resource was not member of the group." + "If you want to check if the resource existed at all, you need to pass the 'validate' query parameter.") @ApiErrors({ @ApiError(code = 404, reason = "Group with the passed id does not exist"), @ApiError(code = 404, reason = "Resource with the passed id does not exist"), @ApiError(code = 204, reason = "Resource was removed from the group or was no member and validation was not set"), @ApiError(code = 404, reason = "Resource was no member of the group and validate was set") }) public Response removeResource(@ApiParam("Id of the existing group") @PathParam("id") int id, @ApiParam("Id of the resource to remove") @PathParam("resourceId") int resourceId, @ApiParam("Validate if the resource exists in the group") @QueryParam( "validate") @DefaultValue("false") boolean validate) { ResourceGroup resourceGroup = fetchGroup(id, false); Resource res = resourceManager.getResource(caller, resourceId); if (res==null) throw new StuffNotFoundException("Resource with id " + resourceId); boolean removed = resourceGroup.removeExplicitResource(res); if (!removed && validate) { throw new StuffNotFoundException("Resource " + resourceId + " in group " + id); } return Response.noContent().build(); }
@DELETE @Path("favorites/group/{id}") @ApiOperation(value = "Remove a group from favorites", notes = "This operation is by default idempotent, returning 204." + "If you want to check if the group was a favorite, you need to pass the 'validate' query parameter.") @ApiErrors({ @ApiError(code = 204, reason = "Group was removed or was no favorite with validation not set"), @ApiError(code = 404, reason = "Group was no favorite and validate was set") }) public void removeResourceGroupFromFavorites( @ApiParam(name = "id", value = "Id of the group") @PathParam("id") int id, @ApiParam("Validate if the group is a favorite") @QueryParam("validate") @DefaultValue("false") boolean validate) { Set<Integer> favIds = getGroupIdsForFavorites(); if (favIds.contains(id)) { favIds.remove(id); updateGroupFavorites(favIds); } else { if (validate) { throw new StuffNotFoundException("Group with id " + id + " in favorites "); } } }
@DELETE @Path("{id}") @ApiOperation(value="Delete the group with the passed id", notes = "This operation is by default idempotent, returning 204." + "If you want to check if the group existed at all, you need to pass the 'validate' query parameter.") @ApiErrors({ @ApiError(code = 204, reason = "Group was deleted or did not exist with validation not set"), @ApiError(code = 404, reason = "Group did not exist and validate was set") }) public Response deleteGroup(@ApiParam("Id of the group to delete") @PathParam("id") int id, @ApiParam("Validate if the group exists") @QueryParam("validate") @DefaultValue("false") boolean validate) { Response.ResponseBuilder builder; try { resourceGroupManager.deleteResourceGroup(caller,id); removeFromCache(id,ResourceGroup.class); builder = Response.noContent(); } catch (ResourceGroupNotFoundException e) { if (validate) { builder = Response.status(Response.Status.NOT_FOUND); } else { builder = Response.noContent(); } } catch (ResourceGroupDeleteException e) { builder = Response.serverError(); builder.entity(e.getMessage()); } return builder.build(); }
"If you want to check if the definition existed at all, you need to pass the 'validate' query parameter.") @ApiErrors({ @ApiError(code = 204, reason = "Definition was deleted or did not exist with validation not set"), @ApiError(code = 404, reason = "Definition did not exist and validate was set") }) public Response deleteGroupDefinition(
@PUT @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) @ApiOperation("Submit a single (numerical) metric to the server") @ApiErrors({ @ApiError(code=404, reason = NO_SCHEDULE_FOR_ID), @ApiError(code=406, reason = "Timestamp is older than 7 days") }) @Path("data/{scheduleId}/raw/{timeStamp}") public Response putMetricValue(@ApiParam("Id of the schedule") @PathParam("scheduleId") int scheduleId, @ApiParam("Timestamp of the metric") @PathParam("timeStamp") long timestamp, @ApiParam(value = "Data value", required = true) DoubleValue value, @Context HttpHeaders headers, @Context UriInfo uriInfo) { MediaType mediaType = headers.getAcceptableMediaTypes().get(0); obtainSchedule(scheduleId, false, DataType.MEASUREMENT); long now = System.currentTimeMillis(); if (timestamp < now - SEVEN_DAYS) throw new IllegalArgumentException("Timestamp is older than 7 days"); Set<MeasurementDataNumeric> data = new HashSet<MeasurementDataNumeric>(1); data.add(new MeasurementDataNumeric(timestamp,scheduleId,value.getValue())); dataManager.addNumericData(data); UriBuilder uriBuilder = uriInfo.getBaseUriBuilder(); uriBuilder.path("/metric/data/{scheduleId}/raw"); uriBuilder.queryParam("startTime",timestamp); uriBuilder.queryParam("endTime",timestamp); URI uri = uriBuilder.build(scheduleId); return Response.created(uri).type(mediaType).build(); }
@POST @Path("data/raw") @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) @ApiOperation(value="Submit a series of (numerical) metric values to the server",responseClass = "No response") @ApiErrors({ @ApiError(code = 201, reason = "There are some submitted datapoints with non-existing scheduleId, API returns rejected values back to client, valid values are accepted"), @ApiError(code = 403, reason = "All submitted datapoints have non-existing scheduleId, API returns rejected values back to client") }) public Response postMetricValues(Collection<NumericDataPoint> points, @Context HttpHeaders headers) { MediaType mediaType = headers.getAcceptableMediaTypes().get(0); Set<MeasurementDataNumeric> data = new HashSet<MeasurementDataNumeric>(points.size()); List<NumericDataPoint> rejected = new ArrayList<NumericDataPoint>(); for (NumericDataPoint point : points) { if (isScheduleAccessible(point.getScheduleId())) { data.add(new MeasurementDataNumeric(point.getTimeStamp(), point.getScheduleId(), point.getValue())); } else { rejected.add(point); } } if (rejected.isEmpty()) { dataManager.addNumericData(data); return Response.noContent().type(mediaType).build(); } else { Map<String, Object> resp = new HashMap<String, Object>(); resp.put("rejected", rejected); resp.put("message", "Schedules for rejected datapoints do not exist"); return Response.status(data.isEmpty() ? Status.FORBIDDEN : Status.CREATED).entity(resp).build(); } }
@DELETE @Path("favorites/resource/{id}") @ApiOperation(value = "Remove a resource from favorites", notes = "This operation is by default idempotent, returning 204." + "If you want to check if the resource was a favorite, you need to pass the 'validate' query parameter.") @ApiErrors({ @ApiError(code = 204, reason = "Resource was removed or was no favorite with validation not set"), @ApiError(code = 404, reason = "Resource was no favorite and validate was set") }) public void removeResourceFromFavorites( @ApiParam(name = "id", value = "Id of the resource") @PathParam("id") int id, @ApiParam("Validate if the resource is a favorite") @QueryParam("validate") @DefaultValue("false") boolean validate) { Set<Integer> favIds = getResourceIdsForFavorites(); if (favIds.contains(id)) { favIds.remove(id); updateResourceFavorites(favIds); } else { if (validate) { throw new StuffNotFoundException("Resource with id " + id + " in favorites "); } } }
@PUT @Path("data/{scheduleId}/trait/{timeStamp}") @Consumes({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML}) @ApiOperation(value = "Submit a new trait value for the passed schedule id") @ApiErrors({ @ApiError(code=404, reason = NO_SCHEDULE_FOR_ID), @ApiError(code=406, reason = "Timestamp is older than 7 days") }) public Response putTraitValue(@ApiParam("Id of the schedule") @PathParam("scheduleId") int scheduleId, @ApiParam("Timestamp of the metric") @PathParam("timeStamp") long timestamp, @ApiParam(value = "Data value", required = true) StringValue value) { obtainSchedule(scheduleId, false, DataType.TRAIT); long now = System.currentTimeMillis(); if (timestamp < now - SEVEN_DAYS) throw new IllegalArgumentException("Timestamp is older than 7 days"); Set<MeasurementDataTrait> traits = new HashSet<MeasurementDataTrait>(1); MeasurementDataPK pk = new MeasurementDataPK(timestamp,scheduleId); traits.add(new MeasurementDataTrait(pk,value.getValue())); dataManager.addTraitData(traits); return Response.ok().build(); }
@Cache(isPrivate = true,maxAge = 60) @GET @Path("{id}") @ApiOperation(value = "Get the group with the passed id") @ApiError(code = 404, reason = "Group with passed id not found") public Response getGroup(@ApiParam(value = "Id of the group") @PathParam("id") int id, @Context HttpHeaders headers, @Context UriInfo uriInfo) { ResourceGroup group = fetchGroup(id, false); GroupRest groupRest = fillGroup(group, uriInfo); MediaType mediaType = headers.getAcceptableMediaTypes().get(0); Response.ResponseBuilder builder = Response.ok(); builder.type(mediaType); if (mediaType.equals(MediaType.TEXT_HTML_TYPE)) { builder.entity(renderTemplate("group", groupRest)); } else { builder.entity(groupRest); } return builder.build(); }