diff --git a/dal-client/pom.xml b/dal-client/pom.xml index b3be6921f..979793be6 100644 --- a/dal-client/pom.xml +++ b/dal-client/pom.xml @@ -6,7 +6,7 @@ com.ctrip.platform dal-client-parent - 2.0.19 + 2.1.6 dal-client jar diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/DalClientFactory.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/DalClientFactory.java index fb9845dd2..052f7ffbc 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/DalClientFactory.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/DalClientFactory.java @@ -88,8 +88,7 @@ public void execute() throws Exception { config.validate(); LogEntry.init(); - DalRequestExecutor.init(config.getFactory().getProperty(DalRequestExecutor.MAX_POOL_SIZE), - config.getFactory().getProperty(DalRequestExecutor.KEEP_ALIVE_TIME)); + DalRequestExecutor.init(config); DalStatusManager.initialize(config); diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/client/ConnectionAction.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/client/ConnectionAction.java index 0b03e3afa..500ead184 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/client/ConnectionAction.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/client/ConnectionAction.java @@ -6,6 +6,7 @@ import java.util.Set; import com.ctrip.framework.dal.cluster.client.Cluster; +import com.ctrip.framework.dal.cluster.client.config.LocalizationConfig; import com.ctrip.platform.dal.common.enums.ShardingCategory; import com.ctrip.platform.dal.common.enums.TableParseSwitch; import com.ctrip.platform.dal.dao.DalClientFactory; @@ -19,12 +20,18 @@ import com.ctrip.platform.dal.dao.configure.DatabaseSet; import com.ctrip.platform.dal.dao.configure.dalproperties.DalPropertiesLocator; import com.ctrip.platform.dal.dao.configure.dalproperties.DalPropertiesManager; +import com.ctrip.platform.dal.dao.datasource.LocalizationValidatable; +import com.ctrip.platform.dal.dao.datasource.ValidationResult; +import com.ctrip.platform.dal.dao.helper.DalElementFactory; +import com.ctrip.platform.dal.dao.helper.EnvUtils; import com.ctrip.platform.dal.dao.task.DalContextConfigure; import com.ctrip.platform.dal.dao.task.DalTaskContext; import com.ctrip.platform.dal.exceptions.DalException; import com.ctrip.platform.dal.exceptions.TransactionSystemException; public abstract class ConnectionAction { + private static final EnvUtils envUtils = DalElementFactory.DEFAULT.getEnvUtils(); + public DalEventEnum operation; public String sql; public String callString; @@ -155,6 +162,28 @@ public void populateDbMeta() { entry.setMaster(connHolder.isMaster()); entry.setShardId(connHolder.getShardId()); } + + recordLocalizationValidation(); + } + + private void recordLocalizationValidation() { + Statement stmt = statement != null ? statement : preparedStatement; + stmt = stmt != null ? stmt : callableStatement; + try { + if (stmt.isWrapperFor(LocalizationValidatable.class)) { + LocalizationValidatable validatable = stmt.unwrap(LocalizationValidatable.class); + LocalizationValidatable.ValidationStatus validationStatus = validatable.getLastValidationStatus(); + ValidationResult validationResult = validatable.getLastValidationResult(); + if ((validationStatus == LocalizationValidatable.ValidationStatus.OK || + validationStatus == LocalizationValidatable.ValidationStatus.FAILED) && + validationResult != null) { + entry.setUcsValidation(validationResult.getUcsValidationMessage()); + entry.setDalValidation(validationResult.getDalValidationMessage()); + } + } + } catch (Throwable t) { + // ignore + } } public void initLogEntry(String logicDbName, DalHints hints) { @@ -163,10 +192,14 @@ public void initLogEntry(String logicDbName, DalHints hints) { if (databaseSet instanceof ClusterDatabaseSet) { Cluster cluster = ((ClusterDatabaseSet) databaseSet).getCluster(); entry.setClusterName(cluster.getClusterName().toLowerCase()); + LocalizationConfig localizationConfig = cluster.getLocalizationConfig(); + if (localizationConfig != null) + entry.setDbZone(localizationConfig.getZoneId()); } entry.setLogicDbName(logicDbName); entry.setDbCategory(DalClientFactory.getDalConfigure().getDatabaseSet(logicDbName).getDatabaseCategory()); entry.setClientVersion(Version.getVersion()); + entry.setClientZone(envUtils.getZone()); entry.setSensitive(hints.is(DalHintEnum.sensitive)); entry.setEvent(operation); entry.setShardingCategory(shardingCategory); diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/client/DalConnectionManager.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/client/DalConnectionManager.java index 209879e66..6047e438a 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/client/DalConnectionManager.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/client/DalConnectionManager.java @@ -124,6 +124,8 @@ private DalConnection getConnectionFromDSLocator(DalHints hints, DataSourceIdentity id = new ClusterDataSourceIdentity(db); conn = locator.getConnection(id); meta = DbMeta.createIfAbsent(id, dbSet.getDatabaseCategory(), conn); + if (shardId == null) + shardId = String.valueOf(db.getShardIndex()); } else if (selectedDataBase instanceof ProviderDataBase) { ConnectionStringConfigureProvider provider = ((ProviderDataBase) selectedDataBase).getConnectionStringProvider(); diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/client/LogEntry.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/client/LogEntry.java index eb78f1077..8d31e2749 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/client/LogEntry.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/client/LogEntry.java @@ -49,6 +49,11 @@ public class LogEntry implements ILogEntry{ private TableParser tableParser = new DefaultTableParser(); private static final String JSON_PATTERN = "{'Decode':'%s','Connect':'%s','Prepare':'%s','Excute':'%s','ClearUp':'%s'}"; + private String clientZone; + private String dbZone; + private String ucsValidation; + private String dalValidation; + /** * Internal performance recorder for performance cost in each stage. * As each low level DB operation will be logged once at ConnectionAction level, this recorder will @@ -453,4 +458,37 @@ public ShardingCategory getShardingCategory() { public void setShardingCategory(ShardingCategory shardingCategory) { this.shardingCategory = shardingCategory; } + + public String getClientZone() { + return clientZone; + } + + public void setClientZone(String clientZone) { + this.clientZone = clientZone; + } + + public String getDbZone() { + return dbZone; + } + + public void setDbZone(String dbZone) { + this.dbZone = dbZone; + } + + public String getUcsValidation() { + return ucsValidation; + } + + public void setUcsValidation(String ucsValidation) { + this.ucsValidation = ucsValidation; + } + + public String getDalValidation() { + return dalValidation; + } + + public void setDalValidation(String dalValidation) { + this.dalValidation = dalValidation; + } + } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/cluster/ClusterManager.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/cluster/ClusterManager.java new file mode 100644 index 000000000..0615bac6e --- /dev/null +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/cluster/ClusterManager.java @@ -0,0 +1,12 @@ +package com.ctrip.platform.dal.dao.cluster; + +import com.ctrip.framework.dal.cluster.client.Cluster; + +/** + * @author c7ch23en + */ +public interface ClusterManager { + + Cluster getOrCreateCluster(String clusterName); + +} diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/cluster/ClusterManagerImpl.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/cluster/ClusterManagerImpl.java new file mode 100644 index 000000000..116a8c13c --- /dev/null +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/cluster/ClusterManagerImpl.java @@ -0,0 +1,46 @@ +package com.ctrip.platform.dal.dao.cluster; + +import com.ctrip.framework.dal.cluster.client.Cluster; +import com.ctrip.framework.dal.cluster.client.config.ClusterConfig; +import com.ctrip.framework.dal.cluster.client.util.StringUtils; +import com.ctrip.platform.dal.dao.configure.ClusterConfigProvider; +import com.ctrip.platform.dal.exceptions.DalRuntimeException; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author c7ch23en + */ +public class ClusterManagerImpl implements ClusterManager { + + private final ClusterConfigProvider configProvider; + private static final Map clusters = new ConcurrentHashMap<>(); + + public ClusterManagerImpl(ClusterConfigProvider configProvider) { + this.configProvider = configProvider; + } + + @Override + public Cluster getOrCreateCluster(String clusterName) { + if (StringUtils.isEmpty(clusterName)) + throw new DalRuntimeException("cluster name is empty"); + clusterName = StringUtils.toTrimmedLowerCase(clusterName); + Cluster cluster = clusters.get(clusterName); + if (cluster == null) + synchronized (clusters) { + cluster = clusters.get(clusterName); + if (cluster == null) { + cluster = createCluster(clusterName); + clusters.put(clusterName, cluster); + } + } + return cluster; + } + + private Cluster createCluster(String clusterName) { + ClusterConfig config = configProvider.getClusterConfig(clusterName); + return new DynamicCluster(config); + } + +} diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/cluster/DynamicCluster.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/cluster/DynamicCluster.java index 61392bcd5..6a3aaf559 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/cluster/DynamicCluster.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/cluster/DynamicCluster.java @@ -7,6 +7,7 @@ import com.ctrip.framework.dal.cluster.client.cluster.ClusterType; import com.ctrip.framework.dal.cluster.client.cluster.DrcCluster; import com.ctrip.framework.dal.cluster.client.config.ClusterConfig; +import com.ctrip.framework.dal.cluster.client.config.LocalizationConfig; import com.ctrip.framework.dal.cluster.client.database.Database; import com.ctrip.framework.dal.cluster.client.database.DatabaseCategory; import com.ctrip.framework.dal.cluster.client.exception.ClusterRuntimeException; @@ -29,9 +30,9 @@ public class DynamicCluster extends ListenableSupport impl private static final ILogger LOGGER = DalElementFactory.DEFAULT.getILogger(); private static final String CAT_LOG_TYPE = "DAL.configure"; - private static final String CAT_LOG_NAME_FORMAT = "SwitchCluster:%s"; - private static final String CAT_EVENT_NAME_NORMAL_TO_DRC = "NormalToDrc:%s"; - private static final String CAT_EVENT_NAME_DRC_TO_NORMAL = "DrcToNormal:%s"; + private static final String CAT_LOG_NAME_FORMAT = "Cluster::switchCluster:%s"; + private static final String CAT_EVENT_NAME_NORMAL_TO_DRC = "Cluster::normalToDrc:%s"; + private static final String CAT_EVENT_NAME_DRC_TO_NORMAL = "Cluster::drcToNormal:%s"; private ClusterConfig clusterConfig; private AtomicReference innerCluster = new AtomicReference<>(); @@ -112,6 +113,11 @@ public ClusterIdGeneratorConfig getIdGeneratorConfig() { return getInnerCluster().getIdGeneratorConfig(); } + @Override + public LocalizationConfig getLocalizationConfig() { + return getInnerCluster().getLocalizationConfig(); + } + private void registerListener() { clusterConfig.addListener(new Listener() { @Override diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/AbstractDataSourceConfigure.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/AbstractDataSourceConfigure.java index 4ac55b9f5..ceceedd30 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/AbstractDataSourceConfigure.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/AbstractDataSourceConfigure.java @@ -82,4 +82,9 @@ public String getInitSQL(){ public String getJdbcInterceptors(){ return null; } + + public Integer getSessionWaitTimeout() { + return null; + } + } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/ClusterDatabaseSet.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/ClusterDatabaseSet.java index 58ee96f8d..6384f28cc 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/ClusterDatabaseSet.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/ClusterDatabaseSet.java @@ -28,6 +28,11 @@ public class ClusterDatabaseSet extends DatabaseSet { private ClusterIdGeneratorConfigAdapter idGeneratorConfig; public ClusterDatabaseSet(String name, Cluster cluster, DalConnectionLocator locator) { + this(name, cluster, locator, null); + } + + public ClusterDatabaseSet(String name, Cluster cluster, DalConnectionLocator locator, Map properties) { + super(properties); this.databaseSetName = name; this.cluster = cluster; this.shardStrategy = new ClusterShardStrategyAdapter(cluster); diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/ClusterDatabaseSetAdapter.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/ClusterDatabaseSetAdapter.java index bb051120d..6e78157a9 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/ClusterDatabaseSetAdapter.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/ClusterDatabaseSetAdapter.java @@ -3,10 +3,14 @@ import com.ctrip.framework.dal.cluster.client.Cluster; import com.ctrip.framework.dal.cluster.client.config.ClusterConfig; import com.ctrip.framework.dal.cluster.client.database.DatabaseRole; +import com.ctrip.framework.dal.cluster.client.util.StringUtils; import com.ctrip.platform.dal.common.enums.DatabaseCategory; import com.ctrip.platform.dal.dao.client.DalConnectionLocator; +import com.ctrip.platform.dal.dao.cluster.ClusterManager; +import com.ctrip.platform.dal.dao.cluster.ClusterManagerImpl; import com.ctrip.platform.dal.dao.cluster.DynamicCluster; import com.ctrip.platform.dal.dao.helper.DalElementFactory; +import com.ctrip.platform.dal.dao.helper.EnvUtils; import com.ctrip.platform.dal.dao.log.DalLogTypes; import com.ctrip.platform.dal.dao.log.ILogger; @@ -19,15 +23,16 @@ public class ClusterDatabaseSetAdapter implements DatabaseSetAdapter { private static final ILogger LOGGER = DalElementFactory.DEFAULT.getILogger(); + private static final EnvUtils envUtils = DalElementFactory.DEFAULT.getEnvUtils(); private ClusterInfoProvider clusterInfoProvider; - private ClusterConfigProvider clusterConfigProvider; + private ClusterManager clusterManager; private DalConnectionLocator connectionLocator; public ClusterDatabaseSetAdapter(DalConnectionLocator connectionLocator) { this.connectionLocator = connectionLocator; this.clusterInfoProvider = connectionLocator.getIntegratedConfigProvider(); - this.clusterConfigProvider = connectionLocator.getIntegratedConfigProvider(); + this.clusterManager = new ClusterManagerImpl(connectionLocator.getIntegratedConfigProvider()); } @Override @@ -44,6 +49,7 @@ public DatabaseSet adapt(DatabaseSet original) { private boolean adaptable(DefaultDatabaseSet defaultDatabaseSet) { /* + * 0. no subEnv, not aws * 1. mysql * 2. no shard strategy * 4. no idgen config @@ -67,9 +73,9 @@ private boolean adaptable(DefaultDatabaseSet defaultDatabaseSet) { private ClusterDatabaseSet tryAdapt(DefaultDatabaseSet defaultDatabaseSet) { try { - List masters = defaultDatabaseSet.getMasterDbs(); - if (masters != null && masters.size() == 1) { - String databaseKey = masters.iterator().next().getConnectionString(); + DataBase master = defaultDatabaseSet.getMasterDbs().iterator().next(); + if ((master instanceof DefaultDataBase) && !(master instanceof ProviderDataBase)) { + String databaseKey = master.getConnectionString(); Map failedConnectionStrings = DataSourceConfigureLocatorManager. getInstance().getFailedConnectionStrings(); if (failedConnectionStrings == null || !failedConnectionStrings.containsKey(databaseKey)) { @@ -77,8 +83,7 @@ private ClusterDatabaseSet tryAdapt(DefaultDatabaseSet defaultDatabaseSet) { if (clusterInfo != null && clusterInfo.getRole() == DatabaseRole.MASTER && !clusterInfo.dbSharding()) { String clusterName = clusterInfo.getClusterName(); - ClusterConfig clusterConfig = clusterConfigProvider.getClusterConfig(clusterName); - Cluster cluster = new DynamicCluster(clusterConfig); + Cluster cluster = clusterManager.getOrCreateCluster(clusterName); LOGGER.logEvent(DalLogTypes.DAL_VALIDATION, "ClusterAdaptSucceeded", String.format("databaseSet: %s, clusterName: %s", defaultDatabaseSet.getName(), clusterName)); diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/ClusterInfo.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/ClusterInfo.java index f210e5aba..95e6cb555 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/ClusterInfo.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/ClusterInfo.java @@ -2,6 +2,7 @@ import com.ctrip.framework.dal.cluster.client.database.DatabaseRole; import com.ctrip.platform.dal.dao.datasource.DataSourceIdentity; +import com.ctrip.platform.dal.dao.datasource.IClusterDataSourceIdentity; public class ClusterInfo { @@ -42,7 +43,7 @@ public void setClusterName(String clusterName) { } public DataSourceIdentity toDataSourceIdentity() { - return new SimpleClusterDataSourceIdentity(toString()); + return new SimpleClusterDataSourceIdentity(this); } @Override @@ -50,12 +51,14 @@ public String toString() { return String.format(ID_FORMAT, clusterName, shardIndex, role != null ? role.getValue() : null); } - static class SimpleClusterDataSourceIdentity implements DataSourceIdentity { + static class SimpleClusterDataSourceIdentity implements DataSourceIdentity, IClusterDataSourceIdentity { + private ClusterInfo clusterInfo; private String id; - public SimpleClusterDataSourceIdentity(String id) { - this.id = id; + public SimpleClusterDataSourceIdentity(ClusterInfo clusterInfo) { + this.clusterInfo = clusterInfo; + this.id = clusterInfo.toString(); } @Override @@ -63,6 +66,21 @@ public String getId() { return id; } + @Override + public String getClusterName() { + return clusterInfo.getClusterName(); + } + + @Override + public Integer getShardIndex() { + return clusterInfo.getShardIndex(); + } + + @Override + public DatabaseRole getDatabaseRole() { + return clusterInfo.getRole(); + } + @Override public boolean equals(Object obj) { if (obj instanceof SimpleClusterDataSourceIdentity) { diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/ConnectionStringParser.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/ConnectionStringParser.java index 7d2fcd57a..f8fdb8d0f 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/ConnectionStringParser.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/ConnectionStringParser.java @@ -119,8 +119,8 @@ public DalConnectionStringConfigure parse(String name, String connectionString) String keyName = ConnectionStringKeyHelper.getKeyName(name); config.setName(keyName); config.setConnectionUrl(url); - config.setUserName(userName); - config.setPassword(password); + config.setUserName(userName != null ? userName : ""); + config.setPassword(password != null ? password : ""); config.setDriverClass(driverClass); config.setVersion(version); config.setHostName(dbhost); diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalConfigureFactory.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalConfigureFactory.java index e897c4c42..00526148a 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalConfigureFactory.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalConfigureFactory.java @@ -10,8 +10,8 @@ import javax.xml.parsers.DocumentBuilderFactory; import com.ctrip.framework.dal.cluster.client.Cluster; -import com.ctrip.platform.dal.dao.cluster.DynamicCluster; -import com.ctrip.framework.dal.cluster.client.config.ClusterConfig; +import com.ctrip.platform.dal.dao.cluster.ClusterManager; +import com.ctrip.platform.dal.dao.cluster.ClusterManagerImpl; import com.ctrip.framework.dal.cluster.client.util.StringUtils; import com.ctrip.platform.dal.dao.annotation.Database; import com.ctrip.platform.dal.dao.helper.ClassScanFilter; @@ -183,30 +183,28 @@ private Node getChildNode(Node node, String name) { private Map readDatabaseSets(Node databaseSetsNode, DalConnectionLocator locator) throws Exception { Map databaseSets = new HashMap<>(); - ClusterConfigProvider provider = locator.getIntegratedConfigProvider(); + ClusterManager clusterManager = new ClusterManagerImpl(locator.getIntegratedConfigProvider()); List clusterList = getChildNodes(databaseSetsNode, CLUSTER); - for (int i = 0; i < clusterList.size(); i++) { - Node node = clusterList.get(i); + for (Node node : clusterList) { String name = getDatabaseSetName(node); - Cluster cluster = readCluster(node, provider); - databaseSets.put(name, new ClusterDatabaseSet(name, cluster, locator)); + Cluster cluster = readCluster(node, clusterManager); + databaseSets.put(name, new ClusterDatabaseSet(name, cluster, locator, getSettings(node))); } List databaseSetList = getChildNodes(databaseSetsNode, DATABASE_SET); - for (int i = 0; i < databaseSetList.size(); i++) { - DatabaseSet databaseSet = readDatabaseSet(databaseSetList.get(i)); + for (Node node : databaseSetList) { + DatabaseSet databaseSet = readDatabaseSet(node); databaseSets.put(databaseSet.getName(), databaseSet); } return databaseSets; } - private Cluster readCluster(Node clusterNode, ClusterConfigProvider provider) throws Exception { + private Cluster readCluster(Node clusterNode, ClusterManager clusterManager) throws Exception { String name = getAttribute(clusterNode, NAME); if (StringUtils.isEmpty(name)) throw new DalConfigException("empty cluster name"); - ClusterConfig config = provider.getClusterConfig(name); - return new DynamicCluster(config); + return clusterManager.getOrCreateCluster(name); } private String getDatabaseSetName(Node clusterNode) { @@ -228,17 +226,17 @@ else if(hasAttribute(databaseSetNode, SHARDING_STRATEGY)) List databaseList = getChildNodes(databaseSetNode, ADD); Map databases = new HashMap<>(); - for (int i = 0; i < databaseList.size(); i++) { - DataBase database = readDataBase(databaseList.get(i), !shardingStrategy.isEmpty()); + for (Node node : databaseList) { + DataBase database = readDataBase(node, !shardingStrategy.isEmpty()); databases.put(database.getName(), database); } if (shardingStrategy.isEmpty()) return new DefaultDatabaseSet(getAttribute(databaseSetNode, NAME), getAttribute(databaseSetNode, PROVIDER), - databases, idGenConfig); + databases, idGenConfig, getSettings(databaseSetNode)); else return new DefaultDatabaseSet(getAttribute(databaseSetNode, NAME), getAttribute(databaseSetNode, PROVIDER), - shardingStrategy, databases, idGenConfig); + shardingStrategy, databases, idGenConfig, getSettings(databaseSetNode)); } private void tryAdaptToClusters(Map databaseSets, DatabaseSetAdapter adapter) { diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalExtendedPoolConfiguration.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalExtendedPoolConfiguration.java index 7597b2d40..7363c13da 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalExtendedPoolConfiguration.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalExtendedPoolConfiguration.java @@ -1,10 +1,14 @@ package com.ctrip.platform.dal.dao.configure; +import com.ctrip.platform.dal.dao.datasource.DataSourceIdentity; + /** * @author c7ch23en */ public interface DalExtendedPoolConfiguration { - int getServerWaitTimeout(); + int getSessionWaitTimeout(); + + DataSourceIdentity getDataSourceId(); } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalExtendedPoolProperties.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalExtendedPoolProperties.java index e7f7ed39b..b9fa83b11 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalExtendedPoolProperties.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalExtendedPoolProperties.java @@ -1,6 +1,8 @@ package com.ctrip.platform.dal.dao.configure; +import com.ctrip.platform.dal.dao.datasource.DataSourceIdentity; import com.ctrip.platform.dal.dao.helper.DalElementFactory; +import com.ctrip.platform.dal.dao.log.DalLogTypes; import com.ctrip.platform.dal.dao.log.ILogger; import org.apache.tomcat.jdbc.pool.PoolProperties; @@ -11,52 +13,53 @@ public class DalExtendedPoolProperties extends PoolProperties implements DalExte private static final ILogger LOGGER = DalElementFactory.DEFAULT.getILogger(); - private static final int DEFAULT_SERVER_WAIT_TIMEOUT = 120; + private static final int DEFAULT_SESSION_WAIT_TIMEOUT = DataSourceConfigureConstants.DEFAULT_SESSION_WAIT_TIMEOUT; // seconds - private volatile int serverWaitTimeout = DEFAULT_SERVER_WAIT_TIMEOUT; + private volatile int sessionWaitTimeout = DEFAULT_SESSION_WAIT_TIMEOUT; + + private DataSourceIdentity dataSourceId; @Override - public int getServerWaitTimeout() { - return getAdjustedServerWaitTimeout(); + public int getSessionWaitTimeout() { + return getAppliedSessionWaitTimeout(); } - public void setServerWaitTimeout(int serverWaitTimeout) { - this.serverWaitTimeout = serverWaitTimeout; + public void setSessionWaitTimeout(int sessionWaitTimeout) { + this.sessionWaitTimeout = sessionWaitTimeout; } - private int getAdjustedServerWaitTimeout() { - if (serverWaitTimeout == 0) { - LOGGER.info("serverWaitTimeout = 0"); + private int getAppliedSessionWaitTimeout() { + LOGGER.logEvent(DalLogTypes.DAL_VALIDATION, + "SessionWaitTimeout=" + sessionWaitTimeout, ""); + if (sessionWaitTimeout == 0) { + LOGGER.info("sessionWaitTimeout = 0"); return 0; } - int adjustedServerWaitTimeout = serverWaitTimeout; - if (serverWaitTimeout < 0) { - LOGGER.info(String.format("serverWaitTimeout < 0, set to %d by default", DEFAULT_SERVER_WAIT_TIMEOUT)); - adjustedServerWaitTimeout = DEFAULT_SERVER_WAIT_TIMEOUT; + int appliedSessionWaitTimeout = sessionWaitTimeout; + if (sessionWaitTimeout < 0) { + LOGGER.info(String.format("sessionWaitTimeout < 0, set to %d by default", DEFAULT_SESSION_WAIT_TIMEOUT)); + appliedSessionWaitTimeout = DEFAULT_SESSION_WAIT_TIMEOUT; } if (!isTestOnBorrow()) { LOGGER.info("testOnBorrow=false"); if (getMinIdle() > 0) { - LOGGER.info(String.format("minIdle=%d, serverWaitTimeout set to 0", getMinIdle())); - return 0; - } - /*if (getTimeBetweenEvictionRunsMillis() <= 0 || getMinEvictableIdleTimeMillis() <= 0) { - LOGGER.info("idle cleaner disabled, serverWaitTimeout set to 0"); + LOGGER.info(String.format("minIdle=%d, sessionWaitTimeout set to 0", getMinIdle())); return 0; } - int maxIdleSeconds = ceil(getTimeBetweenEvictionRunsMillis() + - getMinEvictableIdleTimeMillis(), 1000); - if (maxIdleSeconds > adjustedServerWaitTimeout) { - LOGGER.info(String.format("serverWaitTimeout set to possible maxIdleSeconds: %d", maxIdleSeconds)); - adjustedServerWaitTimeout = maxIdleSeconds; - }*/ } - return adjustedServerWaitTimeout; + LOGGER.logEvent(DalLogTypes.DAL_VALIDATION, + "AppliedSessionWaitTimeout=" + appliedSessionWaitTimeout, ""); + return appliedSessionWaitTimeout; + } + + @Override + public DataSourceIdentity getDataSourceId() { + return dataSourceId; } - private int ceil(int dividend, int divisor) { - return (dividend / divisor) + (dividend % divisor > 0 ? 1 : 0); + public void setDataSourceId(DataSourceIdentity dataSourceId) { + this.dataSourceId = dataSourceId; } } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalPoolPropertiesConfigure.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalPoolPropertiesConfigure.java index 0542311c9..057b51122 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalPoolPropertiesConfigure.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalPoolPropertiesConfigure.java @@ -12,4 +12,6 @@ public interface DalPoolPropertiesConfigure extends PoolPropertiesConfigure { String getDBToken(); Integer getCallMysqlApiPeriod(); DBModel getDBModel(); + String getLocalAccess(); + String[] getIdcPriority(); } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalThreadPoolExecutorConfig.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalThreadPoolExecutorConfig.java new file mode 100644 index 000000000..775049671 --- /dev/null +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalThreadPoolExecutorConfig.java @@ -0,0 +1,16 @@ +package com.ctrip.platform.dal.dao.configure; + +/** + * @author c7ch23en + */ +public interface DalThreadPoolExecutorConfig { + + int getCorePoolSize(); + + int getMaxPoolSize(); + + long getKeepAliveSeconds(); + + int getMaxThreadsPerShard(String logicDbName); + +} diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalThreadPoolExecutorConfigBuilder.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalThreadPoolExecutorConfigBuilder.java new file mode 100644 index 000000000..c66f58655 --- /dev/null +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalThreadPoolExecutorConfigBuilder.java @@ -0,0 +1,62 @@ +package com.ctrip.platform.dal.dao.configure; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author c7ch23en + */ +public class DalThreadPoolExecutorConfigBuilder { + + private int corePoolSize; + private int maxPoolSize; + private long keepAliveSeconds; + private int globalMaxThreadsPerShard; + private final Map dbMaxThreadsPerShardMap = new HashMap<>(); + + public DalThreadPoolExecutorConfigBuilder() {} + + public DalThreadPoolExecutorConfigBuilder setCorePoolSize(int corePoolSize) { + if (corePoolSize < 0) + throw new IllegalArgumentException("corePoolSize < 0, actual value is " + corePoolSize); + this.corePoolSize = corePoolSize; + return this; + } + + public DalThreadPoolExecutorConfigBuilder setMaxPoolSize(int maxPoolSize) { + if (maxPoolSize <= 0) + throw new IllegalArgumentException("maxPoolSize <= 0, actual value is " + maxPoolSize); + this.maxPoolSize = maxPoolSize; + return this; + } + + public DalThreadPoolExecutorConfigBuilder setKeepAliveSeconds(long keepAliveSeconds) { + if (keepAliveSeconds < 0) + throw new IllegalArgumentException("keepAliveSeconds < 0, actual value is " + keepAliveSeconds); + this.keepAliveSeconds = keepAliveSeconds; + return this; + } + + public DalThreadPoolExecutorConfigBuilder setMaxThreadsPerShard(int maxThreadsPerShard) { + if (maxThreadsPerShard < 0) + throw new IllegalArgumentException("maxThreadsPerShard < 0, actual value is " + maxThreadsPerShard); + globalMaxThreadsPerShard = maxThreadsPerShard; + return this; + } + + public DalThreadPoolExecutorConfigBuilder setMaxThreadsPerShard(String logicDbName, int maxThreadsPerShard) { + if (maxThreadsPerShard < 0) + throw new IllegalArgumentException("maxThreadsPerShard < 0, actual value is " + maxThreadsPerShard); + dbMaxThreadsPerShardMap.put(logicDbName, maxThreadsPerShard); + return this; + } + + public DalThreadPoolExecutorConfig build() { + if (maxPoolSize < corePoolSize) + throw new IllegalArgumentException("maxPoolSize < corePoolSize, maxPoolSize is " + maxPoolSize + + ", corePoolSize is " + corePoolSize); + return new DalThreadPoolExecutorConfigImpl(corePoolSize, maxPoolSize, keepAliveSeconds, + globalMaxThreadsPerShard, dbMaxThreadsPerShardMap); + } + +} diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalThreadPoolExecutorConfigImpl.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalThreadPoolExecutorConfigImpl.java new file mode 100644 index 000000000..46d38f3e5 --- /dev/null +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DalThreadPoolExecutorConfigImpl.java @@ -0,0 +1,46 @@ +package com.ctrip.platform.dal.dao.configure; + +import java.util.Map; + +/** + * @author c7ch23en + */ +public class DalThreadPoolExecutorConfigImpl implements DalThreadPoolExecutorConfig { + + private final int corePoolSize; + private final int maxPoolSize; + private final long keepAliveSeconds; + private final int globalMaxThreadsPerShard; + private final Map dbMaxThreadsPerShardMap; + + DalThreadPoolExecutorConfigImpl(int corePoolSize, int maxPoolSize, long keepAliveSeconds, + int globalMaxThreadsPerShard, Map dbMaxThreadsPerShardMap) { + this.corePoolSize = corePoolSize; + this.maxPoolSize = maxPoolSize; + this.keepAliveSeconds = keepAliveSeconds; + this.globalMaxThreadsPerShard = globalMaxThreadsPerShard; + this.dbMaxThreadsPerShardMap = dbMaxThreadsPerShardMap; + } + + @Override + public int getCorePoolSize() { + return corePoolSize; + } + + @Override + public int getMaxPoolSize() { + return maxPoolSize; + } + + @Override + public long getKeepAliveSeconds() { + return keepAliveSeconds; + } + + @Override + public int getMaxThreadsPerShard(String logicDbName) { + Integer dbMaxThreadsPerShard = dbMaxThreadsPerShardMap.get(logicDbName); + return dbMaxThreadsPerShard != null ? dbMaxThreadsPerShard : globalMaxThreadsPerShard; + } + +} diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DataSourceConfigure.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DataSourceConfigure.java index 8fd44da45..d8d6d3012 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DataSourceConfigure.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DataSourceConfigure.java @@ -2,6 +2,7 @@ import com.ctrip.platform.dal.common.enums.DBModel; import com.ctrip.platform.dal.common.enums.DatabaseCategory; +import com.ctrip.platform.dal.dao.datasource.DataSourceIdentity; import com.ctrip.platform.dal.dao.helper.EncryptionHelper; import com.ctrip.platform.dal.exceptions.DalRuntimeException; import org.apache.commons.lang.StringUtils; @@ -10,12 +11,12 @@ public class DataSourceConfigure extends AbstractDataSourceConfigure implements DataSourceConfigureConstants, DalConnectionStringConfigure, DalPoolPropertiesConfigure { + private String name; private Properties properties = new Properties(); private String version; private DalConnectionString connectionString; - - private static final String MYSQL_URL_PREFIX = "jdbc:mysql://"; + private DataSourceIdentity dataSourceId; public DataSourceConfigure() { } @@ -63,7 +64,7 @@ public String getUserName() { } public void setUserName(String userName) { - setProperty(USER_NAME, userName); + setProperty(USER_NAME, userName != null ? userName : ""); } @Override @@ -72,7 +73,7 @@ public String getPassword() { } public void setPassword(String password) { - setProperty(PASSWORD, password); + setProperty(PASSWORD, password != null ? password : ""); } @Override @@ -144,7 +145,8 @@ public String getProperty(String key, String defaultValue) { } public void setProperty(String key, String value) { - properties.setProperty(key, value); + if (key != null && value != null) + properties.setProperty(key, value); } @@ -254,6 +256,18 @@ public DBModel getDBModel() { return DBModel.toDBModel(getProperty(DB_MODEL, DEFAULT_DB_MODEL)); } + @Override + public String getLocalAccess() { + return getProperty(LOCAL_ACCESS); + } + + @Override + public String[] getIdcPriority() { + String value = getProperty(IDC_PRIORITY); + if (com.ctrip.framework.dal.cluster.client.util.StringUtils.isTrimmedEmpty(value)) + return new String[0]; + return StringUtils.split(value, IDC_PRIORITY_SEPARATOR); + } public String getInitSQL() { String initSQL = getProperty(INIT_SQL); @@ -307,18 +321,8 @@ public boolean dynamicPoolPropertiesEnabled() { return Boolean.parseBoolean(value); } - public Integer getServerWaitTimeout() { - if (properties != null) { - String value = properties.getProperty(SERVER_WAIT_TIMEOUT); - if (value != null) { - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { - // ignore - } - } - } - return null; + public Integer getSessionWaitTimeout() { + return getIntProperty(SESSION_WAIT_TIMEOUT, getIntProperty(SERVER_WAIT_TIMEOUT, DEFAULT_SESSION_WAIT_TIMEOUT)); } public DatabaseCategory getDatabaseCategory() { @@ -347,6 +351,7 @@ public synchronized DataSourceConfigure clone() { dataSourceConfigure.setProperties(p); dataSourceConfigure.setVersion(version); dataSourceConfigure.setConnectionString(connectionString == null ? null : connectionString.clone()); + dataSourceConfigure.setDataSourceId(dataSourceId); return dataSourceConfigure; } @@ -356,18 +361,24 @@ public static DataSourceConfigure valueOf(IDataSourceConfigure configure) { else { DataSourceConfigure dataSourceConfigure = new DataSourceConfigure(); Properties properties = new Properties(); - properties.setProperty(USER_NAME, configure.getUserName()); - properties.setProperty(PASSWORD, configure.getPassword()); + String username = configure.getUserName(); + properties.setProperty(USER_NAME, username != null ? username : ""); + String password = configure.getPassword(); + properties.setProperty(PASSWORD, password != null ? password : ""); String connectionUrl = configure.getConnectionUrl(); if (connectionUrl == null) - throw new DalRuntimeException("connetion url cannot be null"); + throw new DalRuntimeException("connection url cannot be null"); properties.setProperty(CONNECTION_URL, connectionUrl); - HostAndPort hostAndPort = ConnectionStringParser.parseHostPortFromURL(connectionUrl); - if (StringUtils.isEmpty(hostAndPort.getHost())) { - properties.setProperty(HOST_NAME, "UnKnown"); - } - else { - properties.setProperty(HOST_NAME, hostAndPort.getHost()); + + try { + HostAndPort hostAndPort = ConnectionStringParser.parseHostPortFromURL(connectionUrl); + if (StringUtils.isEmpty(hostAndPort.getHost())) { + properties.setProperty(HOST_NAME, "unknown"); + } else { + properties.setProperty(HOST_NAME, hostAndPort.getHost()); + } + } catch (Throwable t) { + // ignore } if (configure.getDriverClass() != null) @@ -412,6 +423,11 @@ public static DataSourceConfigure valueOf(IDataSourceConfigure configure) { properties.setProperty(VALIDATORCLASSNAME, configure.getValidatorClassName()); if (configure.getJdbcInterceptors() != null) properties.setProperty(JDBC_INTERCEPTORS, configure.getJdbcInterceptors()); + if (configure instanceof AbstractDataSourceConfigure) { + AbstractDataSourceConfigure configure1 = (AbstractDataSourceConfigure) configure; + if (configure1.getSessionWaitTimeout() != null) + properties.setProperty(SESSION_WAIT_TIMEOUT, String.valueOf(configure1.getSessionWaitTimeout())); + } dataSourceConfigure.setProperties(properties); return dataSourceConfigure; } @@ -422,6 +438,14 @@ public void replaceURL(String ip, int port) { setConnectionUrl(newConnectionUrl); } + public DataSourceIdentity getDataSourceId() { + return dataSourceId; + } + + public void setDataSourceId(DataSourceIdentity dataSourceId) { + this.dataSourceId = dataSourceId; + } + @Override public boolean equals(Object obj) { if (obj instanceof DataSourceConfigure) { @@ -451,7 +475,7 @@ public boolean equals(Object obj) { equals(getJdbcInterceptors(), ref.getJdbcInterceptors()) && equals(getConnectionProperties(), ref.getConnectionProperties()) && equals(getJmxEnabled(), ref.getJmxEnabled()) && - equals(getServerWaitTimeout(), ref.getServerWaitTimeout())); + equals(getSessionWaitTimeout(), ref.getSessionWaitTimeout())); } return false; } @@ -488,7 +512,7 @@ public int hashCode() { append(getJdbcInterceptors()). append(getConnectionProperties()). append(getJmxEnabled()). - append(getServerWaitTimeout()). + append(getSessionWaitTimeout()). generate(); } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DataSourceConfigureConstants.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DataSourceConfigureConstants.java index 8501e78da..1485cba06 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DataSourceConfigureConstants.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DataSourceConfigureConstants.java @@ -11,7 +11,8 @@ public interface DataSourceConfigureConstants { String TESTONBORROW = "testOnBorrow"; String TESTONRETURN = "testOnReturn"; String VALIDATIONQUERY = "validationQuery"; - String VALIDATIONQUERYTIMEOUT = "validationQueryTimeout"; + // validationQueryTimeout -> validationTimeoutMillis + String VALIDATIONQUERYTIMEOUT = "validationTimeoutMillis"; String VALIDATIONINTERVAL = "validationInterval"; String TIMEBETWEENEVICTIONRUNSMILLIS = "timeBetweenEvictionRunsMillis"; String MAX_AGE = "maxAge"; @@ -27,7 +28,8 @@ public interface DataSourceConfigureConstants { String INIT_SQL = "initSql"; // **********Dal extended properties key********** - String SERVER_WAIT_TIMEOUT = "serverWaitTimeout"; + String SERVER_WAIT_TIMEOUT = "serverWaitTimeout"; // alias name for sessionWaitTimeout + String SESSION_WAIT_TIMEOUT = "sessionWaitTimeout"; //used by mgr datasource String DB_TOKEN = "dbToken"; @@ -35,6 +37,9 @@ public interface DataSourceConfigureConstants { String DB_MODEL = "dbModel"; String LOAD_BALANCE_STRATEGY = "loadBalanceStrategy"; String SERVER_AFFINITY_ORDER = "serverAffinityOrder"; + String LOCAL_ACCESS = "localAccess"; + String IDC_PRIORITY = "idcPriority"; + String IDC_PRIORITY_SEPARATOR = ","; // This is for typo error String INIT_SQL2 = "initSQL"; @@ -56,7 +61,10 @@ public interface DataSourceConfigureConstants { boolean DEFAULT_TESTONBORROW = true; boolean DEFAULT_TESTONRETURN = false; String DEFAULT_VALIDATIONQUERY = "SELECT 1"; - int DEFAULT_VALIDATIONQUERYTIMEOUT = 5; + // 1s -> 250ms + int DEFAULT_VALIDATIONQUERYTIMEOUT = 250; + int MIN_VALIDATIONQUERYTIMEOUT = 100; + long DEFAULT_VALIDATIONINTERVAL = 30000L; String DEFAULT_VALIDATORCLASSNAME = "com.ctrip.platform.dal.dao.datasource.DataSourceValidator"; int DEFAULT_TIMEBETWEENEVICTIONRUNSMILLIS = 5000; @@ -78,7 +86,7 @@ public interface DataSourceConfigureConstants { // com.ctrip.platform.dal.dao.interceptor.DefaultConnectionState // **********Dal extended properties default value********** - int DEFAULT_SERVER_WAIT_TIMEOUT = 120; + int DEFAULT_SESSION_WAIT_TIMEOUT = 120; //used by mgr datasource int DEFAULT_CALL_MYSQL_API_PERIOD = 3 * 1000; //ms diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DatabasePoolConfigParser.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DatabasePoolConfigParser.java index a020261e1..d34a94712 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DatabasePoolConfigParser.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DatabasePoolConfigParser.java @@ -22,8 +22,7 @@ public DatabasePoolConfig getDatabasePoolConfig(String name) { poolProperties.setTestOnReturn(configure.getBooleanProperty(TESTONRETURN, DEFAULT_TESTONRETURN)); poolProperties.setValidationQuery(configure.getProperty(VALIDATIONQUERY, DEFAULT_VALIDATIONQUERY)); - poolProperties.setValidationQueryTimeout( - configure.getIntProperty(VALIDATIONQUERYTIMEOUT, DEFAULT_VALIDATIONQUERYTIMEOUT)); + poolProperties.setValidationQueryTimeout(configure.getValidationQueryTimeout()); poolProperties.setValidationInterval(configure.getLongProperty(VALIDATIONINTERVAL, DEFAULT_VALIDATIONINTERVAL)); poolProperties.setTimeBetweenEvictionRunsMillis( diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DatabaseSet.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DatabaseSet.java index b43e50db2..ca8aba5f6 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DatabaseSet.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DatabaseSet.java @@ -1,21 +1,25 @@ package com.ctrip.platform.dal.dao.configure; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; +import com.ctrip.framework.dal.cluster.client.util.StringUtils; import com.ctrip.platform.dal.common.enums.DatabaseCategory; import com.ctrip.platform.dal.dao.strategy.DalShardingStrategy; -import com.ctrip.platform.dal.dao.strategy.ShardColModShardStrategy; -import com.ctrip.platform.dal.exceptions.DalException; import com.ctrip.platform.dal.sharding.idgen.IIdGeneratorConfig; public abstract class DatabaseSet implements IDatabaseSet { + private final Map properties; + + public DatabaseSet() { + properties = null; + } + + public DatabaseSet(Map properties) { + this.properties = properties; + } + @Override public String getName() { throw new UnsupportedOperationException("This is an abstract DatabaseSet."); @@ -91,4 +95,23 @@ public IIdGeneratorConfig getIdGenConfig() { throw new UnsupportedOperationException("This is an abstract DatabaseSet."); } + public String getSetting(String key) { + return properties != null ? properties.get(key) : null; + } + + public Integer getSettingAsInt(String key) { + String value = getSetting(key); + return !StringUtils.isEmpty(value) ? Integer.parseInt(value) : null; + } + + public Long getSettingAsLong(String key) { + String value = getSetting(key); + return !StringUtils.isEmpty(value) ? Long.parseLong(value) : null; + } + + public Boolean getSettingAsBool(String key) { + String value = getSetting(key); + return !StringUtils.isEmpty(value) ? Boolean.parseBoolean(value) : null; + } + } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DefaultDataSourceConfigureLocator.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DefaultDataSourceConfigureLocator.java index 64e6e719f..80057cddd 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DefaultDataSourceConfigureLocator.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DefaultDataSourceConfigureLocator.java @@ -76,6 +76,7 @@ public DataSourceConfigure getDataSourceConfigure(DataSourceIdentity id) { configure = mergeDataSourceConfigure(connectionString); if (configure != null) { dataSourceConfiguresCache.put(id, configure); + configure.setDataSourceId(id); } return configure; } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DefaultDatabaseSet.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DefaultDatabaseSet.java index 88614e18e..232beac15 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DefaultDatabaseSet.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/DefaultDatabaseSet.java @@ -1,12 +1,7 @@ package com.ctrip.platform.dal.dao.configure; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import com.ctrip.platform.dal.common.enums.DatabaseCategory; import com.ctrip.platform.dal.dao.strategy.DalShardingStrategy; @@ -51,13 +46,26 @@ public DefaultDatabaseSet(String name, String provider, String shardStrategy, Ma this(name, provider, shardStrategy, databases, null); } - public DefaultDatabaseSet(String name, String provider, Map databases, IIdGeneratorConfig idGenConfig) + public DefaultDatabaseSet(String name, String provider, Map databases, + IIdGeneratorConfig idGenConfig) throws Exception { this(name, provider, null, databases, idGenConfig); } + public DefaultDatabaseSet(String name, String provider, Map databases, + IIdGeneratorConfig idGenConfig, Map properties) + throws Exception { + this(name, provider, null, databases, idGenConfig, properties); + } + + public DefaultDatabaseSet(String name, String provider, String shardStrategy, Map databases, + IIdGeneratorConfig idGenConfig) throws Exception { + this(name, provider, shardStrategy, databases, idGenConfig, null); + } + public DefaultDatabaseSet(String name, String provider, String shardStrategy, Map databases, - IIdGeneratorConfig idGenConfig) throws Exception { + IIdGeneratorConfig idGenConfig, Map properties) throws Exception { + super(properties); this.name = name; this.provider = provider; this.dbCategory = DatabaseCategory.matchWith(provider); diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/LocalClusterConfigProvider.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/LocalClusterConfigProvider.java index edbb922a7..264c98942 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/LocalClusterConfigProvider.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/configure/LocalClusterConfigProvider.java @@ -2,6 +2,7 @@ import com.ctrip.framework.dal.cluster.client.config.ClusterConfig; import com.ctrip.framework.dal.cluster.client.config.ClusterConfigParser; +import com.ctrip.framework.dal.cluster.client.config.DefaultLocalConfigProvider; import com.ctrip.framework.dal.cluster.client.exception.ClusterConfigException; import java.io.InputStream; @@ -20,18 +21,8 @@ public LocalClusterConfigProvider(ClusterConfigParser parser) { @Override public ClusterConfig getClusterConfig(String clusterName) { - try { - String fileName = getFileName(clusterName); - URL url = LocalClusterConfigProvider.class.getClassLoader().getResource(fileName); - InputStream is = url.openStream(); - return getParser().parse(is); - } catch (Throwable t) { - throw new ClusterConfigException(t); - } - } - - protected String getFileName(String clusterName) { - return clusterName + ".xml"; + DefaultLocalConfigProvider configProvider = new DefaultLocalConfigProvider(clusterName, getParser()); + return configProvider.getClusterConfig(); } } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/AbstractConnectionListener.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/AbstractConnectionListener.java index bdb97bff3..d8b024a37 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/AbstractConnectionListener.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/AbstractConnectionListener.java @@ -16,26 +16,26 @@ public abstract class AbstractConnectionListener implements ConnectionListener { private String ON_WAIT_CONNECTION_FORMAT="[onWaitConnection]%s, %s"; @Override - public void onCreateConnection(String poolDesc, Connection connection, long startTime) { + public void onCreateConnection(String poolDesc, Connection connection, DataSourceIdentity dataSourceId, long startTime) { if (connection == null) return; - doOnCreateConnection(poolDesc, connection, startTime); + doOnCreateConnection(poolDesc, connection, dataSourceId, startTime); } - protected void doOnCreateConnection(String poolDesc, Connection connection, long startTime) { + protected void doOnCreateConnection(String poolDesc, Connection connection, DataSourceIdentity dataSourceId, long startTime) { logInfo(ON_CREATE_CONNECTION_FORMAT, poolDesc, connection); } @Override - public void onCreateConnectionFailed(String poolDesc, String connDesc, Throwable exception, long startTime) { + public void onCreateConnectionFailed(String poolDesc, String connDesc, DataSourceIdentity dataSourceId, Throwable exception, long startTime) { if (exception == null) return; - doOnCreateConnectionFailed(poolDesc, connDesc, exception, startTime); + doOnCreateConnectionFailed(poolDesc, connDesc, dataSourceId, exception, startTime); } - protected void doOnCreateConnectionFailed(String poolDesc, String connDesc, Throwable exception, long startTime) { + protected void doOnCreateConnectionFailed(String poolDesc, String connDesc, DataSourceIdentity dataSourceId, Throwable exception, long startTime) { logError(ON_CREATE_CONNECTION_FAILED_FORMAT, poolDesc, connDesc, exception); } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ApiDataSourceIdentity.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ApiDataSourceIdentity.java index 4eefed034..0d85bed68 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ApiDataSourceIdentity.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ApiDataSourceIdentity.java @@ -5,6 +5,8 @@ import com.ctrip.platform.dal.dao.log.ILogger; import com.ctrip.platform.dal.exceptions.DalRuntimeException; +import java.util.Objects; + public class ApiDataSourceIdentity implements DataSourceIdentity { private static final ILogger LOGGER = DalElementFactory.DEFAULT.getILogger(); @@ -52,17 +54,16 @@ public String getId() { } @Override - public boolean equals(Object obj) { - if (obj instanceof ApiDataSourceIdentity) { - ConnectionStringConfigureProvider objProvider = ((ApiDataSourceIdentity) obj).getProvider(); - return (provider != null && provider.equals(objProvider)) || (provider == null && objProvider == null); - } - return false; + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ApiDataSourceIdentity that = (ApiDataSourceIdentity) o; + return Objects.equals(provider, that.provider); } @Override public int hashCode() { - return provider != null ? provider.hashCode() : 0; + return Objects.hash(provider); } public static class ApiConnectionStringImpl implements DalConnectionString { @@ -100,8 +101,9 @@ public DalConnectionStringConfigure getDomainConnectionStringConfigure() { @Override public DalConnectionString clone() { - throw new UnsupportedOperationException("clone not supported"); + return new ApiConnectionStringImpl(connectionStringConfigure); } + } } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ClusterDataSourceIdentity.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ClusterDataSourceIdentity.java index 2c0fdca16..896e073bb 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ClusterDataSourceIdentity.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ClusterDataSourceIdentity.java @@ -2,6 +2,7 @@ import com.ctrip.framework.dal.cluster.client.database.ConnectionString; import com.ctrip.framework.dal.cluster.client.database.Database; +import com.ctrip.framework.dal.cluster.client.database.DatabaseRole; import com.ctrip.platform.dal.dao.configure.DalConnectionString; import com.ctrip.platform.dal.dao.configure.DalConnectionStringConfigure; import com.ctrip.platform.dal.dao.configure.DataSourceConfigure; @@ -9,7 +10,7 @@ /** * @author c7ch23en */ -public class ClusterDataSourceIdentity implements DataSourceIdentity { +public class ClusterDataSourceIdentity implements DataSourceIdentity, IClusterDataSourceIdentity { private static final String ID_FORMAT = "%s-%d-%s-%s"; // cluster-shard-role-host private static final String MASTER = "master"; @@ -45,6 +46,21 @@ public Database getDatabase() { return database; } + @Override + public String getClusterName() { + return database.getClusterName(); + } + + @Override + public Integer getShardIndex() { + return database.getShardIndex(); + } + + @Override + public DatabaseRole getDatabaseRole() { + return database.isMaster() ? DatabaseRole.MASTER : DatabaseRole.SLAVE; + } + @Override public boolean equals(Object obj) { if (obj instanceof ClusterDataSourceIdentity) { @@ -60,13 +76,14 @@ public int hashCode() { } public static class ClusterConnectionStringImpl implements DalConnectionString { - private String name; + private Database database; private ConnectionString connectionString; private String[] aliasKeys; public ClusterConnectionStringImpl(String name, Database database) { this.name = name; + this.database = database; this.connectionString = database.getConnectionString(); this.aliasKeys = database.getAliasKeys(); } @@ -112,9 +129,8 @@ public DalConnectionStringConfigure getDomainConnectionStringConfigure() { @Override public DalConnectionString clone() { - throw new UnsupportedOperationException("clone not supported"); + return new ClusterConnectionStringImpl(name, database); } - } } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ClusterDynamicDataSource.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ClusterDynamicDataSource.java index 0f09862f8..efedc1107 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ClusterDynamicDataSource.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ClusterDynamicDataSource.java @@ -123,14 +123,14 @@ private RefreshableDataSource createInnerDataSource(ClusterInfo clusterInfo, Clu DataSourceConfigure config = provider.getDataSourceConfigure(id); try { if (cluster != null && cluster.getClusterType() == ClusterType.DRC) { - DrcCluster drcCluster = cluster.unwrap(DrcCluster.class); - LocalizationConfig localizationConfig = drcCluster.getLocalizationConfig(); + LocalizationConfig localizationConfig = cluster.getLocalizationConfig(); LocalizationValidator validator = factory.createValidator(clusterInfo, localizationConfig); LOGGER.logEvent(CAT_LOG_TYPE, String.format(CAT_LOG_NAME_DRC, clusterInfo.toString()), localizationConfig.toString()); return new LocalizedDataSource(validator, id, config); } - } catch (SQLException e) { + } catch (Exception e) { LOGGER.logEvent(CAT_LOG_TYPE, String.format(CAT_LOG_NAME_DRC_FAIL, clusterInfo.toString()), e.getMessage()); + throw e; } LOGGER.logEvent(CAT_LOG_TYPE, String.format(CAT_LOG_NAME_NORMAL, clusterInfo.toString()), ""); return new RefreshableDataSource(id, config); diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ConnectionListener.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ConnectionListener.java index e7aa7ab2f..27af2805e 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ConnectionListener.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ConnectionListener.java @@ -5,9 +5,10 @@ import java.sql.Connection; public interface ConnectionListener extends Ordered { - void onCreateConnection(String poolDesc, Connection connection, long startTime); - void onCreateConnectionFailed(String poolDesc, String connDesc, Throwable exception, long startTime); + void onCreateConnection(String poolDesc, Connection connection, DataSourceIdentity dataSourceId, long startTime); + + void onCreateConnectionFailed(String poolDesc, String connDesc, DataSourceIdentity dataSourceId, Throwable exception, long startTime); void onReleaseConnection(String poolDesc, Connection connection); diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ConstantLocalizationValidator.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ConstantLocalizationValidator.java index 33e7afd13..19a25c15f 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ConstantLocalizationValidator.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ConstantLocalizationValidator.java @@ -15,8 +15,8 @@ public ConstantLocalizationValidator(boolean constantResult) { } @Override - public boolean validateRequest() { - return constantResult; + public ValidationResult validateRequest() { + return new ValidationResult(constantResult, null, null); } @Override diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/DataSourceLocator.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/DataSourceLocator.java index 011d8698e..53a140053 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/DataSourceLocator.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/DataSourceLocator.java @@ -13,6 +13,8 @@ import com.ctrip.framework.dal.cluster.client.config.LocalizationConfig; import com.ctrip.framework.dal.cluster.client.database.Database; import com.ctrip.framework.dal.cluster.client.database.DatabaseRole; +import com.ctrip.platform.dal.dao.cluster.ClusterManager; +import com.ctrip.platform.dal.dao.cluster.ClusterManagerImpl; import com.ctrip.platform.dal.dao.cluster.DynamicCluster; import com.ctrip.framework.dal.cluster.client.config.ClusterConfig; import com.ctrip.platform.dal.dao.configure.*; @@ -32,17 +34,19 @@ public class DataSourceLocator { private DatasourceBackgroundExecutor executor = DalElementFactory.DEFAULT.getDatasourceBackgroundExecutor(); private IntegratedConfigProvider provider; + private ClusterManager clusterManager; private LocalizationValidatorFactory factory = DalElementFactory.DEFAULT.getLocalizationValidatorFactory(); private boolean isForceInitialize = false; public DataSourceLocator(IntegratedConfigProvider provider) { - this.provider = provider; + this(provider, false); } public DataSourceLocator(IntegratedConfigProvider provider, boolean isForceInitialize) { this.provider = provider; this.isForceInitialize = isForceInitialize; + this.clusterManager = new ClusterManagerImpl(provider); } // to be refactored @@ -96,8 +100,7 @@ public DataSource getDataSource(ClusterInfo clusterInfo) { if (ds == null) { try { String clusterName = clusterInfo.getClusterName(); - ClusterConfig clusterConfig = provider.getClusterConfig(clusterName); - ds = createDataSource(id, clusterInfo, new DynamicCluster(clusterConfig)); + ds = createDataSource(id, clusterInfo, clusterManager.getOrCreateCluster(clusterName)); cache.put(id, ds); } catch (Throwable t) { String msg = String.format("error when creating cluster datasource: %s", id.getId()); @@ -138,16 +141,16 @@ private RefreshableDataSource createRefreshableDataSource(DataSourceIdentity id) cluster != null && cluster.dbShardingEnabled()); try { if (cluster != null && cluster.getClusterType() == ClusterType.DRC) { - DrcCluster drcCluster = cluster.unwrap(DrcCluster.class); - LocalizationConfig localizationConfig = drcCluster.getLocalizationConfig(); + LocalizationConfig localizationConfig = cluster.getLocalizationConfig(); LocalizationValidator validator = factory.createValidator(clusterInfo, localizationConfig); LOGGER.logEvent(LOG_TYPE_CREATE_DATASOURCE, String.format(LOG_NAME_CREATE_DRC_DATASOURCE, clusterInfo.toString()), localizationConfig.toString()); return new LocalizedDataSource(validator, id, provider.getDataSourceConfigure(id)); } - } catch (SQLException e) { + } catch (Exception e) { LOGGER.logEvent(LOG_TYPE_CREATE_DATASOURCE, String.format(LOG_NAME_CREATE_DRC_DATASOURCE_FAIL, clusterInfo.toString()), e.getMessage()); + throw e; } } LOGGER.logEvent(LOG_TYPE_CREATE_DATASOURCE, String.format(LOG_NAME_CREATE_NORMAL_DATASOURCE, id.getId()), ""); diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/DataSourceValidator.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/DataSourceValidator.java index 664fb3ce2..4487e2dad 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/DataSourceValidator.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/DataSourceValidator.java @@ -1,11 +1,15 @@ package com.ctrip.platform.dal.dao.datasource; +import com.ctrip.platform.dal.dao.configure.DalExtendedPoolConfiguration; +import com.ctrip.platform.dal.dao.configure.DataSourceConfigureConstants; import com.ctrip.platform.dal.dao.helper.DalElementFactory; import com.ctrip.platform.dal.dao.helper.LoggerHelper; import com.ctrip.platform.dal.dao.helper.MySqlConnectionHelper; import com.ctrip.platform.dal.dao.log.DalLogTypes; import com.ctrip.platform.dal.dao.log.ILogger; +import com.ctrip.platform.dal.dao.log.LogUtils; import com.mysql.jdbc.MySQLConnection; +import org.apache.tomcat.jdbc.pool.PoolConfiguration; import org.apache.tomcat.jdbc.pool.PoolProperties; import org.apache.tomcat.jdbc.pool.PooledConnection; @@ -15,7 +19,6 @@ public class DataSourceValidator implements ValidatorProxy { private static ILogger LOGGER = DalElementFactory.DEFAULT.getILogger(); - private static final int DEFAULT_VALIDATE_TIMEOUT_IN_SECONDS = 1; private static final String CONNECTION_VALIDATE_CONNECTION_FORMAT = "Connection::validateConnection:%s"; private static final String IS_VALID_RETURN_INFO = "isValid() returned false."; private String IS_VALID_FORMAT = "isValid: %s"; @@ -34,7 +37,13 @@ public boolean validate(Connection connection, int validateAction) { connectionUrl = LoggerHelper.getSimplifiedDBUrl(connection.getMetaData().getURL()); transactionName = String.format(CONNECTION_VALIDATE_CONNECTION_FORMAT, connectionUrl); isValid = validateConnection(connection, validateAction); - LOGGER.logTransaction(DalLogTypes.DAL_DATASOURCE, transactionName, String.format(IS_VALID_FORMAT, isValid), startTime); + + PoolConfiguration poolConfig = getPoolProperties(); + DataSourceIdentity dataSourceId = poolConfig instanceof DalExtendedPoolConfiguration ? + ((DalExtendedPoolConfiguration) poolConfig).getDataSourceId() : null; + + LOGGER.logTransaction(DalLogTypes.DAL_DATASOURCE, transactionName, String.format(IS_VALID_FORMAT, isValid), + LogUtils.buildPropertiesFromDataSourceId(dataSourceId), startTime); if (!isValid) { LOGGER.warn(IS_VALID_RETURN_INFO); @@ -63,12 +72,12 @@ private QueryParameter getQueryParameter(int validateAction) { PoolProperties poolProperties = getPoolProperties(); if (poolProperties == null) { - parameter.setValidationQueryTimeout(DEFAULT_VALIDATE_TIMEOUT_IN_SECONDS); + parameter.setValidationQueryTimeout(DataSourceConfigureConstants.DEFAULT_VALIDATIONQUERYTIMEOUT); return parameter; } int validationQueryTimeout = poolProperties.getValidationQueryTimeout(); if (validationQueryTimeout <= 0) { - validationQueryTimeout = DEFAULT_VALIDATE_TIMEOUT_IN_SECONDS; + validationQueryTimeout = DataSourceConfigureConstants.DEFAULT_VALIDATIONQUERYTIMEOUT; } parameter.setValidationQueryTimeout(validationQueryTimeout); @@ -104,7 +113,7 @@ private boolean connectionIsValid(Connection connection, QueryParameter paramete MySQLConnection mySqlConnection = (MySQLConnection) connection; isValid = MySqlConnectionHelper.isValid(mySqlConnection, parameter.getValidationQueryTimeout()); } else { - isValid = connection.isValid(parameter.getValidationQueryTimeout()); + isValid = connection.isValid(parameter.getValidationQueryTimeoutS()); } return isValid; @@ -113,7 +122,7 @@ private boolean connectionIsValid(Connection connection, QueryParameter paramete private boolean executeInitSQL(Connection connection, QueryParameter parameter) throws SQLException { boolean isValid = false; String query = parameter.getQuery(); - int validationQueryTimeout = parameter.getValidationQueryTimeout(); + int validationQueryTimeout = parameter.getValidationQueryTimeoutS(); Statement stmt = null; try { @@ -134,7 +143,7 @@ private boolean executeInitSQL(Connection connection, QueryParameter parameter) private class QueryParameter { private String query = null; - private int validationQueryTimeout = -1; + private int validationQueryTimeout = DataSourceConfigureConstants.DEFAULT_VALIDATIONQUERYTIMEOUT; public String getQuery() { return query; @@ -145,7 +154,11 @@ public void setQuery(String query) { } public int getValidationQueryTimeout() { - return validationQueryTimeout; + return Math.max(validationQueryTimeout, DataSourceConfigureConstants.MIN_VALIDATIONQUERYTIMEOUT); + } + + public int getValidationQueryTimeoutS() { + return validationQueryTimeout / 1000 + (validationQueryTimeout % 1000 > 0 ? 1 : 0); } public void setValidationQueryTimeout(int validationQueryTimeout) { diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ForceSwitchableDataSource.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ForceSwitchableDataSource.java index 95a92dacc..993af436a 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ForceSwitchableDataSource.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ForceSwitchableDataSource.java @@ -72,21 +72,19 @@ public SwitchableDataSourceStatus forceSwitch(FirstAidKit configure, final Strin final String name; final DataSourceConfigure usedConfigure; forceSwitchedStatus = ForceSwitchedStatus.ForceSwitching; - if (isNullDataSource) { - if (configure instanceof IDataSourceConfigure) { - usedConfigure = dataSourceConfigureConvert.desDecrypt(DataSourceConfigure.valueOf((IDataSourceConfigure) configure)); - name = ((IDataSourceConfigure)configure).getConnectionUrl(); - } - else { - throw new DalRuntimeException("Force Switch Error: datasource configure is invalid"); - } - } - else { - usedConfigure = getSingleDataSource().getDataSourceConfigure().clone(); - name = getSingleDataSource().getName(); - } - final String logName = String.format(FORCE_SWITCH, name); try { + if (isNullDataSource) { + if (configure instanceof IDataSourceConfigure) { + usedConfigure = dataSourceConfigureConvert.desDecrypt(DataSourceConfigure.valueOf((IDataSourceConfigure) configure)); + name = ((IDataSourceConfigure) configure).getConnectionUrl(); + } else { + throw new DalRuntimeException("Force Switch Error: datasource configure is invalid"); + } + } else { + usedConfigure = getSingleDataSource().getDataSourceConfigure().clone(); + name = getSingleDataSource().getName(); + } + final String logName = String.format(FORCE_SWITCH, name); LOGGER.logTransaction(DalLogTypes.DAL_CONFIGURE, logName, "forceSwitch", new Callback() { @Override public void execute() throws Exception { @@ -96,13 +94,13 @@ public void execute() throws Exception { LOGGER.logEvent(DalLogTypes.DAL_CONFIGURE, logName, String.format("new connection url: %s", usedConfigure.getConnectionUrl())); asyncRefreshDataSource(name, usedConfigure, new ForceSwitchListener() { public void onCreatePoolSuccess() { - LOGGER.logEvent(DalLogTypes.DAL_DATASOURCE, String.format("onCreatePoolSuccess: %s",name), usedConfigure.getConnectionUrl()); + LOGGER.logEvent(DalLogTypes.DAL_DATASOURCE, String.format("onCreatePoolSuccess: %s", name), usedConfigure.getConnectionUrl()); poolCreated = true; forceSwitchedStatus = ForceSwitchedStatus.ForceSwitched; - oldForceSwitchedStatus = forceSwitchedStatus; + oldForceSwitchedStatus = ForceSwitchedStatus.ForceSwitched; isNullDataSource = false; final SwitchableDataSourceStatus status = getStatus(); - LOGGER.logEvent(DalLogTypes.DAL_DATASOURCE, String.format("onCreatePoolSuccess::notifyListeners: %s",name), "notify listeners' onForceSwitchSuccess"); + LOGGER.logEvent(DalLogTypes.DAL_DATASOURCE, String.format("onCreatePoolSuccess::notifyListeners: %s", name), "notify listeners' onForceSwitchSuccess"); for (final SwitchListener listener : listeners) executor.submit(new Runnable() { @Override @@ -117,10 +115,10 @@ public void run() { } public void onCreatePoolFail(final Throwable e) { - LOGGER.logEvent(DalLogTypes.DAL_DATASOURCE, String.format("onCreatePoolFail: %s",name), e.getMessage()); + LOGGER.logEvent(DalLogTypes.DAL_DATASOURCE, String.format("onCreatePoolFail: %s", name), e.getMessage()); forceSwitchedStatus = oldForceSwitchedStatus; final SwitchableDataSourceStatus status = getStatus(); - LOGGER.logEvent(DalLogTypes.DAL_DATASOURCE, String.format("onCreatePoolFail::notifyListeners: %s",name), "notify listeners' onForceSwitchFail"); + LOGGER.logEvent(DalLogTypes.DAL_DATASOURCE, String.format("onCreatePoolFail::notifyListeners: %s", name), "notify listeners' onForceSwitchFail"); for (final SwitchListener listener : listeners) executor.submit(new Runnable() { @Override @@ -136,9 +134,10 @@ public void run() { }); } }); - } catch (Exception e) { - LOGGER.error("Force Switch Error", e); - throw new DalRuntimeException("Force Switch Error", e); + } catch (Throwable t) { + forceSwitchedStatus = oldForceSwitchedStatus; + LOGGER.error("Force switch error", t); + throw new DalRuntimeException("Force switch error", t); } return oldStatus; } @@ -182,9 +181,9 @@ public void run() { } } }); - } catch (Exception e) { - LOGGER.error("get status error", e); - throw new DalRuntimeException("get status error", e); + } catch (Throwable t) { + LOGGER.error("Get status error", t); + throw new DalRuntimeException("Get status error", t); } boolean isForceSwitched; if (ForceSwitchedStatus.ForceSwitched.equals(forceSwitchedStatus)) { @@ -263,8 +262,9 @@ public void run() { }); } }); - } catch (Exception e) { - throw new DalRuntimeException(e); + } catch (Throwable t) { + LOGGER.error("Restore error", t); + throw new DalRuntimeException("Restore error", t); } return oldStatus; } @@ -278,7 +278,6 @@ private void setIpPortCache(HostAndPort hostAndPort) { this.currentHostAndPort = hostAndPort; } - private void setPoolCreated(boolean poolCreated) { this.poolCreated = poolCreated; } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/IClusterDataSourceIdentity.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/IClusterDataSourceIdentity.java new file mode 100644 index 000000000..3de02c2e3 --- /dev/null +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/IClusterDataSourceIdentity.java @@ -0,0 +1,16 @@ +package com.ctrip.platform.dal.dao.datasource; + +import com.ctrip.framework.dal.cluster.client.database.DatabaseRole; + +/** + * @author c7ch23en + */ +public interface IClusterDataSourceIdentity extends DataSourceIdentity { + + String getClusterName(); + + Integer getShardIndex(); + + DatabaseRole getDatabaseRole(); + +} diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/LocalizationValidatable.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/LocalizationValidatable.java new file mode 100644 index 000000000..5fc90805a --- /dev/null +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/LocalizationValidatable.java @@ -0,0 +1,21 @@ +package com.ctrip.platform.dal.dao.datasource; + +/** + * @author c7ch23en + */ +public interface LocalizationValidatable { + + boolean validate(); + + ValidationStatus getLastValidationStatus(); + + ValidationResult getLastValidationResult(); + + enum ValidationStatus { + OK, + FAILED, + SKIPPED, + UNKNOWN + } + +} diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/LocalizationValidator.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/LocalizationValidator.java index fe4891bdc..f68b5d405 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/LocalizationValidator.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/LocalizationValidator.java @@ -6,7 +6,7 @@ public interface LocalizationValidator { LocalizationValidator DEFAULT = new ConstantLocalizationValidator(); - boolean validateRequest(); + ValidationResult validateRequest(); boolean validateZone(); diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/LocalizedPreparedStatement.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/LocalizedPreparedStatement.java index ec08c6cab..7f384357f 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/LocalizedPreparedStatement.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/LocalizedPreparedStatement.java @@ -143,7 +143,7 @@ public void setObject(int parameterIndex, Object x) throws SQLException { @Override public boolean execute() throws SQLException { - if (needValidate()) + if (isUpdateOperation()) validateLocalization(); return preparedStatement.execute(); } @@ -324,9 +324,8 @@ public long executeLargeUpdate() throws SQLException { return preparedStatement.executeLargeUpdate(); } - @Override - protected boolean needValidate() { - return super.needValidate() && !SqlUtils.isReadOperation(firstAlphaCharUc); + protected boolean isUpdateOperation() { + return !isCallableStatement() && !SqlUtils.isReadOperation(firstAlphaCharUc); } } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/LocalizedStatement.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/LocalizedStatement.java index b0495ae90..45753dd3f 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/LocalizedStatement.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/LocalizedStatement.java @@ -6,11 +6,14 @@ import java.sql.*; -public class LocalizedStatement implements Statement { +public class LocalizedStatement implements Statement, LocalizationValidatable { private LocalizationValidator validator; private Statement statement; + private ValidationStatus lastValidationStatus = ValidationStatus.UNKNOWN; + private ValidationResult lastValidationResult = null; + public LocalizedStatement(Statement statement) { this(LocalizationValidator.DEFAULT, statement); } @@ -21,8 +24,32 @@ public LocalizedStatement(LocalizationValidator validator, Statement statement) } protected void validateLocalization() throws DalException { - if (validator != null && !validator.validateRequest()) - throw new DalException(ErrorCode.NonLocalRequestBlocked, "Non-local insert/update/delete is not allowed for drc cluster"); + if (!validate()) + throw new DalException(ErrorCode.NonLocalRequestBlocked, + "Non-local insert/update/delete is not allowed for drc cluster"); + } + + @Override + public boolean validate() { + if (validator == null) { + lastValidationStatus = ValidationStatus.SKIPPED; + lastValidationResult = new ValidationResult(true, null, null); + return true; + } + ValidationResult result = validator.validateRequest(); + lastValidationStatus = result.getValidationResult() ? ValidationStatus.OK : ValidationStatus.FAILED; + lastValidationResult = result; + return result.getValidationResult(); + } + + @Override + public ValidationStatus getLastValidationStatus() { + return lastValidationStatus; + } + + @Override + public ValidationResult getLastValidationResult() { + return lastValidationResult; } @Override @@ -98,7 +125,7 @@ public void setCursorName(String name) throws SQLException { @Override public boolean execute(String sql) throws SQLException { - if (needValidate(sql)) + if (isUpdateOperation(sql)) validateLocalization(); return statement.execute(sql); } @@ -199,21 +226,21 @@ public int executeUpdate(String sql, String[] columnNames) throws SQLException { @Override public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { - if (needValidate(sql)) + if (isUpdateOperation(sql)) validateLocalization(); return statement.execute(sql, autoGeneratedKeys); } @Override public boolean execute(String sql, int[] columnIndexes) throws SQLException { - if (needValidate(sql)) + if (isUpdateOperation(sql)) validateLocalization(); return statement.execute(sql, columnIndexes); } @Override public boolean execute(String sql, String[] columnNames) throws SQLException { - if (needValidate(sql)) + if (isUpdateOperation(sql)) validateLocalization(); return statement.execute(sql, columnNames); } @@ -295,20 +322,26 @@ public long executeLargeUpdate(String sql, String[] columnNames) throws SQLExcep @Override public T unwrap(Class iface) throws SQLException { - return statement.unwrap(iface); + try { + return iface.cast(this); + } catch (ClassCastException e) { + return statement.unwrap(iface); + } } @Override public boolean isWrapperFor(Class iface) throws SQLException { + if (iface.isInstance(this)) + return true; return statement.isWrapperFor(iface); } - protected boolean needValidate(String sql) { - return needValidate() && !SqlUtils.isReadOperation(sql); + protected boolean isUpdateOperation(String sql) { + return !isCallableStatement() && !SqlUtils.isReadOperation(sql); } - protected boolean needValidate() { - return !(this instanceof CallableStatement); + protected boolean isCallableStatement() { + return this instanceof CallableStatement; } } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/RefreshableDataSource.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/RefreshableDataSource.java index fe2b2dcff..ae7e528e3 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/RefreshableDataSource.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/RefreshableDataSource.java @@ -6,6 +6,7 @@ import java.sql.SQLFeatureNotSupportedException; import java.util.Map; import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.LockSupport; import javax.sql.DataSource; @@ -42,8 +43,9 @@ public class RefreshableDataSource implements DataSource, ClosableDataSource, Si private DataSourceIdentity id; private long switchListenerTimeout = DEFAULT_SWITCH_LISTENER_TIME_OUT; //ms - private volatile long firstAppearContinuousErrorTime = 0; - private volatile long lastReportContinuousErrorTime = 0; + private final AtomicLong firstAppearContinuousErrorTimeAtom = new AtomicLong(0); + private final AtomicLong continuousErrorCountAtom = new AtomicLong(0); + private final AtomicLong lastReportContinuousErrorTimeAtom = new AtomicLong(0); private int switchVersion = 0; @@ -61,8 +63,8 @@ public class RefreshableDataSource implements DataSource, ClosableDataSource, Si private static final String LISTENER_TIME_OUT = "SwitchListenerTimeout:%s"; private static final String BLOCK_CONNECTION = "Connection::blockConnection:%s"; private static final String THREAD_NAME = "DataSourceRefresher"; - public static final int CONTINUOUS_ERROR_DURATION_THRESHOLD = 60; //second - public static final int CONTINUOUS_ERROR_REPORT_PERIOD = 30; //second + public static final int CONTINUOUS_ERROR_DURATION_THRESHOLD = 60 * 1000; // ms + public static final int CONTINUOUS_ERROR_REPORT_PERIOD = 30 * 1000; // ms public RefreshableDataSource(String name, DataSourceConfigure config) { this.id = new DataSourceName(name); @@ -124,33 +126,38 @@ public void run() { }, INIT_DELAY, TimeUnit.MILLISECONDS); } - public void handleException(SQLException e){ + public void handleException(SQLException e, boolean isUpdateOperation) { if (e != null) { long nowTime = System.currentTimeMillis(); - if (firstAppearContinuousErrorTime == 0) { - firstAppearContinuousErrorTime = nowTime; + long firstAppear; + long continuousErrorCount; + synchronized (firstAppearContinuousErrorTimeAtom) { + firstAppear = firstAppearContinuousErrorTimeAtom.get(); + firstAppearContinuousErrorTimeAtom.compareAndSet(0, nowTime); + continuousErrorCount = continuousErrorCountAtom.incrementAndGet(); } - else { - long duration = nowTime - firstAppearContinuousErrorTime; - if (duration > CONTINUOUS_ERROR_DURATION_THRESHOLD * 1000) { - if (isNeedToReport(nowTime)) { - LOGGER.reportError(id.getId()); - } - } + if (firstAppear > 0 && nowTime - firstAppear >= CONTINUOUS_ERROR_DURATION_THRESHOLD && + needToReport(nowTime, continuousErrorCount)) { + LOGGER.reportError(id.getId()); + } + } else if (isUpdateOperation) { + synchronized (firstAppearContinuousErrorTimeAtom) { + continuousErrorCountAtom.set(0); + firstAppearContinuousErrorTimeAtom.set(0); } - } - else { - firstAppearContinuousErrorTime = 0; - lastReportContinuousErrorTime = 0; } } - private synchronized boolean isNeedToReport(long nowTime) { - if (lastReportContinuousErrorTime == 0 || nowTime - lastReportContinuousErrorTime > CONTINUOUS_ERROR_REPORT_PERIOD * 1000) { - lastReportContinuousErrorTime = nowTime; - return true; + private boolean needToReport(long nowTime, long continuousErrorCount) { + synchronized (lastReportContinuousErrorTimeAtom) { + long lastReport = lastReportContinuousErrorTimeAtom.get(); + if ((lastReport == 0 || nowTime - lastReport >= CONTINUOUS_ERROR_REPORT_PERIOD) && + continuousErrorCount >= 3) { + lastReportContinuousErrorTimeAtom.set(nowTime); + return true; + } + return false; } - return false; } @Override @@ -370,11 +377,15 @@ public void run() { } public long getFirstAppearContinuousErrorTime() { - return firstAppearContinuousErrorTime; + return firstAppearContinuousErrorTimeAtom.get(); } public long getLastReportContinuousErrorTime() { - return lastReportContinuousErrorTime; + return lastReportContinuousErrorTimeAtom.get(); + } + + public long getContinuousErrorCount() { + return continuousErrorCountAtom.get(); } @Override diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ValidationResult.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ValidationResult.java new file mode 100644 index 000000000..b8dbb072c --- /dev/null +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/ValidationResult.java @@ -0,0 +1,30 @@ +package com.ctrip.platform.dal.dao.datasource; + +/** + * @author c7ch23en + */ +public class ValidationResult { + + private final boolean result; + private final String ucsMessage; + private final String dalMessage; + + public ValidationResult(boolean result, String ucsMessage, String dalMessage) { + this.result = result; + this.ucsMessage = ucsMessage; + this.dalMessage = dalMessage; + } + + public boolean getValidationResult() { + return result; + } + + public String getUcsValidationMessage() { + return ucsMessage; + } + + public String getDalValidationMessage() { + return dalMessage; + } + +} diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalCallableStatement.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalCallableStatement.java index 81bc69290..d8a999f24 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalCallableStatement.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalCallableStatement.java @@ -12,8 +12,8 @@ public class DalCallableStatement extends DalPreparedStatement implements Callab private CallableStatement callableStatement; - public DalCallableStatement(CallableStatement callableStatement, DalConnection connection) { - super(callableStatement, connection); + public DalCallableStatement(CallableStatement callableStatement, DalConnection connection, String sql) { + super(callableStatement, connection, sql); this.callableStatement = callableStatement; } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalConnection.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalConnection.java index ffa0f0560..b0b901d03 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalConnection.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalConnection.java @@ -3,7 +3,6 @@ import com.ctrip.platform.dal.common.enums.DatabaseCategory; import com.ctrip.platform.dal.dao.datasource.ClusterDataSourceIdentity; import com.ctrip.platform.dal.dao.datasource.DataSourceIdentity; -import com.ctrip.platform.dal.dao.datasource.LocalizedDatabaseMetaDataImpl; import com.ctrip.platform.dal.dao.datasource.RefreshableDataSource; import com.ctrip.platform.dal.dao.helper.DalElementFactory; import com.ctrip.platform.dal.dao.helper.LoggerHelper; @@ -13,18 +12,17 @@ import org.apache.tomcat.jdbc.pool.PooledConnection; import java.sql.*; -import java.util.LinkedList; -import java.util.List; import java.util.Map; import java.util.Properties; import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicReference; public class DalConnection implements Connection { private static ILogger LOGGER = DalElementFactory.DEFAULT.getILogger(); private Connection connection; - private List discardCauses = new LinkedList<>(); + private final AtomicReference discardCauseRef = new AtomicReference<>(); private RefreshableDataSource dataSource; public DalConnection(Connection connection, RefreshableDataSource dataSource) { @@ -36,21 +34,7 @@ public Connection getConnection() { return connection; } - public void handleException(SQLException e) { - try { - if (isSpecificException(e)) - discardCauses.add(e); - } catch (Throwable t) { - LOGGER.warn("connection handleException exception", t); - } - try { - dataSource.handleException(e); - } catch (Throwable t) { - LOGGER.warn("dataSource handleException exception", t); - } - } - - private boolean isSpecificException(Throwable t) { + private boolean isDiscardException(Throwable t) { Throwable t1 = t; while (t1 instanceof DalException) { t1 = t1.getCause(); @@ -64,7 +48,7 @@ private boolean isSpecificException(Throwable t) { SQLException se = (SQLException) t1; if (dbCategory.isSpecificException(se)) return true; - return isSpecificException(se.getNextException()); + return isDiscardException(se.getNextException()); } @Override @@ -74,12 +58,12 @@ public Statement createStatement() throws SQLException { @Override public PreparedStatement prepareStatement(String sql) throws SQLException { - return new DalPreparedStatement(connection.prepareStatement(sql), this); + return new DalPreparedStatement(connection.prepareStatement(sql), this, sql); } @Override public CallableStatement prepareCall(String sql) throws SQLException { - return new DalCallableStatement(connection.prepareCall(sql), this); + return new DalCallableStatement(connection.prepareCall(sql), this, sql); } @Override @@ -99,41 +83,42 @@ public boolean getAutoCommit() throws SQLException { @Override public void commit() throws SQLException { - connection.commit(); + innerExecute(() -> connection.commit()); } @Override public void rollback() throws SQLException { - connection.rollback(); + innerExecute(() -> connection.rollback()); } @Override public void close() throws SQLException { - if (discardCauses.size() > 0) { + SQLException discardCause = discardCauseRef.get(); + if (discardCause != null) { try { - markDiscard(); + markDiscard(discardCause); } catch (Throwable t) { LOGGER.warn("mark connection discarded exception", t); } finally { - discardCauses.clear(); + discardCauseRef.set(null); } } connection.close(); } - private void markDiscard() throws SQLException { + private void markDiscard(SQLException cause) throws SQLException { long startTime = System.currentTimeMillis(); PooledConnection conn = connection.unwrap(PooledConnection.class); conn.setDiscarded(true); String connUrl = conn.getPoolProperties().getUrl(); String logName = String.format("Connection::discardConnection:%s", LoggerHelper.getSimplifiedDBUrl(connUrl)); LOGGER.logTransaction(DalLogTypes.DAL_DATASOURCE, logName, connUrl, startTime); - LOGGER.info(String.format("connection marked discarded: %s", connUrl)); + LOGGER.warn(String.format("connection marked discarded: %s", connUrl), cause); } @Override public boolean isClosed() throws SQLException { - return connection.isClosed(); + return innerExecute(() -> connection.isClosed()); } @Override @@ -194,12 +179,12 @@ public Statement createStatement(int resultSetType, int resultSetConcurrency) th @Override public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { - return new DalPreparedStatement(connection.prepareStatement(sql, resultSetType, resultSetConcurrency), this); + return new DalPreparedStatement(connection.prepareStatement(sql, resultSetType, resultSetConcurrency), this, sql); } @Override public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { - return new DalCallableStatement(connection.prepareCall(sql, resultSetType, resultSetConcurrency), this); + return new DalCallableStatement(connection.prepareCall(sql, resultSetType, resultSetConcurrency), this, sql); } @Override @@ -234,7 +219,7 @@ public Savepoint setSavepoint(String name) throws SQLException { @Override public void rollback(Savepoint savepoint) throws SQLException { - connection.rollback(); + innerExecute(() -> connection.rollback(savepoint)); } @Override @@ -249,27 +234,27 @@ public Statement createStatement(int resultSetType, int resultSetConcurrency, in @Override public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { - return new DalPreparedStatement(connection.prepareStatement(sql, resultSetType, resultSetConcurrency), this); + return new DalPreparedStatement(connection.prepareStatement(sql, resultSetType, resultSetConcurrency), this, sql); } @Override public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { - return new DalCallableStatement(connection.prepareCall(sql, resultSetType, resultSetHoldability), this); + return new DalCallableStatement(connection.prepareCall(sql, resultSetType, resultSetHoldability), this, sql); } @Override public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { - return new DalPreparedStatement(connection.prepareStatement(sql, autoGeneratedKeys), this); + return new DalPreparedStatement(connection.prepareStatement(sql, autoGeneratedKeys), this, sql); } @Override public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { - return new DalPreparedStatement(connection.prepareStatement(sql, columnIndexes), this); + return new DalPreparedStatement(connection.prepareStatement(sql, columnIndexes), this, sql); } @Override public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { - return new DalPreparedStatement(connection.prepareStatement(sql, columnNames), this); + return new DalPreparedStatement(connection.prepareStatement(sql, columnNames), this, sql); } @Override @@ -294,7 +279,7 @@ public SQLXML createSQLXML() throws SQLException { @Override public boolean isValid(int timeout) throws SQLException { - return connection.isValid(timeout); + return innerExecute(() -> connection.isValid(timeout)); } @Override @@ -339,7 +324,7 @@ public String getSchema() throws SQLException { @Override public void abort(Executor executor) throws SQLException { - connection.abort(executor); + innerExecute(() -> connection.abort(executor)); } @Override @@ -362,4 +347,71 @@ public boolean isWrapperFor(Class iface) throws SQLException { return connection.isWrapperFor(iface); } + protected void innerExecute(SqlRunnable task) throws SQLException { + SQLException error = null; + try { + task.run(); + } catch (SQLException e) { + error = e; + throw e; + } finally { + handleExceptionForConnection(error); + } + } + + protected void innerExecute(SqlRunnable task, boolean isUpdateOperation) throws SQLException { + SQLException error = null; + try { + task.run(); + } catch (SQLException e) { + error = e; + throw e; + } finally { + handleExceptionForConnection(error); + handleExceptionForDataSource(error, isUpdateOperation); + } + } + + protected T innerExecute(SqlCallable task) throws SQLException { + SQLException error = null; + try { + return task.call(); + } catch (SQLException e) { + error = e; + throw e; + } finally { + handleExceptionForConnection(error); + } + } + + protected T innerExecute(SqlCallable task, boolean isUpdateOperation) throws SQLException { + SQLException error = null; + try { + return task.call(); + } catch (SQLException e) { + error = e; + throw e; + } finally { + handleExceptionForConnection(error); + handleExceptionForDataSource(error, isUpdateOperation); + } + } + + private void handleExceptionForConnection(SQLException e) { + try { + if (isDiscardException(e)) + discardCauseRef.set(e); + } catch (Throwable t) { + LOGGER.warn("DalConnection handleException exception", t); + } + } + + private void handleExceptionForDataSource(SQLException e, boolean isUpdateOperation) { + try { + dataSource.handleException(e, isUpdateOperation); + } catch (Throwable t) { + LOGGER.warn("RefreshableDataSource handleException exception", t); + } + } + } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalPreparedStatement.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalPreparedStatement.java index c4b05e9dc..74cbeda69 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalPreparedStatement.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalPreparedStatement.java @@ -1,5 +1,7 @@ package com.ctrip.platform.dal.dao.datasource.jdbc; +import com.ctrip.platform.dal.dao.helper.SqlUtils; + import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; @@ -10,10 +12,12 @@ public class DalPreparedStatement extends DalStatement implements PreparedStatement { private PreparedStatement preparedStatement; + private char firstAlphaCharUc = 0; - public DalPreparedStatement(PreparedStatement preparedStatement, DalConnection connection) { + public DalPreparedStatement(PreparedStatement preparedStatement, DalConnection connection, String sql) { super(preparedStatement, connection); this.preparedStatement = preparedStatement; + this.firstAlphaCharUc = SqlUtils.firstAlphaCharUc(sql); } public PreparedStatement getPreparedStatement() { @@ -22,12 +26,12 @@ public PreparedStatement getPreparedStatement() { @Override public ResultSet executeQuery() throws SQLException { - return innerExecute(() -> preparedStatement.executeQuery()); + return innerExecute(() -> preparedStatement.executeQuery(), false); } @Override public int executeUpdate() throws SQLException { - return innerExecute(() -> preparedStatement.executeUpdate()); + return innerExecute(() -> preparedStatement.executeUpdate(), true); } @Override @@ -132,7 +136,7 @@ public void setObject(int parameterIndex, Object x) throws SQLException { @Override public boolean execute() throws SQLException { - return innerExecute(() -> preparedStatement.execute()); + return innerExecute(() -> preparedStatement.execute(), isUpdateOperation()); } @Override @@ -307,7 +311,11 @@ public void setObject(int parameterIndex, Object x, SQLType targetSqlType) throw @Override public long executeLargeUpdate() throws SQLException { - return innerExecute(() -> preparedStatement.executeLargeUpdate()); + return innerExecute(() -> preparedStatement.executeLargeUpdate(), true); + } + + protected boolean isUpdateOperation() { + return !isCallableStatement() && !SqlUtils.isReadOperation(firstAlphaCharUc); } } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalStatement.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalStatement.java index f198f27a8..07edfecc1 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalStatement.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalStatement.java @@ -1,9 +1,8 @@ package com.ctrip.platform.dal.dao.datasource.jdbc; -import com.ctrip.platform.dal.exceptions.DalException; +import com.ctrip.platform.dal.dao.helper.SqlUtils; import java.sql.*; -import java.util.concurrent.Callable; public class DalStatement implements Statement { @@ -21,17 +20,17 @@ public Statement getStatement() { @Override public ResultSet executeQuery(String sql) throws SQLException { - return innerExecute(() -> statement.executeQuery(sql)); + return innerExecute(() -> statement.executeQuery(sql), false); } @Override public int executeUpdate(String sql) throws SQLException { - return innerExecute(() -> statement.executeUpdate(sql)); + return innerExecute(() -> statement.executeUpdate(sql), true); } @Override public void close() throws SQLException { - statement.close(); + innerExecute(() -> statement.close()); } @Override @@ -71,7 +70,7 @@ public void setQueryTimeout(int seconds) throws SQLException { @Override public void cancel() throws SQLException { - statement.cancel(); + innerExecute(() -> statement.cancel()); } @Override @@ -91,7 +90,7 @@ public void setCursorName(String name) throws SQLException { @Override public boolean execute(String sql) throws SQLException { - return innerExecute(() -> statement.execute(sql)); + return innerExecute(() -> statement.execute(sql), isUpdateOperation(sql)); } @Override @@ -106,7 +105,7 @@ public int getUpdateCount() throws SQLException { @Override public boolean getMoreResults() throws SQLException { - return statement.getMoreResults(); + return innerExecute(() -> statement.getMoreResults()); } @Override @@ -151,7 +150,7 @@ public void clearBatch() throws SQLException { @Override public int[] executeBatch() throws SQLException { - return innerExecute(() -> statement.executeBatch()); + return innerExecute(() -> statement.executeBatch(), true); } @Override @@ -161,42 +160,42 @@ public Connection getConnection() throws SQLException { @Override public boolean getMoreResults(int current) throws SQLException { - return statement.getMoreResults(); + return innerExecute(() -> statement.getMoreResults(current)); } @Override public ResultSet getGeneratedKeys() throws SQLException { - return statement.getGeneratedKeys(); + return innerExecute(() -> statement.getGeneratedKeys()); } @Override public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { - return innerExecute(() -> statement.executeUpdate(sql, autoGeneratedKeys)); + return innerExecute(() -> statement.executeUpdate(sql, autoGeneratedKeys), true); } @Override public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { - return innerExecute(() -> statement.executeUpdate(sql, columnIndexes)); + return innerExecute(() -> statement.executeUpdate(sql, columnIndexes), true); } @Override public int executeUpdate(String sql, String[] columnNames) throws SQLException { - return innerExecute(() -> statement.executeUpdate(sql, columnNames)); + return innerExecute(() -> statement.executeUpdate(sql, columnNames), true); } @Override public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { - return innerExecute(() -> statement.execute(sql, autoGeneratedKeys)); + return innerExecute(() -> statement.execute(sql, autoGeneratedKeys), isUpdateOperation(sql)); } @Override public boolean execute(String sql, int[] columnIndexes) throws SQLException { - return innerExecute(() -> statement.execute(sql, columnIndexes)); + return innerExecute(() -> statement.execute(sql, columnIndexes), isUpdateOperation(sql)); } @Override public boolean execute(String sql, String[] columnNames) throws SQLException { - return innerExecute(() -> statement.execute(sql, columnNames)); + return innerExecute(() -> statement.execute(sql, columnNames), isUpdateOperation(sql)); } @Override @@ -206,7 +205,7 @@ public int getResultSetHoldability() throws SQLException { @Override public boolean isClosed() throws SQLException { - return statement.isClosed(); + return innerExecute(() -> statement.isClosed()); } @Override @@ -246,27 +245,27 @@ public long getLargeMaxRows() throws SQLException { @Override public long[] executeLargeBatch() throws SQLException { - return innerExecute(() -> statement.executeLargeBatch()); + return innerExecute(() -> statement.executeLargeBatch(), true); } @Override public long executeLargeUpdate(String sql) throws SQLException { - return innerExecute(() -> statement.executeLargeUpdate(sql)); + return innerExecute(() -> statement.executeLargeUpdate(sql), true); } @Override public long executeLargeUpdate(String sql, int autoGeneratedKeys) throws SQLException { - return innerExecute(() -> statement.executeLargeUpdate(sql, autoGeneratedKeys)); + return innerExecute(() -> statement.executeLargeUpdate(sql, autoGeneratedKeys), true); } @Override public long executeLargeUpdate(String sql, int[] columnIndexes) throws SQLException { - return innerExecute(() -> statement.executeLargeUpdate(sql, columnIndexes)); + return innerExecute(() -> statement.executeLargeUpdate(sql, columnIndexes), true); } @Override public long executeLargeUpdate(String sql, String[] columnNames) throws SQLException { - return innerExecute(() -> statement.executeLargeUpdate(sql, columnNames)); + return innerExecute(() -> statement.executeLargeUpdate(sql, columnNames), true); } @Override @@ -279,18 +278,28 @@ public boolean isWrapperFor(Class iface) throws SQLException { return statement.isWrapperFor(iface); } - protected T innerExecute(Callable task) throws SQLException { - SQLException exception = null; - try { - return task.call(); - } catch (SQLException e) { - exception = e; - throw e; - } catch (Exception ex) { - throw new DalException("innerExecute exception", ex); - } finally { - connection.handleException(exception); - } + protected void innerExecute(SqlRunnable task) throws SQLException { + connection.innerExecute(task); + } + + protected void innerExecute(SqlRunnable task, boolean isUpdateOperation) throws SQLException { + connection.innerExecute(task, isUpdateOperation); + } + + protected T innerExecute(SqlCallable task) throws SQLException { + return connection.innerExecute(task); + } + + protected T innerExecute(SqlCallable task, boolean isUpdateOperation) throws SQLException { + return connection.innerExecute(task, isUpdateOperation); + } + + protected boolean isUpdateOperation(String sql) { + return !isCallableStatement() && !SqlUtils.isReadOperation(sql); + } + + protected boolean isCallableStatement() { + return this instanceof CallableStatement; } } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/SqlCallable.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/SqlCallable.java new file mode 100644 index 000000000..0ac7d3e9d --- /dev/null +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/SqlCallable.java @@ -0,0 +1,12 @@ +package com.ctrip.platform.dal.dao.datasource.jdbc; + +import java.sql.SQLException; + +/** + * @author c7ch23en + */ +public interface SqlCallable { + + T call() throws SQLException; + +} diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/SqlRunnable.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/SqlRunnable.java new file mode 100644 index 000000000..d8b394f36 --- /dev/null +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/jdbc/SqlRunnable.java @@ -0,0 +1,12 @@ +package com.ctrip.platform.dal.dao.datasource.jdbc; + +import java.sql.SQLException; + +/** + * @author c7ch23en + */ +public interface SqlRunnable { + + void run() throws SQLException; + +} diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/tomcat/DalConnectionPool.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/tomcat/DalConnectionPool.java index 36052be0b..eb0a71c53 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/tomcat/DalConnectionPool.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/datasource/tomcat/DalConnectionPool.java @@ -3,6 +3,7 @@ import com.ctrip.platform.dal.common.enums.DatabaseCategory; import com.ctrip.platform.dal.dao.configure.DalExtendedPoolConfiguration; import com.ctrip.platform.dal.dao.datasource.ConnectionListener; +import com.ctrip.platform.dal.dao.datasource.DataSourceIdentity; import com.ctrip.platform.dal.dao.helper.DalElementFactory; import com.ctrip.platform.dal.dao.helper.LoggerHelper; import com.ctrip.platform.dal.dao.helper.ServiceLoaderHelper; @@ -35,9 +36,9 @@ public Connection getConnection() throws SQLException { @Override protected PooledConnection borrowConnection(long now, PooledConnection con, String username, String password) throws SQLException { try { - long waitTime = System.currentTimeMillis() - poolWaitTime.get().longValue(); + long waitTime = System.currentTimeMillis() - poolWaitTime.get(); if (waitTime > 1) { - connectionListener.onWaitConnection(getName(), getConnection(con), poolWaitTime.get().longValue()); + connectionListener.onWaitConnection(getName(), getConnection(con), poolWaitTime.get()); } } catch (Exception e) { logger.error("[borrowConnection]" + this, e); @@ -53,16 +54,20 @@ protected PooledConnection createConnection(long now, PooledConnection notUsed, long startTime = System.currentTimeMillis(); PooledConnection pooledConnection; + PoolConfiguration poolConfig = getPoolProperties(); + DataSourceIdentity dataSourceId = poolConfig instanceof DalExtendedPoolConfiguration ? + ((DalExtendedPoolConfiguration) poolConfig).getDataSourceId() : null; + try { pooledConnection = super.createConnection(now, notUsed, username, password); } catch (Throwable e) { String connectionUrl = LoggerHelper.getSimplifiedDBUrl(getPoolProperties().getUrl()); - connectionListener.onCreateConnectionFailed(getName(), connectionUrl, e, startTime); + connectionListener.onCreateConnectionFailed(getName(), connectionUrl, dataSourceId, e, startTime); throw e; } try { - connectionListener.onCreateConnection(getName(), getConnection(pooledConnection), startTime); + connectionListener.onCreateConnection(getName(), getConnection(pooledConnection), dataSourceId, startTime); } catch (Throwable e) { logger.error("[createConnection]" + this, e); } @@ -106,44 +111,44 @@ private Connection getConnection(PooledConnection con) { private void preHandleConnection(PooledConnection conn) { Connection connection = getConnection(conn); if (connection != null) { - trySetServerWaitTimeout(connection); + trySetSessionWaitTimeout(connection); } } - private void trySetServerWaitTimeout(Connection conn) { + private void trySetSessionWaitTimeout(Connection conn) { PoolConfiguration config = getPoolProperties(); if (config instanceof DalExtendedPoolConfiguration && DatabaseCategory.MySql == DatabaseCategory.matchWithConnectionUrl(config.getUrl())) { - int serverWaitTimeout = ((DalExtendedPoolConfiguration) config).getServerWaitTimeout(); - if (serverWaitTimeout > 0) { + int sessionWaitTimeout = ((DalExtendedPoolConfiguration) config).getSessionWaitTimeout(); + if (sessionWaitTimeout > 0) { String connUrl = LoggerHelper.getSimplifiedDBUrl(config.getUrl()); - String logName = String.format("Connection::setServerWaitTimeout:%s", connUrl); + String logName = String.format("Connection::setSessionWaitTimeout:%s", connUrl); try { logger.logTransaction(DalLogTypes.DAL_DATASOURCE, logName, - String.format("serverWaitTimeout: %ds, connectionUrl: %s", serverWaitTimeout, connUrl), - () -> setServerWaitTimeout(conn, serverWaitTimeout)); + String.format("sessionWaitTimeout: %ds, connectionUrl: %s", sessionWaitTimeout, connUrl), + () -> setSessionWaitTimeout(conn, sessionWaitTimeout)); } catch (Throwable t) { - logger.error("set serverWaitTimeout exception: " + connUrl, t); + logger.error("set sessionWaitTimeout exception: " + connUrl, t); } } } } - private void setServerWaitTimeout(Connection conn, int serverWaitTimeout) throws SQLException { + private void setSessionWaitTimeout(Connection conn, int sessionWaitTimeout) throws SQLException { boolean autoCommit = conn.getAutoCommit(); try { conn.setAutoCommit(true); try (Statement statement = conn.createStatement()) { statement.setQueryTimeout(1); - statement.execute(String.format("set session wait_timeout = %d", serverWaitTimeout)); + statement.execute(String.format("set session wait_timeout = %d", sessionWaitTimeout)); try (ResultSet rs = statement.executeQuery("show session variables like 'wait_timeout'")) { - if (rs != null && rs.next() && serverWaitTimeout == rs.getInt(2)) - logger.info(String.format("set serverWaitTimeout to %ds succeeded: %s", - serverWaitTimeout, getName())); + if (rs != null && rs.next() && sessionWaitTimeout == rs.getInt(2)) + logger.info(String.format("set sessionWaitTimeout to %ds succeeded: %s", + sessionWaitTimeout, getName())); else - logger.warn("check serverWaitTimeout failed: " + getName()); + logger.warn("check sessionWaitTimeout failed: " + getName()); } catch (Throwable t) { - logger.warn("check serverWaitTimeout exception: " + getName(), t); + logger.warn("check sessionWaitTimeout exception: " + getName(), t); } } } finally { diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/DalElementFactory.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/DalElementFactory.java index f7a9df2eb..6c6e8a437 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/DalElementFactory.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/DalElementFactory.java @@ -20,4 +20,6 @@ public interface DalElementFactory extends Ordered { LocalizationValidatorFactory getLocalizationValidatorFactory(); + EnvUtils getEnvUtils(); + } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/DefaultDalElementFactory.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/DefaultDalElementFactory.java index 0cfdda4c9..09cc1fa81 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/DefaultDalElementFactory.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/DefaultDalElementFactory.java @@ -1,5 +1,6 @@ package com.ctrip.platform.dal.dao.helper; +import com.ctrip.framework.dal.cluster.client.util.ObjectHolder; import com.ctrip.platform.dal.dao.configure.dalproperties.DalPropertiesProvider; import com.ctrip.platform.dal.dao.configure.dalproperties.DefaultDalPropertiesProvider; import com.ctrip.platform.dal.dao.datasource.DatasourceBackgroundExecutor; @@ -33,6 +34,8 @@ public class DefaultDalElementFactory implements DalElementFactory { private final AtomicReference localizationValidatorFactoryRef = new AtomicReference<>(); + private final ObjectHolder envUtilsHolder = new ObjectHolder<>(); + @Override public ILogger getILogger() { if (iLogger == null) { @@ -101,6 +104,11 @@ public LocalizationValidatorFactory getLocalizationValidatorFactory() { return factory; } + @Override + public EnvUtils getEnvUtils() { + return envUtilsHolder.getOrCreate(NullEnvUtils::new); + } + @Override public int getOrder() { return LOWEST_PRECEDENCE; diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/EnvUtils.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/EnvUtils.java new file mode 100644 index 000000000..ef09d7b15 --- /dev/null +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/EnvUtils.java @@ -0,0 +1,16 @@ +package com.ctrip.platform.dal.dao.helper; + +/** + * @author c7ch23en + */ +public interface EnvUtils { + + String getEnv(); + + String getSubEnv(); + + String getZone(); + + String getIdc(); + +} diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/MySqlConnectionHelper.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/MySqlConnectionHelper.java index 4af434392..adffdd313 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/MySqlConnectionHelper.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/MySqlConnectionHelper.java @@ -7,7 +7,7 @@ public class MySqlConnectionHelper { private static final ILogger LOGGER = DalElementFactory.DEFAULT.getILogger(); private static final String PING_INTERNAL_EXCEPTION_MESSAGE = - "An error occurred while invoking pingInternal method of MySqlConnection."; + "An error occurred while invoking pingInternal method of MySqlConnection. Refer to http://conf.ctripcorp.com/pages/viewpage.action?pageId=231813020"; public static boolean isValid(MySQLConnection connection, int timeout) { return pingInternal(connection, timeout); @@ -18,11 +18,9 @@ private static boolean pingInternal(MySQLConnection connection, int timeout) { return false; try { - connection.pingInternal(false, timeout * 1000); + connection.pingInternal(false, timeout); } catch (Throwable e) { - DataSourceValidatorException exception = - new DataSourceValidatorException(PING_INTERNAL_EXCEPTION_MESSAGE, e); - LOGGER.warn(exception); + LOGGER.warn(new DataSourceValidatorException(PING_INTERNAL_EXCEPTION_MESSAGE, e)); return false; } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/NullEnvUtils.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/NullEnvUtils.java new file mode 100644 index 000000000..43b8ee529 --- /dev/null +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/NullEnvUtils.java @@ -0,0 +1,28 @@ +package com.ctrip.platform.dal.dao.helper; + +/** + * @author c7ch23en + */ +public class NullEnvUtils implements EnvUtils { + + @Override + public String getEnv() { + return null; + } + + @Override + public String getSubEnv() { + return null; + } + + @Override + public String getZone() { + return null; + } + + @Override + public String getIdc() { + return null; + } + +} diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/PoolPropertiesHelper.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/PoolPropertiesHelper.java index 28cc0ff12..70054c7df 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/PoolPropertiesHelper.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/helper/PoolPropertiesHelper.java @@ -35,8 +35,7 @@ public PoolProperties convert(DataSourceConfigure config) { properties.setTestOnReturn(config.getBooleanProperty(TESTONRETURN, DEFAULT_TESTONRETURN)); properties.setValidationQuery(config.getProperty(VALIDATIONQUERY, DEFAULT_VALIDATIONQUERY)); - properties.setValidationQueryTimeout( - config.getIntProperty(VALIDATIONQUERYTIMEOUT, DEFAULT_VALIDATIONQUERYTIMEOUT)); + properties.setValidationQueryTimeout(config.getValidationQueryTimeout()); properties.setValidationInterval(config.getLongProperty(VALIDATIONINTERVAL, DEFAULT_VALIDATIONINTERVAL)); properties.setTimeBetweenEvictionRunsMillis( @@ -70,7 +69,9 @@ public PoolProperties convert(DataSourceConfigure config) { properties.setJmxEnabled(DEFAULT_JMXENABLED); properties.setJdbcInterceptors(config.getProperty(JDBC_INTERCEPTORS, DEFAULT_JDBCINTERCEPTORS)); - properties.setServerWaitTimeout(config.getIntProperty(SERVER_WAIT_TIMEOUT, DEFAULT_SERVER_WAIT_TIMEOUT)); + properties.setSessionWaitTimeout(config.getSessionWaitTimeout()); + + properties.setDataSourceId(config.getDataSourceId()); return properties; } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/log/AbstractLogger.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/log/AbstractLogger.java index ac0738b96..0ab7330ad 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/log/AbstractLogger.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/log/AbstractLogger.java @@ -3,6 +3,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Map; + public abstract class AbstractLogger implements ILogger { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractLogger.class); @@ -41,6 +43,16 @@ public void logTransaction(String type, String name, String message, Throwable e error(String.format("Type:%s, Name:%s, Message:%s, StartTime:%s", type, name, message, startTime), exception); } + @Override + public void logTransaction(String type, String name, String message, Map properties, long startTime) { + logTransaction(type, name, message, startTime); + } + + @Override + public void logTransaction(String type, String name, String message, Map properties, Throwable exception, long startTime) { + logTransaction(type, name, message, exception, startTime); + } + @Override public void warn(final String msg) { try { diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/log/ILogger.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/log/ILogger.java index 4bc2cb6ed..363c6e238 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/log/ILogger.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/log/ILogger.java @@ -1,5 +1,8 @@ package com.ctrip.platform.dal.dao.log; +import java.util.Map; +import java.util.Properties; + public interface ILogger { void logEvent(String type, String name, String message); @@ -12,6 +15,10 @@ void logTransaction(String type, String name, String message, Callback callback, void logTransaction(String type, String name, String message, Throwable exception, long startTime); + void logTransaction(String type, String name, String message, Map properties, long startTime); + + void logTransaction(String type, String name, String message, Map properties, Throwable exception, long startTime); + void info(final String msg); void warn(final String msg); diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/log/LogUtils.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/log/LogUtils.java new file mode 100644 index 000000000..4d0a95d47 --- /dev/null +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/log/LogUtils.java @@ -0,0 +1,29 @@ +package com.ctrip.platform.dal.dao.log; + +import com.ctrip.platform.dal.dao.datasource.DataSourceIdentity; +import com.ctrip.platform.dal.dao.datasource.IClusterDataSourceIdentity; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author c7ch23en + */ +public class LogUtils { + + public static Map buildPropertiesFromDataSourceId(DataSourceIdentity dataSourceId) { + if (dataSourceId instanceof IClusterDataSourceIdentity) { + IClusterDataSourceIdentity _dataSourceId = (IClusterDataSourceIdentity) dataSourceId; + Map properties = new HashMap<>(); + if (_dataSourceId.getClusterName() != null) + properties.put("DAL.cluster", _dataSourceId.getClusterName()); + if (_dataSourceId.getShardIndex() != null) + properties.put("DAL.cluster.shard", String.valueOf(_dataSourceId.getShardIndex())); + if (_dataSourceId.getDatabaseRole() != null) + properties.put("DAL.cluster.role", _dataSourceId.getDatabaseRole().getValue()); + return properties; + } + return null; + } + +} diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/log/SQLErrorInfo.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/log/SQLErrorInfo.java index 51fe4f25e..682fcae3f 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/log/SQLErrorInfo.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/log/SQLErrorInfo.java @@ -1,5 +1,7 @@ package com.ctrip.platform.dal.dao.log; +import com.ctrip.framework.dal.cluster.client.util.StringUtils; + import java.util.HashMap; import java.util.Map; @@ -13,9 +15,9 @@ public class SQLErrorInfo { private String database; - public SQLErrorInfo(String version, String titanKey) { + public SQLErrorInfo(String version, String dbKey) { this.version = version; - this.database = titanKey; + this.database = dbKey != null ? StringUtils.toTrimmedLowerCase(dbKey) : "Undefined"; } public String getVersion() { @@ -35,7 +37,7 @@ public void setDatabase(String database) { } public Map toTag() { - Map tag = new HashMap(); + Map tag = new HashMap<>(); tag.put(CLIENT, version); tag.put(DB, database); return tag; diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalBulkTaskRequest.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalBulkTaskRequest.java index e8bccb17b..26e7cc2d2 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalBulkTaskRequest.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalBulkTaskRequest.java @@ -87,6 +87,11 @@ private void prepareRequestContext() { } } + @Override + public String getLogicDbName() { + return logicDbName; + } + @Override public boolean isCrossShard() throws SQLException { if(isAlreadySharded(logicDbName, rawTableName, hints)) @@ -260,5 +265,10 @@ private K executeByTableShards() throws SQLException { public DalTaskContext getDalTaskContext() { return this.taskContext; } + + @Override + public String getPreparedDbShard() { + return shuffledDbShard != null ? shuffledDbShard : hints.getShardId(); + } } } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalRequest.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalRequest.java index 0b2a0a826..524fc0911 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalRequest.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalRequest.java @@ -23,6 +23,11 @@ public interface DalRequest { */ void validateAndPrepare() throws SQLException; + /** + * @return logic database name + */ + String getLogicDbName(); + /** * @return true if it is cross shard */ diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalRequestCallable.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalRequestCallable.java new file mode 100644 index 000000000..1c1be7da1 --- /dev/null +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalRequestCallable.java @@ -0,0 +1,37 @@ +package com.ctrip.platform.dal.dao.task; + +import java.util.concurrent.Callable; + +/** + * @author c7ch23en + */ +public class DalRequestCallable implements Callable { + + private final String logicDbName; + private final String shard; + private final Callable task; + + public DalRequestCallable(String logicDbName, String shard, Callable task) { + this.logicDbName = logicDbName; + this.shard = shard; + this.task = task; + } + + @Override + public V call() throws Exception { + return task.call(); + } + + public String getLogicDbName() { + return logicDbName; + } + + public String getShard() { + return shard; + } + + protected Callable getTask() { + return task; + } + +} diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalRequestExecutor.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalRequestExecutor.java index e1699eb93..d2f043e15 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalRequestExecutor.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalRequestExecutor.java @@ -12,10 +12,18 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; +import com.ctrip.framework.dal.cluster.client.util.StringUtils; import com.ctrip.platform.dal.dao.*; import com.ctrip.platform.dal.dao.client.DalLogger; import com.ctrip.platform.dal.dao.client.LogContext; import com.ctrip.platform.dal.dao.client.LogEntry; +import com.ctrip.platform.dal.dao.configure.DalConfigure; +import com.ctrip.platform.dal.dao.configure.DalThreadPoolExecutorConfig; +import com.ctrip.platform.dal.dao.configure.DalThreadPoolExecutorConfigBuilder; +import com.ctrip.platform.dal.dao.configure.DatabaseSet; +import com.ctrip.platform.dal.dao.helper.DalElementFactory; +import com.ctrip.platform.dal.dao.log.DalLogTypes; +import com.ctrip.platform.dal.dao.log.ILogger; import com.ctrip.platform.dal.exceptions.DalException; import com.ctrip.platform.dal.exceptions.ErrorCode; @@ -26,48 +34,106 @@ * @author jhhe */ public class DalRequestExecutor { + + private static final ILogger LOGGER = DalElementFactory.DEFAULT.getILogger(); + private static AtomicReference serviceRef = new AtomicReference<>(); - + public static final String MAX_POOL_SIZE = "maxPoolSize"; public static final String KEEP_ALIVE_TIME = "keepAliveTime"; + public static final String MAX_THREADS_PER_SHARD = "maxThreadsPerShard"; // To be consist with default connection max active size public static final int DEFAULT_MAX_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 2; - public static final int DEFAULT_KEEP_ALIVE_TIME = 10; + public static final int DEFAULT_MAX_THREADS_PER_SHARD = 0; private DalLogger logger = DalClientFactory.getDalLogger(); - - private final static String NA = "N/A"; - + public static void init(String maxPoolSizeStr, String keepAliveTimeStr){ if(serviceRef.get() != null) return; + + synchronized (DalRequestExecutor.class) { + if(serviceRef.get() != null) + return; + + int maxPoolSize = DEFAULT_MAX_POOL_SIZE; + if(maxPoolSizeStr != null) + maxPoolSize = Integer.parseInt(maxPoolSizeStr); + + int keepAliveTime = DEFAULT_KEEP_ALIVE_TIME; + if(keepAliveTimeStr != null) + keepAliveTime = Integer.parseInt(keepAliveTimeStr); + + ThreadPoolExecutor executer = new ThreadPoolExecutor(maxPoolSize, maxPoolSize, keepAliveTime, TimeUnit.SECONDS, new LinkedBlockingQueue(), new ThreadFactory() { + AtomicInteger atomic = new AtomicInteger(); + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "DalRequestExecutor-Worker-" + this.atomic.getAndIncrement()); + } + }); + executer.allowCoreThreadTimeOut(true); + + serviceRef.set(executer); + } + } + + public static void init(DalConfigure configure) { + if(serviceRef.get() != null) + return; synchronized (DalRequestExecutor.class) { if(serviceRef.get() != null) return; int maxPoolSize = DEFAULT_MAX_POOL_SIZE; - if(maxPoolSizeStr != null) + String maxPoolSizeStr = configure.getFactory().getProperty(MAX_POOL_SIZE); + if(!StringUtils.isEmpty(maxPoolSizeStr)) maxPoolSize = Integer.parseInt(maxPoolSizeStr); int keepAliveTime = DEFAULT_KEEP_ALIVE_TIME; - if(keepAliveTimeStr != null) + String keepAliveTimeStr = configure.getFactory().getProperty(KEEP_ALIVE_TIME); + if(!StringUtils.isEmpty(keepAliveTimeStr)) keepAliveTime = Integer.parseInt(keepAliveTimeStr); + + int maxThreadsPerShard = DEFAULT_MAX_THREADS_PER_SHARD; + String maxThreadsPerShardStr = configure.getFactory().getProperty(MAX_THREADS_PER_SHARD); + if(!StringUtils.isEmpty(maxThreadsPerShardStr)) { + maxThreadsPerShard = Integer.parseInt(maxThreadsPerShardStr); + LOGGER.logEvent(DalLogTypes.DAL_VALIDATION, + "MaxThreadsPerShard::Global:" + maxThreadsPerShard, ""); + } + + DalThreadPoolExecutorConfigBuilder builder = new DalThreadPoolExecutorConfigBuilder() + .setCorePoolSize(maxPoolSize) + .setMaxPoolSize(maxPoolSize) + .setKeepAliveSeconds(keepAliveTime) + .setMaxThreadsPerShard(maxThreadsPerShard); + + for (String dbSetName : configure.getDatabaseSetNames()) { + DatabaseSet dbSet = configure.getDatabaseSet(dbSetName); + Integer dbMaxThreadsPerShard = dbSet.getSettingAsInt(MAX_THREADS_PER_SHARD); + if (dbMaxThreadsPerShard != null) { + builder.setMaxThreadsPerShard(dbSetName, dbMaxThreadsPerShard); + LOGGER.logEvent(DalLogTypes.DAL_VALIDATION, + String.format("MaxThreadsPerShard::%s:%d", dbSetName, dbMaxThreadsPerShard), ""); + } + } - ThreadPoolExecutor executer = new ThreadPoolExecutor(maxPoolSize, maxPoolSize, keepAliveTime, TimeUnit.SECONDS, new LinkedBlockingQueue(), new ThreadFactory() { - AtomicInteger atomic = new AtomicInteger(); + ThreadPoolExecutor executor = new DalThreadPoolExecutor(builder.build(), + new LinkedBlockingQueue<>(), new ThreadFactory() { + final AtomicInteger atomic = new AtomicInteger(); @Override public Thread newThread(Runnable r) { return new Thread(r, "DalRequestExecutor-Worker-" + this.atomic.getAndIncrement()); } }); - executer.allowCoreThreadTimeOut(true); + executor.allowCoreThreadTimeOut(true); - serviceRef.set(executer); + serviceRef.set(executor); } - } + } public static void shutdown() { if (serviceRef.get() == null) @@ -145,8 +211,10 @@ private T internalExecute(DalHints hints, DalRequest request, boolean nul private T nonCrossShardExecute(LogContext logContext, DalHints hints, DalRequest request) throws Exception { logContext.setSingleTask(true); + String logicDbName = request.getLogicDbName(); TaskCallable task = request.createTask(); - Callable taskWrapper = new RequestTaskWrapper(NA, task, logContext); + String shard = task.getPreparedDbShard(); + Callable taskWrapper = new RequestTaskWrapper(logicDbName, shard, task, logContext); T result = taskWrapper.call(); logContext.setStatementExecuteTime(task.getDalTaskContext().getStatementExecuteTime()); @@ -162,6 +230,7 @@ private T crossShardExecute(LogContext logContext, DalHints hints, DalReques logContext.setSeqencialExecution(isSequentialExecution); ResultMerger merger = request.getMerger(); + String logicDbName = request.getLogicDbName(); logger.startCrossShardTasks(logContext, isSequentialExecution); @@ -170,8 +239,8 @@ private T crossShardExecute(LogContext logContext, DalHints hints, DalReques try { result = isSequentialExecution? - sequentialExecute(hints, tasks, merger, logContext, callback): - parallelExecute(hints, tasks, merger, logContext, callback); + sequentialExecute(hints, logicDbName, tasks, merger, logContext, callback): + parallelExecute(hints, logicDbName, tasks, merger, logContext, callback); } catch (Throwable e) { error = e; @@ -197,14 +266,15 @@ private void handleCallback(final DalHints hints, T result, Throwable error) qc.onError(error); } - private T parallelExecute(DalHints hints, Map> tasks, ResultMerger merger, + private T parallelExecute(DalHints hints, String logicDbName, Map> tasks, ResultMerger merger, LogContext logContext, ShardExecutionCallback callback) throws SQLException { Map> resultFutures = new HashMap<>(); List logEntries = new ArrayList<>(); long maxStatementExecuteTime = 0; for(final String shard: tasks.keySet()) - resultFutures.put(shard, serviceRef.get().submit(new RequestTaskWrapper(shard, tasks.get(shard), logContext))); + resultFutures.put(shard, serviceRef.get().submit(new RequestTaskWrapper(logicDbName, + shard, tasks.get(shard), logContext))); for(Map.Entry> entry: resultFutures.entrySet()) { String dbShard = entry.getKey(); @@ -230,7 +300,7 @@ private T parallelExecute(DalHints hints, Map> tasks return merger.merge(); } - private T sequentialExecute(DalHints hints, Map> tasks, ResultMerger merger, + private T sequentialExecute(DalHints hints, String logicDbName, Map> tasks, ResultMerger merger, LogContext logContext, ShardExecutionCallback callback) throws SQLException { long totalStatementExecuteTime = 0; List logEntries = new ArrayList<>(); @@ -238,7 +308,7 @@ private T sequentialExecute(DalHints hints, Map> tas Throwable error = null; ShardExecutionResult executionResult; try { - T partial = new RequestTaskWrapper(shard, tasks.get(shard), logContext).call(); + T partial = new RequestTaskWrapper(logicDbName, shard, tasks.get(shard), logContext).call(); merger.addPartial(shard, partial); // TODO: tableShard may be inaccurate executionResult = new ShardExecutionResultImpl<>(shard, null, partial); @@ -278,4 +348,9 @@ private List toList(LogEntry logEntry) { } return logEntries; } + + protected static ExecutorService getExecutor() { + return serviceRef.get(); + } + } \ No newline at end of file diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalRequestFutureTask.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalRequestFutureTask.java new file mode 100644 index 000000000..3b6f2a3d4 --- /dev/null +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalRequestFutureTask.java @@ -0,0 +1,81 @@ +package com.ctrip.platform.dal.dao.task; + +import com.ctrip.platform.dal.dao.helper.DalElementFactory; +import com.ctrip.platform.dal.dao.log.DalLogTypes; +import com.ctrip.platform.dal.dao.log.ILogger; + +import java.util.concurrent.FutureTask; + +/** + * @author c7ch23en + */ +public class DalRequestFutureTask extends FutureTask { + + private static final ILogger LOGGER = DalElementFactory.DEFAULT.getILogger(); + + private final String logicDbName; + private final String shard; + private final DalThreadPoolExecutor executor; + + private STATUS status; + + private volatile long lastLogLimitedTime = 0; + + public DalRequestFutureTask(DalRequestCallable callable, DalThreadPoolExecutor executor) { + super(callable); + this.logicDbName = callable.getLogicDbName(); + this.shard = callable.getShard(); + this.executor = executor; + status = STATUS.INITIALIZED; + } + + public String getLogicDbName() { + return logicDbName; + } + + public String getShard() { + return shard; + } + + @Override + public void run() { + executor.tryExecute(this); + } + + protected void internalRun() { + try { + status = STATUS.RUNNING; + super.run(); + } finally { + status = STATUS.DONE; + } + } + + protected void logLimited(int limit) { + try { + long now = System.currentTimeMillis(); + if (now - lastLogLimitedTime >= 1000) { + lastLogLimitedTime = now; + LOGGER.logEvent(DalLogTypes.DAL_VALIDATION, + String.format("ShardThreadsLimited::%s-%s", logicDbName, shard), + "maxThreadsPerShard=" + limit); + LOGGER.info(String.format("ShardThreadsLimited::%s-%s, maxThreadsPerShard=%d", + logicDbName, shard, limit)); + } + } catch (Throwable t) { + // ignore + } + } + + @Override + public boolean isDone() { + return status == STATUS.DONE && super.isDone(); + } + + enum STATUS { + INITIALIZED, + RUNNING, + DONE + } + +} diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalRequestThreadFactory.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalRequestThreadFactory.java new file mode 100644 index 000000000..dfcc62c00 --- /dev/null +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalRequestThreadFactory.java @@ -0,0 +1,15 @@ +package com.ctrip.platform.dal.dao.task; + +import java.util.concurrent.ThreadFactory; + +/** + * @author c7ch23en + */ +public class DalRequestThreadFactory implements ThreadFactory { + + @Override + public Thread newThread(Runnable r) { + return null; + } + +} diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalSingleTaskRequest.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalSingleTaskRequest.java index 4e536d851..269bda659 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalSingleTaskRequest.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalSingleTaskRequest.java @@ -106,6 +106,11 @@ private void prepareRequestContext() { } } + @Override + public String getLogicDbName() { + return logicDbName; + } + @Override public boolean isCrossShard() { // The single task request is always executed as if the pojos are not corss shard even they really are. @@ -178,5 +183,10 @@ public int[] call() throws Exception { public DalTaskContext getDalTaskContext() { return this.taskContext; } + + @Override + public String getPreparedDbShard() { + return hints.getShardId(); + } } } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalSqlTaskRequest.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalSqlTaskRequest.java index cfebf7c59..b24755304 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalSqlTaskRequest.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalSqlTaskRequest.java @@ -98,6 +98,11 @@ private void prepareRequestContext() { } } + @Override + public String getLogicDbName() { + return logicDbName; + } + @Override public boolean isCrossShard() { return (shards != null && shards.size() > 1); @@ -566,6 +571,11 @@ protected Set tableShards(){ public DalTaskContext getDalTaskContext() { return this.dalTaskContext; } + + @Override + public String getPreparedDbShard() { + return dbShard != null ? dbShard : hints.getShardId(); + } } } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalThreadPoolExecutor.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalThreadPoolExecutor.java new file mode 100644 index 000000000..4068cdc8f --- /dev/null +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/DalThreadPoolExecutor.java @@ -0,0 +1,134 @@ +package com.ctrip.platform.dal.dao.task; + +import com.ctrip.framework.dal.cluster.client.util.StringUtils; +import com.ctrip.platform.dal.dao.configure.DalThreadPoolExecutorConfig; +import com.ctrip.platform.dal.dao.helper.DalElementFactory; +import com.ctrip.platform.dal.dao.log.DalLogTypes; +import com.ctrip.platform.dal.dao.log.ILogger; + +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author c7ch23en + */ +public class DalThreadPoolExecutor extends ThreadPoolExecutor { + + private final DalThreadPoolExecutorConfig executorConfig; + private final Map runningTasks = new ConcurrentHashMap<>(); + + public DalThreadPoolExecutor(DalThreadPoolExecutorConfig executorConfig, + BlockingQueue workQueue) { + super(executorConfig.getCorePoolSize(), executorConfig.getMaxPoolSize(), + executorConfig.getKeepAliveSeconds(), TimeUnit.SECONDS, workQueue); + this.executorConfig = executorConfig; + } + + public DalThreadPoolExecutor(DalThreadPoolExecutorConfig executorConfig, + BlockingQueue workQueue, + ThreadFactory threadFactory) { + super(executorConfig.getCorePoolSize(), executorConfig.getMaxPoolSize(), + executorConfig.getKeepAliveSeconds(), TimeUnit.SECONDS, workQueue, threadFactory); + this.executorConfig = executorConfig; + } + + public DalThreadPoolExecutor(DalThreadPoolExecutorConfig executorConfig, + BlockingQueue workQueue, + RejectedExecutionHandler handler) { + super(executorConfig.getCorePoolSize(), executorConfig.getMaxPoolSize(), + executorConfig.getKeepAliveSeconds(), TimeUnit.SECONDS, workQueue, handler); + this.executorConfig = executorConfig; + } + + public DalThreadPoolExecutor(DalThreadPoolExecutorConfig executorConfig, + BlockingQueue workQueue, + ThreadFactory threadFactory, + RejectedExecutionHandler handler) { + super(executorConfig.getCorePoolSize(), executorConfig.getMaxPoolSize(), + executorConfig.getKeepAliveSeconds(), TimeUnit.SECONDS, workQueue, threadFactory, handler); + this.executorConfig = executorConfig; + } + + @Override + protected RunnableFuture newTaskFor(Callable callable) { + if (callable instanceof DalRequestCallable) + return new DalRequestFutureTask<>((DalRequestCallable) callable, this); + return super.newTaskFor(callable); + } + + public void tryExecute(DalRequestFutureTask task) { + String logicDbName = task.getLogicDbName(); + String shard = task.getShard(); + if (!StringUtils.isEmpty(logicDbName) && !StringUtils.isEmpty(shard)) { + DalRequestIdentity shardIdentity = new DalRequestIdentity(logicDbName, shard); + AtomicInteger shardTaskCount = runningTasks.get(shardIdentity); + if (shardTaskCount == null) { + synchronized (runningTasks) { + shardTaskCount = runningTasks.get(shardIdentity); + if (shardTaskCount == null) { + shardTaskCount = new AtomicInteger(0); + runningTasks.put(shardIdentity, shardTaskCount); + } + } + } + int maxThreadsPerShard = executorConfig.getMaxThreadsPerShard(logicDbName); + int incCount = shardTaskCount.incrementAndGet(); + if (incCount > maxThreadsPerShard && maxThreadsPerShard > 0) { + shardTaskCount.decrementAndGet(); + // retry execution, possibly put to the end of the taskQueue + task.logLimited(maxThreadsPerShard); + execute(task); + return; + } + else { + try { + // actual execution + task.internalRun(); + return; + } finally { + shardTaskCount.decrementAndGet(); + } + } + } + task.internalRun(); + } + + static class DalRequestIdentity { + private final String logicDbName; + private final String shard; + + public DalRequestIdentity(String logicDbName, String shard) { + this.logicDbName = logicDbName; + this.shard = shard; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + DalRequestIdentity that = (DalRequestIdentity) o; + return Objects.equals(logicDbName, that.logicDbName) && + Objects.equals(shard, that.shard); + } + + @Override + public int hashCode() { + return Objects.hash(logicDbName, shard); + } + + @Override + public String toString() { + return "DalRequestIdentity {" + + "logicDbName='" + logicDbName + '\'' + + ", shard='" + shard + '\'' + + '}'; + } + } + + protected DalThreadPoolExecutorConfig getExecutorConfig() { + return executorConfig; + } + +} diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/RequestTaskWrapper.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/RequestTaskWrapper.java index e27df4965..946b6642d 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/RequestTaskWrapper.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/RequestTaskWrapper.java @@ -8,15 +8,21 @@ import com.ctrip.platform.dal.dao.client.LogEntry; import com.ctrip.platform.dal.exceptions.DalException; -public class RequestTaskWrapper implements Callable { - private DalLogger logger = DalClientFactory.getDalLogger(); - private String shard; - private Callable task; - private LogContext logContext; - - public RequestTaskWrapper(String shard, Callable task, LogContext logContext) { - this.shard = shard; - this.task = task; +public class RequestTaskWrapper extends DalRequestCallable implements Callable { + private final static String UNKNOWN_SHARD = "N/A"; + private final DalLogger logger = DalClientFactory.getDalLogger(); + private final String shard; + private final LogContext logContext; + + public RequestTaskWrapper(Callable task, LogContext logContext) { + super(null, null, task); + this.shard = UNKNOWN_SHARD; + this.logContext = logContext; + } + + public RequestTaskWrapper(String logicDbName, String shard, Callable task, LogContext logContext) { + super(logicDbName, shard, task); + this.shard = shard != null ? shard : UNKNOWN_SHARD; this.logContext = logContext; } @@ -30,7 +36,7 @@ public T call() throws Exception { try { LogEntry.populateCurrentCaller(logContext.getCaller()); - result = task.call(); + result = getTask().call(); LogEntry.clearCurrentCaller(); } catch (Throwable e) { diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/TaskAdapter.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/TaskAdapter.java index 64ec78ecb..a8cb16ee9 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/TaskAdapter.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/TaskAdapter.java @@ -34,6 +34,8 @@ public class TaskAdapter extends BaseTaskAdapter implements DaoTask { protected static final String AND = " AND "; protected static final String OR = " OR "; protected static final String TMPL_CALL = "{call %s(%s)}"; + protected static final String SQLSERVER_TMPL_CALL = "exec %s %s"; + protected static final String SQLSERVER_TMPL_SET_VALUE = "@%s=?"; public static String findtmp = "SELECT * FROM %s WHERE %s"; @@ -236,20 +238,6 @@ public void addParametersByIndex(StatementParameters parameters, } } - /** - * According to DBA, call SP by parameter name will invoke sp_sproc_columns to get SP metadata, this is a - * very costly operation. To avoid the cost, it is required to call sp by parameter index instead of name - */ - public void addParametersByIndexNotNullField(StatementParameters parameters, - Map entries) { - int index = parameters.size() + 1; - for (Map.Entry entry : entries.entrySet()) { - if (entry.getValue() != null) { - addParameterByIndex(parameters, index++, entry.getKey(), entry.getValue()); - } - } - } - /** * According to DBA, call SP by parameter name will invoke sp_sproc_columns to get SP metadata, this is a * very costly operation. To avoid the cost, it is required to call sp by parameter index instead of name @@ -466,4 +454,16 @@ else if (tableShardingEnabled) this.shardingCategory = ShardingCategory.NoShard; } + protected String buildSqlServerCallSql(String spName, String[] columns) { + StringBuilder sb = new StringBuilder(); + int i = 0; + for (String value : columns) { + sb.append(String.format(SQLSERVER_TMPL_SET_VALUE, value)); + if (++i < columns.length) + sb.append(COLUMN_SEPARATOR); + } + + return String.format(SQLSERVER_TMPL_CALL, spName, sb.toString()); + } + } diff --git a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/TaskCallable.java b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/TaskCallable.java index 2f44d686c..cdf164647 100644 --- a/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/TaskCallable.java +++ b/dal-client/src/main/java/com/ctrip/platform/dal/dao/task/TaskCallable.java @@ -3,6 +3,9 @@ import java.util.concurrent.Callable; public interface TaskCallable extends Callable { + DalTaskContext getDalTaskContext(); + String getPreparedDbShard(); + } diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/AllTest.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/AllTest.java deleted file mode 100644 index a76725b7e..000000000 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/AllTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.ctrip.platform.dal.dao; - - -import com.ctrip.platform.dal.dao.helper.EntityManagerTest.EntityManagerTest; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -@RunWith(Suite.class) -@SuiteClasses({ - com.ctrip.platform.dal.dao.client.AllTest.class, - com.ctrip.platform.dal.dao.common.AllTest.class, - com.ctrip.platform.dal.dao.datasource.AllTests.class, - com.ctrip.platform.dal.dao.dialet.mysql.MySqlHelperTest.class, - com.ctrip.platform.dal.dao.helper.AllTests.class, - com.ctrip.platform.dal.dao.parser.AllTest.class, - com.ctrip.platform.dal.dao.shard.AllTest.class, - com.ctrip.platform.dal.dao.sqlbuilder.AllTests.class, - com.ctrip.platform.dal.dao.task.AllTest.class, - com.ctrip.platform.dal.dao.unittests.AllTest.class, - com.ctrip.platform.dal.dao.annotation.AllTest.class, - com.ctrip.platform.dal.dao.configure.AllTest.class, - com.ctrip.platform.dal.dao.sharding.idgen.AllTests.class, - EntityManagerTest.class, - /** - * IMPORTANT NOTE! markdown test must be the last one to avoid interfere other test - */ - com.ctrip.platform.dal.dao.markdown.AllTests.class, - -}) -public class AllTest {} \ No newline at end of file diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/AllTests.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/AllTests.java new file mode 100644 index 000000000..89620eca3 --- /dev/null +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/AllTests.java @@ -0,0 +1,32 @@ +package com.ctrip.platform.dal.dao; + + +import com.ctrip.platform.dal.dao.helper.EntityManagerTest.EntityManagerTest; +import com.ctrip.platform.dal.dao.task._AllTests; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +@RunWith(Suite.class) +@SuiteClasses({ + com.ctrip.platform.dal.dao.client._AllTests.class, + com.ctrip.platform.dal.dao.common._AllTests.class, + com.ctrip.platform.dal.dao.datasource._AllTests.class, + com.ctrip.platform.dal.dao.dialet.mysql.MySqlHelperTest.class, + com.ctrip.platform.dal.dao.helper._AllTests.class, + com.ctrip.platform.dal.dao.parser._AllTests.class, + com.ctrip.platform.dal.dao.shard._AllTests.class, + com.ctrip.platform.dal.dao.sqlbuilder._AllTests.class, + _AllTests.class, + com.ctrip.platform.dal.dao.unittests._AllTests.class, + com.ctrip.platform.dal.dao.annotation._AllTests.class, + com.ctrip.platform.dal.dao.configure._AllTests.class, + com.ctrip.platform.dal.dao.sharding.idgen._AllTests.class, + EntityManagerTest.class, + /** + * IMPORTANT NOTE! markdown test must be the last one to avoid interfere other test + */ + com.ctrip.platform.dal.dao.markdown._AllTests.class, + +}) +public class AllTests {} \ No newline at end of file diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/annotation/AllTest.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/annotation/_AllTests.java similarity index 95% rename from dal-client/src/test/java/com/ctrip/platform/dal/dao/annotation/AllTest.java rename to dal-client/src/test/java/com/ctrip/platform/dal/dao/annotation/_AllTests.java index 635ee5116..7418547ed 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/annotation/AllTest.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/annotation/_AllTests.java @@ -1,23 +1,23 @@ -package com.ctrip.platform.dal.dao.annotation; - -import com.ctrip.platform.dal.dao.annotation.autowire.DalTransactionalValidatorAutoWireTest; -import com.ctrip.platform.dal.dao.annotation.beanDefine.DalTransactionalValidatorTest; -import com.ctrip.platform.dal.dao.annotation.javaConfig.EnableTransactionAbnormalTest; -import com.ctrip.platform.dal.dao.annotation.javaConfig.EnableTransactionNormalTest; -import com.ctrip.platform.dal.dao.annotation.normal.BaseDalTransactionalAnnotationTest; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -@RunWith(Suite.class) -@SuiteClasses({ - DalTransactionalValidatorTest.class, - DalTransactionalValidatorAutoWireTest.class, - DalAnnotationValidatorTest.class, - - BaseDalTransactionalAnnotationTest.class, - EnableTransactionNormalTest.class, - EnableTransactionAbnormalTest.class -}) -public class AllTest { -} +package com.ctrip.platform.dal.dao.annotation; + +import com.ctrip.platform.dal.dao.annotation.autowire.DalTransactionalValidatorAutoWireTest; +import com.ctrip.platform.dal.dao.annotation.beanDefine.DalTransactionalValidatorTest; +import com.ctrip.platform.dal.dao.annotation.javaConfig.EnableTransactionAbnormalTest; +import com.ctrip.platform.dal.dao.annotation.javaConfig.EnableTransactionNormalTest; +import com.ctrip.platform.dal.dao.annotation.normal.BaseDalTransactionalAnnotationTest; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +@RunWith(Suite.class) +@SuiteClasses({ + DalTransactionalValidatorTest.class, + DalTransactionalValidatorAutoWireTest.class, + DalAnnotationValidatorTest.class, + + BaseDalTransactionalAnnotationTest.class, + EnableTransactionNormalTest.class, + EnableTransactionAbnormalTest.class +}) +public class _AllTests { +} diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/client/DalConfigureFactoryTest.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/client/DalConfigureFactoryTest.java index 58caab067..be595c84e 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/client/DalConfigureFactoryTest.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/client/DalConfigureFactoryTest.java @@ -1,11 +1,14 @@ package com.ctrip.platform.dal.dao.client; -import com.ctrip.platform.dal.dao.configure.ClusterDatabaseSet; -import com.ctrip.platform.dal.dao.configure.DalConfigure; -import com.ctrip.platform.dal.dao.configure.DalConfigureFactory; -import com.ctrip.platform.dal.dao.configure.DatabaseSet; +import com.ctrip.platform.dal.dao.configure.*; +import com.ctrip.platform.dal.dao.task.DalRequestExecutor; +import com.ctrip.platform.dal.dao.task.DalRequestExecutorUtils; +import com.ctrip.platform.dal.dao.task.DalThreadPoolExecutor; +import org.junit.Assert; import org.junit.Test; +import java.util.concurrent.ExecutorService; + import static org.junit.Assert.*; public class DalConfigureFactoryTest { @@ -49,4 +52,20 @@ public void testLoad() { } } +// @Test + public void testThreadPoolConfig() throws Exception { + DalRequestExecutor.shutdown(); + DalConfigure configure = DalConfigureFactory.load(Thread.currentThread().getContextClassLoader(). + getResource("dal-thread-pool-test.xml")); + DalRequestExecutor.init(configure); + ExecutorService executor = DalRequestExecutorUtils.getExecutor(); + Assert.assertTrue(executor instanceof DalThreadPoolExecutor); + DalThreadPoolExecutorConfig executorConfig = DalRequestExecutorUtils.getExecutorConfig((DalThreadPoolExecutor) executor); + Assert.assertEquals(5, executorConfig.getMaxThreadsPerShard("dao_test_mod_mysql")); + Assert.assertEquals(0, executorConfig.getMaxThreadsPerShard("clusterName1")); + Assert.assertEquals(0, executorConfig.getMaxThreadsPerShard("clusterName2")); + Assert.assertEquals(3, executorConfig.getMaxThreadsPerShard("DbSetName")); + DalRequestExecutor.shutdown(); + } + } diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/client/AllTest.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/client/_AllTests.java similarity index 96% rename from dal-client/src/test/java/com/ctrip/platform/dal/dao/client/AllTest.java rename to dal-client/src/test/java/com/ctrip/platform/dal/dao/client/_AllTests.java index 94c28f6cb..cede5f514 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/client/AllTest.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/client/_AllTests.java @@ -20,6 +20,6 @@ DalCommandRollbackOnlyTest.class, LogSamplingTest.class }) -public class AllTest { +public class _AllTests { } \ No newline at end of file diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/common/AllTest.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/common/_AllTests.java similarity index 88% rename from dal-client/src/test/java/com/ctrip/platform/dal/dao/common/AllTest.java rename to dal-client/src/test/java/com/ctrip/platform/dal/dao/common/_AllTests.java index 96d0bfb14..c72a72177 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/common/AllTest.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/common/_AllTests.java @@ -7,6 +7,6 @@ @Suite.SuiteClasses({ DatabaseCategoryTest.class }) -public class AllTest { +public class _AllTests { } \ No newline at end of file diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/configure/MockDataSourceConfigureProvider.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/configure/MockDataSourceConfigureProvider.java index 61da2c2ee..bbc4a273b 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/configure/MockDataSourceConfigureProvider.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/configure/MockDataSourceConfigureProvider.java @@ -4,8 +4,8 @@ public class MockDataSourceConfigureProvider implements IDataSourceConfigureProv @Override public IDataSourceConfigure getDataSourceConfigure() { -// connectionString="Server=10.32.20.143;port=3306;UID=root;password=!QAZ@WSX1qaz2wsx;database=llj_test;" - String connectionUrl = "jdbc:mysql://10.32.20.143:3306/llj_test?useUnicode=true&characterEncoding=UTF-8"; +// connectionString="Server=10.32.20.128;port=3306;UID=root;password=!QAZ@WSX1qaz2wsx;database=llj_test;" + String connectionUrl = "jdbc:mysql://10.32.20.128:3306/llj_test?useUnicode=true&characterEncoding=UTF-8"; String userName = "root"; String password = "!QAZ@WSX1qaz2wsx"; String driverClass = "com.mysql.jdbc.Driver"; diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/configure/AllTest.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/configure/_AllTests.java similarity index 93% rename from dal-client/src/test/java/com/ctrip/platform/dal/dao/configure/AllTest.java rename to dal-client/src/test/java/com/ctrip/platform/dal/dao/configure/_AllTests.java index c04fbe795..0018c4549 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/configure/AllTest.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/configure/_AllTests.java @@ -11,6 +11,6 @@ ClusterConfigParserTest.class, ClusterConfigValidatorTest.class }) -public class AllTest { +public class _AllTests { } diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/ForceSwitchableDataSourceTest.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/ForceSwitchableDataSourceTest.java index 113d1fb2f..f19361f16 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/ForceSwitchableDataSourceTest.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/ForceSwitchableDataSourceTest.java @@ -11,7 +11,7 @@ import static org.junit.Assert.*; public class ForceSwitchableDataSourceTest { - private final static String IPHOST = "10.32.20.143"; + private final static String IPHOST = "10.32.20.128"; private final static String DOMAINHOST = "dst56614"; private final static String INVALIDHOST = "1.1.1.1"; @@ -171,7 +171,7 @@ public void testConfigChangedAfterForceSwitch() throws Exception { Properties newProperties = new Properties(); newProperties.setProperty(USER_NAME, "root"); newProperties.setProperty(PASSWORD, "!QAZ@WSX1qaz2wsx"); - newProperties.setProperty(CONNECTION_URL, "jdbc:mysql://10.32.20.143:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;"); + newProperties.setProperty(CONNECTION_URL, "jdbc:mysql://10.32.20.128:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;"); newProperties.setProperty(DRIVER_CLASS_NAME, "com.mysql.jdbc.Driver"); DataSourceConfigure newConfigure = new DataSourceConfigure("DalService2DB_w", newProperties); @@ -198,7 +198,7 @@ public void testToString() throws Exception { IDataSourceConfigureProvider provider = new MockDataSourceConfigureProvider(); ForceSwitchableDataSource dataSource = new ForceSwitchableDataSource(provider); SwitchableDataSourceStatus status = dataSource.getStatus(); - assertEquals("isForceSwitched: false, poolCreated: true, hostName: 10.32.20.143, port: 3306", status.toString()); + assertEquals("isForceSwitched: false, poolCreated: true, hostName: 10.32.20.128, port: 3306", status.toString()); } @Test @@ -220,7 +220,7 @@ public void testProviderThrowException() throws Exception { Properties properties = new Properties(); properties.setProperty(USER_NAME, "root"); properties.setProperty(PASSWORD, "!QAZ@WSX1qaz2wsx"); - properties.setProperty(CONNECTION_URL, "jdbc:mysql://10.32.20.143:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;"); + properties.setProperty(CONNECTION_URL, "jdbc:mysql://10.32.20.128:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;"); properties.setProperty(DRIVER_CLASS_NAME, "com.mysql.jdbc.Driver"); DataSourceConfigure dataSourceConfigure = new DataSourceConfigure("DalService2DB_w", properties); dataSource.forceSwitch(SerializableDataSourceConfig.valueOf(dataSourceConfigure), DOMAINHOST, 3306); @@ -234,7 +234,7 @@ public void testProviderThrowException() throws Exception { assertEquals("3306", status1.getPort().toString()); assertEquals("root", dataSource.getSingleDataSource().getDataSourceConfigure().getUserName()); assertEquals("!QAZ@WSX1qaz2wsx", dataSource.getSingleDataSource().getDataSourceConfigure().getPassword()); - assertEquals("jdbc:mysql://10.32.20.143:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;", dataSource.getSingleDataSource().getName()); + assertEquals("jdbc:mysql://10.32.20.128:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;", dataSource.getSingleDataSource().getName()); dataSource.forceSwitch(SerializableDataSourceConfig.valueOf(dataSourceConfigure), INVALIDHOST, 3306); Thread.sleep(20000); @@ -261,7 +261,7 @@ public void testProviderThrowException() throws Exception { assertEquals(IPHOST, status3.getHostName().toLowerCase()); assertTrue(status3.isForceSwitched()); assertTrue(status3.isPoolCreated()); - assertEquals("jdbc:mysql://10.32.20.143:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;", dataSource.getSingleDataSource().getName()); + assertEquals("jdbc:mysql://10.32.20.128:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;", dataSource.getSingleDataSource().getName()); assertEquals("3306", status3.getPort().toString()); dataSource.restore(); @@ -322,7 +322,7 @@ public void testMGRJDBCUrlParser() { } @Test - public void MGRSwitchToNormal() throws Exception { + public void testSwitchMGRToNormal() throws Exception { IDataSourceConfigureProvider nullProvider = new ModifyDataSourceConfigureProvider(); ForceSwitchableDataSource nullDataSource = new ForceSwitchableDataSource(nullProvider); Properties properties = new Properties(); diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/LocalizedDataSourceTest.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/LocalizedDataSourceTest.java index 4998fb6b2..718dab56e 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/LocalizedDataSourceTest.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/LocalizedDataSourceTest.java @@ -392,7 +392,7 @@ private DataSourceConfigure getDataSourceConfig() { Properties p = new Properties(); p.setProperty("userName", "root"); p.setProperty("password", "!QAZ@WSX1qaz2wsx"); - p.setProperty("connectionUrl", "jdbc:mysql://10.32.20.143:3306/llj_test?useUnicode=true&characterEncoding=UTF-8"); + p.setProperty("connectionUrl", "jdbc:mysql://10.32.20.128:3306/llj_test?useUnicode=true&characterEncoding=UTF-8"); p.setProperty("driverClassName", "com.mysql.jdbc.Driver"); return new DataSourceConfigure("llj_test", p); } diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/RefreshableDataSourceTest.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/RefreshableDataSourceTest.java index 9ad4e6f4e..b0be14e27 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/RefreshableDataSourceTest.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/RefreshableDataSourceTest.java @@ -197,7 +197,7 @@ public void testOneSuccessDataSourceAfterOneConnectTimeoutDataSource() throws Ex Properties p3 = new Properties(); p3.setProperty("userName", "root"); p3.setProperty("password", "111111"); - p3.setProperty("connectionUrl", "jdbc:mysql://10.32.20.143:3306/test"); + p3.setProperty("connectionUrl", "jdbc:mysql://10.32.20.128:3306/test"); p3.setProperty("driverClassName", "com.mysql.jdbc.Driver"); p3.setProperty("connectionProperties", "connectTimeout=3000"); final DataSourceConfigure configure3 = new DataSourceConfigure("test", p3); @@ -217,7 +217,7 @@ public void run() { Thread.sleep(4000); Assert.assertNotNull(refreshableDataSource.getSingleDataSource()); Assert.assertNotNull(refreshableDataSource.getSingleDataSource().getDataSource()); - Assert.assertEquals("jdbc:mysql://10.32.20.143:3306/test", refreshableDataSource.getSingleDataSource().getDataSourceConfigure().getProperty("connectionUrl")); + Assert.assertEquals("jdbc:mysql://10.32.20.128:3306/test", refreshableDataSource.getSingleDataSource().getDataSourceConfigure().getProperty("connectionUrl")); } @Test @@ -300,7 +300,7 @@ public void testDataSourceSwitchNotify() throws Exception { Properties p2 = new Properties(); p2.setProperty("userName", "root"); p2.setProperty("password", "!QAZ@WSX1qaz2wsx"); - p2.setProperty("connectionUrl", "jdbc:mysql://10.32.20.143:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;"); + p2.setProperty("connectionUrl", "jdbc:mysql://10.32.20.128:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;"); p2.setProperty("driverClassName", "com.mysql.jdbc.Driver"); DataSourceConfigure configure2 = new DataSourceConfigure("test2", p2); @@ -325,7 +325,7 @@ public void run() { //System.out.println(listenerOne.getStep() + ", " + listenerTwo.getStep()); if (listenerOne.getStep() == 10 && listenerTwo.getStep() == 20) { switched.set(true); - Assert.assertEquals("jdbc:mysql://10.32.20.143:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;", refreshableDataSource.getSingleDataSource().getDataSourceConfigure().getConnectionUrl()); + Assert.assertEquals("jdbc:mysql://10.32.20.128:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;", refreshableDataSource.getSingleDataSource().getDataSourceConfigure().getConnectionUrl()); } latch.countDown(); } @@ -376,7 +376,7 @@ public void testExecuteListenerTimeOut() throws Exception { Properties p2 = new Properties(); p2.setProperty("userName", "root"); p2.setProperty("password", "!QAZ@WSX1qaz2wsx"); - p2.setProperty("connectionUrl", "jdbc:mysql://10.32.20.143:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;"); + p2.setProperty("connectionUrl", "jdbc:mysql://10.32.20.128:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;"); p2.setProperty("driverClassName", "com.mysql.jdbc.Driver"); DataSourceConfigure configure2 = new DataSourceConfigure("test2", p2); @@ -434,7 +434,7 @@ public void testSetExecuteSwitchListenerTimeout() throws Exception { Properties p2 = new Properties(); p2.setProperty("userName", "root"); p2.setProperty("password", "!QAZ@WSX1qaz2wsx"); - p2.setProperty("connectionUrl", "jdbc:mysql://10.32.20.143:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;"); + p2.setProperty("connectionUrl", "jdbc:mysql://10.32.20.128:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;"); p2.setProperty("driverClassName", "com.mysql.jdbc.Driver"); DataSourceConfigure dataSourceConfigure1 = new DataSourceConfigure("test2", p2); @@ -488,7 +488,7 @@ public void testGetConnectionPerformance() throws Exception { Properties p2 = new Properties(); p2.setProperty("userName", "root"); p2.setProperty("password", "!QAZ@WSX1qaz2wsx"); - p2.setProperty("connectionUrl", "jdbc:mysql://10.32.20.143:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;"); + p2.setProperty("connectionUrl", "jdbc:mysql://10.32.20.128:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;"); p2.setProperty("driverClassName", "com.mysql.jdbc.Driver"); DataSourceConfigure configure2 = new DataSourceConfigure("test2", p2); @@ -516,7 +516,7 @@ public void testGetConnection() throws Exception { Properties p2 = new Properties(); p2.setProperty("userName", "root"); p2.setProperty("password", "!QAZ@WSX1qaz2wsx"); - p2.setProperty("connectionUrl", "jdbc:mysql://10.32.20.143:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;"); + p2.setProperty("connectionUrl", "jdbc:mysql://10.32.20.128:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;"); p2.setProperty("driverClassName", "com.mysql.jdbc.Driver"); DataSourceConfigure configure2 = new DataSourceConfigure("test2", p2); @@ -540,7 +540,7 @@ public void run() { Connection connection = refreshableDataSource.getConnection(); long endTime = System.currentTimeMillis(); System.out.println(startTime + ":" + (endTime - startTime)); - if ("jdbc:mysql://10.32.20.143:3306/llj_test".equalsIgnoreCase(ConnectionHelper.obtainUrl(connection))) { + if ("jdbc:mysql://10.32.20.128:3306/llj_test".equalsIgnoreCase(ConnectionHelper.obtainUrl(connection))) { Assert.assertEquals(listenerOne.getStep(), 10); Assert.assertEquals(listenerTwo.getStep(), 20); } @@ -565,7 +565,7 @@ public void testReusedSingleDataSource() { Properties p1 = new Properties(); p1.setProperty("userName", "root"); p1.setProperty("password", "!QAZ@WSX1qaz2wsx"); - p1.setProperty("connectionUrl", "jdbc:mysql://10.32.20.143:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;"); + p1.setProperty("connectionUrl", "jdbc:mysql://10.32.20.128:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;"); p1.setProperty("driverClassName", "com.mysql.jdbc.Driver"); DataSourceConfigure config1 = new DataSourceConfigure("config1", p1); DataSourceConfigure config2 = new DataSourceConfigure("config2", p1); @@ -592,7 +592,7 @@ public void testDataSourceSwitch() throws Exception { Properties p1 = new Properties(); p1.setProperty("userName", "root"); p1.setProperty("password", "!QAZ@WSX1qaz2wsx"); - p1.setProperty("connectionUrl", "jdbc:mysql://10.32.20.143:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;"); + p1.setProperty("connectionUrl", "jdbc:mysql://10.32.20.128:3306/llj_test?useUnicode=true&characterEncoding=UTF-8;"); p1.setProperty("driverClassName", "com.mysql.jdbc.Driver"); Properties p2 = new Properties(); diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/AllTests.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/_AllTests.java similarity index 93% rename from dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/AllTests.java rename to dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/_AllTests.java index fc4e3b41c..41399ae7a 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/AllTests.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/_AllTests.java @@ -1,22 +1,22 @@ -package com.ctrip.platform.dal.dao.datasource; - -import com.ctrip.platform.dal.dao.datasource.jdbc.DalConnectionTest; -import com.ctrip.platform.dal.dao.datasource.jdbc.DalDaoTest; -import com.ctrip.platform.dal.dao.datasource.jdbc.DalStatementTest; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -@RunWith(Suite.class) -@SuiteClasses({ - DatabasePoolConfigParserTest.class, - RefreshableDataSourceTest.class, - ForceSwitchableDataSourceTest.class, - LocalizedDataSourceTest.class, - DalConnectionTest.class, - DalDaoTest.class, - DalStatementTest.class -}) -public class AllTests { - -} +package com.ctrip.platform.dal.dao.datasource; + +import com.ctrip.platform.dal.dao.datasource.jdbc.DalConnectionTest; +import com.ctrip.platform.dal.dao.datasource.jdbc.DalDaoTest; +import com.ctrip.platform.dal.dao.datasource.jdbc.DalStatementTest; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +@RunWith(Suite.class) +@SuiteClasses({ + DatabasePoolConfigParserTest.class, + RefreshableDataSourceTest.class, + ForceSwitchableDataSourceTest.class, + LocalizedDataSourceTest.class, + DalConnectionTest.class, + DalDaoTest.class, + DalStatementTest.class +}) +public class _AllTests { + +} diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalDaoTest.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalDaoTest.java index 8cd963139..a4eb7c42b 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalDaoTest.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/jdbc/DalDaoTest.java @@ -4,6 +4,7 @@ import com.ctrip.platform.dal.dao.datasource.DataSourceLocator; import com.ctrip.platform.dal.dao.datasource.RefreshableDataSource; import com.ctrip.platform.dal.dao.helper.FixedValueRowMapper; +import com.ctrip.platform.dal.dao.sqlbuilder.FreeUpdateSqlBuilder; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -27,32 +28,50 @@ public void testDalDaoExecuteSql() throws Exception { //TestTableDao testTableDao = new TestTableDao(); DalQueryDao client = new DalQueryDao(dbName); - client.query("select 1", new StatementParameters(), new DalHints(), new FixedValueRowMapper<>()); RefreshableDataSource dataSource = getDataSource(); Assert.assertEquals(0, dataSource.getFirstAppearContinuousErrorTime()); Assert.assertEquals(0, dataSource.getLastReportContinuousErrorTime()); try { - client.query("select *from noTable", new StatementParameters(), new DalHints(), new FixedValueRowMapper<>()); + client.query("select * from noTable", new StatementParameters(), new DalHints(), new FixedValueRowMapper<>()); } catch (SQLException e) { - } Assert.assertNotEquals(0, dataSource.getFirstAppearContinuousErrorTime()); + Assert.assertEquals(1, dataSource.getContinuousErrorCount()); Assert.assertEquals(0, dataSource.getLastReportContinuousErrorTime()); Thread.sleep(60*1000); try { - client.query("select *from noTable", new StatementParameters(), new DalHints(), new FixedValueRowMapper<>()); + client.query("select * from noTable", new StatementParameters(), new DalHints(), new FixedValueRowMapper<>()); } catch (SQLException e) { + } + Assert.assertNotEquals(0, dataSource.getFirstAppearContinuousErrorTime()); + Assert.assertEquals(2, dataSource.getContinuousErrorCount()); + Assert.assertEquals(0, dataSource.getLastReportContinuousErrorTime()); + try { + client.query("select * from noTable", new StatementParameters(), new DalHints(), new FixedValueRowMapper<>()); + } catch (SQLException e) { } Assert.assertNotEquals(0, dataSource.getFirstAppearContinuousErrorTime()); + Assert.assertEquals(3, dataSource.getContinuousErrorCount()); Assert.assertNotEquals(0, dataSource.getLastReportContinuousErrorTime()); client.query("select 1", new StatementParameters(), new DalHints(), new FixedValueRowMapper<>()); - Assert.assertEquals(0, dataSource.getFirstAppearContinuousErrorTime()); - Assert.assertEquals(0, dataSource.getLastReportContinuousErrorTime()); + Assert.assertNotEquals(0, dataSource.getFirstAppearContinuousErrorTime()); + Assert.assertEquals(3, dataSource.getContinuousErrorCount()); + Assert.assertNotEquals(0, dataSource.getLastReportContinuousErrorTime()); + + try { + FreeUpdateSqlBuilder builder = new FreeUpdateSqlBuilder(); + builder.setTemplate("update noTable set id = 1 where id > 1"); + client.update(builder, new DalHints()); + } catch (SQLException e) { + } + Assert.assertNotEquals(0, dataSource.getFirstAppearContinuousErrorTime()); + Assert.assertEquals(4, dataSource.getContinuousErrorCount()); + Assert.assertNotEquals(0, dataSource.getLastReportContinuousErrorTime()); } private RefreshableDataSource getDataSource() { diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/tomcat/DalConnectionPoolTest.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/tomcat/DalConnectionPoolTest.java index 6148cad72..a3fae80e2 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/tomcat/DalConnectionPoolTest.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/datasource/tomcat/DalConnectionPoolTest.java @@ -1,6 +1,7 @@ package com.ctrip.platform.dal.dao.datasource.tomcat; import com.ctrip.platform.dal.dao.datasource.AbstractConnectionListener; +import com.ctrip.platform.dal.dao.datasource.DataSourceIdentity; import org.apache.tomcat.jdbc.pool.ConnectionPool; import org.apache.tomcat.jdbc.pool.DataSource; import org.apache.tomcat.jdbc.pool.PoolConfiguration; @@ -37,9 +38,8 @@ public void simpleTest() throws SQLException { final AtomicInteger abandon = new AtomicInteger(); DalConnectionPool.setConnectionListener(new AbstractConnectionListener() { - @Override - public void doOnCreateConnection(String poolDesc, Connection connection, long startTime) { + public void doOnCreateConnection(String poolDesc, Connection connection, DataSourceIdentity dataSourceId, long startTime) { create.incrementAndGet(); } diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/helper/AllTests.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/helper/_AllTests.java similarity index 92% rename from dal-client/src/test/java/com/ctrip/platform/dal/dao/helper/AllTests.java rename to dal-client/src/test/java/com/ctrip/platform/dal/dao/helper/_AllTests.java index 5e2b85a87..d115415ad 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/helper/AllTests.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/helper/_AllTests.java @@ -1,22 +1,22 @@ -package com.ctrip.platform.dal.dao.helper; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -@RunWith(Suite.class) -@SuiteClasses({ - DalFirstResultMergerTest.class, - DalSingleResultMergerTest.class, - PartialQueryTableDaoUnitTest.class, - PartialQueryQueryDaoTest.class, - DalColumnMapRowMapperTest.class, - DalCustomRowMapperTest.class, - DalRowMapperExtractorTest.class, - SQLCompilerTest.class, - ServiceLoaderHelperTest.class, - DalBase64Test.class, - LoggerHelperTest.class, - TableParserTest.class -}) -public class AllTests {} \ No newline at end of file +package com.ctrip.platform.dal.dao.helper; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +@RunWith(Suite.class) +@SuiteClasses({ + DalFirstResultMergerTest.class, + DalSingleResultMergerTest.class, + PartialQueryTableDaoUnitTest.class, + PartialQueryQueryDaoTest.class, + DalColumnMapRowMapperTest.class, + DalCustomRowMapperTest.class, + DalRowMapperExtractorTest.class, + SQLCompilerTest.class, + ServiceLoaderHelperTest.class, + DalBase64Test.class, + LoggerHelperTest.class, + TableParserTest.class +}) +public class _AllTests {} \ No newline at end of file diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/markdown/AllTests.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/markdown/_AllTests.java similarity index 89% rename from dal-client/src/test/java/com/ctrip/platform/dal/dao/markdown/AllTests.java rename to dal-client/src/test/java/com/ctrip/platform/dal/dao/markdown/_AllTests.java index 54a4ce5be..fee026bc3 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/markdown/AllTests.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/markdown/_AllTests.java @@ -1,18 +1,18 @@ -package com.ctrip.platform.dal.dao.markdown; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -@RunWith(Suite.class) -@SuiteClasses({ - MarkdownAndUpIntergration.class, - DetectorCounterTest.class, - TimeoutDetectorTest.class, - AutoMarkdownTest.class, - ManualMarkDownTest.class, - TimeBucketCounterTest.class, - }) -public class AllTests { - -} +package com.ctrip.platform.dal.dao.markdown; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +@RunWith(Suite.class) +@SuiteClasses({ + MarkdownAndUpIntergration.class, + DetectorCounterTest.class, + TimeoutDetectorTest.class, + AutoMarkdownTest.class, + ManualMarkDownTest.class, + TimeBucketCounterTest.class, + }) +public class _AllTests { + +} diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/parser/AllTest.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/parser/_AllTests.java similarity index 90% rename from dal-client/src/test/java/com/ctrip/platform/dal/dao/parser/AllTest.java rename to dal-client/src/test/java/com/ctrip/platform/dal/dao/parser/_AllTests.java index 7bac2bcb4..88f427386 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/parser/AllTest.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/parser/_AllTests.java @@ -1,15 +1,15 @@ -package com.ctrip.platform.dal.dao.parser; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -@RunWith(Suite.class) -@SuiteClasses({ - DalDefaultJpaParserMySqlTest.class, - DalDefaultJpaParserSqlServerTest.class, - DalDefaultJpaParserMySqlTest2.class, - DalDefaultJpaParserSqlServerTest2.class, - DalDefaultJpaParserTest.class -}) -public class AllTest {} +package com.ctrip.platform.dal.dao.parser; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +@RunWith(Suite.class) +@SuiteClasses({ + DalDefaultJpaParserMySqlTest.class, + DalDefaultJpaParserSqlServerTest.class, + DalDefaultJpaParserMySqlTest2.class, + DalDefaultJpaParserSqlServerTest2.class, + DalDefaultJpaParserTest.class +}) +public class _AllTests {} diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/shard/AllTest.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/shard/_AllTests.java similarity index 92% rename from dal-client/src/test/java/com/ctrip/platform/dal/dao/shard/AllTest.java rename to dal-client/src/test/java/com/ctrip/platform/dal/dao/shard/_AllTests.java index 18036b601..1f63cf2d1 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/shard/AllTest.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/shard/_AllTests.java @@ -1,26 +1,26 @@ -package com.ctrip.platform.dal.dao.shard; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -@RunWith(Suite.class) -@SuiteClasses({ - ShardColModShardStrategyTest.class, - SimpleShardHintStrategyTest.class, - - DalTabelDaoShardByTableSqlSvrTest.class, - DalTabelDaoShardByTableMySqlTest.class, - - DalTableDaoShardByDbSqlSvrTest.class, - DalTableDaoShardByDbMySqlTest.class, - - DalTableDaoShardByDbTableSqlSvrTest.class, - DalTableDaoShardByDbTableMySqlTest.class, - - DalQueryDaoMySqlTest.class, - DalQueryDaoSqlSvrTest.class, - - ExecutionCallbackTest.class -}) -public class AllTest {} +package com.ctrip.platform.dal.dao.shard; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +@RunWith(Suite.class) +@SuiteClasses({ + ShardColModShardStrategyTest.class, + SimpleShardHintStrategyTest.class, + + DalTabelDaoShardByTableSqlSvrTest.class, + DalTabelDaoShardByTableMySqlTest.class, + + DalTableDaoShardByDbSqlSvrTest.class, + DalTableDaoShardByDbMySqlTest.class, + + DalTableDaoShardByDbTableSqlSvrTest.class, + DalTableDaoShardByDbTableMySqlTest.class, + + DalQueryDaoMySqlTest.class, + DalQueryDaoSqlSvrTest.class, + + ExecutionCallbackTest.class +}) +public class _AllTests {} diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/sharding/idgen/AllTests.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/sharding/idgen/_AllTests.java similarity index 88% rename from dal-client/src/test/java/com/ctrip/platform/dal/dao/sharding/idgen/AllTests.java rename to dal-client/src/test/java/com/ctrip/platform/dal/dao/sharding/idgen/_AllTests.java index 843b73c7e..b21593ac2 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/sharding/idgen/AllTests.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/sharding/idgen/_AllTests.java @@ -1,14 +1,14 @@ -package com.ctrip.platform.dal.dao.sharding.idgen; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -@RunWith(Suite.class) -@SuiteClasses({ - IdGeneratorConfigTest.class, - IdGeneratorFactoryManagerTest.class, -}) -public class AllTests { - -} +package com.ctrip.platform.dal.dao.sharding.idgen; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +@RunWith(Suite.class) +@SuiteClasses({ + IdGeneratorConfigTest.class, + IdGeneratorFactoryManagerTest.class, +}) +public class _AllTests { + +} diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/sqlbuilder/AllTests.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/sqlbuilder/_AllTests.java similarity index 92% rename from dal-client/src/test/java/com/ctrip/platform/dal/dao/sqlbuilder/AllTests.java rename to dal-client/src/test/java/com/ctrip/platform/dal/dao/sqlbuilder/_AllTests.java index b075d7a3a..601cb42a6 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/sqlbuilder/AllTests.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/sqlbuilder/_AllTests.java @@ -1,24 +1,24 @@ -package com.ctrip.platform.dal.dao.sqlbuilder; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -@RunWith(Suite.class) -@SuiteClasses({ - DeleteSqlBuilderTest.class, - SelectSqlBuilderTest.class, - UpdateSqlBuilderTest.class, - AbstractBuilderTest.class, - BaseQueryBuilderTest.class, - InsertSqlBuilderTest.class, - AbstractFreeSqlBuilderTest.class, - ExpressionsTest.class, - FreeUpdateSqlBuilderTest.class, - FreeSelectSqlBuilderTest.class, - AbstractFreeSqlBuilderMeltdownTest.class, - AbstractFreeSqlBuilderMeltdownWithSpaceSkipDisabledTest.class, - }) -public class AllTests { - -} +package com.ctrip.platform.dal.dao.sqlbuilder; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +@RunWith(Suite.class) +@SuiteClasses({ + DeleteSqlBuilderTest.class, + SelectSqlBuilderTest.class, + UpdateSqlBuilderTest.class, + AbstractBuilderTest.class, + BaseQueryBuilderTest.class, + InsertSqlBuilderTest.class, + AbstractFreeSqlBuilderTest.class, + ExpressionsTest.class, + FreeUpdateSqlBuilderTest.class, + FreeSelectSqlBuilderTest.class, + AbstractFreeSqlBuilderMeltdownTest.class, + AbstractFreeSqlBuilderMeltdownWithSpaceSkipDisabledTest.class, + }) +public class _AllTests { + +} diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/task/DalRequestExecutorTest.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/task/DalRequestExecutorTest.java index 2ed9da542..be1f4c530 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/task/DalRequestExecutorTest.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/task/DalRequestExecutorTest.java @@ -33,7 +33,12 @@ public void validateAndPrepare() throws SQLException { throw e; } - @Override + @Override + public String getLogicDbName() { + return null; + } + + @Override public boolean isCrossShard() throws SQLException { return values.length > 1; } @@ -63,6 +68,11 @@ public DalTaskContext getDalTaskContext() { return this.dalTaskContext; } + @Override + public String getPreparedDbShard() { + return null; + } + public Integer call() throws Exception { return k; } @@ -114,6 +124,11 @@ public DalTaskContext getDalTaskContext() { return this.dalTaskContext; } + @Override + public String getPreparedDbShard() { + return null; + } + public Integer call() throws Exception { all.put(Thread.currentThread().getName(), 1); if(sleep) diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/task/DalRequestExecutorUtils.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/task/DalRequestExecutorUtils.java new file mode 100644 index 000000000..1d3fc3e02 --- /dev/null +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/task/DalRequestExecutorUtils.java @@ -0,0 +1,20 @@ +package com.ctrip.platform.dal.dao.task; + +import com.ctrip.platform.dal.dao.configure.DalThreadPoolExecutorConfig; + +import java.util.concurrent.ExecutorService; + +/** + * @author c7ch23en + */ +public class DalRequestExecutorUtils { + + public static ExecutorService getExecutor() { + return DalRequestExecutor.getExecutor(); + } + + public static DalThreadPoolExecutorConfig getExecutorConfig(DalThreadPoolExecutor executor) { + return executor.getExecutorConfig(); + } + +} diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/task/DalThreadPoolExecutorTest.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/task/DalThreadPoolExecutorTest.java new file mode 100644 index 000000000..87065f468 --- /dev/null +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/task/DalThreadPoolExecutorTest.java @@ -0,0 +1,217 @@ +package com.ctrip.platform.dal.dao.task; + +import com.ctrip.platform.dal.dao.configure.DalThreadPoolExecutorConfig; +import org.junit.Assert; +import org.junit.Test; + +import java.util.concurrent.*; + +/** + * @author c7ch23en + */ +public class DalThreadPoolExecutorTest { + + private final ThreadPoolExecutor executor; + + private static final String DB1 = "testDb1"; + private static final String DB2 = "testDb2"; + private static final String DB3 = "testDb3"; + + public DalThreadPoolExecutorTest() { + executor = new DalThreadPoolExecutor(new MockDalThreadPoolExecutorConfig(), + new LinkedBlockingQueue<>(), new MockThreadFactory()); + } + + @Test + public void testConcurrentExecutions() throws Exception { + testStep1(); + TimeUnit.MILLISECONDS.sleep(25); + testStep2(); + } + + private void testStep1() throws Exception { + DalRequestCallable db1Shard1Task1 = createTask(DB1, "1", 20); + DalRequestCallable db1Shard1Task2 = createTask(DB1, "1", 20); + DalRequestCallable db1Shard1Task3 = createTask(DB1, "1", 20); + + DalRequestCallable db1Shard2Task1 = createTask(DB1, "2", 20); + DalRequestCallable db1Shard2Task2 = createTask(DB1, "2", 20); + DalRequestCallable db1Shard2Task3 = createTask(DB1, "2", 20); + + DalRequestCallable db2Shard1Task1 = createTask(DB2, "1", 20); + DalRequestCallable db2Shard1Task2 = createTask(DB2, "1", 20); + DalRequestCallable db2Shard1Task3 = createTask(DB2, "1", 20); + DalRequestCallable db2Shard1Task4 = createTask(DB2, "1", 20); + + DalRequestCallable db3Shard1Task1 = createTask(DB3, "1", 20); + DalRequestCallable db3Shard1Task2 = createTask(DB3, "1", 20); + DalRequestCallable db3Shard1Task3 = createTask(DB3, "1", 20); + DalRequestCallable db3Shard1Task4 = createTask(DB3, "1", 20); + + Future db1Shard1Future1 = executor.submit(db1Shard1Task1); + Future db1Shard1Future2 = executor.submit(db1Shard1Task2); + + Future db1Shard2Future1 = executor.submit(db1Shard2Task1); + Future db1Shard2Future2 = executor.submit(db1Shard2Task2); + + Future db2Shard1Future1 = executor.submit(db2Shard1Task1); + Future db2Shard1Future2 = executor.submit(db2Shard1Task2); + Future db2Shard1Future3 = executor.submit(db2Shard1Task3); + + Future db3Shard1Future1 = executor.submit(db3Shard1Task1); + Future db3Shard1Future2 = executor.submit(db3Shard1Task2); + Future db3Shard1Future3 = executor.submit(db3Shard1Task3); + Future db3Shard1Future4 = executor.submit(db3Shard1Task4); + + TimeUnit.MILLISECONDS.sleep(10); + + Future db1Shard1Future3 = executor.submit(db1Shard1Task3); + Future db1Shard2Future3 = executor.submit(db1Shard2Task3); + Future db2Shard1Future4 = executor.submit(db2Shard1Task4); + + long[] db1Shard1Result1 = db1Shard1Future1.get(); + long[] db1Shard1Result2 = db1Shard1Future2.get(); + long[] db1Shard1Result3 = db1Shard1Future3.get(); + Assert.assertTrue(max(db1Shard1Result1[0], db1Shard1Result2[0]) < + min(db1Shard1Result1[1], db1Shard1Result2[1])); + Assert.assertTrue(db1Shard1Result3[0] >= + min(db1Shard1Result1[1], db1Shard1Result2[1])); + + long[] db1Shard2Result1 = db1Shard2Future1.get(); + long[] db1Shard2Result2 = db1Shard2Future2.get(); + long[] db1Shard2Result3 = db1Shard2Future3.get(); + Assert.assertTrue(max(db1Shard2Result1[0], db1Shard2Result2[0]) < + min(db1Shard2Result1[1], db1Shard2Result2[1])); + Assert.assertTrue(db1Shard2Result3[0] >= + min(db1Shard2Result1[1], db1Shard2Result2[1])); + + long[] db2Shard1Result1 = db2Shard1Future1.get(); + long[] db2Shard1Result2 = db2Shard1Future2.get(); + long[] db2Shard1Result3 = db2Shard1Future3.get(); + long[] db2Shard1Result4 = db2Shard1Future4.get(); + Assert.assertTrue(max(db2Shard1Result1[0], db2Shard1Result2[0], db2Shard1Result3[0]) < + min(db2Shard1Result1[1], db2Shard1Result2[1], db2Shard1Result3[1])); + Assert.assertTrue(db2Shard1Result4[0] >= + min(db2Shard1Result1[1], db2Shard1Result2[1], db2Shard1Result3[1])); + + long[] db3Shard1Result1 = db3Shard1Future1.get(); + long[] db3Shard1Result2 = db3Shard1Future2.get(); + long[] db3Shard1Result3 = db3Shard1Future3.get(); + long[] db3Shard1Result4 = db3Shard1Future4.get(); + Assert.assertTrue(max(db3Shard1Result1[0], db3Shard1Result2[0], db3Shard1Result3[0], db3Shard1Result4[0]) < + min(db3Shard1Result1[1], db3Shard1Result2[1], db3Shard1Result3[1], db3Shard1Result4[1])); + } + + private void testStep2() throws Exception { + DalRequestCallable db1Shard1Task1 = createTask(DB1, "1", 20); + DalRequestCallable db1Shard1Task2 = createTask(DB1, "1", 20); + + DalRequestCallable db1Shard2Task1 = createTask(DB1, "2", 20); + DalRequestCallable db1Shard2Task2 = createTask(DB1, "2", 20); + + DalRequestCallable db2Shard1Task1 = createTask(DB2, "1", 20); + DalRequestCallable db2Shard1Task2 = createTask(DB2, "1", 20); + DalRequestCallable db2Shard1Task3 = createTask(DB2, "1", 20); + + DalRequestCallable db3Shard1Task1 = createTask(DB3, "1", 20); + DalRequestCallable db3Shard1Task2 = createTask(DB3, "1", 20); + DalRequestCallable db3Shard1Task3 = createTask(DB3, "1", 20); + DalRequestCallable db3Shard1Task4 = createTask(DB3, "1", 20); + + Future db1Shard1Future1 = executor.submit(db1Shard1Task1); + Future db1Shard1Future2 = executor.submit(db1Shard1Task2); + + Future db1Shard2Future1 = executor.submit(db1Shard2Task1); + Future db1Shard2Future2 = executor.submit(db1Shard2Task2); + + Future db2Shard1Future1 = executor.submit(db2Shard1Task1); + Future db2Shard1Future2 = executor.submit(db2Shard1Task2); + Future db2Shard1Future3 = executor.submit(db2Shard1Task3); + + Future db3Shard1Future1 = executor.submit(db3Shard1Task1); + Future db3Shard1Future2 = executor.submit(db3Shard1Task2); + Future db3Shard1Future3 = executor.submit(db3Shard1Task3); + Future db3Shard1Future4 = executor.submit(db3Shard1Task4); + + long[] db1Shard1Result1 = db1Shard1Future1.get(); + long[] db1Shard1Result2 = db1Shard1Future2.get(); + Assert.assertTrue(max(db1Shard1Result1[0], db1Shard1Result2[0]) < + min(db1Shard1Result1[1], db1Shard1Result2[1])); + + long[] db1Shard2Result1 = db1Shard2Future1.get(); + long[] db1Shard2Result2 = db1Shard2Future2.get(); + Assert.assertTrue(max(db1Shard2Result1[0], db1Shard2Result2[0]) < + min(db1Shard2Result1[1], db1Shard2Result2[1])); + + long[] db2Shard1Result1 = db2Shard1Future1.get(); + long[] db2Shard1Result2 = db2Shard1Future2.get(); + long[] db2Shard1Result3 = db2Shard1Future3.get(); + Assert.assertTrue(max(db2Shard1Result1[0], db2Shard1Result2[0], db2Shard1Result3[0]) < + min(db2Shard1Result1[1], db2Shard1Result2[1], db2Shard1Result3[1])); + + long[] db3Shard1Result1 = db3Shard1Future1.get(); + long[] db3Shard1Result2 = db3Shard1Future2.get(); + long[] db3Shard1Result3 = db3Shard1Future3.get(); + long[] db3Shard1Result4 = db3Shard1Future4.get(); + Assert.assertTrue(max(db3Shard1Result1[0], db3Shard1Result2[0], db3Shard1Result3[0], db3Shard1Result4[0]) < + min(db3Shard1Result1[1], db3Shard1Result2[1], db3Shard1Result3[1], db3Shard1Result4[1])); + } + + private DalRequestCallable createTask(String logicDbName, String shard, long delayMs) { + return new DalRequestCallable<>(logicDbName, shard, () -> { + long[] timestamps = new long[2]; + timestamps[0] = System.currentTimeMillis(); + TimeUnit.MILLISECONDS.sleep(delayMs); + timestamps[1] = System.currentTimeMillis(); + return timestamps; + }); + } + + private long max(long... values) { + long result = Long.MIN_VALUE; + for (long value : values) + result = Math.max(result, value); + return result; + } + + private long min(long... values) { + long result = Long.MAX_VALUE; + for (long value : values) + result = Math.min(result, value); + return result; + } + + static class MockDalThreadPoolExecutorConfig implements DalThreadPoolExecutorConfig { + @Override + public int getCorePoolSize() { + return 20; + } + + @Override + public int getMaxPoolSize() { + return 20; + } + + @Override + public long getKeepAliveSeconds() { + return 10; + } + + @Override + public int getMaxThreadsPerShard(String logicDbName) { + if ("testDb1".equalsIgnoreCase(logicDbName)) + return 2; + if ("testDb2".equalsIgnoreCase(logicDbName)) + return 3; + return 0; + } + } + + static class MockThreadFactory implements ThreadFactory { + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "test"); + } + } + +} diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/task/AllTest.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/task/_AllTests.java similarity index 91% rename from dal-client/src/test/java/com/ctrip/platform/dal/dao/task/AllTest.java rename to dal-client/src/test/java/com/ctrip/platform/dal/dao/task/_AllTests.java index a22a66e70..edcdc6657 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/task/AllTest.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/task/_AllTests.java @@ -1,40 +1,41 @@ -package com.ctrip.platform.dal.dao.task; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -@RunWith(Suite.class) -@SuiteClasses({ - BatchDeleteTaskSqlSvrTest.class, - BatchInsertTaskSqlSvrTest.class, - BatchUpdateTaskSqlSvrTest.class, - CombinedInsertTaskSqlSvrTest.class, - SingleDeleteTaskSqlSvrTest.class, - SingleInsertTaskSqlSvrTest.class, - SingleUpdateTaskSqlSvrTest.class, - QuerySqlTaskSqlSvrTest.class, - DeleteSqlTaskSqlSvrTest.class, - UpdateSqlTaskSqlSvrTest.class, - - BatchDeleteTaskMySqlTest.class, - BatchInsertTaskMySqlTest.class, - BatchUpdateTaskMySqlTest.class, - CombinedInsertTaskMySqlTest.class, - SingleDeleteTaskMySqlTest.class, - SingleInsertTaskMySqlTest.class, - SingleUpdateTaskMySqlTest.class, - QuerySqlTaskMySqlTest.class, - DeleteSqlTaskMySqlTest.class, - UpdateSqlTaskMySqlTest.class, - - ShardedIntArrayResultMergerTest.class, - DalSingleTaskRequestTest.class, - DalBulkTaskRequestTest.class, - DalSingleTaskRequestTest.class, - DalSqlTaskRequestTest.class, - DalBulkTaskContextTest.class -}) -public class AllTest { - -} +package com.ctrip.platform.dal.dao.task; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +@RunWith(Suite.class) +@SuiteClasses({ + BatchDeleteTaskSqlSvrTest.class, + BatchInsertTaskSqlSvrTest.class, + BatchUpdateTaskSqlSvrTest.class, + CombinedInsertTaskSqlSvrTest.class, + SingleDeleteTaskSqlSvrTest.class, + SingleInsertTaskSqlSvrTest.class, + SingleUpdateTaskSqlSvrTest.class, + QuerySqlTaskSqlSvrTest.class, + DeleteSqlTaskSqlSvrTest.class, + UpdateSqlTaskSqlSvrTest.class, + + BatchDeleteTaskMySqlTest.class, + BatchInsertTaskMySqlTest.class, + BatchUpdateTaskMySqlTest.class, + CombinedInsertTaskMySqlTest.class, + SingleDeleteTaskMySqlTest.class, + SingleInsertTaskMySqlTest.class, + SingleUpdateTaskMySqlTest.class, + QuerySqlTaskMySqlTest.class, + DeleteSqlTaskMySqlTest.class, + UpdateSqlTaskMySqlTest.class, + + ShardedIntArrayResultMergerTest.class, + DalSingleTaskRequestTest.class, + DalBulkTaskRequestTest.class, + DalSingleTaskRequestTest.class, + DalSqlTaskRequestTest.class, + DalBulkTaskContextTest.class, + DalThreadPoolExecutorTest.class +}) +public class _AllTests { + +} diff --git a/dal-client/src/test/java/com/ctrip/platform/dal/dao/unittests/AllTest.java b/dal-client/src/test/java/com/ctrip/platform/dal/dao/unittests/_AllTests.java similarity index 92% rename from dal-client/src/test/java/com/ctrip/platform/dal/dao/unittests/AllTest.java rename to dal-client/src/test/java/com/ctrip/platform/dal/dao/unittests/_AllTests.java index be848de02..003ef9f70 100644 --- a/dal-client/src/test/java/com/ctrip/platform/dal/dao/unittests/AllTest.java +++ b/dal-client/src/test/java/com/ctrip/platform/dal/dao/unittests/_AllTests.java @@ -1,26 +1,26 @@ -package com.ctrip.platform.dal.dao.unittests; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -@RunWith(Suite.class) -@SuiteClasses({ - DalDirectClientMySqlTest.class, - DalDirectClientSqlServerTest.class, - - DalQueryDaoMySqlTest.class, - DalQueryDaoSqlServerTest.class, - - DalTableDaoMySqlTest.class, - DalTableDaoSqlServerTest.class, - - DatabaseSelectorTest.class, - DalClientFactoryTest.class, - DalClientFactoryLazeLoadTest.class, - DalStatusManagerTest.class, - StatementParametersTest.class, - - KeyHolderTest.class, -}) -public class AllTest {} +package com.ctrip.platform.dal.dao.unittests; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +@RunWith(Suite.class) +@SuiteClasses({ + DalDirectClientMySqlTest.class, + DalDirectClientSqlServerTest.class, + + DalQueryDaoMySqlTest.class, + DalQueryDaoSqlServerTest.class, + + DalTableDaoMySqlTest.class, + DalTableDaoSqlServerTest.class, + + DatabaseSelectorTest.class, + DalClientFactoryTest.class, + DalClientFactoryLazeLoadTest.class, + DalStatusManagerTest.class, + StatementParametersTest.class, + + KeyHolderTest.class, +}) +public class _AllTests {} diff --git a/dal-client/src/test/resources/clusterName1.xml b/dal-client/src/test/resources/clustername1.xml similarity index 80% rename from dal-client/src/test/resources/clusterName1.xml rename to dal-client/src/test/resources/clustername1.xml index 98f113fc9..72b5f4fce 100644 --- a/dal-client/src/test/resources/clusterName1.xml +++ b/dal-client/src/test/resources/clustername1.xml @@ -1,11 +1,11 @@ - - + + - - + + diff --git a/dal-client/src/test/resources/clusterName2.xml b/dal-client/src/test/resources/clustername2.xml similarity index 80% rename from dal-client/src/test/resources/clusterName2.xml rename to dal-client/src/test/resources/clustername2.xml index af973a715..c28c1551f 100644 --- a/dal-client/src/test/resources/clusterName2.xml +++ b/dal-client/src/test/resources/clustername2.xml @@ -1,11 +1,11 @@ - - + + - - + + diff --git a/dal-client/src/test/resources/dal-thread-pool-test.xml b/dal-client/src/test/resources/dal-thread-pool-test.xml new file mode 100644 index 000000000..496feac82 --- /dev/null +++ b/dal-client/src/test/resources/dal-thread-pool-test.xml @@ -0,0 +1,49 @@ + + + + + 5 + + + + + + + + + + 3 + + + + + com.ctrip.platform.dal.dao.client.DefaultLogger + + false + dalctripcn + false + 10 + false + + + + com.ctrip.platform.dal.dao.datasource.DefaultDalConnectionLocator + + + D:\dal\database.properties + com.ctrip.platform.dal.dao.configure.PropertyFileConfigureProvider + + + + + 100 + + + + com.ctrip.platform.dal.dao.configure.FreshnessSelector + + com.ctrip.platform.dal.dao.configure.TestFreshnessReader + 2 + + + diff --git a/dal-client/src/test/resources/dal.xml b/dal-client/src/test/resources/dal.xml index fa99a00e9..35b4760ab 100644 --- a/dal-client/src/test/resources/dal.xml +++ b/dal-client/src/test/resources/dal.xml @@ -155,7 +155,7 @@ com.ctrip.platform.dal.dao.datasource.DefaultDalConnectionLocator - D:\dal\database.properties + com.ctrip.platform.dal.dao.configure.PropertyFileConfigureProvider diff --git a/dal-client/src/test/resources/database.properties b/dal-client/src/test/resources/database.properties index fc6417d2d..8e0f7de57 100644 --- a/dal-client/src/test/resources/database.properties +++ b/dal-client/src/test/resources/database.properties @@ -1,4 +1,109 @@ test.userName=testUser test.password=testPassword test.connectionUrl=jdbc:mysql://testIP:3306/testDb -test.driverClassName=com.mysql.jdbc.Driver \ No newline at end of file +test.driverClassName=com.mysql.jdbc.Driver + +ha_test.userName=root +ha_test.password=!QAZ@WSX1qaz2wsx +ha_test.connectionUrl=jdbc:mysql://10.32.20.128:3306/ha_test +ha_test.driverClassName=com.mysql.jdbc.Driver + +ha_test_1.userName=root +ha_test_1.password=!QAZ@WSX1qaz2wsx +ha_test_1.connectionUrl=jdbc:mysql://10.32.20.128:3306/ha_test +ha_test_1.driverClassName=com.mysql.jdbc.Driver + +ha_test_2.userName=root +ha_test_2.password=!QAZ@WSX1qaz2wsx +ha_test_2.connectionUrl=jdbc:mysql://10.32.20.128:3306/ha_test +ha_test_2.driverClassName=com.mysql.jdbc.Driver + +dao_test.userName=root +dao_test.password=!QAZ@WSX1qaz2wsx +dao_test.connectionUrl=jdbc:mysql://10.32.20.128:3306/dao_test +dao_test.driverClassName=com.mysql.jdbc.Driver + +dao_test_sqlsvr.userName=sa +dao_test_sqlsvr.password=!QAZ@WSX1qaz2wsx +dao_test_sqlsvr.connectionUrl=jdbc:sqlserver://10.32.20.128:1433;DatabaseName=daoTest +dao_test_sqlsvr.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver + +dao_test_sqlsvr_0.userName=sa +dao_test_sqlsvr_0.password=!QAZ@WSX1qaz2wsx +dao_test_sqlsvr_0.connectionUrl=jdbc:sqlserver://10.32.20.128:1433;DatabaseName=daoTest +dao_test_sqlsvr_0.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver + +dao_test_sqlsvr_1.userName=sa +dao_test_sqlsvr_1.password=!QAZ@WSX1qaz2wsx +dao_test_sqlsvr_1.connectionUrl=jdbc:sqlserver://10.32.20.128:1433;DatabaseName=daoTest +dao_test_sqlsvr_1.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver + +dao_test_mysql.userName=root +dao_test_mysql.password=!QAZ@WSX1qaz2wsx +dao_test_mysql.connectionUrl=jdbc:mysql://10.32.20.128:3306/dao_test_mysql +dao_test_mysql.driverClassName=com.mysql.jdbc.Driver + +dao_test_mysql_0.userName=root +dao_test_mysql_0.password=!QAZ@WSX1qaz2wsx +dao_test_mysql_0.connectionUrl=jdbc:mysql://10.32.20.128:3306/dao_test_mysql +dao_test_mysql_0.driverClassName=com.mysql.jdbc.Driver + +dao_test_mysql_1.userName=root +dao_test_mysql_1.password=!QAZ@WSX1qaz2wsx +dao_test_mysql_1.connectionUrl=jdbc:mysql://10.32.20.128:3306/dao_test_mysql +dao_test_mysql_1.driverClassName=com.mysql.jdbc.Driver + +dal_test_new.userName=root +dal_test_new.password=!QAZ@WSX1qaz2wsx +dal_test_new.connectionUrl=jdbc:mysql://10.32.20.128:3306/DAL_TEST +dal_test_new.driverClassName=com.mysql.jdbc.Driver + +MySqlShard_0.userName=root +MySqlShard_0.password=!QAZ@WSX1qaz2wsx +MySqlShard_0.connectionUrl=jdbc:mysql://10.32.20.128:3306/Shard_0 +MySqlShard_0.driverClassName=com.mysql.jdbc.Driver + +MySqlShard_1.userName=root +MySqlShard_1.password=!QAZ@WSX1qaz2wsx +MySqlShard_1.connectionUrl=jdbc:mysql://10.32.20.128:3306/Shard_1 +MySqlShard_1.driverClassName=com.mysql.jdbc.Driver + +SqlSvrShard_0.userName=sa +SqlSvrShard_0.password=!QAZ@WSX1qaz2wsx +SqlSvrShard_0.connectionUrl=jdbc:sqlserver://10.32.20.128:1433;DatabaseName=Shard_0 +SqlSvrShard_0.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver + +SqlSvrShard_1.userName=sa +SqlSvrShard_1.password=!QAZ@WSX1qaz2wsx +SqlSvrShard_1.connectionUrl=jdbc:sqlserver://10.32.20.128:1433;DatabaseName=Shard_1 +SqlSvrShard_1.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver + +OracleShard_0.userName=SYSTEM +OracleShard_0.password=Admin1234 +OracleShard_0.connectionUrl=jdbc:oracle:thin:@127.0.0.1:1521:SHARD0 +OracleShard_0.driverClassName=oracle.jdbc.driver.OracleDriver + +OracleShard_1.userName=SYSTEM +OracleShard_1.password=Admin1234 +OracleShard_1.connectionUrl=jdbc:oracle:thin:@127.0.0.1:1521:SHARD1 +OracleShard_1.driverClassName=oracle.jdbc.driver.OracleDriver + +dao_test_select.userName=root +dao_test_select.password=!QAZ@WSX1qaz2wsx +dao_test_select.connectionUrl=jdbc:mysql://10.32.20.128:3306/dao_test +dao_test_select.driverClassName=com.mysql.jdbc.Driver + +dal_shard_0.userName=root +dal_shard_0.password=!QAZ@WSX1qaz2wsx +dal_shard_0.connectionUrl=jdbc:mysql://10.32.20.128:3306/dal_shard_0 +dal_shard_0.driverClassName=com.mysql.jdbc.Driver + +dal_shard_1.userName=root +dal_shard_1.password=!QAZ@WSX1qaz2wsx +dal_shard_1.connectionUrl=jdbc:mysql://10.32.20.128:3306/dal_shard_1 +dal_shard_1.driverClassName=com.mysql.jdbc.Driver + +allinonelessdatasource.userName=root +allinonelessdatasource.password=!QAZ@WSX1qaz2wsx +allinonelessdatasource.connectionUrl=jdbc:mysql://10.32.20.128:3306/Shard_0?useUnicode=true&characterEncoding=UTF-8 +allinonelessdatasource.driverClassName=com.mysql.jdbc.Driver diff --git a/dal-client/src/test/resources/NonShardingCluster.xml b/dal-client/src/test/resources/nonshardingcluster.xml similarity index 57% rename from dal-client/src/test/resources/NonShardingCluster.xml rename to dal-client/src/test/resources/nonshardingcluster.xml index 4f5ee5c43..b6e181a56 100644 --- a/dal-client/src/test/resources/NonShardingCluster.xml +++ b/dal-client/src/test/resources/nonshardingcluster.xml @@ -1,8 +1,8 @@ - - + + diff --git a/dal-client/src/test/resources/readme.txt b/dal-client/src/test/resources/readme.txt index dc75d61b2..2fb76f2f0 100644 --- a/dal-client/src/test/resources/readme.txt +++ b/dal-client/src/test/resources/readme.txt @@ -7,6 +7,6 @@ To run test: * replace testDbSvrIp with real server ip * provide user name, password for each database * set user name, password, connection url for each database -* run test.com.ctrip.platform.dal.dao.AllTest as test case +* run test.com.ctrip.platform.dal.dao.AllTests as test case * it usually takes 10 to 20 minutes to finish all the tests * have fun! \ No newline at end of file diff --git a/dal-client/src/test/resources/TestCluster.xml b/dal-client/src/test/resources/testcluster.xml similarity index 80% rename from dal-client/src/test/resources/TestCluster.xml rename to dal-client/src/test/resources/testcluster.xml index 992974dad..d1acd7b10 100644 --- a/dal-client/src/test/resources/TestCluster.xml +++ b/dal-client/src/test/resources/testcluster.xml @@ -1,11 +1,11 @@ - - + + - - + + diff --git a/dal-cluster-client/pom.xml b/dal-cluster-client/pom.xml index b169e0829..085234c60 100644 --- a/dal-cluster-client/pom.xml +++ b/dal-cluster-client/pom.xml @@ -6,7 +6,7 @@ com.ctrip.platform dal-client-parent - 2.0.19 + 2.1.6 com.ctrip.framework.dal dal-cluster-client diff --git a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/Cluster.java b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/Cluster.java index 0f9902db1..e24832a5e 100644 --- a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/Cluster.java +++ b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/Cluster.java @@ -3,6 +3,7 @@ import com.ctrip.framework.dal.cluster.client.base.Listenable; import com.ctrip.framework.dal.cluster.client.cluster.ClusterSwitchedEvent; import com.ctrip.framework.dal.cluster.client.cluster.ClusterType; +import com.ctrip.framework.dal.cluster.client.config.LocalizationConfig; import com.ctrip.framework.dal.cluster.client.database.Database; import com.ctrip.framework.dal.cluster.client.database.DatabaseCategory; import com.ctrip.framework.dal.cluster.client.sharding.context.DbShardContext; @@ -46,4 +47,6 @@ public interface Cluster extends Listenable, Wrapper { ClusterIdGeneratorConfig getIdGeneratorConfig(); + LocalizationConfig getLocalizationConfig(); + } diff --git a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/cluster/DefaultCluster.java b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/cluster/DefaultCluster.java index 4bee2a982..e59e64bb6 100644 --- a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/cluster/DefaultCluster.java +++ b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/cluster/DefaultCluster.java @@ -3,6 +3,7 @@ import com.ctrip.framework.dal.cluster.client.Cluster; import com.ctrip.framework.dal.cluster.client.base.UnsupportedListenable; import com.ctrip.framework.dal.cluster.client.config.ClusterConfigImpl; +import com.ctrip.framework.dal.cluster.client.config.LocalizationConfig; import com.ctrip.framework.dal.cluster.client.database.Database; import com.ctrip.framework.dal.cluster.client.database.DatabaseCategory; import com.ctrip.framework.dal.cluster.client.exception.ClusterRuntimeException; @@ -24,6 +25,7 @@ public class DefaultCluster extends UnsupportedListenable private Map databaseShards = new HashMap<>(); private ShardStrategyProxy shardStrategyProxy; private ClusterIdGeneratorConfig idGeneratorConfig; + private LocalizationConfig localizationConfig; public DefaultCluster(ClusterConfigImpl clusterConfig) { this.clusterConfig = clusterConfig; @@ -104,6 +106,11 @@ public ClusterIdGeneratorConfig getIdGeneratorConfig() { return idGeneratorConfig; } + @Override + public LocalizationConfig getLocalizationConfig() { + return localizationConfig; + } + public void addDatabaseShard(DatabaseShard databaseShard) { databaseShards.put(databaseShard.getShardIndex(), databaseShard); } @@ -116,6 +123,12 @@ public void setIdGeneratorConfig(ClusterIdGeneratorConfig idGeneratorConfig) { this.idGeneratorConfig = idGeneratorConfig; } + public void setLocalizationConfig(LocalizationConfig localizationConfig) { + this.localizationConfig = localizationConfig; + } + + public void validate() {} + @Override public T unwrap(Class iface) throws SQLException { try { diff --git a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/cluster/DefaultDrcCluster.java b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/cluster/DefaultDrcCluster.java index 350f899a6..55a04b015 100644 --- a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/cluster/DefaultDrcCluster.java +++ b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/cluster/DefaultDrcCluster.java @@ -2,24 +2,23 @@ import com.ctrip.framework.dal.cluster.client.config.ClusterConfigImpl; import com.ctrip.framework.dal.cluster.client.config.LocalizationConfig; +import com.ctrip.framework.dal.cluster.client.exception.ClusterConfigException; public class DefaultDrcCluster extends DefaultCluster implements DrcCluster { - private LocalizationConfig localizationConfig; - - public DefaultDrcCluster(ClusterConfigImpl clusterConfig, LocalizationConfig localizationConfig) { + public DefaultDrcCluster(ClusterConfigImpl clusterConfig) { super(clusterConfig); - this.localizationConfig = localizationConfig; } @Override - public ClusterType getClusterType() { - return ClusterType.DRC; + public void validate() { + if (getLocalizationConfig() == null || getLocalizationConfig().getUnitStrategyId() == null) + throw new ClusterConfigException("Missing ucs strategy for drc cluster: " + getClusterName()); } @Override - public LocalizationConfig getLocalizationConfig() { - return localizationConfig; + public ClusterType getClusterType() { + return ClusterType.DRC; } } diff --git a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/cluster/DrcCluster.java b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/cluster/DrcCluster.java index 929be7d6b..c95e906cc 100644 --- a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/cluster/DrcCluster.java +++ b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/cluster/DrcCluster.java @@ -7,7 +7,4 @@ * @author c7ch23en */ public interface DrcCluster extends Cluster { - - LocalizationConfig getLocalizationConfig(); - } diff --git a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/ClusterConfigImpl.java b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/ClusterConfigImpl.java index 3e2096d18..a3389a68e 100644 --- a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/ClusterConfigImpl.java +++ b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/ClusterConfigImpl.java @@ -65,7 +65,7 @@ public Cluster getOrCreateCluster() { private Cluster innerGenerate() { DefaultCluster cluster = (clusterType == ClusterType.NORMAL ? - new DefaultCluster(this) : new DefaultDrcCluster(this, generateLocalizationConfig())); + new DefaultCluster(this) : new DefaultDrcCluster(this)); for (DatabaseShardConfig databaseShardConfig : databaseShardConfigs) cluster.addDatabaseShard(databaseShardConfig.generate()); ShardStrategyProxy shardStrategy = new ShardStrategyProxy(defaultShardStrategy); @@ -73,15 +73,11 @@ private Cluster innerGenerate() { shardStrategy.addStrategy(strategy); cluster.setShardStrategy(shardStrategy); cluster.setIdGeneratorConfig(idGeneratorConfig); + cluster.setLocalizationConfig(new LocalizationConfigImpl(unitStrategyId, zoneId)); + cluster.validate(); return cluster; } - private LocalizationConfig generateLocalizationConfig() { - if (unitStrategyId == null) - throw new ClusterConfigException("unitStrategyId is necessary for drc cluster"); - return new LocalizationConfigImpl(unitStrategyId, zoneId); - } - @Override public boolean checkSwitchable(ClusterConfig newConfig) { if (newConfig instanceof ClusterConfigImpl) { diff --git a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/ClusterConfigXMLParser.java b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/ClusterConfigXMLParser.java index d8617c5a9..5b3a8eec5 100644 --- a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/ClusterConfigXMLParser.java +++ b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/ClusterConfigXMLParser.java @@ -10,7 +10,7 @@ import com.ctrip.framework.dal.cluster.client.sharding.strategy.ModShardStrategy; import com.ctrip.framework.dal.cluster.client.sharding.strategy.ShardStrategy; import com.ctrip.framework.dal.cluster.client.sharding.strategy.UserHintStrategy; -import com.ctrip.framework.dal.cluster.client.util.ServiceLoaderUtils; +import com.ctrip.framework.dal.cluster.client.util.SPIUtils; import com.ctrip.framework.dal.cluster.client.util.StringUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -91,8 +91,7 @@ private ClusterConfig parseCluster(Node clusterNode) { if (idGeneratorsNode != null) parseIdGenerators(clusterConfig, idGeneratorsNode); - if (clusterType == ClusterType.DRC) - parseDrcConfig(clusterConfig, clusterNode); + parseDrcConfig(clusterConfig, clusterNode); return clusterConfig; } @@ -282,7 +281,7 @@ private IdGeneratorConfigXMLParser getIdGeneratorConfigXMLParser() { if (idGeneratorConfigXMLParser == null) { synchronized (this) { if (idGeneratorConfigXMLParser == null) { - idGeneratorConfigXMLParser = ServiceLoaderUtils.getInstance(IdGeneratorConfigXMLParser.class); + idGeneratorConfigXMLParser = SPIUtils.getInstance(IdGeneratorConfigXMLParser.class); if (idGeneratorConfigXMLParser == null) throw new ClusterRuntimeException("load IdGeneratorConfigXMLParser failed"); } diff --git a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/DefaultLocalConfigProvider.java b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/DefaultLocalConfigProvider.java index e2898b88e..b9c07f47a 100644 --- a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/DefaultLocalConfigProvider.java +++ b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/DefaultLocalConfigProvider.java @@ -1,6 +1,7 @@ package com.ctrip.framework.dal.cluster.client.config; import com.ctrip.framework.dal.cluster.client.exception.ClusterConfigException; +import com.ctrip.framework.dal.cluster.client.util.FileUtils; import java.io.InputStream; import java.net.URL; @@ -10,22 +11,30 @@ */ public class DefaultLocalConfigProvider implements ClusterConfigProvider { - private String fileName; - private ClusterConfigParser parser = new ClusterConfigXMLParser(); + private final String clusterName; + private final ClusterConfigParser parser; public DefaultLocalConfigProvider(String clusterName) { - this.fileName = clusterName + ".xml"; + this(clusterName, new ClusterConfigXMLParser()); + } + + public DefaultLocalConfigProvider(String clusterName, ClusterConfigParser parser) { + this.clusterName = clusterName; + this.parser = parser; } @Override public ClusterConfig getClusterConfig() { - try { - URL url = DefaultLocalConfigProvider.class.getClassLoader().getResource(fileName); - InputStream is = url.openStream(); + try (InputStream is = FileUtils.getResourceInputStream(getConfigFileName(), + DefaultLocalConfigProvider.class.getClassLoader())) { return parser.parse(is); } catch (Throwable t) { - throw new ClusterConfigException(t); + throw new ClusterConfigException("Load cluster config failed, cluster name: " + clusterName, t); } } + protected String getConfigFileName() { + return clusterName != null ? clusterName + ".xml" : null; + } + } diff --git a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/LocalizationConfig.java b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/LocalizationConfig.java index 890866864..0cc057e15 100644 --- a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/LocalizationConfig.java +++ b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/LocalizationConfig.java @@ -5,7 +5,7 @@ */ public interface LocalizationConfig { - int getUnitStrategyId(); + Integer getUnitStrategyId(); String getZoneId(); diff --git a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/LocalizationConfigImpl.java b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/LocalizationConfigImpl.java index 3108bff28..b724e2f78 100644 --- a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/LocalizationConfigImpl.java +++ b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/config/LocalizationConfigImpl.java @@ -5,16 +5,16 @@ */ public class LocalizationConfigImpl implements LocalizationConfig { - private int unitStrategyId; + private Integer unitStrategyId; private String zoneId; - public LocalizationConfigImpl(int unitStrategyId, String zoneId) { + public LocalizationConfigImpl(Integer unitStrategyId, String zoneId) { this.unitStrategyId = unitStrategyId; this.zoneId = zoneId; } @Override - public int getUnitStrategyId() { + public Integer getUnitStrategyId() { return unitStrategyId; } diff --git a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/util/FileUtils.java b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/util/FileUtils.java new file mode 100644 index 000000000..d4d958f6e --- /dev/null +++ b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/util/FileUtils.java @@ -0,0 +1,39 @@ +package com.ctrip.framework.dal.cluster.client.util; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.*; + +/** + * @author c7ch23en + */ +public class FileUtils { + + public static InputStream getResourceInputStream(String fileName) throws IOException { + return getResourceInputStream(fileName, Thread.currentThread().getContextClassLoader()); + } + + public static InputStream getResourceInputStream(String fileName, ClassLoader classLoader) throws IOException { + if (classLoader == null) + throw new RuntimeException("Class loader is null"); + Set candidateFileNames = getCandidateFileNames(fileName); + for (String candidateFileName : candidateFileNames) { + URL url = classLoader.getResource(candidateFileName); + if (url != null) + return url.openStream(); + } + throw new RuntimeException("Resource not found, candidate file names: " + candidateFileNames); + } + + private static Set getCandidateFileNames(String fileName) { + if (fileName == null) + return new HashSet<>(); + Set candidateFileNames = new LinkedHashSet<>(); + candidateFileNames.add(fileName); + candidateFileNames.add(fileName.toLowerCase()); + candidateFileNames.add(fileName.toUpperCase()); + return candidateFileNames; + } + +} diff --git a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/util/ObjectHolder.java b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/util/ObjectHolder.java new file mode 100644 index 000000000..88a7be99f --- /dev/null +++ b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/util/ObjectHolder.java @@ -0,0 +1,49 @@ +package com.ctrip.framework.dal.cluster.client.util; + +import java.util.concurrent.atomic.AtomicReference; + +/** + * @author c7ch23en + */ +public class ObjectHolder { + + private final AtomicReference objectRef; + + public ObjectHolder() { + objectRef = new AtomicReference<>(); + } + + public ObjectHolder(T initialObject) { + objectRef = new AtomicReference<>(initialObject); + } + + public T getOrCreate(Creator creator) { + T object = objectRef.get(); + if (object == null) + synchronized (objectRef) { + object = objectRef.get(); + if (object == null && creator != null) { + object = creator.create(); + objectRef.set(object); + } + } + return object; + } + + public T getAndSet(T newObject) { + return objectRef.getAndSet(newObject); + } + + public T get() { + return objectRef.get(); + } + + public void set(T newObject) { + objectRef.set(newObject); + } + + public interface Creator { + T create(); + } + +} diff --git a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/util/ServiceLoaderUtils.java b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/util/SPIUtils.java similarity index 90% rename from dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/util/ServiceLoaderUtils.java rename to dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/util/SPIUtils.java index 37b56d724..8ffa02731 100644 --- a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/util/ServiceLoaderUtils.java +++ b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/util/SPIUtils.java @@ -8,9 +8,9 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; -public class ServiceLoaderUtils { +public class SPIUtils { - private static final Logger LOGGER = LoggerFactory.getLogger(ServiceLoaderUtils.class); + private static final Logger LOGGER = LoggerFactory.getLogger(SPIUtils.class); private static Map, Object> allServices = new ConcurrentHashMap<>(); @@ -41,7 +41,7 @@ public static T getInstance(Class clazz) { } private static Iterator getIterator(Class clazz) { - ServiceLoader loader = ServiceLoader.load(clazz, ServiceLoaderUtils.class.getClassLoader()); + ServiceLoader loader = ServiceLoader.load(clazz, SPIUtils.class.getClassLoader()); return loader.iterator(); } diff --git a/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/util/ValueWrapper.java b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/util/ValueWrapper.java new file mode 100644 index 000000000..b791d1b81 --- /dev/null +++ b/dal-cluster-client/src/main/java/com/ctrip/framework/dal/cluster/client/util/ValueWrapper.java @@ -0,0 +1,18 @@ +package com.ctrip.framework.dal.cluster.client.util; + +/** + * @author c7ch23en + */ +public class ValueWrapper { + + private final V value; + + public ValueWrapper(V value) { + this.value = value; + } + + public V getValue() { + return value; + } + +} diff --git a/dal-cluster-client/src/test/java/com/ctrip/framework/dal/cluster/client/AllTests.java b/dal-cluster-client/src/test/java/com/ctrip/framework/dal/cluster/client/AllTests.java index 01f545917..bdb493955 100644 --- a/dal-cluster-client/src/test/java/com/ctrip/framework/dal/cluster/client/AllTests.java +++ b/dal-cluster-client/src/test/java/com/ctrip/framework/dal/cluster/client/AllTests.java @@ -2,6 +2,7 @@ import com.ctrip.framework.dal.cluster.client.cluster.DefaultClusterTest; import com.ctrip.framework.dal.cluster.client.cluster.DefaultLocalConfigProviderTest; +import com.ctrip.framework.dal.cluster.client.util.ObjectHolderTest; import org.junit.runner.RunWith; import org.junit.runners.Suite; @@ -11,7 +12,8 @@ @RunWith(Suite.class) @Suite.SuiteClasses({ DefaultClusterTest.class, - DefaultLocalConfigProviderTest.class + DefaultLocalConfigProviderTest.class, + ObjectHolderTest.class }) public class AllTests { } diff --git a/dal-cluster-client/src/test/java/com/ctrip/framework/dal/cluster/client/util/ObjectHolderTest.java b/dal-cluster-client/src/test/java/com/ctrip/framework/dal/cluster/client/util/ObjectHolderTest.java new file mode 100644 index 000000000..50275c605 --- /dev/null +++ b/dal-cluster-client/src/test/java/com/ctrip/framework/dal/cluster/client/util/ObjectHolderTest.java @@ -0,0 +1,31 @@ +package com.ctrip.framework.dal.cluster.client.util; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author c7ch23en + */ +public class ObjectHolderTest { + + @Test + public void testObjectHolder() { + ObjectHolder holder = new ObjectHolder<>(); + + Assert.assertNull(holder.get()); + Assert.assertNull(holder.getAndSet(new Object())); + Assert.assertNotNull(holder.get()); + holder.set(null); + Assert.assertNull(holder.getAndSet(null)); + + Object obj1 = new Object(); + Object holdObj = holder.getOrCreate(() -> obj1); + Assert.assertEquals(obj1, holdObj); + + Object obj2 = new Object(); + holdObj = holder.getOrCreate(() -> obj2); + Assert.assertNotEquals(obj2, holdObj); + Assert.assertEquals(obj1, holdObj); + } + +} diff --git a/dal-dao-gen/pom.xml b/dal-dao-gen/pom.xml index 9dfa7c989..de4ca0052 100644 --- a/dal-dao-gen/pom.xml +++ b/dal-dao-gen/pom.xml @@ -1,23 +1,27 @@ - - + 4.0.0 - com.ctrip.platform + + com.ctrip.platform + dal-client-parent + 2.1.6 + dal-dao-gen - 1.16.17 war + open - UTF-8 - 1.16.17 + com.ctrip.platform dao-gen-core - ${dao-gen-core-version} + open @@ -32,6 +36,7 @@ + @@ -45,20 +50,7 @@ src/main/resources/log - ROOT - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.0 - - 1.8 - 1.8 - UTF-8 - true - true - - org.apache.maven.plugins maven-resources-plugin @@ -89,37 +81,6 @@ - - org.apache.maven.plugins - maven-source-plugin - 2.4 - - - attach-sources - install - - jar - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.8.1 - - ${file_encoding} - - - - attach-javadocs - install - - jar - - - - diff --git a/dal-dao-gen/src/main/java/com/ctrip/platform/dal/daogen/resource/DalUserResource.java b/dal-dao-gen/src/main/java/com/ctrip/platform/dal/daogen/resource/DalUserResource.java index 5f9d66616..c712c4ede 100644 --- a/dal-dao-gen/src/main/java/com/ctrip/platform/dal/daogen/resource/DalUserResource.java +++ b/dal-dao-gen/src/main/java/com/ctrip/platform/dal/daogen/resource/DalUserResource.java @@ -414,9 +414,9 @@ public void logOut(@Context HttpServletRequest request, @Context HttpServletResp @POST @Path("getDefaultDBInfo") - public DalGroupDB getDefaultDBInfo(@FormParam("dbType") String dbType) throws Exception { + public DalGroupDB getDefaultDBInfo(@FormParam("dbType") String dbType, @FormParam("dbName") String dbName) throws Exception { try { - return CustomizedResource.getInstance().getDefaultDBInfo(dbType); + return CustomizedResource.getInstance().getDefaultDBInfo(dbType, dbName); } catch (Throwable e) { LoggerManager.getInstance().error(e); throw e; diff --git a/dal-dao-gen/src/main/java/com/ctrip/platform/dal/daogen/resource/DatabaseResource.java b/dal-dao-gen/src/main/java/com/ctrip/platform/dal/daogen/resource/DatabaseResource.java index 033ad0bd8..6085ffe7f 100644 --- a/dal-dao-gen/src/main/java/com/ctrip/platform/dal/daogen/resource/DatabaseResource.java +++ b/dal-dao-gen/src/main/java/com/ctrip/platform/dal/daogen/resource/DatabaseResource.java @@ -11,6 +11,7 @@ import com.ctrip.platform.dal.daogen.utils.*; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.lang.StringUtils; import javax.annotation.Resource; import javax.inject.Singleton; @@ -18,10 +19,14 @@ import javax.ws.rs.*; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; +import java.io.IOException; +import java.io.InputStream; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; @Resource @Singleton @@ -29,6 +34,9 @@ public class DatabaseResource { private static ClassLoader classLoader; private static ObjectMapper mapper = new ObjectMapper(); + private static final Pattern dbnamePattern = Pattern.compile("(database|initial\\scatalog)=([^;]+)", 2); + private final String CONF_PROPERTIES = "conf.properties"; + private final String USER_INFO_CLASS_NAME = "userinfo_class"; static { classLoader = Thread.currentThread().getContextClassLoader(); @@ -94,14 +102,16 @@ public Status mergeDB(@Context HttpServletRequest request) throws Exception { @Path("connectionTest") public Status connectionTest(@FormParam("dbtype") String dbtype, @FormParam("dbaddress") String dbaddress, @FormParam("dbport") String dbport, @FormParam("dbuser") String dbuser, - @FormParam("dbpassword") String dbpassword) throws Exception { + @FormParam("dbpassword") String dbpassword, @FormParam("dbName") String dbName) throws Exception { Connection conn = null; ResultSet rs = null; try { Status status = Status.OK(); try { + String info=String.format("connectionTest:%s,user:%s,pwd:%s,dbname:%s,dbtype:%s",dbaddress,dbpassword,dbuser,dbName,dbtype); + LoggerManager.getInstance().info(info); conn = DataSourceUtil.getConnection(dbaddress, dbport, dbuser, dbpassword, - DatabaseType.valueOf(dbtype).getValue()); + DatabaseType.valueOf(dbtype).getValue(), dbName); // conn.setNetworkTimeout(Executors.newFixedThreadPool(1), 5000); rs = conn.getMetaData().getCatalogs(); Set allCatalog = new HashSet(); @@ -130,6 +140,54 @@ public Status connectionTest(@FormParam("dbtype") String dbtype, @FormParam("dba } } + @POST + @Produces(MediaType.APPLICATION_JSON) + @Path("getAllDB") + public Status getAllDB(@FormParam("dbType") String dbType) { + try { + Status status = Status.OK(); + String className = CustomizedResource.getInstance().getDBLevelInfoApiClassName(); + if (StringUtils.isNotBlank(className)) { + Class clazz = Class.forName(className); + DBInfoApi dbInfoApi = (DBInfoApi) clazz.newInstance(); + List dbLevelInfos = dbInfoApi.getDBLevelInfo(dbType); + List allDBs = new ArrayList<>(); + for (DBLevelInfo dbLevelInfo : dbLevelInfos) { + allDBs.add(dbLevelInfo.getDb_name()); + } + status.setInfo(mapper.writeValueAsString(allDBs)); + } + return status; + } catch (Exception e) { + LoggerManager.getInstance().error(e); + Status status = Status.ERROR(); + status.setInfo(e.getMessage()); + return status; + } + } + + @POST + @Produces(MediaType.APPLICATION_JSON) + @Path("getTitanKeyByDBName") + public Status getTitanKeyByDBName(@FormParam("dbName") String dbName) { + + try { + Status status = Status.OK(); + String className = CustomizedResource.getInstance().getAllInOneKeyApiClassName(); + if (StringUtils.isNotBlank(className)) { + Class clazz = Class.forName(className); + AllInOneKeyApi allInOneKeyApi = (AllInOneKeyApi) clazz.newInstance(); + status.setInfo(mapper.writeValueAsString(allInOneKeyApi.getAllInOneKeys(dbName))); + } + return status; + } catch (Exception e) { + LoggerManager.getInstance().error(e); + Status status = Status.ERROR(); + status.setInfo(e.getMessage()); + return status; + } + } + @POST @Produces(MediaType.APPLICATION_JSON) @Path("addNewAllInOneDB") @@ -527,7 +585,7 @@ private List filterSP(List tables, List + +
+
+ +
+
+
-
-
- -
-
+
+
+
+ +
+
-
-
- -
-
+ Name:
diff --git a/dal-dao-gen/src/main/webapp/static/js/dbview.js b/dal-dao-gen/src/main/webapp/static/js/dbview.js index a6c6d453b..39754fedd 100644 --- a/dal-dao-gen/src/main/webapp/static/js/dbview.js +++ b/dal-dao-gen/src/main/webapp/static/js/dbview.js @@ -1,745 +1,923 @@ -(function ($, window, document, undefined) { - var Render = function () { - }; - - function refreshAllDB() { - w2ui['grid'].clear(); - cblock($("body")); - $.get("/rest/groupdb/allgroupdbs", {rand: Math.random()}, function (data) { - var allGroupDbs = []; - $.each(data, function (index, value) { - value.recid = allGroupDbs.length + 1; - allGroupDbs.push(value); - }); - w2ui['grid'].add(allGroupDbs); - $("body").unblock(); - }).fail(function (data) { - $("body").unblock(); - alert("获取所有Group失败!"); - }); - }; - - function addDB() { - $.get("/rest/project/userGroups", {root: true, rand: Math.random()}).done(function (data) { - if (data.length > 0 && data[0]['id'] > 0) { - $("#error_msg").html(''); - $("#add_new_db_step1").show(); - $("#add_new_db_step2").hide(); - $("#conn_test").show(); - $("#add_new_db_next").show(); - $("#add_new_db_prev").hide(); - $("#add_new_db_save").hide(); - var dbcatalog = $("#dbcatalog"); - if (dbcatalog[0] != undefined && dbcatalog[0].selectize != undefined) { - dbcatalog[0].selectize.clearOptions(); - } else { - dbcatalog.selectize({ - valueField: 'id', - labelField: 'title', - searchField: 'title', - sortField: 'title', - options: [], - create: false - }); - } - var dalgroup = $("#dalgroup"); - if (dalgroup[0] != undefined && dalgroup[0].selectize != undefined) { - dalgroup[0].selectize.clearOptions(); - } - else { - dalgroup.selectize({ - valueField: 'id', - labelField: 'title', - searchField: 'title', - sortField: 'title', - options: [], - create: false - }); - } - $("#addDbModal").modal({"backdrop": "static"}); - } else { - alert("请先加入一个DAL Team."); - } - $("body").unblock(); - }).fail(function (data) { - alert('获取用户加入的所有DAL Team失败.'); - $("body").unblock(); - }); - }; - - function editDB() { - $("#update_error_msg").html(''); - $("#update_db_step1").show(); - $("#update_db_step2").hide(); - $("#update_conn_test").show(); - $("#update_db_next").show(); - $("#update_db_prev").hide(); - $("#update_db_save").hide(); - var records = w2ui['grid'].getSelection(); - var record = w2ui['grid'].get(records[0]); - if (record == null) { - alert('请先选择一个 database'); - return; - } - cblock($("body")); - $.post("/rest/db/getOneDB", {allinonename: record['dbname']}, function (data) { - if (data.code == "OK") { - var db = $.parseJSON(data.info); - $("#dbtype_up").val(db['db_providerName']); - $("#dbaddress_up").val(db['db_address']); - $("#dbport_up").val(db['db_port']); - $("#dbuser_up").val(db['db_user']); - $("#dbpassword_up").val(db['db_password']); - $("#allinonename_up").val(db['dbname']); - if ($("#dbcatalog_up")[0] != undefined && $("#dbcatalog_up")[0].selectize != undefined) { - $("#dbcatalog_up")[0].selectize.clearOptions(); - } else { - $("#dbcatalog_up").selectize({ - valueField: 'id', - labelField: 'title', - searchField: 'title', - sortField: 'title', - options: [], - create: false - }); - } - $("#updateDbModal").modal({"backdrop": "static"}); - } else { - $("#errorMess").html(data.info); - $("#errorNoticeDiv").modal({"backdrop": "static"}); - } - $("body").unblock(); - }).fail(function (data) { - alert("执行异常"); - $("body").unblock(); - }); - }; - - function delDB() { - var records = w2ui['grid'].getSelection(); - var record = w2ui['grid'].get(records[0]); - if (record != null) { - if (confirm("您确定要删除吗?")) { - $.post("/rest/db/deleteAllInOneDB", {allinonename: record['dbname']}, function (data) { - if (data.code == "OK") { - refreshAllDB(); - } else { - $("#errorMess").html(data.info); - $("#errorNoticeDiv").modal({"backdrop": "static"}); - } - }).fail(function (data) { - alert("执行异常"); - $("body").unblock(); - }); - } - } else { - alert('请选择一个database!'); - } - }; - - function isDefaultUser() { - cblock($("body")); - $.get("/rest/user/isDefaultUser", {rand: Math.random()}, function (data) { - if (data == "true") { - $("#validateKeyname").hide(); - } - $("body").unblock(); - }); - } - - Render.prototype = { - render_layout: function (render_obj) { - $(render_obj).w2layout({ - name: 'main_layout', - panels: [{type: 'main'}] - }); - }, - render_grid: function () { - var existsGrid = w2ui['grid']; - if (existsGrid != undefined) { - return; - } - - w2ui['main_layout'].content('main', $().w2grid({ - name: 'grid', - show: { - toolbar: true, - footer: true, - toolbarReload: false, - toolbarColumns: false, - toolbarAdd: false, - toolbarDelete: false, - toolbarEdit: false - }, - toolbar: { - items: [{ - type: 'break' - }, { - type: 'button', - id: 'refreshAllDB', - caption: '刷新', - icon: 'glyphicon glyphicon-refresh' - }, { - type: 'button', - id: 'addDB', - caption: '添加DB', - icon: 'glyphicon glyphicon-plus' - }, { - type: 'button', - id: 'editDB', - caption: '修改DB', - icon: 'glyphicon glyphicon-edit' - }, { - type: 'button', - id: 'delDB', - caption: '删除DB', - icon: 'glyphicon glyphicon-remove' - }], - onClick: function (target, data) { - switch (target) { - case 'refreshAllDB': - refreshAllDB(); - break; - case 'addDB': - addDB(); - break; - case 'editDB': - editDB(); - break; - case 'delDB': - delDB(); - break; - } - } - }, - searches: [{ - field: 'dbname', - caption: 'DB Name', - type: 'text' - }, { - field: 'comment', - caption: '所属 DAL Team', - type: 'text' - }, { - field: 'db_address', - caption: 'DB Address', - type: 'text' - }, { - field: 'db_catalog', - caption: 'DB Catalog', - type: 'text' - }, { - field: 'db_providerName', - caption: '数据库类型', - type: 'text' - }], - columns: [{ - field: 'dbname', - caption: 'DB All-In-One Name', - size: '20%', - attr: 'align=center', - sortable: true, - resizable: true - }, { - field: 'comment', - caption: '所属 DAL Team', - size: '15%', - attr: 'align=center', - sortable: true, - resizable: true - }, { - field: 'db_address', - caption: 'DB Address', - size: '15%', - attr: 'align=center', - sortable: true, - resizable: true - }, { - field: 'db_port', - caption: 'DB Port', - size: '5%', - attr: 'align=center', - sortable: true, - resizable: true - }, { - field: 'db_user', - caption: 'DB User', - size: '10%', - attr: 'align=center', - sortable: true, - resizable: true - }, { - field: 'db_password', - caption: 'DB Password', - size: '10%', - attr: 'align=center', - sortable: true, - resizable: true - }, { - field: 'db_catalog', - caption: 'DB Catalog', - size: '15%', - attr: 'align=center', - sortable: true, - resizable: true - }, { - field: 'db_providerName', - caption: '数据库类型', - size: '10%', - attr: 'align=center', - sortable: true, - resizable: true - }], - records: [] - })); - - refreshAllDB(); - } - }; - - window.render = new Render(); - $('#main_layout').height($(document).height() - 50); - window.render.render_layout($('#main_layout')); - window.render.render_grid(); - - $(window).resize(function () { - $('#main_layout').height($(document).height() - 50); - }); - - $(function () { - var setDefaultDbVal = function () { - $("#error_msg").html(" "); - var dbType = $.trim($("#dbtype").val()); - - $.post("/rest/user/getDefaultDBInfo", { - dbType: dbType - }, function (data) { - $("#dbaddress").val(data.db_address); - $("#dbport").val(data.db_port); - $("#dbuser").val(data.db_user); - $("#dbpassword").val(data.db_password); - }); - }; - - var getAllCatalog = function (successInfo) { - var dbType = $("#dbtype").val(); - var dbAddress = $("#dbaddress").val(); - var dbPort = $("#dbport").val(); - var dbUser = $("#dbuser").val(); - var dbPassword = $("#dbpassword").val(); - var dbcatalog = $("#dbcatalog"); - var error_msg = $("#error_msg"); - error_msg.html("正在连接数据库,请稍等..."); - var result = true; - - $.ajax({ - type: "POST", - url: "/rest/db/connectionTest", - data: { - dbtype: dbType, - dbaddress: dbAddress, - dbport: dbPort, - dbuser: dbUser, - dbpassword: dbPassword - }, - async: false, - success: function (data) { - if (data.code == "OK") { - var allCatalog = []; - $.each($.parseJSON(data.info), function (index, value) { - allCatalog.push({ - id: value, title: value - }); - }); - dbcatalog[0].selectize.clearOptions(); - dbcatalog[0].selectize.addOption(allCatalog); - dbcatalog[0].selectize.refreshOptions(false); - error_msg.html(successInfo); - } else { - error_msg.html("连接失败:" + data.info); - result = false; - } - } - }); - - return result; - }; - - var getUserGroups = function () { - var dalgroup = $("#dalgroup"); - $.get("/rest/member", function (data) { - if (data != undefined && data != null) { - if (data.length > 1) { - var groups = []; - $.each(data, function (index, value) { - groups.push({ - id: value.id, title: value.group_name - }); - }); - dalgroup[0].selectize.clearOptions(); - dalgroup[0].selectize.addOption(groups); - dalgroup[0].selectize.refreshOptions(false); - } - else { - $("#dalgroupspan").hide(); - } - } - }); - }; - - $(document.body).on("change", "#dbtype", function () { - $.get("/rest/user/isDefaultUser", {rand: Math.random()}, function (data) { - if (data == "false") { - setDefaultDbVal(); - } - }); - }); - - $(document.body).on("click", "#add_new_db_next", function () { - var dbType = $("#dbtype").val(); - var dbAddress = $("#dbaddress").val(); - var dbPort = $("#dbport").val(); - var dbUser = $("#dbuser").val(); - var dbPassword = $("#dbpassword").val(); - var error_msg = $("#error_msg"); - - if (dbType == "no") { - error_msg.html("请选择数据库类型"); - return; - } - if (dbAddress == null || dbAddress.length == 0) { - error_msg.html("请选择数据库"); - return; - } - if (dbPort == null || dbPort.length == 0) { - error_msg.html("请输入数据库端口"); - return; - } - if (dbUser == null || dbUser.length == 0) { - error_msg.html("请输入数据库登陆用户"); - return; - } - if (dbPassword == null || dbPassword.length == 0) { - error_msg.html("请输入数据库登陆用户密码"); - return; - } - - var result = getAllCatalog(""); - if (!result) { - return; - } - - $("#add_new_db_step1").hide(); - $("#add_new_db_step2").show(); - $("#conn_test").hide(); - $("#add_new_db_next").hide(); - $("#add_new_db_prev").show(); - $("#add_new_db_save").show(); - getUserGroups(); - }); - - $(document.body).on("click", "#add_new_db_prev", function () { - $("#add_new_db_step1").show(); - $("#add_new_db_step2").hide(); - $("#conn_test").show(); - $("#add_new_db_next").show(); - $("#add_new_db_prev").hide(); - $("#add_new_db_save").hide(); - $("#error_msg").html(""); - }); - - $(document.body).on("click", "#conn_test", function () { - getAllCatalog("连接成功"); - }); - - $(document.body).on("click", "#add_new_db_save", function () { - var dbType = $("#dbtype").val(); - var all_In_One_Name = $("#allinonename").val(); - var dbAddress = $("#dbaddress").val(); - var dbPort = $("#dbport").val(); - var dbUser = $("#dbuser").val(); - var dbPassword = $("#dbpassword").val(); - var dbCatalog = $("#dbcatalog").val(); - var dalGroup = $("#dalgroup").val(); - var error_msg = $("#error_msg"); - - if (dbType == "no") { - error_msg.html("请选择数据库类型"); - return; - } - if (all_In_One_Name == "" || null == all_In_One_Name) { - error_msg.html("请输入All-In-One Name"); - return; - } - - var result = validateKeyName($("#allinonename"), error_msg); - if (!result) { - return; - } - - if (dbAddress == null || dbAddress.length == 0) { - error_msg.html("请选择数据库"); - return; - } - if (dbPort == null || dbPort.length == 0) { - error_msg.html("请输入数据库端口"); - return; - } - if (dbUser == null || dbUser.length == 0) { - error_msg.html("请输入数据库登陆用户"); - return; - } - if (dbPassword == null || dbPassword.length == 0) { - error_msg.html("请输入数据库登陆用户密码"); - return; - } - if (dbCatalog == null || dbCatalog.length == 0) { - error_msg.html("请输入数据库"); - return; - } - - $.post("/rest/db/addNewAllInOneDB", { - dbtype: dbType, - allinonename: all_In_One_Name, - dbaddress: dbAddress, - dbport: dbPort, - dbuser: dbUser, - dbpassword: dbPassword, - dbcatalog: dbCatalog, - addtogroup: $("#add_to_group").is(":checked"), - dalgroup: dalGroup == undefined ? "" : dalGroup, - gen_default_dbset: $("#gen_default_dbset").is(":checked") - }, function (data) { - if (data.code == "OK") { - error_msg.html("保存成功"); - refreshAllDB(); - } else { - error_msg.html(data.info); - } - }); - }); - - $(document.body).on("click", "#add_to_group", function () { - var flag = $(this).is(":checked"); - var genDefault = $("#gen_default_dbset"); - genDefault.prop({"checked": flag, "disabled": !flag}); - }); - - $(document.body).on("change", "#dbtype_up", function () { - $("#error_msg").html(" "); - var dbType = $.trim($("#dbtype_up").val()); - - $.post("/rest/user/getDefaultDBInfo", { - dbType: dbType - }, function (data) { - $("#dbaddress_up").val(data.db_address); - $("#dbport_up").val(data.db_port); - $("#dbuser_up").val(data.db_user); - $("#dbpassword_up").val(data.db_password); - }); - }); - - var getUpdateCatalog = function (successInfo) { - $("#update_error_msg").html("正在连接数据库,请稍等..."); - var dbType = $("#dbtype_up").val(); - var dbAddress = $("#dbaddress_up").val(); - var dbPort = $("#dbport_up").val(); - var dbUser = $("#dbuser_up").val(); - var dbPassword = $("#dbpassword_up").val(); - var result = true; - - $.ajax({ - type: "POST", - url: "/rest/db/connectionTest", - data: { - dbtype: dbType, - dbaddress: dbAddress, - dbport: dbPort, - dbuser: dbUser, - dbpassword: dbPassword - }, - async: false, - success: function (data) { - if (data.code == "OK") { - var allCatalog = []; - $.each($.parseJSON(data.info), function (index, value) { - allCatalog.push({ - id: value, title: value - }); - }); - $("#dbcatalog_up")[0].selectize.clearOptions(); - $("#dbcatalog_up")[0].selectize.addOption(allCatalog); - $("#dbcatalog_up")[0].selectize.refreshOptions(false); - $("#update_error_msg").html(successInfo); - var records = w2ui['grid'].getSelection(); - var record = w2ui['grid'].get(records[0]); - $.post("/rest/db/getOneDB", { - allinonename: record['dbname'] - }, - function (data) { - if (data.code == "OK") { - var db = $.parseJSON(data.info); - $("#dbcatalog_up")[0].selectize.setValue(db['db_catalog']); - } - }); - } else { - $("#update_error_msg").html("连接错误:" + data.info); - result = false; - } - } - }); - - return result; - }; - - var validateKeyName = function (obj, msg) { - var result = true; - var key = obj.val(); - if (key.length == 0) - return false; - - $.ajax({ - type: "GET", - dataType: "json", - url: "/rest/db/validation", - data: {"key": key}, - async: false, - success: function (data) { - if (data.info.length > 0) { - $(msg).html(data.info); - result = false; - } - } - }); - return result; - }; - - $(document.body).on("click", "#update_conn_test", function () { - getUpdateCatalog("连接成功"); - }); - - $(document.body).on("click", "#update_db_next", function () { - var dbType = $("#dbtype_up").val(); - var dbAddress = $("#dbaddress_up").val(); - var dbPort = $("#dbport_up").val(); - var dbUser = $("#dbuser_up").val(); - var dbPassword = $("#dbpassword_up").val(); - var update_error_msg = $("#update_error_msg"); - - if (dbType == "no") { - update_error_msg.html("请选择数据库类型"); - return; - } - if (dbAddress == null || dbAddress.length == 0) { - update_error_msg.html("请选择数据库"); - return; - } - if (dbPort == null || dbPort.length == 0) { - update_error_msg.html("请输入数据库端口"); - return; - } - if (dbUser == null || dbUser.length == 0) { - update_error_msg.html("请输入数据库登陆用户"); - return; - } - if (dbPassword == null || dbPassword.length == 0) { - update_error_msg.html("请输入数据库登陆用户密码"); - return; - } - - var result = getUpdateCatalog(""); - if (!result) { - return; - } - - $("#update_db_step1").hide(); - $("#update_db_step2").show(); - $("#update_conn_test").hide(); - $("#update_db_next").hide(); - $("#update_db_prev").show(); - $("#update_db_save").show(); - }); - - $(document.body).on("click", "#update_db_prev", function () { - $("#update_db_step1").show(); - $("#update_db_step2").hide(); - $("#update_conn_test").show(); - $("#update_db_next").show(); - $("#update_db_prev").hide(); - $("#update_db_save").hide(); - $("#update_error_msg").html(""); - }); - - $(document.body).on("click", "#update_db_save", function () { - var dbType = $("#dbtype_up").val(); - var all_In_One_Name = $("#allinonename_up").val(); - var dbAddress = $("#dbaddress_up").val(); - var dbPort = $("#dbport_up").val(); - var dbUser = $("#dbuser_up").val(); - var dbPassword = $("#dbpassword_up").val(); - var dbCatalog = $("#dbcatalog_up").val(); - var update_error_msg = $("#update_error_msg"); - - if (dbType == "no") { - update_error_msg.html("请选择数据库类型"); - return; - } - if (all_In_One_Name == null || all_In_One_Name.length == 0) { - update_error_msg.html("请输入All-In-One Name"); - return; - } - - var result = validateKeyName($("#allinonename_up"), update_error_msg); - if (!result) { - return; - } - - if (dbAddress == null || dbAddress.length == 0) { - update_error_msg.html("请选择数据库"); - return; - } - if (dbPort == null || dbPort.length == 0) { - update_error_msg.html("请输入数据库端口"); - return; - } - if (dbUser == null || dbUser.length == 0) { - update_error_msg.html("请输入数据库登陆用户"); - return; - } - if (dbPassword == null || dbPassword.length == 0) { - update_error_msg.html("请输入数据库登陆用户密码"); - return; - } - if (dbCatalog == null || dbCatalog.length == 0) { - update_error_msg.html("请输入数据库"); - return; - } - - var records = w2ui['grid'].getSelection(); - var record = w2ui['grid'].get(records[0]); - $.post("/rest/db/updateDB", { - "id": record['id'], - "dbtype": dbType, - "allinonename": all_In_One_Name, - "dbaddress": dbAddress, - "dbport": dbPort, - "dbuser": dbUser, - "dbpassword": dbPassword, - "dbcatalog": dbCatalog - }, function (data) { - if (data.code == "OK") { - update_error_msg.html("更新成功."); - refreshAllDB(); - } else { - update_error_msg.html(data.info); - } - }); - }); - - $(document.body).on("click", "#validateKeyname", function () { - validateKeyName($("#allinonename"), $("#error_msg")); - }); - - isDefaultUser(); - }); +(function ($, window, document, undefined) { + var Render = function () { + }; + + var catalogChangeCount_up = 0; + + function refreshAllDB() { + w2ui['grid'].clear(); + cblock($("body")); + $.get("/rest/groupdb/allgroupdbs", {rand: Math.random()}, function (data) { + var allGroupDbs = []; + $.each(data, function (index, value) { + value.recid = allGroupDbs.length + 1; + allGroupDbs.push(value); + }); + w2ui['grid'].add(allGroupDbs); + $("body").unblock(); + }).fail(function (data) { + $("body").unblock(); + alert("获取所有Group失败!"); + }); + }; + + function addDB() { + $.get("/rest/project/userGroups", {root: true, rand: Math.random()}).done(function (data) { + if (data.length > 0 && data[0]['id'] > 0) { + $("#error_msg").html(''); + $("#add_new_db_step1").show(); + $("#add_new_db_step2").hide(); + $("#conn_test").show(); + $("#add_new_db_next").show(); + $("#add_new_db_prev").hide(); + $("#add_new_db_save").hide(); + var dbcatalog = $("#dbcatalog"); + if (dbcatalog[0] != undefined && dbcatalog[0].selectize != undefined) { + dbcatalog[0].selectize.clearOptions(); + } else { + dbcatalog.selectize({ + valueField: 'id', + labelField: 'title', + searchField: 'title', + sortField: 'title', + options: [], + create: true + }); + } + var dalgroup = $("#dalgroup"); + if (dalgroup[0] != undefined && dalgroup[0].selectize != undefined) { + dalgroup[0].selectize.clearOptions(); + } + else { + dalgroup.selectize({ + valueField: 'id', + labelField: 'title', + searchField: 'title', + sortField: 'title', + options: [], + create: false + }); + } + $("#addDbModal").modal({"backdrop": "static"}); + var dbcatalog = $("#dbcatalog"); + var db_providerName = $.trim($("#dbtype").val()); + if (db_providerName !== null || db_providerName.length > 0) { + $.post("/rest/db/getAllDB", { + dbType: db_providerName + }, function (data) { + var allCatalog_up = []; + $.each($.parseJSON(data.info), function (index, value) { + allCatalog_up.push({ + id: value, title: value + }); + }); + dbcatalog[0].selectize.clearOptions(); + dbcatalog[0].selectize.addOption(allCatalog_up); + dbcatalog[0].selectize.refreshOptions(false); + }); + } + } else { + alert("请先加入一个DAL Team."); + } + $("body").unblock(); + }).fail(function (data) { + alert('获取用户加入的所有DAL Team失败.'); + $("body").unblock(); + }); + }; + + var getAllInOneKeyByDbName_up = function (allInOneName) { + var dbcatalog = $("#dbcatalog_up").val(); + var allinonename = $("#allinonename_up"); + if (allinonename[0] != undefined && allinonename[0].selectize != undefined) { + allinonename[0].selectize.clearOptions(); + } else { + allinonename.selectize({ + valueField: 'id', + labelField: 'title', + searchField: 'title', + sortField: 'title', + options: [], + create: true + }); + } + $.post("/rest/db/getTitanKeyByDBName",{ + dbName: dbcatalog + }, function (data) { + var allInOneNames = []; + if(data.info!="null"){ + $.each($.parseJSON(data.info), function (index, value) { + allInOneNames.push({ + id: value, title: value + }); + }); + } + allinonename[0].selectize.clearOptions(); + allinonename[0].selectize.addOption(allInOneNames); + allinonename[0].selectize.refreshOptions(false); + + if (allInOneName!=""){ + allinonename[0].selectize.addOption({ + id : allInOneName, + title : allInOneName, + }); + allinonename[0].selectize.setValue(allInOneName); + } + }); + }; + var record=null; + function editDB() { + $("#update_error_msg").html(''); + $("#update_db_step1").show(); + $("#update_db_step2").hide(); + $("#update_conn_test").show(); + $("#update_db_next").show(); + $("#update_db_prev").hide(); + $("#update_db_save").hide(); + var records = w2ui['grid'].getSelection(); + record= w2ui['grid'].get(records[0]); + if (record == null) { + alert('请先选择一个 database'); + return; + } + cblock($("body")); + $.post("/rest/db/getOneDB", {allinonename: record['dbname']}, function (data) { + if (data.code == "OK") { + var db = $.parseJSON(data.info); + $("#dbtype_up").val(db['db_providerName']); + $("#dbaddress_up").val(db['db_address']); + $("#dbport_up").val(db['db_port']); + $("#dbuser_up").val(db['db_user']); + $("#dbpassword_up").val(db['db_password']); + // $("#allinonename_up").val(db['dbname']); + if ($("#dbcatalog_up")[0] != undefined && $("#dbcatalog_up")[0].selectize != undefined) { + $("#dbcatalog_up")[0].selectize.clearOptions(); + } else { + $("#dbcatalog_up").selectize({ + valueField: 'id', + labelField: 'title', + searchField: 'title', + sortField: 'title', + options: [], + create: true + }); + } + $("#updateDbModal").modal({"backdrop": "static"}); + var dbcatalog_up = $("#dbcatalog_up"); + $.post("/rest/db/getAllDB", { + dbType: db['db_providerName'] + }, function (data) { + var allCatalog_up = []; + $.each($.parseJSON(data.info), function (index, value) { + allCatalog_up.push({ + id: value, title: value + }); + }); + dbcatalog_up[0].selectize.clearOptions(); + dbcatalog_up[0].selectize.addOption(allCatalog_up); + dbcatalog_up[0].selectize.refreshOptions(false); + $("#dbcatalog_up")[0].selectize.addOption({ + id : db['db_catalog'], + title : db['db_catalog'] + }); + catalogChangeCount_up = 0; + $("#dbcatalog_up")[0].selectize.setValue(db['db_catalog']); + getAllInOneKeyByDbName_up(db['dbname']); + }); + } else { + $("#errorMess").html(data.info); + $("#errorNoticeDiv").modal({"backdrop": "static"}); + } + $("body").unblock(); + }).fail(function (data) { + alert("执行异常"); + $("body").unblock(); + }); + }; + + function delDB() { + var records = w2ui['grid'].getSelection(); + var record = w2ui['grid'].get(records[0]); + if (record != null) { + if (confirm("您确定要删除吗?")) { + $.post("/rest/db/deleteAllInOneDB", {allinonename: record['dbname']}, function (data) { + if (data.code == "OK") { + refreshAllDB(); + } else { + $("#errorMess").html(data.info); + $("#errorNoticeDiv").modal({"backdrop": "static"}); + } + }).fail(function (data) { + alert("执行异常"); + $("body").unblock(); + }); + } + } else { + alert('请选择一个database!'); + } + }; + + function isDefaultUser() { + cblock($("body")); + $.get("/rest/user/isDefaultUser", {rand: Math.random()}, function (data) { + if (data == "true") { + $("#validateKeyname").hide(); + } + $("body").unblock(); + }); + } + + Render.prototype = { + render_layout: function (render_obj) { + $(render_obj).w2layout({ + name: 'main_layout', + panels: [{type: 'main'}] + }); + }, + render_grid: function () { + var existsGrid = w2ui['grid']; + if (existsGrid != undefined) { + return; + } + + w2ui['main_layout'].content('main', $().w2grid({ + name: 'grid', + show: { + toolbar: true, + footer: true, + toolbarReload: false, + toolbarColumns: false, + toolbarAdd: false, + toolbarDelete: false, + toolbarEdit: false + }, + toolbar: { + items: [{ + type: 'break' + }, { + type: 'button', + id: 'refreshAllDB', + caption: '刷新', + icon: 'glyphicon glyphicon-refresh' + }, { + type: 'button', + id: 'addDB', + caption: '添加DB', + icon: 'glyphicon glyphicon-plus' + }, { + type: 'button', + id: 'editDB', + caption: '修改DB', + icon: 'glyphicon glyphicon-edit' + }, { + type: 'button', + id: 'delDB', + caption: '删除DB', + icon: 'glyphicon glyphicon-remove' + }], + onClick: function (target, data) { + switch (target) { + case 'refreshAllDB': + refreshAllDB(); + break; + case 'addDB': + addDB(); + break; + case 'editDB': + editDB(); + break; + case 'delDB': + delDB(); + break; + } + } + }, + searches: [{ + field: 'dbname', + caption: 'DB Name', + type: 'text' + }, { + field: 'comment', + caption: '所属 DAL Team', + type: 'text' + }, { + field: 'db_address', + caption: 'DB Address', + type: 'text' + }, { + field: 'db_catalog', + caption: 'DB Catalog', + type: 'text' + }, { + field: 'db_providerName', + caption: '数据库类型', + type: 'text' + }], + columns: [{ + field: 'dbname', + caption: 'DB All-In-One Name', + size: '20%', + attr: 'align=center', + sortable: true, + resizable: true + }, { + field: 'comment', + caption: '所属 DAL Team', + size: '15%', + attr: 'align=center', + sortable: true, + resizable: true + }, { + field: 'db_address', + caption: 'DB Address', + size: '15%', + attr: 'align=center', + sortable: true, + resizable: true + }, { + field: 'db_port', + caption: 'DB Port', + size: '5%', + attr: 'align=center', + sortable: true, + resizable: true + }, { + field: 'db_user', + caption: 'DB User', + size: '10%', + attr: 'align=center', + sortable: true, + resizable: true + }, { + field: 'db_password', + caption: 'DB Password', + size: '10%', + attr: 'align=center', + sortable: true, + resizable: true + }, { + field: 'db_catalog', + caption: 'DB Catalog', + size: '15%', + attr: 'align=center', + sortable: true, + resizable: true + }, { + field: 'db_providerName', + caption: '数据库类型', + size: '10%', + attr: 'align=center', + sortable: true, + resizable: true + }], + records: [] + })); + + refreshAllDB(); + } + }; + + window.render = new Render(); + $('#main_layout').height($(document).height() - 50); + window.render.render_layout($('#main_layout')); + window.render.render_grid(); + + $(window).resize(function () { + $('#main_layout').height($(document).height() - 50); + }); + + $(function () { + var setDefaultDbVal = function () { + var dbcatalog = $("#dbcatalog"); + $("#error_msg").html(" "); + var dbType = $.trim($("#dbtype").val()); + + $.post("/rest/db/getAllDB", { + dbType: dbType + }, function (data) { + var allCatalog = []; + $.each($.parseJSON(data.info), function (index, value) { + allCatalog.push({ + id: value, title: value + }); + }); + dbcatalog[0].selectize.clearOptions(); + dbcatalog[0].selectize.addOption(allCatalog); + dbcatalog[0].selectize.refreshOptions(false); + }); + var dbName = $("#dbcatalog").val(); + $.post("/rest/user/getDefaultDBInfo", { + dbType: dbType, + dbName: dbName + }, function (data) { + $("#dbaddress").val(data.db_address); + $("#dbport").val(data.db_port); + $("#dbuser").val(data.db_user); + $("#dbpassword").val(data.db_password); + }); + + }; + + var getAllCatalog = function (successInfo) { + var dbType = $("#dbtype").val(); + var dbAddress = $("#dbaddress").val(); + var dbPort = $("#dbport").val(); + var dbUser = $("#dbuser").val(); + var dbPassword = $("#dbpassword").val(); + var dbCatalog = $("#dbcatalog").val(); + + var error_msg = $("#error_msg"); + error_msg.html("正在连接数据库,请稍等..."); + var result = true; + + $.ajax({ + type: "POST", + url: "/rest/db/connectionTest", + data: { + dbtype: dbType, + dbaddress: dbAddress, + dbport: dbPort, + dbuser: dbUser, + dbpassword: dbPassword, + dbName: dbCatalog + }, + async: false, + success: function (data) { + if (data.code == "OK") { + /*var allCatalog = []; + $.each($.parseJSON(data.info), function (index, value) { + allCatalog.push({ + id: value, title: value + }); + }); + dbcatalog[0].selectize.clearOptions(); + dbcatalog[0].selectize.addOption(allCatalog); + dbcatalog[0].selectize.refreshOptions(false);*/ + error_msg.html(successInfo); + } else { + error_msg.html("连接失败:" + data.info); + result = false; + } + } + }); + + return result; + }; + + + + var getAllInOneKeyByDbName = function () { + var dbcatalog = $("#dbcatalog").val(); + var allinonename = $("#allinonename"); + if (allinonename[0] != undefined && allinonename[0].selectize != undefined) { + allinonename[0].selectize.clearOptions(); + } else { + allinonename.selectize({ + valueField: 'id', + labelField: 'title', + searchField: 'title', + sortField: 'title', + options: [], + create: true + }); + } + $.post("/rest/db/getTitanKeyByDBName",{ + dbName: dbcatalog + }, function (data) { + var allInOneNames = []; + $.each($.parseJSON(data.info), function (index, value) { + allInOneNames.push({ + id: value, title: value + }); + }); + allinonename[0].selectize.clearOptions(); + allinonename[0].selectize.addOption(allInOneNames); + allinonename[0].selectize.refreshOptions(false); + }); + }; + + var getUserGroups = function () { + var dalgroup = $("#dalgroup"); + $.get("/rest/member", function (data) { + if (data != undefined && data != null) { + if (data.length > 1) { + var groups = []; + $.each(data, function (index, value) { + groups.push({ + id: value.id, title: value.group_name + }); + }); + dalgroup[0].selectize.clearOptions(); + dalgroup[0].selectize.addOption(groups); + dalgroup[0].selectize.refreshOptions(false); + } + else { + $("#dalgroupspan").hide(); + } + } + }); + }; + + $(document.body).on("change", "#dbtype", function () { + $.get("/rest/user/isDefaultUser", {rand: Math.random()}, function (data) { + if (data == "false") { + setDefaultDbVal(); + } + }); + }); + + $(document.body).on("change", "#dbcatalog", function () { + var dbcatalog = $("#dbcatalog").val(); + var dbType = $.trim($("#dbtype").val()); + if (dbType === "MySQL") { + $.post("/rest/user/getDefaultDBInfo", { + dbType: dbType, + dbName: dbcatalog + }, function (data) { + $("#dbaddress").val(data.db_address); + $("#dbport").val(data.db_port); + $("#dbuser").val(data.db_user); + $("#dbpassword").val(data.db_password); + }); + } + }); + + $(document.body).on("click", "#add_new_db_next", function () { + var dbType = $("#dbtype").val(); + var dbAddress = $("#dbaddress").val(); + var dbPort = $("#dbport").val(); + var dbUser = $("#dbuser").val(); + var dbPassword = $("#dbpassword").val(); + var error_msg = $("#error_msg"); + + if (dbType == "no") { + error_msg.html("请选择数据库类型"); + return; + } + if (dbAddress == null || dbAddress.length == 0) { + error_msg.html("请选择数据库"); + return; + } + if (dbPort == null || dbPort.length == 0) { + error_msg.html("请输入数据库端口"); + return; + } + if (dbUser == null || dbUser.length == 0) { + error_msg.html("请输入数据库登陆用户"); + return; + } + if (dbPassword == null || dbPassword.length == 0) { + error_msg.html("请输入数据库登陆用户密码"); + return; + } + + var result = getAllCatalog(""); + if (!result) { + return; + } + + $("#add_new_db_step1").hide(); + $("#add_new_db_step2").show(); + $("#conn_test").hide(); + $("#add_new_db_next").hide(); + $("#add_new_db_prev").show(); + $("#add_new_db_save").show(); + getUserGroups(); + + getAllInOneKeyByDbName(); + }); + + $(document.body).on("click", "#add_new_db_prev", function () { + $("#add_new_db_step1").show(); + $("#add_new_db_step2").hide(); + $("#conn_test").show(); + $("#add_new_db_next").show(); + $("#add_new_db_prev").hide(); + $("#add_new_db_save").hide(); + $("#error_msg").html(""); + }); + + $(document.body).on("click", "#conn_test", function () { + getAllCatalog("连接成功"); + }); + + $(document.body).on("click", "#add_new_db_save", function () { + var dbType = $("#dbtype").val(); + var all_In_One_Name = $("#allinonename").val(); + var dbAddress = $("#dbaddress").val(); + var dbPort = $("#dbport").val(); + var dbUser = $("#dbuser").val(); + var dbPassword = $("#dbpassword").val(); + var dbCatalog = $("#dbcatalog").val(); + var dalGroup = $("#dalgroup").val(); + var error_msg = $("#error_msg"); + + if (dbType == "no") { + error_msg.html("请选择数据库类型"); + return; + } + if (all_In_One_Name == "" || null == all_In_One_Name) { + error_msg.html("请输入All-In-One Name"); + return; + } + + var result = validateKeyName($("#allinonename"), dbCatalog, error_msg); + if (!result) { + return; + } + + if (dbAddress == null || dbAddress.length == 0) { + error_msg.html("请选择数据库"); + return; + } + if (dbPort == null || dbPort.length == 0) { + error_msg.html("请输入数据库端口"); + return; + } + if (dbUser == null || dbUser.length == 0) { + error_msg.html("请输入数据库登陆用户"); + return; + } + if (dbPassword == null || dbPassword.length == 0) { + error_msg.html("请输入数据库登陆用户密码"); + return; + } + if (dbCatalog == null || dbCatalog.length == 0) { + error_msg.html("请输入数据库"); + return; + } + + $.post("/rest/db/addNewAllInOneDB", { + dbtype: dbType, + allinonename: all_In_One_Name, + dbaddress: dbAddress, + dbport: dbPort, + dbuser: dbUser, + dbpassword: dbPassword, + dbcatalog: dbCatalog, + addtogroup: $("#add_to_group").is(":checked"), + dalgroup: dalGroup == undefined ? "" : dalGroup, + gen_default_dbset: $("#gen_default_dbset").is(":checked") + }, function (data) { + if (data.code == "OK") { + error_msg.html("保存成功"); + refreshAllDB(); + } else { + error_msg.html(data.info); + } + }); + }); + + $(document.body).on("click", "#add_to_group", function () { + var flag = $(this).is(":checked"); + var genDefault = $("#gen_default_dbset"); + genDefault.prop({"checked": flag, "disabled": !flag}); + }); + + $(document.body).on("change", "#dbtype_up", function () { + $("#error_msg").html(" "); + var dbType = $.trim($("#dbtype_up").val()); + var dbCatalog = $("#dbcatalog_up").val(); + + $.post("/rest/user/getDefaultDBInfo", { + dbType: dbType, + dbName: dbCatalog + }, function (data) { + $("#dbaddress_up").val(data.db_address); + $("#dbport_up").val(data.db_port); + $("#dbuser_up").val(data.db_user); + $("#dbpassword_up").val(data.db_password); + }); + + }); + + $(document.body).on("change", "#dbcatalog_up", function () { + var dbcatalog = $("#dbcatalog_up").val(); + var dbType = $.trim($("#dbtype_up").val()); + var dbaddress = $("#dbaddress_up").val(); + catalogChangeCount_up = catalogChangeCount_up + 1; + if (dbType === "MySQL") { + $.post("/rest/user/getDefaultDBInfo", { + dbType: dbType, + dbName: dbcatalog + }, function (data) { + if (catalogChangeCount_up > 1 && data.db_address !== "") { + $("#dbaddress_up").val(data.db_address); + $("#dbport_up").val(data.db_port); + $("#dbuser_up").val(data.db_user); + $("#dbpassword_up").val(data.db_password); + } + }); + + } + getAllInOneKeyByDbName_up(record['dbname']); + + }); + + var getUpdateCatalog = function (successInfo) { + $("#update_error_msg").html("正在连接数据库,请稍等..."); + var dbType = $("#dbtype_up").val(); + var dbAddress = $("#dbaddress_up").val(); + var dbPort = $("#dbport_up").val(); + var dbUser = $("#dbuser_up").val(); + var dbPassword = $("#dbpassword_up").val(); + var dbName=$("#dbcatalog_up").val(); + var result = true; + + $.ajax({ + type: "POST", + url: "/rest/db/connectionTest", + data: { + dbtype: dbType, + dbaddress: dbAddress, + dbport: dbPort, + dbuser: dbUser, + dbpassword: dbPassword, + dbName:dbName + }, + async: false, + success: function (data) { + if (data.code == "OK") { + /*var allCatalog = []; + $.each($.parseJSON(data.info), function (index, value) { + allCatalog.push({ + id: value, title: value + }); + }); + $("#dbcatalog_up")[0].selectize.clearOptions(); + $("#dbcatalog_up")[0].selectize.addOption(allCatalog); + $("#dbcatalog_up")[0].selectize.refreshOptions(false);*/ + $("#update_error_msg").html(successInfo); + /*var records = w2ui['grid'].getSelection(); + var record = w2ui['grid'].get(records[0]); + $.post("/rest/db/getOneDB", { + allinonename: record['dbname'] + }, + function (data) { + if (data.code == "OK") { + var db = $.parseJSON(data.info); + $("#dbcatalog_up")[0].selectize.setValue(db['db_catalog']); + } + });*/ + } else { + $("#update_error_msg").html("连接错误:" + data.info); + result = false; + } + } + }); + + return result; + }; + + var validateKeyName = function (obj, dbCatalog, msg) { + var result = true; + var key = obj.val(); + if (key.length == 0) + return false; + + $.ajax({ + type: "GET", + dataType: "json", + url: "/rest/db/validation", + data: {"key": key, "dbName": dbCatalog}, + async: false, + success: function (data) { + if (data.info.length > 0) { + $(msg).html(data.info); + result = false; + } + } + }); + return result; + }; + + $(document.body).on("click", "#update_conn_test", function () { + getUpdateCatalog("连接成功"); + }); + + $(document.body).on("click", "#update_db_next", function () { + var dbType = $("#dbtype_up").val(); + var dbAddress = $("#dbaddress_up").val(); + var dbPort = $("#dbport_up").val(); + var dbUser = $("#dbuser_up").val(); + var dbPassword = $("#dbpassword_up").val(); + var dbCatalog = $("#dbcatalog").val(); + var update_error_msg = $("#update_error_msg"); + + if (dbType == "no") { + update_error_msg.html("请选择数据库类型"); + return; + } + if (dbAddress == null || dbAddress.length == 0) { + update_error_msg.html("请选择数据库"); + return; + } + if (dbPort == null || dbPort.length == 0) { + update_error_msg.html("请输入数据库端口"); + return; + } + if (dbUser == null || dbUser.length == 0) { + update_error_msg.html("请输入数据库登陆用户"); + return; + } + if (dbPassword == null || dbPassword.length == 0) { + update_error_msg.html("请输入数据库登陆用户密码"); + return; + } + + var result = getUpdateCatalog(""); + if (!result) { + return; + } + $("#update_db_step1").hide(); + $("#update_db_step2").show(); + $("#update_conn_test").hide(); + $("#update_db_next").hide(); + $("#update_db_prev").show(); + $("#update_db_save").show(); + + }); + + $(document.body).on("click", "#update_db_prev", function () { + $("#update_db_step1").show(); + $("#update_db_step2").hide(); + $("#update_conn_test").show(); + $("#update_db_next").show(); + $("#update_db_prev").hide(); + $("#update_db_save").hide(); + $("#update_error_msg").html(""); + }); + + $(document.body).on("click", "#update_db_save", function () { + var dbType = $("#dbtype_up").val(); + var all_In_One_Name = $("#allinonename_up").val(); + var dbAddress = $("#dbaddress_up").val(); + var dbPort = $("#dbport_up").val(); + var dbUser = $("#dbuser_up").val(); + var dbPassword = $("#dbpassword_up").val(); + var dbCatalog = $("#dbcatalog_up").val(); + var update_error_msg = $("#update_error_msg"); + + if (dbType == "no") { + update_error_msg.html("请选择数据库类型"); + return; + } + if (all_In_One_Name == null || all_In_One_Name.length == 0) { + update_error_msg.html("请输入All-In-One Name"); + return; + } + + var result = validateKeyName($("#allinonename_up"), dbCatalog, update_error_msg); + if (!result) { + return; + } + + if (dbAddress == null || dbAddress.length == 0) { + update_error_msg.html("请选择数据库"); + return; + } + if (dbPort == null || dbPort.length == 0) { + update_error_msg.html("请输入数据库端口"); + return; + } + if (dbUser == null || dbUser.length == 0) { + update_error_msg.html("请输入数据库登陆用户"); + return; + } + if (dbPassword == null || dbPassword.length == 0) { + update_error_msg.html("请输入数据库登陆用户密码"); + return; + } + if (dbCatalog == null || dbCatalog.length == 0) { + update_error_msg.html("请输入数据库"); + return; + } + + var records = w2ui['grid'].getSelection(); + var record = w2ui['grid'].get(records[0]); + $.post("/rest/db/updateDB", { + "id": record['id'], + "dbtype": dbType, + "allinonename": all_In_One_Name, + "dbaddress": dbAddress, + "dbport": dbPort, + "dbuser": dbUser, + "dbpassword": dbPassword, + "dbcatalog": dbCatalog + }, function (data) { + if (data.code == "OK") { + update_error_msg.html("更新成功."); + refreshAllDB(); + } else { + update_error_msg.html(data.info); + } + }); + }); + + $(document.body).on("click", "#validateKeyname", function () { + validateKeyName($("#allinonename"), $("#dbcatalog").val(), $("#error_msg")); + }); + + isDefaultUser(); + }); })(jQuery, window, document); \ No newline at end of file diff --git a/dal-dao-gen/src/main/webapp/static/js/wizzard.js b/dal-dao-gen/src/main/webapp/static/js/wizzard.js index 65a3b485b..ceb8f62e4 100644 --- a/dal-dao-gen/src/main/webapp/static/js/wizzard.js +++ b/dal-dao-gen/src/main/webapp/static/js/wizzard.js @@ -491,7 +491,7 @@ nextStep.text("正在加载..."); nextStep.removeClass("btn-primary"); var data = undefined; - $.get("/rest/task/table/apiList", { + $.post("/rest/task/table/apiList", { db_name: $("#databases").val(), table_names: tableList.join(","), sql_style: $("#sql_style").val(), diff --git a/dal-dao-gen/src/test/java/com/ctrip/platform/dal/daogen/AllTests.java b/dal-dao-gen/src/test/java/com/ctrip/platform/dal/daogen/AllTests.java new file mode 100644 index 000000000..af1354904 --- /dev/null +++ b/dal-dao-gen/src/test/java/com/ctrip/platform/dal/daogen/AllTests.java @@ -0,0 +1,17 @@ +package com.ctrip.platform.dal.daogen; + +import com.ctrip.platform.dal.daogen.sql.builder.SQLBuilderTests; +import com.ctrip.platform.dal.daogen.sql.validate.SQLValidationTests; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * @author c7ch23en + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + SQLBuilderTests.class, + SQLValidationTests.class +}) +public class AllTests { +} diff --git a/dal-dao-gen/src/test/java/com/ctrip/platform/dal/daogen/sql/builder/SQLBuilderTests.java b/dal-dao-gen/src/test/java/com/ctrip/platform/dal/daogen/sql/builder/SQLBuilderTests.java index 49e670199..ef02accce 100644 --- a/dal-dao-gen/src/test/java/com/ctrip/platform/dal/daogen/sql/builder/SQLBuilderTests.java +++ b/dal-dao-gen/src/test/java/com/ctrip/platform/dal/daogen/sql/builder/SQLBuilderTests.java @@ -20,4 +20,5 @@ public void testJava2Java() { String sql2 = SqlBuilder.net2Java(sql); assertEquals(sql, sql2); } + } diff --git a/dao-gen-core/pom.xml b/dao-gen-core/pom.xml index 523cca9cc..a7a3f2093 100644 --- a/dao-gen-core/pom.xml +++ b/dao-gen-core/pom.xml @@ -3,234 +3,106 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.ctrip.platform + + com.ctrip.platform + dal-client-parent + 2.1.6 + dao-gen-core - 1.16.17 - - UTF-8 - 1.18.3 - 3.1.0 - 4.5.3 - 2.0.1 - 2.25.1 - 21.0 - 7.0.76 - 5.1.41 - 1.4 - 2.5 - 1.7.21 - 1.2.2 - 1.2.67 - 2.9.9 - 1.2 - 4.12 - 3.16 - 2.1.1 - - - - - org.apache.poi - poi-ooxml - ${poi-version} - - - org.apache.xmlbeans - xmlbeans - - - - - + jar + com.ctrip.platform dal-client - ${dal-client-version} javax.servlet javax.servlet-api - ${javax-servlet-version} org.apache.httpcomponents httpclient - ${httpclient-version} javax.ws.rs javax.ws.rs-api - ${ws-rs-version} org.glassfish.jersey.containers jersey-container-servlet - ${jersey-version} org.glassfish.jersey.media jersey-media-moxy - ${jersey-version} org.glassfish.jersey.ext jersey-entity-filtering - ${jersey-version} com.google.guava guava - ${guava-version} org.apache.tomcat tomcat-jdbc - ${tomcat-jdbc-version} mysql mysql-connector-java - ${mysql-connector-version} org.apache.commons commons-email - ${commons-email-version} commons-io commons-io - ${commons-io-version} org.slf4j jcl-over-slf4j - ${jcl-over-slf4j} ch.qos.logback logback-classic - ${logback-version} ch.qos.logback logback-core - ${logback-version} ch.qos.logback logback-access - ${logback-version} - com.alibaba - fastjson - ${fastjson-version} + com.google.code.gson + gson com.fasterxml.jackson.core jackson-core - ${jackson-version} com.fasterxml.jackson.core jackson-databind - ${jackson-version} com.github.jsqlparser jsqlparser - ${jsqlparser-version} org.apache.velocity velocity - 1.7 org.dom4j dom4j - ${dom4j-version} - - - junit - junit - ${junit-version} org.apache.poi poi-ooxml - - - - maven-deploy-plugin - 2.8.1 - - internal.repo::default::file://${project.build.directory}/mvn-repo - - - - - com.github.github - site-maven-plugin - 0.11 - - Maven artifacts for ${project.artifactId}, ${project.version} - true - ${project.build.directory}/mvn-repo - - refs/heads/mvn-repo - - **/* - - dal - ctripcorp - github - true - - - - - site - - deploy - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.0 - - 1.8 - 1.8 - ${file_encoding} - true - true - - - - org.apache.maven.plugins - maven-resources-plugin - 2.7 - - ${file_encoding} - - - - - - - internal.repo - Temporary Staging Repository - file://${project.build.directory}/mvn-repo - - true - always - - - - \ No newline at end of file + diff --git a/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/UserInfo.java b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/UserInfo.java index 1d4dc3193..7838e1efa 100644 --- a/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/UserInfo.java +++ b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/UserInfo.java @@ -15,5 +15,5 @@ public interface UserInfo { void logOut(HttpServletRequest request, HttpServletResponse response); - DalGroupDB getDefaultDBInfo(String dbType); + DalGroupDB getDefaultDBInfo(String dbType, String name); } diff --git a/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/dao/DaoOfProject.java b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/dao/DaoOfProject.java index ed82f69a2..dc7f706d7 100644 --- a/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/dao/DaoOfProject.java +++ b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/dao/DaoOfProject.java @@ -34,7 +34,7 @@ public Project getProjectByID(int id) throws SQLException { public List getProjectByGroupId(int groupId) throws SQLException { FreeSelectSqlBuilder> builder = new FreeSelectSqlBuilder<>(dbCategory); builder.setTemplate( - "SELECT id, name, namespace,dal_group_id,dal_config_name,update_user_no,update_time FROM project WHERE dal_group_id = ?"); + "SELECT id, name, namespace,dal_group_id,dal_config_name,update_user_no,update_time FROM project WHERE dal_group_id = ? order by id desc"); StatementParameters parameters = new StatementParameters(); int i = 1; parameters.set(i++, "dal_group_id", Types.INTEGER, groupId); diff --git a/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/entity/DBLevelInfo.java b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/entity/DBLevelInfo.java new file mode 100644 index 000000000..2b91894ce --- /dev/null +++ b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/entity/DBLevelInfo.java @@ -0,0 +1,93 @@ +package com.ctrip.platform.dal.daogen.entity; + +public class DBLevelInfo { + private int organization_id; + + private String organization_name; + + private int level; + + private String db_type; + + private String db_name_base; + + private int dns_port; + + private String db_name; + + private String dns; + + private String dbowners; + + public int getOrganization_id() { + return organization_id; + } + + public void setOrganization_id(int organization_id) { + this.organization_id = organization_id; + } + + public String getOrganization_name() { + return organization_name; + } + + public void setOrganization_name(String organization_name) { + this.organization_name = organization_name; + } + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + public String getDb_type() { + return db_type; + } + + public void setDb_type(String db_type) { + this.db_type = db_type; + } + + public String getDb_name_base() { + return db_name_base; + } + + public void setDb_name_base(String db_name_base) { + this.db_name_base = db_name_base; + } + + public int getDns_port() { + return dns_port; + } + + public void setDns_port(int dns_port) { + this.dns_port = dns_port; + } + + public String getDb_name() { + return db_name; + } + + public void setDb_name(String db_name) { + this.db_name = db_name; + } + + public String getDns() { + return dns; + } + + public void setDns(String dns) { + this.dns = dns; + } + + public String getDbowners() { + return dbowners; + } + + public void setDbowners(String dbowners) { + this.dbowners = dbowners; + } +} diff --git a/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/entity/DefaultUserInfo.java b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/entity/DefaultUserInfo.java index 85c33fdf9..726c28b0c 100644 --- a/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/entity/DefaultUserInfo.java +++ b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/entity/DefaultUserInfo.java @@ -70,7 +70,7 @@ public void logOut(HttpServletRequest request, HttpServletResponse response) { } @Override - public DalGroupDB getDefaultDBInfo(String dbType) { + public DalGroupDB getDefaultDBInfo(String dbType, String dbName) { DalGroupDB db = new DalGroupDB(); if (dbType == null || dbType.isEmpty()) return db; diff --git a/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/resource/CustomizedResource.java b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/resource/CustomizedResource.java index 3794b4cfe..e96f90965 100644 --- a/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/resource/CustomizedResource.java +++ b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/resource/CustomizedResource.java @@ -20,6 +20,8 @@ public class CustomizedResource { private ClassLoader classLoader = null; private final String CONF_PROPERTIES = "conf.properties"; private final String USER_INFO_CLASS_NAME = "userinfo_class"; + private final String DB_LEVEL_INFO_API_CLASS_NAME = "db_level_info_api"; + private final String ALL_IN_ONE_KEY_API_CLASS_NAME = "all_in_one_key_api"; private UserInfo userInfo = null; private Boolean isDefaultUser = null; @@ -116,6 +118,14 @@ public String getConfigClassName() throws IOException { return getClassNameFromConf(CONFIG_CLASS_NAME); } + public String getDBLevelInfoApiClassName() throws IOException { + return getClassNameFromConf(DB_LEVEL_INFO_API_CLASS_NAME); + } + + public String getAllInOneKeyApiClassName() throws IOException { + return getClassNameFromConf(ALL_IN_ONE_KEY_API_CLASS_NAME); + } + private String getClassNameFromConf(String className) throws IOException { if (className == null || className.isEmpty()) return null; @@ -134,8 +144,8 @@ public void logOut(HttpServletRequest request, HttpServletResponse response) { userInfo.logOut(request, response); } - public DalGroupDB getDefaultDBInfo(String dbType) { - return userInfo.getDefaultDBInfo(dbType); + public DalGroupDB getDefaultDBInfo(String dbType, String dbName) { + return userInfo.getDefaultDBInfo(dbType, dbName); } } diff --git a/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/utils/AllInOneKeyApi.java b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/utils/AllInOneKeyApi.java new file mode 100644 index 000000000..cad9083d0 --- /dev/null +++ b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/utils/AllInOneKeyApi.java @@ -0,0 +1,7 @@ +package com.ctrip.platform.dal.daogen.utils; + +import java.util.List; + +public interface AllInOneKeyApi { + public List getAllInOneKeys(String dbName); +} diff --git a/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/utils/DBInfoApi.java b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/utils/DBInfoApi.java new file mode 100644 index 000000000..3f82dcb46 --- /dev/null +++ b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/utils/DBInfoApi.java @@ -0,0 +1,9 @@ +package com.ctrip.platform.dal.daogen.utils; + +import com.ctrip.platform.dal.daogen.entity.DBLevelInfo; + +import java.util.List; + +public interface DBInfoApi { + public List getDBLevelInfo(String dbType); +} diff --git a/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/utils/DataSourceUtil.java b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/utils/DataSourceUtil.java index 6937e4051..777dda929 100644 --- a/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/utils/DataSourceUtil.java +++ b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/utils/DataSourceUtil.java @@ -3,6 +3,7 @@ import com.ctrip.platform.dal.daogen.dao.DalGroupDBDao; import com.ctrip.platform.dal.daogen.entity.DalGroupDB; import com.ctrip.platform.dal.daogen.enums.DatabaseType; +import com.ctrip.platform.dal.daogen.log.LoggerManager; import org.apache.tomcat.jdbc.pool.PoolProperties; import javax.sql.DataSource; @@ -32,7 +33,31 @@ public class DataSourceUtil { private static volatile Map cache2 = new ConcurrentHashMap<>(); public static Connection getConnection(String address, String port, String userName, String password, - String driverClass) throws Exception { + String driverClass, String dbName) throws Exception { + validateParam(address, port, userName, password, driverClass); + String key = address.trim() +dbName.trim()+ port.trim() + userName.trim() + password.trim(); + DataSource ds = cache1.get(key); + if (ds != null) { + Connection conn = ds.getConnection(); + return conn; + } + synchronized (DataSourceUtil.class) { + ds = cache1.get(key); + if (ds != null) { + Connection conn = ds.getConnection(); + return conn; + } else { + DataSource newDS = createDataSource(address.trim(), port.trim(), dbName.trim(), userName.trim(), password.trim(), + driverClass.trim()); + cache1.put(key, newDS); + Connection conn = newDS.getConnection(); + return conn; + } + } + } + + public static Connection getConnection(String address, String port, String userName, String password, + String driverClass) throws Exception { validateParam(address, port, userName, password, driverClass); String key = address.trim() + port.trim() + userName.trim() + password.trim(); DataSource ds = cache1.get(key); diff --git a/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/utils/HttpUtil.java b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/utils/HttpUtil.java index af360a7ac..56a5f8568 100644 --- a/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/utils/HttpUtil.java +++ b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/utils/HttpUtil.java @@ -1,7 +1,6 @@ package com.ctrip.platform.dal.daogen.utils; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; + import com.ctrip.platform.dal.daogen.enums.HttpMethod; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; @@ -15,6 +14,7 @@ import org.apache.http.util.EntityUtils; import java.net.URI; +import java.util.HashMap; import java.util.Map; public class HttpUtil { @@ -42,11 +42,11 @@ public static T getJSONEntity(Class clazz, String url, Map 0) { - JSONObject json = new JSONObject(); + Map map = new HashMap(); for (Map.Entry parameter : parameters.entrySet()) { - json.put(parameter.getKey(), parameter.getValue()); + map.put(parameter.getKey(), parameter.getValue()); } - StringEntity stringEntity = new StringEntity(json.toString()); + StringEntity stringEntity = new StringEntity(JsonUtils.toJson(map)); request.setEntity(stringEntity); } @@ -55,7 +55,7 @@ public static T getJSONEntity(Class clazz, String url, Map T fromJson(String json, Class clazz) { + return getInstance().gson.fromJson(json, clazz); + } + + public static JsonObject parseObject(String json) { + return getInstance().parser.parse(json).getAsJsonObject(); + } + + public static JsonArray parseArray(String json) { + return getInstance().parser.parse(json).getAsJsonArray(); + } + + public static JsonElement parse(String json) { + return getInstance().parser.parse(json); + } + +} \ No newline at end of file diff --git a/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/utils/WebUtil.java b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/utils/WebUtil.java index b35d679e2..8a0db4769 100644 --- a/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/utils/WebUtil.java +++ b/dao-gen-core/src/main/java/com/ctrip/platform/dal/daogen/utils/WebUtil.java @@ -1,6 +1,5 @@ package com.ctrip.platform.dal.daogen.utils; -import com.alibaba.fastjson.JSON; import com.ctrip.platform.dal.daogen.entity.Response; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; @@ -55,7 +54,7 @@ public static Response getAllInOneResponse(String keyname, String environment) t HttpResponse response = sslClient.execute(httpGet); HttpEntity entity = response.getEntity(); String content = EntityUtils.toString(entity); - res = JSON.parseObject(content, Response.class); + res = JsonUtils.fromJson(content, Response.class); } return res; diff --git a/pom.xml b/pom.xml index 1fb4300f3..95ca2e918 100644 --- a/pom.xml +++ b/pom.xml @@ -10,18 +10,25 @@ com.ctrip.platform dal-client-parent - 2.0.19 + 2.1.6 pom dal-cluster-client dal-client + dao-gen-core + dal-dao-gen 1.8 + 1.1.1 + ${project.version} - 3.1-b09 + ${project.version} + ${project.version} + + 3.1.0 3.0.0.v201103241009 4.3.8.RELEASE 2.1_3 @@ -38,6 +45,19 @@ 2.8.2 4.12 2.3 + + 4.5.3 + 2.0.1 + 2.25.1 + 21.0 + 1.4 + 2.5 + 2.9.6 + 3.16 + 2.1.1 + 1.7 + 1.2.2 + 3.8.1 2.5 3.0.0 @@ -46,16 +66,34 @@ 2.19.1 2.8.1 0.11 + UTF-8 + + javax.activation + activation + ${javax.activation.version} + + com.ctrip.framework.dal dal-cluster-client ${dal-cluster-client.version} + + com.ctrip.platform + dal-client + ${dal-client.version} + + + com.ctrip.platform + dao-gen-core + ${dao-gen-core.version} + + javax.servlet javax.servlet-api @@ -134,12 +172,12 @@ org.apache.logging.log4j - log4j-slf4j-impl + log4j-core ${log4j.version} org.apache.logging.log4j - log4j-core + log4j-slf4j-impl ${log4j.version} @@ -151,16 +189,112 @@ junit junit ${junit.version} + test org.easymock easymockclassextension ${easymock.version} + test org.springframework spring-test ${spring.version} + test + + + + org.apache.httpcomponents + httpclient + ${httpclient.version} + + + commons-logging + commons-logging + + + + + javax.ws.rs + javax.ws.rs-api + ${ws-rs.version} + + + org.glassfish.jersey.containers + jersey-container-servlet + ${jersey.version} + + + org.glassfish.jersey.media + jersey-media-moxy + ${jersey.version} + + + org.glassfish.jersey.ext + jersey-entity-filtering + ${jersey.version} + + + com.google.guava + guava + ${guava.version} + + + org.apache.commons + commons-email + ${commons-email.version} + + + commons-io + commons-io + ${commons-io.version} + + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + org.apache.poi + poi-ooxml + ${poi.version} + + + org.apache.xmlbeans + xmlbeans + + + + + org.dom4j + dom4j + ${dom4j.version} + + + org.apache.velocity + velocity + ${velocity.version} + + + ch.qos.logback + logback-core + ${logback.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + ch.qos.logback + logback-access + ${logback.version} @@ -360,8 +494,8 @@ -