org.apache.hadoop.chukwa.database.Macro.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.chukwa.database.Macro.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.hadoop.chukwa.database;

import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.chukwa.util.DatabaseWriter;

public class Macro {
    private static Log log = LogFactory.getLog(Macro.class);
    private boolean forCharting = false;
    private long current = 0;
    private long start = 0;
    private long end = 0;
    private static DatabaseConfig dbc = new DatabaseConfig();
    private static DatabaseWriter db = null;
    private String query = null;
    private HttpServletRequest request = null;

    public Macro(long timestamp, String query) {
        this.current = timestamp;
        this.start = timestamp;
        this.end = timestamp;
        this.query = query;
    }

    public Macro(long startTime, long endTime, String query) {
        this.current = endTime;
        this.start = startTime;
        this.end = endTime;
        forCharting = true;
        this.query = query;
    }

    public Macro(long startTime, long endTime, String query, HttpServletRequest request) {
        this.request = request;
        this.current = endTime;
        this.start = startTime;
        this.end = endTime;
        forCharting = true;
        this.query = query;
    }

    public HashMap<String, String> findMacros(String query) throws SQLException {
        boolean add = false;
        HashMap<String, String> macroList = new HashMap<String, String>();
        String macro = "";
        for (int i = 0; i < query.length(); i++) {
            if (query.charAt(i) == ']') {
                add = false;
                if (!macroList.containsKey(macro)) {
                    String subString = computeMacro(macro);
                    macroList.put(macro, subString);
                }
                macro = "";
            }
            if (add) {
                macro = macro + query.charAt(i);
            }
            if (query.charAt(i) == '[') {
                add = true;
            }
        }
        return macroList;
    }

    public String computeMacro(String macro) throws SQLException {
        Pattern p = Pattern.compile("past_(.*)_minutes");
        Matcher matcher = p.matcher(macro);
        if (macro.indexOf("avg(") == 0 || macro.indexOf("group_avg(") == 0 || macro.indexOf("sum(") == 0) {
            String meta = "";
            String[] table = null;
            if (forCharting) {
                table = dbc.findTableNameForCharts(macro.substring(macro.indexOf("(") + 1, macro.indexOf(")")),
                        start, end);
            } else {
                table = dbc.findTableName(macro.substring(macro.indexOf("(") + 1, macro.indexOf(")")), start, end);
            }
            try {
                String cluster = System.getProperty("CLUSTER");
                if (cluster == null) {
                    cluster = "unknown";
                }
                db = new DatabaseWriter(cluster);
                DatabaseMetaData dbMetaData = db.getConnection().getMetaData();
                ResultSet rs = dbMetaData.getColumns(null, null, table[0], null);
                boolean first = true;
                while (rs.next()) {
                    if (!first) {
                        meta = meta + ",";
                    }
                    String name = rs.getString(4);
                    int type = rs.getInt(5);
                    if (type == java.sql.Types.VARCHAR) {
                        if (macro.indexOf("group_avg(") < 0) {
                            meta = meta + "count(" + name + ") as " + name;
                        } else {
                            meta = meta + name;
                        }
                        first = false;
                    } else if (type == java.sql.Types.DOUBLE || type == java.sql.Types.FLOAT
                            || type == java.sql.Types.INTEGER) {
                        if (macro.indexOf("sum(") == 0) {
                            meta = meta + "sum(" + name + ")";
                        } else {
                            meta = meta + "avg(" + name + ")";
                        }
                        first = false;
                    } else if (type == java.sql.Types.TIMESTAMP) {
                        meta = meta + name;
                        first = false;
                    } else {
                        if (macro.indexOf("sum(") == 0) {
                            meta = meta + "SUM(" + name + ")";
                        } else {
                            meta = meta + "AVG(" + name + ")";
                        }
                        first = false;
                    }
                }
                db.close();
                if (first) {
                    throw new SQLException("Table is undefined.");
                }
            } catch (SQLException ex) {
                throw new SQLException("Table does not exist:" + table[0]);
            }
            return meta;
        } else if (macro.indexOf("now") == 0) {
            SimpleDateFormat sdf = new SimpleDateFormat();
            return DatabaseWriter.formatTimeStamp(current);
        } else if (macro.intern() == "start".intern()) {
            return DatabaseWriter.formatTimeStamp(start);
        } else if (macro.intern() == "end".intern()) {
            return DatabaseWriter.formatTimeStamp(end);
        } else if (matcher.find()) {
            int period = Integer.parseInt(matcher.group(1));
            long timestamp = current - (current % (period * 60 * 1000L)) - (period * 60 * 1000L);
            return DatabaseWriter.formatTimeStamp(timestamp);
        } else if (macro.indexOf("past_hour") == 0) {
            return DatabaseWriter.formatTimeStamp(current - 3600 * 1000L);
        } else if (macro.endsWith("_week")) {
            long partition = current / DatabaseConfig.WEEK;
            if (partition <= 0) {
                partition = 1;
            }
            String[] buffers = macro.split("_");
            StringBuffer tableName = new StringBuffer();
            for (int i = 0; i < buffers.length - 1; i++) {
                tableName.append(buffers[i]);
                tableName.append("_");
            }
            tableName.append(partition);
            tableName.append("_week");
            return tableName.toString();
        } else if (macro.endsWith("_month")) {
            long partition = current / DatabaseConfig.MONTH;
            if (partition <= 0) {
                partition = 1;
            }
            String[] buffers = macro.split("_");
            StringBuffer tableName = new StringBuffer();
            for (int i = 0; i < buffers.length - 1; i++) {
                tableName.append(buffers[i]);
                tableName.append("_");
            }
            tableName.append(partition);
            tableName.append("_month");
            return tableName.toString();
        } else if (macro.endsWith("_quarter")) {
            long partition = current / DatabaseConfig.QUARTER;
            if (partition <= 0) {
                partition = 1;
            }
            String[] buffers = macro.split("_");
            StringBuffer tableName = new StringBuffer();
            for (int i = 0; i < buffers.length - 1; i++) {
                tableName.append(buffers[i]);
                tableName.append("_");
            }
            tableName.append(partition);
            tableName.append("_quarter");
            return tableName.toString();
        } else if (macro.endsWith("_year")) {
            long partition = current / DatabaseConfig.YEAR;
            if (partition <= 0) {
                partition = 1;
            }
            String[] buffers = macro.split("_");
            StringBuffer tableName = new StringBuffer();
            for (int i = 0; i < buffers.length - 1; i++) {
                tableName.append(buffers[i]);
                tableName.append("_");
            }
            tableName.append(partition);
            tableName.append("_year");
            return tableName.toString();
        } else if (macro.endsWith("_decade")) {
            long partition = current / DatabaseConfig.DECADE;
            if (partition <= 0) {
                partition = 1;
            }
            String[] buffers = macro.split("_");
            StringBuffer tableName = new StringBuffer();
            for (int i = 0; i < buffers.length - 1; i++) {
                tableName.append(buffers[i]);
                tableName.append("_");
            }
            tableName.append(partition);
            tableName.append("_decade");
            return tableName.toString();
        }
        if (forCharting) {
            if (macro.startsWith("session(") && request != null) {
                String keyword = macro.substring(macro.indexOf("(") + 1, macro.indexOf(")"));
                String[] objects = null;
                if (request.getSession().getAttribute(keyword) != null) {
                    objects = ((String) request.getSession().getAttribute(keyword)).split(",");
                }
                StringBuffer buf = new StringBuffer();
                boolean first = true;
                if (objects != null) {
                    for (String object : objects) {
                        if (!first) {
                            buf.append(" or ");
                        }
                        first = false;
                        buf.append(
                                macro.substring(macro.indexOf("(") + 1, macro.indexOf(")")) + "='" + object + "'");
                    }
                    return buf.toString();
                }
                return "";
            } else {
                String[] tableList = dbc.findTableNameForCharts(macro, start, end);
                StringBuffer buf = new StringBuffer();
                boolean first = true;
                for (String table : tableList) {
                    if (!first) {
                        buf.append("|");
                    }
                    first = false;
                    buf.append(table);
                }
                return buf.toString();
            }
        }
        String[] tableList = dbc.findTableName(macro, current, current);
        return tableList[0];
    }

    public String toString() {
        try {
            HashMap<String, String> macroList = findMacros(query);
            Iterator<String> macroKeys = macroList.keySet().iterator();
            while (macroKeys.hasNext()) {
                String mkey = macroKeys.next();
                if (macroList.get(mkey).contains("|")) {
                    StringBuffer buf = new StringBuffer();
                    String[] tableList = macroList.get(mkey).split("\\|");
                    boolean first = true;
                    for (String table : tableList) {
                        String newQuery = query.replace("[" + mkey + "]", table);
                        if (!first) {
                            buf.append(" union ");
                        }
                        buf.append("(");
                        buf.append(newQuery);
                        buf.append(")");
                        first = false;
                    }
                    query = buf.toString();
                } else {
                    log.debug("replacing:" + mkey + " with " + macroList.get(mkey));
                    query = query.replace("[" + mkey + "]", macroList.get(mkey));
                }
            }
        } catch (SQLException ex) {
            log.error(query);
            log.error(ex.getMessage());
        }
        return query;
    }

}