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());