package org.dayatang.datasource4saas.dsregistry; import org.apache.commons.lang3.StringUtils; import org.dayatang.utils.Slf4JLogger; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; /** * 数据源注册表实现,将租户数据源映射到JNDI * * @author yyang (<a href="mailto:gdyangyu@gmail.com">gdyangyu@gmail.com</a>) * */ public class JndiMappingDataSourceRegistry extends MapBasedDataSourceRegistry { private static final Slf4JLogger LOGGER = Slf4JLogger.getLogger(JndiMappingDataSourceRegistry.class); private Context context; private String jndiPrefix; private String jndiSuffix; private Context getContext() { if (context == null) { try { context = new InitialContext(); } catch (NamingException e) { throw new DataSourceRegistryException("Cannot initiate JNDI environment!", e); } } return context; } public void setContext(Context context) { this.context = context; } public void setJndiPrefix(String jndiPrefix) { this.jndiPrefix = jndiPrefix; } public void setJndiSuffix(String jndiSuffix) { this.jndiSuffix = jndiSuffix; } /** * 根据租户名称,拼装上相应的前缀和后缀作为数据源JNDI名称,从应用服务器上获取已部署的数据源。 */ @Override public DataSource findOrCreateDataSourceForTenant(String tenant) { DataSource result = null; String dataSourceJndi = StringUtils.defaultString(jndiPrefix) + tenant + StringUtils.defaultString(jndiSuffix); try { result = (DataSource) getContext().lookup(dataSourceJndi); } catch (NamingException e) { String message = "Lookup jndi: " + dataSourceJndi + " failed!"; LOGGER.error(message, e); throw new DataSourceRegistryException(message, e); } if (result == null) { throw new DataSourceRegistryException("There's no data source prepared for tenant " + tenant); } LOGGER.info("Found JNDI " + dataSourceJndi + " for tenant {}", tenant); return result; } }