Package org.jcsp.net

Class Link

  • All Implemented Interfaces:
    CSProcess
    Direct Known Subclasses:
    LoopbackLink, TCPIPLink

    public abstract class Link
    extends java.lang.Object
    implements CSProcess

    This class is an abstract class that all JCSP.NET protocol implementations must implement. Concrete implementations of the Link class must provide the mechanism for sending data to remote Nodes and receiving data back. When a concrete implementation of link is initiated by calling the run() method, it must inititate a handshaking procedure and call certain protected methods in this abstract class.

    During handshaking, the runTests(ChannelInput, ChannelOutput, boolean) should be called. See the documentation for this method for a full explanation.

    When a Link receives an object from over the network it should deliver the object to its destination by calling the deliverReceivedObject(Object) method.

    Link implementations obtain objects to send to the remote Node by reading from the protected txChannel object.

    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      private static class  Link.LinkTest  
    • Constructor Summary

      Constructors 
      Constructor Description
      Link​(ProtocolID protocolID, boolean client, boolean connected)
      A constructor that must be called by sub-classes.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      (package private) void addTxFilter​(Filter filter, int index)
      Adds a transmission filter.
      protected boolean connect()
      Establishes a connection to the peer node.
      protected boolean createResources()
      Allocates the resources necessary for the actual connection.
      protected void deliverReceivedObject​(java.lang.Object obj)
      A protected method for concrete implementations of this class to call when they received a an object from the remote Node.
      protected void destroyResources()
      Deallocates any resources allocated by createResources.
      boolean equals​(java.lang.Object o)
      Compares another object with this object.
      protected boolean exchangeNodeIDs()
      Sends the ID of this node to the peer process and receives its ID.
      long getPingTime()
      A public accessor for obtaining the ping time between the local Node and this Link's remote Node.
      (package private) Profile getProfile()  
      protected ProtocolID getProtocolID()
      A protected accessor for obtaining the identifier of the protocol implementing this Link object.
      protected boolean[] getReadSequence​(boolean client)
      This is used by concrete Link implementations before calling the runTests method.
      protected NodeID getRemoteNodeID()
      Returns the other computer's ID.
      (package private) Specification[] getSpecifications()  
      protected ChannelOutput getTxChannel()
      Returns channel to use for transmitting.
      (package private) int getTxFilterCount()
      Gets the number of installed transmission filters.
      private int handshake()
      Does handshaking.
      int hashCode()
      Returns an int hash code for this Link.
      private int lostLink()
      This should be called once to notify users of the link that the link has been dropped.
      NodeID obtainNodeID()
      This returns the NodeID of the remote Node to which this link is connected.
      boolean performedPingTest()
      A public accessor for enquiring as to whether this Link object has performed a ping test.
      long ping()
      Performs a ping on the link.
      protected boolean readLinkDecision()
      Reads a boolean link decision as to whether this node can keep or discard the link.
      protected java.lang.Object readTestObject()
      Reads a test object from the underlying connection.
      private void registerFailure()
      Called to inform the local LinkManager that this link has failed.
      private boolean registerLink()
      This is called during handshaking in order to register the link with the local LinkManager.
      (package private) void removeTxFilter​(Filter filter)
      Removes a transmission filter.
      void run()
      Main process for the link, containing generic code that makes calls on the abstract methods that should be implemented by a concrete subclass.
      private void runTestProcess​(ChannelInput in, ChannelOutput out, boolean client)
      This should be called during the handshaking process.
      protected void runTxRxLoop()
      Performs send and receive actions for the link exchanging data with the peer node.
      (package private) void setProfile​(Profile profile)  
      (package private) void setSpecifications​(Specification[] specifications)  
      protected void waitForReplies​(int numAcknowledgements)
      Waits for numRepliesOutstanding instances of LinkLost to arrive from the txChannel.
      protected void writeLinkDecision​(boolean use)
      Writes a boolean link decision as to whether the other node has the option to keep or discard the link.
      protected void writeTestObject​(java.lang.Object obj)
      Writes a test object to the underlying connection.
      • Methods inherited from class java.lang.Object

        clone, finalize, getClass, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • HS_ERROR

        private static final int HS_ERROR
        Handshake result code - a problem occurred
        See Also:
        Constant Field Values
      • HS_TEMPORARY

        private static final int HS_TEMPORARY
        Handshake result code - temporary link
        See Also:
        Constant Field Values
      • HS_OK

        private static final int HS_OK
        Handshake result code - permanant link ok
        See Also:
        Constant Field Values
      • connected

        private boolean connected
        True if connect() has been called or the underlying connection is already open. False otherwise.
      • client

        private boolean client
        True if this is a client during handshaking, false if it is the server.
      • txChannel

        protected FilteredAny2OneChannel txChannel
        The channel used for TX over the link. In the future, this might be made private. It is recommended that implementations use the getTxChannel() to obtain the channel. Protocol implementations should NOT alter any of the filters on this channel.
      • remoteNodeID

        protected NodeID remoteNodeID
        The remote NodeID. The subclass must set this during exchangeNodeIDs.
      • sendNodeID

        protected boolean sendNodeID
        True if the subclass must pass the ID of this node to the peer node.
      • performedPingTest

        private boolean performedPingTest
      • pingTime

        private long pingTime
    • Constructor Detail

      • Link

        public Link​(ProtocolID protocolID,
                    boolean client,
                    boolean connected)

        A constructor that must be called by sub-classes.

        Parameters:
        protocolID - A ProtocolID object for identifying the protocol that is implementing the Link.
        client - Indicates whether this is the client (true) or server (false) end of the connection.
        connected - true if a connection is already established; otherwise connect() will later be called
    • Method Detail

      • connect

        protected boolean connect()
                           throws java.lang.Exception

        Establishes a connection to the peer node. Called when the process is started unless connected was true in the constructor. This is called internally from this class' run method - do not call it.

        Returns:
        true on success, false on failure
        Throws:
        java.lang.Exception
      • createResources

        protected boolean createResources()
                                   throws java.lang.Exception

        Allocates the resources necessary for the actual connection. Called as the first part of the handshaking process. This is called internally from the class' handshake method - do not call it.

        Returns:
        true on success, false on failure
        Throws:
        java.lang.Exception
      • destroyResources

        protected void destroyResources()
                                 throws java.lang.Exception

        Deallocates any resources allocated by createResources. Called in the event of an error during handshaking or when the link is dropped. An implementation of this method must cope with being called multiple times without an intervening call to createResources.

        Throws:
        java.lang.Exception
      • exchangeNodeIDs

        protected boolean exchangeNodeIDs()
                                   throws java.lang.Exception

        Sends the ID of this node to the peer process and receives its ID. It is only necessary to send this node's ID if sendNodeID is true. The remoteNodeID attribute should be set to the ID of the remote node if received. This is called internally during handshaking - do not call it.

        Returns:
        true on success, false on failure.
        Throws:
        java.lang.Exception
      • runTxRxLoop

        protected void runTxRxLoop()
                            throws java.lang.Exception
        Performs send and receive actions for the link exchanging data with the peer node. This is called from this class' run method - do not call it directly.
        Throws:
        java.lang.Exception
      • waitForReplies

        protected void waitForReplies​(int numAcknowledgements)
                               throws java.lang.Exception
        Waits for numRepliesOutstanding instances of LinkLost to arrive from the txChannel. This is called internally from this class' run method - do not call it directly.
        Parameters:
        numRepliesOutstanding - LinkLost instances to wait for.
        Throws:
        java.lang.Exception
      • writeTestObject

        protected void writeTestObject​(java.lang.Object obj)
                                throws java.lang.Exception
        Writes a test object to the underlying connection. Called internally during handshaking - do not call it directly. The value written must be delivered by readTestObject at the remote node.
        Parameters:
        obj - object to be written
        Throws:
        java.lang.Exception
      • readTestObject

        protected java.lang.Object readTestObject()
                                           throws java.lang.Exception
        Reads a test object from the underlying connection. Called internally during handshaking - do not call it directly. It must deliver the value passed to writeTestObject at the peer node.
        Returns:
        the object received.
        Throws:
        java.lang.Exception
      • writeLinkDecision

        protected void writeLinkDecision​(boolean use)
                                  throws java.lang.Exception
        Writes a boolean link decision as to whether the other node has the option to keep or discard the link. Called internally during handshaking - do not call it directly. The value written must be delivered by readLinkDecision at the peer node.
        Parameters:
        use - decision result
        Throws:
        java.lang.Exception
      • readLinkDecision

        protected boolean readLinkDecision()
                                    throws java.lang.Exception
        Reads a boolean link decision as to whether this node can keep or discard the link. Called internally during handshaking - do not call it directly. It must return the value passed to writeLinkDecision at the peer node.
        Returns:
        decision result
        Throws:
        java.lang.Exception
      • addTxFilter

        void addTxFilter​(Filter filter,
                         int index)
        Adds a transmission filter. This filter will run in the thread that is trying to send something over this Link.
        Parameters:
        filter - the filter.
        index - the index position of the filter.
      • removeTxFilter

        void removeTxFilter​(Filter filter)
        Removes a transmission filter.
        Parameters:
        filter - the filter to remove.
      • getTxFilterCount

        int getTxFilterCount()
        Gets the number of installed transmission filters.
        Returns:
        the number of transmission filters installed.
      • getRemoteNodeID

        protected NodeID getRemoteNodeID()
        Returns the other computer's ID. This method is safe to call while the process is running, however it will return null if the other computer has not yet identified itself.
        Returns:
        ID of connected computer.
      • getProtocolID

        protected ProtocolID getProtocolID()
        A protected accessor for obtaining the identifier of the protocol implementing this Link object.
        Returns:
        the ProtocolID of the protocol implementing this Link.
      • setProfile

        void setProfile​(Profile profile)
      • getTxChannel

        protected ChannelOutput getTxChannel()
        Returns channel to use for transmitting. This method is safe to call while the process is running. May block for if handshaking is still in progress. When written to, if the object supplied is not Serializable then an IllegalArgumentException Runtime exception.
        Returns:
        Channel you should send data to if you want to transmit on this Connection.
      • deliverReceivedObject

        protected void deliverReceivedObject​(java.lang.Object obj)
        A protected method for concrete implementations of this class to call when they received a an object from the remote Node. This method delivers the message to its destination (a Channel, Connection etc.).
        Parameters:
        obj - the object to deliver.
      • setSpecifications

        void setSpecifications​(Specification[] specifications)
      • getPingTime

        public long getPingTime()
        A public accessor for obtaining the ping time between the local Node and this Link's remote Node.
        Returns:
        the ping time as a long.
      • ping

        public long ping()
        Performs a ping on the link.
        Returns:
        the ping time in ms.
      • performedPingTest

        public boolean performedPingTest()

        A public accessor for enquiring as to whether this Link object has performed a ping test.

        Returns:
        true iff a ping test has been performed.
      • getReadSequence

        protected boolean[] getReadSequence​(boolean client)

        This is used by concrete Link implementations before calling the runTests method. When tests are run, a series of messages are exchanged between both sides of the link. This allows the link to perform its tests using a single thread.

        Parameters:
        client - a boolean indicating whether this Link object is the client side of the link. If this object is the client then the parameter should be true.
        Returns:
        an array of boolean values indicating the sequence of when to read and when to transmit.
      • runTestProcess

        private void runTestProcess​(ChannelInput in,
                                    ChannelOutput out,
                                    boolean client)

        This should be called during the handshaking process. The in parameter should be a ChannelInput that reads from a process that receives object from the remote Node. The out parameter is a ChannelOutput that, when written to, will transmit the object to the remote Node. The client parameter should be true iff the current Link is acting as a client side link (if it establishes the initial connection).

        The method will start a testing process and then return. The concrete implementation of Link that calls this method should call the getReadSequence(boolean) method before calling this method. Once this method has returned, the calling process should loop through the returned array of boolean values. If the value is true, the process should wait to recieve an object from over the network and then send it down the channel supplied as the in parameter. If the value is false, the process should read from the channel supplied as the out parameter and then send the object it receives over the network.

        Once the calling process has finished looping through the array, it should perform a read from the channel supplied as the out channel. This is some example code for what concrete implementations of Link need to do:

            One2OneChannel fromTestProcess = Channel.one2one();
            One2OneChannel toTestProcess = Channel.one2one();
            boolean[] readSequence = super.getReadSequence(client);
            super.runTests(toTestProcess.in(), fromTestProcess.out(), client);
            try {
                for(int i=0; i
        Parameters:
        in - a ChannelInput that the test process can use to receive objects from over the network.
        out - a ChannelOutput that the test process should use to send objects over the network.
        client - a boolean that is true iff this Link object is the object that established the connection to the remote Node.
      • registerLink

        private boolean registerLink()

        This is called during handshaking in order to register the link with the local LinkManager. It returns true if the link is successfully registered.

        Returns:
        true iff the link is successfully registered.
      • registerFailure

        private void registerFailure()

        Called to inform the local LinkManager that this link has failed.

        Currently, this should be called if the link fails once it has been registered but before the handshaking is complete.

      • lostLink

        private int lostLink()

        This should be called once to notify users of the link that the link has been dropped. The method returns the number of channels that are using the link that has been dropped. Implementations should read from txChannel the number of times returned by this method.

        This is an example:

            int numRepliesOutstanding = super.lostLink();
            while (numRepliesOutstanding > 0) {
                Object obj = txChannel.read();
                if (obj instanceof LinkLost) {
                    numRepliesOutstanding--;
                }
            }
         
        Returns:
        an int indicating the number of channels that are using the link.
      • equals

        public final boolean equals​(java.lang.Object o)

        Compares another object with this object. This implementation returns true iff the supplied object is the same instance object as this object.

        Overrides:
        equals in class java.lang.Object
        Parameters:
        o - an object to compare with this object.
        Returns:
        true iff the parameter equals this object.
      • hashCode

        public final int hashCode()

        Returns an int hash code for this Link. The current implementation just uses the instance from Object.

        Overrides:
        hashCode in class java.lang.Object
        Returns:
        an int hash code.
      • run

        public final void run()

        Main process for the link, containing generic code that makes calls on the abstract methods that should be implemented by a concrete subclass. The subclass will be required to connect() if it hasn't done so, perform handshaking, runTxRxLoop() and then waitForReplies() to acknowledge link termination.

        Specified by:
        run in interface CSProcess
      • handshake

        private int handshake()

        Does handshaking. Checks that the other side is a JCSP.net server of the same version, then decides whether or not this link is a duplicate of an existing link. If the versions match and there is no link to the other server, then the link is registered with the LinkManager, true is returned, and the link is ready for real data. Otherwise, the link is closed and false is returned.

        This method contains generic code. Calls are made on abstract methods that a concrete subclass must implement to provide link functionality.

        Returns:
        HS_ERROR if a problem occurs, HS_REMPORARY if the link is to be discarded or HS_OK for a permanent link.
      • obtainNodeID

        public final NodeID obtainNodeID()

        This returns the NodeID of the remote Node to which this link is connected. If a connection has not already been established, this method may connect to the remote Node and request its NodeID and then drop the connection.

        Returns:
        the remote Node's NodeID object.