+
-
- ${alfresco.jgroups.configLocation}
-
diff --git a/config/alfresco/jgroups-default.xml b/config/alfresco/jgroups-default.xml
deleted file mode 100644
index 4ea0e87e69..0000000000
--- a/config/alfresco/jgroups-default.xml
+++ /dev/null
@@ -1,116 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/config/alfresco/jgroups/JGroups-2.8.xsd b/config/alfresco/jgroups/JGroups-2.8.xsd
new file mode 100644
index 0000000000..82585ccb74
--- /dev/null
+++ b/config/alfresco/jgroups/JGroups-2.8.xsd
@@ -0,0 +1,2000 @@
+
+
+
+
+
+
+
+
+
+The NIC on which the ServerSocket should listen on
+
+
+
+
+Timeout for getting socket cache from coordinator. Default is 1000 msec
+
+
+
+
+Interval for broadcasting suspect messages. Default is 5000 msec
+
+
+
+
+Number of attempts coordinator is solicited for socket cache until we give up. Default is 3
+
+
+
+
+Start port for server socket. Default value of 0 picks a random port
+
+
+
+
+Whether to use KEEP_ALIVE on the ping socket or not. Default is true
+
+
+
+
+Max time in millis to wait for ping Socket.connect() to return
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+Number of ports to be probed for initial membership. Default is 1
+
+
+
+
+Comma delimeted list of hosts to be contacted for initial membership
+
+
+
+
+Timeout to wait for the initial members. Default is 3000 msec
+
+
+
+
+Minimum number of initial members to get a response from. Default is 2
+
+
+
+
+Minimum number of server responses (PingData.isServer()=true). If this value is greater than 0, we'll ignore num_initial_members
+
+
+
+
+Return from the discovery phase as soon as we have 1 coordinator response
+
+
+
+
+Number of discovery requests to be sent distributed over timeout. Default is 2
+
+
+
+
+Whether or not to return the entire logical-physical address cache mappings on a discovery request, or not. Default is false, except for TCPPING
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+The interface (NIC) which should be used by this transport
+
+
+
+
+Ignores all bind address parameters and let's the OS return the local host address. Default is false
+
+
+
+
+ If true, the transport should use all available interfaces to receive multicast messages. Default is false
+
+
+
+
+Comma delimited list of interfaces (IP addresses or interface names) to receive multicasts on
+
+
+
+
+The port to which the transport binds. Default of 0 binds to any (ephemeral) port
+
+
+
+
+
+
+
+
+
+tries to make sure ephemeral ports are used
+
+
+
+
+Messages to self are looped back immediately if true. Default is false
+
+
+
+
+Discard packets with a different version if true. Default is false
+
+
+
+
+Thread naming pattern for threads in this channel. Default is cl
+
+
+
+
+Switch for enabling thread pool for OOB messages. Default true
+
+
+
+
+Minimum thread pool size for OOB messages. Default is 2
+
+
+
+
+Maximum thread pool size for OOB messages. Default is 10
+
+
+
+
+Timeout in milliseconds to remove idle thread from OOB pool. Default is 30000
+
+
+
+
+Use queue to enqueue incoming OOB messages. Default is true
+
+
+
+
+Maximum queue size for incoming OOB messages. Default is 500
+
+
+
+
+Thread rejection policy. Possible values are Abort, Discard, DiscardOldest and Run. Default is Run
+
+
+
+
+Minimum thread pool size for regular messages. Default is 2
+
+
+
+
+Maximum thread pool size for regular messages. Default is 10
+
+
+
+
+Timeout in milliseconds to remove idle thread from regular pool. Default is 30000
+
+
+
+
+Switch for enabling thread pool for regular messages. Default true
+
+
+
+
+Use queue to enqueue incoming regular messages. Default is true
+
+
+
+
+Maximum queue size for incoming OOB messages. Default is 500
+
+
+
+
+Thread rejection policy. Possible values are Abort, Discard, DiscardOldest and Run Default is Run
+
+
+
+
+Number of threads to be used by the timer thread pool. Default is 4
+
+
+
+
+Enable bundling of smaller messages into bigger ones. Default is true
+
+
+
+
+Enable bundling of smaller messages into bigger ones for unicast messages. Default is false
+
+
+
+
+Switch to enable diagnostic probing. Default is true
+
+
+
+
+Address for diagnostic probing. Default is 224.0.75.75
+
+
+
+
+Port for diagnostic probing. Default is 7500
+
+
+
+
+If assigned enable this transport to be a singleton (shared) transport
+
+
+
+
+Path to a file to store currently used ports on this machine
+
+
+
+
+Timeout to expire ports used with PortManager. Default is 30000 msec
+
+
+
+
+Switch to enable tracking of currently used ports on this machine. Default is false
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+
+
+Max time barrier can be closed. Default is 60000 msec
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+Interval in which a HEARTBEAT is sent to the cluster. Default is 3000 msec
+
+
+
+
+Timeout after which a node P is suspected if neither a heartbeat nor data were received from P. Default is 5000 msec
+
+
+
+
+Treat messages received from members as heartbeats. Note that this means we're updating a value in a hashmap every time a message is passing up the stack through FD_ALL, which is costly. Default is false
+
+
+
+
+Shun switch. Default is true
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+Rate of continious refresh registering of underlying gossip client with gossip server. Default is 20000 msec
+
+
+
+
+Max time for socket creation. Default is 1000 msec
+
+
+
+
+Max time in milliseconds to block on a read. 0 blocks forever
+
+
+
+
+Timeout to wait for the initial members. Default is 3000 msec
+
+
+
+
+Minimum number of initial members to get a response from. Default is 2
+
+
+
+
+Minimum number of server responses (PingData.isServer()=true). If this value is greater than 0, we'll ignore num_initial_members
+
+
+
+
+Return from the discovery phase as soon as we have 1 coordinator response
+
+
+
+
+Number of discovery requests to be sent distributed over timeout. Default is 2
+
+
+
+
+Whether or not to return the entire logical-physical address cache mappings on a discovery request, or not. Default is false, except for TCPPING
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+
+Whether to loop back messages sent to self. Default is false
+
+
+
+
+Max number of milliseconds we try to retransmit a message to any given member. After that, the connection is removed. Any new connection to that member will start with seqno #1 again. 0 disables this
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+
+The max number of bytes in a message. Larger messages will be fragmented. Default is 8192 bytes
+
+
+
+
+The max size in bytes for the byte array output buffer
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+Should unicast messages to suspected members be dropped. Default is false
+
+
+
+
+If cannot send a message to P (on an exception), should SUSPECT message be raised. Default is false
+
+
+
+
+Reaper interval in msec. Default is 0 (no reaping)
+
+
+
+
+Max time connection can be idle before being reaped
+
+
+
+
+Should separate send queues be used for each connection. Default is true
+
+
+
+
+Max number of messages in a send queue. Default is 10000 messages
+
+
+
+
+Receiver buffer size in bytes. Default is 150000 bytes
+
+
+
+
+Send buffer size in bytes. Default is 150000 bytes
+
+
+
+
+Max time allowed for a socket creation in ConnectionTable. Default is 2000 msec
+
+
+
+
+Max time to block on reading of peer address. Default is 1000 msec
+
+
+
+
+Should TCP no delay flag be turned on. Default is false
+
+
+
+
+SO_LINGER in msec. Default of -1 disables it
+
+
+
+
+The interface (NIC) which should be used by this transport
+
+
+
+
+Ignores all bind address parameters and let's the OS return the local host address. Default is false
+
+
+
+
+ If true, the transport should use all available interfaces to receive multicast messages. Default is false
+
+
+
+
+Comma delimited list of interfaces (IP addresses or interface names) to receive multicasts on
+
+
+
+
+The port to which the transport binds. Default of 0 binds to any (ephemeral) port
+
+
+
+
+
+
+
+
+
+tries to make sure ephemeral ports are used
+
+
+
+
+Messages to self are looped back immediately if true. Default is false
+
+
+
+
+Discard packets with a different version if true. Default is false
+
+
+
+
+Thread naming pattern for threads in this channel. Default is cl
+
+
+
+
+Switch for enabling thread pool for OOB messages. Default true
+
+
+
+
+Minimum thread pool size for OOB messages. Default is 2
+
+
+
+
+Maximum thread pool size for OOB messages. Default is 10
+
+
+
+
+Timeout in milliseconds to remove idle thread from OOB pool. Default is 30000
+
+
+
+
+Use queue to enqueue incoming OOB messages. Default is true
+
+
+
+
+Maximum queue size for incoming OOB messages. Default is 500
+
+
+
+
+Thread rejection policy. Possible values are Abort, Discard, DiscardOldest and Run. Default is Run
+
+
+
+
+Minimum thread pool size for regular messages. Default is 2
+
+
+
+
+Maximum thread pool size for regular messages. Default is 10
+
+
+
+
+Timeout in milliseconds to remove idle thread from regular pool. Default is 30000
+
+
+
+
+Switch for enabling thread pool for regular messages. Default true
+
+
+
+
+Use queue to enqueue incoming regular messages. Default is true
+
+
+
+
+Maximum queue size for incoming OOB messages. Default is 500
+
+
+
+
+Thread rejection policy. Possible values are Abort, Discard, DiscardOldest and Run Default is Run
+
+
+
+
+Number of threads to be used by the timer thread pool. Default is 4
+
+
+
+
+Enable bundling of smaller messages into bigger ones. Default is true
+
+
+
+
+Enable bundling of smaller messages into bigger ones for unicast messages. Default is false
+
+
+
+
+Switch to enable diagnostic probing. Default is true
+
+
+
+
+Address for diagnostic probing. Default is 224.0.75.75
+
+
+
+
+Port for diagnostic probing. Default is 7500
+
+
+
+
+If assigned enable this transport to be a singleton (shared) transport
+
+
+
+
+Path to a file to store currently used ports on this machine
+
+
+
+
+Timeout to expire ports used with PortManager. Default is 30000 msec
+
+
+
+
+Switch to enable tracking of currently used ports on this machine. Default is false
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+Use "external_addr" if you have hosts on different networks, behind firewalls. On each firewall, set up a port forwarding rule (sometimes called "virtual server") to the local IP (e.g. 192.168.1.100) of the host then on each host, set "external_addr" TCP transport parameter to the external (public IP) address of the firewall.
+
+
+
+
+
+
+
+
+
+
+Number of millisecs to wait for a response from a suspected member
+
+
+
+
+Number of verify heartbeats sent to a suspected member
+
+
+
+
+Use InetAddress.isReachable() to verify suspected member instead of regular messages
+
+
+
+
+Interface for ICMP pings. Used if use_icmp is true
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+Gossip host
+
+
+
+
+Gossip port
+
+
+
+
+Time in msecs after which the entry in GossipRouter will be refreshed. Default is 20000 msec
+
+
+
+
+Number of ports to be probed for initial membership. Default is 1
+
+
+
+
+If socket is used for discovery, time in msecs to wait until socket is connected. Default is 1000 msec
+
+
+
+
+Max to block on the socket on a read (in ms). 0 means block forever
+
+
+
+
+Time (in ms) to wait for our own discovery message to be received. 0 means don't wait. If the discovery message is not received within discovery_timeout ms, a warning will be logged
+
+
+
+
+Timeout to wait for the initial members. Default is 3000 msec
+
+
+
+
+Minimum number of initial members to get a response from. Default is 2
+
+
+
+
+Minimum number of server responses (PingData.isServer()=true). If this value is greater than 0, we'll ignore num_initial_members
+
+
+
+
+Return from the discovery phase as soon as we have 1 coordinator response
+
+
+
+
+Number of discovery requests to be sent distributed over timeout. Default is 2
+
+
+
+
+Whether or not to return the entire logical-physical address cache mappings on a discovery request, or not. Default is false, except for TCPPING
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+
+
+
+
+Router host address
+
+
+
+
+Router port
+
+
+
+
+Interval in msec to attempt connecting back to router in case of torn connection. Default is 5000 msec
+
+
+
+
+The interface (NIC) which should be used by this transport
+
+
+
+
+Ignores all bind address parameters and let's the OS return the local host address. Default is false
+
+
+
+
+ If true, the transport should use all available interfaces to receive multicast messages. Default is false
+
+
+
+
+Comma delimited list of interfaces (IP addresses or interface names) to receive multicasts on
+
+
+
+
+The port to which the transport binds. Default of 0 binds to any (ephemeral) port
+
+
+
+
+
+
+
+
+
+tries to make sure ephemeral ports are used
+
+
+
+
+Messages to self are looped back immediately if true. Default is false
+
+
+
+
+Discard packets with a different version if true. Default is false
+
+
+
+
+Thread naming pattern for threads in this channel. Default is cl
+
+
+
+
+Switch for enabling thread pool for OOB messages. Default true
+
+
+
+
+Minimum thread pool size for OOB messages. Default is 2
+
+
+
+
+Maximum thread pool size for OOB messages. Default is 10
+
+
+
+
+Timeout in milliseconds to remove idle thread from OOB pool. Default is 30000
+
+
+
+
+Use queue to enqueue incoming OOB messages. Default is true
+
+
+
+
+Maximum queue size for incoming OOB messages. Default is 500
+
+
+
+
+Thread rejection policy. Possible values are Abort, Discard, DiscardOldest and Run. Default is Run
+
+
+
+
+Minimum thread pool size for regular messages. Default is 2
+
+
+
+
+Maximum thread pool size for regular messages. Default is 10
+
+
+
+
+Timeout in milliseconds to remove idle thread from regular pool. Default is 30000
+
+
+
+
+Switch for enabling thread pool for regular messages. Default true
+
+
+
+
+Use queue to enqueue incoming regular messages. Default is true
+
+
+
+
+Maximum queue size for incoming OOB messages. Default is 500
+
+
+
+
+Thread rejection policy. Possible values are Abort, Discard, DiscardOldest and Run Default is Run
+
+
+
+
+Number of threads to be used by the timer thread pool. Default is 4
+
+
+
+
+Enable bundling of smaller messages into bigger ones. Default is true
+
+
+
+
+Enable bundling of smaller messages into bigger ones for unicast messages. Default is false
+
+
+
+
+Switch to enable diagnostic probing. Default is true
+
+
+
+
+Address for diagnostic probing. Default is 224.0.75.75
+
+
+
+
+Port for diagnostic probing. Default is 7500
+
+
+
+
+If assigned enable this transport to be a singleton (shared) transport
+
+
+
+
+Path to a file to store currently used ports on this machine
+
+
+
+
+Timeout to expire ports used with PortManager. Default is 30000 msec
+
+
+
+
+Switch to enable tracking of currently used ports on this machine. Default is false
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+
+
+
+The interface (NIC) which should be used by this transport
+
+
+
+
+Ignores all bind address parameters and let's the OS return the local host address. Default is false
+
+
+
+
+ If true, the transport should use all available interfaces to receive multicast messages. Default is false
+
+
+
+
+Comma delimited list of interfaces (IP addresses or interface names) to receive multicasts on
+
+
+
+
+The port to which the transport binds. Default of 0 binds to any (ephemeral) port
+
+
+
+
+
+
+
+
+
+tries to make sure ephemeral ports are used
+
+
+
+
+Messages to self are looped back immediately if true. Default is false
+
+
+
+
+Discard packets with a different version if true. Default is false
+
+
+
+
+Thread naming pattern for threads in this channel. Default is cl
+
+
+
+
+Switch for enabling thread pool for OOB messages. Default true
+
+
+
+
+Minimum thread pool size for OOB messages. Default is 2
+
+
+
+
+Maximum thread pool size for OOB messages. Default is 10
+
+
+
+
+Timeout in milliseconds to remove idle thread from OOB pool. Default is 30000
+
+
+
+
+Use queue to enqueue incoming OOB messages. Default is true
+
+
+
+
+Maximum queue size for incoming OOB messages. Default is 500
+
+
+
+
+Thread rejection policy. Possible values are Abort, Discard, DiscardOldest and Run. Default is Run
+
+
+
+
+Minimum thread pool size for regular messages. Default is 2
+
+
+
+
+Maximum thread pool size for regular messages. Default is 10
+
+
+
+
+Timeout in milliseconds to remove idle thread from regular pool. Default is 30000
+
+
+
+
+Switch for enabling thread pool for regular messages. Default true
+
+
+
+
+Use queue to enqueue incoming regular messages. Default is true
+
+
+
+
+Maximum queue size for incoming OOB messages. Default is 500
+
+
+
+
+Thread rejection policy. Possible values are Abort, Discard, DiscardOldest and Run Default is Run
+
+
+
+
+Number of threads to be used by the timer thread pool. Default is 4
+
+
+
+
+Enable bundling of smaller messages into bigger ones. Default is true
+
+
+
+
+Enable bundling of smaller messages into bigger ones for unicast messages. Default is false
+
+
+
+
+Switch to enable diagnostic probing. Default is true
+
+
+
+
+Address for diagnostic probing. Default is 224.0.75.75
+
+
+
+
+Port for diagnostic probing. Default is 7500
+
+
+
+
+If assigned enable this transport to be a singleton (shared) transport
+
+
+
+
+Path to a file to store currently used ports on this machine
+
+
+
+
+Timeout to expire ports used with PortManager. Default is 30000 msec
+
+
+
+
+Switch to enable tracking of currently used ports on this machine. Default is false
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+
+
+Max number of bytes to send per receiver until an ack must be received to proceed. Default is 2000000 bytes
+
+
+
+
+Max time (in milliseconds) to block. Default is 5000 msec
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+Max number of bytes to send per receiver until an ack must be received to proceed. Default is 500000 bytes
+
+
+
+
+Max time (in milliseconds) to block. Default is 5000 msec
+
+
+
+
+If credits fall below this limit, we send more credits to the sender. Default is 0.25
+
+
+
+
+Computed as max_credits x min_theshold unless explicitely set
+
+
+
+
+Does not block a down message if it is a result of handling an up message in thesame thread. Fixes JGRP-928
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+Max times to block for the listed messages sizes (Message.getLength())
+
+
+
+
+
+
+
+
+Cryptographic Service Provider. Default is Bouncy Castle Provider
+
+
+
+
+Cipher engine transformation for asymmetric algorithm. Default is RSA
+
+
+
+
+Cipher engine transformation for symmetric algorithm. Default is AES
+
+
+
+
+Initial public/private key length. Default is 512
+
+
+
+
+Initial key length for matching symmetric algorithm. Default is 128
+
+
+
+
+File on classpath that contains keystore repository
+
+
+
+
+Password used to check the integrity/unlock the keystore. Change the default
+
+
+
+
+Password for recovering the key. Change the default
+
+
+
+
+Alias used for recovering the key. Change the default
+
+
+
+
+
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+Lower bound in msec to run merge protocol. Default is 5000 msec
+
+
+
+
+Upper bound in msec to run merge protocol. Default is 20000 msec
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+Traffic class for sending unicast and multicast datagrams. Default is 8
+
+
+
+
+The multicast address used for sending and receiving packets. Default is 228.8.8.8
+
+
+
+
+The multicast port used for sending and receiving packets. Default is 7600
+
+
+
+
+Multicast toggle. If false multiple unicast datagrams are sent instead of one multicast. Default is true
+
+
+
+
+The time-to-live (TTL) for multicast datagram packets. Default is 8
+
+
+
+
+Send buffer size of the multicast datagram socket. Default is 100'000 bytes
+
+
+
+
+Receive buffer size of the multicast datagram socket. Default is 500'000 bytes
+
+
+
+
+Send buffer size of the unicast datagram socket. Default is 100'000 bytes
+
+
+
+
+Receive buffer size of the unicast datagram socket. Default is 64'000 bytes
+
+
+
+
+The interface (NIC) which should be used by this transport
+
+
+
+
+Ignores all bind address parameters and let's the OS return the local host address. Default is false
+
+
+
+
+ If true, the transport should use all available interfaces to receive multicast messages. Default is false
+
+
+
+
+Comma delimited list of interfaces (IP addresses or interface names) to receive multicasts on
+
+
+
+
+The port to which the transport binds. Default of 0 binds to any (ephemeral) port
+
+
+
+
+
+
+
+
+
+tries to make sure ephemeral ports are used
+
+
+
+
+Messages to self are looped back immediately if true. Default is false
+
+
+
+
+Discard packets with a different version if true. Default is false
+
+
+
+
+Thread naming pattern for threads in this channel. Default is cl
+
+
+
+
+Switch for enabling thread pool for OOB messages. Default true
+
+
+
+
+Minimum thread pool size for OOB messages. Default is 2
+
+
+
+
+Maximum thread pool size for OOB messages. Default is 10
+
+
+
+
+Timeout in milliseconds to remove idle thread from OOB pool. Default is 30000
+
+
+
+
+Use queue to enqueue incoming OOB messages. Default is true
+
+
+
+
+Maximum queue size for incoming OOB messages. Default is 500
+
+
+
+
+Thread rejection policy. Possible values are Abort, Discard, DiscardOldest and Run. Default is Run
+
+
+
+
+Minimum thread pool size for regular messages. Default is 2
+
+
+
+
+Maximum thread pool size for regular messages. Default is 10
+
+
+
+
+Timeout in milliseconds to remove idle thread from regular pool. Default is 30000
+
+
+
+
+Switch for enabling thread pool for regular messages. Default true
+
+
+
+
+Use queue to enqueue incoming regular messages. Default is true
+
+
+
+
+Maximum queue size for incoming OOB messages. Default is 500
+
+
+
+
+Thread rejection policy. Possible values are Abort, Discard, DiscardOldest and Run Default is Run
+
+
+
+
+Number of threads to be used by the timer thread pool. Default is 4
+
+
+
+
+Enable bundling of smaller messages into bigger ones. Default is true
+
+
+
+
+Enable bundling of smaller messages into bigger ones for unicast messages. Default is false
+
+
+
+
+Switch to enable diagnostic probing. Default is true
+
+
+
+
+Address for diagnostic probing. Default is 224.0.75.75
+
+
+
+
+Port for diagnostic probing. Default is 7500
+
+
+
+
+If assigned enable this transport to be a singleton (shared) transport
+
+
+
+
+Path to a file to store currently used ports on this machine
+
+
+
+
+Timeout to expire ports used with PortManager. Default is 30000 msec
+
+
+
+
+Switch to enable tracking of currently used ports on this machine. Default is false
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+
+
+Timeout to suspect a node P if neither a heartbeat nor data were received from P. Default is 3000 msec
+
+
+
+
+Shun switch. Default is true
+
+
+
+
+Number of times to send heartbeat. Default is 2
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+Bind address for multicast socket
+
+
+
+
+Time to live for discovery packets. Default is 8
+
+
+
+
+Multicast port for discovery packets. Default is 7555
+
+
+
+
+If true, the transport should use all available interfaces to receive multicast messages. Default is false
+
+
+
+
+List of interfaces to receive multicasts on
+
+
+
+
+Whether send messages are sent on all interfaces. Default is false
+
+
+
+
+List of interfaces to send multicasts on
+
+
+
+
+Gossip host
+
+
+
+
+Gossip port
+
+
+
+
+Time in msecs after which the entry in GossipRouter will be refreshed. Default is 20000 msec
+
+
+
+
+Number of ports to be probed for initial membership. Default is 1
+
+
+
+
+If socket is used for discovery, time in msecs to wait until socket is connected. Default is 1000 msec
+
+
+
+
+Max to block on the socket on a read (in ms). 0 means block forever
+
+
+
+
+Time (in ms) to wait for our own discovery message to be received. 0 means don't wait. If the discovery message is not received within discovery_timeout ms, a warning will be logged
+
+
+
+
+Timeout to wait for the initial members. Default is 3000 msec
+
+
+
+
+Minimum number of initial members to get a response from. Default is 2
+
+
+
+
+Minimum number of server responses (PingData.isServer()=true). If this value is greater than 0, we'll ignore num_initial_members
+
+
+
+
+Return from the discovery phase as soon as we have 1 coordinator response
+
+
+
+
+Number of discovery requests to be sent distributed over timeout. Default is 2
+
+
+
+
+Whether or not to return the entire logical-physical address cache mappings on a discovery request, or not. Default is false, except for TCPPING
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+Compression level 0-9 (0=no compression, 9=best compression). Default is 9
+
+
+
+
+Minimal payload size of a message (in bytes) for compression to kick in. Default is 500 bytes
+
+
+
+
+Number of inflaters/deflaters for concurrent processing. Default is 2
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+View synchronization interval. Default is 60 sec
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+The max number of bytes in a message. Larger messages will be fragmented. Default is 1500 bytes
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+Join timeout. Default is 5000 msec
+
+
+
+
+Leave timeout. Default is 5000 msec
+
+
+
+
+Timeout to complete merge. Default is 10000 msec
+
+
+
+
+Shunning toggle. Default is false
+
+
+
+
+If true this member is a designated merge leader. Default is false
+
+
+
+
+Print local address of this member after connect. Default is true
+
+
+
+
+If true this member can never become coordinator. Default is false
+
+
+
+
+Temporary switch. Default is true and should not be changed
+
+
+
+
+Should views be bundled? Default is true
+
+
+
+
+Max view bundling timeout if view bundling is turned on. Default is 50 msec
+
+
+
+
+Max number of old members to keep in history. Default is 50
+
+
+
+
+Time in ms to wait for all VIEW acks (0 == wait forever. Default is 2000 msec
+
+
+
+
+Timeout to resume ViewHandler. Default is 20000 msec
+
+
+
+
+Use flush for view changes. Default is true
+
+
+
+
+
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+The interface (NIC) used to accept state requests
+
+
+
+
+The port listening for state requests. Default value of 0 binds to any (ephemeral) port
+
+
+
+
+Maximum number of pool threads serving state requests. Default is 5
+
+
+
+
+Keep alive for pool threads serving state requests. Default is 20000 msec
+
+
+
+
+Buffer size for state transfer. Default is 8192 bytes
+
+
+
+
+If default transport is used the total state buffer size before state producer is blocked. Default is 81920 bytes
+
+
+
+
+If true default transport is used for state transfer rather than seperate TCP sockets. Default is false
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+Timeout before requesting retransmissions. Default is 600, 1200, 2400, 4800
+
+
+
+
+If true, retransmissions stats will be captured. Default is false
+
+
+
+
+Garbage collection lag. Default is 20 msec
+
+
+
+
+Retransmit messages using multicast rather than unicast. Default is true
+
+
+
+
+Use a multicast to request retransmission of missing messages. Default is false
+
+
+
+
+Ask a random member for retransmission of a missing message. Default is false
+
+
+
+
+The first value (in milliseconds) to use in the exponential backoff. Enabled if greater than 0. Default is 0
+
+
+
+
+Use statistics gathered from actual retransmission times to compute new retransmission times. Default is false
+
+
+
+
+Should messages delivered to application be discarded. Default is false
+
+
+
+
+See http://jira.jboss.com/jira/browse/JGRP-656. Default is true
+
+
+
+
+If value is > 0, the retransmit buffer is bounded. If value <= 0 unbounded buffers are used. Default is 0
+
+
+
+
+Size of retransmission history. Default is 50 entries
+
+
+
+
+Timeout to rebroadcast messages. Default is 2000 msec
+
+
+
+
+Should stability history be printed if we fail in retransmission. Default is false
+
+
+
+
+Size of send and receive history. Default is 20 entries
+
+
+
+
+discards warnings about promiscuous traffic
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+Max time to keep channel blocked in flush. Default is 8000 msec
+
+
+
+
+Timeout (per atttempt) to quiet the cluster during the first flush phase. Default is 2500 msec
+
+
+
+
+Retry timeout after an unsuccessful attempt to quiet the cluster (first flush phase). Default is 3000 msec
+
+
+
+
+Reconcilliation phase toggle. Default is true
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
+Average time to send a STABLE message. Default is 20000 msec
+
+
+
+
+Delay before stability message is sent. Default is 6000 msec
+
+
+
+
+Maximum number of bytes received in all messages before sending a STABLE message is triggered. Default is 0 (disabled)
+
+
+
+
+Determines whether to collect statistics (and expose them via JMX). Default is true
+
+
+
+
+
+
+
+
diff --git a/config/alfresco/jgroups/alfresco-jgroups-TCP.xml b/config/alfresco/jgroups/alfresco-jgroups-TCP.xml
new file mode 100644
index 0000000000..a74ec1f82a
--- /dev/null
+++ b/config/alfresco/jgroups/alfresco-jgroups-TCP.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/jgroups/alfresco-jgroups-UDP.xml b/config/alfresco/jgroups/alfresco-jgroups-UDP.xml
new file mode 100644
index 0000000000..37b76982ff
--- /dev/null
+++ b/config/alfresco/jgroups/alfresco-jgroups-UDP.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/alfresco/repository.properties b/config/alfresco/repository.properties
index cad431893d..ae3e2c2a00 100644
--- a/config/alfresco/repository.properties
+++ b/config/alfresco/repository.properties
@@ -66,14 +66,14 @@ system.bootstrap.config_check.strict=true
# Leave this empty to disable cluster entry
alfresco.cluster.name=
+# The protocol stack to use from the JGroups configuration file
+# Use this property to select which communication method should be used.
+# The JGroups configuration file is build up using the protocol string
+alfresco.jgroups.defaultProtocol=UDP
# JGroups configuration (http://www.jgroups.org)
# The location of the JGroups configuration file
-# It is also possible to override this by just dropping a file in classpath:alfresco/extension/jgroups-custom.xml
-alfresco.jgroups.configLocation=classpath:alfresco/jgroups-default.xml
-# The protocol stack to use from the JGroups configuration file
-# The JGroups configuration files are divided into protocol stacks.
-# Use this property to select which communication method should be used.
-alfresco.jgroups.defaultProtocol=UDP
+alfresco.jgroups.configLocation=classpath:alfresco/jgroups/alfresco-jgroups-${alfresco.jgroups.defaultProtocol}.xml
+#alfresco.jgroups.configLocation=alfresco/jgroups/alfresco-jgroups-${alfresco.jgroups.defaultProtocol}.xml
#
# How long should shutdown wait to complete normally before
diff --git a/source/java/org/alfresco/repo/jgroups/AlfrescoJGroupsChannelFactory.java b/source/java/org/alfresco/repo/jgroups/AlfrescoJGroupsChannelFactory.java
index 2a10d7bc4a..ca4851ac10 100644
--- a/source/java/org/alfresco/repo/jgroups/AlfrescoJGroupsChannelFactory.java
+++ b/source/java/org/alfresco/repo/jgroups/AlfrescoJGroupsChannelFactory.java
@@ -24,7 +24,6 @@
*/
package org.alfresco.repo.jgroups;
-import java.io.FileNotFoundException;
import java.io.Serializable;
import java.net.URL;
import java.util.HashMap;
@@ -50,12 +49,13 @@ import org.jgroups.ChannelListener;
import org.jgroups.ChannelNotConnectedException;
import org.jgroups.Event;
import org.jgroups.JChannel;
-import org.jgroups.JChannelFactory;
import org.jgroups.Message;
import org.jgroups.Receiver;
import org.jgroups.TimeoutException;
import org.jgroups.UpHandler;
import org.jgroups.View;
+import org.jgroups.protocols.LOOPBACK;
+import org.jgroups.stack.ProtocolStack;
import org.springframework.context.ApplicationEvent;
import org.springframework.util.ResourceUtils;
@@ -63,23 +63,12 @@ import org.springframework.util.ResourceUtils;
* A cache peer provider that does heartbeat sending and receiving using JGroups.
*
* The cluster name needs to be set before any communication is possible. This can be done using the
- * system property
- * {@link #PROP_CLUSTER_NAME_PREFIX -Dalfresco.cluster-name-prefix}=MyCluster
- * or by declaring a bean
- *
- *
- *
- * MyCluster
- *
- *
- *
+ * property {@link #setClusterName(String)}.
*
* The channels provided to the callers will be proxies to underlying channels that will be hot-swappable.
* This means that the client code can continue to use the channel references while the actual
* implementation can be switched in and out as required.
*
- * @see #PROP_CLUSTER_NAME_PREFIX
- *
* @author Derek Hulley
* @since 2.1.3
*/
@@ -89,15 +78,10 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
public static final String APP_REGION_DEFAULT = "DEFAULT";
/** The application region used by the EHCache heartbeat implementation over JGroups. */
public static final String APP_REGION_EHCACHE_HEARTBEAT = "EHCACHE_HEARTBEAT";
- /** The UDP protocol stack (default) */
- public static final String PROTOCOL_STACK_UDP = "UDP";
- /** The TCP protocol stack */
- public static final String PROTOCOL_STACK_TCP = "TCP";
-
-
- public static final String PROP_CLUSTER_NAME_PREFIX = "alfresco.cluster-name-prefix";
- public static final String CUSTOM_CONFIGURATION_FILE = "classpath:alfresco/extension/jgroups-custom.xml";
- public static final String DEFAULT_CONFIGURATION_FILE = "classpath:alfresco/jgroups-default.xml";
+ /** The UDP protocol config (default) */
+ public static final String DEFAULT_CONFIG_UDP = "classpath:alfresco/jgroups/alfresco-jgroups-UDP.xml";
+ /** The TCP protocol config */
+ public static final String DEFAULT_CONFIG_TCP = "classpath:alfresco/jgroups/alfresco-jgroups-TCP.xml";
private static Log logger = LogFactory.getLog(AlfrescoJGroupsChannelFactory.class);
@@ -107,13 +91,11 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
// Values that are modified by the bean implementation
private static String clusterNamePrefix;
- private static URL configUrl;
- private static Map stacksByAppRegion;
+ private static Map configUrlsByAppRegion;
// Derived data
/** A map that stores channel information by the application region. */
- private static final Map channels;
- private static JChannelFactory channelFactory;
+ private static final Map channelsByAppRegion;
static
{
@@ -121,17 +103,13 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
readLock = readWriteLock.readLock();
writeLock = readWriteLock.writeLock();
- channels = new HashMap(5);
+ channelsByAppRegion = new HashMap(5);
clusterNamePrefix = null;
- configUrl = null;
- stacksByAppRegion = new HashMap(5);
- stacksByAppRegion.put(
- AlfrescoJGroupsChannelFactory.APP_REGION_EHCACHE_HEARTBEAT,
- AlfrescoJGroupsChannelFactory.PROTOCOL_STACK_UDP);
- stacksByAppRegion.put(
+ configUrlsByAppRegion = new HashMap(5);
+ configUrlsByAppRegion.put(
AlfrescoJGroupsChannelFactory.APP_REGION_DEFAULT,
- AlfrescoJGroupsChannelFactory.PROTOCOL_STACK_UDP);
+ AlfrescoJGroupsChannelFactory.DEFAULT_CONFIG_UDP);
}
/**
@@ -158,7 +136,7 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
*/
private static void closeChannels()
{
- for (Map.Entry entry : channels.entrySet())
+ for (Map.Entry entry : channelsByAppRegion.entrySet())
{
ChannelProxy channelProxy = entry.getValue();
@@ -166,7 +144,6 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
try
{
channelProxy.close();
- channelProxy.shutdown();
if (logger.isDebugEnabled())
{
logger.debug("\n" +
@@ -183,12 +160,44 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
}
}
+ /**
+ * Returns the configuration URL to use for the given application region. This might default to the
+ * {@link #APP_REGION_DEFAULT default app region}.
+ */
+ private static String getConfigUrl(String appRegion)
+ {
+ readLock.lock();
+ try
+ {
+ // Get the configuration to use
+ String configUrlStr = configUrlsByAppRegion.get(appRegion);
+ if (!PropertyCheck.isValidPropertyString(configUrlStr))
+ {
+ configUrlStr = configUrlsByAppRegion.get(AlfrescoJGroupsChannelFactory.APP_REGION_DEFAULT);
+ }
+ if (configUrlStr == null)
+ {
+ throw new AlfrescoRuntimeException(
+ "No protocol configuration was found for application region: \n" +
+ " Cluster prefix: " + clusterNamePrefix + "\n" +
+ " App region: " + appRegion + "\n" +
+ " Regions defined: " + configUrlsByAppRegion);
+ }
+ return configUrlStr;
+ }
+ finally
+ {
+ readLock.unlock();
+ }
+ }
+
+ /**
/**
* Creates a channel for the cluster. This method should not be heavily used
- * as the checks and synchronizations will slow the calls. Returns channels can be
+ * as the checks and synchronizations will slow the calls. Returned channels can be
* kept and will be modified directly using the factory-held references, if necessary.
*
- * The application region is used to determine the protocol stack to apply.
+ * The application region is used to determine the protocol configuration to apply.
*
* This method returns a dummy channel if no cluster name has been provided.
*
@@ -200,7 +209,7 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
readLock.lock();
try
{
- ChannelProxy channelProxy = channels.get(appRegion);
+ ChannelProxy channelProxy = channelsByAppRegion.get(appRegion);
if (channelProxy != null)
{
// This will do
@@ -216,8 +225,7 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
writeLock.lock();
try
{
- // Double check
- ChannelProxy channelProxy = channels.get(appRegion);
+ ChannelProxy channelProxy = channelsByAppRegion.get(appRegion);
if (channelProxy != null)
{
// This will do
@@ -228,7 +236,7 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
// Proxy the channel
channelProxy = new ChannelProxy(channel);
// Store the channel to the map
- channels.put(appRegion, channelProxy);
+ channelsByAppRegion.put(appRegion, channelProxy);
// Done
return channelProxy;
}
@@ -240,7 +248,7 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
/**
* Creates a channel for the given cluster. The application region is used
- * to determine the protocol stack to apply.
+ * to determine the protocol configuration to apply.
*
* @param appRegion the application region identifier.
* @return Returns a channel
@@ -249,6 +257,7 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
private static /*synchronized*/ Channel getChannelInternal(String appRegion)
{
Channel channel;
+ URL configUrl = null;
// If there is no cluster defined (yet) then we define a dummy channel
if (AlfrescoJGroupsChannelFactory.clusterNamePrefix == null)
{
@@ -267,26 +276,13 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
}
else // Create real channel
{
- JChannelFactory channelFactory = getChannelFactory();
- // Get the protocol stack to use
- String stack = stacksByAppRegion.get(appRegion);
- if (!PropertyCheck.isValidPropertyString(stack))
- {
- stack = stacksByAppRegion.get(AlfrescoJGroupsChannelFactory.APP_REGION_DEFAULT);
- }
- if (stack == null)
- {
- throw new AlfrescoRuntimeException(
- "No protocol stack was found for application region: \n" +
- " Cluster prefix: " + clusterNamePrefix + "\n" +
- " App region: " + appRegion + "\n" +
- " Regions defined: " + stacksByAppRegion);
- }
+ // Get the protocol configuration to use
+ String configUrlStr = getConfigUrl(appRegion);
try
{
- // Get the stack config from the factory (we are not using MUX)
- String config = channelFactory.getConfig(stack);
- channel = new JChannel(config);
+ // Construct the JChannel directly
+ configUrl = ResourceUtils.getURL(configUrlStr);
+ channel = new JChannel(configUrl);
}
catch (Throwable e)
{
@@ -294,8 +290,8 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
"Failed to create JGroups channel: \n" +
" Cluster prefix: " + clusterNamePrefix + "\n" +
" App region: " + appRegion + "\n" +
- " Protocol stack: " + stack + "\n" +
- " Configuration URL: " + AlfrescoJGroupsChannelFactory.configUrl,
+ " Regions defined: " + configUrlsByAppRegion + "\n" +
+ " Configuration URL: " + configUrlStr,
e);
}
}
@@ -303,14 +299,10 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
try
{
String clusterName = clusterNamePrefix + ":" + appRegion;
- // Set reconnect property
- channel.setOpt(Channel.AUTO_RECONNECT, Boolean.TRUE);
// Don't accept messages from self
channel.setOpt(Channel.LOCAL, Boolean.FALSE);
- // No state transfer
- channel.setOpt(Channel.AUTO_GETSTATE, Boolean.FALSE);
// Connect
- channel.connect(clusterName, null, null, 5000L);
+ channel.connect(clusterName);
// Done
if (logger.isDebugEnabled())
{
@@ -318,8 +310,9 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
"Created JGroups channel: \n" +
" Cluster prefix: " + clusterNamePrefix + "\n" +
" App region: " + appRegion + "\n" +
+ " Regions defined: " + configUrlsByAppRegion + "\n" +
" Channel: " + channel + "\n" +
- " Configuration URL: " + AlfrescoJGroupsChannelFactory.configUrl);
+ " Configuration URL: " + configUrl);
}
}
catch (Throwable e)
@@ -329,65 +322,26 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
" Cluster prefix: " + clusterNamePrefix + "\n" +
" App region: " + appRegion + "\n" +
" Channel: " + channel + "\n" +
- " Configuration URL: " + AlfrescoJGroupsChannelFactory.configUrl,
+ " Configuration URL: " + configUrl,
e);
}
return channel;
}
/**
- * Builds and initializes a JChannelFactory
+ * Rebuild all the channels using the current cluster name and configuration mappings.
*/
- /* All calls to this are ultimately wrapped in the writeLock. */
- private static /*synchronized*/ JChannelFactory getChannelFactory()
+ public static void rebuildChannels()
{
- if (AlfrescoJGroupsChannelFactory.channelFactory != null)
- {
- return AlfrescoJGroupsChannelFactory.channelFactory;
- }
- // Set the config location to use
- if (AlfrescoJGroupsChannelFactory.configUrl == null)
- {
- // This was not set by the bean so set it using the default mechanism
- try
- {
- AlfrescoJGroupsChannelFactory.configUrl = ResourceUtils.getURL(CUSTOM_CONFIGURATION_FILE);
- }
- catch (FileNotFoundException e)
- {
- // try the alfresco default
- try
- {
- AlfrescoJGroupsChannelFactory.configUrl = ResourceUtils.getURL(DEFAULT_CONFIGURATION_FILE);
- }
- catch (FileNotFoundException ee)
- {
- throw new AlfrescoRuntimeException("Missing default JGroups config: " + DEFAULT_CONFIGURATION_FILE);
- }
- }
- }
+ writeLock.lock();
try
{
- // Construct factory
- AlfrescoJGroupsChannelFactory.channelFactory = new JChannelFactory();
- channelFactory.setMultiplexerConfig(AlfrescoJGroupsChannelFactory.configUrl);
+ rebuildChannelsInternal();
}
- catch (Throwable e)
+ finally
{
- throw new AlfrescoRuntimeException(
- "Failed to construct JChannelFactory using config: " + AlfrescoJGroupsChannelFactory.configUrl,
- e);
+ writeLock.unlock();
}
- // done
- if (logger.isInfoEnabled())
- {
- logger.info("\n" +
- "Created JChannelFactory: \n" +
- " Cluster Name: " + (AlfrescoJGroupsChannelFactory.clusterNamePrefix == null ? "" : AlfrescoJGroupsChannelFactory.clusterNamePrefix) + "\n" +
- " Stack Mapping: " + AlfrescoJGroupsChannelFactory.stacksByAppRegion + "\n" +
- " Configuration: " + AlfrescoJGroupsChannelFactory.configUrl);
- }
- return AlfrescoJGroupsChannelFactory.channelFactory;
}
/**
@@ -395,29 +349,25 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
* be reconstructed from scratch. All the channels are reconstructed - but this will not
* affect any references to channels held outside this class as the values returned are proxies
* on top of hot swappable implementations.
+ *
+ * The old channel is closed before the new one is created, so it is possible for a channel
+ * held by client code to be rendered unusable during the switch-over.
*/
/* All calls to this are ultimately wrapped in the writeLock. */
- private static /*synchronized*/ void rebuildChannels()
+ private static /*synchronized*/ void rebuildChannelsInternal()
{
- // First throw away the channel factory. It will be fetched lazily.
- AlfrescoJGroupsChannelFactory.channelFactory = null;
-
// Reprocess all the application regions with the new data
- for (Map.Entry entry : channels.entrySet())
+ for (Map.Entry entry : channelsByAppRegion.entrySet())
{
String appRegion = entry.getKey();
ChannelProxy channelProxy = entry.getValue();
- // Create the new channel
- Channel newChannel = getChannelInternal(appRegion);
-
- // Now do the hot-swap
- Channel oldChannel = channelProxy.swap(newChannel);
- // Close the old channel
+ // Get the old channel
+ Channel oldChannel = channelProxy.getDelegate();
+ // Close the old channel.
try
{
oldChannel.close();
- oldChannel.shutdown();
if (logger.isDebugEnabled())
{
logger.debug("\n" +
@@ -432,6 +382,12 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
" Old channel: " + oldChannel,
e);
}
+
+ // Create the new channel
+ Channel newChannel = getChannelInternal(appRegion);
+
+ // Now do the hot-swap
+ channelProxy.swap(newChannel);
}
}
@@ -442,6 +398,8 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
* clusterNamePrefix:appRegion
*
* If no cluster name prefix is declared, the cluster is effectively disabled.
+ *
+ * NOTE: The channels must be {@link #rebuildChannels() rebuilt}.
*
* @param clusterNamePrefix a prefix to append to the cluster names used
*/
@@ -467,22 +425,24 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
}
/**
- * Configure a mapping between the application regions and the available JGroup protocol stacks.
+ * Configure a mapping between the application regions and the available JGroup protocol configurations.
* The map must contain a mapping for application region 'DEFAULT'.
+ *
+ * NOTE: The channels must be {@link #rebuildChannels() rebuilt}.
*
- * @param protocolMap a mapping from application region (keys) to protocol stacks (values)
+ * @param configUrlsByAppRegion a mapping from application region (keys) to protocol configuration URLs (values)
*/
- public static void changeProtocolStackMapping(Map protocolMap)
+ private static void changeConfigUrlsMapping(Map configUrlsByAppRegion)
{
writeLock.lock();
try
{
// Check that there is a mapping for default
- if (!protocolMap.containsKey(AlfrescoJGroupsChannelFactory.APP_REGION_DEFAULT))
+ if (!configUrlsByAppRegion.containsKey(AlfrescoJGroupsChannelFactory.APP_REGION_DEFAULT))
{
- throw new AlfrescoRuntimeException("A protocol stack must be defined for 'DEFAULT'");
+ throw new AlfrescoRuntimeException("A configuration URL must be defined for 'DEFAULT'");
}
- stacksByAppRegion = protocolMap;
+ AlfrescoJGroupsChannelFactory.configUrlsByAppRegion = configUrlsByAppRegion;
}
finally
{
@@ -490,38 +450,6 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
}
}
- /**
- * Set the URL location of the JGroups configuration file. This must refer to a MUX-compatible
- * configuration file.
- *
- * @param configUrl a url of the form file:... or classpath:
- */
- public static void changeJgroupsConfigurationUrl(String configUrl)
- {
- writeLock.lock();
- if (!PropertyCheck.isValidPropertyString(configUrl))
- {
- // It's not really being set
- AlfrescoJGroupsChannelFactory.configUrl = null;
- return;
- }
- // It's a real attempt to set it
- try
- {
- AlfrescoJGroupsChannelFactory.configUrl = ResourceUtils.getURL(configUrl);
- }
- catch (FileNotFoundException e)
- {
- throw new AlfrescoRuntimeException(
- "Failed to set property 'jgroupsConfigurationUrl'. The url is invalid: " + configUrl,
- e);
- }
- finally
- {
- writeLock.unlock();
- }
- }
-
/**
* Bean-enabling constructor
*/
@@ -538,31 +466,31 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
}
/**
- * @see AlfrescoJGroupsChannelFactory#changeProtocolStackMapping(Map)
+ * @see AlfrescoJGroupsChannelFactory#changeConfigUrlsMapping(Map)
*/
- public void setProtocolStackMapping(Map protocolMap)
+ public void setConfigUrlsByAppRegion(Map configUrlsByAppRegion)
{
- AlfrescoJGroupsChannelFactory.changeProtocolStackMapping(protocolMap);
+ AlfrescoJGroupsChannelFactory.changeConfigUrlsMapping(configUrlsByAppRegion);
}
/**
- * Set the URL location of the JGroups configuration file. This must refer to a MUX-compatible
- * configuration file.
- *
- * @param configUrl a url of the form file:... or classpath:
+ * @deprecated Use {@link #setConfigUrlsByAppRegion(Map)}
+ */
+ public void setProtocolStackMapping(Map unused)
+ {
+ throw new AlfrescoRuntimeException(
+ "Properties 'protocolStackMapping' and 'jgroupsConfigurationUrl'" +
+ " have been deprecated in favour of 'configUrlsByAppRegion'.");
+ }
+
+ /**
+ * @deprecated Use {@link #setConfigUrlsByAppRegion(Map)}
*/
public void setJgroupsConfigurationUrl(String configUrl)
{
- try
- {
- AlfrescoJGroupsChannelFactory.configUrl = ResourceUtils.getURL(configUrl);
- }
- catch (FileNotFoundException e)
- {
- throw new AlfrescoRuntimeException(
- "Failed to set property 'jgroupsConfigurationUrl'. The url is invalid: " + configUrl,
- e);
- }
+ throw new AlfrescoRuntimeException(
+ "Properties 'protocolStackMapping' and 'jgroupsConfigurationUrl'" +
+ " have been deprecated in favour of 'configUrlsByAppRegion'.");
}
@Override
@@ -587,7 +515,28 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
{
public DummyJChannel() throws ChannelException
{
- super("DUMMY_TP:UDP(mcast_addr=224.10.10.200;mcast_port=5679)");
+ super("org.alfresco.repo.jgroups.AlfrescoJGroupsChannelFactory$DummyProtocol");
+ }
+ }
+
+ public static class DummyProtocol extends LOOPBACK
+ {
+ @Override
+ public String getName()
+ {
+ return "ALF_DUMMY";
+ }
+
+ @Override
+ public Object down(Event evt)
+ {
+ return null;
+ }
+
+ @Override
+ public Object up(Event evt)
+ {
+ return null;
}
}
@@ -609,13 +558,24 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
private UpHandler delegateUpHandler;
private Set delegateChannelListeners;
private Receiver delegateReceiver;
-
+
+ /**
+ * @param delegate the real channel that will do the work
+ */
public ChannelProxy(Channel delegate)
{
this.delegate = delegate;
this.delegateChannelListeners = new HashSet(7);
}
+ /**
+ * @return Returns the channel to which the implementation will delegate
+ */
+ public Channel getDelegate()
+ {
+ return delegate;
+ }
+
/**
* Swap the channel. The old delegate will be disconnected before the swap occurs.
* This guarantees data consistency, assuming that any failures will be handled.
@@ -625,7 +585,7 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
* @param the new delegate
* @return the old, disconnected delegate
*/
- public Channel swap(Channel channel)
+ public synchronized Channel swap(Channel channel)
{
// Remove the listeners from the old channel
delegate.setReceiver(null);
@@ -635,7 +595,7 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
}
delegate.setUpHandler(null);
- Channel oldDelegage = delegate;
+ Channel oldDelegate = delegate;
// Assign the new delegate and carry the listeners over
delegate = channel;
@@ -646,22 +606,42 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
}
delegate.setUpHandler(delegateUpHandler);
// Done
- return oldDelegage;
+ return oldDelegate;
}
@Override
- protected Log getLog()
+ protected org.jgroups.logging.Log getLog()
{
throw new UnsupportedOperationException();
}
- public void setReceiver(Receiver r)
+ @Override
+ public Address getAddress()
+ {
+ return delegate.getAddress();
+ }
+
+ @Override
+ public String getName()
+ {
+ return delegate.getName();
+ }
+
+ @Override
+ public ProtocolStack getProtocolStack()
+ {
+ return delegate.getProtocolStack();
+ }
+
+ @Override
+ public synchronized void setReceiver(Receiver r)
{
delegateReceiver = r;
delegate.setReceiver(r);
}
- public void addChannelListener(ChannelListener listener)
+ @Override
+ public synchronized void addChannelListener(ChannelListener listener)
{
if (listener == null)
{
@@ -671,7 +651,8 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
delegate.addChannelListener(listener);
}
- public void removeChannelListener(ChannelListener listener)
+ @Override
+ public synchronized void removeChannelListener(ChannelListener listener)
{
if (listener != null)
{
@@ -680,223 +661,273 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
delegate.removeChannelListener(listener);
}
- public void clearChannelListeners()
+ @Override
+ public synchronized void clearChannelListeners()
{
delegateChannelListeners.clear();
delegate.clearChannelListeners();
}
- public void setUpHandler(UpHandler up_handler)
+ @Override
+ public synchronized void setUpHandler(UpHandler up_handler)
{
delegateUpHandler = up_handler;
delegate.setUpHandler(up_handler);
}
+ @Override
public void blockOk()
{
delegate.blockOk();
}
+ @Override
public void close()
{
delegate.close();
}
+ @Override
public void connect(String cluster_name, Address target, String state_id, long timeout) throws ChannelException
{
delegate.connect(cluster_name, target, state_id, timeout);
}
+ @Override
public void connect(String cluster_name) throws ChannelException
{
delegate.connect(cluster_name);
}
+ @Override
public void disconnect()
{
delegate.disconnect();
}
+ @Override
public void down(Event evt)
{
delegate.down(evt);
}
+ @Override
public Object downcall(Event evt)
{
return delegate.downcall(evt);
}
+ @Override
public String dumpQueue()
{
return delegate.dumpQueue();
}
+ @Override
@SuppressWarnings("unchecked")
public Map dumpStats()
{
return delegate.dumpStats();
}
+ @Override
public boolean equals(Object obj)
{
return delegate.equals(obj);
}
+ @Override
public boolean flushSupported()
{
return delegate.flushSupported();
}
+ @Override
@SuppressWarnings("unchecked")
public boolean getAllStates(Vector targets, long timeout) throws ChannelNotConnectedException, ChannelClosedException
{
return delegate.getAllStates(targets, timeout);
}
+ @Override
public String getChannelName()
{
return delegate.getChannelName();
}
+ @Override
public String getClusterName()
{
return delegate.getClusterName();
}
+ @Override
public Map getInfo()
{
return delegate.getInfo();
}
+ @Override
public Address getLocalAddress()
{
return delegate.getLocalAddress();
}
+ @Override
public int getNumMessages()
{
return delegate.getNumMessages();
}
+ @Override
public Object getOpt(int option)
{
return delegate.getOpt(option);
}
+ @Override
public boolean getState(Address target, long timeout) throws ChannelNotConnectedException, ChannelClosedException
{
return delegate.getState(target, timeout);
}
+ @Override
public boolean getState(Address target, String state_id, long timeout) throws ChannelNotConnectedException, ChannelClosedException
{
return delegate.getState(target, state_id, timeout);
}
+ @Override
public View getView()
{
return delegate.getView();
}
+ @Override
public int hashCode()
{
return delegate.hashCode();
}
+ @Override
public boolean isConnected()
{
return delegate.isConnected();
}
+ @Override
public boolean isOpen()
{
return delegate.isOpen();
}
+ @Override
public void open() throws ChannelException
{
delegate.open();
}
+ @Override
public Object peek(long timeout) throws ChannelNotConnectedException, ChannelClosedException, TimeoutException
{
return delegate.peek(timeout);
}
+ @Override
public Object receive(long timeout) throws ChannelNotConnectedException, ChannelClosedException, TimeoutException
{
return delegate.receive(timeout);
}
+ @Override
public void returnState(byte[] state, String state_id)
{
delegate.returnState(state, state_id);
}
+ @Override
public void returnState(byte[] state)
{
delegate.returnState(state);
}
+ @Override
public void send(Address dst, Address src, Serializable obj) throws ChannelNotConnectedException, ChannelClosedException
{
delegate.send(dst, src, obj);
}
+ @Override
public void send(Message msg) throws ChannelNotConnectedException, ChannelClosedException
{
delegate.send(msg);
}
+ @Override
public void setChannelListener(ChannelListener channel_listener)
{
delegate.setChannelListener(channel_listener);
}
+ @Override
public void setInfo(String key, Object value)
{
delegate.setInfo(key, value);
}
+ @Override
public void setOpt(int option, Object value)
{
delegate.setOpt(option, value);
}
+ @Override
public void shutdown()
{
delegate.shutdown();
}
+ @Override
public boolean startFlush(boolean automatic_resume)
{
return delegate.startFlush(automatic_resume);
}
+ @Override
public boolean startFlush(List flushParticipants, boolean automatic_resume)
{
return delegate.startFlush(flushParticipants, automatic_resume);
}
+ @Override
public boolean startFlush(long timeout, boolean automatic_resume)
{
return delegate.startFlush(timeout, automatic_resume);
}
+ @Override
public void stopFlush()
{
delegate.stopFlush();
}
+ @Override
public void stopFlush(List flushParticipants)
{
delegate.stopFlush(flushParticipants);
}
- public String toString()
+ @Override
+ public synchronized String toString()
{
- return delegate.toString();
+ if (delegate instanceof DummyJChannel)
+ {
+ return delegate.toString() + "(dummy)";
+ }
+ else
+ {
+ return delegate.toString();
+ }
}
}
}
diff --git a/source/java/org/alfresco/repo/jgroups/AlfrescoJGroupsChannelFactoryTest.java b/source/java/org/alfresco/repo/jgroups/AlfrescoJGroupsChannelFactoryTest.java
index 2c35095e94..2551fe4f24 100644
--- a/source/java/org/alfresco/repo/jgroups/AlfrescoJGroupsChannelFactoryTest.java
+++ b/source/java/org/alfresco/repo/jgroups/AlfrescoJGroupsChannelFactoryTest.java
@@ -75,6 +75,7 @@ public class AlfrescoJGroupsChannelFactoryTest extends TestCase
public void testBasicCluster() throws Exception
{
AlfrescoJGroupsChannelFactory.changeClusterNamePrefix("blah");
+ AlfrescoJGroupsChannelFactory.rebuildChannels();
Channel channel = AlfrescoJGroupsChannelFactory.getChannel(appRegion);
stressChannel(channel);
}
@@ -82,9 +83,11 @@ public class AlfrescoJGroupsChannelFactoryTest extends TestCase
public void testHotSwapCluster() throws Exception
{
AlfrescoJGroupsChannelFactory.changeClusterNamePrefix("ONE");
+ AlfrescoJGroupsChannelFactory.rebuildChannels();
Channel channel1 = AlfrescoJGroupsChannelFactory.getChannel(appRegion);
stressChannel(channel1);
AlfrescoJGroupsChannelFactory.changeClusterNamePrefix("TWO");
+ AlfrescoJGroupsChannelFactory.rebuildChannels();
Channel channel2 = AlfrescoJGroupsChannelFactory.getChannel(appRegion);
stressChannel(channel1);
assertTrue("Channel reference must be the same", channel1 == channel2);