package org.dayatang.datasource4saas.dsregistry;
import org.dayatang.datasource4saas.DataSourceRegistry;
import org.dayatang.utils.Assert;
import org.dayatang.utils.Slf4JLogger;
import javax.sql.DataSource;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public abstract class MapBasedDataSourceRegistry implements DataSourceRegistry {
private static final Slf4JLogger LOGGER = Slf4JLogger.getLogger(MapBasedDataSourceRegistry.class);
private ConcurrentMap<String, DataSource> dataSources = new ConcurrentHashMap<String, DataSource>();
private ConcurrentMap<String, Date> lastAccess = new ConcurrentHashMap<String, Date>();
public MapBasedDataSourceRegistry() {
}
@Override
public DataSource getDataSourceOfTenant(String tenant) {
Assert.notBlank(tenant, "Tenant is null or blank!");
recordLastAccessTimeOfTenant(tenant, new Date());
DataSource result = dataSources.get(tenant);
if (result != null) {
return result;
}
result = findOrCreateDataSourceForTenant(tenant);
dataSources.putIfAbsent(tenant, result);
return result;
}
/**
* 为租户查找或创建对应的数据源(由子类决定是查找还是创建)。
* @param tenant
* @return
*/
protected abstract DataSource findOrCreateDataSourceForTenant(String tenant);
/**
* 记录租户对数据源的最后访问时间
* @param tenant 租户
* @param accessTime 访问时间
*/
protected void recordLastAccessTimeOfTenant(String tenant, Date accessTime) {
lastAccess.put(tenant, accessTime);
}
@Override
public synchronized void registerDataSourceForTenant(String tenant, DataSource dataSource) {
dataSources.put(tenant, dataSource);
}
@Override
public synchronized void registerDataSources(Map<String, DataSource> dataSources) {
dataSources.putAll(dataSources);
}
@Override
public synchronized void unregisterDataSourceOfTenant(String tenant) {
DataSource dataSource = dataSources.remove(tenant);
if (dataSource != null) {
dataSource = null;
LOGGER.debug("Data source of tenant '" + tenant + "' released!");
}
lastAccess.remove(tenant);
}
@Override
public synchronized void releaseAllDataSources() {
dataSources.clear();
lastAccess.clear();
LOGGER.debug("All tenant datasource have been released!");
}
@Override
public int size() {
return dataSources.size();
}
@Override
public boolean existsDataSourceOfTenant(String tenant) {
return dataSources.containsKey(tenant);
}
/**
* 获取每个租户的最后访问时间。
* @param tenant
* @return
*/
@Override
public Date getLastAccessTimeOfTenant(String tenant) {
return lastAccess.get(tenant);
}
}