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    package org.apache.activemq;
018    
019    import java.io.Serializable;
020    import java.util.Random;
021    
022    /**
023     * Configuration options used to control how messages are re-delivered when they
024     * are rolled back.
025     *
026     * @org.apache.xbean.XBean element="redeliveryPolicy"
027     *
028     */
029    public class RedeliveryPolicy implements Cloneable, Serializable {
030    
031        public static final int NO_MAXIMUM_REDELIVERIES = -1;
032        private static Random randomNumberGenerator;
033    
034        // +/-15% for a 30% spread -cgs
035        private double collisionAvoidanceFactor = 0.15d;
036        private int maximumRedeliveries = 6;
037        private long maximumRedeliveryDelay = -1;
038        private long initialRedeliveryDelay = 1000L;
039        private boolean useCollisionAvoidance;
040        private boolean useExponentialBackOff;
041        private double backOffMultiplier = 5.0;
042        private long redeliveryDelay = initialRedeliveryDelay;
043    
044        public RedeliveryPolicy() {
045        }
046    
047        public RedeliveryPolicy copy() {
048            try {
049                return (RedeliveryPolicy)clone();
050            } catch (CloneNotSupportedException e) {
051                throw new RuntimeException("Could not clone: " + e, e);
052            }
053        }
054    
055        public double getBackOffMultiplier() {
056            return backOffMultiplier;
057        }
058    
059        public void setBackOffMultiplier(double backOffMultiplier) {
060            this.backOffMultiplier = backOffMultiplier;
061        }
062    
063        public short getCollisionAvoidancePercent() {
064            return (short)Math.round(collisionAvoidanceFactor * 100);
065        }
066    
067        public void setCollisionAvoidancePercent(short collisionAvoidancePercent) {
068            this.collisionAvoidanceFactor = collisionAvoidancePercent * 0.01d;
069        }
070    
071        public long getInitialRedeliveryDelay() {
072            return initialRedeliveryDelay;
073        }
074    
075        public void setInitialRedeliveryDelay(long initialRedeliveryDelay) {
076            this.initialRedeliveryDelay = initialRedeliveryDelay;
077        }
078    
079        public long getMaximumRedeliveryDelay() {
080            return maximumRedeliveryDelay;
081        }
082    
083        public void setMaximumRedeliveryDelay(long maximumRedeliveryDelay) {
084            this.maximumRedeliveryDelay = maximumRedeliveryDelay;
085        }
086    
087        public int getMaximumRedeliveries() {
088            return maximumRedeliveries;
089        }
090    
091        public void setMaximumRedeliveries(int maximumRedeliveries) {
092            this.maximumRedeliveries = maximumRedeliveries;
093        }
094    
095        public long getNextRedeliveryDelay(long previousDelay) {
096            long nextDelay;
097    
098            if (previousDelay == 0) {
099                nextDelay = redeliveryDelay;
100            } else if (useExponentialBackOff && backOffMultiplier > 1) {
101                nextDelay = (long) (previousDelay * backOffMultiplier);
102                if(maximumRedeliveryDelay != -1 && nextDelay > maximumRedeliveryDelay) {
103                    // in case the user made max redelivery delay less than redelivery delay for some reason.
104                    nextDelay = Math.max(maximumRedeliveryDelay, redeliveryDelay);
105                }
106            } else {
107                nextDelay = previousDelay;
108            }
109    
110            if (useCollisionAvoidance) {
111                /*
112                 * First random determines +/-, second random determines how far to
113                 * go in that direction. -cgs
114                 */
115                Random random = getRandomNumberGenerator();
116                double variance = (random.nextBoolean() ? collisionAvoidanceFactor : -collisionAvoidanceFactor) * random.nextDouble();
117                nextDelay += nextDelay * variance;
118            }
119    
120            return nextDelay;
121        }
122    
123        public boolean isUseCollisionAvoidance() {
124            return useCollisionAvoidance;
125        }
126    
127        public void setUseCollisionAvoidance(boolean useCollisionAvoidance) {
128            this.useCollisionAvoidance = useCollisionAvoidance;
129        }
130    
131        public boolean isUseExponentialBackOff() {
132            return useExponentialBackOff;
133        }
134    
135        public void setUseExponentialBackOff(boolean useExponentialBackOff) {
136            this.useExponentialBackOff = useExponentialBackOff;
137        }
138    
139        protected static synchronized Random getRandomNumberGenerator() {
140            if (randomNumberGenerator == null) {
141                randomNumberGenerator = new Random();
142            }
143            return randomNumberGenerator;
144        }
145    
146        public void setRedeliveryDelay(long redeliveryDelay) {
147            this.redeliveryDelay = redeliveryDelay;
148        }
149    
150        public long getRedeliveryDelay() {
151            return redeliveryDelay;
152        }
153    }