/*
* RHQ Management Platform
* Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package org.rhq.enterprise.server.rest;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiError;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
import org.jboss.resteasy.annotations.GZIP;
import org.rhq.core.domain.drift.DriftCategory;
import org.rhq.enterprise.server.rest.domain.Link;
import org.rhq.enterprise.server.rest.reporting.AlertDefinitionLocal;
import org.rhq.enterprise.server.rest.reporting.ConfigurationHistoryLocal;
import org.rhq.enterprise.server.rest.reporting.DriftComplianceLocal;
import org.rhq.enterprise.server.rest.reporting.InventorySummaryLocal;
import org.rhq.enterprise.server.rest.reporting.PlatformUtilizationLocal;
import org.rhq.enterprise.server.rest.reporting.RecentAlertLocal;
import org.rhq.enterprise.server.rest.reporting.RecentDriftLocal;
import org.rhq.enterprise.server.rest.reporting.RecentOperationsLocal;
import org.rhq.enterprise.server.rest.reporting.SuspectMetricLocal;
/**
* The reports from the reports section of Coregui.
* This class basically wrap the reports in the org.rhq.enterprise.server.rest.reports package
* so that they are available outside Coregui as well.
*
* @author Heiko W. Rupp
*/
@Stateless
@Path("/reports")
@Produces({"text/csv"})
@Api("Provide the reports that are also run from the Reports section of the UI. All reports are only available in CSV format")
@Interceptors(SetCallerInterceptor.class)
public class ReportsHandlerBean extends AbstractRestBean {
@EJB
private AlertDefinitionLocal alertDefinitionLocal;
@EJB
private ConfigurationHistoryLocal configurationHistoryLocal;
@EJB
private DriftComplianceLocal driftComplianceLocal;
@EJB
private InventorySummaryLocal inventorySummaryLocal;
@EJB
private PlatformUtilizationLocal platformUtilizationLocal;
@EJB
private RecentAlertLocal recentAlertLocal;
@EJB
private RecentDriftLocal recentDriftLocal;
@EJB
private RecentOperationsLocal recentOperationsLocal;
@EJB
private SuspectMetricLocal suspectMetricLocal;
private String[] reports = {
"alertDefinitions",
"configurationHistory",
"driftCompliance",
"inventorySummary",
"platformUtilization",
"recentAlerts",
"recentDrift",
"recentOperations",
"suspectMetrics"
};
@GET
@Path("/")
@ApiOperation(value = "List the available reports", responseClass = "String", multiValueResponse = true)
@Produces({MediaType.TEXT_HTML,MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML,"text/csv"})
public Response listReports(@Context HttpHeaders headers, @Context UriInfo uriInfo) {
List<Link> links = new ArrayList<Link>(reports.length);
for (String report: reports) {
UriBuilder uriBuilder = uriInfo.getBaseUriBuilder();
uriBuilder.path("/reports/{report}");
URI uri = uriBuilder.build(report);
Link link = new Link(report,uri.toString());
links.add(link);
}
MediaType mediaType = headers.getAcceptableMediaTypes().get(0);
Response.ResponseBuilder builder = Response.ok();
if (mediaType.getType().equals("text") && mediaType.getSubtype().equals("csv")) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Report,URL\n");
for (Link link: links) {
stringBuilder.append(link.getRel()).append(",").append(link.getHref());
stringBuilder.append('\n');
}
builder.entity(stringBuilder.toString());
}
else if (mediaType.equals(MediaType.TEXT_HTML_TYPE)) {
builder.entity(renderTemplate("reportIndex", links));
} else {
GenericEntity<List<Link>> list = new GenericEntity<List<Link>>(links) {
};
builder.entity(list);
}
CacheControl cacheControl = new CacheControl();
cacheControl.setMaxAge(86400); // TODO 1 day or longer? What unit is this anyway?
builder.cacheControl(cacheControl);
return builder.build();
}
@GZIP
@GET
@Path("alertDefinitions")
@ApiOperation(value = "Export the AlertDefinitions as CSV", responseClass = "String", multiValueResponse = true)
public StreamingOutput alertDefinitions(@Context HttpServletRequest request) {
return alertDefinitionLocal.alertDefinitionsInternal(request, caller);
}
@GZIP
@GET
@Path("configurationHistory")
@ApiOperation(value = "Export the Configuration History data as CSV", responseClass = "String", multiValueResponse = true)
public StreamingOutput configurationHistory(@Context HttpServletRequest request) {
return configurationHistoryLocal.configurationHistoryInternal(request,caller);
}
@GZIP
@GET
@Path("driftCompliance")
@ApiOperation(value = "Export the drift compliance data", responseClass = "String", multiValueResponse = true)
public StreamingOutput generateDriftComplianceReport(
@Context HttpServletRequest request,
@QueryParam("resourceTypeId") String resourceTypeId,
@QueryParam("version") String version) {
return driftComplianceLocal.generateReportInternal(request,resourceTypeId,version,caller);
}
@GZIP
@GET
@Path("inventorySummary")
@ApiOperation(value = "Export the Inventory Summary data as CSV", responseClass = "String", multiValueResponse = true)
public StreamingOutput generateInventorySummaryReport(
@Context HttpServletRequest request,
@QueryParam("resourceTypeId") String resourceTypeId,
@QueryParam("version") String version) {
return inventorySummaryLocal.generateReportInternal(request,resourceTypeId,version,caller);
}
@GZIP
@GET
@Path("platformUtilization")
@ApiOperation(value = "Export the Platform utilization data as CSV", responseClass = "String", multiValueResponse = true)
public StreamingOutput generateReport(@Context HttpServletRequest request) {
return platformUtilizationLocal.generateReportInternal(request, caller);
}
@GZIP
@GET
@Path("recentAlerts")
@ApiOperation(value = "Export the Recent Alert data as CSV", responseClass = "String", multiValueResponse = true)
public StreamingOutput recentAlerts(
@QueryParam("alertPriority") @DefaultValue("high,medium,low") String alertPriority,
@QueryParam("startTime") Long startTime,
@QueryParam("endTime") Long endTime,
@Context HttpServletRequest request) {
return recentAlertLocal.recentAlertsInternal(alertPriority, startTime, endTime, request, caller);
}
@GZIP
@GET
@Path("recentDrift")
@ApiOperation(value = "Export the Recent drift data as CSV", responseClass = "String", multiValueResponse = true)
@ApiError(code = 404, reason = "If no category is provided or the category is wrong")
public StreamingOutput recentDrift(
@ApiParam(value = "Drift categories to report on", allowableValues = "FILE_ADDED, FILE_CHANGED, FILE_REMOVED") @QueryParam("categories") String categories,
@QueryParam("snapshot") Integer snapshot,
@QueryParam("path") String path,
@QueryParam("definition") String definitionName,
@QueryParam("startTime") Long startTime,
@QueryParam("endTime") Long endTime,
@Context HttpServletRequest request) {
if (categories==null) {
throw new BadArgumentException("categories","You need to provide at least one category");
}
String [] cats = categories.split(",");
for (String cat : cats) {
try {
DriftCategory.valueOf(cat.toUpperCase());
}
catch (IllegalArgumentException iae) {
throw new BadArgumentException("category",cat);
}
}
return recentDriftLocal.recentDriftInternal(categories,snapshot,path,definitionName,startTime,endTime,request,caller);
}
@GZIP
@GET
@Path("recentOperations")
@ApiOperation(value = "Export the Recent Operations Data as CSV", responseClass = "String", multiValueResponse = true)
public StreamingOutput recentOperations(
@ApiParam("Status to look for. If parameter is not given, all values are used")
@QueryParam("status") @DefaultValue("inprogress,success,failure,canceled") String operationRequestStatus,
@ApiParam("The start time in ms since epoch of the time range to export.")
@QueryParam("startTime") Long startTime,
@ApiParam("The end time in ms since epoch of the time range to export. Defaults to 'now' if only the start time is given")
@QueryParam("endTime") Long endTime,
@Context HttpServletRequest request) {
return recentOperationsLocal.recentOperationsInternal(operationRequestStatus,startTime,endTime,request,caller);
}
@GZIP
@GET
@Path("suspectMetrics")
@ApiOperation(value = "Export the Suspect Metrics data as CSV", responseClass = "String", multiValueResponse = true)
public StreamingOutput suspectMetrics(@Context HttpServletRequest request) {
return suspectMetricLocal.suspectMetricsInternal(request,caller);
}
}