001package org.apache.commons.jcs3.auxiliary.remote.http.client; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import org.apache.commons.jcs3.auxiliary.AbstractAuxiliaryCacheFactory; 023import org.apache.commons.jcs3.auxiliary.AuxiliaryCache; 024import org.apache.commons.jcs3.auxiliary.AuxiliaryCacheAttributes; 025import org.apache.commons.jcs3.auxiliary.remote.RemoteCacheNoWait; 026import org.apache.commons.jcs3.auxiliary.remote.behavior.IRemoteCacheClient; 027import org.apache.commons.jcs3.auxiliary.remote.http.client.behavior.IRemoteHttpCacheClient; 028import org.apache.commons.jcs3.auxiliary.remote.server.behavior.RemoteType; 029import org.apache.commons.jcs3.engine.behavior.ICompositeCacheManager; 030import org.apache.commons.jcs3.engine.behavior.IElementSerializer; 031import org.apache.commons.jcs3.engine.logging.behavior.ICacheEventLogger; 032import org.apache.commons.jcs3.log.Log; 033import org.apache.commons.jcs3.log.LogManager; 034import org.apache.commons.jcs3.utils.config.OptionConverter; 035 036/** 037 * The RemoteCacheFactory creates remote caches for the cache hub. It returns a no wait facade which 038 * is a wrapper around a no wait. The no wait object is either an active connection to a remote 039 * cache or a balking zombie if the remote cache is not accessible. It should be transparent to the 040 * clients. 041 */ 042public class RemoteHttpCacheFactory 043 extends AbstractAuxiliaryCacheFactory 044{ 045 /** The logger */ 046 private static final Log log = LogManager.getLog( RemoteHttpCacheFactory.class ); 047 048 /** Monitor thread instance */ 049 private RemoteHttpCacheMonitor monitor; 050 051 /** 052 * For LOCAL clients we get a handle to all the failovers, but we do not register a listener 053 * with them. We create the RemoteCacheManager, but we do not get a cache. 054 * <p> 055 * The failover runner will get a cache from the manager. When the primary is restored it will 056 * tell the manager for the failover to deregister the listener. 057 * <p> 058 * @param iaca 059 * @param cacheMgr 060 * @param cacheEventLogger 061 * @param elementSerializer 062 * @return AuxiliaryCache 063 */ 064 @Override 065 public <K, V> AuxiliaryCache<K, V> createCache( final AuxiliaryCacheAttributes iaca, final ICompositeCacheManager cacheMgr, 066 final ICacheEventLogger cacheEventLogger, final IElementSerializer elementSerializer ) 067 { 068 final RemoteHttpCacheAttributes rca = (RemoteHttpCacheAttributes) iaca; 069 070 // TODO, use the configured value. 071 rca.setRemoteType( RemoteType.LOCAL ); 072 073 final RemoteHttpClientListener<K, V> listener = new RemoteHttpClientListener<>( rca, cacheMgr, elementSerializer ); 074 075 final IRemoteHttpCacheClient<K, V> remoteService = createRemoteHttpCacheClientForAttributes(rca); 076 077 final IRemoteCacheClient<K, V> remoteCacheClient = 078 new RemoteHttpCache<>( rca, remoteService, listener, monitor ); 079 remoteCacheClient.setCacheEventLogger( cacheEventLogger ); 080 remoteCacheClient.setElementSerializer( elementSerializer ); 081 082 final RemoteCacheNoWait<K, V> remoteCacheNoWait = new RemoteCacheNoWait<>( remoteCacheClient ); 083 remoteCacheNoWait.setCacheEventLogger( cacheEventLogger ); 084 remoteCacheNoWait.setElementSerializer( elementSerializer ); 085 086 return remoteCacheNoWait; 087 } 088 089 /** 090 * This is an extension point. The manager and other classes will only create 091 * RemoteHttpCacheClient through this method. 092 093 * @param cattr the cache configuration 094 * @return the client instance 095 */ 096 protected <V, K> IRemoteHttpCacheClient<K, V> createRemoteHttpCacheClientForAttributes(final RemoteHttpCacheAttributes cattr) 097 { 098 IRemoteHttpCacheClient<K, V> remoteService = OptionConverter.instantiateByClassName( cattr 099 .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}