1 /***
2 * Copyright 2003-2010 Terracotta, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package net.sf.ehcache.distribution;
18
19 import net.sf.ehcache.CacheException;
20 import net.sf.ehcache.CacheManager;
21 import net.sf.ehcache.Ehcache;
22
23 import java.net.MalformedURLException;
24 import java.rmi.Naming;
25 import java.rmi.NotBoundException;
26 import java.rmi.RemoteException;
27 import java.util.Collections;
28 import java.util.Date;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35
36 /***
37 * A provider of Peer RMI addresses.
38 *
39 * @author Greg Luck
40 * @version $Id: RMICacheManagerPeerProvider.html 13146 2011-08-01 17:12:39Z oletizi $
41 */
42 public abstract class RMICacheManagerPeerProvider implements CacheManagerPeerProvider {
43
44 private static final Logger LOG = LoggerFactory.getLogger(RMICacheManagerPeerProvider.class.getName());
45
46 /***
47 * Contains a RMI URLs of the form: "//" + hostName + ":" + port + "/" + cacheName;
48 */
49 protected final Map peerUrls = Collections.synchronizedMap(new HashMap());
50
51 /***
52 * The CacheManager this peer provider is associated with.
53 */
54 protected CacheManager cacheManager;
55
56
57 /***
58 * Constructor
59 *
60 * @param cacheManager
61 */
62 public RMICacheManagerPeerProvider(CacheManager cacheManager) {
63 this.cacheManager = cacheManager;
64 }
65
66 /***
67 * Empty constructor
68 */
69 public RMICacheManagerPeerProvider() {
70
71 }
72
73
74 /***
75 * {@inheritDoc}
76 */
77 public abstract void init();
78
79
80 /***
81 * Register a new peer
82 *
83 * @param rmiUrl
84 */
85 public abstract void registerPeer(String rmiUrl);
86
87
88
89 /***
90 * Gets the cache name out of the url
91 * @param rmiUrl
92 * @return the cache name as it would appear in ehcache.xml
93 */
94 static String extractCacheName(String rmiUrl) {
95 return rmiUrl.substring(rmiUrl.lastIndexOf('/') + 1);
96 }
97
98 /***
99 * Unregisters a peer
100 *
101 * @param rmiUrl
102 */
103 public final synchronized void unregisterPeer(String rmiUrl) {
104 peerUrls.remove(rmiUrl);
105 }
106
107 /***
108 * @return a list of {@link net.sf.ehcache.distribution.CachePeer} peers for the given cache, excluding the local peer.
109 */
110 public abstract List listRemoteCachePeers(Ehcache cache) throws CacheException;
111
112 /***
113 * Whether the entry should be considered stale. This will depend on the type of RMICacheManagerPeerProvider.
114 * <p/>
115 * @param date the date the entry was created
116 * @return true if stale
117 */
118 protected abstract boolean stale(Date date);
119
120
121 /***
122 * The use of one-time registry creation and Naming.rebind should mean we can create as many listeneres as we like.
123 * They will simply replace the ones that were there.
124 */
125 public CachePeer lookupRemoteCachePeer(String url) throws MalformedURLException, NotBoundException, RemoteException {
126 LOG.debug("Lookup URL {}", url);
127 CachePeer cachePeer = (CachePeer) Naming.lookup(url);
128 return cachePeer;
129 }
130
131 /***
132 * Providers may be doing all sorts of exotic things and need to be able to clean up on dispose.
133 *
134 * @throws net.sf.ehcache.CacheException
135 */
136 public void dispose() throws CacheException {
137
138 }
139
140 /***
141 * The cacheManager this provider is bound to
142 */
143 public final CacheManager getCacheManager() {
144 return cacheManager;
145 }
146
147 /***
148 * The replication scheme. Each peer provider has a scheme name, which can be used to specify
149 * the scheme for replication and bootstrap purposes. Each <code>CacheReplicator</code> should lookup
150 * the provider for its scheme type during replication. Similarly a <code>BootstrapCacheLoader</code>
151 * should also look up the provider for its scheme.
152 * <p/>
153 * @since 1.6 introduced to permit multiple distribution schemes to be used in the same CacheManager
154 * @return the well-known scheme name, which is determined by the replication provider author.
155 */
156 public String getScheme() {
157 return "RMI";
158 }
159 }