18 package com.mysql.clusterj.core;
 
   20 import com.mysql.clusterj.ClusterJException;
 
   21 import com.mysql.clusterj.ClusterJFatalException;
 
   22 import com.mysql.clusterj.ClusterJFatalInternalException;
 
   23 import com.mysql.clusterj.ClusterJFatalUserException;
 
   24 import com.mysql.clusterj.ClusterJHelper;
 
   25 import com.mysql.clusterj.ClusterJUserException;
 
   26 import com.mysql.clusterj.Constants;
 
   27 import com.mysql.clusterj.Session;
 
   28 import com.mysql.clusterj.SessionFactory;
 
   30 import com.mysql.clusterj.core.spi.DomainTypeHandler;
 
   31 import com.mysql.clusterj.core.spi.DomainTypeHandlerFactory;
 
   32 import com.mysql.clusterj.core.metadata.DomainTypeHandlerFactoryImpl;
 
   34 import com.mysql.clusterj.core.store.Db;
 
   35 import com.mysql.clusterj.core.store.ClusterConnection;
 
   36 import com.mysql.clusterj.core.store.ClusterConnectionService;
 
   37 import com.mysql.clusterj.core.store.Dictionary;
 
   38 import com.mysql.clusterj.core.store.Table;
 
   40 import com.mysql.clusterj.core.util.I18NHelper;
 
   41 import com.mysql.clusterj.core.util.Logger;
 
   42 import com.mysql.clusterj.core.util.LoggerFactoryService;
 
   44 import java.util.ArrayList;
 
   45 import java.util.HashMap;
 
   46 import java.util.List;
 
   61     String CLUSTER_CONNECTION_SERVICE;
 
   62     String CLUSTER_CONNECT_STRING;
 
   63     int CLUSTER_CONNECT_RETRIES;
 
   64     int CLUSTER_CONNECT_DELAY;
 
   65     int CLUSTER_CONNECT_VERBOSE;
 
   66     int CLUSTER_CONNECT_TIMEOUT_BEFORE;
 
   67     int CLUSTER_CONNECT_TIMEOUT_AFTER;
 
   69     int CLUSTER_MAX_TRANSACTIONS;
 
   72     List<Integer> nodeIds = 
new ArrayList<Integer>();
 
   75     int connectionPoolSize;
 
   79     static private Map<Class<?>, Class<?>> proxyClassToDomainClass = 
new HashMap<Class<?>, Class<?>>();
 
   84             new HashMap<Class<?>, DomainTypeHandler<?>>();
 
   95             new HashMap<String, SessionFactoryImpl>();
 
  101     private List<ClusterConnection> pooledConnections = 
new ArrayList<ClusterConnection>();
 
  108                     CLUSTER_CONNECTION_SERVICE);
 
  121         String sessionFactoryKey = getSessionFactoryKey(props);
 
  123         if (connectionPoolSize != 0) {
 
  127                 if (result == null) {
 
  139     private static String getSessionFactoryKey(Map<?, ?> 
props) {
 
  140         String clusterConnectString = 
 
  144         return clusterConnectString + 
"+" + clusterDatabase;
 
  154         this.key = getSessionFactoryKey(props);
 
  173         createClusterConnectionPool();
 
  180         } 
catch (Exception e) {
 
  182                 logger.warn(local.
message(
"ERR_Session_Factory_Impl_Failed_To_Complete_Transaction"));
 
  183                 throw (ClusterJException)e;
 
  188     protected void createClusterConnectionPool() {
 
  190         if (nodeIdsProperty != null) {
 
  192             String[] nodeIdsStringArray = nodeIdsProperty.split(
"[,; \t\n\r]+", 48);
 
  193             for (
String nodeIdString : nodeIdsStringArray) {
 
  195                     int nodeId = Integer.parseInt(nodeIdString);
 
  197                 } 
catch (NumberFormatException ex) {
 
  204                 if (nodeIds.size() ==1) {
 
  206                     for (
int i = 1; 
i < connectionPoolSize; ++
i) {
 
  207                         nodeIds.add(nodeIds.get(
i - 1) + 1);
 
  210                 if (connectionPoolSize != nodeIds.size()) {
 
  211                     throw new ClusterJFatalUserException(
 
  212                             local.
message(
"ERR_Node_Ids_Must_Match_Connection_Pool_Size",
 
  213                                     nodeIdsProperty, connectionPoolSize));
 
  218                 connectionPoolSize = nodeIds.size();
 
  222         if (nodeIds.size() == 0) {
 
  224             for (
int i = 0; 
i < connectionPoolSize; ++
i) {
 
  225                 createClusterConnection(service, 
props, 0);
 
  228             for (
int i = 0; 
i < connectionPoolSize; ++
i) {
 
  229                 createClusterConnection(service, 
props, nodeIds.get(
i));
 
  234     protected ClusterConnection createClusterConnection(
 
  235             ClusterConnectionService service, Map<?, ?> 
props, 
int nodeId) {
 
  236         ClusterConnection result = null;
 
  238             result = service.create(CLUSTER_CONNECT_STRING, nodeId);
 
  239             result.connect(CLUSTER_CONNECT_RETRIES, CLUSTER_CONNECT_DELAY,
true);
 
  240             result.waitUntilReady(CLUSTER_CONNECT_TIMEOUT_BEFORE,CLUSTER_CONNECT_TIMEOUT_AFTER);
 
  241         } 
catch (Exception ex) {
 
  243             for (ClusterConnection connection: pooledConnections) {
 
  246             pooledConnections.clear();
 
  247             throw new ClusterJFatalUserException(
 
  248                     local.
message(
"ERR_Connecting", props), ex);
 
  250         this.pooledConnections.add(result);
 
  273                 checkConnection(clusterConnection);
 
  274                 db = clusterConnection.createDb(CLUSTER_DATABASE, CLUSTER_MAX_TRANSACTIONS);
 
  277             return new SessionImpl(
this, properties, db, dictionary);
 
  280         } 
catch (Exception ex) {
 
  282                     local.
message(
"ERR_Create_Ndb"), ex);
 
  287         if (connectionPoolSize <= 1) {
 
  288             return pooledConnections.get(0);
 
  293         ClusterConnection result = null;
 
  294         int bestCount = Integer.MAX_VALUE;
 
  295         for (ClusterConnection pooledConnection: pooledConnections ) {
 
  296             int count = pooledConnection.dbCount();
 
  297             if (count < bestCount) {
 
  299                 result = pooledConnection;
 
  305     private void checkConnection(ClusterConnection clusterConnection) {
 
  306         if (clusterConnection == null) {
 
  307             throw new ClusterJUserException(local.
message(
"ERR_Session_Factory_Closed"));
 
  319             @SuppressWarnings( 
"unchecked" )
 
  320             DomainTypeHandler<T> domainTypeHandler = (DomainTypeHandler<T>) 
typeToHandlerMap.get(cls);
 
  321             return domainTypeHandler;
 
  336             @SuppressWarnings(
"unchecked")
 
  337             DomainTypeHandler<T> domainTypeHandler = (DomainTypeHandler<T>) 
typeToHandlerMap.get(cls);
 
  338             if (logger.isDetailEnabled()) logger.detail("DomainTypeToHandler for "
 
  339                     + cls.getName() + "(" + cls
 
  340                     + ") returned " + domainTypeHandler);
 
  341             if (domainTypeHandler == null) {
 
  342                 domainTypeHandler = domainTypeHandlerFactory.createDomainTypeHandler(cls,
 
  344                 if (logger.isDetailEnabled()) logger.detail(
"createDomainTypeHandler for " 
  345                         + cls.getName() + 
"(" + cls
 
  346                         + 
") returned " + domainTypeHandler);
 
  348                 Class<?> proxyClass = domainTypeHandler.getProxyClass();
 
  349                 if (proxyClass != null) {
 
  350                     proxyClassToDomainClass.put(proxyClass, cls);
 
  353             return domainTypeHandler;
 
  364         Class<T> cls = getClassForProxy(
object);
 
  366         if (result != null) {
 
  373     @SuppressWarnings(
"unchecked")
 
  374     protected static <T> Class<T> getClassForProxy(T 
object) {
 
  375         Class cls = 
object.getClass();
 
  376         if (cls.getName().startsWith(
"$Proxy")) {
 
  377             cls = proxyClassToDomainClass.get(cls);
 
  382     public <T> T newInstance(Class<T> cls, Dictionary dictionary) {
 
  384         return domainTypeHandler.newInstance();
 
  387     public Table getTable(
String tableName, Dictionary dictionary) {
 
  390             result = dictionary.getTable(tableName);
 
  391         } 
catch(Exception ex) {
 
  392             throw new ClusterJFatalInternalException(
 
  393                         local.
message(
"ERR_Get_Table"), ex);
 
  404         return (
String)props.get(propertyName);
 
  416         if (result == null) {
 
  417             result = defaultValue;
 
  430         if (result == null) {
 
  432                         local.
message(
"ERR_NullProperty", propertyName));                            
 
  445         Object 
property = props.get(propertyName);
 
  454                 int result = Integer.parseInt((String)
property);
 
  456             } 
catch (NumberFormatException ex) {
 
  467             clusterConnection.close();
 
  469         pooledConnections.clear();
 
  477         this.domainTypeHandlerFactory = domainTypeHandlerFactory;
 
  480     public DomainTypeHandlerFactory getDomainTypeHandlerFactory() {
 
  481         return domainTypeHandlerFactory;
 
  486         for (ClusterConnection connection: pooledConnections) {
 
  487             result.add(connection.dbCount());