All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openas2.processor.msgtracking.DbTrackingModule Maven / Gradle / Ivy

Go to download

Open source implementation of the AS2 standard for signed encrypted and compressed document transfer

There is a newer version: 2.10.1
Show newest version
package org.openas2.processor.msgtracking;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openas2.OpenAS2Exception;
import org.openas2.Session;
import org.openas2.message.Message;
import org.openas2.params.ComponentParameters;
import org.openas2.params.CompositeParameters;
import org.openas2.params.ParameterParser;
import org.openas2.util.DateUtil;
import org.openas2.util.Properties;

public class DbTrackingModule extends BaseMsgTrackingModule
{
	public static final String PARAM_TCP_SERVER_START = "tcp_server_start";
	public static final String PARAM_TCP_SERVER_PORT = "tcp_server_port";
	public static final String PARAM_TCP_SERVER_PWD = "tcp_server_password";
	public static final String PARAM_DB_USER = "db_user";
	public static final String PARAM_DB_PWD = "db_pwd";
	public static final String PARAM_DB_NAME = "db_name";
	public static final String PARAM_DB_DIRECTORY = "db_directory";
	public static final String PARAM_JDBC_CONNECT_STRING = "jdbc_connect_string";
	public static final String PARAM_JDBC_DRIVER = "jdbc_driver";
	public static final String PARAM_JDBC_SERVER_URL = "jdbc_server_url";
	public static final String PARAM_JDBC_PARAMS = "jdbc_extra_paramters";

	public static final String PARAM_USE_EMBEDDED_DB = "use_embedded_db";
	public static final String PARAM_FORCE_LOAD_JDBC_DRIVER = "force_load_jdbc_driver";

	private String dbUser = null;
	private String dbPwd = null;
	private String jdbcConnectString = null;
	private String configBaseDir = null;
	private String jdbcDriver = null;
	private boolean isRunning = false;
	private String sqlEscapeChar = "'";
	private boolean useEmbeddedDB = true;
	private boolean forceLoadJdbcDriver = false;
	private String dbPlatform = "h2";
	IDBHandler dbHandler = null;

	private Log logger = LogFactory.getLog(DbTrackingModule.class.getSimpleName());

	public void init(Session session, Map options) throws OpenAS2Exception
	{
		super.init(session, options);
		CompositeParameters paramParser = createParser();
		dbUser = getParameter(PARAM_DB_USER, true);
		dbPwd = getParameter(PARAM_DB_PWD, true);
		configBaseDir = session.getBaseDirectory();
		jdbcConnectString = getParameter(PARAM_JDBC_CONNECT_STRING, true);
		jdbcConnectString.replace("%home%", configBaseDir);
		// Support component attributes in connect string
		jdbcConnectString = ParameterParser.parse(jdbcConnectString, paramParser);
		dbPlatform = jdbcConnectString.replaceAll(".*jdbc:([^:]*):.*", "$1");
		jdbcDriver = getParameter(PARAM_JDBC_DRIVER, false);
		sqlEscapeChar = Properties.getProperty("sql_escape_character", "'");
		useEmbeddedDB = "true".equals(getParameter(PARAM_USE_EMBEDDED_DB, "true"));
		forceLoadJdbcDriver = "true".equals(getParameter(PARAM_USE_EMBEDDED_DB, "false"));
		if (!useEmbeddedDB && forceLoadJdbcDriver)
		{
			try
			{

				Class.forName(jdbcDriver);

			} catch (ClassNotFoundException e)
			{

				logger.error("Failed to load JDBC driver: " + jdbcDriver, e);
				e.printStackTrace();
				return;

			}
		}
	}

	protected String getModuleAction()
	{
		return DO_TRACK_MSG;
	}

	protected CompositeParameters createParser()
	{
		CompositeParameters params = new CompositeParameters(true);

		params.add("component", new ComponentParameters(this));
		return params;
	}

	protected void persist(Message msg, Map map)
	{
		Connection conn = null;
		try
		{
			if (useEmbeddedDB)
				conn = dbHandler.getConnection();
			else
			{
				conn = DriverManager.getConnection(jdbcConnectString, dbUser, dbPwd);
			}
			Statement s = conn.createStatement();
			String msgIdField = FIELDS.MSG_ID;
			ResultSet rs = s.executeQuery(
					"select * from msg_metadata where " + msgIdField + " = '" + map.get(msgIdField) + "'");
			ResultSetMetaData meta = rs.getMetaData();
			boolean isUpdate = rs.next(); // Record already exists so update
			StringBuffer fieldStmt = new StringBuffer();
			StringBuffer valuesStmt = new StringBuffer();
			for (int i = 0; i < meta.getColumnCount(); i++)
			{
				String colName = meta.getColumnLabel(i + 1);
				if (colName.equalsIgnoreCase("ID"))
					continue;
				else if (colName.equalsIgnoreCase(FIELDS.UPDATE_DT))
				{
					// Ignore if not update mode
					if (isUpdate)
						appendFieldForUpdate(colName, DateUtil.getSqlTimestamp(), fieldStmt, meta.getColumnType(i + 1));
				} else if (colName.equalsIgnoreCase(FIELDS.CREATE_DT))
					map.remove(FIELDS.CREATE_DT);
				else if (isUpdate)
				{
					// Only write unchanged field values
					String mapVal = map.get(colName.toUpperCase());
					if (mapVal == null)
					{
						continue;
					}
					String dbVal = rs.getString(colName);
					if (dbVal != null && mapVal.equals(dbVal))
					{
						// Unchanged value so remove from map
						continue;
					}
					appendFieldForUpdate(colName, mapVal, fieldStmt, meta.getColumnType(i + 1));
				} else
				{
					// For new record add every field that is not NULL
					String mapVal = map.get(colName.toUpperCase());
					if (mapVal == null)
					{
						continue;
					}
					appendFieldForInsert(colName, mapVal, fieldStmt, valuesStmt, meta.getColumnType(i + 1));
				}
			}
			if (fieldStmt.length() > 0)
			{
				String stmt = "";
				if (isUpdate)
				{
					stmt = "update msg_metadata set " + fieldStmt.toString() + " where " + FIELDS.MSG_ID + " = '"
							+ map.get(msgIdField) + "'";
				} else
					stmt = "insert into msg_metadata (" + fieldStmt.toString() + ") values (" + valuesStmt.toString() + ")";
				if (s.executeUpdate(stmt) > 0)
				{
					if (logger.isDebugEnabled())
						logger.debug("Tracking record successfully persisted to database: " + map);
				} else
				{
					throw new OpenAS2Exception("Failed to persist tracking record to DB: " + map);
				}
			} else
			{
				if (logger.isInfoEnabled())
					logger.info("No change from existing record in DB. Tracking record not updated: " + map);
			}
		} catch (Exception e)
		{
			msg.setLogMsg("Failed to persist a tracking event: " + org.openas2.logging.Log.getExceptionMsg(e)
					+ " ::: Data map: " + map);
			logger.error(msg, e);
		} finally
		{
			if (conn != null)
			{
				try
				{
					conn.close();
				} catch (SQLException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

	}

	private String formatField(String value, int dataType)
	{
		if (value == null)
			return "NULL";
		switch (dataType)
		{
		case Types.BIGINT:
		case Types.DECIMAL:
		case Types.DOUBLE:
		case Types.FLOAT:
		case Types.INTEGER:
		case Types.NUMERIC:
		case Types.REAL:
		case Types.SMALLINT:
		case Types.BINARY:
		case Types.TINYINT:
		//case Types.ROWID:
			return value;
		case Types.TIME_WITH_TIMEZONE:
		case Types.TIMESTAMP_WITH_TIMEZONE:
		case Types.DATE:
		case Types.TIME:
		case Types.TIMESTAMP:
			if ("oracle".equalsIgnoreCase(dbPlatform))
			{
				if (value.length() > 19)
					return ("TO_TIMESTAMP('" + value + "','YYYY-MM-DD HH24:MI:SS.FF')");
				else
					return ("TO_DATE('" + value + "','YYYY-MM-DD HH24:MI:SS')");
			} else if ("mssql".equalsIgnoreCase(dbPlatform))
				return ("CAST('" + value + "' AS DATETIME)");
			else
				return "'" + value + "'";

		}
		// Must be some kind of string value if it gets here
		return "'" + value.replaceAll("'", sqlEscapeChar + "'") + "'";

	}

	private void appendFieldForUpdate(String name, String value, StringBuffer sb, int dataType)
	{
		if (sb.length() > 0)
			sb.append(",");

		sb.append(name).append("=").append(formatField(value, dataType));

	}

	private void appendFieldForInsert(String name, String value, StringBuffer names, StringBuffer values, int dataType)
	{
		if (names.length() > 0)
		{
			names.append(",");
			values.append(",");
		}

		names.append(name);
		values.append(formatField(value, dataType));

	}

	public boolean isRunning()
	{
		if (useEmbeddedDB)
			return isRunning;
		else
			return true;
	}

	public void start() throws OpenAS2Exception
	{
		if (!useEmbeddedDB)
			return;

		dbHandler = new EmbeddedDBHandler();
		dbHandler.start(jdbcConnectString, dbUser, dbPwd, getParameters());
		isRunning = true;
	}

	public void stop()
	{
		if (!useEmbeddedDB)
			return;

		dbHandler.stop();
	}

	@Override
	public boolean healthcheck(List failures)
	{
		Connection conn = null;
		try
		{
			if (useEmbeddedDB)
				conn = dbHandler.getConnection();
			else
			{
				conn = DriverManager.getConnection(jdbcConnectString, dbUser, dbPwd);
			}
			Statement s = conn.createStatement();
			ResultSet rs = s.executeQuery(
					"select count(*) from msg_metadata");
		} catch (Exception e)
		{
			failures.add(this.getClass().getSimpleName()
					+ " - Failed to check DB tracking module connection to DB: " + e.getMessage()
					+ " :: Connect String: " + jdbcConnectString);
			return false;
		} finally
		{
			if (conn != null)
			{
				try
				{
					conn.close();
				} catch (Exception e)
				{
				}
			}
		}

		return true;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy