// Sample code file: JdbcLogDriver.java

// Warning: This code has been marked up for HTML
/*
*  2002-2003 (C) Unpublished Copyright Novell, Inc. 
*  All Rights Reserved.
*
*  No part of this file may be duplicated, revised, translated,
*  localized or modified in any manner or compiled, linked or 
*  uploaded or downloaded to or from any computer system without
*  the prior written consent of Novell, Inc.
* 
*  File:    JdbcLogDriver.java
*  Purpose: Generic jdbc log driver
*
*  Author: Rick Meredith
*
* 
*/
package com.novell.naudit;

import com.novell.naudit.EventStruct;

import java.sql.*;
import java.util.*;
import java.io.*;
import java.nio.*;

class JdbcLogDriver
{
   //property file name and values
   private static final String CONFIG_FILE = "jdbc.properties";
   // ***** Get config values from file read above
   private static String jdbcClass;
   private static String jdbcURL;
   private static String jdbcUser;
   private static String jdbcPwd;
   private static String jdbcCreateTable;
   private static String jdbcTable = "log";
   
   private static Connection db;
   private static int retryCount = 0;
   
   
   public static void Init(String arg) throws Exception
   {
      //read in properties file
      Properties configuration = new Properties();
      //InputStream in = Class.forName("com.novell.naudit.JdbcLogDriver").getResourceAsStream(CONFIG_FILE);
      InputStream in = ClassLoader.getSystemResourceAsStream(CONFIG_FILE);
      
      if (in == null) 
      {
         throw new Exception("Can't find properties file: " + CONFIG_FILE);
      }
      
      configuration.load( in );
      in.close();
      
      // ***** Get config values from file read above
      jdbcClass = configuration.getProperty("JdbcClass");
      jdbcURL = configuration.getProperty("JdbcURL");
      jdbcUser = configuration.getProperty("JdbcUser");
      jdbcPwd = configuration.getProperty("JdbcPwd");
      jdbcCreateTable = configuration.getProperty("JdbcCreateTable");
      jdbcTable = configuration.getProperty("JdbcTable");
            
      //grab connection
      getConnection(true);
   }
   
   private static void getConnection(boolean createTable) throws Exception
   {
      //initialize the jdbc driver
      Driver d = (Driver)Class.forName(jdbcClass).newInstance();
      DriverManager.registerDriver(d);
      
      //get a connection to the database         
      db = DriverManager.getConnection(jdbcURL, jdbcUser, jdbcPwd);
      
      //try to create the table
      //only on startup
      if(createTable && jdbcCreateTable != null && jdbcCreateTable.length() > 0)
      {
         try
         {
            Statement stmt = db.createStatement();
            stmt.executeUpdate(jdbcCreateTable);
            stmt.close();
         }
         catch(Exception e)
         {
            //ok if it fails, table may already be created
         }
      }
      
   }
   
   private static void closeConnection()
   {
      try
      {
         if(db != null)
         {
            db.close();
            db = null;
         }
      }
      catch(Exception e)
      {
         db = null;
      }
   }
   
   public static void ProcessEvent(ByteBuffer buffer) throws Exception
   {
      //create event
      EventStruct event = new EventStruct(buffer);
      storeEvent(event);
      
   }
   
   public static void storeEvent(EventStruct event) throws Exception
   {
      try
      {         
         //create insert statement
         String insertStmt = "INSERT INTO " + jdbcTable + 
         " (SourceIP, ClientTimestamp, ClientMS, ServerTimestamp, SessionID, " +
         " Component, EventID, Severity, Grouping," +
         " Originator, OriginatorType, Target, TargetType, SubTarget," +
         " Text1, Text2, Text3, " +
         " Value1, Value2, Value3, MIMEType, DataSize, Data, Signature) VALUES" +
         " ('" + event.sourceIP + "', '" + event.clientTimestamp + "'," + 
         " '" + event.clientMilliseconds + "', '" + event.serverTimestamp + "', '" + event.sessionId + "', " +
         " ?, '" + event.ID + "', '" + event.severity + "'," + //?=component
         " '" + event.groupID + "', " + 
         " ?, '" + event.originatorType + "', ?, '" + event.targetType + "', ?, " +
         " ?, ?, ?," + //?=text1, text2, text3
         " '" + event.value1 + "', '" + event.value2 + "', '" + event.value3 +"', '" + event.MIMEHint + "'," +
         " '" + event.dataSize + "', ?, ?)"; //'?' are for values to be added later ?=Data, and signature
         
         PreparedStatement stmt = db.prepareStatement(insertStmt);
         
         //add binary and string data
         stmt.setString(1, event.component);
         stmt.setString(2, event.originator);
         stmt.setString(3, event.target);
         stmt.setString(4, event.subTarget);
         stmt.setString(5, event.text1);
         stmt.setString(6, event.text2);
         stmt.setString(7, event.text3);
         stmt.setBytes(8, event.data);
         stmt.setString(9, event.signature);
         
         //insert new row
         stmt.executeUpdate();
         
         stmt.close();
      }
      catch(SQLException sql)
      {
         if(retryCount > 3)
         {
            retryCount = 0;
            throw sql;
         }
         
         //try again upto three times
         retryCount++;
         getConnection(false);
         storeEvent(event);
      }
      
      retryCount = 0 ;
   }
   
   public static void Shutdown(String arg) throws Exception
   {
      if(!db.isClosed())
      {
         db.close();
      }
   }
}