View Javadoc

1   /**
2    * Copyright (C) 2005-2009 Alfresco Software Limited.
3    *
4    * This file is part of the Spring Surf Extension project.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * 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, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.springframework.extensions.webscripts.connector;
20  
21  import java.util.concurrent.ConcurrentHashMap;
22  import java.util.concurrent.ConcurrentMap;
23  
24  /**
25   * The EndpointManager is responsible for maintaining connection timeout and connection
26   * retry information for endpoints. It may be used by multiple Connector objects to
27   * ensure that shared endpoints are not repeatedly connected to or waited on.
28   * 
29   * @author Kevin Roast
30   */
31  public final class EndpointManager
32  {
33      /** timeout value in milliseconds before a reconnection
34          to a particular endpoint should be attempted */
35      private static final int RECONNECT_TIMEOUT = 20000;
36      
37      /** conncurrent map of endpoint->timeout values */
38      private static ConcurrentMap<String, Long> endpointTimeouts = new ConcurrentHashMap<String, Long>();
39      
40      
41      /**
42       * Private constructor
43       */
44      private EndpointManager()
45      {
46      }
47      
48      
49      /**
50       * Register an endpoint with the manager - the same endpoint can be registered
51       * any number of times with side effects.
52       * 
53       * @param endpoint      The endpoint to register
54       */
55      public static void registerEndpoint(String endpoint)
56      {
57          endpointTimeouts.putIfAbsent(endpoint, 0L);
58      }
59      
60      /**
61       * Returns true if the connector should make a connection attempt to the specified
62       * endpoint, false if the endpoint is still in the "wait" period between retries.
63       * 
64       * @param endpoint      The endpoint to test
65       * 
66       * @return true to allow connect, false otherwise
67       */
68      public static boolean allowConnect(String endpoint)
69      {
70          return (endpointTimeouts.get(endpoint) + RECONNECT_TIMEOUT < System.currentTimeMillis());
71      }
72      
73      /**
74       * Process the given response code for an endpoint - recording if that remote
75       * connection is unavailable for a time. Returns true if further response
76       * processing should continue, false otherwise.
77       * 
78       * @param endpoint      The endpoint to record code against
79       * @param code          Response code
80       * 
81       * @return true if further processing should continue, false otherwise
82       */
83      public static boolean processResponseCode(String endpoint, int code)
84      {
85          boolean allowContinue = true;;
86          
87          if (RemoteClient.SC_REMOTE_CONN_NOHOST == code ||
88              RemoteClient.SC_REMOTE_CONN_TIMEOUT == code)
89          {
90              // If special error codes were returned, don't check the remote connection
91              // again for a short time. This is to ensure that if an endpoint is not
92              // currently available, we don't continually connect+timeout potentially
93              // 100's of times in a row therefore slowing the server startup etc. 
94              endpointTimeouts.put(endpoint, System.currentTimeMillis());
95              allowContinue = false;
96          }
97          
98          return allowContinue;
99      }
100 }