package org.rhq.enterprise.server.rest.reporting; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Date; 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.WebApplicationException; import javax.ws.rs.core.StreamingOutput; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.criteria.DriftCriteria; import org.rhq.core.domain.criteria.GenericDriftCriteria; import org.rhq.core.domain.drift.DriftCategory; import org.rhq.core.domain.drift.DriftComposite; import org.rhq.core.domain.util.PageList; import org.rhq.enterprise.server.drift.DriftManagerLocal; import org.rhq.enterprise.server.rest.AbstractRestBean; import org.rhq.enterprise.server.rest.ReportsInterceptor; import org.rhq.enterprise.server.util.CriteriaQuery; import org.rhq.enterprise.server.util.CriteriaQueryExecutor; import static org.rhq.enterprise.server.rest.reporting.ReportFormatHelper.parseAncestry; @Interceptors(ReportsInterceptor.class) @Stateless public class RecentDriftHandler extends AbstractRestBean implements RecentDriftLocal { private final Log log = LogFactory.getLog(RecentDriftHandler.class); @EJB private DriftManagerLocal driftManager; public StreamingOutput recentDriftInternal( String categories, Integer snapshot, String path, String definitionName, Long startTime, Long endTime, HttpServletRequest request, Subject user) { this.caller = user; return recentDrift(categories,snapshot,path,definitionName,startTime,endTime,request); } @Override public StreamingOutput recentDrift(final String categories, final Integer snapshot, final String path, final String definitionName, final Long startTime, final Long endTime, final HttpServletRequest request) { if (log.isDebugEnabled()) { log.debug("Received request to generate report for " + caller); } return new StreamingOutput() { @Override public void write(OutputStream stream) throws IOException, WebApplicationException { GenericDriftCriteria criteria = new GenericDriftCriteria(); // Need to fetch the change set so that we can the definition id which is // needed to build the details url. criteria.fetchChangeSet(true); criteria.addFilterChangeSetStartVersion(1);// always start at 1 for this report if(startTime != null){ criteria.addFilterStartTime(startTime); } if(endTime != null){ criteria.addFilterEndTime(endTime); } // lets default the end time for them to now if they didnt enter it if(startTime != null && endTime == null){ Date today = new Date(); criteria.addFilterEndTime(today.getTime()); } if(snapshot != null) { log.info("Drift Snapshot version Filter set for: " + snapshot); criteria.addFilterChangeSetEndVersion(snapshot); } if(path != null) { log.info("Drift Path Filter set for: " + path); criteria.addFilterPath(path); } if(definitionName != null) { log.info("Drift Definition Filter set for: " + definitionName); //@todo: drift sorting is done in the resultset after no criteria for definition } criteria.addFilterCategories(getCategories()); CriteriaQueryExecutor<DriftComposite, DriftCriteria> queryExecutor = new CriteriaQueryExecutor<DriftComposite, DriftCriteria>() { @Override public PageList<DriftComposite> execute(DriftCriteria criteria) { return driftManager.findDriftCompositesByCriteria(caller, criteria); } }; CriteriaQuery<DriftComposite, DriftCriteria> query = new CriteriaQuery<DriftComposite, DriftCriteria>(criteria, queryExecutor); CsvWriter<DriftComposite> csvWriter = new CsvWriter<DriftComposite>(); csvWriter.setColumns("drift.ctime", "driftDefinitionName", "drift.changeSet.version", "drift.category", "drift.path", "resource.name", "ancestry", "detailsURL"); csvWriter.setPropertyConverter("drift.ctime", csvWriter.DATE_CONVERTER); csvWriter.setPropertyConverter("ancestry", new PropertyConverter<DriftComposite>() { @Override public Object convert(DriftComposite driftComposite, String propertyName) { return parseAncestry(driftComposite.getResource().getAncestry()); } }); csvWriter.setPropertyConverter("detailsURL", new PropertyConverter<DriftComposite>() { @Override public Object convert(DriftComposite driftComposite, String propertyName) { return getDetailsURL(driftComposite); } }); stream.write((getHeader() + "\n").getBytes()); if (definitionName != null) { for (DriftComposite driftComposite : query) { if(driftComposite.getDriftDefinitionName() != null && driftComposite.getDriftDefinitionName().contains(definitionName)) { csvWriter.write(driftComposite, stream); } } } else { for (DriftComposite driftComposite : query) { csvWriter.write(driftComposite, stream); } } } private DriftCategory[] getCategories() { List<DriftCategory> driftCategoryList = new ArrayList<DriftCategory>(10); String categoryArray[] = categories.split(","); for (String category : categoryArray) { log.info("DriftCategories Filter set for: " + category); driftCategoryList.add(DriftCategory.valueOf(category.toUpperCase())); } return (driftCategoryList.toArray(new DriftCategory[driftCategoryList.size()])); } private String getHeader(){ return "Creation Time,Definition,Snapshot,Category,Path,Resource,Ancestry,Details URL"; } private String getDetailsURL(DriftComposite driftDetails) { String protocol; if (request.isSecure()) { protocol = "https"; } else { protocol = "http"; } return protocol + "://" + request.getServerName() + ":" + request.getServerPort() + "/coregui/#Resource/" + driftDetails.getResource().getId() + "/Drift/Definitions/" + driftDetails.getDrift().getChangeSet().getDriftDefinitionId() + "/Drift/0id_" + driftDetails.getDrift().getId(); } }; } }