net.sf.hajdbc.sync.SynchronizationContextImpl Maven / Gradle / Ivy
/*
* HA-JDBC: High-Availability JDBC
* Copyright (C) 2012 Paul Ferraro
*
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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 program. If not, see .
*/
package net.sf.hajdbc.sync;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import net.sf.hajdbc.Database;
import net.sf.hajdbc.DatabaseCluster;
import net.sf.hajdbc.DatabaseProperties;
import net.sf.hajdbc.balancer.Balancer;
import net.sf.hajdbc.cache.DatabaseMetaDataCache;
import net.sf.hajdbc.codec.Decoder;
import net.sf.hajdbc.dialect.Dialect;
import net.sf.hajdbc.logging.Level;
import net.sf.hajdbc.logging.Logger;
import net.sf.hajdbc.logging.LoggerFactory;
import net.sf.hajdbc.util.Resources;
/**
* @author Paul Ferraro
* @param Driver or DataSource
*/
public class SynchronizationContextImpl> implements SynchronizationContext
{
private static final Logger logger = LoggerFactory.getLogger(SynchronizationContextImpl.class);
private final Set activeDatabaseSet;
private final D sourceDatabase;
private final D targetDatabase;
private final DatabaseCluster cluster;
private final DatabaseProperties sourceDatabaseProperties;
private final DatabaseProperties targetDatabaseProperties;
private final Map> connectionMap = new HashMap>();
private final ExecutorService executor;
/**
* @param cluster
* @param database
* @throws SQLException
*/
public SynchronizationContextImpl(DatabaseCluster cluster, D database) throws SQLException
{
this.cluster = cluster;
Balancer balancer = cluster.getBalancer();
this.sourceDatabase = balancer.next();
this.activeDatabaseSet = balancer;
this.targetDatabase = database;
this.executor = Executors.newFixedThreadPool(this.activeDatabaseSet.size(), this.cluster.getThreadFactory());
DatabaseMetaDataCache cache = cluster.getDatabaseMetaDataCache();
this.targetDatabaseProperties = cache.getDatabaseProperties(this.targetDatabase, this.getConnection(this.targetDatabase));
this.sourceDatabaseProperties = cache.getDatabaseProperties(this.sourceDatabase, this.getConnection(this.sourceDatabase));
}
/**
* @see net.sf.hajdbc.sync.SynchronizationContext#getConnection(net.sf.hajdbc.Database)
*/
@Override
public Connection getConnection(D database) throws SQLException
{
Map.Entry entry = this.connectionMap.get(database);
if (entry == null)
{
Connection connection = database.connect(database.getConnectionSource(), database.decodePassword(this.cluster.getDecoder()));
entry = new AbstractMap.SimpleImmutableEntry(connection, connection.getAutoCommit());
this.connectionMap.put(database, entry);
}
return entry.getKey();
}
/**
* @see net.sf.hajdbc.sync.SynchronizationContext#getSourceDatabase()
*/
@Override
public D getSourceDatabase()
{
return this.sourceDatabase;
}
/**
* @see net.sf.hajdbc.sync.SynchronizationContext#getTargetDatabase()
*/
@Override
public D getTargetDatabase()
{
return this.targetDatabase;
}
/**
* @see net.sf.hajdbc.sync.SynchronizationContext#getActiveDatabaseSet()
*/
@Override
public Set getActiveDatabaseSet()
{
return this.activeDatabaseSet;
}
/**
* @see net.sf.hajdbc.sync.SynchronizationContext#getSourceDatabaseProperties()
*/
@Override
public DatabaseProperties getSourceDatabaseProperties()
{
return this.sourceDatabaseProperties;
}
/**
* @see net.sf.hajdbc.sync.SynchronizationContext#getTargetDatabaseProperties()
*/
@Override
public DatabaseProperties getTargetDatabaseProperties()
{
return this.targetDatabaseProperties;
}
/**
* @see net.sf.hajdbc.sync.SynchronizationContext#getDialect()
*/
@Override
public Dialect getDialect()
{
return this.cluster.getDialect();
}
/**
* {@inheritDoc}
* @see net.sf.hajdbc.sync.SynchronizationContext#getDecoder()
*/
@Override
public Decoder getDecoder()
{
return this.cluster.getDecoder();
}
/**
* @see net.sf.hajdbc.sync.SynchronizationContext#getExecutor()
*/
@Override
public ExecutorService getExecutor()
{
return this.executor;
}
/**
* {@inheritDoc}
* @see net.sf.hajdbc.sync.SynchronizationContext#getSynchronizationSupport()
*/
@Override
public SynchronizationSupport getSynchronizationSupport()
{
return new SynchronizationSupportImpl(this);
}
/**
* @see net.sf.hajdbc.sync.SynchronizationContext#close()
*/
@Override
public void close()
{
for (Map.Entry entry: this.connectionMap.values())
{
Connection connection = entry.getKey();
try
{
connection.setAutoCommit(entry.getValue());
}
catch (SQLException e)
{
logger.log(Level.WARN, e);
}
finally
{
Resources.close(connection);
}
}
this.executor.shutdown();
}
@Override
public DatabaseCluster getDatabaseCluster() {
return cluster;
}
}