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

org.parallelj.tracknrestart.jdbc.JDBCSupport Maven / Gradle / Ivy

Go to download

ParallelJ is a Java framework for parallel computing. It provides flow modeling and execution. This project allows to deal with error management in ParallelJ and allows to track a Program execution, and restart it if some errors are found.

There is a newer version: 1.3.3
Show newest version
/*
 *     ParallelJ, framework for parallel computing
 *
 *     Copyright (C) 2010, 2011, 2012 Atos Worldline or third-party contributors as
 *     indicated by the @author tags or express copyright attribution
 *     statements applied by the authors.
 *
 *     This library is free software; you can redistribute it and/or
 *     modify it under the terms of the GNU Lesser General Public
 *     License as published by the Free Software Foundation; either
 *     version 2.1 of the License.
 *
 *     This library is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *     Lesser General Public License for more details.
 *
 *     You should have received a copy of the GNU Lesser General Public
 *     License along with this library; if not, write to the Free Software
 *     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
package org.parallelj.tracknrestart.jdbc;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import org.parallelj.launching.LaunchingMessageKind;
import org.parallelj.tracknrestart.TrackNRestartMessageKind;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobPersistenceException;
import org.quartz.SchedulerException;
import org.quartz.impl.jdbcjobstore.AttributeRestoringConnectionInvocationHandler;
import org.quartz.impl.jdbcjobstore.Constants;
import org.quartz.impl.jdbcjobstore.TablePrefixAware;
import org.quartz.impl.jdbcjobstore.Util;
import org.quartz.utils.DBConnectionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JDBCSupport implements Serializable {

	protected String dataSource;

    protected String tablePrefix = Constants.DEFAULT_TABLE_PREFIX + "TRACK_";

    protected boolean useProperties = false;
    
	public static final String TABLE_PREFIX_SUBST = "{0}";

	public static final String SCHED_NAME_SUBST = "{1}";

	public static final String COL_UID_SUBST = "UID";
	
	public static final String COL_RESULT_SUBST = "RESULT";

	public static final String COL_RETURN_CODE_SUBST = "RETURN_CODE";

	public static final String COL_RESTARTED_UID_SUBST = "RESTARTED_UID";


	private final Logger log = LoggerFactory.getLogger(getClass());

	public String getDataSource() {
		return dataSource;
	}

	public void setDataSource(String dataSource) {
		this.dataSource = dataSource;
	}

    public String getTablePrefix() {
		return tablePrefix;
	}

	public void setTablePrefix(String tablePrefix) {
		this.tablePrefix = tablePrefix;
	}

	public boolean canUseProperties() {
		return useProperties;
	}

	public void setUseProperties(boolean useProperties) {
		this.useProperties = useProperties;
	}

    protected Logger getLog() {
        return log;
    }

	public Connection getNonManagedTXConnection()
			throws JobPersistenceException {
		return getConnection();
	}

	protected Connection getAttributeRestoringConnection(Connection conn) {
		return (Connection) Proxy.newProxyInstance(Thread.currentThread()
				.getContextClassLoader(), new Class[] { Connection.class },
				new AttributeRestoringConnectionInvocationHandler(conn));
	}

	protected Connection getConnection() throws JobPersistenceException {
		Connection conn = null;
		try {
			conn = DBConnectionManager.getInstance().getConnection(
					getDataSource());
		} catch (SQLException sqle) {
			throw new JobPersistenceException(
					"Failed to obtain DB connection from data source '"
							+ getDataSource() + "': " + sqle.toString(), sqle);
		} catch (Throwable e) {
			throw new JobPersistenceException(
					"Failed to obtain DB connection from data source '"
							+ getDataSource() + "': " + e.toString(), e);
		}

		if (conn == null) {
			throw new JobPersistenceException(
					"Could not get connection from DataSource '"
							+ getDataSource() + "'");
		}

		// Protect connection attributes we might change.
		conn = getAttributeRestoringConnection(conn);

		// Set any connection connection attributes we are to override.
		try {
			// if (!isDontSetAutoCommitFalse()) {
			// conn.setAutoCommit(false);
			// }
			conn.setAutoCommit(true);

			// if(isTxIsolationLevelSerializable()) {
			// conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
			// }
			conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
		} catch (SQLException sqle) {
			TrackNRestartMessageKind.WTNRJDBC0003.format();
			getLog().warn(
					"Failed to override connection auto commit/transaction isolation.",
					sqle);
		} catch (Throwable e) {
			try {
				conn.close();
			} catch (Throwable tt) {
			}

			throw new JobPersistenceException("Failure setting up connection.",
					e);
		}

		return conn;
	}

	public void closeStatement(Statement statement) {
		if (null != statement) {
			try {
				statement.close();
			} catch (SQLException ignore) {
			}
		}
	}

	public final String rtp(String query, String schedName) {
		String rtp = Util.rtp(query, tablePrefix, "'" + schedName + "'");
		return rtp;
	}

	protected ByteArrayOutputStream serializeJobData(JobDataMap data)
			throws IOException {
		if (canUseProperties()) {
			return serializeProperties(data);
		}

		try {
			return serializeObject(data);
		} catch (NotSerializableException e) {
			throw new NotSerializableException(
					"Unable to serialize JobDataMap for insertion into "
							+ "database because the value of property '"
							+ getKeyOfNonSerializableValue(data)
							+ "' is not serializable: " + e.getMessage());
		}
	}

	private ByteArrayOutputStream serializeProperties(JobDataMap data)
			throws IOException {
		ByteArrayOutputStream ba = new ByteArrayOutputStream();
		if (null != data) {
			Properties properties = convertToProperty(data.getWrappedMap());
			properties.store(ba, "");
		}

		return ba;
	}

	protected Properties convertToProperty(Map data) throws IOException {
		Properties properties = new Properties();

		for (Iterator entryIter = data.entrySet().iterator(); entryIter
				.hasNext();) {
			Map.Entry entry = (Map.Entry) entryIter.next();

			Object key = entry.getKey();
			Object val = (entry.getValue() == null) ? "" : entry.getValue();

			if (!(key instanceof String)) {
				throw new IOException("JobDataMap keys/values must be Strings "
						+ "when the 'useProperties' property is set. "
						+ " offending Key: " + key);
			}

			if (!(val instanceof String)) {
				throw new IOException("JobDataMap values must be Strings "
						+ "when the 'useProperties' property is set. "
						+ " Key of offending value: " + key);
			}

			properties.put(key, val);
		}

		return properties;
	}

	protected ByteArrayOutputStream serializeObject(Object obj)
			throws IOException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		if (null != obj) {
			ObjectOutputStream out = new ObjectOutputStream(baos);
			out.writeObject(obj);
			out.flush();
		}
		return baos;
	}

	protected Object getKeyOfNonSerializableValue(Map data) {
		for (Iterator entryIter = data.entrySet().iterator(); entryIter
				.hasNext();) {
			Map.Entry entry = (Map.Entry) entryIter.next();

			ByteArrayOutputStream baos = null;
			try {
				baos = serializeObject(entry.getValue());
			} catch (IOException e) {
				return entry.getKey();
			} finally {
				if (baos != null) {
					try {
						baos.close();
					} catch (IOException ignore) {
					}
				}
			}
		}

		// As long as it is true that the Map was not serializable, we should
		// not hit this case.
		return null;
	}

	public void cleanupConnection(Connection conn) {
		if (conn != null) {
			if (conn instanceof Proxy) {
				Proxy connProxy = (Proxy) conn;

				InvocationHandler invocationHandler = Proxy
						.getInvocationHandler(connProxy);
				if (invocationHandler instanceof AttributeRestoringConnectionInvocationHandler) {
					AttributeRestoringConnectionInvocationHandler connHandler = (AttributeRestoringConnectionInvocationHandler) invocationHandler;

					connHandler.restoreOriginalAtributes();
					closeConnection(connHandler.getWrappedConnection());
					return;
				}
			}

			// Wan't a Proxy, or was a Proxy, but wasn't ours.
			closeConnection(conn);
		}
	}

	protected void closeConnection(Connection conn) {
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				TrackNRestartMessageKind.ETNRJDBC0001.format();
//				getLog().error("Failed to close Connection", e);
			} catch (Throwable e) {
				TrackNRestartMessageKind.ETNRJDBC0002.format(e);
//				getLog().error(
//						"Unexpected exception closing Connection."
//								+ "  This is often due to a Connection being returned after or during shutdown.",
//						e);
			}
		}
	}

    public JobDataMap getJobDataMapResultFromBlob(ResultSet rs)
            throws ClassNotFoundException, IOException, SQLException {
            Map map;
            JobDataMap jobDataMap = (JobDataMap) getJobDataFromBlob(rs, COL_RESULT_SUBST);
            return jobDataMap;
        }

    protected Object getJobDataFromBlob(ResultSet rs, String colName)
            throws ClassNotFoundException, IOException, SQLException {
            if (canUseProperties()) {
                Blob blobLocator = rs.getBlob(colName);
                if (blobLocator != null) {
                    InputStream binaryInput = blobLocator.getBinaryStream();
                    return binaryInput;
                } else {
                    return null;
                }
            }

            return getObjectFromBlob(rs, colName);
        }

//TODO Sybase
//    protected Object getJobDataFromBlob(ResultSet rs, String colName)
//            throws ClassNotFoundException, IOException, SQLException {
//            if (canUseProperties()) {
//                InputStream binaryInput = rs.getBinaryStream(colName);
//                return binaryInput;
//            }
//            return getObjectFromBlob(rs, colName);
//        }
        
    protected Object getObjectFromBlob(ResultSet rs, String colName)
            throws ClassNotFoundException, IOException, SQLException {
            Object obj = null;

            Blob blobLocator = rs.getBlob(colName);
            if (blobLocator != null && blobLocator.length() != 0) {
                InputStream binaryInput = blobLocator.getBinaryStream();

                if (null != binaryInput) {
                    if (binaryInput instanceof ByteArrayInputStream
                        && ((ByteArrayInputStream) binaryInput).available() == 0 ) {
                        //do nothing
                    } else {
                        ObjectInputStream in = new ObjectInputStream(binaryInput);
                        try {
                            obj = in.readObject();
                        } finally {
                            in.close();
                        }
                    }
                }

            }
            return obj;
        }

//TODO Sybase
//    protected Object getObjectFromBlob(ResultSet rs, String colName)
//            throws ClassNotFoundException, IOException, SQLException {
//            InputStream binaryInput = rs.getBinaryStream(colName);
//
//            if(binaryInput == null || binaryInput.available() == 0) {
//                return null;
//            }
//
//            Object obj = null;
//
//            ObjectInputStream in = new ObjectInputStream(binaryInput);
//            try {
//                obj = in.readObject();
//            } finally {
//                in.close();
//            }
//
//            return obj;
//        }

    public Map getMapFromProperties(ResultSet rs)
            throws ClassNotFoundException, IOException, SQLException {
            Map map;
            InputStream is = (InputStream) getJobDataFromBlob(rs, Constants.COL_JOB_DATAMAP);
            if(is == null) {
                return null;
            }
            Properties properties = new Properties();
            if (is != null) {
                try {
                    properties.load(is);
                } finally {
                    is.close();
                }
            }
            map = convertFromProperty(properties);
            return map;
        }

    protected Map convertFromProperty(Properties properties) throws IOException {
        return new HashMap(properties);
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy