Hello3Client

The class starts with these imports. By now we have discussed all of these:


package org.jtrix.project.helloworld;

import org.jtrix.base.*;
import org.jtrix.facets1.util.io.IInputStream;
import org.jtrix.facets1.netlet.IBootstrapFacet;
import org.jtrix.project.libjtrix.io.FacetInputStreamWrapper;
import org.jtrix.project.libjtrix.netlet.NullService;

/** Bootstrap netlet which accesses a hello world service using a warrant
 * read from a bootstrap input stream. That stream is called "warrant-in".
 */
public class Hello3Client implements INetlet
{
    private INode _node;

Most of the INetlet methods are minimal. Even the initialise() method is tiny, although it does save the link to the node for reference later on:


    public byte[] initialise(INode node, Object bean, byte[] unsigned)
        throws InitialiseException
    {
        _node = node;
        return null;
    }

    public void terminate(long date, INetlet.IShutdownProgress progress)
    {
        // Nothing to clean up
    }

    public IService bindService(Warrant warrant, IService consumer)
        throws ServiceBindException
    {
        // No services for other netlets
        throw new ServiceBindException();
    }

It gets interesting around the other INetlet methods, because this is the first time we've offered a netlet facet. Our two methods tell the node what facet we offer, and deal with a request for it:


    /** Lets a node see what facets we offer it.
     * @return An array naming the one facet we do offer the node: the facet
     *     through which we can access the I/O streams at bootstrap time.
     */
    public String[] getFacets()
    {
        return new String[]{ IBootstrapFacet.class.getName() };
    }

    /** Allows the node to bind any facets we can offer it.
     * @param facet  The name of the facet the node wishes to bind.
     * @return  An interface giving the node access to that facet.
     */
    public IRemote bindFacet(String facet) throws FacetBindException
    {
        if (facet.equals(IBootstrapFacet.class.getName()))
        {
            return new FacetHandle(new WarrantReader(), facet);
        }
        else
        {
            throw new FacetBindException();
        }
    }

Notice, again, our use of FacetHandle. When the node binds our IBootstrapFacet we wrap the implenting object in a FacetHandle to help it through the mediation.

And here is the implementing class, the WarrantReader. The boot() method is called by the node which gives us an IManager, and from that we get the appropriate input stream containing the warrant:


    /**
     * Read a warrant from an input stream granted to us by the node when it
     * boots.
     */
    private class WarrantReader implements IBootstrapFacet
    {
        /** The longest the node can expect the boot method call to last.
         * @return  Number of milliseconds after which if the boot method
         *     has not finished the node can stop it itself.
         */
        public long getBootInvocationTimeout()
        {
            return (5*60*1000);
        }

        /** Use the bootstrap system to pick up the input stream named
         * "warrant-in".
         * @param mgr  The object that allows us to access the I/O streams.
         * @return  Success flag.
         */
        public boolean boot(IBootstrapFacet.IManager mgr)
        {
            try
            {
                // Read the warrant from the "warrant-in" bootstrap parameter

                IInputStream is = mgr.getInputStream("Warrant for service",
                                                     "warrant-in");
                Warrant warrant = new Warrant(new FacetInputStreamWrapper(is));

                // Use the warrant to bind the service, and then a facet
                // we know is in the service

                IService service = _node.bindService(warrant, new NullService());
                String hf_name = IHelloFacet.class.getName();
                IHelloFacet facet = (IHelloFacet)(service.bindFacet(hf_name));

                // Use the facet
                System.out.println(facet.getMessage());
                return true;
            }
            catch (Exception e)
            {
                e.printStackTrace();
                return false;
            }
        } // boot()

    } // WarrantReader

} // Hello3Client

Notice that this use of the service is exactly the same as in our original Hello1Client. All that's different in this example is the way we got the warrant.

Nik Silver 2002-03-09