public boolean initialise(final String config) { if (ActiveMQXARecoveryLogger.LOGGER.isTraceEnabled()) { ActiveMQXARecoveryLogger.LOGGER.trace(this + " intialise: " + config); } String[] configs = config.split(";"); XARecoveryConfig[] xaRecoveryConfigs = new XARecoveryConfig[configs.length]; for (int i = 0, configsLength = configs.length; i < configsLength; i++) { String s = configs[i]; ConfigParser parser = new ConfigParser(s); String connectorFactoryClassName = parser.getConnectorFactoryClassName(); Map<String, Object> connectorParams = parser.getConnectorParameters(); String username = parser.getUsername(); String password = parser.getPassword(); TransportConfiguration transportConfiguration = new TransportConfiguration(connectorFactoryClassName, connectorParams); xaRecoveryConfigs[i] = new XARecoveryConfig( false, new TransportConfiguration[] {transportConfiguration}, username, password, null, null); } res = new ActiveMQXAResourceWrapper(xaRecoveryConfigs); if (ActiveMQXARecoveryLogger.LOGGER.isTraceEnabled()) { ActiveMQXARecoveryLogger.LOGGER.trace(this + " initialised"); } return true; }
public XAResource getXAResource() { if (ActiveMQXARecoveryLogger.LOGGER.isTraceEnabled()) { ActiveMQXARecoveryLogger.LOGGER.trace(this + " getXAResource"); } return res; }
public boolean hasMoreResources() { if (ActiveMQXARecoveryLogger.LOGGER.isTraceEnabled()) { ActiveMQXARecoveryLogger.LOGGER.trace(this + " hasMoreResources"); } /* * The way hasMoreResources is supposed to work is as follows: * For each "sweep" the recovery manager will call hasMoreResources, then if it returns * true it will call getXAResource. * It will repeat that until hasMoreResources returns false. * Then the sweep is over. * For the next sweep hasMoreResources should return true, etc. * * In our case where we only need to return one XAResource per sweep, * hasMoreResources should basically alternate between true and false. * * */ hasMore = !hasMore; return hasMore; }
public ActiveMQXAResourceRecovery() { if (trace) { ActiveMQXARecoveryLogger.LOGGER.trace("Constructing ActiveMQXAResourceRecovery"); } }
/** * A XAResourceRecovery instance that can be used to recover any JMS provider. * * <p>In reality only recover, rollback and commit will be called but we still need to be implement * all methods just in case. * * <p>To enable this add the following to the jbossts-properties file * * <pre> * <property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.ACTIVEMQ1" * value="org.apache.activemq.artemis.jms.server.recovery.ActiveMQXAResourceRecovery;org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnectorFactory"/> * </pre> * * <p>you'll need something like this if the ActiveMQ Artemis Server is remote * * <pre> * <property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.ACTIVEMQ2" * value="org.apache.activemq.artemis.jms.server.recovery.ActiveMQXAResourceRecovery;org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory,guest,guest,host=localhost,port=61616"/> * </pre> * * <p>you'll need something like this if the ActiveMQ Artemis Server is remote and has failover * configured * * <pre> * <property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.ACTIVEMQ2" * value="org.apache.activemq.artemis.jms.server.recovery.ActiveMQXAResourceRecovery;org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory,guest,guest,host=localhost,port=61616;org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory,guest,guest,host=localhost2,port=61617"/> * </pre> */ public class ActiveMQXAResourceRecovery { private final boolean trace = ActiveMQXARecoveryLogger.LOGGER.isTraceEnabled(); private boolean hasMore; private ActiveMQXAResourceWrapper res; public ActiveMQXAResourceRecovery() { if (trace) { ActiveMQXARecoveryLogger.LOGGER.trace("Constructing ActiveMQXAResourceRecovery"); } } public boolean initialise(final String config) { if (ActiveMQXARecoveryLogger.LOGGER.isTraceEnabled()) { ActiveMQXARecoveryLogger.LOGGER.trace(this + " intialise: " + config); } String[] configs = config.split(";"); XARecoveryConfig[] xaRecoveryConfigs = new XARecoveryConfig[configs.length]; for (int i = 0, configsLength = configs.length; i < configsLength; i++) { String s = configs[i]; ConfigParser parser = new ConfigParser(s); String connectorFactoryClassName = parser.getConnectorFactoryClassName(); Map<String, Object> connectorParams = parser.getConnectorParameters(); String username = parser.getUsername(); String password = parser.getPassword(); TransportConfiguration transportConfiguration = new TransportConfiguration(connectorFactoryClassName, connectorParams); xaRecoveryConfigs[i] = new XARecoveryConfig( false, new TransportConfiguration[] {transportConfiguration}, username, password, null, null); } res = new ActiveMQXAResourceWrapper(xaRecoveryConfigs); if (ActiveMQXARecoveryLogger.LOGGER.isTraceEnabled()) { ActiveMQXARecoveryLogger.LOGGER.trace(this + " initialised"); } return true; } public boolean hasMoreResources() { if (ActiveMQXARecoveryLogger.LOGGER.isTraceEnabled()) { ActiveMQXARecoveryLogger.LOGGER.trace(this + " hasMoreResources"); } /* * The way hasMoreResources is supposed to work is as follows: * For each "sweep" the recovery manager will call hasMoreResources, then if it returns * true it will call getXAResource. * It will repeat that until hasMoreResources returns false. * Then the sweep is over. * For the next sweep hasMoreResources should return true, etc. * * In our case where we only need to return one XAResource per sweep, * hasMoreResources should basically alternate between true and false. * * */ hasMore = !hasMore; return hasMore; } public XAResource getXAResource() { if (ActiveMQXARecoveryLogger.LOGGER.isTraceEnabled()) { ActiveMQXARecoveryLogger.LOGGER.trace(this + " getXAResource"); } return res; } public XAResource[] getXAResources() { return new XAResource[] {res}; } @Override protected void finalize() { res.close(); } public static class ConfigParser { private final String connectorFactoryClassName; private final Map<String, Object> connectorParameters; private String username; private String password; public ConfigParser(final String config) { if (config == null || config.length() == 0) { throw new IllegalArgumentException( "Must specify provider connector factory class name in config"); } String[] strings = config.split(","); // First (mandatory) param is the connector factory class name if (strings.length < 1) { throw new IllegalArgumentException( "Must specify provider connector factory class name in config"); } connectorFactoryClassName = strings[0].trim(); // Next two (optional) parameters are the username and password to use for creating the // session for recovery if (strings.length >= 2) { username = strings[1].trim(); if (username.length() == 0) { username = null; } if (strings.length == 2) { throw new IllegalArgumentException( "If username is specified, password must be specified too"); } password = strings[2].trim(); if (password.length() == 0) { password = null; } } // other tokens are for connector configurations connectorParameters = new HashMap<String, Object>(); if (strings.length >= 3) { for (int i = 3; i < strings.length; i++) { String[] str = strings[i].split("="); if (str.length == 2) { connectorParameters.put(str[0].trim(), str[1].trim()); } } } } public String getConnectorFactoryClassName() { return connectorFactoryClassName; } public Map<String, Object> getConnectorParameters() { return connectorParameters; } public String getUsername() { return username; } public String getPassword() { return password; } } }