CSP for Java
(JCSP) 1.1-rc4

org.jcsp.net.cns
Class CNS

java.lang.Object
  extended by org.jcsp.net.cns.CNS
All Implemented Interfaces:
CSProcess, Service

public class CNS
extends Object
implements Service, CSProcess

This class is the Channel Name Server's main server process class.

This class should only be instantiated at Nodes wishing to run a server process. Although this class does not need to be used by clients wishing to interact with a server, it does provide some convenient static methods for client code to use. There are static versions of the methods provided in CNSService and there are also static factory methods for constructing CNS registered channel objects.

Server Installation

Channel Name Servers may be run either on a dedicated Node or else on the same Node as one of the user Nodes. The former approach is recommended for most sitations but for smaller scale use, the latter approach may suffice. The service implements the org.jcsp.net.Service interface and can be installed in the same way as any other other service by using the service manager (ServiceManager). Alternatively, the service provides install methods which handle the service manager interaction directly.

The following example initializes a Node and installs a Channel Name Server. It then proceeds to install a CNS client service and creates and resolves a channel. The example does not proceed to do anything else but could be used as the framework for an application wishing to host its own Channel Name Server.

 import org.jcsp.lang.*;
 import org.jcsp.net.*;
 import org.jcsp.net.cns.*;
 import org.jcsp.net.tcpip.*;

 import java.io.IOException;

 public class CNSInSameJVM implements CSProcess {

   //main method for running example
   public static void main(String[] args) {
     CNSInSameJVM proc = new CNSInSameJVM();
     proc.run();
   }

   public void run() {
     NodeKey key = null;
     NodeID localNodeID = null;
     try {
       //Initialize a Node that does not have a CNS client
       key = Node.getInstance().init(new XMLNodeFactory("nocns.xml"));
       localNodeID = Node.getInstance().getNodeID();

       //Initialize the CNS Server Process
       CNS.install(key);

       //Dedicated server code could stop here

       //Initialize the CNS client
       //use the first address of the local Node as CNS address
       NodeAddressID cnsAddress = localNodeID.getAddresses()[0];
       CNSService.install(key, cnsAddress);

       //creating Channel named "in"
       NetChannelInput in = CNS.createNet2One("in");
       //resolve the channel
       NetChannelOutput out = CNS.createOne2Net("in");

       //could now use these channels for something!!
       //but this is only a test so will terminate


     } catch (NodeInitFailedException e) {
       e.printStackTrace();
     } catch (IOException e) {
       e.printStackTrace();
     }
     Node.info.log(this, "Done.");
   }

 }
 

This is the contents of the nocns.xml file:

<JCSP-CONFIG>
<PROTOCOLS>
<PROTOCOL id="TCPIP" name="TCP/IP" idclass="org.jcsp.net.tcpip.TCPIPProtocolID">
</PROTOCOL>
</PROTOCOLS>
<ADDRESSES>
<ADDRESS protocolid="TCPIP" value="127.0.0.1:7896" unique="FALSE">
</ADDRESS>
</ADDRESSES>
</JCSP-CONFIG>

The above code can be copied into a file named CNSInSameJVM.java and compiled an run in same directory as the nocns.xml file.

Channel Factory Methods

In order to construct a ChannelInput object which can be resolved by other users of a channel name server, a client simply needs to to do this:

   NetChannelInput in = CNS.createNet2One("Fred");
 

Another process using the same channel name server can create a ChannelOutput that will send objects to this channel by do this:

   NetChannelOutput out = CNS.createOne2Net("Fred");
 

When these factory methods are called, various resources are used within the JCSP infrastructure. A channel name will be registered and held in the channel name server. These resources are taken for the duration of the JCSP Node's runtime unless the user manually frees the resources. When channel ends are constructed with these factory methods, the destroyChannelEnd(***) methods can be used to free all resources. It is only really necessary to do this if channels are being created for short term use within a long-lived Node.

This is an example "Hello World" program which contains two inner classes with main methods, each of which can be run in separate JVMs.

  import org.jcsp.lang.*;
  import org.jcsp.net.*;
  import org.jcsp.net.cns.*;

  public class TestCNS {

    public static class Rx {
      public static void main(String[] args) {
          try {
            Node.getInstance().init();
            NetChannelInput in = CNS.createNet2One("rx.in");
            System.out.println(in.read());
            CNS.destroyChannelEnd(in);
          } catch (NodeInitFailedException e) {
            e.printStackTrace();
          }
      }
    }

    public static class Tx {
      public static void main(String[] args) {
        try {
          Node.getInstance().init();
          NetChannelOutput out = CNS.createOne2Net("rx.in");
          out.write("Hello World");
          CNS.destroyChannelEnd(out);
        } catch (NodeInitFailedException e) {
          e.printStackTrace();
        }
      }
    }
  }
 

This code can be compiled and then the following run at two command prompts:

java TestCNS$Rx

java TestCNS$Tx

The programs will connect to a default channel name server. The Rx program will create a NetChannelInput and wait for a message on the channel. Once it has received the message, it prints it, destroys its channel and then terminates. The Tx program creates a NetChannelOutput that will send to the Rx program's input channel. It sends a "Hello World" message. Once this has been accepted by the Rx process, it destoys its output channel and terminates.

CNS Client Methods

The following code functions the same as the above code but does not use the CNS class' factory methods. The code uses the CNS client methods and manually registers and resolves the channel with the channel name server.

  import org.jcsp.lang.*;
  import org.jcsp.net.*;
  import org.jcsp.net.cns.*;

  public class TestCNS {

    public static class Rx {
      public static void main(String[] args) {
          try {
            Node.getInstance().init();
          NetChannelInput in = NetChannelEnd.createNet2One();
          ChannelNameKey key = CNS.register(in, "rx.in");
          System.out.println(in.read());
          CNS.deregisterChannelName("rx.in", null, key);
          } catch (NodeInitFailedException e) {
            e.printStackTrace();
          }
      }
    }

    public static class Tx {
      public static void main(String[] args) {
        try {
          Node.getInstance().init();
          NetChannelLocation loc = CNS.resolve("rx.in");
          NetChannelOutput out = NetChannelEnd.createOne2Net(loc);
          out.write("Hello World");
          out.destroyWriter();
        } catch (NodeInitFailedException e) {
          e.printStackTrace();
        }
      }
    }
  }
 

The CNS client methods provide the programmer with greater control over how the Channel Name Server is used. Interaction with the server need not be performed at the same time as construction of the channel. A channel can be registered with a Channel Name Server at any time after construction of its input end. A channel can be resolved at any time before construction of an output end. This allows one process to resolve a name into a NetChannelLocation object and then pass this object on for another process to use in constructing the channel. The Channel Name Server will allow a channel to be registered multiple times with different names and/or in different name spaces. Channel implementations that make direct use of the Channel Name Server may forbid this, so the behaviour of channel implemenations should be checked before this is carried out

Author:
Quickstone Technologies Limited
See Also:
CNSService, ServiceManager, Node

Field Summary
static String CNS_DEFAULT_SERVICE_NAME
           
 
Constructor Summary
CNS(NodeKey nodeKey)
          A public constructor which takes a NodeKey as a parameter which should be the key for the local Node.
 
Method Summary
static NetSharedChannelOutput createAny2Net(String name)
           
static NetSharedChannelOutput createAny2Net(String name, NameAccessLevel accessLevel)
           
static NetSharedChannelInput createNet2Any(String name)
           
static NetSharedChannelInput createNet2Any(String name, NameAccessLevel nameAccessLevel)
           
static NetAltingChannelInput createNet2One(String name)
           
static NetAltingChannelInput createNet2One(String name, NameAccessLevel nameAccessLevel)
           
static NetChannelOutput createOne2Net(String name)
           
static NetChannelOutput createOne2Net(String name, NameAccessLevel accessLevel)
           
static boolean deregisterChannelName(String name, NameAccessLevel accessLevel, ChannelNameKey channelKey)
          This deregisters a Channel name with the CNS.
static void destroyChannelEnd(NetChannelInput chanInEnd)
           
static void destroyChannelEnd(NetChannelOutput chanOutEnd)
           
 ServiceUserObject getUserObject()
          Returns a null reference as this method has no use with this service.
 boolean init(ServiceSettings settings)
          This method does not need to be called for the Channel Name Server.
static CNS install(NodeKey key)
          Installs and starts a Channel Name Server on the local Node.
static CNS install(NodeKey key, String serviceName)
          Installs and starts a Channel Name Server on the local Node.
 boolean isRunning()
          Returns whether the service is running.
static ChannelNameKey leaseChannelName(String name, NameAccessLevel accessLevel, ChannelNameKey channelKey)
           
static ChannelNameKey register(NetChannelLocation ownerLocation, String name, NameAccessLevel accessLevel, ChannelNameKey key)
           
static ChannelNameKey register(Networked owner, String name)
           
static ChannelNameKey register(Networked owner, String name, ChannelNameKey key)
           
static ChannelNameKey register(Networked owner, String name, NameAccessLevel accessLevel)
           
static ChannelNameKey register(Networked owner, String name, NameAccessLevel accessLevel, ChannelNameKey key)
           
static NetChannelLocation resolve(String name)
           
static NetChannelLocation resolve(String name, NameAccessLevel accessLevel)
           
 void run()
          This defines the actions of the process.
 boolean start()
          This starts the channel name server.
 boolean stop()
          Stops the channel name server.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

CNS_DEFAULT_SERVICE_NAME

public static final String CNS_DEFAULT_SERVICE_NAME
See Also:
Constant Field Values
Constructor Detail

CNS

public CNS(NodeKey nodeKey)
    throws IllegalStateException,
           SecurityException
A public constructor which takes a NodeKey as a parameter which should be the key for the local Node.

Parameters:
nodeKey - a NodeKey object that should match the local Node's NodeKey.
Throws:
IllegalStateException - if the local Node has not been initialized.
SecurityException - if the supplied NodeKey object cannot be verified by the local Node.
Method Detail

start

public boolean start()
This starts the channel name server.

Specified by:
start in interface Service
Returns:
true iff the channel name server is able to start.

stop

public boolean stop()
Stops the channel name server.

Specified by:
stop in interface Service
Returns:
true iff the Channel Name Server has accepted the stop request.

init

public boolean init(ServiceSettings settings)
This method does not need to be called for the Channel Name Server. It returns true.

Specified by:
init in interface Service
Parameters:
settings - A ServiceSettings object containing settings for the service.
Returns:
false

isRunning

public boolean isRunning()
Returns whether the service is running. At the moment this always returns false. This will probably change in the future. Early JCSP.NET applications always had the CNS process running in its own JVM.

Specified by:
isRunning in interface Service
Returns:
false

getUserObject

public ServiceUserObject getUserObject()
                                throws SecurityException
Returns a null reference as this method has no use with this service.

Specified by:
getUserObject in interface Service
Returns:
null.
Throws:
SecurityException - if the calling Thread does not have access to the object.

run

public void run()
Description copied from interface: CSProcess
This defines the actions of the process.

Specified by:
run in interface CSProcess

resolve

public static NetChannelLocation resolve(String name)

resolve

public static NetChannelLocation resolve(String name,
                                         NameAccessLevel accessLevel)

register

public static ChannelNameKey register(Networked owner,
                                      String name)

register

public static ChannelNameKey register(Networked owner,
                                      String name,
                                      NameAccessLevel accessLevel)

register

public static ChannelNameKey register(Networked owner,
                                      String name,
                                      ChannelNameKey key)

register

public static ChannelNameKey register(Networked owner,
                                      String name,
                                      NameAccessLevel accessLevel,
                                      ChannelNameKey key)

register

public static ChannelNameKey register(NetChannelLocation ownerLocation,
                                      String name,
                                      NameAccessLevel accessLevel,
                                      ChannelNameKey key)

leaseChannelName

public static ChannelNameKey leaseChannelName(String name,
                                              NameAccessLevel accessLevel,
                                              ChannelNameKey channelKey)
                                       throws ChannelNameException,
                                              NameAccessLevelException
Throws:
ChannelNameException
NameAccessLevelException

deregisterChannelName

public static boolean deregisterChannelName(String name,
                                            NameAccessLevel accessLevel,
                                            ChannelNameKey channelKey)
This deregisters a Channel name with the CNS. If the CNS Service is not running, this method will block until it is running. A boolean is returned to indicate whether deregistration was successful. This is also returned if the link to the CNS is lost.

Parameters:
name - the name of the channel as a String.
nameAccessLevel - the nameAccessLevel of the channel.
channelKey - the ChannelNameKey to use to deregister the Channel name.
Returns:
a boolean indicating success.

createNet2One

public static NetAltingChannelInput createNet2One(String name)
See Also:
NamedChannelEndFactory.createNet2One(String)

createNet2One

public static NetAltingChannelInput createNet2One(String name,
                                                  NameAccessLevel nameAccessLevel)
See Also:
NamedChannelEndFactory.createNet2One(String, NameAccessLevel)

createNet2Any

public static NetSharedChannelInput createNet2Any(String name)
See Also:
NamedChannelEndFactory.createNet2Any(String)

createNet2Any

public static NetSharedChannelInput createNet2Any(String name,
                                                  NameAccessLevel nameAccessLevel)
See Also:
NamedChannelEndFactory.createNet2Any(String, NameAccessLevel)

createOne2Net

public static NetChannelOutput createOne2Net(String name)
See Also:
NamedChannelEndFactory.createOne2Net(String)

createOne2Net

public static NetChannelOutput createOne2Net(String name,
                                             NameAccessLevel accessLevel)
See Also:
NamedChannelEndFactory.createOne2Net(String, NameAccessLevel)

createAny2Net

public static NetSharedChannelOutput createAny2Net(String name)
See Also:
NamedChannelEndFactory.createAny2Net(String)

createAny2Net

public static NetSharedChannelOutput createAny2Net(String name,
                                                   NameAccessLevel accessLevel)
See Also:
NamedChannelEndFactory.createAny2Net(String, NameAccessLevel)

destroyChannelEnd

public static void destroyChannelEnd(NetChannelInput chanInEnd)

destroyChannelEnd

public static void destroyChannelEnd(NetChannelOutput chanOutEnd)

install

public static CNS install(NodeKey key)
Installs and starts a Channel Name Server on the local Node. The service is installed with the default service name as specified by CNS.CNS_DEFAULT_SERVICE_NAME. This method needs to be supplied with the local Node's NodeKey. This is required in order to obtain access to the Node's service manager.

Parameters:
key - the local Node's NodeKey.
Returns:
the CNS object installed.
Throws:
ServiceInstallationException - if installation fails.

install

public static CNS install(NodeKey key,
                          String serviceName)
Installs and starts a Channel Name Server on the local Node. The service is installed with the specified service name. This method needs to be supplied with the local Node's NodeKey. This is required in order to obtain access to the Node's service manager.

Parameters:
key - the local Node's NodeKey.
name - the name to give the service.
Returns:
the CNS object installed.
Throws:
ServiceInstallationException - if installation fails.

CSP for Java
(JCSP) 1.1-rc4

Submit a bug or feature to jcsp-team@kent.ac.uk
Version 1.1-rc4 of the JCSP API Specification (Copyright 1997-2008 P.D.Austin and P.H.Welch - All Rights Reserved)
Java is a trademark or registered trademark of Sun Microsystems, Inc. in the US and other countries.