View Javadoc

1   package org.apache.jcs.auxiliary.remote;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.Serializable;
23  import java.util.ArrayList;
24  import java.util.HashMap;
25  import java.util.StringTokenizer;
26  
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  import org.apache.jcs.auxiliary.AuxiliaryCache;
30  import org.apache.jcs.auxiliary.AuxiliaryCacheAttributes;
31  import org.apache.jcs.auxiliary.AuxiliaryCacheFactory;
32  import org.apache.jcs.auxiliary.remote.server.behavior.RemoteType;
33  import org.apache.jcs.engine.behavior.ICache;
34  import org.apache.jcs.engine.behavior.ICompositeCacheManager;
35  import org.apache.jcs.engine.behavior.IElementSerializer;
36  import org.apache.jcs.engine.logging.behavior.ICacheEventLogger;
37  
38  /**
39   * The RemoteCacheFactory creates remote caches for the cache hub. It returns a no wait facade which
40   * is a wrapper around a no wait. The no wait object is either an active connection to a remote
41   * cache or a balking zombie if the remote cache is not accessible. It should be transparent to the
42   * clients.
43   */
44  public class RemoteCacheFactory
45      implements AuxiliaryCacheFactory
46  {
47      /** The logger. */
48      private final static Log log = LogFactory.getLog( RemoteCacheFactory.class );
49  
50      /** The name of this auxiliary */
51      private String name;
52  
53      /** store reference of facades to initiate failover */
54      private final static HashMap<String, RemoteCacheNoWaitFacade<? extends Serializable, ? extends Serializable>> facades =
55          new HashMap<String, RemoteCacheNoWaitFacade<? extends Serializable, ? extends Serializable>>();
56  
57      /**
58       * For LOCAL clients we get a handle to all the failovers, but we do not register a listener
59       * with them. We create the RemoteCacheManager, but we do not get a cache.
60       * <p>
61       * The failover runner will get a cache from the manager. When the primary is restored it will
62       * tell the manager for the failover to deregister the listener.
63       * <p>
64       * @param iaca
65       * @param cacheMgr
66       * @param cacheEventLogger
67       * @param elementSerializer
68       * @return AuxiliaryCache
69       */
70      public <K extends Serializable, V extends Serializable> AuxiliaryCache<K, V> createCache(
71              AuxiliaryCacheAttributes iaca, ICompositeCacheManager cacheMgr,
72             ICacheEventLogger cacheEventLogger, IElementSerializer elementSerializer )
73      {
74          RemoteCacheAttributes rca = (RemoteCacheAttributes) iaca;
75  
76          ArrayList<ICache<K, V>> noWaits = new ArrayList<ICache<K, V>>();
77  
78          // if LOCAL
79          if ( rca.getRemoteType() == RemoteType.LOCAL )
80          {
81              // a list to be turned into an array of failover server information
82              ArrayList<String> failovers = new ArrayList<String>();
83  
84              // not necessary if a failover list is defined
85              // REGISTER PRIMARY LISTENER
86              // if it is a primary
87              boolean primayDefined = false;
88              if ( rca.getRemoteHost() != null )
89              {
90                  primayDefined = true;
91  
92                  failovers.add( rca.getRemoteHost() + ":" + rca.getRemotePort() );
93  
94                  RemoteCacheManager rcm = RemoteCacheManager.getInstance( rca, cacheMgr, cacheEventLogger,
95                                                                           elementSerializer );
96                  ICache<K, V> ic = rcm.getCache( rca );
97                  if ( ic != null )
98                  {
99                      noWaits.add( ic );
100                 }
101                 else
102                 {
103                     log.info( "noWait is null" );
104                 }
105             }
106 
107             // GET HANDLE BUT DONT REGISTER A LISTENER FOR FAILOVERS
108             String failoverList = rca.getFailoverServers();
109             if ( failoverList != null )
110             {
111                 StringTokenizer fit = new StringTokenizer( failoverList, "," );
112                 int fCnt = 0;
113                 while ( fit.hasMoreElements() )
114                 {
115                     fCnt++;
116 
117                     String server = (String) fit.nextElement();
118                     failovers.add( server );
119 
120                     rca.setRemoteHost( server.substring( 0, server.indexOf( ":" ) ) );
121                     rca.setRemotePort( Integer.parseInt( server.substring( server.indexOf( ":" ) + 1 ) ) );
122                     RemoteCacheManager rcm = RemoteCacheManager.getInstance( rca, cacheMgr, cacheEventLogger,
123                                                                              elementSerializer );
124                     // add a listener if there are none, need to tell rca what
125                     // number it is at
126                     if ( ( !primayDefined && fCnt == 1 ) || noWaits.size() <= 0 )
127                     {
128                         ICache<K, V> ic = rcm.getCache( rca );
129                         if ( ic != null )
130                         {
131                             noWaits.add( ic );
132                         }
133                         else
134                         {
135                             log.info( "noWait is null" );
136                         }
137                     }
138                 }
139                 // end while
140             }
141             // end if failoverList != null
142 
143             rca.setFailovers( failovers.toArray( new String[0] ) );
144 
145             // if CLUSTER
146         }
147         else if ( rca.getRemoteType() == RemoteType.CLUSTER )
148         {
149             // REGISTER LISTENERS FOR EACH SYSTEM CLUSTERED CACHEs
150             StringTokenizer it = new StringTokenizer( rca.getClusterServers(), "," );
151             while ( it.hasMoreElements() )
152             {
153                 // String server = (String)it.next();
154                 String server = (String) it.nextElement();
155                 // p( "tcp server = " + server );
156                 rca.setRemoteHost( server.substring( 0, server.indexOf( ":" ) ) );
157                 rca.setRemotePort( Integer.parseInt( server.substring( server.indexOf( ":" ) + 1 ) ) );
158                 RemoteCacheManager rcm = RemoteCacheManager.getInstance( rca, cacheMgr, cacheEventLogger,
159                                                                          elementSerializer );
160                 rca.setRemoteType( RemoteType.CLUSTER );
161                 ICache<K, V> ic = rcm.getCache( rca );
162                 if ( ic != null )
163                 {
164                     noWaits.add( ic );
165                 }
166                 else
167                 {
168                     log.info( "noWait is null" );
169                 }
170             }
171 
172         }
173         // end if CLUSTER
174 
175         @SuppressWarnings("unchecked") // No generic arrays in java
176         RemoteCacheNoWait<K, V>[] rcnwArray = noWaits.toArray( new RemoteCacheNoWait[0] );
177         RemoteCacheNoWaitFacade<K, V> rcnwf =
178             new RemoteCacheNoWaitFacade<K, V>(rcnwArray, rca, cacheMgr, cacheEventLogger, elementSerializer );
179 
180         getFacades().put( rca.getCacheName(), rcnwf );
181 
182         return rcnwf;
183     }
184 
185     // end createCache
186 
187     /**
188      * Gets the name attribute of the RemoteCacheFactory object
189      * @return The name value
190      */
191     public String getName()
192     {
193         return this.name;
194     }
195 
196     /**
197      * Sets the name attribute of the RemoteCacheFactory object
198      * @param name The new name value
199      */
200     public void setName( String name )
201     {
202         this.name = name;
203     }
204 
205     /**
206      * The facades are what the cache hub talks to.
207      * @return Returns the facades.
208      */
209     public static HashMap<String, RemoteCacheNoWaitFacade<? extends Serializable, ? extends Serializable>> getFacades()
210     {
211         return facades;
212     }
213 }