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    private int maxSendRetries = 10;
029    private long sendRetryDelay = 1000L;
030
031    private int maxReconnectAttempts = -1;
032    private int maxInitialConnectAttempts = -1;
033    private long maximumReconnectDelay = 30000;
034    private long initialReconnectDelay = 1000L;
035    private boolean useExponentialBackOff = false;
036    private double backOffMultiplier = 2.0;
037
038    /**
039     * Gets the maximum number of a times a Message send should be retried before
040     * a JMSExeception is thrown indicating that the operation failed.
041     *
042     * @return number of send retries that will be performed.
043     */
044    public int getMaxSendRetries() {
045        return maxSendRetries;
046    }
047
048    /**
049     * Sets the maximum number of a times a Message send should be retried before
050     * a JMSExeception is thrown indicating that the operation failed.
051     *
052     * @param maxRetries
053     *                  number of send retries that will be performed.
054     */
055    public void setMaxSendRetries(int maxSendRetries) {
056        this.maxSendRetries = maxSendRetries;
057    }
058
059    /**
060     * Get the amount of time the DestionationBridge will wait between attempts
061     * to forward a message.
062     *
063     * @return time in milliseconds to wait between send attempts.
064     */
065    public long getSendRetryDelay() {
066        return this.sendRetryDelay;
067    }
068
069    /**
070     * Set the amount of time the DestionationBridge will wait between attempts
071     * to forward a message.  The default policy limits the minimum time between
072     * send attempt to one second.
073     *
074     * @param sendRetryDelay
075     *          Time in milliseconds to wait before attempting another send.
076     */
077    public void setSendRetyDelay(long sendRetryDelay) {
078        if (sendRetryDelay < 1000L) {
079            this.sendRetryDelay = 1000L;
080        }
081
082        this.sendRetryDelay = sendRetryDelay;
083    }
084
085    /**
086     * Gets the number of time that {@link JmsConnector} will attempt to connect
087     * or reconnect before giving up.  By default the policy sets this value to
088     * a negative value meaning try forever.
089     *
090     * @return the number of attempts to connect before giving up.
091     */
092    public int getMaxReconnectAttempts() {
093        return maxReconnectAttempts;
094    }
095
096    /**
097     * Sets the number of time that {@link JmsConnector} will attempt to connect
098     * or reconnect before giving up.  By default the policy sets this value to
099     * a negative value meaning try forever, set to a positive value to retry a
100     * fixed number of times, or zero to never try and reconnect.
101     *
102     * @param maxReconnectAttempts
103     */
104    public void setMaxReconnectAttempts(int maxReconnectAttempts) {
105        this.maxReconnectAttempts = maxReconnectAttempts;
106    }
107
108    /**
109     * Gets the maximum number of times that the {@link JmsConnector} will try
110     * to connect on startup to before it marks itself as failed and does not
111     * try any further connections.
112     *
113     * @returns the max number of times a connection attempt is made before failing.
114     */
115    public int getMaxInitialConnectAttempts() {
116        return this.maxInitialConnectAttempts;
117    }
118
119    /**
120     * Sets the maximum number of times that the {@link JmsConnector} will try
121     * to connect on startup to before it marks itself as failed and does not
122     * try any further connections.
123     *
124     * @param maxAttempts
125     *          The max number of times a connection attempt is made before failing.
126     */
127    public void setMaxInitialConnectAttempts(int maxAttempts) {
128        this.maxInitialConnectAttempts = maxAttempts;
129    }
130
131    /**
132     * Gets the maximum delay that is inserted between each attempt to connect
133     * before another attempt is made.  The default setting for this value is
134     * 30 seconds.
135     *
136     * @return the max delay between connection attempts in milliseconds.
137     */
138    public long getMaximumReconnectDelay() {
139        return maximumReconnectDelay;
140    }
141
142    /**
143     * Sets the maximum delay that is inserted between each attempt to connect
144     * before another attempt is made.
145     *
146     * @param maximumReconnectDelay
147     *          The maximum delay between connection attempts in milliseconds.
148     */
149    public void setMaximumReconnectDelay(long maximumReconnectDelay) {
150        this.maximumReconnectDelay = maximumReconnectDelay;
151    }
152
153    /**
154     * Gets the initial delay value used before a reconnection attempt is made.  If the
155     * use exponential back-off value is set to false then this will be the fixed time
156     * between connection attempts.  By default this value is set to one second.
157     *
158     * @return time in milliseconds that will be used between connection retries.
159     */
160    public long getInitialReconnectDelay() {
161        return initialReconnectDelay;
162    }
163
164    /**
165     * Gets the initial delay value used before a reconnection attempt is made.  If the
166     * use exponential back-off value is set to false then this will be the fixed time
167     * between connection attempts.  By default this value is set to one second.
168
169     * @param initialReconnectDelay
170     *          Time in milliseconds to wait before the first reconnection attempt.
171     */
172    public void setInitialReconnectDelay(long initialReconnectDelay) {
173        this.initialReconnectDelay = initialReconnectDelay;
174    }
175
176    /**
177     * Gets whether the policy uses the set back-off multiplier to grow the time between
178     * connection attempts.
179     *
180     * @return true if the policy will grow the time between connection attempts.
181     */
182    public boolean isUseExponentialBackOff() {
183        return useExponentialBackOff;
184    }
185
186    /**
187     * Sets whether the policy uses the set back-off multiplier to grow the time between
188     * connection attempts.
189     *
190     * @param useExponentialBackOff
191     */
192    public void setUseExponentialBackOff(boolean useExponentialBackOff) {
193        this.useExponentialBackOff = useExponentialBackOff;
194    }
195
196    /**
197     * Gets the multiplier used to grow the delay between connection attempts from the initial
198     * time to the max set time.  By default this value is set to 2.0.
199     *
200     * @return the currently configured connection delay multiplier.
201     */
202    public double getBackOffMultiplier() {
203        return backOffMultiplier;
204    }
205
206    /**
207     * Gets the multiplier used to grow the delay between connection attempts from the initial
208     * time to the max set time.  By default this value is set to 2.0.
209     *
210     * @param backOffMultiplier
211     *          The multiplier value used to grow the reconnection delay.
212     */
213    public void setBackOffMultiplier(double backOffMultiplier) {
214        this.backOffMultiplier = backOffMultiplier;
215    }
216
217    /**
218     * Returns the next computed delay value that the connection controller should use to
219     * wait before attempting another connection for the {@link JmsConnector}.
220     *
221     * @param attempt
222     *          The current connection attempt.
223     *
224     * @return the next delay amount in milliseconds.
225     */
226    public long getNextDelay(int attempt) {
227
228        if (attempt == 0) {
229            return 0;
230        }
231
232        long nextDelay = initialReconnectDelay;
233
234        if (useExponentialBackOff) {
235            nextDelay = nextDelay * (long)(attempt * backOffMultiplier);
236        }
237
238        if (maximumReconnectDelay > 0 && nextDelay > maximumReconnectDelay) {
239            nextDelay = maximumReconnectDelay;
240        }
241
242        return nextDelay;
243    }
244}