/* * JBoss, Home of Professional Open Source * Copyright 2009, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. * See the copyright.txt in the distribution for a * full listing of individual contributors. * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU Lesser General Public License, v. 2.1. * This program is distributed in the hope that it will be useful, but WITHOUT A * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License, * v.2.1 along with this distribution; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. * * (C) 2009, * @author JBoss, a division of Red Hat. */ package com.arjuna.ats.arjuna.common; import java.net.InetAddress; import java.util.ArrayList; import java.util.List; import com.arjuna.ats.arjuna.recovery.ExpiryScanner; import com.arjuna.ats.arjuna.recovery.RecoveryActivator; import com.arjuna.ats.arjuna.recovery.RecoveryModule; import com.arjuna.ats.arjuna.utils.Utility; import com.arjuna.ats.internal.arjuna.recovery.PeriodicRecovery; import com.arjuna.common.internal.util.ClassloadingUtility; import com.arjuna.common.internal.util.propertyservice.ConcatenationPrefix; import com.arjuna.common.internal.util.propertyservice.FullPropertyName; import com.arjuna.common.internal.util.propertyservice.PropertyPrefix; /** * A JavaBean containing configuration properties for the recovery system. * * @author Jonathan Halliday (jonathan.halliday@redhat.com) */ @PropertyPrefix(prefix = "com.arjuna.ats.arjuna.recovery.") public class RecoveryEnvironmentBean implements RecoveryEnvironmentBeanMBean { private volatile int periodicRecoveryPeriod = PeriodicRecovery._defaultRecoveryPeriod; private volatile int recoveryBackoffPeriod = PeriodicRecovery._defaultBackoffPeriod; private volatile int periodicRecoveryInitilizationOffset = 0; private volatile boolean recoveryListener = false; private volatile int recoveryPort = 0; private volatile String recoveryAddress = "localhost"; private volatile int transactionStatusManagerPort = 0; private volatile String transactionStatusManagerAddress = "localhost"; private volatile int expiryScanInterval = 12; // hours private volatile int transactionStatusManagerExpiryTime = 12; // hours @ConcatenationPrefix(prefix = "com.arjuna.ats.arjuna.recovery.expiryScanner") private volatile List<String> expiryScannerClassNames = new ArrayList<String>(); private volatile List<ExpiryScanner> expiryScanners = null; @ConcatenationPrefix(prefix = "com.arjuna.ats.arjuna.recovery.recoveryExtension") private volatile List<String> recoveryModuleClassNames = new ArrayList<String>(); private volatile List<RecoveryModule> recoveryModules = null; @ConcatenationPrefix(prefix = "com.arjuna.ats.arjuna.recovery.recoveryActivator") private volatile List<String> recoveryActivatorClassNames = new ArrayList<String>(); private volatile List<RecoveryActivator> recoveryActivators = null; @FullPropertyName(name = "com.arjuna.ats.internal.arjuna.recovery.listener.timeoutsocket") private volatile boolean timeoutSocket = false; /** * Returns the interval between recovery scans, in seconds. * * Default: 120 seconds * Equivalent deprecated property: com.arjuna.ats.arjuna.recovery.periodicRecoveryPeriod * * @return the recovery scan period, in seconds. */ public int getPeriodicRecoveryPeriod() { return periodicRecoveryPeriod; } /** * Sets the interval between recovery scans, in seconds. * * @param periodicRecoveryPeriod the recovery scan period, in seconds. */ public void setPeriodicRecoveryPeriod(int periodicRecoveryPeriod) { this.periodicRecoveryPeriod = periodicRecoveryPeriod; } /** * Returns the interval between recovery phases within a recovery scan, in seconds. * * Default: 10 seconds * Equivalent deprecated property: com.arjuna.ats.arjuna.recovery.recoveryBackoffPeriod * * @return the interval between recovery phases, in seconds. */ public int getRecoveryBackoffPeriod() { return recoveryBackoffPeriod; } /** * Sets the interval between recovery phases, in seconds. * * @param recoveryBackoffPeriod the interval between recovery scan phases, in seconds. */ public void setRecoveryBackoffPeriod(int recoveryBackoffPeriod) { this.recoveryBackoffPeriod = recoveryBackoffPeriod; } /** * Returns the initial period to wait before starting recovery. Useful when starting multiple servers at once. * * @return The initial offset (in seconds) */ public int getPeriodicRecoveryInitilizationOffset() { return periodicRecoveryInitilizationOffset; } /** * Set the period of time to wait before starting recovery. * * @param periodicRecoveryInitilizationOffset The period (in seconds) to wait before starting first recovery run. */ public RecoveryEnvironmentBean setPeriodicRecoveryInitilizationOffset(int periodicRecoveryInitilizationOffset) { this.periodicRecoveryInitilizationOffset = periodicRecoveryInitilizationOffset; return null; } /** * Returns true if the recovery system should listen on a network socket. * * Default: true * Equivalent deprecated property: com.arjuna.ats.arjuna.recovery.recoveryListener * * @return true for network recovery, false for local JVM only use. */ public boolean isRecoveryListener() { return recoveryListener; } /** * Sets if the recovery system should listen on a network socket or not. * * @param recoveryListener true for network use, false for local JVM only. */ public void setRecoveryListener(boolean recoveryListener) { this.recoveryListener = recoveryListener; } /** * Returns the network port number on which the recovery listener should bind. * * Default: 0 * Equivalent deprecated property: com.arjuna.ats.arjuna.recovery.recoveryPort * * @return the port number for recovery listener. */ public int getRecoveryPort() { return recoveryPort; } /** * Sets the network port number on which the recovery listener should bind. * * @param recoveryPort the port number for the recovery listener. */ public void setRecoveryPort(int recoveryPort) { Utility.validatePortRange(recoveryPort); this.recoveryPort = recoveryPort; } /** * Returns the hostname on which the recovery listener should bind. * * Default: "localhost" * Equivalent deprecated property: com.arjuna.ats.arjuna.recovery.recoveryAddress * * @return the hostname on which the recovery system will listen. */ public String getRecoveryAddress() { return recoveryAddress; } /** * Sets the hostname on which the recovery listener should bind. * * @param recoveryAddress the hostname on which the recovery system will listen. */ public void setRecoveryAddress(String recoveryAddress) { this.recoveryAddress = recoveryAddress; } /** * Sets the InetAddress on which the recovery listener should bind. * Mainly intended for use by strongly typed bean injection systems, * this is a wrapper around the String form of the method. * * @param inetAddress the address on which to bind the recovery listener. */ public void setRecoveryInetAddress(InetAddress inetAddress) { setRecoveryAddress(inetAddress.getHostAddress()); } /** * Returns the network port number on which the transaction status manager should bind. * * Default: 0 * Equivalent deprecated property: com.arjuna.ats.arjuna.recovery.transactionStatusManagerPort * * @return the port number for the transaction status manager listener. */ public int getTransactionStatusManagerPort() { return transactionStatusManagerPort; } /** * Sets the network port number on which the transaction status manager should bind. * * @param transactionStatusManagerPort the port number for the transaction status manager listener. */ public void setTransactionStatusManagerPort(int transactionStatusManagerPort) { Utility.validatePortRange(transactionStatusManagerPort); this.transactionStatusManagerPort = transactionStatusManagerPort; } /** * Returns the hostname on which the transaction status manager should bind. * * Default: "localhost" * Equivalent deprecated property: com.arjuna.ats.arjuna.recovery.transactionStatusManagerAddress * * @return the hostname on which the transaction status manager will listen. */ public String getTransactionStatusManagerAddress() { return transactionStatusManagerAddress; } /** * Sets the hostname on which the transaction status manager should bind. * * @param transactionStatusManagerAddress the hostname on which the transaction status manager will listen. */ public void setTransactionStatusManagerAddress(String transactionStatusManagerAddress) { this.transactionStatusManagerAddress = transactionStatusManagerAddress; } /** * Sets the InetAddress on which the transaction status manager should bind. * Mainly intended for use by strongly typed bean injection systems, * this is a wrapper around the String form of the method. * * @param inetAddress the address on which to bind the transaction status manager. */ public void setTransactionStatusManagerInetAddress(InetAddress inetAddress) { setTransactionStatusManagerAddress(inetAddress.getHostAddress()); } /** * Returns the interval on which the ObjectStore will be scanned for expired items, in hours. * * Default: 12 hours * Equivalent deprecated property: com.arjuna.ats.arjuna.recovery.expiryScanInterval * * @return the interval between ObjectStore expiry checks, in hours. */ public int getExpiryScanInterval() { return expiryScanInterval; } /** * Sets the interval on which the ObjectStore will be scanned for expired items, in hours. * * @param expiryScanInterval the interval between ObjectStore expiry checks, in hours. */ public void setExpiryScanInterval(int expiryScanInterval) { this.expiryScanInterval = expiryScanInterval; } /** * Returns the time period after which items will be considered to have expired, in hours. * * Default: 12 hours * Equivalent deprecated property: com.arjuna.ats.arjuna.recovery.transactionStatusManagerExpiryTime * * @return the expiry timeout, in hours. */ public int getTransactionStatusManagerExpiryTime() { return transactionStatusManagerExpiryTime; } /** * Sets the time period after which items will be considered to have expired, in hours. * * @param transactionStatusManagerExpiryTime the expiry timeout, in hours. */ public void setTransactionStatusManagerExpiryTime(int transactionStatusManagerExpiryTime) { this.transactionStatusManagerExpiryTime = transactionStatusManagerExpiryTime; } /** * Returns a list of names of classes that implement ExpiryScanner. * The returned list is a copy. May return an empty list, will not return null. * * Default: empty list. * Equivalent deprecated property prefix: com.arjuna.ats.arjuna.recovery.expiryScanner * * @return a list of ExpiryScanner implementation class names. */ public List<String> getExpiryScannerClassNames() { synchronized(this) { return new ArrayList<String>(expiryScannerClassNames); } } /** * Sets the expiry scanners. * List elements should be names of classes that implement ExpiryScanner. * The provided list will be copied, not retained. * * @param expiryScannerClassNames a list of ExpiryScanner implementation class names. */ public void setExpiryScannerClassNames(List<String> expiryScannerClassNames) { synchronized(this) { if(expiryScannerClassNames == null) { this.expiryScanners = new ArrayList<ExpiryScanner>(); this.expiryScannerClassNames = new ArrayList<String>(); } else if(!expiryScannerClassNames.equals(this.expiryScannerClassNames)) { this.expiryScanners = null; this.expiryScannerClassNames = new ArrayList<String>(expiryScannerClassNames); } } } /** * Returns the set of ExpiryScanner instances. * The returned list is a copy. May return an empty list, will not return null. * * If there is no pre-instantiated instance set and classloading or instantiation of one or more * elements fails, this method will log an appropriate warning and return a non-null set with * fewer elements. * * @return the set of ExpiryScanner instances. */ public List<ExpiryScanner> getExpiryScanners() { synchronized(this) { if(expiryScanners == null) { List<ExpiryScanner> instances = ClassloadingUtility.loadAndInstantiateClasses(ExpiryScanner.class, expiryScannerClassNames); expiryScanners = instances; } return new ArrayList<ExpiryScanner>(expiryScanners); } } /** * Sets the instances of ExpiryScanner. * The provided list will be copied, not retained. * * @param expiryScanners the set of ExpiryScanner instances. */ public void setExpiryScanners(List<ExpiryScanner> expiryScanners) { synchronized(this) { if(expiryScanners == null) { this.expiryScanners = new ArrayList<ExpiryScanner>(); this.expiryScannerClassNames = new ArrayList<String>(); } else { this.expiryScanners = new ArrayList<ExpiryScanner>(expiryScanners); List<String> names = ClassloadingUtility.getNamesForClasses(this.expiryScanners); this.expiryScannerClassNames = names; } } } /** * Returns a list of names of classes that implement RecoveryModule. * The returned list is a copy. May return an empty list, will not return null. * * Default: empty list. * Equivalent deprecated property prefix: * * @return a list of RecoveryModule implementation class names. */ public List<String> getRecoveryModuleClassNames() { synchronized(this) { return new ArrayList<String>(recoveryModuleClassNames); } } /** * Sets the recovery modules. * List elements should be names of classes that implement RecoveryModule. * The provided list will be copied, not retained. * * @param recoveryModuleClassNames a list of RecoveryModule implementation class names. */ public void setRecoveryModuleClassNames(List<String> recoveryModuleClassNames) { synchronized(this) { if(recoveryModuleClassNames == null) { this.recoveryModules = new ArrayList<RecoveryModule>(); this.recoveryModuleClassNames = new ArrayList<String>(); } else if(!recoveryModuleClassNames.equals(this.recoveryModuleClassNames)) { this.recoveryModules = null; this.recoveryModuleClassNames = new ArrayList<String>(recoveryModuleClassNames); } } } /** * Returns the set of RecoveryModule instances. * The returned list is a copy. May return an empty list, will not return null. * * If there is no pre-instantiated instance set and classloading or instantiation of one or more * elements fails, this method will log an appropriate warning and return a non-null set with * fewer elements. * * @return the set of RecoveryModule instances. */ public List<RecoveryModule> getRecoveryModules() { synchronized(this) { if(recoveryModules == null) { List<RecoveryModule> instances = ClassloadingUtility.loadAndInstantiateClassesWithInit(RecoveryModule.class, recoveryModuleClassNames); recoveryModules = instances; } return new ArrayList<RecoveryModule>(recoveryModules); } } /** * Sets the instances of RecoveryModule. * The provided list will be copied, not retained. * * @param recoveryModules the set of RecoveryModule instances. */ public void setRecoveryModules(List<RecoveryModule> recoveryModules) { synchronized(this) { if(recoveryModules == null) { this.recoveryModules = new ArrayList<RecoveryModule>(); this.recoveryModuleClassNames = new ArrayList<String>(); } else { this.recoveryModules = new ArrayList<RecoveryModule>(recoveryModules); List<String> names = ClassloadingUtility.getNamesForClasses(this.recoveryModules); this.recoveryModuleClassNames = names; } } } /** * Returns a list of names of classes that implement RecoveryActivator. * The returned list is a copy. May return an empty list, will not return null. * * Default: empty list. * Equivalent deprecated property prefix: * * @return a list of RecoveryActivator implementation class names. */ public List<String> getRecoveryActivatorClassNames() { synchronized(this) { return new ArrayList<String>(recoveryActivatorClassNames); } } /** * Sets the recovery activators. * List elements should be names of classes that implement RecoveryActivator. * The provided list will be copied, not retained. * * @param recoveryActivatorClassNames a list of RecoveryActivator implementation class names. */ public void setRecoveryActivatorClassNames(List<String> recoveryActivatorClassNames) { synchronized(this) { if(recoveryActivatorClassNames == null) { this.recoveryActivators = new ArrayList<RecoveryActivator>(); this.recoveryActivatorClassNames = new ArrayList<String>(); } else if(!recoveryActivatorClassNames.equals(this.recoveryActivatorClassNames)) { this.recoveryActivators = null; this.recoveryActivatorClassNames = new ArrayList<String>(recoveryActivatorClassNames); } } } /** * Returns the set of RecoveryActivator instances. * The returned list is a copy. May return an empty list, will not return null. * * If there is no pre-instantiated instance set and classloading or instantiation of one or more * elements fails, this method will log an appropriate warning and return a non-null set with * fewer elements. * * @return the set of RecoveryActivator instances. */ public List<RecoveryActivator> getRecoveryActivators() { synchronized(this) { if(recoveryActivators == null) { List<RecoveryActivator> instances = ClassloadingUtility.loadAndInstantiateClassesWithInit(RecoveryActivator.class, recoveryActivatorClassNames); recoveryActivators = instances; } return new ArrayList<RecoveryActivator>(recoveryActivators); } } /** * Sets the instances of RecoveryActivator. * The provided list will be copied, not retained. * * @param recoveryActivators the set of RecoveryActivator instances. */ public void setRecoveryActivators(List<RecoveryActivator> recoveryActivators) { synchronized(this) { if(recoveryActivators == null) { this.recoveryActivators = new ArrayList<RecoveryActivator>(); this.recoveryActivatorClassNames = new ArrayList<String>(); } else { this.recoveryActivators = new ArrayList<RecoveryActivator>(recoveryActivators); List<String> names = ClassloadingUtility.getNamesForClasses(this.recoveryActivators); this.recoveryActivatorClassNames = names; } } } /** * Returns true if SO_TIMEOUT should be set on Listener socket instances. * * Default: false * Equivalent deprecated property: com.arjuna.ats.internal.arjuna.recovery.listener.timeoutsocket * * @return true if SO_TIMEOUT should be used, false if not. */ public boolean isTimeoutSocket() { return timeoutSocket; } /** * Sets the socket timeout behaviour of the Listener instances. * * @param timeoutSocket true to enable timeouts, false to disable. */ public void setTimeoutSocket(boolean timeoutSocket) { this.timeoutSocket = timeoutSocket; } }