1 /**
2 * Copyright 2003-2007 Greg Luck
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
18 package net.sf.ehcache.distribution;
19
20 import net.sf.ehcache.CacheException;
21 import net.sf.ehcache.Ehcache;
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24
25 import java.rmi.NotBoundException;
26 import java.util.ArrayList;
27 import java.util.Date;
28 import java.util.Iterator;
29 import java.util.List;
30
31 /**
32 * A provider of Peer RMI addresses based off manual configuration.
33 * <p/>
34 * Because there is no monitoring of whether a peer is actually there, the list of peers is dynamically
35 * looked up and verified each time a lookup request is made.
36 * <p/>
37 * @author Greg Luck
38 * @version $Id: ManualRMICacheManagerPeerProvider.java 512 2007-07-10 09:18:45Z gregluck $
39 */
40 public final class ManualRMICacheManagerPeerProvider extends RMICacheManagerPeerProvider {
41
42 private static final Log LOG = LogFactory.getLog(ManualRMICacheManagerPeerProvider.class.getName());
43
44 /**
45 * Empty constructor.
46 */
47 public ManualRMICacheManagerPeerProvider() {
48 super();
49 }
50
51 /**
52 * {@inheritDoc}
53 */
54 public final void init() {
55 //nothing to do here
56 }
57
58 /**
59 * Time for a cluster to form. This varies considerably, depending on the implementation.
60 *
61 * @return the time in ms, for a cluster to form
62 */
63 public long getTimeForClusterToForm() {
64 return 0;
65 }
66
67 /**
68 * Register a new peer.
69 *
70 * @param rmiUrl
71 */
72 public final synchronized void registerPeer(String rmiUrl) {
73 peerUrls.put(rmiUrl, new Date());
74 }
75
76
77 /**
78 * @return a list of {@link CachePeer} peers, excluding the local peer.
79 */
80 public final synchronized List listRemoteCachePeers(Ehcache cache) throws CacheException {
81 List remoteCachePeers = new ArrayList();
82 List staleList = new ArrayList();
83 for (Iterator iterator = peerUrls.keySet().iterator(); iterator.hasNext();) {
84 String rmiUrl = (String) iterator.next();
85 String rmiUrlCacheName = extractCacheName(rmiUrl);
86 try {
87 if (!rmiUrlCacheName.equals(cache.getName())) {
88 continue;
89 }
90 Date date = (Date) peerUrls.get(rmiUrl);
91 if (!stale(date)) {
92 CachePeer cachePeer = lookupRemoteCachePeer(rmiUrl);
93 remoteCachePeers.add(cachePeer);
94 } else {
95 if (LOG.isDebugEnabled()) {
96 LOG.debug("rmiUrl " + rmiUrl + " is stale. Either the remote peer is shutdown or the " +
97 "network connectivity has been interrupted. Will be removed from list of remote cache peers");
98 }
99 staleList.add(rmiUrl);
100 }
101 } catch (NotBoundException e) {
102 if (LOG.isDebugEnabled()) {
103 LOG.debug("No cache peer bound to URL at " + rmiUrl
104 + ". It must have disappeared since the last heartbeat");
105 }
106 } catch (Exception exception) {
107 LOG.error(exception.getMessage(), exception);
108 throw new CacheException("Unable to list remote cache peers. Error was " + exception.getMessage());
109 }
110 }
111
112 //Remove any stale remote peers. Must be done here to avoid concurrent modification exception.
113 for (int i = 0; i < staleList.size(); i++) {
114 String rmiUrl = (String) staleList.get(i);
115 peerUrls.remove(rmiUrl);
116 }
117 return remoteCachePeers;
118 }
119
120
121 /**
122 * Whether the entry should be considered stale.
123 * <p/>
124 * Manual RMICacheManagerProviders use a static list of urls and are therefore never stale.
125 *
126 * @param date the date the entry was created
127 * @return true if stale
128 */
129 protected final boolean stale(Date date) {
130 return false;
131 }
132
133 }