Home » synapse-1.2-src » org.apache.synapse.endpoints.algorithms » [javadoc | source]

    1   /*
    2   *  Licensed to the Apache Software Foundation (ASF) under one
    3   *  or more contributor license agreements.  See the NOTICE file
    4   *  distributed with this work for additional information
    5   *  regarding copyright ownership.  The ASF licenses this file
    6   *  to you under the Apache License, Version 2.0 (the
    7   *  "License"); you may not use this file except in compliance
    8   *  with the License.  You may obtain a copy of the License at
    9   *
   10   *   http://www.apache.org/licenses/LICENSE-2.0
   11   *
   12   *  Unless required by applicable law or agreed to in writing,
   13   *  software distributed under the License is distributed on an
   14   *   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15   *  KIND, either express or implied.  See the License for the
   16   *  specific language governing permissions and limitations
   17   *  under the License.
   18   */
   19   package org.apache.synapse.endpoints.algorithms;
   20   
   21   import org.apache.axis2.clustering.ClusteringFault;
   22   import org.apache.axis2.clustering.context.Replicator;
   23   import org.apache.axis2.context.ConfigurationContext;
   24   import org.apache.commons.logging.Log;
   25   import org.apache.commons.logging.LogFactory;
   26   import org.apache.synapse.SynapseException;
   27   
   28   /**
   29    * Keeps the states of the load balance algorithm.This hides where those states are kept.For a
   30    * cluster environment ,all states are kept in the axis2 configuration context in order to replicate
   31    * those states so that other synapse instance in the same cluster can see those changes .
   32    * This class can be evolved to keep any run time states related to the endpoint .
   33    * For a non-clustered environment , all data are kept locally.
   34    * <p/>
   35    * This class provide the abstraction need to separate the dynamic data from the static data
   36    * and improve the  high cohesion and provides capability to replicate only required state at
   37    * a given time. This improves the performance when replicate data.
   38    */
   39   public class AlgorithmContext {
   40   
   41       private static final Log log = LogFactory.getLog(AlgorithmContext.class);
   42   
   43       /* The  static constant only for construct key prefix for each property in a dispatcher context
   44        * as it is need when those property state going to replicate in a cluster env. */
   45       private static final String UNDERSCORE_STRING = "_";
   46       private static final String CURRENT_EPR = "currentEPR";
   47   
   48       /* The axis configuration context-  this will hold the all callers states
   49        * when doing throttling in a clustered environment. */
   50       private ConfigurationContext configCtx;
   51   
   52       /* Is this env. support clustering*/
   53       private boolean isClusteringEnable = false;
   54   
   55       /* The key for 'currentEPR' attribute and this is used when this attribute value being
   56        * replicated */
   57       private String currentEPRPropertyKey;
   58   
   59       /* The pointer to current epr - The position of the current EPR */
   60       private int currentEPR = 0;
   61   
   62       /**
   63        * To get the  position of the current EPR
   64        * If there is no value and if there will not appear any errors , then '0' will be returned.
   65        *
   66        * @return The  position of the current EPR
   67        */
   68       public int getCurrentEndpointIndex() {
   69   
   70           if (this.isClusteringEnable) {  // if this is a clustering env.
   71   
   72               if (this.currentEPRPropertyKey == null || "".equals(this.currentEPRPropertyKey)) {
   73                   handleException("Cannot find the required key to find the " +
   74                           "shared state of the 'currentEPR' attribute");
   75               }
   76   
   77               Object value = this.configCtx.getPropertyNonReplicable(this.currentEPRPropertyKey);
   78               if (value == null) {
   79                   return 0;
   80               }
   81               try {
   82                   if (value instanceof Integer) {
   83                       return ((Integer) value).intValue();
   84                   } else if (value instanceof String) {
   85                       return Integer.parseInt((String) value);
   86                   }
   87               } catch (NumberFormatException e) {
   88                   handleException("The invalid value for the 'currentEPR' attribute");
   89               }
   90           } else {
   91               return currentEPR;
   92           }
   93           return 0;
   94       }
   95   
   96       /**
   97        * The  position of the current EPR
   98        *
   99        * @param currentEPR The current position
  100        */
  101       public void setCurrentEPR(int currentEPR) {
  102   
  103           if (isClusteringEnable) {  // if this is a clustering env.
  104   
  105               if (currentEPRPropertyKey != null) {
  106                   if (log.isDebugEnabled()) {
  107                       log.debug("Setting the current EPR " + currentEPR
  108                               + " with the key " + currentEPRPropertyKey);
  109                   }
  110                   // Sets the property and  replicates the current state  so that all instances
  111                   setAndReplicateState(currentEPRPropertyKey, currentEPR);
  112               }
  113           } else {
  114               if (log.isDebugEnabled()) {
  115                   log.debug("Setting the current EPR " + currentEPR);
  116               }
  117               this.currentEPR = currentEPR;
  118           }
  119       }
  120   
  121       /**
  122        * Get the configuration context instance . This is only available for cluster env.
  123        *
  124        * @return Returns the ConfigurationContext instance
  125        */
  126       public ConfigurationContext getConfigurationContext() {
  127           return configCtx;
  128       }
  129   
  130       /**
  131        * Sets the  ConfigurationContext instance . This is only used for cluster env.
  132        * By setting this , indicates that this is a cluster env.
  133        *
  134        * @param configCtx The ConfigurationContext instance
  135        */
  136       public void setConfigurationContext(ConfigurationContext configCtx) {
  137   
  138           if (configCtx == null) {
  139               handleException("The ConfigurationContext cannot be null when system " +
  140                       "in a cluster environment");
  141           }
  142   
  143           this.configCtx = configCtx;
  144           this.isClusteringEnable = true; // Now, the environment is considered as a cluster
  145       }
  146   
  147       /**
  148        * Sets the identifier for this algorithm context , so that , this can be identified
  149        * uniquely across the cluster. The id will be the name of the endpoint
  150        *
  151        * @param contextID The Id for this algorithm context
  152        */
  153       public void setContextID(String contextID) {
  154   
  155           if (contextID == null || "".equals(contextID)) {
  156               handleException("The Context ID cannot be null when system in a cluster environment");
  157           }
  158   
  159           //Making required key for each property in the algorithm context- Those will be used when
  160           //replicating states
  161           StringBuffer buffer = new StringBuffer();
  162           buffer.append(contextID);
  163           buffer.append(UNDERSCORE_STRING);
  164           buffer.append(CURRENT_EPR);
  165           currentEPRPropertyKey = buffer.toString();
  166       }
  167   
  168   
  169       /**
  170        * Helper methods for handle errors.
  171        *
  172        * @param msg The error message
  173        */
  174       protected void handleException(String msg) {
  175           log.error(msg);
  176           throw new SynapseException(msg);
  177       }
  178   
  179       /**
  180        * Helper methods for handle errors.
  181        *
  182        * @param msg The error message
  183        * @param e   The exception
  184        */
  185       protected void handleException(String msg, Exception e) {
  186           log.error(msg, e);
  187           throw new SynapseException(msg, e);
  188       }
  189   
  190       /**
  191        * Helper method to replicates states of the property with given key
  192        * Sets property and  replicates the current state  so that all instances
  193        * across cluster can see this state
  194        *
  195        * @param key   The key of the property
  196        * @param value The value of the property
  197        */
  198       private void setAndReplicateState(String key, Object value) {
  199   
  200           if (configCtx != null && key != null && value != null) {
  201   
  202               try {
  203                   if (log.isDebugEnabled()) {
  204                       log.debug("Start replicating the property with key : " + key
  205                               + " value : " + value);
  206                   }
  207   
  208                   configCtx.setProperty(key, value);
  209                   Replicator.replicate(configCtx, new String[]{key});
  210   
  211                   if (log.isDebugEnabled()) {
  212                       log.debug("Completed replication of the property with key : " + key);
  213                   }
  214   
  215               } catch (ClusteringFault clusteringFault) {
  216                   handleException("Error during the replicating states ", clusteringFault);
  217               }
  218           }
  219       }
  220   
  221   }

Home » synapse-1.2-src » org.apache.synapse.endpoints.algorithms » [javadoc | source]