Home » synapse-1.2-src » org.apache.synapse.endpoints » [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;
   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 endpoint.This hides where those states are kept .For a cluster
   30    * environment,all states are kept in the axis2 configuration context in order to replicate those
   31    * states so that other synapse instance in the same cluster can see those changes . This class can
   32    * be evolved to keep any run time states related to the endpoint .For a non-clustered environment,
   33    * all data are kept locally.
   34    * <p/>
   35    * This class provide the abstraction need to separate the dynamic data from the static data and
   36    * 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 EndpointContext {
   40   
   41       private static final Log log = LogFactory.getLog(EndpointContext.class);
   42   
   43       /* The  static constant only for construct key prefix for each property in endpoint context
   44        * as it is need when those property state going to replicate in a cluster env. */
   45       private static final String ACTIVE = "active";
   46       private static final String RECOVER_ON = "recover_on";
   47       private static final String UNDERSCORE_STRING = "_";
   48   
   49       /* Determines if this endpoint is active or not. This variable have to be loaded always from the
   50        * memory as multiple threads could access it.*/
   51       private boolean active = true;
   52   
   53       /* Time to recover a failed endpoint.*/
   54       private long recoverOn = Long.MAX_VALUE;
   55   
   56       /* The axis configuration context-  this will hold the all callers states
   57        * when doing throttling in a clustered environment. */
   58       private ConfigurationContext configCtx;
   59   
   60       /* The key for 'active' attribute and this is used when this attribute value being replicated */
   61       private String activePropertyKey;
   62       /* The key for 'recoverOn' attribute and this is used when this attribute value being
   63        * replicated */
   64       private String recoverOnPropertyKey;
   65   
   66       /* Is this env. support clustering*/
   67       private boolean isClusteringEnable = false;
   68   
   69       /**
   70        * Checks if the endpoint is active (failed or not)
   71        *
   72        * @return Returns true if the endpoint is active , otherwise , false will be returned
   73        */
   74       public boolean isActive() {
   75   
   76           if (this.isClusteringEnable) {  // if this is a clustering env.
   77   
   78               if (this.activePropertyKey == null || "".equals(this.activePropertyKey)) {
   79                   handleException("Cannot find the required key to find the " +
   80                           "shared state of 'active' attribute");
   81               }
   82   
   83               // gets the value from configuration context (The shared state across all instances )
   84               Object value = this.configCtx.getPropertyNonReplicable(this.activePropertyKey);
   85               if (value == null) {
   86                   return true;
   87               }
   88               if (value instanceof Boolean) {
   89                   return ((Boolean) value).booleanValue();
   90               } else if (value instanceof String) {
   91                   return Boolean.parseBoolean((String) value);
   92               } else {
   93                   handleException("Unsupported object type for value" + value);
   94               }
   95   
   96           } else {
   97               return active;
   98           }
   99   
  100           throw new SynapseException("Invalid states in endpoint context");
  101   
  102       }
  103   
  104       /**
  105        * Sets if endpoint active or not.
  106        *
  107        * @param active True for make endpoint active , false for make it inactive
  108        */
  109       public synchronized void setActive(boolean active) {
  110   
  111           if (this.isClusteringEnable) {  // if this is a clustering env.
  112               // replicates the state so that all instances across cluster can see this state
  113               setAndReplicateState(this.activePropertyKey, active);
  114           } else {
  115               this.active = active;
  116           }
  117   
  118       }
  119   
  120       /**
  121        * Time to recover a failed endpoint.
  122        *
  123        * @return Returns time to recover a failed endpoint.
  124        */
  125       public long getRecoverOn() {
  126   
  127           if (this.isClusteringEnable) {    // if this is a clustering env.
  128   
  129               if (this.recoverOnPropertyKey == null || "".equals(this.recoverOnPropertyKey)) {
  130                   handleException("Cannot find the required key to find the " +
  131                           "shared state of 'recoveOn' attribute");
  132               }
  133   
  134               // gets the value from configuration context (The shared state across all instances )
  135               Object value = this.configCtx.getPropertyNonReplicable(this.recoverOnPropertyKey);
  136               if (value == null) {
  137                   return Long.MAX_VALUE;
  138               }
  139               if (value instanceof Long) {
  140                   return ((Long) value).longValue();
  141               } else if (value instanceof String) {
  142                   try {
  143                       return Long.parseLong((String) value);
  144                   } catch (NumberFormatException e) {
  145                       return Long.MAX_VALUE;
  146                   }
  147               } else {
  148                   handleException("Unsupported object type for value" + value);
  149               }
  150   
  151           } else {
  152               return recoverOn;
  153           }
  154           throw new SynapseException("Invalid states in endpoint context");
  155       }
  156   
  157       /**
  158        * Sets time to recover a failed endpoint.
  159        *
  160        * @param recoverOn The value for recover time
  161        */
  162       public void setRecoverOn(long recoverOn) {
  163   
  164           if (this.isClusteringEnable) { // if this is a clustering env.
  165               // replicates the state so that all instances across cluster can see this state
  166               setAndReplicateState(this.recoverOnPropertyKey, recoverOn);
  167           } else {
  168               this.recoverOn = recoverOn;
  169           }
  170       }
  171   
  172       /**
  173        * Get the configuration context instance . This is only available for cluster env.
  174        *
  175        * @return Returns the ConfigurationContext instance
  176        */
  177       public ConfigurationContext getConfigurationContext() {
  178           return configCtx;
  179       }
  180   
  181       /**
  182        * Sets the  ConfigurationContext instance . This is only used for cluster env.
  183        * By setting this , indicates that this is a cluster env.
  184        *
  185        * @param configCtx The ConfigurationContext instance
  186        */
  187       public void setConfigurationContext(ConfigurationContext configCtx) {
  188   
  189           if (configCtx == null) {
  190               handleException("The ConfigurationContext cannot be null" +
  191                       " when system in a cluster environment");
  192           }
  193   
  194           this.configCtx = configCtx;
  195           this.isClusteringEnable = true; // Now, the environment is considered as a cluster
  196       }
  197   
  198       /**
  199        * Sets the identifier for this endpoint context , so that , this can be identified
  200        * uniquely across the cluster. The id will be the name of the endpoint
  201        *
  202        * @param contextID The Id for this endpoint context
  203        */
  204       public void setContextID(String contextID) {
  205   
  206           if (contextID == null || "".equals(contextID)) {
  207               handleException("The Context ID cannot be null when system in a cluster environment");
  208           }
  209   
  210           //Making required key for each property in the endpoint context - Those will be used when
  211           //replicating states
  212           StringBuffer buffer = new StringBuffer();
  213           buffer.append(contextID);
  214           buffer.append(UNDERSCORE_STRING);
  215           String prefix = buffer.toString();
  216   
  217           this.recoverOnPropertyKey = prefix + RECOVER_ON;
  218           this.activePropertyKey = prefix + ACTIVE;
  219   
  220       }
  221   
  222   
  223       /**
  224        * Helper method to replicates states of the property with given key
  225        * replicates  the given state so that all instances across cluster can see this state
  226        *
  227        * @param key   The key of the property
  228        * @param value The value of the property
  229        */
  230       private void setAndReplicateState(String key, Object value) {
  231   
  232           if (configCtx != null && key != null && value != null) {
  233   
  234               try {
  235                   if (log.isDebugEnabled()) {
  236                       log.debug("Start replicating the property with key : " + key +
  237                               " value : " + value);
  238                   }
  239   
  240                   configCtx.setProperty(key, value);
  241                   Replicator.replicate(configCtx, new String[]{key});
  242   
  243                   if (log.isDebugEnabled()) {
  244                       log.debug("Completed replication of the property with key : " + key);
  245                   }
  246   
  247               } catch (ClusteringFault clusteringFault) {
  248                   handleException("Error during the replicating states ", clusteringFault);
  249               }
  250           }
  251       }
  252   
  253       /**
  254        * Helper methods for handle errors.
  255        *
  256        * @param msg The error message
  257        */
  258       protected void handleException(String msg) {
  259           log.error(msg);
  260           throw new SynapseException(msg);
  261       }
  262   
  263       /**
  264        * Helper methods for handle errors.
  265        *
  266        * @param msg The error message
  267        * @param e   The exception
  268        */
  269       protected void handleException(String msg, Exception e) {
  270           log.error(msg, e);
  271           throw new SynapseException(msg, e);
  272       }
  273   }

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