KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > cruisecontrol > distributed > util > MulticastDiscovery


1 /****************************************************************************
2 * CruiseControl, a Continuous Integration Toolkit
3 * Copyright (c) 2001, ThoughtWorks, Inc.
4 * 651 W Washington Ave. Suite 600
5 * Chicago, IL 60661 USA
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * + Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * + Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
19 *
20 * + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
21 * names of its contributors may be used to endorse or promote
22 * products derived from this software without specific prior
23 * written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
29 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 ****************************************************************************/

37
38 package net.sourceforge.cruisecontrol.distributed.util;
39
40 import java.io.IOException JavaDoc;
41 import java.rmi.RemoteException JavaDoc;
42 import java.util.Arrays JavaDoc;
43
44 import net.jini.core.lookup.ServiceTemplate;
45 import net.jini.core.lookup.ServiceItem;
46 import net.jini.core.lookup.ServiceRegistrar;
47 import net.jini.core.discovery.LookupLocator;
48 import net.jini.core.entry.Entry;
49 import net.jini.lease.LeaseRenewalManager;
50 import net.jini.discovery.LookupDiscovery;
51 import net.jini.discovery.LookupDiscoveryManager;
52 import net.jini.lookup.ServiceDiscoveryManager;
53 import net.jini.lookup.LookupCache;
54 import net.jini.lookup.ServiceDiscoveryEvent;
55 import net.jini.lookup.ServiceDiscoveryListener;
56 import net.jini.lookup.ServiceItemFilter;
57 import net.sourceforge.cruisecontrol.distributed.BuildAgentService;
58 import net.sourceforge.cruisecontrol.distributed.PropertyEntry;
59
60 import org.apache.log4j.Logger;
61
62 public class MulticastDiscovery {
63
64     private static final Logger LOG = Logger.getLogger(MulticastDiscovery.class);
65
66     private final ServiceTemplate serviceTemplate;
67     private final ServiceDiscoveryManager clientMgr;
68     private final LookupCache lookupCache;
69
70     public MulticastDiscovery(final Entry[] entries) {
71         this(LookupDiscovery.ALL_GROUPS, null, BuildAgentService.class, entries);
72     }
73
74     public MulticastDiscovery(final String JavaDoc[] lookupGroups, final LookupLocator[] unicastLocaters,
75                               final Class JavaDoc klass, final Entry[] entries) {
76         LOG.debug("Starting multicast discovery for groups: " + lookupGroups);
77         ReggieUtil.setupRMISecurityManager();
78
79         try {
80
81             final LookupDiscoveryManager discoverMgr = new LookupDiscoveryManager(
82                 lookupGroups, unicastLocaters, null);
83
84             clientMgr = new ServiceDiscoveryManager(discoverMgr, new LeaseRenewalManager());
85         } catch (IOException JavaDoc e) {
86             final String JavaDoc message = "Error starting discovery";
87             LOG.debug(message, e);
88             throw new RuntimeException JavaDoc(message, e);
89         }
90
91         // create cache of desired _service providers
92
final Class JavaDoc[] classes = new Class JavaDoc[] {klass};
93         serviceTemplate = new ServiceTemplate(null, classes, entries);
94         try {
95             lookupCache = getClientManager().createLookupCache(
96                     getServiceTemplate(), null, new ServiceDiscListener(this));
97         } catch (RemoteException JavaDoc e) {
98             final String JavaDoc message = "Error creating _service cache";
99             LOG.debug(message, e);
100             throw new RuntimeException JavaDoc(message, e);
101         }
102
103 // elsewhere, do lookup for service if we don't use a cache
104
//
105
// ServiceItem item = null;
106
// // Try to find the _service, blocking till timeout if necessary
107
// item = _clientMgr.lookup(template,
108
// null, /* no filter */
109
// WAITFOR /* timeout */);
110

111     }
112
113     /** Only for use by JiniLookUpUtility and InteractiveBuilder. **/
114     public ServiceRegistrar[] getRegistrars() {
115         //@todo remove ?
116
return getClientManager().getDiscoveryManager().getRegistrars();
117     }
118
119
120     private ServiceTemplate getServiceTemplate() {
121         return serviceTemplate;
122     }
123
124     private ServiceDiscoveryManager getClientManager() {
125         return clientMgr;
126     }
127
128     /** Intended only for use by util classes. */
129     LookupCache getLookupCache() {
130         return lookupCache;
131     }
132
133     public ServiceItem findMatchingService() throws RemoteException JavaDoc {
134         return findMatchingService(true);
135     }
136     public ServiceItem findMatchingService(final boolean doClaim) throws RemoteException JavaDoc {
137         final ServiceItem result = getLookupCache().lookup(FLTR_AVAILABLE);
138         if (doClaim && result != null) {
139             ((BuildAgentService) result.service).claim();
140         }
141         return result;
142     }
143
144     static final BuildAgentFilter FLTR_AVAILABLE = new BuildAgentFilter(true);
145     static final BuildAgentFilter FLTR_ANY = new BuildAgentFilter(false);
146
147     static final class BuildAgentFilter implements ServiceItemFilter {
148         private final boolean findOnlyNonBusy;
149
150         private BuildAgentFilter(final boolean onlyNonBusy) {
151             findOnlyNonBusy = onlyNonBusy;
152         }
153
154         public boolean check(final ServiceItem item) {
155
156             LOG.debug("Service Filter: item.service: " + item.service);
157             if (!(item.service instanceof BuildAgentService)) {
158                 return false;
159             }
160
161             final BuildAgentService agent = (BuildAgentService) item.service;
162             // read agent machine name to make sure agent is still valid
163
final String JavaDoc agentMachine;
164             try {
165                 agentMachine = agent.getMachineName();
166             } catch (RemoteException JavaDoc e) {
167                 final String JavaDoc msg = "Error reading agent machine name. Filtering out agent.";
168                 LOG.debug(msg, e);
169                 return false; // filter out this agent by returning false
170
}
171
172             if (!findOnlyNonBusy) {
173                 return true; // we don't care if agent is busy or not
174
}
175
176             try {
177                 return !agent.isBusy();
178             } catch (RemoteException JavaDoc e) {
179                 final String JavaDoc msg = "Error checking agent busy status. Filtering out agent on machine: "
180                         + agentMachine;
181                 LOG.debug(msg, e);
182                 return false; // filter out this agent by returning false
183
}
184         }
185     }
186
187     public void terminate() {
188         if (getClientManager() != null) {
189             getClientManager().terminate();
190         }
191     }
192
193
194
195     private boolean isDiscovered;
196     private synchronized void setDiscovered(final boolean discovered) {
197         isDiscovered = discovered;
198     }
199     public synchronized boolean isDiscovered() {
200         return isDiscovered;
201     }
202
203     public final class ServiceDiscListener implements ServiceDiscoveryListener {
204         private final MulticastDiscovery discovery;
205
206         private ServiceDiscListener(final MulticastDiscovery discovery) {
207             this.discovery = discovery;
208         }
209
210         private String JavaDoc buildDiscoveryMsg(final ServiceDiscoveryEvent event, final String JavaDoc actionName) {
211             String JavaDoc msg = "\nService " + actionName + ": ";
212
213             final ServiceItem postItem = event.getPostEventServiceItem();
214             if (postItem != null) {
215                 msg = toStringServiceItem(postItem, msg + "PostEvent: ");
216             } else {
217                 final ServiceItem preItem = event.getPreEventServiceItem();
218                 if (preItem != null) {
219                     msg = toStringServiceItem(preItem, msg + "PreEvent: ");
220                 } else {
221                     msg += "NOT SURE WHAT THIS EVENT IS!!!";
222                 }
223             }
224             return msg;
225         }
226
227         public void serviceAdded(final ServiceDiscoveryEvent event) {
228             discovery.setDiscovered(true);
229             LOG.info(buildDiscoveryMsg(event, "Added"));
230         }
231
232         public void serviceRemoved(final ServiceDiscoveryEvent event) {
233             discovery.setDiscovered(false);
234             LOG.info(buildDiscoveryMsg(event, "Removed"));
235         }
236
237         public void serviceChanged(final ServiceDiscoveryEvent event) {
238             LOG.info(buildDiscoveryMsg(event, "Changed"));
239         }
240     }
241
242
243     public static String JavaDoc toStringServiceItem(final ServiceItem serviceItem, String JavaDoc msgPrefix) {
244         msgPrefix += serviceItem.service.getClass().toString() + "; ID:" + serviceItem.serviceID
245                 + toStringEntries(serviceItem.attributeSets);
246         return msgPrefix;
247     }
248
249     public static String JavaDoc toStringEntries(final Entry[] entries) {
250         return "\n\tEntries:\n\t"
251                 + Arrays.asList(entries).toString().replaceAll("\\), ", "\\), \n\t")
252                     .replaceAll(PropertyEntry.class.getName(), "")
253                 + "\n";
254     }
255 }
256
Popular Tags