]> sjero.net Git - linphone/blob - p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/rendezvous/adhoc/AdhocPeerRdvService.java
8d7b0d376c501aa64e81595f281122adaa5da5f5
[linphone] / p2pproxy / dependencies-src / jxse-src-2.5 / impl / src / net / jxta / impl / rendezvous / adhoc / AdhocPeerRdvService.java
1 /*
2  * Copyright (c) 2001-2007 Sun Microsystems, Inc.  All rights reserved.
3  *  
4  *  The Sun Project JXTA(TM) Software License
5  *  
6  *  Redistribution and use in source and binary forms, with or without 
7  *  modification, are permitted provided that the following conditions are met:
8  *  
9  *  1. Redistributions of source code must retain the above copyright notice,
10  *     this list of conditions and the following disclaimer.
11  *  
12  *  2. Redistributions in binary form must reproduce the above copyright notice, 
13  *     this list of conditions and the following disclaimer in the documentation 
14  *     and/or other materials provided with the distribution.
15  *  
16  *  3. The end-user documentation included with the redistribution, if any, must 
17  *     include the following acknowledgment: "This product includes software 
18  *     developed by Sun Microsystems, Inc. for JXTA(TM) technology." 
19  *     Alternately, this acknowledgment may appear in the software itself, if 
20  *     and wherever such third-party acknowledgments normally appear.
21  *  
22  *  4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must 
23  *     not be used to endorse or promote products derived from this software 
24  *     without prior written permission. For written permission, please contact 
25  *     Project JXTA at http://www.jxta.org.
26  *  
27  *  5. Products derived from this software may not be called "JXTA", nor may 
28  *     "JXTA" appear in their name, without prior written permission of Sun.
29  *  
30  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
31  *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
32  *  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SUN 
33  *  MICROSYSTEMS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
34  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
35  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
36  *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
37  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
38  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
39  *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  *  
41  *  JXTA is a registered trademark of Sun Microsystems, Inc. in the United 
42  *  States and other countries.
43  *  
44  *  Please see the license information page at :
45  *  <http://www.jxta.org/project/www/license.html> for instructions on use of 
46  *  the license in source files.
47  *  
48  *  ====================================================================
49  *  
50  *  This software consists of voluntary contributions made by many individuals 
51  *  on behalf of Project JXTA. For more information on Project JXTA, please see 
52  *  http://www.jxta.org.
53  *  
54  *  This license is based on the BSD license adopted by the Apache Foundation. 
55  */
56
57 package net.jxta.impl.rendezvous.adhoc;
58
59
60 import net.jxta.document.Advertisement;
61 import net.jxta.document.AdvertisementFactory;
62 import net.jxta.document.XMLDocument;
63 import net.jxta.endpoint.EndpointAddress;
64 import net.jxta.endpoint.Message;
65 import net.jxta.endpoint.Messenger;
66 import net.jxta.id.ID;
67 import net.jxta.impl.protocol.RdvConfigAdv;
68 import net.jxta.impl.rendezvous.RendezVousPropagateMessage;
69 import net.jxta.impl.rendezvous.RendezVousServiceImpl;
70 import net.jxta.impl.rendezvous.RendezVousServiceProvider;
71 import net.jxta.impl.rendezvous.rendezvousMeter.RendezvousMeterBuildSettings;
72 import net.jxta.logging.Logging;
73 import net.jxta.peergroup.PeerGroup;
74 import net.jxta.platform.Module;
75 import net.jxta.protocol.ConfigParams;
76 import net.jxta.rendezvous.RendezvousEvent;
77
78 import java.io.IOException;
79 import java.util.Enumeration;
80 import java.util.Vector;
81 import java.util.logging.Level;
82 import java.util.logging.Logger;
83
84
85 /**
86  * A JXTA {@link net.jxta.rendezvous.RendezVousService} implementation which
87  * implements the ad hoc portion of the standard JXTA Rendezvous Protocol (RVP).
88  *
89  * @see net.jxta.rendezvous.RendezVousService
90  * @see <a href="https://jxta-spec.dev.java.net/nonav/JXTAProtocols.html#proto-rvp" target="_blank">JXTA Protocols Specification : Rendezvous Protocol</a>
91  */
92 public class AdhocPeerRdvService extends RendezVousServiceProvider {
93
94     /**
95      * Log4J Logger
96      */
97     private final static transient Logger LOG = Logger.getLogger(AdhocPeerRdvService.class.getName());
98
99     /**
100      * Default Maximum TTL. This is minimum needed to bridge networks.
101      */
102     private static final int DEFAULT_MAX_TTL = 2;
103
104     /**
105      * Constructor
106      *
107      * @param g          the peergroup
108      * @param rdvService the rendezvous service
109      */
110     public AdhocPeerRdvService(PeerGroup g, RendezVousServiceImpl rdvService) {
111
112         super(g, rdvService);
113
114         ConfigParams confAdv = g.getConfigAdvertisement();
115
116         // Get the config. If we do not have a config, we're done; we just keep
117         // the defaults (edge peer/no auto-rdv)
118         if (confAdv != null) {
119             Advertisement adv = null;
120
121             try {
122                 XMLDocument configDoc = (XMLDocument) confAdv.getServiceParam(rdvService.getAssignedID());
123
124                 if (null != configDoc) {
125                     // XXX 20041027 backwards compatibility
126                     configDoc.addAttribute("type", RdvConfigAdv.getAdvertisementType());
127
128                     adv = AdvertisementFactory.newAdvertisement(configDoc);
129                 }
130             } catch (java.util.NoSuchElementException ignored) {// ignored
131             }
132
133             if (adv instanceof RdvConfigAdv) {
134                 RdvConfigAdv rdvConfigAdv = (RdvConfigAdv) adv;
135
136                 MAX_TTL = (-1 != rdvConfigAdv.getMaxTTL()) ? rdvConfigAdv.getMaxTTL() : DEFAULT_MAX_TTL;
137             } else {
138                 MAX_TTL = DEFAULT_MAX_TTL;
139             }
140         } else {
141             MAX_TTL = DEFAULT_MAX_TTL;
142         }
143
144         if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {
145             LOG.info("RendezVous Service is initialized for " + g.getPeerGroupID() + " as an ad hoc peer. ");
146         }
147     }
148
149     /**
150      * {@inheritDoc}
151      */
152     @Override
153     protected int startApp(String[] arg) {
154
155         super.startApp(arg);
156
157         // The other services may not be fully functional but they're there
158         // so we can start our subsystems.
159         // As for us, it does not matter if our methods are called between init
160         // and startApp().
161
162         if (RendezvousMeterBuildSettings.RENDEZVOUS_METERING && (rendezvousMeter != null)) {
163             rendezvousMeter.startEdge();
164         }
165
166         // we are nominally an edge peer
167         rdvService.generateEvent(RendezvousEvent.BECAMEEDGE, group.getPeerID());
168
169         return Module.START_OK;
170     }
171
172     /**
173      * {@inheritDoc}
174      */
175     @Override
176     public synchronized void stopApp() {
177
178         if (closed) {
179             return;
180         }
181
182         closed = true;
183
184         super.stopApp();
185
186         if (RendezvousMeterBuildSettings.RENDEZVOUS_METERING && (rendezvousMeter != null)) {
187             rendezvousMeter.stopEdge();
188         }
189     }
190
191     /**
192      * {@inheritDoc}
193      */
194     @Override
195     public Vector<ID> getConnectedPeerIDs() {
196
197         return new Vector<ID>(0);
198     }
199
200     /**
201      * {@inheritDoc}
202      */
203     @Override
204     public boolean isConnectedToRendezVous() {
205         // It's as connected as it's ever going to get....
206         return true;
207     }
208
209     /**
210      * {@inheritDoc}
211      */
212     @Override
213     public void connectToRendezVous(EndpointAddress addr, Object hint) throws IOException {
214
215         throw new UnsupportedOperationException("Not supported by ad hoc");
216     }
217
218     /**
219      * {@inheritDoc}
220      */
221     @Override
222     public void challengeRendezVous(ID peer, long delay) {
223
224         throw new UnsupportedOperationException("Not supported by ad hoc");
225     }
226
227     /**
228      * {@inheritDoc}
229      */
230     @Override
231     public void disconnectFromRendezVous(ID peerId) {
232
233         throw new UnsupportedOperationException("Not supported by ad hoc");
234     }
235
236     /**
237      * {@inheritDoc}
238      */
239     @Override
240     public void propagate(Message msg, String serviceName, String serviceParam, int ttl) throws IOException {
241
242         ttl = Math.min(ttl, MAX_TTL);
243
244         RendezVousPropagateMessage propHdr = updatePropHeader(msg, getPropHeader(msg), serviceName, serviceParam, ttl);
245
246         if (null != propHdr) {
247             sendToNetwork(msg, propHdr);
248
249             if (RendezvousMeterBuildSettings.RENDEZVOUS_METERING && (rendezvousMeter != null)) {
250                 rendezvousMeter.propagateToGroup();
251             }
252         }
253     }
254
255     /**
256      * {@inheritDoc}
257      */
258     @Override
259     public void propagateInGroup(Message msg, String serviceName, String serviceParam, int ttl) throws IOException {
260
261         ttl = Math.min(ttl, MAX_TTL);
262
263         RendezVousPropagateMessage propHdr = updatePropHeader(msg, getPropHeader(msg), serviceName, serviceParam, ttl);
264
265         if (null != propHdr) {
266             sendToNetwork(msg, propHdr);
267
268             if (RendezvousMeterBuildSettings.RENDEZVOUS_METERING && (rendezvousMeter != null)) {
269                 rendezvousMeter.propagateToGroup();
270             }
271         }
272     }
273
274     /**
275      * {@inheritDoc}
276      */
277     @Override
278     public void propagate(Enumeration<? extends ID> destPeerIDs, Message msg, String serviceName, String serviceParam, int ttl) {
279
280         ttl = Math.min(ttl, MAX_TTL);
281
282         RendezVousPropagateMessage propHdr = updatePropHeader(msg, getPropHeader(msg), serviceName, serviceParam, ttl);
283
284         if (null != propHdr) {
285             int numPeers = 0;
286
287             try {
288                 while (destPeerIDs.hasMoreElements()) {
289                     ID dest = destPeerIDs.nextElement();
290
291                     if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
292                         LOG.fine("Sending " + msg + " to client " + dest);
293                     }
294
295                     EndpointAddress addr = mkAddress(dest, PropSName, PropPName);
296
297                     Messenger messenger = rdvService.endpoint.getMessenger(addr);
298
299                     if (null != messenger) {
300                         try {
301                             messenger.sendMessage(msg);
302                             numPeers++;
303                         } catch (IOException failed) {// ignored
304                         }
305                     }
306                 }
307             } finally {
308                 if (RendezvousMeterBuildSettings.RENDEZVOUS_METERING && (rendezvousMeter != null)) {
309                     rendezvousMeter.propagateToPeers(numPeers);
310                 }
311             }
312         }
313     }
314
315     /**
316      * {@inheritDoc}
317      */
318     @Override
319     public void propagateToNeighbors(Message msg, String serviceName, String serviceParam, int ttl) throws IOException {
320
321         ttl = Math.min(ttl, MAX_TTL);
322
323         RendezVousPropagateMessage propHdr = updatePropHeader(msg, getPropHeader(msg), serviceName, serviceParam, ttl);
324
325         if (null != propHdr) {
326             try {
327                 sendToNetwork(msg, propHdr);
328
329                 if (RendezvousMeterBuildSettings.RENDEZVOUS_METERING && (rendezvousMeter != null)) {
330                     rendezvousMeter.propagateToNeighbors();
331                 }
332             } catch (IOException failed) {
333                 if (RendezvousMeterBuildSettings.RENDEZVOUS_METERING && (rendezvousMeter != null)) {
334                     rendezvousMeter.propagateToNeighborsFailed();
335                 }
336
337                 throw failed;
338             }
339         }
340     }
341
342     /**
343      * {@inheritDoc}
344      * <p/>
345      * The definition of walk says that we should forward the message to the
346      * most appropriate peer. Since we don't make any effort keep track of other
347      * peers we don't have anywhere to send the message.
348      */
349     @Override
350     public void walk(Message msg, String serviceName, String serviceParam, int ttl) throws IOException {
351         // Do nothing. Really.
352     }
353
354     /**
355      * {@inheritDoc}
356      * <p/>
357      * Unlike the undirected walk we are told where to send the message so we
358      * deliver it as requested.
359      */
360     @Override
361     public void walk(Vector<? extends ID> destPeerIDs, Message msg, String serviceName, String serviceParam, int ttl) throws IOException {
362
363         propagate(destPeerIDs.elements(), msg, serviceName, serviceParam, ttl);
364     }
365
366     /**
367      * {@inheritDoc}
368      */
369     @Override
370     protected void repropagate(Message msg, RendezVousPropagateMessage propHdr, String serviceName, String serviceParam) {
371
372         if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
373             LOG.fine("Repropagating " + msg + " (" + propHdr.getMsgId() + ")");
374         }
375
376         if (RendezvousMeterBuildSettings.RENDEZVOUS_METERING && (rendezvousMeter != null)) {
377             rendezvousMeter.receivedMessageRepropagatedInGroup();
378         }
379
380         try {
381             propHdr = updatePropHeader(msg, propHdr, serviceName, serviceParam, MAX_TTL);
382
383             if (null != propHdr) {
384                 sendToNetwork(msg, propHdr);
385             } else {
386                 if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
387                     LOG.fine("No propagate header, declining to repropagate " + msg + ")");
388                 }
389             }
390         } catch (Exception ez1) {
391             // Not much we can do
392             if (Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) {
393                 if (propHdr != null) {
394                     LOG.log(Level.WARNING, "Failed to repropagate " + msg + " (" + propHdr.getMsgId() + ")", ez1);
395                 } else {
396                     LOG.log(Level.WARNING, "Could to repropagate " + msg, ez1);
397                 }
398             }
399         }
400     }
401 }