package com.yc.multiData;
|
|
import com.alibaba.fastjson.JSON;
|
import com.mchange.v2.c3p0.ComboPooledDataSource;
|
import com.yc.action.panval.InvGet;
|
import com.yc.entity.AttachmentConfig;
|
import com.yc.entity.DataSourceEntity;
|
import com.yc.entity.DemoConstant;
|
import com.yc.exception.ApplicationException;
|
import com.yc.factory.FactoryBean;
|
import com.yc.open.mutual.service.MutualServiceIfc;
|
import com.yc.sdk.password.action.ChangePassword;
|
import com.yc.sdk.shopping.util.SettingKey;
|
import com.yc.sdk.weixinmp.util.MD5Util;
|
import com.yc.service.demo.DemoIfc;
|
import com.yc.service.demo.DemoImpl;
|
import com.yc.service.impl.DBHelper;
|
import com.yc.utils.SessionKey;
|
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.LogFactory;
|
import org.jetbrains.annotations.Nullable;
|
import org.springframework.beans.BeansException;
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContextAware;
|
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.EmptyResultDataAccessException;
|
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpSession;
|
import javax.sql.DataSource;
|
import java.io.PrintWriter;
|
import java.sql.Connection;
|
import java.sql.SQLException;
|
import java.sql.SQLFeatureNotSupportedException;
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.logging.Logger;
|
import java.util.stream.Collectors;
|
|
|
/**
|
* @author pengbei
|
*/
|
public class MultiDataSource implements DataSource, ApplicationContextAware {
|
|
private static final Log log = LogFactory.getLog(MultiDataSource.class);
|
private ApplicationContext applicationContext = null;
|
/**
|
* 新增配置
|
*/
|
private static Map<String, ComboPooledDataSource> comMap = new HashMap<String, ComboPooledDataSource>();
|
// private static Map<String, com.alibaba.druid.pool.DruidDataSource> comMap = new HashMap<String, com.alibaba.druid.pool.DruidDataSource>();
|
/**
|
* 新增配置是否停用 之后停用/启动在操作页控制,也更改下配置
|
*/
|
private static Map<String, DataSourceEntity> dataSourceMap = new HashMap<String, DataSourceEntity>();
|
// /** 在登录时或者demo查询时是否查询下所有配置 */
|
// private boolean infoAllTo = true;
|
/**
|
* 基础配置
|
*/
|
private static com.yc.dataAccess.ComboPooledDataSource demoDataSource = null;
|
|
public static boolean hasDemoDataSource() {
|
if (demoDataSource != null) return true;
|
if (getDataSourceMap(SpObserver.DEMOXML) != null) return true;
|
return false;
|
}
|
|
/**
|
* 按 dbid 获取数据源 DataSourceEntity 对象
|
*
|
* @param dbid
|
* @return
|
*/
|
public static DataSourceEntity getDataSourceMap(String dbId) {
|
DataSourceEntity dataSource = dataSourceMap.get(dbId);
|
DemoConstant demoConstant=new DemoConstant();
|
demoConstant.setDbId(dbId);
|
dataSource = getDataSourceFromDemoDataBase(demoConstant, dataSource);
|
return dataSource;
|
}
|
|
@Nullable
|
private static DataSourceEntity getDataSourceFromDemoDataBase(DemoConstant demoConstant, DataSourceEntity dataSource) {
|
if (dataSource == null) {
|
//由于现在数据源池不再是加载所有的数据源,当需要取不存在于当前服务器上的数据源信息,需要读取数据库重新从加载 by by danaus 2022/3/29 15:54
|
try {
|
SpObserver.setDBtoDemo();
|
DemoIfc demoIfc = (DemoIfc) FactoryBean.getBean("demo");
|
|
final List<DataSourceEntity> list = demoIfc.getDataSource(demoConstant);
|
if(list!=null&&list.size()>0) {
|
dataSource =list.get(0);
|
for(DataSourceEntity dataSourceEntity:list) {
|
dataSourceMap.put(dataSourceEntity.getDbId() + "", dataSourceEntity);// 这里只是生成数据源实体对象 by danaus 2023-05-13 11:10
|
MultiDataSource multiDataSource = (MultiDataSource) FactoryBean.getBean("multiDataSource");
|
multiDataSource.setDataSourceByMap(dataSourceEntity, demoConstant);
|
}
|
}
|
}catch (NoSuchBeanDefinitionException e1){
|
//demo数据源不存在,这种情况是在新系统才出现,所以不需要处理
|
}catch (DataAccessException e){
|
if(e instanceof EmptyResultDataAccessException){
|
String error="没有找到数据源";
|
if(StringUtils.isNotBlank(demoConstant.getDbId())){
|
error="没有找到dbid为【" + demoConstant.getDbId() + "】数据源【dbid:" + demoConstant.getDbId() + "】";
|
}else if(StringUtils.isNotBlank(demoConstant.getMiniAppId())){
|
error="没有找到小程序MiniAppId为【" + demoConstant.getMiniAppId() + "】数据源【MiniAppId:" + demoConstant.getMiniAppId() + "】";
|
}else if(StringUtils.isNotBlank(demoConstant.getCorpId())){
|
error="没有找到企业微信CorpId为【" + demoConstant.getCorpId() + "】数据源【CorpId:" + demoConstant.getCorpId() + "】";
|
}else if(StringUtils.isNotBlank(demoConstant.getMpAppId())){
|
error="没有找到公众号MpAppId为【" + demoConstant.getMpAppId() + "】数据源【MpAppId:" + demoConstant.getMpAppId() + "】";
|
}
|
throw new ApplicationException(error);
|
}else{
|
throw e;
|
}
|
}catch (Exception ex) {
|
throw ex;
|
} finally {
|
SpObserver.setDBtoInstance();
|
}
|
}
|
return dataSource;
|
}
|
|
/**
|
* 按 corpid ,mpAppid ,maAppid,dbid, SHOPPING_DBID ,hosturl 顺序取数据源
|
*
|
* @param request
|
* @return
|
* @throws Exception
|
*/
|
public static DataSourceEntity getDataSourceMap(HttpServletRequest request) throws Exception {
|
String wx = request.getParameter(SessionKey.WEIXIN_FROM);
|
String appId = request.getParameter(SessionKey.WEIXIN_CORPID);
|
|
if (appId == null || "".equals(appId)) {
|
appId = request.getParameter(SessionKey.WEIXIN_APPID);
|
}
|
DataSourceEntity dataSourceEntity = null;
|
//按企业号 corpid 查找数据源
|
if (wx != null && ("1".equals(wx) || "4".equals(wx)) && appId != null && !"".equals(appId)) {
|
dataSourceEntity = getDataSourceMapByCorpId(appId);
|
if (dataSourceEntity == null) {
|
throw new Exception("没有找到微信企业号数据源【corpid:" + appId + "】");
|
}
|
return dataSourceEntity;
|
}
|
//按公众号 appid 查找数据源
|
if (wx != null && "2".equals(wx) && appId != null && !"".equals(appId)) {
|
dataSourceEntity = getDataSourceMapByMpAppId(appId);
|
if (dataSourceEntity == null) {
|
throw new Exception("没有找到微信公众号数据源【appid:" + appId + "】");
|
}
|
return dataSourceEntity;
|
}
|
//按小程序 appid 查找数据源
|
if (wx != null && "3".equals(wx) && appId != null && !"".equals(appId)) {
|
dataSourceEntity = getDataSourceMapByMaAppId(appId);
|
if (dataSourceEntity == null) {
|
throw new Exception("没有找到微信小程序数据源【appid:" + appId + "】");
|
}
|
return dataSourceEntity;
|
}
|
HttpSession session = request.getSession();
|
String dbId = request.getParameter(SessionKey.DATA_BASE_ID);
|
|
if (dbId == null || "".equals(dbId)) {
|
dbId = (String) session.getAttribute(SessionKey.DATA_BASE_ID);
|
}
|
if (dbId == null || "".equals(dbId)) {
|
dbId = (request.getAttribute(SessionKey.DATA_BASE_ID) == null ? null :
|
(String) request.getAttribute(SessionKey.DATA_BASE_ID));
|
}
|
if (dbId == null || "".equals(dbId)) {
|
dbId = request.getParameter(SessionKey.SHOPPING_DBID);
|
}
|
if (dbId == null || "".equals(dbId)) {
|
dbId = (request.getAttribute(SessionKey.SHOPPING_DBID) == null ? null :
|
(String) request.getAttribute(SessionKey.SHOPPING_DBID));
|
}
|
if (dbId == null || "".equals(dbId)) {
|
dbId = (session.getAttribute(SessionKey.SHOPPING_DBID) == null ? null :
|
(String) session.getAttribute(SessionKey.SHOPPING_DBID));
|
}
|
//解决首页登录,在多公司中有部分数据源过期的情况,会导致里面正常的数据源也用不的问题,by danaus 2021/7/9 9:38
|
if (StringUtils.isBlank(dbId)) {
|
dbId = request.getParameter("dataName") != null ? request.getParameter("dataName") : null;
|
}
|
//按已经存在的 会话 dbid查找
|
if (dbId != null && !"".equals(dbId)) {
|
dataSourceEntity = getDataSourceMap(dbId);
|
if (dataSourceEntity == null) {
|
throw new Exception("没有找到dbid为【" + dbId + "】数据源【dbid:" + dbId + "】");
|
}
|
return dataSourceEntity;
|
}
|
|
//按 唯一主机名 CorpUrl 查找
|
String hostUrl = SettingKey.getHostUrl(request);
|
dataSourceEntity = getDataSourceMapByCorpURL(hostUrl);
|
if (dataSourceEntity != null) {
|
return dataSourceEntity;
|
}
|
|
//按主机域名查找
|
String domain = com.yc.utils.HtmlUtil.getDomain(hostUrl);
|
List<DataSourceEntity> list = MultiDataSource.getDataSourceMapsByDomain(domain);
|
if (list != null && list.size() > 0) {
|
dataSourceEntity = list.get(0);
|
}
|
|
if (dataSourceEntity == null) {
|
throw new Exception("没有找到hostUrl为【" + hostUrl + "】数据源【hostUrl:" + hostUrl + "】");
|
}
|
return dataSourceEntity;
|
}
|
|
|
/**
|
* 获取数据源ID
|
*
|
* @param request
|
* @return
|
*/
|
public static String getDatabaseId(HttpServletRequest request) {
|
HttpSession session = request.getSession(); //必须传 false 值
|
String dbId = null;
|
|
dbId = request.getParameter(SessionKey.DATA_BASE_ID);
|
|
if ((dbId == null || "".equals(dbId)) && session != null) {
|
dbId = (String) session.getAttribute(SessionKey.DATA_BASE_ID);
|
}
|
|
if (dbId == null || "".equals(dbId)) {
|
dbId = request.getParameter(SessionKey.SHOPPING_DBID);
|
}
|
|
if (dbId == null || "".equals(dbId)) {
|
// 如果是微信过来的,则要给 USERCODE 赋值
|
String corpId = request.getParameter(SessionKey.WEIXIN_CORPID);
|
|
//微信点击来源: 1 从企业号点击 , 2 从公众号点击
|
String wx = request.getParameter(SessionKey.WEIXIN_FROM);
|
if (corpId == null || "".equals(corpId)) {
|
corpId = request.getParameter(SessionKey.WEIXIN_APPID);
|
}
|
if (corpId != null || !"".equals(corpId)) {
|
DataSourceEntity dataSourceEntity = null;
|
if (wx == null || "".equals(wx)) {
|
dataSourceEntity = MultiDataSource.getDataSourceMapByMpAppId(corpId);
|
wx = "2";
|
} else {
|
dataSourceEntity = MultiDataSource.getDataSourceMapByCorpId(corpId);
|
}
|
if (dataSourceEntity != null) {
|
dbId = dataSourceEntity.getDbId() + "";
|
}
|
|
|
if (dbId == null || "".equals(dbId)) {
|
//按 域名 重新取数据源信息
|
String hostUrl = SettingKey.getHostUrl(request);
|
//String URL = (request.getRequestURL()+"").replace(request.getRequestURI(),"") + request.getContextPath();
|
String domain = com.yc.utils.HtmlUtil.getDomain(hostUrl);
|
List<DataSourceEntity> list = MultiDataSource.getDataSourceMapsByDomain(domain);
|
if (list != null && list.size() > 0) {
|
dbId = (list.get(0).getDbId() + "");
|
}
|
}
|
|
|
}
|
}
|
return dbId;
|
}
|
|
/**
|
* 获取所有数据源 DataSourceEntity 对象
|
*
|
* @return
|
*/
|
public static Map<String, DataSourceEntity> getDataSourceMaps() {
|
return dataSourceMap;
|
}
|
|
/**
|
* 获取所有数据源 DataSourceEntity 对象
|
*
|
* @return
|
*/
|
public static List<DataSourceEntity> getDataSourceMapsAll() {
|
List<DataSourceEntity> list = new ArrayList<DataSourceEntity>();
|
for (Map.Entry<String, DataSourceEntity> entry : dataSourceMap.entrySet()) {
|
list.add(entry.getValue());
|
}
|
return list;
|
}
|
|
/**
|
* 根据URL 地址中的域名 获取数据源 DataSourceEntity 对象列表 获取 isShowInLoginPage = true 的记录 ,主要用于登录主页面 login.jsp
|
*
|
* @param domain
|
* @return
|
*/
|
public static List<DataSourceEntity> getDataSourceMapsByDomainByShowInLoginPage(String domain) {
|
List<DataSourceEntity> list = getDataSourceMapsByDomain(domain);
|
if (list != null) {
|
return list.stream().filter(x -> x.isShowInLoginPage()).collect(Collectors.toList());
|
} else {
|
return list;
|
}
|
}
|
|
/**
|
* 根据URL 地址中的域名 获取数据源 DataSourceEntity 对象列表
|
*
|
* @param domain
|
* @return
|
*/
|
public static List<DataSourceEntity> getDataSourceMapsByDomain(String domain) {
|
if (domain == null) return null;
|
List<DataSourceEntity> hasDomainList = new ArrayList<DataSourceEntity>();
|
List<DataSourceEntity> hasNoDomainList = new ArrayList<DataSourceEntity>();
|
for (Map.Entry<String, DataSourceEntity> entry : dataSourceMap.entrySet()) {
|
DataSourceEntity dataSourceEntity = entry.getValue();
|
String dsDmain = null;
|
if (dataSourceEntity.getDomain() != null) {
|
dsDmain = dataSourceEntity.getDomain().toLowerCase().trim();
|
}
|
|
if (dsDmain != null && !"".equals(dsDmain)
|
&& (dsDmain.startsWith(domain.toLowerCase().trim() + ";")
|
|| dsDmain.endsWith(";" + domain.toLowerCase().trim())
|
|| dsDmain.equals(domain.toLowerCase().trim())
|
|| dsDmain.contains(";" + domain.toLowerCase().trim() + ";"))) {
|
hasDomainList.add(dataSourceEntity);
|
} else {
|
//hasNoDomainList.add(dataSourceEntity); //避免程序漏洞,把它注释掉,modified by Johns Wang, 2017-06-20
|
}
|
}
|
|
if (hasDomainList.size() > 0) {
|
return hasDomainList;
|
} else {
|
//---都没有符合,则重新加载数据库生成数据源 by danaus 2023-06-28 15:07
|
DataSourceEntity dataSourceEntity=null;
|
DemoConstant constant=new DemoConstant();
|
constant.setDomain(domain);
|
dataSourceEntity=getDataSourceFromDemoDataBase(constant,dataSourceEntity);
|
hasNoDomainList.add(dataSourceEntity);
|
return hasNoDomainList;
|
}
|
}
|
|
/**
|
* 把不同数据库主机IP和端口号的 数据源取出来,用于计算数据库使用空间
|
*
|
* @return
|
*/
|
public static Map<String, DataSourceEntity> getDataSourceMapsByHostAndPort() {
|
Map<String, DataSourceEntity> map = new HashMap<String, DataSourceEntity>();
|
for (Map.Entry<String, DataSourceEntity> entry : dataSourceMap.entrySet()) {
|
DataSourceEntity dataSourceEntity = entry.getValue();
|
if (dataSourceEntity.getHost() != null && !"".equals(dataSourceEntity.getHost())
|
&& dataSourceEntity.getPort() != null && !"".equals(dataSourceEntity.getPort())
|
&& dataSourceEntity.getDb() != null && !"".equals(dataSourceEntity.getDb())) {
|
String hostAndPort = dataSourceEntity.getHost() + "_" + dataSourceEntity.getPort();
|
if (!map.containsKey(hostAndPort)) {
|
map.put(hostAndPort, dataSourceEntity);
|
}
|
}
|
|
}
|
|
return map;
|
}
|
|
|
/**
|
* 把不同数据库主机IP和端口号的 数据源取出来,用于计算数据库使用空间
|
*
|
* @return
|
*/
|
public static List<DataSourceEntity> getDataSourceListByHostAndPort(String host, String port) {
|
List<DataSourceEntity> list = new ArrayList<DataSourceEntity>();
|
for (Map.Entry<String, DataSourceEntity> entry : dataSourceMap.entrySet()) {
|
DataSourceEntity dataSourceEntity = entry.getValue();
|
if (dataSourceEntity.getHost() != null && dataSourceEntity.getPort() != null && dataSourceEntity.getDb() != null
|
&& !"".equals(dataSourceEntity.getHost())
|
&& !"".equals(dataSourceEntity.getPort())
|
&& !"".equals(dataSourceEntity.getDb())
|
&& dataSourceEntity.getHost().equals(host)) {
|
//String hostAndPort = dataSourceEntity.getHost() + "_" + dataSourceEntity.getPort();
|
list.add(dataSourceEntity);
|
}
|
|
}
|
|
return list;
|
}
|
|
/**
|
* 根据客户 cltid 获取数据源 DataSourceEntity 对象
|
*
|
* @param cltId
|
* @return
|
*/
|
public static DataSourceEntity getDataSourceMapByCltId(int cltId) {
|
if (cltId == 0) return null;
|
|
for (Map.Entry<String, DataSourceEntity> entry : dataSourceMap.entrySet()) {
|
DataSourceEntity dataSourceEntity = entry.getValue();
|
if (dataSourceEntity.getCltId() != 0 && dataSourceEntity.getCltId() == cltId) {
|
return dataSourceEntity;
|
}
|
}
|
return null;
|
}
|
|
/**
|
* 根据微信企业号 corpId 获取数据源 DataSourceEntity 对象
|
*
|
* @param corpId
|
* @return
|
*/
|
public static DataSourceEntity getDataSourceMapByCorpId(String corpId) {
|
if (corpId == null) return null;
|
DataSourceEntity dataSourceEntity=null;
|
for (Map.Entry<String, DataSourceEntity> entry : dataSourceMap.entrySet()) {
|
dataSourceEntity = entry.getValue();
|
if (dataSourceEntity.getCorpId() != null && dataSourceEntity.getCorpId().toLowerCase().equals(corpId.toLowerCase())) {
|
return dataSourceEntity;
|
}
|
}
|
DemoConstant demoConstant=new DemoConstant();
|
demoConstant.setCorpId(corpId);
|
return getDataSourceFromDemoDataBase(demoConstant, dataSourceEntity);
|
}
|
|
/**
|
* 根据accesske获得数据源
|
*
|
* @param accesskey
|
* @return
|
*/
|
public static DataSourceEntity getDataSourceByAccesskey(String accesskey) {
|
if (accesskey == null) return null;
|
|
for (Map.Entry<String, DataSourceEntity> entry : dataSourceMap.entrySet()) {
|
DataSourceEntity dataSourceEntity = entry.getValue();
|
if (dataSourceEntity.getSystemAccessKey() != null && MD5Util.string2MD5(dataSourceEntity.getSystemAccessKey()).equals(accesskey)) {
|
return dataSourceEntity;
|
}
|
}
|
return null;
|
}
|
|
/**
|
* 获取微信企业号所有数据源 DataSourceEntity 对象
|
*
|
* @return
|
*/
|
public static List<DataSourceEntity> getDataSourceMapsByCorpId() {
|
List<DataSourceEntity> list = new ArrayList<DataSourceEntity>();
|
|
for (Map.Entry<String, DataSourceEntity> entry : dataSourceMap.entrySet()) {
|
DataSourceEntity dataSourceEntity = entry.getValue();
|
if (dataSourceEntity.getCorpId() != null && !dataSourceEntity.getCorpId().equals("") && dataSourceEntity.getActived()) {
|
list.add(dataSourceEntity);
|
}
|
}
|
return list;
|
}
|
|
/**
|
* 根据微信企公众号 MpAppId 获取数据源 DataSourceEntity 对象
|
*
|
* @param mpAppId
|
* @return
|
*/
|
public static DataSourceEntity getDataSourceMapByMpAppId(String mpAppId) {
|
if (mpAppId == null) return null;
|
DataSourceEntity dataSourceEntity=null;
|
for (Map.Entry<String, DataSourceEntity> entry : dataSourceMap.entrySet()) {
|
dataSourceEntity = entry.getValue();
|
if (dataSourceEntity.getMpAppId() != null && dataSourceEntity.getMpAppId().toLowerCase().equals(mpAppId.toLowerCase())) {
|
return dataSourceEntity;
|
}
|
}
|
DemoConstant demoConstant=new DemoConstant();
|
demoConstant.setMpAppId(mpAppId);
|
return getDataSourceFromDemoDataBase(demoConstant, dataSourceEntity);
|
}
|
|
/**
|
* 根据微信小程序号 MaAppId 获取数据源 DataSourceEntity 对象
|
*
|
* @param maAppId
|
* @return
|
*/
|
public static DataSourceEntity getDataSourceMapByMaAppId(String maAppId) {
|
if (maAppId == null) return null;
|
DataSourceEntity dataSourceEntity=null;
|
List<Map.Entry<String, DataSourceEntity>> collect = dataSourceMap.entrySet().stream().filter(entry -> {
|
DataSourceEntity dataSource = entry.getValue();
|
if (dataSource.getMiniAppId() != null && dataSource.getMiniAppId().toLowerCase().equals(maAppId.toLowerCase())) {
|
return true;
|
}
|
return false;
|
}).collect(Collectors.toList());
|
if(collect!=null&&collect.size()>0) {
|
dataSourceEntity = collect.get(0).getValue();
|
}
|
DemoConstant demoConstant=new DemoConstant();
|
demoConstant.setMiniAppId(maAppId);
|
return getDataSourceFromDemoDataBase(demoConstant, dataSourceEntity);
|
}
|
|
/**
|
* 按小程序原始ID找数据源
|
*
|
* @param miniAppOrgId
|
* @return
|
*/
|
public static DataSourceEntity getDataSourceMapByMaOrgId(String miniAppOrgId) {
|
if (miniAppOrgId == null) return null;
|
|
for (Map.Entry<String, DataSourceEntity> entry : dataSourceMap.entrySet()) {
|
DataSourceEntity dataSourceEntity = entry.getValue();
|
if (dataSourceEntity.getMiniAppOrgId() != null && dataSourceEntity.getMiniAppOrgId().toLowerCase().equals(miniAppOrgId.toLowerCase())) {
|
return dataSourceEntity;
|
}
|
}
|
return null;
|
}
|
|
/**
|
* 获取微信公众号所有数据源 DataSourceEntity 对象
|
*
|
* @return
|
*/
|
public static List<DataSourceEntity> getDataSourceMapsByMpAppId() {
|
List<DataSourceEntity> list = new ArrayList<DataSourceEntity>();
|
|
for (Map.Entry<String, DataSourceEntity> entry : dataSourceMap.entrySet()) {
|
DataSourceEntity dataSourceEntity = entry.getValue();
|
if (dataSourceEntity.getMpAppId() != null && !dataSourceEntity.getMpAppId().equals("")) {
|
list.add(dataSourceEntity);
|
}
|
}
|
return list;
|
}
|
|
/**
|
* 获取微信小程序所有数据源 DataSourceEntity 对象
|
*
|
* @return
|
*/
|
public static List<DataSourceEntity> getDataSourceMapsByMaAppId() {
|
List<DataSourceEntity> list = new ArrayList<DataSourceEntity>();
|
|
for (Map.Entry<String, DataSourceEntity> entry : dataSourceMap.entrySet()) {
|
DataSourceEntity dataSourceEntity = entry.getValue();
|
if (dataSourceEntity.getMiniAppId() != null && !dataSourceEntity.getMiniAppId().equals("")) {
|
list.add(dataSourceEntity);
|
}
|
}
|
return list;
|
}
|
|
/**
|
* 按唯一主机名访问,适用于 导购网店 shopping 模块,需要主机名来访问数据源, 获取数据源 DataSourceEntity 对象
|
*
|
* @param cltId
|
* @return
|
*/
|
public static DataSourceEntity getDataSourceMapByCorpURL(String corpURL) {
|
if (corpURL == null || "".equals(corpURL) || "null".equals(corpURL)) {
|
return null;
|
}
|
corpURL = corpURL.replace("https://", "");
|
corpURL = corpURL.replace("http://", "");
|
// 去掉端口号,Added by Johns Wang, 2016-07-09
|
int i = corpURL.indexOf(":");
|
if (i > 0) {
|
corpURL = corpURL.substring(0, i);
|
}
|
|
|
for (Map.Entry<String, DataSourceEntity> entry : dataSourceMap.entrySet()) {
|
DataSourceEntity dataSourceEntity = entry.getValue();
|
String dsCorpUrl = dataSourceEntity.getCorpURL();
|
if (dsCorpUrl != null) {
|
dsCorpUrl = dsCorpUrl.replace("https://", "");
|
dsCorpUrl = dsCorpUrl.replace("http://", "");
|
|
// 去掉端口号,Added by Johns Wang, 2020-05-23
|
int k = dsCorpUrl.indexOf(":");
|
if (k > 0) {
|
dsCorpUrl = dsCorpUrl.substring(0, k);
|
}
|
|
|
if (dsCorpUrl.toLowerCase().equals(corpURL.toLowerCase())) {
|
return dataSourceEntity;
|
}
|
}
|
}
|
//---都没有符合,则重新加载数据库生成数据源 by danaus 2023-06-28 15:08
|
DataSourceEntity dataSourceEntity=null;
|
DemoConstant constant=new DemoConstant();
|
constant.setHostUrl(corpURL);
|
dataSourceEntity=getDataSourceFromDemoDataBase(constant,dataSourceEntity);
|
return dataSourceEntity;
|
}
|
|
|
/**
|
* 按高德地图 WebApi Key 获取数据源 DataSourceEntity 对象
|
*
|
* @param cltId
|
* @return
|
*/
|
public static DataSourceEntity getDataSourceMapByGeoWebApiKey(String geoWebApiKey) {
|
if (geoWebApiKey == null) return null;
|
|
for (Map.Entry<String, DataSourceEntity> entry : dataSourceMap.entrySet()) {
|
DataSourceEntity dataSourceEntity = entry.getValue();
|
if (dataSourceEntity.getGeoWebApiKey() != null && dataSourceEntity.getGeoWebApiKey().toLowerCase().equals(geoWebApiKey.toLowerCase())) {
|
return dataSourceEntity;
|
}
|
}
|
return null;
|
}
|
|
|
/*
|
* (non-Javadoc)
|
*
|
* @see javax.sql.DataSource#getConnection()
|
*/
|
public Connection getConnection() throws SQLException {
|
try {
|
DataSource ds = getDataSource();
|
if (ds == null) {
|
throw new SQLException("连接数据库" + SpObserver.getCurrentInstance() + "出错,原因:数据源为 null 值,解决办法:检查数据源的IP、用户名、密码是否正确");
|
}
|
|
return getDataSource().getConnection();
|
} catch (SQLException e) {
|
throw new SQLException("连接数据库" + SpObserver.getCurrentInstance() + "出错,原因:" + e.getMessage());
|
} catch (Exception e) {
|
throw e;
|
}
|
}
|
|
/*
|
* (non-Javadoc)
|
*
|
* @see javax.sql.DataSource#getConnection(java.lang.String, java.lang.String)
|
*/
|
public Connection getConnection(String arg0, String arg1) throws SQLException {
|
return getDataSource().getConnection(arg0, arg1);
|
}
|
|
/*
|
* (non-Javadoc)
|
*
|
* @see javax.sql.DataSource#getLogWriter()
|
*/
|
public PrintWriter getLogWriter() throws SQLException {
|
return getDataSource().getLogWriter();
|
}
|
|
/*
|
* (non-Javadoc)
|
*
|
* @see javax.sql.DataSource#getLoginTimeout()
|
*/
|
public int getLoginTimeout() throws SQLException {
|
return getDataSource().getLoginTimeout();
|
}
|
|
/*
|
* (non-Javadoc)
|
*
|
* @see javax.sql.DataSource#setLogWriter(java.io.PrintWriter)
|
*/
|
public void setLogWriter(PrintWriter arg0) throws SQLException {
|
getDataSource().setLogWriter(arg0);
|
}
|
|
/*
|
* (non-Javadoc)
|
*
|
* @see javax.sql.DataSource#setLoginTimeout(int)
|
*/
|
public void setLoginTimeout(int arg0) throws SQLException {
|
getDataSource().setLoginTimeout(arg0);
|
}
|
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
this.applicationContext = applicationContext;
|
}
|
|
public DataSource getDataSource(String dataSourceName) {// 数据id 例如:_12
|
String dataSourceNameKey = dataSourceName.substring(1);
|
ComboPooledDataSource ds = comMap.get(dataSourceNameKey);
|
if (ds != null) {
|
return (DataSource) ds;
|
}
|
|
if (dataSourceName.equals(SpObserver.DEMOXML)) {
|
if (demoDataSource == null) {
|
DataSourceEntity dataSourceEntity = dataSourceMap.get(SpObserver.DEMOXML);
|
if (dataSourceEntity != null) {
|
try {
|
demoDataSource = new com.yc.dataAccess.ComboPooledDataSource();
|
demoDataSource.setDriverClass(DBHelper.encryptHelper.encrypt(InvGet.driverClass));
|
demoDataSource.setJdbcUrl(DBHelper.encryptHelper.encrypt("jdbc:sqlserver://" + dataSourceEntity.getHost() + ":" + dataSourceEntity.getPort() + ";encrypt=true;trustServerCertificate=true;databaseName=" + dataSourceEntity.getDb()));
|
demoDataSource.setUser(DBHelper.encryptHelper.encrypt(dataSourceEntity.getUserid()));
|
demoDataSource.setPassword(dataSourceEntity.getPassword());
|
demoDataSource.setInitialPoolSize(InvGet.initialPoolSize);
|
demoDataSource.setMinPoolSize(InvGet.minPoolSize);
|
demoDataSource.setMaxPoolSize(InvGet.maxPoolSize);
|
demoDataSource.setAcquireIncrement(InvGet.acquireIncrement);
|
demoDataSource.setMaxIdleTime(InvGet.maxIdleTime);
|
demoDataSource.setIdleConnectionTestPeriod(InvGet.idleConnectionTestPeriod);
|
demoDataSource.setMaxStatements(InvGet.maxStatements);
|
demoDataSource.resetPoolManager();
|
|
} catch (Exception e) {
|
// TODO Auto-generated catch block
|
e.printStackTrace();
|
return null;
|
}
|
} else {
|
demoDataSource = (com.yc.dataAccess.ComboPooledDataSource) this.applicationContext.getBean(SpObserver.DEMOXML);
|
}
|
}
|
return (DataSource) demoDataSource;
|
}
|
return null;
|
}
|
|
/**
|
* 按 dbid 刷新数据源 , 如果 dbid 参数为空值,则刷新所有数据源
|
*
|
* @param dbId
|
* @return
|
* @throws SQLException
|
*/
|
public List<DataSourceEntity> refreshDataSource(String dbId) throws SQLException {
|
return refreshDataSource(dbId, null);
|
}
|
|
/**
|
* 按 dbid 和 domain 刷新数据源 ,如果2个参数全部为空值,则刷新所有数据源
|
*
|
* @param dbId
|
* @param domain
|
* @throws SQLException
|
*/
|
public List<DataSourceEntity> refreshDataSource(String dbId, String domain) throws SQLException {
|
try {
|
if (demoDataSource == null) {// 判断是否加载,未加载就先赋值
|
demoDataSource = (com.yc.dataAccess.ComboPooledDataSource) this.applicationContext.getBean(SpObserver.DEMOXML);
|
}
|
//removeDataSource(dbId) ; //先删除数据源
|
//System.out.println(this.getClass()+" getInfoAll() 准备刷新数据源");
|
DemoIfc demoIfc = (DemoIfc) FactoryBean.getBean("demo");
|
|
//List<Map<String, Object>> infoList = null;
|
List<DataSourceEntity> list = null;
|
try {
|
SpObserver.setDBtoDemo();
|
list = demoIfc.getDataSource(DemoConstant.getInstance().setDbId(dbId).setActived(null).setDomain(domain));
|
} finally {
|
SpObserver.setDBtoInstance();
|
}
|
|
//System.out.println(this.getClass()+" getInfoAll() 已经获取了 infoList is null : " + (infoList == null?"false":"true") + " infoList.size : " + infoList.size() );
|
if (list != null) {
|
DemoConstant demoConstant=new DemoConstant();
|
for (DataSourceEntity dataSourceEntity : list) {
|
demoConstant.setDbId(dataSourceEntity.getDbId()+"");
|
setDataSourceByMap(dataSourceEntity,demoConstant);
|
|
}
|
}
|
//test
|
// for (Map.Entry<String, DataSourceEntity> entry : dataSourceMap.entrySet()) {
|
// System.out.println(this.getClass()+" 数据源:" + entry.getValue().getSystemID() + " dbid:" + entry.getValue().getDbId());
|
// }
|
return list;
|
} catch (Exception e) {
|
e.printStackTrace();
|
throw e;
|
}
|
}
|
|
/**
|
* 删除一个数据源
|
*
|
* @param dbid
|
* @return
|
*/
|
public boolean removeDataSource(String dbid) {
|
try {
|
if (dbid != null && !"".equals(dbid)) {
|
ComboPooledDataSource cpds = comMap.get(dbid);
|
if (cpds != null) {
|
cpds.close(); //关闭数据源,使它不再使用
|
cpds.resetPoolManager();
|
comMap.remove(dbid); //先删除
|
dataSourceMap.remove(dbid);
|
return true;
|
}
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
throw e;
|
}
|
return false;
|
}
|
|
/**
|
* 刷新当前数据源的过期时间
|
*/
|
public void refreshExpiredDataSource() {
|
try {
|
SpObserver.setDBtoDemo();
|
DemoConstant demoConstant = new DemoConstant();
|
DemoIfc demoIfc = (DemoIfc) FactoryBean.getBean("demo");
|
List<DataSourceEntity> list = demoIfc.getDataSource(demoConstant);
|
for (int i = 0; list != null && i < list.size(); i++) {
|
DataSourceEntity dataSourceEntity = dataSourceMap.get(list.get(i).getDbId() + "");
|
if (dataSourceEntity != null) {
|
dataSourceEntity.setExpiredDate(list.get(i).getExpiredDate());
|
dataSourceEntity.setExpiredDays(list.get(i).getExpiredDays());
|
dataSourceEntity.setActived(list.get(i).getActived());
|
}
|
|
}
|
} catch (DataAccessException e) {
|
e.printStackTrace();
|
return;
|
} catch (Exception e) {
|
e.printStackTrace();
|
return;
|
} finally {
|
SpObserver.setDBtoInstance();
|
}
|
}
|
|
/**
|
* 根据attachment.config.properties的相关设置判断是否需要加载当前数据源
|
*
|
* @param dataSourceEntity
|
* @return
|
*/
|
private boolean processDataSource(DataSourceEntity dataSourceEntity) {
|
//attachment.config.properties中localHostBindIPs有配置,则只能加载匹配配置的IP的数据源
|
//只在设置了定时任务的服务器上运行
|
String isCreateAllPool = AttachmentConfig.get("isCreateAllPool");
|
//定本机IP匹配数据源绑定的IP,未配置就匹配所有
|
String localHostBindIPs = AttachmentConfig.get("localHostBindIPs");
|
//创建最少的连接数和超时时间,用于开发环境(9010)及定时任务服务,生产环境(9001)不配置
|
String isMiniConnectionSetting = AttachmentConfig.get("isMiniConnectionSetting");
|
boolean isMiniConection = false;
|
|
//----定时作业服务器,图片服务器
|
if (StringUtils.isNotBlank(isCreateAllPool) && "1".equals(isCreateAllPool)) {
|
//表示是定时作业的服务器,需要加载所有的数据源,localHostBindIPs不需要处理
|
if (StringUtils.isNotBlank(isMiniConnectionSetting) && "1".equals(isMiniConnectionSetting)) {
|
//表示需要创建最小的连接数,也就是jdbc.properties配置文件定义
|
isMiniConection = true;
|
|
}
|
}
|
//----9010
|
else if (StringUtils.isNotBlank(isMiniConnectionSetting) && "1".equals(isMiniConnectionSetting)) {
|
//表示需要创建最小的连接数,也就是jdbc.properties配置文件定义
|
// 且执行localHostBindIPs的过滤
|
if (StringUtils.isNotBlank(localHostBindIPs) && StringUtils.isNotBlank(dataSourceEntity.getDomainIpList())) {
|
//处理一个数据源对应多个域名情况,yingchen.onbus.cn;mp.onbus.cn
|
String domainIPlist=dataSourceEntity.getDomainIpList();
|
if(StringUtils.isNotBlank(dataSourceEntity.getDomainStaticIpList())){
|
domainIPlist+=";"+dataSourceEntity.getDomainStaticIpList();
|
}
|
String[] ipList=domainIPlist.split(";");
|
for(String ip:ipList) {
|
if ((";" + localHostBindIPs + ";").contains(";" + ip + ";")) {
|
//判断当前数据源所绑定的IP是否属于定义的IP名单里面
|
isMiniConection = true;
|
break;
|
}
|
}
|
if(!isMiniConection) {
|
return false;//不属于当前服务器的不需要生成数据源
|
}
|
} else {
|
//没设置则不需要过滤
|
isMiniConection = true;
|
}
|
}
|
//---9001
|
else if (StringUtils.isNotBlank(localHostBindIPs) && StringUtils.isNotBlank(dataSourceEntity.getDomainIpList())) {
|
String domainIPlist=dataSourceEntity.getDomainIpList();
|
if(StringUtils.isNotBlank(dataSourceEntity.getDomainStaticIpList())){
|
domainIPlist+=";"+dataSourceEntity.getDomainStaticIpList();
|
}
|
String[] ipList=domainIPlist.split(";");
|
for(String ip:ipList) {
|
if ((";" + localHostBindIPs + ";").contains(";" + ip + ";")) {
|
//默认取数据源定义的配置,如果没配置再取配置文件的值
|
setDataSourceInfo(dataSourceEntity);//取数据源配置
|
return true;
|
}
|
}
|
}else{
|
//什么也不配置,加载所有
|
isMiniConection=true;
|
}
|
if (isMiniConection) {
|
//默认配置
|
dataSourceEntity.setDataSourceMaxIdleTime(InvGet.maxIdleTime);
|
dataSourceEntity.setDataSourceMinPoolSize(InvGet.minPoolSize);
|
dataSourceEntity.setDataSourceMaxStatements(InvGet.maxStatements);
|
dataSourceEntity.setDataSourceMaxPoolSize(InvGet.maxPoolSize);
|
dataSourceEntity.setDataSourceAcquireIncrement(InvGet.acquireIncrement);
|
dataSourceEntity.setDataSourceInitialPoolSize(InvGet.initialPoolSize);
|
dataSourceEntity.setDataSourceIdleConnectionTestPeriod(InvGet.idleConnectionTestPeriod);
|
return true;
|
}
|
return false;
|
}
|
|
/**
|
* 根据map获得一个datasource
|
*
|
*/
|
public void setDataSourceByMap(DataSourceEntity dataSourceEntity,DemoConstant demoConstant) {
|
|
try {
|
if(StringUtils.isNotBlank(demoConstant.getDbId())) {
|
if (!processDataSource(dataSourceEntity)) {return;}//不是当前服务器的数据源,不进行加载
|
}else {
|
//小程序,公众号需要获取数据连接池,不能调用processDataSource过滤掉
|
setDataSourceInfo(dataSourceEntity);
|
}
|
boolean found = true;
|
ComboPooledDataSource cpds = comMap.get(dataSourceEntity.getDbId() + "");
|
if (cpds == null) {
|
found = false;
|
cpds = new ComboPooledDataSource();
|
}
|
|
cpds.setDriverClass(InvGet.driverClass);
|
cpds.setJdbcUrl("jdbc:sqlserver://" + dataSourceEntity.getHost() + ":" + dataSourceEntity.getPort() + ";encrypt=true;trustServerCertificate=true;databaseName=" + dataSourceEntity.getDb() + "");
|
|
//加密 2次
|
String plainTextPassword = ChangePassword.getDecryptPassword(dataSourceEntity.getPassword());
|
|
cpds.setUser(dataSourceEntity.getUserid());
|
cpds.setPassword(plainTextPassword);
|
//默认加载
|
cpds.setInitialPoolSize(dataSourceEntity.getDataSourceInitialPoolSize()); // demoDataSource.getInitialPoolSize());
|
cpds.setMinPoolSize(dataSourceEntity.getDataSourceMinPoolSize());// demoDataSource.getMinPoolSize());
|
cpds.setMaxPoolSize(dataSourceEntity.getDataSourceMaxPoolSize()); // demoDataSource.getMaxPoolSize());
|
cpds.setAcquireIncrement(dataSourceEntity.getDataSourceAcquireIncrement()); // demoDataSource.getAcquireIncrement());
|
cpds.setMaxIdleTime(dataSourceEntity.getDataSourceMaxIdleTime()); // demoDataSource.getMaxIdleTime());
|
cpds.setIdleConnectionTestPeriod(dataSourceEntity.getDataSourceIdleConnectionTestPeriod()); // demoDataSource.getIdleConnectionTestPeriod());
|
cpds.setMaxStatements(dataSourceEntity.getDataSourceMaxStatements()); // demoDataSource.getMaxStatements());
|
|
cpds.resetPoolManager();
|
// TODO 连接需要增加信息 在此后面添加 暂时不做处理
|
String dbId = dataSourceEntity.getDemoDataSource() != null && !"".equals(dataSourceEntity.getDemoDataSource()) ? dataSourceEntity.getDemoDataSource() : dataSourceEntity.getDbId() + "";
|
if (!found) {
|
//comMap.remove(dataSourceEntity.getDbId()+"") ; //先删除 , 不能删除,因为这是数据源连接,如果删除了就变成死链接,数据源会提示: APP Dead Lock!!!
|
comMap.put(dbId, cpds);
|
}
|
dataSourceMap.remove(dbId); //这个只是个集合,可以先删除然后再新增
|
dataSourceMap.put(dbId, dataSourceEntity);
|
} catch (Exception e) {
|
log.error(e.getMessage());
|
e.printStackTrace();
|
}
|
}
|
public DataSourceEntity setDataSourceInfo(DataSourceEntity dataSourceEntity) {
|
|
try {
|
dataSourceEntity.setDataSourceMaxIdleTime(
|
dataSourceEntity.getDataSourceMaxIdleTime() != null ? dataSourceEntity.getDataSourceMaxIdleTime() : InvGet.maxIdleTime);
|
dataSourceEntity.setDataSourceMinPoolSize(
|
dataSourceEntity.getDataSourceMinPoolSize() != null ? dataSourceEntity.getDataSourceMinPoolSize() : InvGet.minPoolSize);
|
dataSourceEntity.setDataSourceMaxStatements(
|
dataSourceEntity.getDataSourceMaxStatements() != null ? dataSourceEntity.getDataSourceMaxStatements() : InvGet.maxStatements);
|
dataSourceEntity.setDataSourceMaxPoolSize(
|
dataSourceEntity.getDataSourceMaxPoolSize() != null ? dataSourceEntity.getDataSourceMaxPoolSize() : InvGet.maxPoolSize);
|
dataSourceEntity.setDataSourceAcquireIncrement(
|
dataSourceEntity.getDataSourceAcquireIncrement() != null ? dataSourceEntity.getDataSourceAcquireIncrement() : InvGet.acquireIncrement);
|
dataSourceEntity.setDataSourceInitialPoolSize(
|
dataSourceEntity.getDataSourceInitialPoolSize() != null ? dataSourceEntity.getDataSourceInitialPoolSize() : InvGet.initialPoolSize);
|
dataSourceEntity.setDataSourceIdleConnectionTestPeriod(
|
dataSourceEntity.getDataSourceIdleConnectionTestPeriod() != null ? dataSourceEntity.getDataSourceIdleConnectionTestPeriod() : InvGet.idleConnectionTestPeriod);
|
|
} catch (Exception e) {
|
log.error(e.getMessage());
|
e.printStackTrace();
|
return null;
|
}
|
return dataSourceEntity;
|
}
|
|
public static Map<String, ComboPooledDataSource> getcomm() {
|
return comMap;
|
}
|
|
|
public DataSource getDataSource() {
|
return getDataSource(SpObserver.getCurrentInstance());
|
}
|
|
@Override
|
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
return false;
|
}
|
|
@Override
|
public <T> T unwrap(Class<T> iface) throws SQLException {
|
return null;
|
}
|
|
@Override
|
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
|
return null;
|
}
|
}
|