📄 discoveryserviceimpl.java
字号:
}
/**
* Ask this service to stop.
*
* dettach from the resolver
*
* @since
*/
public void stopApp() {
// Check resolver in case someone calls stop before start
if ( resolver != null
&& resolver.unregisterHandler(handlerName) == null) {
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("failed to unregister discovery from resolver.");
}
}
/**
* init is called by PeerGroup to init the Service.
*
* @param pg Peer Group
* @param sadv Description of Parameter
* @since
* @throws PeerGroupException throw any exception thrown during obtaining
* Service
*/
public void init(PeerGroup pg, ID assignedID, Advertisement impl)
throws PeerGroupException {
implAdvertisement = (ModuleImplAdvertisement) impl;
group = pg;
handlerName = assignedID.toString();
localPeerId = group.getPeerID().toString();
localPeerAdvStr = advToString(group.getPeerAdvertisement());
// Keep track of the changes in the rdv status. An easy to find
// clue that we must update our expensive-to-make string version
// of the peeradv.
lastIsRdv = group.isRendezvous();
// By creating the cm here we make it possible to find local advs
// even before startApp was called. The price to pay is that the
// initial round of expiration will not be published because the resolver
// is not there yet. However not being able to find local advs realy
// hurts the router in the early phase, so...
try {
String pgdir =
group.getPeerGroupID().getUniqueValue().toString();
cm = new Cm(pgdir,
new Cm.ExpirationListener() {
public void expired(String dn,
String fn,
long timeout) {
int type = -1;
if (dn.equals(dirname[GROUP])) {
type = GROUP;
} else if (dn.equals(dirname[PEER])) {
type = PEER;
} else if (dn.equals(dirname[ADV])) {
type = ADV;
}
if (type != -1) {
try {
String restoredAdv;
restoredAdv =
new String(cm.restoreBytes(dn,
fn));
remotePublish(restoredAdv,
type,
timeout);
} catch (IOException e) {
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("Cannot restore " + dn + "/" + fn, e);
}
}
}
},
// enable index
true);
String [] pElements = {"Name", "PID"};
String [] gElements = {"Name", "GID", "Desc"};
String [] aElements = {"Name", "Id", "MSID", "RdvGroupId"};
cm.createFolder( dirname[PEER], pElements);
cm.createFolder(dirname[GROUP], gElements);
cm.createFolder( dirname[ADV], aElements);
} catch (Exception e) {
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("Error during creation of local store", e);
}
// Publish the local Peer Advertisement
try {
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("publishing local advertisement");
// This is our own; we can publish it for a long time in our cache
publish(group.getPeerAdvertisement(), PEER,
DEFAULT_LIFETIME, DEFAULT_EXPIRATION);
} catch (Exception e) {
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("Error when publishing local peer advertisement: ", e);
}
}
/**
* flush cached peer Advertisements.
*
* @param id Description of Parameter
* @param type Description of Parameter
* @exception IOException Description of Exception
* @since
*/
public void flushAdvertisements(String id, int type)
throws IOException {
if ((type <= ADV) && (id != null)) {
//added
System.out.println("DiscoveryServiceImpl: id = " + id);
ID advID = IDFactory.fromURL( new URL( id ) );
//added
System.out.println("DiscoveryServiceImpl: new URL(id) = " + new URL(id));
String advName = advID.getUniqueValue().toString();
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("flushing adv " + advName + " of type " + dirname[type]);
cm.remove(dirname[type], advName );
} else {
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("flushing advertisements of type " + dirname[type]);
String[] fn = cm.getFileNames(dirname[type]);
for (int i = 0; i < fn.length; i++) {
cm.remove(dirname[type], fn[i]);
}
}
}
/**
* Publish an advertisement with a default lifetime of <code>
* DEFAULT_LIFETIME</code> and default expiration time for "others"
* of <code>DEFAULT_EXPIRATION</code>
*
*@param advertisement publish an adverisement within this group
*@param type Discovery type PEER, GROUP, ADV
*@exception IOException - If an I/O error occurs
*@since JXTA 1.0
*/
public void publish(Advertisement adv, int type)
throws IOException {
publish(adv,
type,
DiscoveryService.DEFAULT_LIFETIME,
DiscoveryService.DEFAULT_EXPIRATION);
}
/**
* Publish an advertisement that will expire after a certain time. A
* node that finds this advertisement will hold it for about <i>
* lifetimeForOthers</i> milliseconds, while the peer that has
* originally published the advertisement will republish it about every
* <i>lifetiemForOthers</i> milliseconds, until <i>lifetime</i>
* expires.
*
* @param type Discovery type PEER, GROUP, ADV
* @param lifetime the amount of time this advertisement will
* live in my cache
* @param lifetimeForOthers the amount of time this advertisement will
* live in other people's caches.
* @param adv advertisement to publish
* @exception IOException If an I/O error occurs
*/
public void publish(Advertisement adv,
int type,
long timeoutForMe,
long timeoutForOthers)
throws IOException {
ID advID = null;
String advName = null;
advID = adv.getID();
if (advID != null && advID.equals( ID.nullID )) advID = null;
StructuredDocument doc;
try {
doc = (StructuredDocument) adv.getDocument(
new MimeMediaType("text/xml"));
} catch (Exception everything) {
throw new IOException
("Advertisement couldnt be saved because of :"
+ everything.toString());
}
// if we dont have a unique id for the adv, use the hash method
if( advID == null )
advName = cm.createTmpName(doc);
else
advName = advID.getUniqueValue().toString();
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("publishing " + advName + " in " + dirname[type]);
// save it
cm.save(dirname[type],
advName,
doc,
timeoutForMe,
timeoutForOthers);
}
/**
* Description of the Method
*
* @param adv Description of Parameter
* @param type Description of Parameter
* @since
*/
public void remotePublish(Advertisement adv, int type) {
remotePublish(adv, type, DiscoveryService.DEFAULT_EXPIRATION);
}
/**
* Remote Publish an advertisement will attempt to remote publish
* adv on all configured transports, the Advertisement will carry a
* lifetime of Expiration time
*
*@param type Discovery type PEER, GROUP, ADV
*@param adv advertisement to publish
*@since JXTA 1.0
*/
public void remotePublish(Advertisement adv, int type, long timeout) {
remotePublish(advToString(adv), type, timeout);
}
/**
* deal with incoming responses for discovery
*
* @param response
*/
public void processResponse(ResolverResponseMsg response) {
DiscoveryResponse res;
try {
res = new DiscoveryResponse(
new ByteArrayInputStream(
(response.getResponse()).getBytes()));
} catch (Exception e) {
// we don't understand this msg, let's skip it
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug(e);
return;
}
PeerAdvertisement padv;
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("Got a " + dirname[res.getDiscoveryType()] + " response : " +
res.getQueryAttr() + " = " + res.getQueryValue());
try {
String aRes = (String) res.getPeerAdv();
InputStream is = new ByteArrayInputStream((aRes).getBytes());
padv = (PeerAdvertisement)
AdvertisementFactory.newAdvertisement(
new MimeMediaType("text/xml"), is);
if (padv != null) {
// The sender does not put an expiration on that one, but
// we do not want to keep it around for more than the
// default duration. It may get updated or become invalid.
publish(padv, PEER, DEFAULT_EXPIRATION, DEFAULT_EXPIRATION);
}
} catch (Exception e) {
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug(e);
return;
}
Advertisement adv;
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("getting responses");
Enumeration enum = res.getResponses();
Enumeration exps = res.getExpirations();
String str;
long exp;
if (enum != null) {
while (enum.hasMoreElements()) {
str = (String) enum.nextElement();
exp = ((Long) exps.nextElement()).longValue();
if (exp > 0) {
try {
adv = (Advertisement)
AdvertisementFactory.newAdvertisement
(new MimeMediaType("text/xml"),
new ByteArrayInputStream
(str.getBytes()));
if (adv != null) {
publish(adv, res.getDiscoveryType(), exp, exp);
}
} catch (Exception e) {
}
}
}
}
DiscoveryEvent newevent =
new DiscoveryEvent(this, res, response.getQueryId());
DiscoveryListener dl = (DiscoveryListener)
listenerTable.get(new Integer(response.getQueryId()));
if (dl != null)
dl.discoveryEvent(new DiscoveryEvent(this, res, response.getQueryId()));
// are there any registered discovery listeners,
// generate the event and callback.
if (listeners.size() > 0) {
for (int i = 0; i < listeners.size(); i++) {
dl = (DiscoveryListener) listeners.elementAt(i);
dl.discoveryEvent(newevent);
}
}
}
/**
* Handler API method
*
* @param query GenericResolverMsg
* @return ResolverResponseMsg response
* @exception DiscardQueryException Description of Exception
* @exception IOException Description of Exception
* @exception ResendQueryException Description of Exception
* @since
* @NoResponseException thrown when no response is generated
* @throws NoResponseException if no Responses were received
*/
public ResolverResponseMsg processQuery(ResolverQueryMsg query)
throws NoResponseException,
DiscardQueryException,
IOException,
ResendQueryException {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -