/*
* Copyright (C) 2005-2013 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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.
*
* Alfresco 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 Alfresco. If not, see .
*/
package org.alfresco.repo.tenant;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import javax.sql.DataSource;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.extensions.surf.util.ParameterCheck;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* Experimental
*
* @author janv
* @since 4.2
*/
public class TenantRoutingDataSource extends AbstractRoutingDataSource
{
Map tenantDataSources = new HashMap();
private BasicDataSource baseDataSource;
private TenantService tenantService;
public void setTenantService(TenantService tenantService)
{
this.tenantService = tenantService;
}
public void setBaseDataSource(BasicDataSource baseDataSource)
{
this.baseDataSource = baseDataSource;
}
@Override
protected Object determineCurrentLookupKey()
{
//return tenantService.getCurrentUserDomain(); // note: this is re-entrant if it checks whether tenant is enabled !
String runAsUser = AuthenticationUtil.getRunAsUser();
String tenantDomain = TenantService.DEFAULT_DOMAIN;
if (runAsUser != null)
{
String[] parts = runAsUser.split(TenantService.SEPARATOR);
if (parts.length == 2)
{
tenantDomain = parts[1];
}
}
return tenantDomain;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void afterPropertiesSet()
{
ParameterCheck.mandatory("baseDataSource", baseDataSource);
ParameterCheck.mandatory("tenantDataSources", tenantDataSources);
String dbUrl = baseDataSource.getUrl();
setTargetDataSources((Map)tenantDataSources);
try
{
// default tenant
DataSource defaultTargetDataSource = new TenantBasicDataSource(baseDataSource, dbUrl, -1);
tenantDataSources.put(TenantService.DEFAULT_DOMAIN, defaultTargetDataSource);
setDefaultTargetDataSource(defaultTargetDataSource);
}
catch (SQLException se)
{
throw new RuntimeException(se);
}
super.afterPropertiesSet();
}
public synchronized void addTenantDataSource(String tenantDomain, String dbUrl) throws SQLException
{
String currentTenantDomain = tenantService.getCurrentUserDomain();
if (! TenantService.DEFAULT_DOMAIN.equals(currentTenantDomain))
{
throw new RuntimeException("Unexpected - should not be in context of a tenant ["+currentTenantDomain+"]");
}
tenantDataSources.put(tenantDomain, new TenantBasicDataSource(baseDataSource, dbUrl, -1));
super.afterPropertiesSet(); // to update resolved data sources
}
public synchronized void removeTenantDataSource(String tenantDomain) throws SQLException
{
String currentTenantDomain = tenantService.getCurrentUserDomain();
if (! TenantService.DEFAULT_DOMAIN.equals(currentTenantDomain))
{
throw new RuntimeException("Unexpected - should not be in context of a tenant ["+currentTenantDomain+"]");
}
tenantDataSources.remove(tenantDomain);
super.afterPropertiesSet(); // to update resolved data sources
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException
{
throw new SQLFeatureNotSupportedException();
}
}