[jboss-svn-commits] JBL Code SVN: r19417 - in labs/jbosstm/trunk: ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/recovery and 10 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Fri Apr 4 09:22:05 EDT 2008
Author: mmusgrov
Date: 2008-04-04 09:22:05 -0400 (Fri, 04 Apr 2008)
New Revision: 19417
Modified:
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/Environment.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/recovery/RecoveryManager.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/recovery/TransactionStatusManager.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/utils/Utility.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/PeriodicRecovery.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/RecoveryManagerImple.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/TransactionStatusManagerItem.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/utils/SocketProcessId.java
labs/jbosstm/trunk/ArjunaCore/arjuna/etc/default-RecoveryManager-properties.xml
labs/jbosstm/trunk/ArjunaCore/arjuna/etc/default-arjuna-properties.xml
labs/jbosstm/trunk/ArjunaJTA/jta/etc/default-RecoveryManager-properties.xml
labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/jacorb/recoverycoordinators/JacOrbRCServiceInit.java
labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/jts/common/Environment.java
labs/jbosstm/trunk/ArjunaJTS/jts/etc/default-RecoveryManager-properties.xml
labs/jbosstm/trunk/ArjunaJTS/jts/etc/default-jts-properties.xml
labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/jbossatx/jta/TransactionManagerService.java
labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/jbossatx/jts/TransactionManagerService.java
Log:
Updated SocketProcessId such that the port is configurable via the properties
com.arjuna.ats.internal.arjuna.utils.SocketProcessIdPort
com.arjuna.ats.internal.arjuna.utils.SocketProcessIdMaxPorts
Added properties to configure the address used by the Recovery Manager and Transaction Status Manager and
Recovery Manager orb:
com.arjuna.ats.arjuna.recovery.recoveryAddress
com.arjuna.ats.arjuna.recovery.transactionStatusManagerAddress
com.arjuna.ats.jts.recoveryManagerAddress
When running inside an AS these properties are ignored (and the AS listen address is used instead).
Resolves issues JBTM-348, JBTM-253 and JBTM-324
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/Environment.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/Environment.java 2008-04-04 13:12:45 UTC (rev 19416)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/Environment.java 2008-04-04 13:22:05 UTC (rev 19417)
@@ -137,9 +137,20 @@
public static final String OBJECTSTORE_SHARE = "com.arjuna.ats.arjuna.objectstore.share";
public static final String OBJECTSTORE_HIERARCHY_RETRY = "com.arjuna.ats.arjuna.objectstore.hierarchyRetry";
public static final String OBJECTSTORE_HIERARCHY_TIMEOUT = "com.arjuna.ats.arjuna.objectstore.hierarchyTimeout";
- public static final String RECOVERY_MANAGER_PORT = "com.arjuna.ats.internal.arjuna.recovery.recoveryPort";
+ public static final String RECOVERY_MANAGER_PORT = "com.arjuna.ats.arjuna.recovery.recoveryPort";
+ public static final String RECOVERY_MANAGER_ADDRESS = "com.arjuna.ats.arjuna.recovery.recoveryAddress";
public static final String XA_NODE_IDENTIFIER = "com.arjuna.ats.arjuna.xa.nodeIdentifier";
public static final String DEFAULT_TIMEOUT = "com.arjuna.ats.arjuna.coordinator.defaultTimeout";
-
+ public static final String TRANSACTION_STATUS_MANAGER_PORT = "com.arjuna.ats.arjuna.recovery.transactionStatusManagerPort";
+ public static final String TRANSACTION_STATUS_MANAGER_ADDRESS = "com.arjuna.ats.arjuna.recovery.transactionStatusManagerAddress";
+ public static final String SOCKET_PROCESS_ID_PORT= "com.arjuna.ats.internal.arjuna.utils.SocketProcessIdPort";
+ public static final String SOCKET_PROCESS_ID_MAX_PORTS= "com.arjuna.ats.internal.arjuna.utils.SocketProcessIdMaxPorts";
+
+ /**
+ * Constant that holds the name of the environment property
+ * for specifying the bind address for transaction services
+ *
+ */
+ public static final String SERVER_BIND_ADDRESS = "jbossts.bind.address";
}
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/recovery/RecoveryManager.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/recovery/RecoveryManager.java 2008-04-04 13:12:45 UTC (rev 19416)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/recovery/RecoveryManager.java 2008-04-04 13:22:05 UTC (rev 19417)
@@ -32,9 +32,24 @@
package com.arjuna.ats.arjuna.recovery;
import java.util.Vector;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.io.IOException;
import com.arjuna.ats.internal.arjuna.recovery.RecoveryManagerImple;
+import com.arjuna.ats.arjuna.utils.Utility;
+import com.arjuna.ats.arjuna.logging.tsLogger;
+import com.arjuna.common.util.propertyservice.PropertyManager;
+import com.arjuna.common.util.propertyservice.PropertyManagerFactory;
+/**
+ * @message com.arjuna.ats.arjuna.recovery.RecoveryManager_1 [com.arjuna.ats.arjuna.recovery.RecoveryManager_1] - Invalid recovery manager port specified {0}
+ * @message com.arjuna.ats.arjuna.recovery.RecoveryManager_2 [com.arjuna.ats.arjuna.recovery.RecoveryManager_2] - Invalid recovery manager host specified {0}
+ * @message com.arjuna.ats.arjuna.recovery.RecoveryManager_3 [com.arjuna.ats.arjuna.recovery.RecoveryManager_3] - Recovery manager bound to {0}:{1}
+ * @message com.arjuna.ats.arjuna.recovery.RecoveryManager_4 [com.arjuna.ats.arjuna.recovery.RecoveryManager_4] - Connected to recovery manager on {0}:{1}
+ * @message com.arjuna.ats.arjuna.recovery.RecoveryManager_5 [com.arjuna.ats.arjuna.recovery.RecoveryManager_5] - Invalid recovery manager port specified
+ */
class ScanThread extends Thread
{
@@ -147,7 +162,7 @@
* and will return immediately. Notification of completion of the
* scan is done through the RecoveryScan object.
*
- * @param RecoveryScan callback The callback mechanism used to
+ * @param callback callback The callback mechanism used to
* inform users that the scan has completed. If this is <code>null</code>
* then no callback will happen and asynchronous scanning will occur.
*/
@@ -207,7 +222,7 @@
/**
* Add a recovery module to the system.
*
- * @param RecoveryModule module The module to add.
+ * @param module module The module to add.
*/
public final void addModule (RecoveryModule module)
@@ -248,6 +263,70 @@
{
return _mode;
}
+
+ public static InetAddress getRecoveryManagerHost(boolean useASBindAddress) throws UnknownHostException
+ {
+ PropertyManager pm = PropertyManagerFactory.getPropertyManager("com.arjuna.ats.propertymanager", "recoverymanager");
+
+ if ( pm == null )
+ return InetAddress.getLocalHost();
+
+ String hostPropName = com.arjuna.ats.arjuna.common.Environment.RECOVERY_MANAGER_ADDRESS;
+ String host = ((useASBindAddress) ? Utility.getServerBindAddress(pm, hostPropName) : pm.getProperty(hostPropName));
+
+ return Utility.hostNameToInetAddress(host, "com.arjuna.ats.arjuna.recovery.RecoveryManager_2");
+ }
+
+ public static int getRecoveryManagerPort()
+ {
+ PropertyManager pm = PropertyManagerFactory.getPropertyManager("com.arjuna.ats.propertymanager", "recoverymanager");
+
+ if (pm == null)
+ return 0;
+
+ String portPropName = com.arjuna.ats.arjuna.common.Environment.RECOVERY_MANAGER_PORT;
+ Integer port = Utility.lookupBoundedIntegerProperty(pm, portPropName, null,
+ "com.arjuna.ats.arjuna.recovery.RecoveryManager_1",
+ 0, Utility.MAX_PORT);
+
+ if (port == null)
+ {
+ String portStr = pm.getProperty(portPropName);
+
+ /*
+ * if the property files specified a value for the port which is invalid throw a fatal error. An empty value or no value
+ * corresponds to any port
+ */
+ if (portStr == null || portStr.length() == 0)
+ port = 0;
+ else
+ throw new com.arjuna.ats.arjuna.exceptions.FatalError(tsLogger.log_mesg.getString("com.arjuna.ats.arjuna.recovery.RecoveryManager_5"));
+ }
+
+ return port;
+ }
+
+ /**
+ * Obtain a client connection to the recovery manager
+ *
+ * @param useASBindAddress if true and the recovery manager is running within an appserver then
+ * bind the socket to the same address that the AS is using. Otherwise use the environment config
+ * to choose which address to bind to
+ * @return a bound client socket connection to the recovery manager
+ * @throws IOException
+ */
+ public static Socket getClientSocket (boolean useASBindAddress) throws IOException
+ {
+ Socket socket = new Socket(getRecoveryManagerHost(useASBindAddress), getRecoveryManagerPort());
+
+ if (tsLogger.arjLogger.isInfoEnabled())
+ {
+ tsLogger.arjLoggerI18N.info("com.arjuna.ats.arjuna.recovery.RecoveryManager_4",
+ new Object[]{socket.getInetAddress().getHostAddress(), socket.getLocalPort()});
+ }
+
+ return socket;
+ }
/**
* Run the RecoveryManager. See Administration manual for details.
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/recovery/TransactionStatusManager.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/recovery/TransactionStatusManager.java 2008-04-04 13:12:45 UTC (rev 19416)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/recovery/TransactionStatusManager.java 2008-04-04 13:22:05 UTC (rev 19417)
@@ -33,20 +33,16 @@
import java.io.* ;
import java.net.* ;
-import java.util.* ;
-import com.arjuna.common.util.propertyservice.PropertyManager;
import com.arjuna.ats.arjuna.utils.Utility ;
import com.arjuna.ats.internal.arjuna.recovery.Listener ;
import com.arjuna.ats.internal.arjuna.recovery.TransactionStatusManagerItem ;
-import com.arjuna.ats.internal.arjuna.utils.SocketProcessId;
import com.arjuna.ats.arjuna.common.arjPropertyManager;
import com.arjuna.ats.arjuna.logging.tsLogger;
-import com.arjuna.ats.arjuna.logging.FacilityCode;
+import com.arjuna.common.util.propertyservice.PropertyManager;
+import com.arjuna.common.util.propertyservice.PropertyManagerFactory;
-import com.arjuna.common.util.logging.*;
-
/**
* This implementation is tied closely with the socket/port version of
* getpid. If a pid is obtained via a port, then this class will obtain
@@ -60,39 +56,40 @@
*
* @message com.arjuna.ats.arjuna.recovery.TransactionStatusManager_1 [com.arjuna.ats.arjuna.recovery.TransactionStatusManager_1] - Starting service {0} on port {1}
* @message com.arjuna.ats.arjuna.recovery.TransactionStatusManager_2 [com.arjuna.ats.arjuna.recovery.TransactionStatusManager_2] - Listener failed
- * @message com.arjuna.ats.arjuna.recovery.TransactionStatusManager_3 [com.arjuna.ats.arjuna.recovery.TransactionStatusManager_3] - TransactionStatusManager started on port {0} with service {1}
+ * @message com.arjuna.ats.arjuna.recovery.TransactionStatusManager_3 [com.arjuna.ats.arjuna.recovery.TransactionStatusManager_3] - TransactionStatusManager started on port {0} and host {1} with service {2}
* @message com.arjuna.ats.arjuna.recovery.TransactionStatusManager_4 [com.arjuna.ats.arjuna.recovery.TransactionStatusManager_4] - Class not found: {0}
* @message com.arjuna.ats.arjuna.recovery.TransactionStatusManager_5 [com.arjuna.ats.arjuna.recovery.TransactionStatusManager_5] - Failed to instantiate service class: {0}
* @message com.arjuna.ats.arjuna.recovery.TransactionStatusManager_6 [com.arjuna.ats.arjuna.recovery.TransactionStatusManager_6] - Illegal access to service class: {0}
* @message com.arjuna.ats.arjuna.recovery.TransactionStatusManager_7 [com.arjuna.ats.arjuna.recovery.TransactionStatusManager_7] - Failed to create server socket on port: {0}
* @message com.arjuna.ats.arjuna.recovery.TransactionStatusManager_8 [com.arjuna.ats.arjuna.recovery.TransactionStatusManager_8] - Invalid port specified {0}
* @message com.arjuna.ats.arjuna.recovery.TransactionStatusManager_9 [com.arjuna.ats.arjuna.recovery.TransactionStatusManager_9] - Could not get unique port.
+ * @message com.arjuna.ats.arjuna.recovery.TransactionStatusManager_10 [com.arjuna.ats.arjuna.recovery.TransactionStatusManager_10] - Unknown host {0}
+ * @message com.arjuna.ats.arjuna.recovery.TransactionStatusManager_11 [com.arjuna.ats.arjuna.recovery.TransactionStatusManager_11] - Invalid port specified
+ * @message com.arjuna.ats.arjuna.recovery.TransactionStatusManager_12 [com.arjuna.ats.arjuna.recovery.TransactionStatusManager_12] - Unknown host specified
+ * @message com.arjuna.ats.arjuna.recovery.TransactionStatusManager_13 [com.arjuna.ats.arjuna.recovery.TransactionStatusManager_13] - Invalid host or port
+ * @message com.arjuna.ats.arjuna.recovery.TransactionStatusManager_14 [com.arjuna.ats.arjuna.recovery.TransactionStatusManager_14] - Failed to create server socket on address {0} and port: {1}
*/
public class TransactionStatusManager
{
public TransactionStatusManager()
{
- int port = getTsmPort();
-
- start( _defaultTsmService, port ) ;
+ start( _defaultTsmService, null, -1 ) ;
}
public TransactionStatusManager( int port )
{
- start( _defaultTsmService, port ) ;
+ start( _defaultTsmService, null, port ) ;
}
public TransactionStatusManager( String serviceName )
{
- int port = getTsmPort();
-
- start( serviceName, port ) ;
+ start( serviceName, null, -1 ) ;
}
public TransactionStatusManager( String serviceName, int port )
{
- start( serviceName, port ) ;
+ start( serviceName, null, port ) ;
}
/**
@@ -134,32 +131,28 @@
TransactionStatusManagerItem.removeThis( Utility.getProcessUid() ) ;
}
}
-
+
/**
* Create service and Transaction status manager item.
*/
- private void start( String serviceName, int port )
+ private void start( String serviceName, String host, int port )
{
- int localPort = 0;
-
try
{
Class serviceClass = Thread.currentThread().getContextClassLoader().loadClass( serviceName ) ;
Service service = (Service) serviceClass.newInstance() ;
- ServerSocket socketServer = getTsmServerSocket(port);
-
- localPort = socketServer.getLocalPort();
+ ServerSocket socketServer = getTsmServerSocket(host, port);
addService( service, socketServer ) ;
- TransactionStatusManagerItem.createAndSave( socketServer.getLocalPort() ) ;
+ TransactionStatusManagerItem.createAndSave(socketServer.getInetAddress().getHostAddress(), socketServer.getLocalPort() ) ;
if (tsLogger.arjLoggerI18N.isInfoEnabled())
{
tsLogger.arjLoggerI18N.info("com.arjuna.ats.arjuna.recovery.TransactionStatusManager_3",
- new Object[]{Integer.toString(localPort), serviceName});
+ new Object[]{Integer.toString(socketServer.getLocalPort()), socketServer.getInetAddress().getHostAddress(), serviceName});
}
}
catch ( ClassNotFoundException ex )
@@ -190,70 +183,100 @@
{
if (tsLogger.arjLoggerI18N.isWarnEnabled())
{
- tsLogger.arjLoggerI18N.warn("com.arjuna.ats.arjuna.recovery.TransactionStatusManager_7",
- new Object[]{Integer.toString(localPort)});
+ tsLogger.arjLoggerI18N.warn("com.arjuna.ats.arjuna.recovery.TransactionStatusManager_14",
+ new Object[]{getListenerHostName(), getListenerPort(-1)});
}
throw new com.arjuna.ats.arjuna.exceptions.FatalError(tsLogger.log_mesg.getString("com.arjuna.ats.arjuna.recovery.TransactionStatusManager_9"));
}
}
-
+
/**
- * If the socket based version of getpid is being used, then it will
- * have already assigned a port and created a ServerSocket. We should
- * use this - don't want too many ports assigned to a given process,
- * especially if they aren't used. In which case, the port parameter
- * is not used, because we got it from the getpid class anyway.
+ * Lookup the listener port for the transaction manager
+ * @param defValue the value to use if no valid port number can be found
+ * @return the listener port
*/
+ private int getListenerPort(Integer defValue)
+ {
+ // has the port already been bound
+ if (_port > 0)
+ return _port;
-private static final ServerSocket getTsmServerSocket (int port) throws IOException
+ PropertyManager pm = PropertyManagerFactory.getPropertyManager("com.arjuna.ats.propertymanager", "recoverymanager");
+ //pm = arjPropertyManager.propertyManager;
+
+ String portStr = pm.getProperty(com.arjuna.ats.arjuna.common.Environment.TRANSACTION_STATUS_MANAGER_PORT);
+
+ if ( portStr == null || portStr.length() == 0)
+ {
+ return DEFAULT_TMS_PORT;
+ }
+ else
+ {
+ Integer port = Utility.lookupBoundedIntegerProperty(pm, com.arjuna.ats.arjuna.common.Environment.TRANSACTION_STATUS_MANAGER_PORT, defValue,
+ "com.arjuna.ats.arjuna.recovery.TransactionStatusManager_8",
+ 0, Utility.MAX_PORT);
+
+ if (port == null)
+ throw new com.arjuna.ats.arjuna.exceptions.FatalError(tsLogger.log_mesg.getString("com.arjuna.ats.arjuna.recovery.TransactionStatusManager_11"));
+
+ return port;
+ }
+
+ }
+
+ private String getListenerHostName()
{
- ServerSocket socket = SocketProcessId.getSocket();
-
- return ((socket == null) ? new ServerSocket(port) : socket);
+ PropertyManager pm = PropertyManagerFactory.getPropertyManager("com.arjuna.ats.propertymanager", "recoverymanager");
+ //pm = arjPropertyManager.propertyManager;
+
+ return Utility.getServerBindAddress(pm, com.arjuna.ats.arjuna.common.Environment.TRANSACTION_STATUS_MANAGER_ADDRESS);
}
-
- /**
- * Return the port specified by the property
- * com.arjuna.ats.arjuna.recovery.TransactionStatusManagerPort,
- * otherwise return a default port.
- *
- * If the socket based version of getpid is being used, then it will
- * already have assigned our port, so use that.
- */
-private static final int getTsmPort ()
- {
- if (SocketProcessId.getSocket() == null)
- {
- int port = _defaultTsmPort ;
-
- // TODO these properties should be documented!!
+ /**
+ * Create a new listener socket. If the input paramters are invalid use the config properties
+ * to choose the desired address and port to bind the listener to. A port value of -1 is considered
+ * invalid.
+ *
+ * @param hostNameOverride override the config property for the hostname
+ * @param portOverride override the config property for the port
+ * @return a socket bound to the appropriate host and port
+ * @throws IOException if the host name is unknown
+ */
+ private ServerSocket getTsmServerSocket (String hostNameOverride, int portOverride) throws IOException
+ {
+ if (_socket != null)
+ {
+ // the socket has already been created
+ return _socket;
+ }
- String tsmPortStr = arjPropertyManager.propertyManager.getProperty("com.arjuna.ats.arjuna.recovery.transactionStatusManagerPort" ) ;
-
- if ( tsmPortStr != null )
- {
- try
- {
- port = Integer.parseInt( tsmPortStr ) ;
- }
- catch ( Exception ex )
- {
- if (tsLogger.arjLoggerI18N.isWarnEnabled())
- {
- tsLogger.arjLoggerI18N.warn("com.arjuna.ats.arjuna.recovery.TransactionStatusManager_8",
- new Object[]{ex});
- }
- }
- }
+ if (_port == -1)
+ {
+ // a previous attempt to create the socket failed
+ throw new com.arjuna.ats.arjuna.exceptions.FatalError(tsLogger.log_mesg.getString("com.arjuna.ats.arjuna.recovery.TransactionStatusManager_13"));
+ }
- return port ;
- }
- else
- return SocketProcessId.getSocket().getLocalPort();
- }
+ try
+ {
+ String host = hostNameOverride == null ? getListenerHostName() : hostNameOverride;
+ InetAddress bindAddress = Utility.hostNameToInetAddress(host, "com.arjuna.ats.arjuna.recovery.TransactionStatusManager_10");
+ _port = portOverride == -1 ? getListenerPort(null) : portOverride;
+ _socket = new ServerSocket(_port, Utility.BACKLOG, bindAddress);
+
+ _port = _socket.getLocalPort();
+ }
+ catch (UnknownHostException ex)
+ {
+ _port = -1;
+
+ throw ex;
+ }
+
+ return _socket;
+ }
+
/**
* Listener thread.
*/
@@ -263,17 +286,27 @@
* Default service run on listener thread.
*/
private static final String _defaultTsmService = "com.arjuna.ats.arjuna.recovery.ActionStatusService" ;
-
+
/**
- * Default port is any free port.
- */
- private static final int _defaultTsmPort = 0 ;
-
- /**
* Flag used to ensure finalize gets called just once.
*/
private boolean _finalizeCalled = false ;
+ /**
+ * The listener socket
+ */
+ private ServerSocket _socket;
+
+ /**
+ * Bound port for listener socket
+ * A value of -1 means that the attempt to create the socket failed
+ */
+ private int _port = 0;
+
+ /**
+ * Default bind port is any port
+ */
+ private int DEFAULT_TMS_PORT = 0;
}
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/utils/Utility.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/utils/Utility.java 2008-04-04 13:12:45 UTC (rev 19416)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/utils/Utility.java 2008-04-04 13:22:05 UTC (rev 19417)
@@ -35,16 +35,11 @@
import com.arjuna.ats.arjuna.common.*;
import com.arjuna.common.util.propertyservice.PropertyManager;
-import java.util.Properties;
-import java.io.*;
+
import java.net.InetAddress;
-import com.arjuna.ats.arjuna.exceptions.FatalError;
import java.net.UnknownHostException;
import java.lang.NumberFormatException;
-import java.lang.StringIndexOutOfBoundsException;
-import java.io.IOException;
-import java.io.FileNotFoundException;
/**
* Various useful functions that we wrap in a single class.
@@ -193,6 +188,100 @@
}
/**
+ * If the transaction service is running within a JBoss instance return the jboss bind port
+ *
+ * @param hostPropName the hostname property to use if running standalone (must not be null)
+ * @return the host name
+ */
+ public static final String getServerBindAddress(PropertyManager pm, String hostPropName)
+ {
+ String host = System.getProperty(Environment.SERVER_BIND_ADDRESS);
+
+ if (host == null)
+ {
+ host = pm.getProperty(hostPropName);
+ }
+
+ return host;
+ }
+
+ /**
+ * Convert a host name into an InetAddress object
+ *
+ * @param host if empty or null then the loopback address is used
+ * @param messageKey message key to a report warning if host is unknown
+ * @return an InetAddress structure corresponding the desired host name
+ * @throws UnknownHostException if the hostname cannot be found
+ */
+ public static InetAddress hostNameToInetAddress(String host, String messageKey) throws UnknownHostException
+ {
+ try {
+ if (host == null || host.length() == 0)
+ return InetAddress.getLocalHost();
+ else
+ return InetAddress.getByName(host);
+ }
+ catch (UnknownHostException ex)
+ {
+ /*
+ * The hostname is unknown
+ */
+ if (tsLogger.arjLoggerI18N.isWarnEnabled() && messageKey != null)
+ tsLogger.arjLoggerI18N.warn(messageKey,ex);
+
+ throw ex;
+ }
+ }
+
+ /**
+ * Lookup and valid a port number.
+ *
+ * @param intProperty property name of an integer valued property
+ * @param defValue a value to return if intProperty is invalid. If a null value is used and intProperty is invalid then @com.arjuna.ats.arjuna.exceptions.FatalError
+ * is thrown
+ * @param warnMsgKey message key to report a warning if property values is invalid
+ * @param minValue minimum value for the integer propertry
+ * @param maxValue maximum value for the integer propertry
+ * @return the integer value of property or the default value if the property does not represent an integer
+ */
+ public static Integer lookupBoundedIntegerProperty(PropertyManager pm, String intProperty, Integer defValue, String warnMsgKey, int minValue, int maxValue)
+ {
+ String intStr = pm.getProperty(intProperty);
+
+ // if the propery is not found or empty just return the default
+ if (intStr == null || intStr.length() == 0)
+ {
+ return defValue;
+ }
+
+ try
+ {
+ int i = Integer.parseInt(intStr);
+
+ if (i < minValue || i > maxValue)
+ {
+ // the value is an invalid number
+ if (warnMsgKey != null && tsLogger.arjLoggerI18N.isWarnEnabled())
+ {
+ tsLogger.arjLoggerI18N.warn(warnMsgKey, new Object[]{intStr});
+ }
+ }
+ else
+ {
+ return i;
+ }
+ }
+ catch (Exception ex)
+ {
+ // the value is not a number
+ if (warnMsgKey != null && tsLogger.arjLoggerI18N.isWarnEnabled())
+ tsLogger.arjLoggerI18N.warn(warnMsgKey,ex);
+ }
+
+ return defValue;
+ }
+
+ /**
* @return the process id. This had better be unique between processes
* on the same machine. If not we're in trouble!
*
@@ -271,6 +360,14 @@
private static final String hexStart = "0x";
private static final String defaultProcessId = "com.arjuna.ats.internal.arjuna.utils.SocketProcessId";
-
+ /**
+ * The maximum queue length for incoming connection indications (a request to connect)
+ */
+ public static final int BACKLOG = 50;
+
+ /**
+ * Maximum value for a socket port
+ */
+ public static final int MAX_PORT = 65535;
}
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/PeriodicRecovery.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/PeriodicRecovery.java 2008-04-04 13:12:45 UTC (rev 19416)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/PeriodicRecovery.java 2008-04-04 13:22:05 UTC (rev 19417)
@@ -42,10 +42,12 @@
import com.arjuna.ats.arjuna.recovery.RecoveryModule;
import com.arjuna.ats.arjuna.recovery.RecoveryEnvironment;
+import com.arjuna.ats.arjuna.recovery.RecoveryManager;
import com.arjuna.ats.arjuna.common.arjPropertyManager;
import com.arjuna.ats.arjuna.logging.FacilityCode;
import com.arjuna.ats.arjuna.logging.tsLogger;
+import com.arjuna.ats.arjuna.utils.Utility;
import com.arjuna.common.util.logging.*;
@@ -70,6 +72,9 @@
* @message com.arjuna.ats.internal.arjuna.recovery.PeriodicRecovery_8 [com.arjuna.ats.internal.arjuna.recovery.PeriodicRecovery_8] - Invalid port specified {0}
* @message com.arjuna.ats.internal.arjuna.recovery.PeriodicRecovery_9 [com.arjuna.ats.internal.arjuna.recovery.PeriodicRecovery_9] - Could not create recovery listener {0}
* @message com.arjuna.ats.internal.arjuna.recovery.PeriodicRecovery_10 [com.arjuna.ats.internal.arjuna.recovery.PeriodicRecovery_10] - Ignoring request to scan because RecoveryManager state is: {0}
+ * @message com.arjuna.ats.internal.arjuna.recovery.PeriodicRecovery_11 [com.arjuna.ats.internal.arjuna.recovery.PeriodicRecovery_11] - Invalid host specified {0}
+ * @message com.arjuna.ats.internal.arjuna.recovery.PeriodicRecovery_12 [com.arjuna.ats.internal.arjuna.recovery.PeriodicRecovery_12] - Could not create recovery listener
+ * @message com.arjuna.ats.internal.arjuna.recovery.PeriodicRecovery_13 [com.arjuna.ats.internal.arjuna.recovery.PeriodicRecovery_13] - Recovery manager listening on endpoint {0}:{1}
*/
public class PeriodicRecovery extends Thread
@@ -151,6 +156,13 @@
_listener = new Listener(getServerSocket(), _workerService);
_listener.setDaemon(true);
+
+ if (tsLogger.arjLoggerI18N.isInfoEnabled())
+ tsLogger.arjLoggerI18N.info(
+ "com.arjuna.ats.internal.arjuna.recovery.PeriodicRecovery_13",
+ new Object[] {
+ _socket.getInetAddress().getHostAddress(), _socket.getLocalPort()
+ });
}
catch (Exception ex)
{
@@ -294,40 +306,20 @@
}
}
- /**
- * Return the port specified by the property
- * com.arjuna.ats.internal.arjuna.recovery.recoveryPort,
- * otherwise return a default port.
- */
-
+ /**
+ *
+ * @return a bound server socket corresponding to the recovery manager
+ * @throws IOException if the host name is unknown or the endpoint has already been bound
+ */
public static ServerSocket getServerSocket () throws IOException
{
- if (_socket == null)
- {
- // TODO these properties should be documented!!
+ synchronized (PeriodicRecovery._socketLock)
+ {
+ if (_socket == null)
+ _socket = new ServerSocket(RecoveryManager.getRecoveryManagerPort(), Utility.BACKLOG, RecoveryManager.getRecoveryManagerHost(true));
- String tsmPortStr = arjPropertyManager.propertyManager.getProperty(com.arjuna.ats.arjuna.common.Environment.RECOVERY_MANAGER_PORT);
- int port = 0;
-
- if (tsmPortStr != null)
- {
- try
- {
- port = Integer.parseInt( tsmPortStr );
- }
- catch (Exception ex)
- {
- if (tsLogger.arjLoggerI18N.isWarnEnabled())
- {
- tsLogger.arjLoggerI18N.warn("com.arjuna.ats.internal.arjuna.recovery.PeriodicRecovery_8", new Object[]{ex});
- }
- }
- }
-
- _socket = new ServerSocket(port);
- }
-
- return _socket;
+ return _socket;
+ }
}
/**
@@ -1042,6 +1034,7 @@
* socket used by listener worker thread
*/
private static ServerSocket _socket = null;
+ private static final Object _socketLock = new Object();
/**
* listener thread running worker service
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/RecoveryManagerImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/RecoveryManagerImple.java 2008-04-04 13:12:45 UTC (rev 19416)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/RecoveryManagerImple.java 2008-04-04 13:22:05 UTC (rev 19417)
@@ -40,6 +40,7 @@
import com.arjuna.ats.arjuna.exceptions.FatalError;
import com.arjuna.ats.arjuna.recovery.RecoveryConfiguration;
import com.arjuna.ats.arjuna.recovery.RecoveryModule;
+import com.arjuna.ats.arjuna.recovery.RecoveryManager;
import com.arjuna.ats.arjuna.logging.FacilityCode;
import com.arjuna.ats.arjuna.logging.tsLogger;
@@ -74,6 +75,9 @@
* @message com.arjuna.ats.internal.arjuna.recovery.ready
* [com.arjuna.ats.internal.arjuna.recovery.ready]
* RecoveryManagerImple is ready on port {0}
+ * @message com.arjuna.ats.internal.arjuna.recovery.fail
+ * [com.arjuna.ats.internal.arjuna.recovery.fail]
+ * RecoveryManagerImple: cannot bind to socket on address {0} and port {1}
*/
public RecoveryManagerImple (boolean threaded)
@@ -112,12 +116,34 @@
/*
* Check whether there is a recovery daemon running - only allow one per
- * machine (currently!)
+ * object store
*/
- if (activeRecoveryManager())
+ if (isRecoveryManagerEndPointInUse())
{
- throw new FatalError("Recovery manager already active!");
+ if (tsLogger.arjLoggerI18N.isFatalEnabled())
+ {
+ try
+ {
+ tsLogger.arjLoggerI18N.fatal(
+ "com.arjuna.ats.internal.arjuna.recovery.fail",
+ new Object[] {
+ RecoveryManager.getRecoveryManagerHost(true), RecoveryManager.getRecoveryManagerPort()
+ }
+ );
+ }
+ catch (Throwable t)
+ {
+ tsLogger.arjLoggerI18N.fatal(
+ "com.arjuna.ats.internal.arjuna.recovery.fail",
+ new Object[] {
+ "unknown", "unknown"
+ }
+ );
+ }
+ }
+
+ throw new FatalError("Recovery manager already active (or recovery port and address are in use)!");
}
// start the expiry scanners
@@ -221,28 +247,30 @@
stop(true);
}
- private final boolean activeRecoveryManager ()
+ /**
+ * Test whether the recovery manager (RM) port and address are available - if not assume that another
+ * recovery manager is already active.
+ *
+ * Ideally this method needs to discover whether or not another RM is already monitoring the object store
+ *
+ * @return true if the RM port and address are in use
+ */
+ private final boolean isRecoveryManagerEndPointInUse ()
{
- // we should be checking for the port in use or something!
+ try
+ {
+ /*
+ * attempt to create the server socket. If an exception is thrown then some other
+ * process is using the RM endpoint
+ */
+ PeriodicRecovery.getServerSocket();
- SocketProcessId socket = null;
- boolean active = false;
-
- try
- {
- socket = new SocketProcessId();
-
- if (socket.getpid() == -1)
- active = true;
- }
- catch (FatalError ex)
- {
- // already active on that port
-
- active = true;
- }
-
- return active;
+ return false;
+ }
+ catch (Throwable e)
+ {
+ return true;
+ }
}
}
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/TransactionStatusManagerItem.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/TransactionStatusManagerItem.java 2008-04-04 13:12:45 UTC (rev 19416)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/TransactionStatusManagerItem.java 2008-04-04 13:22:05 UTC (rev 19417)
@@ -74,7 +74,20 @@
}
return ret_status ;
}
-
+
+ public static boolean createAndSave(String hostAddress, int port )
+ {
+ boolean ret_status = true ;
+
+ if ( _singularItem == null )
+ {
+ _singularItem = new TransactionStatusManagerItem(hostAddress, port );
+
+ ret_status = _singularItem.saveThis();
+ }
+ return ret_status ;
+ }
+
/**
* Get a reference to the Object Store.
*/
@@ -343,8 +356,40 @@
}
}
}
-
+
/**
+ * Constructor which obtains the process uid for
+ * use with the specified host and port.
+ */
+ private TransactionStatusManagerItem (String host, int port )
+ {
+ _pidUid = Utility.getProcessUid() ;
+ _port = port ;
+
+ try
+ {
+ // make sure the passed in host is valid
+ Utility.hostNameToInetAddress(host, "com.arjuna.ats.internal.arjuna.recovery.TransactionStatusManagerItem_4");
+ _host = host;
+
+ if (tsLogger.arjLogger.isInfoEnabled())
+ {
+ tsLogger.arjLogger.info
+ ( "TransactionStatusManagerItem - " + "host: " + _host +
+ " port: " + _port ) ;
+ }
+ }
+ catch ( UnknownHostException ex )
+ {
+ if (tsLogger.arjLoggerI18N.isWarnEnabled())
+ {
+ tsLogger.arjLoggerI18N.warn("com.arjuna.ats.internal.arjuna.recovery.TransactionStatusManagerItem_4",
+ new Object[]{ex});
+ }
+ }
+ }
+
+ /**
* Used by a Recovery Manager to recreate a Transaction
* status manager contact item.
*/
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/utils/SocketProcessId.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/utils/SocketProcessId.java 2008-04-04 13:12:45 UTC (rev 19416)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/utils/SocketProcessId.java 2008-04-04 13:22:05 UTC (rev 19417)
@@ -32,21 +32,15 @@
package com.arjuna.ats.internal.arjuna.utils;
import com.arjuna.ats.arjuna.logging.tsLogger;
-import com.arjuna.common.util.propertyservice.PropertyManager;
+import com.arjuna.ats.arjuna.common.Environment;
import com.arjuna.ats.arjuna.common.arjPropertyManager;
-import com.arjuna.ats.arjuna.utils.Process;
import com.arjuna.ats.arjuna.utils.Utility;
-import java.io.*;
import java.net.*;
import com.arjuna.ats.arjuna.exceptions.FatalError;
-import java.net.UnknownHostException;
-import java.lang.NumberFormatException;
-import java.lang.StringIndexOutOfBoundsException;
import java.io.IOException;
-import java.io.FileNotFoundException;
/**
* Obtains a unique value to represent the process id via sockets and
@@ -70,6 +64,7 @@
*
* @message com.arjuna.ats.internal.arjuna.utils.SocketProcessId_1 [com.arjuna.ats.internal.arjuna.utils.SocketProcessId_1]- Invalid port specified
* @message com.arjuna.ats.internal.arjuna.utils.SocketProcessId_2 [com.arjuna.ats.internal.arjuna.utils.SocketProcessId_2] - SocketProcessId.getpid could not get unique port.
+ * @message com.arjuna.ats.internal.arjuna.utils.SocketProcessId_3 [com.arjuna.ats.internal.arjuna.utils.SocketProcessId_3]- Invalid value for SocketProcessIdMaxPorts specified {0}
*/
public int getpid ()
@@ -80,40 +75,32 @@
{
if (_theSocket == null)
{
- int port = _defaultPort;
-
- String portStr = arjPropertyManager.propertyManager.getProperty("com.arjuna.ats.arjuna.recovery.transactionStatusManagerPort");
+ Integer port = Utility.lookupBoundedIntegerProperty(arjPropertyManager.propertyManager, Environment.SOCKET_PROCESS_ID_PORT, _defaultPort,
+ "com.arjuna.ats.internal.arjuna.utils.SocketProcessId_1",
+ 0, Utility.MAX_PORT);
+ Integer maxPorts = Utility.lookupBoundedIntegerProperty(arjPropertyManager.propertyManager, Environment.SOCKET_PROCESS_ID_MAX_PORTS, 1,
+ "com.arjuna.ats.internal.arjuna.utils.SocketProcessId_3",
+ 0, Utility.MAX_PORT);
+ int maxPort;
+
+ if (maxPorts <= 1)
+ {
+ maxPort = port;
+ }
+ else if (Utility.MAX_PORT - maxPorts < port)
+ {
+ maxPort = Utility.MAX_PORT;
+ }
+ else
+ {
+ maxPort = port + maxPorts;
+ }
- if ( portStr != null )
- {
- try
- {
- port = Integer.parseInt(portStr);
- }
- catch (Exception ex)
- {
- if (tsLogger.arjLoggerI18N.isWarnEnabled())
- tsLogger.arjLoggerI18N.warn("com.arjuna.ats.internal.arjuna.utils.SocketProcessId_1",ex);
-
- port = -1;
- }
- }
-
- if (port != -1)
- {
- try
- {
- _theSocket = new ServerSocket(port);
-
- _thePort = _theSocket.getLocalPort();
- }
- catch (Exception ex)
- {
- _thePort = -1;
- }
- }
- else
- _thePort = -1;
+ do {
+ _theSocket = createSocket(port);
+ } while (_theSocket == null && ++port < maxPort);
+
+ _thePort = ((_theSocket == null) ? -1 : _theSocket.getLocalPort());
}
}
}
@@ -124,8 +111,20 @@
return _thePort;
}
- public static final ServerSocket getSocket ()
+ private static ServerSocket createSocket(int port)
{
+ try
+ {
+ return new ServerSocket(port);
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+
+ public static ServerSocket getSocket ()
+ {
synchronized (SocketProcessId._lock)
{
return _theSocket;
@@ -134,7 +133,7 @@
private static int _thePort = 0;
private static ServerSocket _theSocket = null;
- private static Object _lock = new Object();
+ private static final Object _lock = new Object();
/**
* Default port is any free port.
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/etc/default-RecoveryManager-properties.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/etc/default-RecoveryManager-properties.xml 2008-04-04 13:12:45 UTC (rev 19416)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/etc/default-RecoveryManager-properties.xml 2008-04-04 13:22:05 UTC (rev 19417)
@@ -79,7 +79,19 @@
<property
name="com.arjuna.ats.arjuna.recovery.expiryScanInterval"
value="12"/>
+
<!--
+ The address and port number on which the recovery manager listens
+ If running within an AS then the address the AS is bound to (jboss.bind.address) takes precedence
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.recovery.recoveryPort"
+ value="4712"/>
+ <property
+ name="com.arjuna.ats.arjuna.recovery.recoveryAddress"
+ value=""/>
+
+ <!--
Age, in hours, for removal of transaction status manager item.
This should be longer than any ts-using process will remain running.
Zero = Never removed. Default is 12.
@@ -94,5 +106,15 @@
<property
name="com.arjuna.ats.arjuna.recovery.transactionStatusManagerPort"
value="0"/>
+
+ <!--
+ Use this to fix the address on which the TransactionStatusManager binds,
+ The default behaviour is to use the loopback address (ie localhost).
+ If running within an AS then the address the AS is bound to (jboss.bind.address) takes precedence
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.recovery.transactionStatusManagerAddress"
+ value=""/>
+
</properties>
</transaction-service>
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/etc/default-arjuna-properties.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/etc/default-arjuna-properties.xml 2008-04-04 13:12:45 UTC (rev 19416)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/etc/default-arjuna-properties.xml 2008-04-04 13:22:05 UTC (rev 19417)
@@ -123,6 +123,28 @@
name="com.arjuna.ats.arjuna.xa.nodeIdentifier"
value="1"/>
+ <!--
+ Base port number for determining a unique number to associate with an instance of the transaction service
+ (which is needed in order to support multiple instances on the same machine).
+ Use the value 0 to allow the system to select the first available port number.
+ If the port number is non-zero and the port is in use then the value will be incremented until either a successful binding
+ to the loopback address is created or until the the maximum number of ports (specified by the
+ com.arjuna.ats.internal.arjuna.utils.SocketProcessIdMaxPorts property) have been tried or until the port number
+ reaches the maximum possible port number.
+ -->
+ <property
+ name="com.arjuna.ats.internal.arjuna.utils.SocketProcessIdPort"
+ value="0"/>
+
+ <!--
+ The maximum number of ports to try starting from the value specified by the property
+ com.arjuna.ats.internal.arjuna.utils.SocketProcessIdPort. Any non-numeric or value less than 1 will
+ defautl to 1.
+ -->
+ <property
+ name="com.arjuna.ats.internal.arjuna.utils.SocketProcessIdMaxPorts"
+ value="1"/>
+
<!-- property
name="com.arjuna.ats.arjuna.coordinator.actionStore"
value="HashedActionStore"
Modified: labs/jbosstm/trunk/ArjunaJTA/jta/etc/default-RecoveryManager-properties.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/etc/default-RecoveryManager-properties.xml 2008-04-04 13:12:45 UTC (rev 19416)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/etc/default-RecoveryManager-properties.xml 2008-04-04 13:22:05 UTC (rev 19417)
@@ -50,6 +50,20 @@
name="com.arjuna.ats.arjuna.recovery.recoveryBackoffPeriod"
value="10"/>
<!--
+ The port number on which the recovery manager listens.
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.recovery.recoveryPort"
+ value="4712"/>
+ <!--
+ The address on which the recovery manager listens.
+ If running within an AS then the address the AS is bound to (jboss.bind.address) takes precedence
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.recovery.recoveryAddress"
+ value=""/>
+
+ <!--
Periodic recovery modules to use. Invoked in sort-order of names.
-->
<property
@@ -99,5 +113,14 @@
name="com.arjuna.ats.arjuna.recovery.transactionStatusManagerPort"
value="0"/>
+ <!--
+ Use this to fix the address on which the TransactionStatusManager binds,
+ The default behaviour is to use the loopback address (ie localhost).
+ If running within an AS then the address the AS is bound to (jboss.bind.address) takes precedence
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.recovery.transactionStatusManagerAddress"
+ value=""/>
+
</properties>
</transaction-service>
Modified: labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/jacorb/recoverycoordinators/JacOrbRCServiceInit.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/jacorb/recoverycoordinators/JacOrbRCServiceInit.java 2008-04-04 13:12:45 UTC (rev 19416)
+++ labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/jacorb/recoverycoordinators/JacOrbRCServiceInit.java 2008-04-04 13:22:05 UTC (rev 19417)
@@ -55,6 +55,8 @@
import com.arjuna.ats.arjuna.coordinator.TxControl;
import com.arjuna.ats.arjuna.objectstore.ObjectStore;
import com.arjuna.ats.arjuna.state.*;
+import com.arjuna.ats.arjuna.utils.Utility;
+
import java.io.IOException;
import java.util.Properties;
@@ -70,7 +72,7 @@
* @message com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRCServiceInit_3 [com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRCServiceInit_3] - JacOrbRCServiceInit - Failed to start RC service
* @message com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRCServiceInit_4 [com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRCServiceInit_4] - Unable to create file ObjectId
* @message com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRCServiceInit_5 [com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRCServiceInit_5] - Unable to create file ObjectId - security problems
- * @message com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRCServiceInit_6 [com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRCServiceInit_6] - Staring RecoveryServer ORB on port {0}
+ * @message com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRCServiceInit_6 [com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRCServiceInit_6] - Starting RecoveryServer ORB on port {0} and address {1}
* @message com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRCServiceInit_6a [com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRCServiceInit_6a] - Sharing RecoveryServer ORB on port {0}
* @message com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRCServiceInit_7 [com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRCServiceInit_7] - Failed to create orb and poa for transactional objects {1}
*/
@@ -105,19 +107,26 @@
String poaName = POA_NAME_PREFIX + rcServiceName+domainName;
boolean oaInit = true;
String oaPort = "OAPort";
- String oldPort = System.getProperty(oaPort, "");
+ String oaAddr = "OAIAddr";
+ String oldPort = System.getProperty(oaPort, "");
+ String oldAddr = System.getProperty(oaAddr, "");
- /** If the ORB Manager hasn't been initialised then create our own ORB **/
+ /** If the ORB Manager hasn't been initialised then create our own ORB **/
if ( !RecoveryORBManager.isInitialised() )
{
_orb = com.arjuna.orbportability.internal.InternalORB.getInstance("RecoveryServer");
String[] params = null;
String recoveryManagerPort = jtsPropertyManager.propertyManager.getProperty(com.arjuna.ats.jts.common.Environment.RECOVERY_MANAGER_PORT, "4711");
+ String recoveryManagerAddr = Utility.getServerBindAddress(jtsPropertyManager.propertyManager, com.arjuna.ats.jts.common.Environment.RECOVERY_MANAGER_ADDRESS);
- if (jtsLogger.loggerI18N.isInfoEnabled())
+ if (recoveryManagerAddr == null)
+ recoveryManagerAddr = "";
+
+ if (jtsLogger.loggerI18N.isInfoEnabled())
{
- jtsLogger.loggerI18N.info("com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRCServiceInit_6", new java.lang.Object[]{recoveryManagerPort});
+ jtsLogger.loggerI18N.info("com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRCServiceInit_6",
+ new java.lang.Object[]{recoveryManagerPort, recoveryManagerAddr});
}
final Properties p = new Properties();
@@ -139,15 +148,22 @@
}
}
p.setProperty(oaPort, recoveryManagerPort);
- _orb.initORB(params, p);
+
+ if (recoveryManagerAddr.length() != 0)
+ {
+ p.setProperty(oaAddr, recoveryManagerAddr);
+ System.setProperty(oaAddr, oldAddr);
+ }
+
+ _orb.initORB(params, p);
_oa = OA.getRootOA(_orb);
if (oldPort == null)
oldPort = "";
-
- System.setProperty(oaPort, oldPort); // Remove property that JacORB added so future ORB's work.
- RecoveryORBManager.setORB(_orb);
+ System.setProperty(oaPort, oldPort); // Remove property that JacORB added so future ORB's work.
+
+ RecoveryORBManager.setORB(_orb);
RecoveryORBManager.setPOA(_oa);
}
else
Modified: labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/jts/common/Environment.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/jts/common/Environment.java 2008-04-04 13:12:45 UTC (rev 19416)
+++ labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/jts/common/Environment.java 2008-04-04 13:22:05 UTC (rev 19417)
@@ -56,5 +56,6 @@
public static final String PROPAGATE_TERMINATOR = "com.arjuna.ats.jts.propagateTerminator";
public static final String CONTEXT_PROP_MODE = "com.arjuna.ats.jts.contextPropMode";
public static final String RECOVERY_MANAGER_PORT = "com.arjuna.ats.jts.recoveryManagerPort";
+ public static final String RECOVERY_MANAGER_ADDRESS = "com.arjuna.ats.jts.recoveryManagerAddress";
public static final String OTS_1_0_TIMEOUT_PROPAGATION = "com.arjuna.ats.jts.ots_1_0.timeoutPropagation";
}
Modified: labs/jbosstm/trunk/ArjunaJTS/jts/etc/default-RecoveryManager-properties.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jts/etc/default-RecoveryManager-properties.xml 2008-04-04 13:12:45 UTC (rev 19416)
+++ labs/jbosstm/trunk/ArjunaJTS/jts/etc/default-RecoveryManager-properties.xml 2008-04-04 13:22:05 UTC (rev 19417)
@@ -116,7 +116,22 @@
<property
name="com.arjuna.ats.arjuna.recovery.transactionStatusManagerExpiryTime"
value="12"/>
+
<!--
+ The port number on which the recovery manager listens.
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.recovery.recoveryPort"
+ value="4712"/>
+ <!--
+ The address on which the recovery manager listens.
+ If running within an AS then the address the AS is bound to (jboss.bind.address) takes precedence
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.recovery.recoveryAddress"
+ value=""/>
+
+ <!--
Use this to fix the port on which the TransactionStatusManager listens,
The default behaviour is to use any free port.
-->
@@ -124,5 +139,14 @@
name="com.arjuna.ats.arjuna.recovery.transactionStatusManagerPort"
value="0"/>
+ <!--
+ Use this to fix the address on which the TransactionStatusManager binds,
+ The default behaviour is to use the loopback address (ie localhost).
+ If running within an AS then the address the AS is bound to (jboss.bind.address) takes precedence
+ -->
+ <property
+ name="com.arjuna.ats.arjuna.recovery.transactionStatusManagerAddress"
+ value=""/>
+
</properties>
</transaction-service>
Modified: labs/jbosstm/trunk/ArjunaJTS/jts/etc/default-jts-properties.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jts/etc/default-jts-properties.xml 2008-04-04 13:12:45 UTC (rev 19416)
+++ labs/jbosstm/trunk/ArjunaJTS/jts/etc/default-jts-properties.xml 2008-04-04 13:22:05 UTC (rev 19417)
@@ -137,5 +137,13 @@
<property
name="com.arjuna.ats.jts.recoveryManagerPort"
value="4711"/>
+
+ <!--
+ This property controls the address on which the Recovery ORB binds - defaults to the loopback connection
+ If running within an AS then the address the AS is bound to (jboss.bind.address) takes precedence
+ -->
+ <property
+ name="com.arjuna.ats.jts.recoveryManagerAddress"
+ value=""/>
</properties>
</transaction-service>
Modified: labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/jbossatx/jta/TransactionManagerService.java
===================================================================
--- labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/jbossatx/jta/TransactionManagerService.java 2008-04-04 13:12:45 UTC (rev 19416)
+++ labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/jbossatx/jta/TransactionManagerService.java 2008-04-04 13:22:05 UTC (rev 19417)
@@ -33,6 +33,7 @@
import org.jboss.mx.util.ObjectNameFactory;
import org.jboss.system.ServiceMBeanSupport;
import org.jboss.system.server.Server;
+import org.jboss.system.server.ServerConfig;
import org.jboss.tm.JBossXATerminator;
import org.jboss.tm.LastResource;
import org.jboss.tm.XAExceptionFormatter;
@@ -133,7 +134,8 @@
System.setProperty(com.arjuna.ats.tsmx.TransactionServiceMX.AGENT_IMPLEMENTATION_PROPERTY,
com.arjuna.ats.internal.jbossatx.agent.LocalJBossAgentImpl.class.getName());
System.setProperty(Environment.LAST_RESOURCE_OPTIMISATION_INTERFACE, LastResource.class.getName()) ;
-
+ System.setProperty(com.arjuna.ats.arjuna.common.Environment.SERVER_BIND_ADDRESS, System.getProperty(ServerConfig.SERVER_BIND_ADDRESS));
+
if (timeout != 0)
{
TxControl.setDefaultTimeout(timeout);
@@ -219,39 +221,17 @@
private boolean isRecoveryManagerRunning() throws Exception
{
boolean active = false;
- int port = 0;
PropertyManager pm = PropertyManagerFactory.getPropertyManager("com.arjuna.ats.propertymanager", "recoverymanager");
if ( pm != null )
{
- String portStr = pm.getProperty(com.arjuna.ats.arjuna.common.Environment.RECOVERY_MANAGER_PORT);
-
- if (portStr != null)
- {
- try
- {
- port = Integer.parseInt(portStr);
- }
- catch (Exception ex)
- {
- port = -1;
- }
- }
- else
- {
- throw new Exception("The transaction status manager port is not set - please refer to the JBossTS documentation");
- }
-
-
BufferedReader in = null;
PrintStream out = null;
try
{
- getLog().info("Connecting to recovery manager on port "+port);
+ Socket sckt = RecoveryManager.getClientSocket(getRunInVMRecoveryManager());
- Socket sckt = new Socket(InetAddress.getLocalHost(),port);
-
in = new BufferedReader(new InputStreamReader(sckt.getInputStream()));
out = new PrintStream(sckt.getOutputStream());
Modified: labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/jbossatx/jts/TransactionManagerService.java
===================================================================
--- labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/jbossatx/jts/TransactionManagerService.java 2008-04-04 13:12:45 UTC (rev 19416)
+++ labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/jbossatx/jts/TransactionManagerService.java 2008-04-04 13:22:05 UTC (rev 19417)
@@ -32,6 +32,7 @@
import org.jboss.system.ServiceMBeanSupport;
import org.jboss.system.server.Server;
+import org.jboss.system.server.ServerConfig;
import org.jboss.iiop.CorbaORBService;
import org.jboss.mx.util.ObjectNameFactory;
import org.jboss.tm.JBossXATerminator;
@@ -69,6 +70,7 @@
import javax.transaction.UserTransaction;
import java.net.Socket;
import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
@@ -137,6 +139,8 @@
com.arjuna.ats.internal.jbossatx.agent.LocalJBossAgentImpl.class.getName());
System.setProperty(Environment.LAST_RESOURCE_OPTIMISATION_INTERFACE, LastResource.class.getName()) ;
+ System.setProperty(com.arjuna.ats.arjuna.common.Environment.SERVER_BIND_ADDRESS, System.getProperty(ServerConfig.SERVER_BIND_ADDRESS));
+
final String alwaysPropagateProperty = alwaysPropagateContext ? "YES" : "NO" ;
System.setProperty(com.arjuna.ats.jts.common.Environment.ALWAYS_PROPAGATE_CONTEXT, alwaysPropagateProperty);
@@ -235,38 +239,17 @@
private boolean isRecoveryManagerRunning() throws Exception
{
boolean active = false;
- int port = 0;
PropertyManager pm = PropertyManagerFactory.getPropertyManager("com.arjuna.ats.propertymanager", "recoverymanager");
if ( pm != null )
{
- String portStr = pm.getProperty(com.arjuna.ats.arjuna.common.Environment.RECOVERY_MANAGER_PORT);
-
- if (portStr != null)
- {
- try
- {
- port = Integer.parseInt(portStr);
- }
- catch (Exception ex)
- {
- port = -1;
- }
- }
- else
- {
- throw new Exception("The transaction status manager port is not set - please refer to the JBossTS documentation");
- }
-
BufferedReader in = null;
PrintStream out = null;
try
{
- getLog().info("Connecting to recovery manager on port "+port);
+ Socket sckt = RecoveryManager.getClientSocket(getRunInVMRecoveryManager());
- Socket sckt = new Socket(InetAddress.getLocalHost(),port);
-
in = new BufferedReader(new InputStreamReader(sckt.getInputStream()));
out = new PrintStream(sckt.getOutputStream());
@@ -280,7 +263,18 @@
}
catch (Exception ex)
{
- getLog().error("Failed to connect to recovery manager", ex);
+ try
+ {
+ InetAddress host = RecoveryManager.getRecoveryManagerHost(getRunInVMRecoveryManager());
+ int port = RecoveryManager.getRecoveryManagerPort();
+
+ getLog().error("Failed to connect to recovery manager on " + host.getHostAddress() + ':' + port);
+ }
+ catch (UnknownHostException e)
+ {
+ getLog().error("Failed to connect to recovery manager", ex);
+ }
+
active = false;
}
finally
More information about the jboss-svn-commits
mailing list