📄 discoveryserviceimpl.java
字号:
*/
public int startApp(String[] arg) {
// Now we know that the resolver is going to be there.
// The cm needs the resolver. The code is arranged so that
// until the resolver and the cm are created, we just pretend
// to be working. We have no requirement to be operational before
// startApp() is called, but we must tolerate our public methods
// being invoked. The reason for it is that services are registered
// upon return from init() so that other services startApp() methods
// can find them. (all startApp()s are called after all init()s - with
// a few exceptions).
resolver = group.getResolverService();
membership = group.getMembershipService();
resolver.registerHandler(handlerName, this);
try {
Enumeration enum = membership.getCurrentCredentials();
if (enum.hasMoreElements()) {
// get the only credential "nobody"
credential = (Credential)enum.nextElement();
credentialDoc = credential.getDocument(textXml);
}
} catch (Exception e) {
if (LOG.isEnabledFor(Priority.ERROR)) {
LOG.error("failed to get credential", e );
}
}
return 0;
}
/**
* Ask this service to stop.
*
* dettach from the resolver
*
*/
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, 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.ERROR)) {
LOG.error("Error during creation of local store", e);
}
throw new PeerGroupException( "Error during creation of local store : " + e.getMessage() );
}
// 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,
INFINITE_LIFETIME,
DEFAULT_EXPIRATION );
} catch (Exception ignoring ) {
if (LOG.isEnabledFor(Priority.WARN)) {
LOG.warn("Could not publish local eer advertisement: ", ignoring );
}
}
}
/**
* flushs stored Advertisement(s),
*
*@param id Document ID, Peer ID, or PeerGroup ID, a null value
* flushs all content of type "type"
*@param type Discovery type PEER, GROUP, ADV
*@exception IOException - If an I/O error occurs
*@since JXTA 1.0
*/
public void flushAdvertisements(String id, int type)
throws IOException {
if ((type <= ADV) && (id != null)) {
ID advID = IDFactory.fromURL( IDFactory.jxtaURL( 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(textXml);
} 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);
}
/**
* Remote Publish an advertisement will attempt to remote publish adv on all
* configured transports, the Advertisement will carry a lifetime of
* Expiration time, or lifetime whichever is smaller
*
*@param type Discovery type PEER, GROUP, ADV
*@param adv advertisement to publish
*@since JXTA 1.0
*/
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(textXml, 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(textXml,
new ByteArrayInputStream(str.getBytes()));
if (adv != null) {
publish(adv, res.getDiscoveryType(), exp, exp);
}
} catch (Exception e) {
if (LOG.isEnabledFor(Priority.DEBUG)) {
LOG.debug("Error publishing Advertisement", 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 thrown if the query is malformed
* @exception IOException thrown when an ioexption occurs during search
* @exception ResendQueryException thrown when no responces is generated, and to indicate repropagation
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -