|
@@ -0,0 +1,232 @@
|
|
|
+/**
|
|
|
+ * 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
|
|
|
+ * <p>
|
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
|
+ * <p>
|
|
|
+ * 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.ozone.audit.parser.common;
|
|
|
+
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.apache.hadoop.ozone.audit.parser.model.AuditEntry;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+
|
|
|
+import java.io.*;
|
|
|
+import java.sql.*;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Properties;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Database helper for ozone audit parser tool.
|
|
|
+ */
|
|
|
+public final class DatabaseHelper {
|
|
|
+ private DatabaseHelper() {
|
|
|
+ //Never constructed
|
|
|
+ }
|
|
|
+ static {
|
|
|
+ loadProperties();
|
|
|
+ }
|
|
|
+ private static final Logger LOG =
|
|
|
+ LoggerFactory.getLogger(DatabaseHelper.class);
|
|
|
+ private static Map<String, String> properties;
|
|
|
+
|
|
|
+ public static boolean setup(String dbName, String logs) {
|
|
|
+ //loadProperties();
|
|
|
+ if(createAuditTable(dbName)) {
|
|
|
+ return insertAudits(dbName, logs);
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static Connection getConnection(String dbName) {
|
|
|
+
|
|
|
+ Connection connection = null;
|
|
|
+ try{
|
|
|
+ Class.forName(ParserConsts.DRIVER);
|
|
|
+ connection = DriverManager.getConnection(
|
|
|
+ ParserConsts.CONNECTION_PREFIX + dbName);
|
|
|
+ } catch (ClassNotFoundException e) {
|
|
|
+ LOG.error(e.getMessage());
|
|
|
+ } catch (SQLException e) {
|
|
|
+ LOG.error(e.getMessage());
|
|
|
+ }
|
|
|
+ return connection;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void loadProperties() {
|
|
|
+ Properties props = new Properties();
|
|
|
+ try{
|
|
|
+ InputStream inputStream = DatabaseHelper.class.getClassLoader()
|
|
|
+ .getResourceAsStream(ParserConsts.PROPS_FILE);
|
|
|
+ if (inputStream != null) {
|
|
|
+ props.load(inputStream);
|
|
|
+ properties = props.entrySet().stream().collect(
|
|
|
+ Collectors.toMap(
|
|
|
+ e -> e.getKey().toString(),
|
|
|
+ e -> e.getValue().toString()
|
|
|
+ )
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ throw new FileNotFoundException("property file '"
|
|
|
+ + ParserConsts.PROPS_FILE + "' not found in the classpath");
|
|
|
+ }
|
|
|
+ } catch(Exception e){
|
|
|
+ LOG.error(e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean createAuditTable(String dbName) {
|
|
|
+
|
|
|
+ try(Connection connection = getConnection(dbName);
|
|
|
+ Statement st = connection.createStatement()) {
|
|
|
+
|
|
|
+ st.executeUpdate(properties.get(ParserConsts.CREATE_AUDIT_TABLE));
|
|
|
+ } catch (SQLException e) {
|
|
|
+ LOG.error(e.getMessage());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean insertAudits(String dbName, String logs) {
|
|
|
+
|
|
|
+ try(Connection connection = getConnection(dbName);
|
|
|
+ PreparedStatement preparedStatement = connection.prepareStatement(
|
|
|
+ properties.get(ParserConsts.INSERT_AUDITS))) {
|
|
|
+
|
|
|
+ ArrayList<AuditEntry> auditEntries = parseAuditLogs(logs);
|
|
|
+ //Insert list to db
|
|
|
+ for(AuditEntry audit : auditEntries) {
|
|
|
+ preparedStatement.setString(1, audit.getTimestamp());
|
|
|
+ preparedStatement.setString(2, audit.getLevel());
|
|
|
+ preparedStatement.setString(3, audit.getLogger());
|
|
|
+ preparedStatement.setString(4, audit.getUser());
|
|
|
+ preparedStatement.setString(5, audit.getIp());
|
|
|
+ preparedStatement.setString(6, audit.getOp());
|
|
|
+ preparedStatement.setString(7, audit.getParams());
|
|
|
+ preparedStatement.setString(8, audit.getResult());
|
|
|
+ preparedStatement.setString(9, audit.getException());
|
|
|
+
|
|
|
+ preparedStatement.executeUpdate();
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ LOG.error(e.getMessage());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static ArrayList<AuditEntry> parseAuditLogs(String filePath)
|
|
|
+ throws Exception {
|
|
|
+ ArrayList<AuditEntry> listResult = new ArrayList<AuditEntry>();
|
|
|
+ try(FileInputStream fis = new FileInputStream(filePath);
|
|
|
+ InputStreamReader isr = new InputStreamReader(fis);
|
|
|
+ BufferedReader bReader = new BufferedReader(isr)) {
|
|
|
+ String currentLine = null;
|
|
|
+ String[] entry = null;
|
|
|
+ AuditEntry tempEntry = null;
|
|
|
+ String nextLine = null;
|
|
|
+ currentLine = bReader.readLine();
|
|
|
+ nextLine = bReader.readLine();
|
|
|
+
|
|
|
+ while(true) {
|
|
|
+ if(tempEntry == null){
|
|
|
+ tempEntry = new AuditEntry();
|
|
|
+ }
|
|
|
+
|
|
|
+ if(currentLine == null) {
|
|
|
+ break;
|
|
|
+ } else {
|
|
|
+ if(!currentLine.matches(ParserConsts.DATE_REGEX)){
|
|
|
+ tempEntry.appendException(currentLine);
|
|
|
+ } else {
|
|
|
+ entry = StringUtils.stripAll(currentLine.split("\\|"));
|
|
|
+ tempEntry = new AuditEntry.Builder()
|
|
|
+ .setTimestamp(entry[0])
|
|
|
+ .setLevel(entry[1])
|
|
|
+ .setLogger(entry[2])
|
|
|
+ .setUser(entry[3].substring(entry[3].indexOf('=') + 1))
|
|
|
+ .setIp(entry[4].substring(entry[4].indexOf('=') + 1))
|
|
|
+ .setOp(entry[5].substring(entry[5].indexOf('=') + 1))
|
|
|
+ .setParams(entry[6])
|
|
|
+ .setResult(entry[7].substring(entry[7].indexOf('=') + 1))
|
|
|
+ .build();
|
|
|
+ if(entry.length == 9){
|
|
|
+ tempEntry.setException(entry[8]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(nextLine == null || nextLine.matches(ParserConsts.DATE_REGEX)){
|
|
|
+ listResult.add(tempEntry);
|
|
|
+ tempEntry = null;
|
|
|
+ }
|
|
|
+ currentLine = nextLine;
|
|
|
+ nextLine = bReader.readLine();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (RuntimeException rx) {
|
|
|
+ throw rx;
|
|
|
+ } catch (Exception ex) {
|
|
|
+ throw ex;
|
|
|
+ }
|
|
|
+
|
|
|
+ return listResult;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String executeCustomQuery(String dbName, String query)
|
|
|
+ throws SQLException {
|
|
|
+ return executeStatement(dbName, query);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String executeTemplate(String dbName, String template)
|
|
|
+ throws SQLException {
|
|
|
+ return executeStatement(dbName,
|
|
|
+ properties.get(template));
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String executeStatement(String dbName, String sql)
|
|
|
+ throws SQLException {
|
|
|
+ StringBuilder result = new StringBuilder();
|
|
|
+ ResultSet rs = null;
|
|
|
+ Statement st = null;
|
|
|
+ ResultSetMetaData rsm = null;
|
|
|
+ try(Connection connection = getConnection(dbName)) {
|
|
|
+ //loadProperties();
|
|
|
+
|
|
|
+ if(connection != null){
|
|
|
+ st = connection.createStatement();
|
|
|
+ rs = st.executeQuery(sql);
|
|
|
+ if(rs != null) {
|
|
|
+ rsm = rs.getMetaData();
|
|
|
+ int cols = rsm.getColumnCount();
|
|
|
+ while(rs.next()){
|
|
|
+ for(int index =1; index<=cols; index++){
|
|
|
+ result.append(rs.getObject(index) + "\t");
|
|
|
+ }
|
|
|
+ result.append("\n");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ st.close();
|
|
|
+ rs.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static boolean validateTemplate(String templateName) {
|
|
|
+ return (properties.get(templateName) != null);
|
|
|
+ }
|
|
|
+}
|