View Javadoc
1   package org.apache.commons.jcs3.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.jcs3.auxiliary.AbstractAuxiliaryCacheFactory;
23  import org.apache.commons.jcs3.auxiliary.AuxiliaryCache;
24  import org.apache.commons.jcs3.auxiliary.AuxiliaryCacheAttributes;
25  import org.apache.commons.jcs3.auxiliary.remote.RemoteCacheNoWait;
26  import org.apache.commons.jcs3.auxiliary.remote.behavior.IRemoteCacheClient;
27  import org.apache.commons.jcs3.auxiliary.remote.http.client.behavior.IRemoteHttpCacheClient;
28  import org.apache.commons.jcs3.auxiliary.remote.server.behavior.RemoteType;
29  import org.apache.commons.jcs3.engine.behavior.ICompositeCacheManager;
30  import org.apache.commons.jcs3.engine.behavior.IElementSerializer;
31  import org.apache.commons.jcs3.engine.logging.behavior.ICacheEventLogger;
32  import org.apache.commons.jcs3.log.Log;
33  import org.apache.commons.jcs3.log.LogManager;
34  import org.apache.commons.jcs3.utils.config.OptionConverter;
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 = LogManager.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( final AuxiliaryCacheAttributes iaca, final ICompositeCacheManager cacheMgr,
66                                         final ICacheEventLogger cacheEventLogger, final IElementSerializer elementSerializer )
67      {
68          final RemoteHttpCacheAttributes rca = (RemoteHttpCacheAttributes) iaca;
69  
70          // TODO, use the configured value.
71          rca.setRemoteType( RemoteType.LOCAL );
72  
73          final RemoteHttpClientListener<K, V> listener = new RemoteHttpClientListener<>( rca, cacheMgr, elementSerializer );
74  
75          final IRemoteHttpCacheClient<K, V> remoteService = createRemoteHttpCacheClientForAttributes(rca);
76  
77          final IRemoteCacheClient<K, V> remoteCacheClient =
78                  new RemoteHttpCache<>( rca, remoteService, listener, monitor );
79          remoteCacheClient.setCacheEventLogger( cacheEventLogger );
80          remoteCacheClient.setElementSerializer( elementSerializer );
81  
82          final RemoteCacheNoWait<K, V> remoteCacheNoWait = new RemoteCacheNoWait<>( 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(final RemoteHttpCacheAttributes cattr)
97      {
98          IRemoteHttpCacheClient<K, V> remoteService = OptionConverter.instantiateByClassName( cattr
99                          .getRemoteHttpClientClassName(), null );
100 
101         if ( remoteService == null )
102         {
103             log.info( "Creating the default client for {0}",
104                     cattr::getCacheName);
105             remoteService = new RemoteHttpCacheClient<>();
106         }
107 
108         remoteService.initialize( cattr );
109         return remoteService;
110     }
111 
112     /**
113      * @see org.apache.commons.jcs3.auxiliary.AbstractAuxiliaryCacheFactory#initialize()
114      */
115     @Override
116     public void initialize()
117     {
118         super.initialize();
119         monitor = new RemoteHttpCacheMonitor(this);
120         monitor.setDaemon(true);
121         monitor.start();
122     }
123 
124     /**
125      * @see org.apache.commons.jcs3.auxiliary.AbstractAuxiliaryCacheFactory#dispose()
126      */
127     @Override
128     public void dispose()
129     {
130         if (monitor != null)
131         {
132             monitor.notifyShutdown();
133             try
134             {
135                 monitor.join(5000);
136             }
137             catch (final InterruptedException e)
138             {
139                 // swallow
140             }
141             monitor = null;
142         }
143 
144         super.dispose();
145     }
146 }