001 package org.hackystat.telemetry.analyzer.reducer.impl; 002 003 import java.util.List; 004 005 import org.hackystat.dailyprojectdata.client.DailyProjectDataClient; 006 import org.hackystat.dailyprojectdata.resource.commit.jaxb.CommitDailyProjectData; 007 import org.hackystat.dailyprojectdata.resource.commit.jaxb.MemberData; 008 import org.hackystat.sensorbase.resource.projects.jaxb.Project; 009 import org.hackystat.telemetry.analyzer.model.TelemetryDataPoint; 010 import org.hackystat.telemetry.analyzer.model.TelemetryStream; 011 import org.hackystat.telemetry.analyzer.model.TelemetryStreamCollection; 012 import org.hackystat.telemetry.analyzer.reducer.TelemetryReducer; 013 import org.hackystat.telemetry.analyzer.reducer.TelemetryReducerException; 014 import org.hackystat.telemetry.analyzer.reducer.util.IntervalUtility; 015 import org.hackystat.telemetry.service.server.ServerProperties; 016 import org.hackystat.utilities.time.interval.Interval; 017 import org.hackystat.utilities.time.period.Day; 018 import org.hackystat.utilities.tstamp.Tstamp; 019 020 021 /** 022 * Returns a single stream providing Commit counts. 023 * <p> 024 * Options: 025 * <ol> 026 * <li> member: The project member whose commit counts are to be returned, or "*" for all members. 027 * <li> isCumulative: True or false. Default is false. 028 * </ol> 029 * 030 * @author Philip Johnson 031 */ 032 public class CommitReducer implements TelemetryReducer { 033 034 /** 035 * Computes and returns the required telemetry streams object. 036 * 037 * @param project The project. 038 * @param dpdClient The DPD Client. 039 * @param interval The interval. 040 * @param options The optional parameters. 041 * 042 * @return Telemetry stream collection. 043 * @throws TelemetryReducerException If there is any error. 044 */ 045 public TelemetryStreamCollection compute(Project project, DailyProjectDataClient dpdClient, 046 Interval interval, String[] options) throws TelemetryReducerException { 047 String member = null; 048 boolean isCumulative = false; 049 //process options 050 if (options.length > 2) { 051 throw new TelemetryReducerException("Commit reducer takes 2 optional parameters."); 052 } 053 if (options.length >= 1) { 054 member = options[0]; 055 } 056 057 if (options.length >= 2) { 058 try { 059 isCumulative = Boolean.valueOf(options[1]); 060 } 061 catch (Exception e) { 062 throw new TelemetryReducerException("Illegal cumulative value.", e); 063 } 064 } 065 066 // Find out the DailyProjectData host, throw error if not found. 067 String dpdHost = System.getProperty(ServerProperties.DAILYPROJECTDATA_FULLHOST_KEY); 068 if (dpdHost == null) { 069 throw new TelemetryReducerException("Null DPD host in CommitReducer"); 070 } 071 072 // now get the telemetry stream. 073 try { 074 TelemetryStream telemetryStream = this.getStream(dpdClient, project, interval, 075 member, isCumulative, null); 076 TelemetryStreamCollection streams = new TelemetryStreamCollection(null, project, interval); 077 streams.add(telemetryStream); 078 return streams; 079 } 080 catch (Exception e) { 081 throw new TelemetryReducerException(e); 082 } 083 } 084 085 /** 086 * Gets the telemetry stream. 087 * 088 * @param dpdClient The DailyProjectData client we will contact for the data. 089 * @param project The project. 090 * @param interval The interval. 091 * @param member The member, or "*" for all members. 092 * @param isCumulative True for cumulative measure. 093 * @param streamTagValue The tag for the generated telemetry stream. 094 * 095 * @return The telemetry stream as required. 096 * 097 * @throws Exception If there is any error. 098 */ 099 TelemetryStream getStream(DailyProjectDataClient dpdClient, 100 Project project, Interval interval, 101 String member, boolean isCumulative, Object streamTagValue) 102 throws Exception { 103 TelemetryStream telemetryStream = new TelemetryStream(streamTagValue); 104 List<IntervalUtility.Period> periods = IntervalUtility.getPeriods(interval); 105 long cumulativeCommits = 0; 106 107 for (IntervalUtility.Period period : periods) { 108 Long value = this.getData(dpdClient, project, period.getStartDay(), period.getEndDay(), 109 member); 110 111 if (value != null) { 112 cumulativeCommits += value; 113 } 114 115 if (isCumulative) { 116 telemetryStream.addDataPoint(new TelemetryDataPoint(period.getTimePeriod(), 117 cumulativeCommits)); 118 } 119 else { 120 telemetryStream.addDataPoint(new TelemetryDataPoint(period.getTimePeriod(), value)); 121 } 122 } 123 return telemetryStream; 124 } 125 126 /** 127 * Returns a Commit value for the specified time interval, or null if no SensorData. 128 * 129 * @param dpdClient The DailyProjectData client we will use to get this data. 130 * @param project The project. 131 * @param startDay The start day (inclusive). 132 * @param endDay The end day (inclusive). 133 * @param member The member email, or "*" for all members. 134 * @throws TelemetryReducerException If anything goes wrong. 135 * 136 * @return The UnitTest count, or null if there is no UnitTest SensorData for that time period. 137 */ 138 Long getData(DailyProjectDataClient dpdClient, Project project, Day startDay, Day endDay, 139 String member) throws TelemetryReducerException { 140 long count = 0; 141 boolean hasData = false; 142 try { 143 // For each day in the interval... 144 for (Day day = startDay; day.compareTo(endDay) <= 0; day = day.inc(1) ) { 145 // Get the DPD... 146 CommitDailyProjectData data = 147 dpdClient.getCommit(project.getOwner(), project.getName(), Tstamp.makeTimestamp(day)); 148 // Go through the DPD per-member data... 149 for (MemberData memberData : data.getMemberData()) { 150 if ((member == null) || "*".equals(member) || 151 (memberData.getMemberUri().endsWith(member))) { 152 hasData = true; 153 count += memberData.getCommits(); 154 } 155 } 156 } 157 } 158 catch (Exception ex) { 159 throw new TelemetryReducerException(ex); 160 } 161 162 //Return null if no data, the Commit counts otherwise. 163 return (hasData) ? Long.valueOf(count) : null; 164 } 165 166 }