com.comcast.cns.model.CNSRetryPolicy.java Source code

Java tutorial

Introduction

Here is the source code for com.comcast.cns.model.CNSRetryPolicy.java

Source

/**
 * Copyright 2012 Comcast Corporation
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.comcast.cns.model;

import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import org.apache.log4j.Logger;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * Class represents the retry policy.
 * @author jorge, bwolf
 *
 * Class is not thread-safe. Caller must ensure thread safety
 */
public class CNSRetryPolicy {

    private static Logger logger = Logger.getLogger(CNSRetryPolicy.class);

    public enum CnsBackoffFunction {
        linear, arithmetic, geometric, exponential;
    }

    private int minDelayTarget;
    private int maxDelayTarget;
    private int numRetries;
    private int numMaxDelayRetries;
    private int numMinDelayRetries;
    private int numNoDelayRetries;
    private CnsBackoffFunction backOffFunction;

    /*
     * Create an retryPolicy object by getting the variables directly
     */
    public CNSRetryPolicy(int minDelayTarget, int maxDelayTarget, int numRetries, int numMaxDelayRetries,
            int numMinDelayRetries, int numNoDelayRetries, CnsBackoffFunction backoffFunction) {

        this.minDelayTarget = minDelayTarget;
        this.maxDelayTarget = maxDelayTarget;
        this.numRetries = numRetries;
        this.numMaxDelayRetries = numMaxDelayRetries;
        this.numMinDelayRetries = numMinDelayRetries;
        this.numNoDelayRetries = numNoDelayRetries;
        this.backOffFunction = backoffFunction;
    }

    /*
     * Create a default policy
     */
    public CNSRetryPolicy() {

        this.minDelayTarget = 20;
        this.maxDelayTarget = 20;
        this.numRetries = 3;
        this.numMaxDelayRetries = 0;
        this.numMinDelayRetries = 0;
        this.numNoDelayRetries = 0;
        this.backOffFunction = CnsBackoffFunction.linear;
    }

    /**
     * Create a policy from a JSONObject
     * @param json The JSONObject that contains all the info for this Retry policy
     * @return the RetryPolicy formatted to default, or the parameter passed.
     */
    public CNSRetryPolicy(JSONObject json) throws CNSModelConstructionException {

        boolean error = false;
        String message = "";

        try {

            this.minDelayTarget = 20;
            this.maxDelayTarget = 20;
            this.numRetries = 3;
            this.numMaxDelayRetries = 0;
            this.numMinDelayRetries = 0;
            this.numNoDelayRetries = 0;
            this.backOffFunction = CnsBackoffFunction.linear;

            if (json.has("minDelayTarget")) {
                minDelayTarget = json.getInt("minDelayTarget");
            } else {
                message = "minDelayTarget must be specified";
                error = true;
            }

            if (json.has("maxDelayTarget")) {
                maxDelayTarget = json.getInt("maxDelayTarget");
            } else {
                message = "maxDelayTarget must be specified";
                error = true;
            }

            if (json.has("numRetries")) {
                numRetries = json.getInt("numRetries");
            } else {
                message = "numRetries must be specified";
                error = true;
            }

            if (json.has("numMaxDelayRetries")) {
                numMaxDelayRetries = json.getInt("numMaxDelayRetries");
            }

            if (json.has("numMinDelayRetries")) {
                numMinDelayRetries = json.getInt("numMinDelayRetries");
            }

            if (json.has("numNoDelayRetries")) {
                numNoDelayRetries = json.getInt("numNoDelayRetries");
            }

            if (json.has("backoffFunction")) {

                String backoffFunctionStr = json.getString("backoffFunction");

                try {
                    backOffFunction = CnsBackoffFunction.valueOf(backoffFunctionStr);
                } catch (Exception e) {
                    error = true;
                    message = "invalid backoffFunction";
                }
            }

            if (minDelayTarget > maxDelayTarget) {
                message = "maxDelayTarget must be greater than or equal to minDelayTarget";
                error = true;
            }

            if (numRetries < numMaxDelayRetries + numMinDelayRetries + numNoDelayRetries) {
                message = "numRetries must be greater than or equal to total of numMinDelayRetries, numNoDelayRetries and numMaxDelayRetries";
                error = true;
            }

            if (numRetries > 100) {
                message = "numRetries must be less than or equal to 100";
                error = true;
            }

            if (numRetries < 0 || minDelayTarget < 0 || maxDelayTarget < 0 || numMaxDelayRetries < 0
                    || numMinDelayRetries < 0 || numNoDelayRetries < 0) {
                message = "all variables must be greater than or equal to 0";
                error = true;
            }

            if (maxDelayTarget > 3600) {
                message = "max delay target must be less than or equal to 3600";
                error = true;
            }

        } catch (JSONException e) {
            logger.error("event=construct_cns_retry_policy", e);
            throw new CNSModelConstructionException("JSON parameter format error");
        }

        if (error) {
            logger.error("event=construct_cns_retry_policy message=" + message);
            throw new CNSModelConstructionException(message);
        }
    }

    private void update(Integer lminDelayTarget, Integer lmaxDelayTarget, Integer lnumRetries,
            Integer lnumMinDelayRetries, Integer lnumMaxDelayRetries, Integer lnumNoDelayRetries,
            CnsBackoffFunction lbackOffFunction) {

        this.minDelayTarget = lminDelayTarget;
        this.maxDelayTarget = lmaxDelayTarget;
        this.numRetries = lnumRetries;
        this.numMinDelayRetries = lnumMinDelayRetries;
        this.numMaxDelayRetries = lnumMaxDelayRetries;
        this.numNoDelayRetries = lnumNoDelayRetries;
        this.backOffFunction = lbackOffFunction;
    }

    /**
     * Update this object by taking values from parameter (if present) or the default values
     *  Also do validation checks
     * @param json
     * @throws Exception
     */
    public void update(JSONObject json) throws Exception {

        boolean error = false;
        String message = "";

        try {

            //Reset the values to default, then set it to the new values

            Integer lminDelayTarget = 20;
            Integer lmaxDelayTarget = 20;
            Integer lnumRetries = 3;
            Integer lnumMinDelayRetries = 0;
            Integer lnumMaxDelayRetries = 0;
            Integer lnumNoDelayRetries = 0;
            CnsBackoffFunction lbackOffFunction = CnsBackoffFunction.linear;

            if (json.has("minDelayTarget")) {
                lminDelayTarget = json.getInt("minDelayTarget");
            } else {
                message = "minDelayTarget must be specified";
                error = true;
            }

            if (json.has("maxDelayTarget")) {
                lmaxDelayTarget = json.getInt("maxDelayTarget");
            } else {
                message = "maxDelayTarget must be specified";
                error = true;
            }

            if (json.has("numRetries")) {
                lnumRetries = json.getInt("numRetries");
            } else {
                message = "numRetries must be specified";
                error = true;
            }

            if (json.has("numMinDelayRetries")) {
                lnumMinDelayRetries = json.getInt("numMinDelayRetries");
            }

            if (json.has("numMaxDelayRetries")) {
                lnumMaxDelayRetries = json.getInt("numMaxDelayRetries");
            }

            if (json.has("numNoDelayRetries")) {
                lnumNoDelayRetries = json.getInt("numNoDelayRetries");
            }

            if (json.has("backoffFunction")) {

                String backoffFunctionStr = json.getString("backoffFunction");

                try {
                    lbackOffFunction = CnsBackoffFunction.valueOf(backoffFunctionStr);
                } catch (Exception e) {
                    error = true;
                    message = "invalid backoffFunction";
                }
            }

            if (!error) {

                if (lminDelayTarget > lmaxDelayTarget) {
                    message = "maxDelayTarget must be greater than or equal to minDelayTarget";
                    error = true;
                }

                if (lnumRetries < lnumMaxDelayRetries + lnumMinDelayRetries + lnumNoDelayRetries) {
                    message = "numRetries must be greater than or equal to total of numMinDelayRetries, numNoDelayRetries and numMaxDelayRetries";
                    error = true;
                }

                if (lnumRetries > 100) {
                    message = "numRetries must be less than or equal to 100";
                    error = true;
                }

                if (lnumRetries < 0 || lminDelayTarget < 0 || lmaxDelayTarget < 0 || lnumMaxDelayRetries < 0
                        || lnumMinDelayRetries < 0 || lnumNoDelayRetries < 0) {
                    message = "all variables must be greater than or equal to 0";
                    error = true;
                }

                if (lmaxDelayTarget > 3600) {
                    message = "maxDelayTarget must be less than or equal to 3600";
                    error = true;
                }

                if (!error) {
                    this.update(lminDelayTarget, lmaxDelayTarget, lnumRetries, lnumMinDelayRetries,
                            lnumMaxDelayRetries, lnumNoDelayRetries, lbackOffFunction);
                }
            }

        } catch (Exception e) {

            logger.error("event=update_cns_retry_policy", e);
            throw new CNSModelConstructionException("JSON parameter format error");
        }

        if (error) {
            logger.error("event=update_cns_retry_policy message=" + message);
            throw new CNSModelConstructionException(message);
        }
    }

    public int getMinDelayTarget() {
        return minDelayTarget;
    }

    public void setMinDelayTarget(int minDelayTarget) {
        this.minDelayTarget = minDelayTarget;
    }

    public int getMaxDelayTarget() {
        return maxDelayTarget;
    }

    public void setMaxDelayTarget(int maxDelayTarget) {
        this.maxDelayTarget = maxDelayTarget;
    }

    public int getNumRetries() {
        return numRetries;
    }

    public void setNumRetries(int numRetries) {
        this.numRetries = numRetries;
    }

    public int getNumMaxDelayRetries() {
        return numMaxDelayRetries;
    }

    public void setNumMaxDelayRetries(int numMaxDelayRetries) {
        this.numMaxDelayRetries = numMaxDelayRetries;
    }

    public CnsBackoffFunction getBackOffFunction() {
        return backOffFunction;
    }

    public void setBackOffFunction(CnsBackoffFunction backOffFunction) {
        this.backOffFunction = backOffFunction;
    }

    public JSONObject toJSON() {

        try {

            JSONObject json = new JSONObject();
            json.put("minDelayTarget", minDelayTarget);
            json.put("maxDelayTarget", maxDelayTarget);
            json.put("numRetries", numRetries);
            json.put("numMaxDelayRetries", numMaxDelayRetries);
            json.put("numMinDelayRetries", numMinDelayRetries);
            json.put("numNoDelayRetries", numNoDelayRetries);
            json.put("backoffFunction", backOffFunction.toString());

            return json;

        } catch (Exception e) {
            logger.error("event=cns_retry_policy_to_json", e);
        }

        return null;
    }

    @Override
    public String toString() {

        try {

            JSONObject json = this.toJSON();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            Writer writer = new PrintWriter(out);
            json.write(writer);
            writer.flush();

            return out.toString();

        } catch (Exception e) {
            return null;
        }
    }

    public int getNumMinDelayRetries() {
        return numMinDelayRetries;
    }

    public void setNumMinDelayRetries(int numMinDelayRetries) {
        this.numMinDelayRetries = numMinDelayRetries;
    }

    public int getNumNoDelayRetries() {
        return numNoDelayRetries;
    }

    public void setNumNoDelayRetries(int numNoDelayRetries) {
        this.numNoDelayRetries = numNoDelayRetries;
    }
}