001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.activemq.network.jms;
019
020/**
021 * A policy object that defines how a {@link JmsConnector} deals with
022 * reconnection of the local and foreign connections.
023 *
024 * @org.apache.xbean.XBean element="reconnectionPolicy"
025 */
026public class ReconnectionPolicy {
027
028    public static final int INFINITE = -1;
029
030    private int maxSendRetries = 10;
031    private long sendRetryDelay = 1000L;
032
033    private int maxReconnectAttempts = INFINITE;
034    private int maxInitialConnectAttempts = INFINITE;
035    private long maximumReconnectDelay = 30000;
036    private long initialReconnectDelay = 1000L;
037    private boolean useExponentialBackOff = false;
038    private double backOffMultiplier = 2.0;
039
040    /**
041     * Gets the maximum number of a times a Message send should be retried before
042     * a JMSExeception is thrown indicating that the operation failed.
043     *
044     * @return number of send retries that will be performed.
045     */
046    public int getMaxSendRetries() {
047        return maxSendRetries;
048    }
049
050    /**
051     * Sets the maximum number of a times a Message send should be retried before
052     * a JMSExeception is thrown indicating that the operation failed.
053     *
054     * @param maxSendRetries
055     *                  number of send retries that will be performed.
056     */
057    public void setMaxSendRetries(int maxSendRetries) {
058        this.maxSendRetries = maxSendRetries;
059    }
060
061    /**
062     * Get the amount of time the DestionationBridge will wait between attempts
063     * to forward a message.
064     *
065     * @return time in milliseconds to wait between send attempts.
066     */
067    public long getSendRetryDelay() {
068        return this.sendRetryDelay;
069    }
070
071    /**
072     * Set the amount of time the DestionationBridge will wait between attempts
073     * to forward a message.  The default policy limits the minimum time between
074     * send attempt to one second.
075     *
076     * @param sendRetryDelay
077     *          Time in milliseconds to wait before attempting another send.
078     */
079    public void setSendRetyDelay(long sendRetryDelay) {
080        if (sendRetryDelay < 1000L) {
081            this.sendRetryDelay = 1000L;
082        }
083
084        this.sendRetryDelay = sendRetryDelay;
085    }
086
087    /**
088     * Gets the number of time that {@link JmsConnector} will attempt to connect
089     * or reconnect before giving up.  By default the policy sets this value to
090     * a negative value meaning try forever.
091     *
092     * @return the number of attempts to connect before giving up.
093     */
094    public int getMaxReconnectAttempts() {
095        return maxReconnectAttempts;
096    }
097
098    /**
099     * Sets the number of time that {@link JmsConnector} will attempt to connect
100     * or reconnect before giving up.  By default the policy sets this value to
101     * a negative value meaning try forever, set to a positive value to retry a
102     * fixed number of times, or zero to never try and reconnect.
103     *
104     * @param maxReconnectAttempts
105     */
106    public void setMaxReconnectAttempts(int maxReconnectAttempts) {
107        this.maxReconnectAttempts = maxReconnectAttempts;
108    }
109
110    /**
111     * Gets the maximum number of times that the {@link JmsConnector} will try
112     * to connect on startup to before it marks itself as failed and does not
113     * try any further connections.
114     *
115     * @returns the max number of times a connection attempt is made before failing.
116     */
117    public int getMaxInitialConnectAttempts() {
118        return this.maxInitialConnectAttempts;
119    }
120
121    /**
122     * Sets the maximum number of times that the {@link JmsConnector} will try
123     * to connect on startup to before it marks itself as failed and does not
124     * try any further connections.
125     *
126     * @param maxAttempts
127     *          The max number of times a connection attempt is made before failing.
128     */
129    public void setMaxInitialConnectAttempts(int maxAttempts) {
130        this.maxInitialConnectAttempts = maxAttempts;
131    }
132
133    /**
134     * Gets the maximum delay that is inserted between each attempt to connect
135     * before another attempt is made.  The default setting for this value is
136     * 30 seconds.
137     *
138     * @return the max delay between connection attempts in milliseconds.
139     */
140    public long getMaximumReconnectDelay() {
141        return maximumReconnectDelay;
142    }
143
144    /**
145     * Sets the maximum delay that is inserted between each attempt to connect
146     * before another attempt is made.
147     *
148     * @param maximumReconnectDelay
149     *          The maximum delay between connection attempts in milliseconds.
150     */
151    public void setMaximumReconnectDelay(long maximumReconnectDelay) {
152        this.maximumReconnectDelay = maximumReconnectDelay;
153    }
154
155    /**
156     * Gets the initial delay value used before a reconnection attempt is made.  If the
157     * use exponential back-off value is set to false then this will be the fixed time
158     * between connection attempts.  By default this value is set to one second.
159     *
160     * @return time in milliseconds that will be used between connection retries.
161     */
162    public long getInitialReconnectDelay() {
163        return initialReconnectDelay;
164    }
165
166    /**
167     * Gets the initial delay value used before a reconnection attempt is made.  If the
168     * use exponential back-off value is set to false then this will be the fixed time
169     * between connection attempts.  By default this value is set to one second.
170
171     * @param initialReconnectDelay
172     *          Time in milliseconds to wait before the first reconnection attempt.
173     */
174    public void setInitialReconnectDelay(long initialReconnectDelay) {
175        this.initialReconnectDelay = initialReconnectDelay;
176    }
177
178    /**
179     * Gets whether the policy uses the set back-off multiplier to grow the time between
180     * connection attempts.
181     *
182     * @return true if the policy will grow the time between connection attempts.
183     */
184    public boolean isUseExponentialBackOff() {
185        return useExponentialBackOff;
186    }
187
188    /**
189     * Sets whether the policy uses the set back-off multiplier to grow the time between
190     * connection attempts.
191     *
192     * @param useExponentialBackOff
193     */
194    public void setUseExponentialBackOff(boolean useExponentialBackOff) {
195        this.useExponentialBackOff = useExponentialBackOff;
196    }
197
198    /**
199     * Gets the multiplier used to grow the delay between connection attempts from the initial
200     * time to the max set time.  By default this value is set to 2.0.
201     *
202     * @return the currently configured connection delay multiplier.
203     */
204    public double getBackOffMultiplier() {
205        return backOffMultiplier;
206    }
207
208    /**
209     * Gets the multiplier used to grow the delay between connection attempts from the initial
210     * time to the max set time.  By default this value is set to 2.0.
211     *
212     * @param backOffMultiplier
213     *          The multiplier value used to grow the reconnection delay.
214     */
215    public void setBackOffMultiplier(double backOffMultiplier) {
216        this.backOffMultiplier = backOffMultiplier;
217    }
218
219    /**
220     * Returns the next computed delay value that the connection controller should use to
221     * wait before attempting another connection for the {@link JmsConnector}.
222     *
223     * @param attempt
224     *          The current connection attempt.
225     *
226     * @return the next delay amount in milliseconds.
227     */
228    public long getNextDelay(int attempt) {
229
230        if (attempt == 0) {
231            return 0;
232        }
233
234        long nextDelay = initialReconnectDelay;
235
236        if (useExponentialBackOff) {
237            nextDelay = nextDelay * (long)(attempt * backOffMultiplier);
238        }
239
240        if (maximumReconnectDelay > 0 && nextDelay > maximumReconnectDelay) {
241            nextDelay = maximumReconnectDelay;
242        }
243
244        return nextDelay;
245    }
246}