FileDocCategorySizeDatePackage
RestoPeerService.javaAPI DocExample12907Sun Jan 06 12:29:50 GMT 2002None

RestoPeerService.java

import java.io.*;
import java.util.*;
import java.net.URL;

import net.jxta.service.Service;
import net.jxta.peergroup.PeerGroup;
import net.jxta.peergroup.PeerGroupFactory;
import net.jxta.exception.PeerGroupException;
import net.jxta.document.AdvertisementFactory;
import net.jxta.document.StructuredDocumentFactory;
import net.jxta.document.Advertisement;
import net.jxta.document.Element;
import net.jxta.document.TextElement;
import net.jxta.document.MimeMediaType;
import net.jxta.document.StructuredDocument;
import net.jxta.document.StructuredTextDocument;
import net.jxta.discovery.DiscoveryService;
import net.jxta.pipe.PipeService;
import net.jxta.pipe.InputPipe;
import net.jxta.pipe.OutputPipe;
import net.jxta.pipe.PipeID;
import net.jxta.protocol.PipeAdvertisement;
import net.jxta.protocol.PeerGroupAdvertisement;
import net.jxta.protocol.ModuleImplAdvertisement;
import net.jxta.endpoint.Message;
import net.jxta.id.IDFactory;
import net.jxta.id.ID;

// The class RestoPeerService is an example of a PeerGroup Service.
// This service is registered as a RestoNet Peergroup service.
// This service implements the RestoPeer service for Chez JXTA.
public class RestoPeerService implements Service {


    // Service Module Spec Index ID
    public static String Module_Spec_ID =
        "jxta:uuid-737D1ED776B043E7A8718B102B62055A05";

    private String brand = "Chez JXTA";         // Brand of this restaurant
    private String specials = "large ($3.00)";  // Current restaurant Special

    private PeerGroup restoNet = null;   // The RestoNet Peergroup
    private PipeService pipes = null;    // Pipe service in the RestoNet

    private ModuleImplAdvertisement srvImpl = null;
    private PipeAdvertisement myAdv = null;  // My pipe advertisement
    private InputPipe pipeIn = null;         // Input pipe that we listening
                                             // to for requests
    private int rtimeout = 8000;             // Resolver pipe timeout

    // Service objects are not manipulated directly to protect usage
    //of the service. A Service interface is returned to access the service
    public Service getInterface() {
        return this;
    }

    // Returns the module impl advertisement for this service.
    public Advertisement getImplAdvertisement() {
        return srvImpl;
    }

    // Called when the peergroup initializes the service
    public void init(PeerGroup group, ID assignedID, Advertisement impl) {
        // Save the RestoNet pointer, the pipe and the RestoPeer Service
        restoNet = group;
        srvImpl = (ModuleImplAdvertisement) impl;
        System.out.println("Initialization RestoPeer Special Service: " +
                           srvImpl.getModuleSpecID());

        // Extract the service pipe advertisement from the service
        // module impl Advertisement. The client MUST use the same pipe
        // advertisement to talk to the service. When the client
        // discovers the peergroup advertisement, it will extract the
        // pipe advertisement to create the connecting pipe by getting
        // the module impl advertisement associated with the RestoPeer
        // service.
        System.out.println("Extract the pipe advertisement from the Service");
        PipeAdvertisement pipeadv = null;

        try {
            // Extract the pipe adv from the Module impl param section
            myAdv = (PipeAdvertisement)
                AdvertisementFactory.newAdvertisement((TextElement)
                      srvImpl.getParam().getChildren().nextElement());
        } catch (Exception e) {
            System.out.println("failed to read/parse pipe advertisement");
            e.printStackTrace();
            System.exit(-1);
        }

        // Start the RestoPeer service loop thread to respond to Hungry peers
        // fries requests. Start a new thread for processing all the
        // requests
        HandleFriesRequest peerRequest = new HandleFriesRequest();
        peerRequest.start();
    }

    // Called when the service is started
    public int startApp (String args[]) {
        // nothing to do here
        return 0;
    }

    // Called just before the service is stopped
    public void stopApp() {
    }

    // Thread to handle fries auction requests from HungryPeers.
    // The method waits for HungryPeer requests pipe messages to arrive.
    // Incoming requests contain a pipe advertisement to respond to the
    // HungryPeers requester and a fries size.
    // The method generates a bid offer for the request, opens an output
    // pipe to the HungryPeer requester and send the response.
    private class HandleFriesRequest extends Thread {

        InputStream ip = null;               // Input Stream of message
        PipeAdvertisement hungryPipe = null; // HungryPeer Requester pipe
        StructuredDocument request = null;   // Request document
        StructuredDocument bid = null;       // Bid response
        MimeMediaType mimeType = new MimeMediaType("text", "xml");
        Element el = null;                   // Element in document
        String name = null;                  // Name of the sender
        String size = null;                  // Fries size Requested
        OutputPipe pipeOut = null;           // Output pipe to respond to
                                             // HungryPeer requester

        public void run() {
            // Need to check that the Pipe peergroup service of
            // RestoNet is initialized. Peergroup services are loaded
            // dynamically. Here we just wait until the pipe service
            // is initialized so we can create a new pipe.
            try {
                while (pipes == null) {
                    Thread.sleep(2000);
                    pipes = restoNet.getPipeService();
                }

                // Create the input pipe to receive incoming request
                if (!createRestoPipe()) {
                    System.out.println(
                        "Aborting due to failure to create RestoPeer pipe");
                    return;
                }
            } catch (Exception ex) {
                    System.out.println(
                           "Exception while creating RestoPeer pipe");
                    return;
            }

            System.out.println("RestoNet Restaurant (" + brand +
                           ") waiting for HungryPeer requests");

            // Loop waiting for HungryPeer Requests
            while (true) {
                Message msg = null;          // incoming pipe message
                try {
                    // Block until a message arrive on the RestoPeer pipe
                    msg = pipeIn.waitForMessage();

                    // If message is null, discard message
                    if (msg == null) {
                        if (Thread.interrupted()) {
                            // We have been asked to stop
                            System.out.println("Abort: RestoPeer interrupted");
                            return;
                        }
                    }

                    // We received a message; extract the request
                    try {
                        // Extract the HungryPipe pipe information
                        // to reply to the sender
                        ip = msg.getElement("HungryPeerPipe").getStream();

                        // Construct the associated pipe advertisement
                        // via the AdvertisementFactory
                        hungryPipe = (PipeAdvertisement)
                        AdvertisementFactory.newAdvertisement(mimeType, ip);

                        // Extract the sender name and fries size requested
                        // building a StructuredDocument
                        ip = msg.getElement("Request").getStream();
                        request = StructuredDocumentFactory.
                                    newStructuredDocument(mimeType, ip);

                        // Extract the fields from the structured Document
                        Enumeration enum = request.getChildren();

                        // Loop over all the elements of the document
                        while (enum.hasMoreElements()) {
                            el = (Element) enum.nextElement();
                            String attr = (String) el.getKey();
                            String value = (String) el.getValue();

                            // Extract the HungryPeer Requester Name
                            if (attr.equals("Name")) {
                                name = value;
                                continue;
                            }

                            // Extract the Fries  size requested
                            if (attr.equals("Fries")) {
                                size = value;
                                continue;
                            }
                        }
                    } catch (Exception e) {
                        // Broken Content
                        continue;
                    }

                    System.out.println("Received Request from HungryPeer "
                               + name + " for " + size + " Fries.");

                    // The auction request is valid. We can
                    // create the output pipe to send the response bid to
                    // the HungryPeer requester
                    try {
                        System.out.println(
                           "Attempting to create Output Pipe to HungryPeer " +
                            name);

                        // Create an output pipe connection to the HungryPeer
                        // requester
                        pipeOut = pipes.createOutputPipe(hungryPipe, rtimeout);
                        // Check if we have a pipe
                        if (pipeOut == null) {
                            // Cannot conect the pipe
                            System.out.println(
                                "Could not find HungryPeer pipe");
                            continue;
                        }
                    } catch (Exception e) {
                        // Pipe creation exception
                        System.out.println(
                            "HungryPeer may not be listening anymore");
                        continue;
                    }

                    // We have a pipe connection to the HungryPeer. Now
                    // create the bid response document
                    try {
                        bid = StructuredDocumentFactory.newStructuredDocument(
                                     mimeType, "RestoNet:Bid");

                        // Set the Bid values (Brand, price, special)
                        // in the response document
                        el = bid.createElement("Brand", brand);
                        bid.appendChild(el);
                        el = bid.createElement("Price", ""+ friesPrice(size));
                        bid.appendChild(el);
                        el = bid.createElement("Specials", specials);
                        bid.appendChild(el);

                        // Create a new pipe message
                        msg = pipes.createMessage();

                        // Add the Bid offer to the message
                        msg.addElement(msg.newMessageElement(
                                   "Bid", mimeType, bid.getStream()));

                        pipeOut.send(msg);
                        pipeOut.close();

                    } catch (Exception ex) {
                        System.out.println(
                            "Error sending bid offer to HungryPeer " + name);
                    }

                    System.out.println("Sent Bid Offer to HungryPeer ("
                        + name  + ") Fries price = "  + friesPrice(size) +
                        ", special = " + specials);
                } catch (Exception e) {
                    System.out.println("Abort RestoPeer interrupted");
                    return;
                }
            }
        }
    }

    // Determine the price of the French fries depending on the size
    private String friesPrice(String size) {
        if (size.equals("small"))
              return "$1.50";
        if (size.equals("medium"))
              return "2.50";
        if (size.equals("large"))
              return "3.00";
        return "error";
    }

    // Create the input endpoint
    private boolean createRestoPipe() {
        try {
            // Create my input pipe to listen for hungry peers
            // requests
            pipeIn = pipes.createInputPipe(myAdv);
        } catch (Exception e) {
            System.out.println(
                "Could not initialize the Restaurant pipe" + e.getMessage());
            return false;
        }
        return true;
    }
}