This project has retired. For details please refer to its Attic page.
Macro xref
View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.chukwa.database;
19  
20  import java.sql.DatabaseMetaData;
21  import java.sql.ResultSet;
22  import java.sql.SQLException;
23  import java.util.HashMap;
24  import java.util.Map.Entry;
25  import java.util.regex.Matcher;
26  import java.util.regex.Pattern;
27  
28  import javax.servlet.http.HttpServletRequest;
29  
30  import org.apache.commons.logging.Log;
31  import org.apache.commons.logging.LogFactory;
32  import org.apache.hadoop.chukwa.util.DatabaseWriter;
33  
34  public class Macro {
35      private static Log log = LogFactory.getLog(Macro.class);
36      private boolean forCharting = false;
37      private long current = 0;
38      private long start = 0;
39      private long end = 0;
40      private static DatabaseConfig dbc = new DatabaseConfig();
41      private DatabaseWriter db = null;
42      private String query = null;
43      private HttpServletRequest request = null;
44  
45      public Macro(long timestamp, String query) {
46          this.current = timestamp;
47          this.start = timestamp;
48          this.end = timestamp;
49          this.query = query;
50      }
51  
52      public Macro(long startTime, long endTime, String query) {
53          this.current = endTime;
54          this.start = startTime;
55          this.end = endTime;
56          forCharting = true;	
57          this.query = query;
58      }
59      
60      public Macro(long startTime, long endTime, String query, HttpServletRequest request) {
61          this.request = request;
62          this.current = endTime;
63          this.start = startTime;
64          this.end = endTime;
65          forCharting = true; 
66          this.query = query;        
67      }
68      public HashMap<String,String> findMacros(String query) throws SQLException {
69          boolean add=false;
70          HashMap<String,String> macroList = new HashMap<String,String>();
71          String macro="";
72          for(int i=0;i<query.length();i++) {
73              if(query.charAt(i)==']') {
74                  add=false;
75                  if(!macroList.containsKey(macro)) {
76                      String subString = computeMacro(macro);
77                      macroList.put(macro,subString);	    			
78                  }
79                  macro="";
80              }
81              if(add) {
82                  macro=macro+query.charAt(i);
83              }
84              if(query.charAt(i)=='[') {
85                  add=true;
86              }
87          }
88          return macroList;
89      }
90  
91      public String computeMacro(String macro) throws SQLException {
92          Pattern p = Pattern.compile("past_(.*)_minutes");
93          Matcher matcher = p.matcher(macro);
94          if(macro.indexOf("avg(")==0 || macro.indexOf("group_avg(")==0 || macro.indexOf("sum(")==0) {
95              String meta="";
96              String[] table = null;
97              if(forCharting) {
98                  table = dbc.findTableNameForCharts(macro.substring(macro.indexOf("(")+1,macro.indexOf(")")), start, end);
99              } else {
100                 table = dbc.findTableName(macro.substring(macro.indexOf("(")+1,macro.indexOf(")")), start, end);
101             }
102             try {
103                 String cluster = System.getProperty("CLUSTER");
104                 if(cluster==null) {
105                     cluster="unknown";
106                 }
107                 db = new DatabaseWriter(cluster);
108                 DatabaseMetaData dbMetaData = db.getConnection().getMetaData();
109                 ResultSet rs = dbMetaData.getColumns ( null,null,table[0], null);
110                 boolean first=true;
111                 while(rs.next()) {
112                     if(!first) {
113                         meta = meta+",";
114                     }
115                     String name = rs.getString(4);
116                     int type = rs.getInt(5);
117                     if(type==java.sql.Types.VARCHAR) {
118                         if(macro.indexOf("group_avg(")<0) {
119                             meta=meta+"count("+name+") as "+name;
120                         } else {
121                             meta=meta+name;
122                         }
123                         first=false;
124                     } else if(type==java.sql.Types.DOUBLE ||
125                             type==java.sql.Types.FLOAT ||
126                             type==java.sql.Types.INTEGER) {
127                         if(macro.indexOf("sum(")==0) {
128                             meta=meta+"sum("+name+")";	            			
129                         } else {
130                             meta=meta+"avg("+name+")";
131                         }
132                         first=false;
133                     } else if(type==java.sql.Types.TIMESTAMP) {
134                         meta=meta+name;	            			
135                         first=false;
136                     } else {
137                         if(macro.indexOf("sum(")==0) {
138                             meta=meta+"SUM("+name+")";
139                         } else {
140                             meta=meta+"AVG("+name+")";	            			
141                         }
142                         first=false;
143                     }
144                 }
145                 db.close();
146                 if(first) {
147                     throw new SQLException("Table is undefined.");
148                 }
149             } catch(SQLException ex) {
150                 throw new SQLException("Table does not exist:"+ table[0]);
151             }
152             return meta;
153         } else if(macro.indexOf("now")==0) {
154             return DatabaseWriter.formatTimeStamp(current);
155         } else if(macro.intern()=="start".intern()) {
156             return DatabaseWriter.formatTimeStamp(start);
157         } else if(macro.intern()=="end".intern()) {
158             return DatabaseWriter.formatTimeStamp(end);
159         } else if(matcher.find()) {
160             int period = Integer.parseInt(matcher.group(1));
161             long timestamp = current - (current % (period*60*1000L)) - (period*60*1000L);
162             return DatabaseWriter.formatTimeStamp(timestamp);
163         } else if(macro.indexOf("past_hour")==0) {
164             return DatabaseWriter.formatTimeStamp(current-3600*1000L);
165         } else if(macro.endsWith("_week")) {
166             long partition = current / DatabaseConfig.WEEK;
167             if(partition<=0) {
168                 partition=1;
169             }
170             String[] buffers = macro.split("_");
171             StringBuffer tableName = new StringBuffer();
172             for(int i=0;i<buffers.length-1;i++) {
173                 tableName.append(buffers[i]);
174                 tableName.append("_");
175             }
176             tableName.append(partition);
177             tableName.append("_week");
178             return tableName.toString();
179         } else if(macro.endsWith("_month")) {
180             long partition = current / DatabaseConfig.MONTH;
181             if(partition<=0) {
182                 partition=1;
183             }
184             String[] buffers = macro.split("_");
185             StringBuffer tableName = new StringBuffer();
186             for(int i=0;i<buffers.length-1;i++) {
187                 tableName.append(buffers[i]);
188                 tableName.append("_");
189             }
190             tableName.append(partition);
191             tableName.append("_month");
192             return tableName.toString();
193         } else if(macro.endsWith("_quarter")) {
194             long partition = current / DatabaseConfig.QUARTER;
195             if(partition<=0) {
196                 partition=1;
197             }
198             String[] buffers = macro.split("_");
199             StringBuffer tableName = new StringBuffer();
200             for(int i=0;i<buffers.length-1;i++) {
201                 tableName.append(buffers[i]);
202                 tableName.append("_");
203             }
204             tableName.append(partition);
205             tableName.append("_quarter");
206             return tableName.toString();
207         } else if(macro.endsWith("_year")) {
208             long partition = current / DatabaseConfig.YEAR;
209             if(partition<=0) {
210                 partition=1;
211             }
212             String[] buffers = macro.split("_");
213             StringBuffer tableName = new StringBuffer();
214             for(int i=0;i<buffers.length-1;i++) {
215                 tableName.append(buffers[i]);
216                 tableName.append("_");
217             }
218             tableName.append(partition);
219             tableName.append("_year");
220             return tableName.toString();
221         } else if(macro.endsWith("_decade")) {
222             long partition = current / DatabaseConfig.DECADE;
223             if(partition<=0) {
224                 partition=1;
225             }
226             String[] buffers = macro.split("_");
227             StringBuffer tableName = new StringBuffer();
228             for(int i=0;i<buffers.length-1;i++) {
229                 tableName.append(buffers[i]);
230                 tableName.append("_");
231             }
232             tableName.append(partition);
233             tableName.append("_decade");
234             return tableName.toString();
235         }
236         if(forCharting) {
237             if(macro.startsWith("session(") && request!=null){
238                 String keyword = macro.substring(macro.indexOf("(")+1,macro.indexOf(")"));
239                 String[] objects = null;
240                 if(request.getSession().getAttribute(keyword)!=null) {
241                     objects = ((String)request.getSession().getAttribute(keyword)).split(",");
242                 }
243                 StringBuffer buf = new StringBuffer();
244                 boolean first = true;
245                 if(objects!=null) {
246                     for(String object : objects) {
247                         if(!first) {
248                             buf.append(" or ");
249                         }
250                         first = false;
251                         buf.append(macro.substring(macro.indexOf("(")+1,macro.indexOf(")"))+"='"+object+"'");
252                     }
253                     return buf.toString();
254                 }
255                 return "";
256             } else {
257                 String[] tableList = dbc.findTableNameForCharts(macro, start, end);
258                 StringBuffer buf = new StringBuffer();
259                 boolean first = true;
260                 for(String table : tableList) {
261                     if(!first) {
262                         buf.append("|");
263                     }
264                     first = false;
265                     buf.append(table);
266                 }
267                 return buf.toString();
268             }
269         }
270         String[] tableList = dbc.findTableName(macro,current,current);
271         return tableList[0];
272     }
273     public String toString() {
274         try {
275           HashMap<String, String> macroList = findMacros(query);
276           for(Entry<String, String> entry : macroList.entrySet()) {
277             String mkey = entry.getKey();
278             String value = entry.getValue();
279             if(value.contains("|")) {
280               StringBuffer buf = new StringBuffer();
281               String[] tableList = value.split("\\|");
282               boolean first = true;
283               for(String table : tableList) {
284                 String newQuery = query.replace("["+mkey+"]", table);
285                 if(!first) {
286                   buf.append(" union ");
287                 }
288                 buf.append("(");
289                 buf.append(newQuery);
290                 buf.append(")");
291                 first = false;
292               }
293               query = buf.toString();
294             } else {
295               log.debug("replacing:"+mkey+" with "+macroList.get(mkey));
296               query = query.replace("["+mkey+"]", macroList.get(mkey));
297             }
298           }
299         } catch(SQLException ex) {
300             log.error(query);
301             log.error(ex.getMessage());
302         }
303         return query;
304     }
305 
306 }