f5001409db0d6ae146a08323b4668e9f44085c8e
[dmaap/datarouter.git] / datarouter-prov / src / main / java / org / onap / dmaap / datarouter / reports / LatencyReport.java
1 /*******************************************************************************\r
2  * ============LICENSE_START==================================================\r
3  * * org.onap.dmaap\r
4  * * ===========================================================================\r
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
6  * * ===========================================================================\r
7  * * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * * you may not use this file except in compliance with the License.\r
9  * * You may obtain a copy of the License at\r
10  * *\r
11  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * *\r
13  *  * Unless required by applicable law or agreed to in writing, software\r
14  * * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * * See the License for the specific language governing permissions and\r
17  * * limitations under the License.\r
18  * * ============LICENSE_END====================================================\r
19  * *\r
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
21  * *\r
22  ******************************************************************************/\r
23 \r
24 \r
25 package org.onap.dmaap.datarouter.reports;\r
26 \r
27 import java.io.FileNotFoundException;\r
28 import java.io.PrintWriter;\r
29 import java.sql.Connection;\r
30 import java.sql.PreparedStatement;\r
31 import java.sql.ResultSet;\r
32 import java.sql.SQLException;\r
33 import java.util.ArrayList;\r
34 import java.util.List;\r
35 \r
36 import org.onap.dmaap.datarouter.provisioning.utils.DB;\r
37 \r
38 /**\r
39  * Generate a per-file latency report.  It reports on the details related to one file published\r
40  * on one feed. This report can be further reduced in order to generate more specific reports\r
41  * based on feed ID or node name. The report is a .csv file containing the following columns:\r
42  * <table>\r
43  * <tr><td>recordid</td><td>the unique record ID assigned to a particular incoming feed</td></tr>\r
44  * <tr><td>feedid</td><td>the Feed ID for this record</td></tr>\r
45  * <tr><td>uri</td><td>the URI of the file delivered</td></tr>\r
46  * <tr><td>size</td><td>the size of the file delivered</td></tr>\r
47  * <tr><td>min</td><td>the minimum latency in delivering this feed to a subscriber (in ms)</td></tr>\r
48  * <tr><td>max</td><td>the maximum latency in delivering this feed to a subscriber (in ms)</td></tr>\r
49  * <tr><td>avg</td><td>the average latency in delivering this feed to all subscribers (in ms)</td></tr>\r
50  * <tr><td>fanout</td><td>the number of subscribers this feed was delivered to</td></tr>\r
51  * </table>\r
52  *\r
53  * @author Robert P. Eby\r
54  * @version $Id: LatencyReport.java,v 1.1 2013/10/28 18:06:53 eby Exp $\r
55  */\r
56 public class LatencyReport extends ReportBase {\r
57     private static final String SELECT_SQL =\r
58             "select EVENT_TIME, TYPE, PUBLISH_ID, FEED_FILEID, FEEDID, CONTENT_LENGTH from LOG_RECORDS" +\r
59                     " where EVENT_TIME >= ? and EVENT_TIME <= ? order by PUBLISH_ID, EVENT_TIME";\r
60 \r
61     private class Event {\r
62         public final String type;\r
63         public final long time;\r
64 \r
65         public Event(String t, long tm) {\r
66             type = t;\r
67             time = tm;\r
68         }\r
69     }\r
70 \r
71     private class Counters {\r
72         public final String id;\r
73         public final int feedid;\r
74         public final long clen;\r
75         public final String fileid;\r
76         public final List<Event> events;\r
77 \r
78         public Counters(String i, int fid, long c, String s) {\r
79             id = i;\r
80             feedid = fid;\r
81             clen = c;\r
82             fileid = s;\r
83             events = new ArrayList<Event>();\r
84         }\r
85 \r
86         private long pubtime;\r
87 \r
88         public void addEvent(String t, long tm) {\r
89             events.add(new Event(t, tm));\r
90             if (t.equals("pub"))\r
91                 pubtime = tm;\r
92         }\r
93 \r
94         public long min() {\r
95             long min = Long.MAX_VALUE;\r
96             for (Event e : events) {\r
97                 if (e.type.equals("del")) {\r
98                     min = Math.min(min, e.time - pubtime);\r
99                 }\r
100             }\r
101             return min;\r
102         }\r
103 \r
104         public long max() {\r
105             long max = 0;\r
106             for (Event e : events) {\r
107                 if (e.type.equals("del")) {\r
108                     max = Math.max(max, e.time - pubtime);\r
109                 }\r
110             }\r
111             return max;\r
112         }\r
113 \r
114         public long avg() {\r
115             long total = 0, c = 0;\r
116             for (Event e : events) {\r
117                 if (e.type.equals("del")) {\r
118                     total += e.time - pubtime;\r
119                     c++;\r
120                 }\r
121             }\r
122             return (c == 0) ? 0 : total / c;\r
123         }\r
124 \r
125         public int fanout() {\r
126             int n = 0;\r
127             for (Event e : events) {\r
128                 if (e.type.equals("del")) {\r
129                     n++;\r
130                 }\r
131             }\r
132             return n;\r
133         }\r
134 \r
135         @Override\r
136         public String toString() {\r
137             return feedid + "," + fileid + "," + clen + "," + min() + "," + max() + "," + avg() + "," + fanout();\r
138         }\r
139     }\r
140 \r
141     @Override\r
142     public void run() {\r
143         long start = System.currentTimeMillis();\r
144         try {\r
145             DB db = new DB();\r
146             @SuppressWarnings("resource")\r
147             Connection conn = db.getConnection();\r
148             try(PreparedStatement ps = conn.prepareStatement(SELECT_SQL)){\r
149             ps.setLong(1, from);\r
150             ps.setLong(2, to);\r
151             try(ResultSet rs = ps.executeQuery()) {\r
152                 try(PrintWriter os = new PrintWriter(outfile)) {\r
153                     os.println("recordid,feedid,uri,size,min,max,avg,fanout");\r
154                     Counters c = null;\r
155                     while (rs.next()) {\r
156                         long etime = rs.getLong("EVENT_TIME");\r
157                         String type = rs.getString("TYPE");\r
158                         String id = rs.getString("PUBLISH_ID");\r
159                         String fid = rs.getString("FEED_FILEID");\r
160                         int feed = rs.getInt("FEEDID");\r
161                         long clen = rs.getLong("CONTENT_LENGTH");\r
162                         if (c != null && !id.equals(c.id)) {\r
163                             String line = id + "," + c.toString();\r
164                             os.println(line);\r
165                             c = null;\r
166                         }\r
167                         if (c == null) {\r
168                             c = new Counters(id, feed, clen, fid);\r
169                         }\r
170                         if (feed != c.feedid)\r
171                             System.err.println("Feed ID mismatch, " + feed + " <=> " + c.feedid);\r
172                         if (clen != c.clen)\r
173                             System.err.println("Cont Len mismatch, " + clen + " <=> " + c.clen);\r
174                         c.addEvent(type, etime);\r
175                     }\r
176                 }\r
177              db.release(conn);\r
178             }\r
179             }\r
180         } catch (FileNotFoundException e) {\r
181             System.err.println("File cannot be written: " + outfile);\r
182         } catch (SQLException e) {\r
183             logger.error("SQLException: " + e.getMessage());\r
184         }\r
185         logger.debug("Query time: " + (System.currentTimeMillis() - start) + " ms");\r
186     }\r
187 }\r