JXTA DiscoveryServer.javaのシーケンス図

jxta-src-2.4.1/tutorials/discovery/DiscoveryServer.javaを理解してみよう……(とりあえず今日はこれぐらいで…orz)



(修正版)

シーケンス図の書き方微妙に知らない…結構適当に書いたんで,適当に参考にするぐらいがいいだろう.
DiscoveryServer.java

package tutorial.discovery;

import java.util.Enumeration;
import net.jxta.discovery.DiscoveryEvent;
import net.jxta.discovery.DiscoveryListener;
import net.jxta.discovery.DiscoveryService;
import net.jxta.document.Advertisement;
import net.jxta.document.AdvertisementFactory;
import net.jxta.id.IDFactory;
import net.jxta.peergroup.PeerGroup;
import net.jxta.peergroup.PeerGroupID;
import net.jxta.pipe.PipeService;
import net.jxta.protocol.DiscoveryResponseMsg;
import net.jxta.protocol.PeerGroupAdvertisement;
import net.jxta.protocol.PipeAdvertisement;
import tutorial.network.NetworkManager;


public class DiscoveryServer implements DiscoveryListener {

    private transient static PeerGroup netPeerGroup = null;
    private transient static PeerGroupAdvertisement groupAdvertisement = null;
    private transient NetworkManager manager;
    private transient DiscoveryService discovery;

    /**
     * Constructor for the DiscoveryServer
     */
    public DiscoveryServer() {
        manager = new NetworkManager("DiscoveryServer");
        manager.start("principal", "password");
        //Get the NetPeerGroup
        netPeerGroup = manager.getNetPeerGroup();
        // get the discovery service
        discovery = netPeerGroup.getDiscoveryService();
        // obtain our group advertisement
        groupAdvertisement = netPeerGroup.getPeerGroupAdvertisement();
    }

    /**
     *  main
     *
     * @param  args  command line args
     */
    public static void main(String args[]) {
        DiscoveryServer disocveryServer = new DiscoveryServer();
        disocveryServer.start();
    }

    /**
     * create a new pipe adv, publish it for 2 minut network time, 
     * sleep for 3 minutes, then repeat
     * 
     */
    public void start() {
        long lifetime = 60 * 2 * 1000L;
        long expiration = 60 * 2 * 1000L;
        long waittime = 60 * 3 * 1000L;

        try {
            while (true) {
                PipeAdvertisement pipeAdv = getPipeAdvertisement();
                //このadvはpipeID(defaultNetPeerGroupID),pipetype(PipeService.UnicastType),Name("Discovery tutorial")
                // publish the advertisement with a lifetime of 2 mintutes
                System.out.println("Publishing the following advertisement with lifetime :"+lifetime+" expiration :"+expiration);
                System.out.println(pipeAdv.toString());//XMLが表示される
                discovery.publish(pipeAdv, lifetime, expiration);
                //ローカルに公開する
                //Publish an Advertisement. The Advertisement will expire automatically after the specified time. 
                //A peer that discovers this advertisement will hold it for about expiration or lifetime milliseconds, whichever is smaller.
                discovery.remotePublish(pipeAdv, expiration);
                //リモートに公開する
                //Publish an Advertisement to another peer on the network. This does not result in the advertisement being stored locally. 
                //The Advertisement will be published with an expiration time of DEFAULT_EXPIRATION.
                try {
                    System.out.println("Sleeping for :"+waittime);
                    Thread.sleep(waittime);//このスレッドはスリープする
                } catch (Exception e) {}
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * This method is called whenever a discovery response is received, which are
     * either in response to a query we sent, or a remote publish by another node
     *
     * @param  ev  the discovery event
     */
    public void discoveryEvent(DiscoveryEvent ev) {

        DiscoveryResponseMsg res = ev.getResponse();
        // let's get the responding peer's advertisement
        System.out.println(" [  Got a Discovery Response [" +
                res.getResponseCount() + " elements]  from peer : " + ev.getSource() + "  ]");

        Advertisement adv = null;
        Enumeration en = res.getAdvertisements();
        if (en != null) {
            while (en.hasMoreElements()) {
                adv = (Advertisement) en.nextElement();
                System.out.println(adv);
            }
        }
    }
    /**
     * Creates a pipe advertisement
     *
     * @return    a Pipe Advertisement
     */
    public static PipeAdvertisement getPipeAdvertisement() {
        PipeAdvertisement advertisement = (PipeAdvertisement)
                                          AdvertisementFactory.newAdvertisement(PipeAdvertisement.getAdvertisementType());
        advertisement.setPipeID(IDFactory.newPipeID(PeerGroupID.defaultNetPeerGroupID));
        advertisement.setType(PipeService.UnicastType);
        advertisement.setName("Discovery tutorial");
        return advertisement;
    }

    /**
     * Stops the platform
     */
    public void stop() {
        //Stop JXTA
        manager.stop();
    }
}

NetworkManager.java

package tutorial.network;

import java.io.File;
import java.io.IOException;
import java.net.URI;

import net.jxta.credential.AuthenticationCredential;
import net.jxta.credential.Credential;
import net.jxta.document.Advertisement;
import net.jxta.exception.PeerGroupException;
import net.jxta.id.IDFactory;
import net.jxta.impl.membership.pse.StringAuthenticator;
import net.jxta.membership.InteractiveAuthenticator;
import net.jxta.membership.MembershipService;
import net.jxta.platform.NetworkConfigurator;
import net.jxta.peergroup.PeerGroup;
import net.jxta.peergroup.NetPeerGroupFactory;
import net.jxta.peergroup.PeerGroupID;
import net.jxta.protocol.ConfigParams;
import net.jxta.rendezvous.RendezvousEvent;
import net.jxta.rendezvous.RendezvousListener;
import net.jxta.rendezvous.RendezVousService;

/**
 *  A simple and re-usable exmaple of starting and stopping a JXTA platform
 *
 * @author     Mohamed Abdelaziz (hamada)
 * @created    December 17, 2005
 */

public class NetworkManager implements RendezvousListener {

    private PeerGroup netPeerGroup = null;
    private boolean started = false;
    private boolean stopped = false;
    private RendezVousService rendezvous;
    private final static String connectLock = new String("connectLock");
    private String instanceName = "NA";//インスタンスの名前
    private final static File home = new File(System.getProperty("JXTA_HOME", ".cache"));

    /**
     *  A simple and re-usable exmaple of starting and stopping a JXTA platform
     *
     * @param  instanceName  Node name
     * @param  home          Cache storage home directory
     */
    public NetworkManager(String instanceName) {
        this.instanceName = instanceName;
    }

    /**
     *  Creates and starts the JXTA NetPeerGroup using a platform configuration
     *  template. This class also registers a listener for rendezvous events
     *
     * @param  principal  principal used the generate the self signed peer root cert
     * @param  password   the root cert password
     */
    public synchronized void start(String principal, String password) {
        if (started) {//既にスタートしている場合
            return;
        }
        try {
            File instanceHome = new File(home, instanceName);//homeはJXTAのキャッシュ等を指している.
            //instanceNameは現在”NA”が与えられている.
            NetworkConfigurator config = new NetworkConfigurator();
            config.setHome(instanceHome);
            //Set the current directory for configuration and cache persistent store
            
            if (!config.exists()) {//configが生成できれば…config(NetworkConfigurator)の設定
                config.setPeerID(IDFactory.newPeerID(PeerGroupID.defaultNetPeerGroupID));
                //Set the PeerID (by default, a new PeerID is generated).
                config.setName(instanceName);
                // Sets the node name
                config.setDescription("Created by Network Manager");
                //Sets PlaformConfig Peer Description element
                config.setMode(NetworkConfigurator.EDGE_NODE);
                //Sets the current node configuration mode.
                config.setPrincipal(principal);
                //Sets the Principal for the peer root certificate
                config.setPassword(password);
                //Sets the password used to sign the private key of the root certificate
                try {
                    config.addRdvSeedingURI(new URI("http://rdv.jxtahosts.net/cgi-bin/rendezvous.cgi?2"));
                    //Sets Rendezvous Seeding URI
                    config.addRelaySeedingURI(new URI("http://rdv.jxtahosts.net/cgi-bin/relays.cgi?2"));
                    //Sets the RelayService Seeding URI
                } catch (java.net.URISyntaxException use) {
                    use.printStackTrace();
                }
                try {
                    config.save();//Persists a PlatformConfig advertisement under getHome()+"/PlaformConfig"
                } catch (IOException io) {
                    io.printStackTrace();
                }
            }
            // create, and Start the default jxta NetPeerGroup
            NetPeerGroupFactory factory  = new NetPeerGroupFactory((ConfigParams) config.getPlatformConfig(), instanceHome.toURI());
            //A factory for instantiating a Network Peer Group instances. 
            //The Network Peer Group is the base peer group for applications and services within the JXTA network.
            //Most applications and services will instantiate their own peer groups using the Network Peer Group as a base.
            netPeerGroup = factory.getInterface();
            //Returns a strong (reference counted) interface object for the Net Peer Group instance.
            System.out.println("Node PeerID :"+netPeerGroup.getPeerID().getUniqueValue().toString());
            //peerGroupのpeerID(ユニークな値)を表示する
            rendezvous = netPeerGroup.getRendezVousService();
            // Return the Rendezvous Service for this Peer Group.
            rendezvous.addListener(this);
            //Add a listener for RendezVousEvents.
            //rendezvous is "The RendezVous Service provides propagation of messages within a JXTA PeerGroup."↓
            //While the internal protcol of diffusion is left to the implementation of the service,
            //the JXTA RendezVous Service defines a subscription mechanism allowing JXTA peers to receive propagated messages
            //(clients of the service) or become a repeater of the service (rendezvous peers).
            started = true;//start作業は完了
        } catch (PeerGroupException e) {
            // could not instantiate the group, print the stack and exit
            System.out.println("fatal error : group creation failure");
            e.printStackTrace();
            System.exit(1);
        }
    }

    /**
     *  Establishes group credential.  This is a required step when planning to
     *  to utilize TLS messegers or secure pipes
     *
     * @param  group      peer group to establish credentials in
     * @param  principal  the principal
     * @param  password   pass word
     */
    public static void login(PeerGroup group, String principal, String password) {
        try {
            StringAuthenticator auth = null;
            MembershipService membership = group.getMembershipService();
            Credential cred = membership.getDefaultCredential();
            if (cred == null) {
                AuthenticationCredential authCred = new AuthenticationCredential(group, "StringAuthentication", null);
                try {
                    auth = (StringAuthenticator) membership.apply(authCred);
                } catch (Exception failed) {
                    ;
                }

                if (auth != null) {
                    auth.setAuth1_KeyStorePassword(password.toCharArray());
                    auth.setAuth2Identity(group.getPeerID());
                    auth.setAuth3_IdentityPassword(principal.toCharArray());
                    if (auth.isReadyForJoin()) {
                        membership.join(auth);
                    }
                }
            }

            cred = membership.getDefaultCredential();
            if (null == cred) {
                AuthenticationCredential authCred = new AuthenticationCredential(group, "InteractiveAuthentication", null);
                InteractiveAuthenticator iAuth = (InteractiveAuthenticator) membership.apply(authCred);
                if (iAuth.interact() && iAuth.isReadyForJoin()) {
                    membership.join(iAuth);
                }
            }
        } catch (Throwable e) {
            // make sure output buffering doesn't wreck console display.
            System.err.println("Uncaught Throwable caught by 'main':");
            e.printStackTrace();
            System.exit(1);
        } finally {
            System.err.flush();
            System.out.flush();
        }
    }

    /**
     *  Stops and unrefrences the NetPeerGroup
     */
    public synchronized void stop() {
        if (stopped && !started) {
            return;
        }
        rendezvous.removeListener(this);
        netPeerGroup.stopApp();
        netPeerGroup.unref();
        netPeerGroup = null;
        stopped = true;
    }

    /**
     *  Gets the netPeerGroup object
     *
     * @return    The netPeerGroup value
     */
    public PeerGroup getNetPeerGroup() {
        return netPeerGroup;
    }

    /**
     * Blocks if not connected to a rendezvous, or
     * until a connection to rendezvous node occurs
     *
     * @param  timeout  timeout in milliseconds
     */
    public void waitForRendezvousConncection(long timeout) {
        if (!rendezvous.isConnectedToRendezVous() || !rendezvous.isRendezVous()) {
            System.out.println("Waiting for Rendezvous Connection");
            try {
                if (!rendezvous.isConnectedToRendezVous()) {
                    synchronized (connectLock) {
                        connectLock.wait(timeout);
                    }
                }
                System.out.println("Connected to Rendezvous");
            } catch (InterruptedException e) {}
        }
    }

    /**
     *  rendezvousEvent the rendezvous event
     *
     * @param  event  rendezvousEvent
     */
    public void rendezvousEvent(RendezvousEvent event) {
        if (event.getType() == event.RDVCONNECT ||
            event.getType() == event.RDVRECONNECT ||
            event.getType() == event.BECAMERDV) {
            switch(event.getType()) {
            case RendezvousEvent.RDVCONNECT :
                System.out.println("Connected to rendezvous peer :"+event.getPeerID());
                break;
            case RendezvousEvent.RDVRECONNECT :
                System.out.println("Reconnected to rendezvous peer :"+event.getPeerID());
                break;
            case RendezvousEvent.BECAMERDV :
                System.out.println("Became a Rendezvous");
                break;
            }
            synchronized (connectLock) {
                connectLock.notify();
            }
        }
    }

    /**
     *  Main method
     *
     * @param  args  none defined
     */
    public static void main(String args[]) {
        NetworkManager manager = new NetworkManager("Network Manager");
        System.out.println("Starting NetworkManager ....");
        manager.start("principal", "password");
        PeerGroup netPG = manager.getNetPeerGroup();
        manager.waitForRendezvousConncection(10000);
        System.out.println("Good Bye ....");
        manager.stop();
    }
}