View Javadoc
1   package org.apache.commons.jcs.auxiliary.remote.http.client;
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 org.apache.commons.jcs.auxiliary.AbstractAuxiliaryCacheFactory;
23  import org.apache.commons.jcs.auxiliary.AuxiliaryCache;
24  import org.apache.commons.jcs.auxiliary.AuxiliaryCacheAttributes;
25  import org.apache.commons.jcs.auxiliary.remote.RemoteCacheNoWait;
26  import org.apache.commons.jcs.auxiliary.remote.behavior.IRemoteCacheClient;
27  import org.apache.commons.jcs.auxiliary.remote.http.client.behavior.IRemoteHttpCacheClient;
28  import org.apache.commons.jcs.auxiliary.remote.server.behavior.RemoteType;
29  import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
30  import org.apache.commons.jcs.engine.behavior.IElementSerializer;
31  import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
32  import org.apache.commons.jcs.utils.config.OptionConverter;
33  import org.apache.commons.logging.Log;
34  import org.apache.commons.logging.LogFactory;
35  
36  /**
37   * The RemoteCacheFactory creates remote caches for the cache hub. It returns a no wait facade which
38   * is a wrapper around a no wait. The no wait object is either an active connection to a remote
39   * cache or a balking zombie if the remote cache is not accessible. It should be transparent to the
40   * clients.
41   */
42  public class RemoteHttpCacheFactory
43      extends AbstractAuxiliaryCacheFactory
44  {
45      /** The logger */
46      private static final Log log = LogFactory.getLog( RemoteHttpCacheFactory.class );
47  
48      /** Monitor thread instance */
49      private RemoteHttpCacheMonitor monitor;
50  
51      /**
52       * For LOCAL clients we get a handle to all the failovers, but we do not register a listener
53       * with them. We create the RemoteCacheManager, but we do not get a cache.
54       * <p>
55       * The failover runner will get a cache from the manager. When the primary is restored it will
56       * tell the manager for the failover to deregister the listener.
57       * <p>
58       * @param iaca
59       * @param cacheMgr
60       * @param cacheEventLogger
61       * @param elementSerializer
62       * @return AuxiliaryCache
63       */
64      @Override
65      public <K, V> AuxiliaryCache<K, V> createCache( AuxiliaryCacheAttributes iaca, ICompositeCacheManager cacheMgr,
66                                         ICacheEventLogger cacheEventLogger, IElementSerializer elementSerializer )
67      {
68          RemoteHttpCacheAttributes rca = (RemoteHttpCacheAttributes) iaca;
69  
70          // TODO, use the configured value.
71          rca.setRemoteType( RemoteType.LOCAL );
72  
73          RemoteHttpClientListener<K, V> listener = new RemoteHttpClientListener<K, V>( rca, cacheMgr, elementSerializer );
74  
75          IRemoteHttpCacheClient<K, V> remoteService = createRemoteHttpCacheClientForAttributes(rca);
76  
77          IRemoteCacheClient<K, V> remoteCacheClient =
78                  new RemoteHttpCache<K, V>( rca, remoteService, listener, monitor );
79          remoteCacheClient.setCacheEventLogger( cacheEventLogger );
80          remoteCacheClient.setElementSerializer( elementSerializer );
81  
82          RemoteCacheNoWait<K, V> remoteCacheNoWait = new RemoteCacheNoWait<K, V>( remoteCacheClient );
83          remoteCacheNoWait.setCacheEventLogger( cacheEventLogger );
84          remoteCacheNoWait.setElementSerializer( elementSerializer );
85  
86          return remoteCacheNoWait;
87      }
88  
89      /**
90       * This is an extension point. The manager and other classes will only create
91       * RemoteHttpCacheClient through this method.
92  
93       * @param cattr the cache configuration
94       * @return the client instance
95       */
96      protected <V, K> IRemoteHttpCacheClient<K, V> createRemoteHttpCacheClientForAttributes(RemoteHttpCacheAttributes cattr)
97      {
98          IRemoteHttpCacheClient<K, V> remoteService = OptionConverter.instantiateByClassName( cattr
99                          .getRemoteHttpClientClassName(), null );
100 
101         if ( remoteService == null )
102         {
103             if ( log.isInfoEnabled() )
104             {
105                 log.info( "Creating the default client for " + cattr.getCacheName());
106             }
107             remoteService = new RemoteHttpCacheClient<K, V>( );
108         }
109 
110         remoteService.initialize( cattr );
111         return remoteService;
112     }
113 
114     /**
115      * @see org.apache.commons.jcs.auxiliary.AbstractAuxiliaryCacheFactory#initialize()
116      */
117     @Override
118     public void initialize()
119     {
120         super.initialize();
121         monitor = new RemoteHttpCacheMonitor(this);
122         monitor.setDaemon(true);
123         monitor.start();
124     }
125 
126     /**
127      * @see org.apache.commons.jcs.auxiliary.AbstractAuxiliaryCacheFactory#dispose()
128      */
129     @Override
130     public void dispose()
131     {
132         if (monitor != null)
133         {
134             monitor.notifyShutdown();
135             try
136             {
137                 monitor.join(5000);
138             }
139             catch (InterruptedException e)
140             {
141                 // swallow
142             }
143             monitor = null;
144         }
145 
146         super.dispose();
147     }
148 }