1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.common.aws.s3.monitor;
17
18 import java.io.File;
19 import java.io.IOException;
20 import java.text.SimpleDateFormat;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.Date;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.TreeMap;
27
28 import org.apache.commons.io.FileUtils;
29 import org.kuali.common.aws.s3.pojo.AccountDeltaSummary;
30 import org.kuali.common.aws.s3.pojo.BucketDeltaLine;
31 import org.kuali.common.aws.s3.pojo.BucketDeltaSummary;
32 import org.kuali.common.aws.s3.pojo.BucketSummaryLine;
33 import org.kuali.common.aws.s3.pojo.BucketSummaryLineComparator;
34 import org.kuali.common.util.FormatUtils;
35
36 public class DeltaUtils {
37 SimpleDateFormat shortDateFormatter = new SimpleDateFormat("yyyy-MM-dd");
38
39 private static DeltaUtils instance;
40
41 public static synchronized DeltaUtils getInstance() {
42 if (instance == null) {
43 instance = new DeltaUtils();
44 }
45 return instance;
46 }
47
48 protected DeltaUtils() {
49 super();
50 }
51
52 public AccountDeltaSummary getAccountDeltaSummary(File csv) {
53
54 List<String> lines = getLines(csv);
55 List<BucketSummaryLine> summaryLines = getBucketSummaryLines(lines);
56 List<String> buckets = getBucketNames(summaryLines);
57 List<BucketDeltaSummary> bucketDeltaSummaries = new ArrayList<BucketDeltaSummary>();
58
59 for (String bucket : buckets) {
60 List<BucketSummaryLine> matchingLines = getMatchingSummaryLines(bucket, summaryLines);
61 BucketDeltaSummary bds = getBucketDeltaSummary(matchingLines);
62 List<BucketDeltaLine> deltaLines = getBucketDeltaLines(matchingLines);
63 bds.setBucket(bucket);
64 bds.setDeltaLines(deltaLines);
65 bucketDeltaSummaries.add(bds);
66 }
67
68 AccountDeltaSummary ads = new AccountDeltaSummary();
69 ads.setBucketDeltaSummaries(bucketDeltaSummaries);
70 return ads;
71 }
72
73 public BucketDeltaSummary getBucketDeltaSummary(List<BucketSummaryLine> summaryLines) {
74
75 if (summaryLines.size() < 2) {
76 return new BucketDeltaSummary();
77 }
78
79 BucketSummaryLine first = summaryLines.get(0);
80 BucketSummaryLine last = summaryLines.get(summaryLines.size() - 1);
81
82 Date startDate = first.getDate();
83 Date endDate = last.getDate();
84 long interval = endDate.getTime() - startDate.getTime();
85 long fileDelta = last.getFiles() - first.getFiles();
86 long byteDelta = last.getBytes() - first.getBytes();
87
88 BucketDeltaSummary deltaSummary = new BucketDeltaSummary();
89 deltaSummary.setByteDelta(byteDelta);
90 deltaSummary.setInterval(interval);
91 deltaSummary.setStartDate(startDate);
92 deltaSummary.setEndDate(endDate);
93 deltaSummary.setFileDelta(fileDelta);
94 return deltaSummary;
95 }
96
97 public String toString(AccountDeltaSummary summary) {
98 List<String[]> rows = new ArrayList<String[]>();
99 for (BucketDeltaSummary bds : summary.getBucketDeltaSummaries()) {
100 rows.addAll(getRows(bds.getBucket(), bds.getDeltaLines()));
101 String files = FormatUtils.getCount(bds.getFileDelta());
102 String bytes = FormatUtils.getSize(bds.getByteDelta());
103 String start = shortDateFormatter.format(bds.getStartDate());
104 String end = shortDateFormatter.format(bds.getEndDate());
105 String interval = FormatUtils.getTime(bds.getInterval());
106 rows.add(new String[] { "", "", "", "", "", "" });
107 rows.add(new String[] { "totals", files, bytes, start, end, interval });
108 rows.add(getPerDayRow(bds));
109 rows.add(new String[] { "", "", "", "", "", "" });
110 rows.add(new String[] { "", "", "", "", "", "" });
111 }
112 List<String> columns = new ArrayList<String>();
113 columns.add("bucket");
114 columns.add("files");
115 columns.add("size");
116 columns.add("start");
117 columns.add("end");
118 columns.add("interval");
119 return S3Utils.getInstance().toString(columns, rows);
120 }
121
122 protected String[] getPerDayRow(BucketDeltaSummary bds) {
123 String perDay = "per day";
124 double days = bds.getInterval() / FormatUtils.DAY;
125 String files = FormatUtils.getCount((long) (bds.getFileDelta() / days));
126 long byteDelta = bds.getByteDelta();
127 long bytesPerDay = (long) (byteDelta / days);
128 String bytes = FormatUtils.getSize(bytesPerDay);
129 return new String[] { perDay, files, bytes, "", "", "" };
130 }
131
132 public List<String[]> getRows(String bucket, List<BucketDeltaLine> deltaLines) {
133 List<String[]> rows = new ArrayList<String[]>();
134 for (BucketDeltaLine deltaLine : deltaLines) {
135 String files = FormatUtils.getCount(deltaLine.getFileDelta());
136 String size = FormatUtils.getSize(deltaLine.getByteDelta());
137 String start = shortDateFormatter.format(deltaLine.getStartDate());
138 String end = shortDateFormatter.format(deltaLine.getEndDate());
139 String interval = FormatUtils.getTime(deltaLine.getInterval());
140 String[] row = new String[] { bucket, files, size, start, end, interval };
141 rows.add(row);
142 }
143 return rows;
144 }
145
146 public List<String> getLines(File file) {
147 try {
148 return FileUtils.readLines(file);
149 } catch (IOException e) {
150 throw new IllegalStateException("Can't read lines from " + getCanonicalPath(file), e);
151 }
152 }
153
154 public String getCanonicalPath(File file) {
155 try {
156 return file.getCanonicalPath();
157 } catch (IOException e) {
158 throw new IllegalArgumentException("Unable to determine canonical path for " + file, e);
159 }
160 }
161
162 public List<BucketSummaryLine> getBucketSummaryLines(List<String> lines) {
163 List<BucketSummaryLine> summaryLines = new ArrayList<BucketSummaryLine>();
164
165 for (int i = 1; i < lines.size(); i++) {
166 String line = lines.get(i);
167 String[] tokens = line.split(",");
168 String bucket = tokens[0];
169 Long files = new Long(tokens[1]);
170 Long bytes = new Long(tokens[2]);
171 Date date = FormatUtils.parseDate(tokens[3]);
172 BucketSummaryLine bsl = new BucketSummaryLine();
173 bsl.setBucket(bucket);
174 bsl.setFiles(files);
175 bsl.setBytes(bytes);
176 bsl.setDate(date);
177 summaryLines.add(bsl);
178 }
179 return summaryLines;
180 }
181
182 public List<String> getBucketNames(List<BucketSummaryLine> summaryLines) {
183 Map<String, String> map = new TreeMap<String, String>();
184 for (BucketSummaryLine bsl : summaryLines) {
185 map.put(bsl.getBucket(), bsl.getBucket());
186 }
187 return new ArrayList<String>(map.keySet());
188
189 }
190
191 public List<BucketDeltaLine> getBucketDeltaLines(List<BucketSummaryLine> summaryLines) {
192 List<BucketDeltaLine> bdls = new ArrayList<BucketDeltaLine>();
193 for (int i = 0; i < summaryLines.size() - 1; i++) {
194 BucketSummaryLine current = summaryLines.get(i);
195 BucketSummaryLine next = summaryLines.get(i + 1);
196 long fileDelta = next.getFiles() - current.getFiles();
197 long byteDelta = next.getBytes() - current.getBytes();
198 Date startDate = current.getDate();
199 Date endDate = next.getDate();
200 long interval = endDate.getTime() - startDate.getTime();
201 BucketDeltaLine bdl = new BucketDeltaLine();
202 bdl.setFileDelta(fileDelta);
203 bdl.setByteDelta(byteDelta);
204 bdl.setStartDate(startDate);
205 bdl.setEndDate(endDate);
206 bdl.setInterval(interval);
207 bdls.add(bdl);
208 }
209 return bdls;
210 }
211
212 public List<BucketSummaryLine> getMatchingSummaryLines(String bucket, List<BucketSummaryLine> summaryLines) {
213 Collections.sort(summaryLines, new BucketSummaryLineComparator());
214 List<BucketSummaryLine> matchingLines = new ArrayList<BucketSummaryLine>();
215 for (BucketSummaryLine bsl : summaryLines) {
216 if (bsl.getBucket().equals(bucket)) {
217 matchingLines.add(bsl);
218 }
219 }
220 return matchingLines;
221 }
222
223 }