/** * Creates a new client end of a NetBarrier * * @param name * The name to resolve with the BNS * @param enrolled * The number of locally enrolled processes * @return A new NetBarrier client end with the number of enrolled processes * @//throws JCSPNetworkException * Thrown if something goes wrong in the underlying architecture * @//throws ArgumentException * Thrown if the number of of local enrolled is outside the defined range * @//throws InvalidOperationException * Thrown if the connection to the BNS has not been initialised */ public static NetBarrier netBarrier(String name, int enrolled) // //throws ArgumentException , InvalidOperationException, JCSPNetworkException { // Check if the BNS connection is initialised if (!BNS.initialised) { throw new InvalidOperationException("The connection to the BNS has not been initialised"); } // Resolve the location of the barrier NetBarrierLocation loc = BNS.service.resolve(name); // Return a new NetBarrier return(NetBarrierEnd.netBarrier(loc, enrolled)); }
/** * Decodes a byte array back into a BNSMessage * * @param bytes * The bytes to convert back into a BNSMessage * @return The recreated BNSMessage * @//throws IOException * Thrown if something goes wrong during the recreation */ public Object filterRX(byte[] bytes) ////throws IOException { this.byteIn = new MemoryStream(bytes); this.dis = new BinaryReader(byteIn); // Recreate the message BNSMessage msg = new BNSMessage(); msg.type = this.dis.ReadByte(); msg.success = this.dis.ReadBoolean(); msg.serviceLocation = NetChannelLocation.parse(this.dis.ReadString()); msg.location = NetBarrierLocation.parse(this.dis.ReadString()); msg.name = this.dis.ReadString(); return(msg); }
/** * The run method for the BNS process */ public void run() { // Create the channel to receive incoming messages on. The index is 2. NetAltingChannelInput In = NetChannel.numberedNet2One(2, new BNSNetworkMessageFilter.FilterRX()); // We now wish to alternate upon this channel and the link lost channel Alternative alt = new Alternative(new Guard[] { this.lostLink, In }); // Loop forever while (true) { // Select next available Guard. Give priority to link failure switch (alt.priSelect()) { // We have lost the connection to a Node case 0: // Read in the NodeID of the lost Node NodeID lostNode = (NodeID)this.lostLink.read(); // Log loss of connection Node.log.log(this.GetType(), "Lost Link to: " + lostNode.toString()); // Remove the logged client this.loggedClients.Remove(lostNode); // Next get the ArrayList of any barriers registered by that Node ArrayList registeredBars = (ArrayList)this.barrierRegister[lostNode]; // If this ArrayList is null, we have no registrations if (registeredBars != null) { // There are registered barriers // Remove the list from the Hashmap this.barrierRegister.Remove(lostNode); // Now remove all the barriers registered by the Node for (IEnumerator enumerator = registeredBars.GetEnumerator(); enumerator.MoveNext();) { String toRemove = (String)enumerator.Current; this.registeredBarriers.Remove(toRemove); Node.log.log(this.GetType(), toRemove + " deregistered"); } } break; // We have received a new incoming message case 1: { // Read in the message BNSMessage message = (BNSMessage)In.read(); // Now behave based on the type of the message switch (message.type) { // We have received a logon message case BNSMessageProtocol.LOGON_MESSAGE: { // Log the logon attempt Node.log.log(this.GetType(), "Logon received from: " + message.serviceLocation.getNodeID().toString()); // try-catch loop. We don't want the BNS to fail try { // Check if the node is already logged on NetChannelOutput Out = (NetChannelOutput)this.loggedClients[message.serviceLocation.getNodeID()]; // If out is null, no previous logon received if (Out != null) { // This Node is already logged on. Send fail message // Log failed attempt Node.err.log(this.GetType(), message.serviceLocation.getNodeID().toString() + " already logged on. Rejecting"); // Create reply channel to the Node NetChannelOutput toNewRegister = NetChannel.one2net(message.serviceLocation, new BNSNetworkMessageFilter.FilterTX()); // Create the reply message BNSMessage reply = new BNSMessage(); reply.type = BNSMessageProtocol.LOGON_REPLY_MESSAGE; reply.success = false; // Asynchronously write to Node. We don't want the BNS to block toNewRegister.asyncWrite(reply); // Destroy the temporary channel toNewRegister.destroy(); } else { // Node hasn't previously registered // Log registration Node.log.log(this.GetType(), message.serviceLocation.getNodeID().toString() + " successfully logged on"); // Create the reply channel NetChannelOutput toNewRegister = NetChannel.one2net(message.serviceLocation, new BNSNetworkMessageFilter.FilterTX()); // Add the Node and reply channel to the logged clients map this.loggedClients.Add(message.serviceLocation.getNodeID(), toNewRegister); // Create a reply message BNSMessage reply = new BNSMessage(); reply.type = BNSMessageProtocol.LOGON_REPLY_MESSAGE; reply.success = true; // Write reply asynchronously to the logging on Node toNewRegister.asyncWrite(reply); } } catch (JCSPNetworkException jne) { // Catch any JCSPNetworkException. We don't let the BNS go down } break; } // A Node is attempting to register a Barrier case BNSMessageProtocol.REGISTER_REQUEST: { // Log registration attempt Node.log.log(this.GetType(), "Registeration for " + message.name + " received"); // Catch any JCSPNetworkException try { // Get the reply channel from our logged clients map NetChannelOutput Out = (NetChannelOutput)this.loggedClients[message.serviceLocation.getNodeID()]; // Check if the Node has logged on with us if (Out == null) { // The Node is not logged on. Send failure message Node.err.log(this.GetType(), "Registration failed. " + message.serviceLocation.getNodeID() + " not logged on"); // Create the channel to reply to Out = NetChannel.one2net(message.serviceLocation, new BNSNetworkMessageFilter.FilterTX()); // Create the reply message BNSMessage reply = new BNSMessage(); reply.type = BNSMessageProtocol.REGISTER_REPLY; reply.success = false; // Write message asynchronously to the Node Out.asyncWrite(reply); // Destroy the temporary channel Out.destroy(); } // The Node is registered. Now check if the name is else if (this.registeredBarriers.ContainsKey(message.name)) { // The name is already registered. Inform the register // Log the failed registration Node.err.log(this.GetType(), "Registration failed. " + message.name + " already registered"); // Create reply message BNSMessage reply = new BNSMessage(); reply.type = BNSMessageProtocol.RESOLVE_REPLY; reply.success = false; // Write the reply asynchronously. Do not block the BNS Out.asyncWrite(reply); } else { BNSMessage reply; // The name is not registered // Log successful registration Node.log.log(this.GetType(), "Registration of " + message.name + " succeeded."); // First check if any client end is waiting for this name ArrayList pending = (ArrayList)this.waitingResolves[message.name]; if (pending != null) { // We have waiting resolves. Complete for (IEnumerator enumerator = pending.GetEnumerator(); enumerator.MoveNext();) { NetChannelOutput toPending = null; // We now catch internally any JCSPNetworkException try { // Get the next waiting message BNSMessage msg = (BNSMessage)enumerator.Current; // Log resolve completion Node.log.log(this.GetType(), "Queued resolve of " + message.name + " by " + msg.serviceLocation.getNodeID() + " completed"); // Create channel to the resolver toPending = NetChannel.one2net(msg.serviceLocation, new BNSNetworkMessageFilter.FilterTX()); // Create the reply message reply = new BNSMessage(); reply.type = BNSMessageProtocol.RESOLVE_REPLY; reply.location = message.location; reply.success = true; // Write the reply asynchronously to the waiting resolver toPending.asyncWrite(reply); } catch (JCSPNetworkException jne) { // Something went wrong as we tried to send the resolution complete // message // Do nothing } finally { // Check if we need to destroy the temporary channel if (toPending != null) { toPending.destroy(); } } } // Remove the name from the pending resolves this.waitingResolves.Remove(message.name); } // We have completed any pending resolves. Now register the barrier this.registeredBarriers.Add(message.name, message.location); // Now add the registered barrier to the barriers registered by this Node ArrayList registered = (ArrayList)this.barrierRegister[message.serviceLocation.getNodeID()]; // If the ArrayList is null, we have no previous registrations if (registered == null) { // Create a new ArrayList to store the registered names registered = new ArrayList(); // Add it to the barrier register this.barrierRegister.Add(message.location.getNodeID(), registered); } // Add the name to the ArrayList registered.Add(message.name); // Log the successful registration Node.log.log(this.GetType(), message.name + " registered to " + message.location); // Create the reply message reply = new BNSMessage(); reply.type = BNSMessageProtocol.REGISTER_REPLY; reply.success = true; // Write the reply asynchronously to the Node Out.asyncWrite(reply); } } catch (JCSPNetworkException jne) { // Do nothing. Do not let the BNS break } break; } // We have received a resolve request case BNSMessageProtocol.RESOLVE_REQUEST: { // Log resolve request Node.log.log(this.GetType(), "Resolve request for " + message.name + " received"); // Catch any JCSPNetworkException try { // Check if the resolving Node is logged on NetChannelOutput Out = (NetChannelOutput)this.loggedClients[message.serviceLocation.getNodeID()]; // If the channel is null, then the Node has yet to log on with us if (Out == null) { // Node is not logged on // Log failed resolution Node.err.log(this.GetType(), "Resolve failed. " + message.serviceLocation.getNodeID() + " not logged on"); // Create connection to the receiver Out = NetChannel.one2net(message.serviceLocation, new BNSNetworkMessageFilter.FilterTX()); // Create the reply message BNSMessage reply = new BNSMessage(); reply.type = BNSMessageProtocol.RESOLVE_REPLY; reply.success = false; // Write message asynchronously to the Node Out.asyncWrite(reply); // Destroy the temporary channel Out.destroy(); } else { // Node is logged on. Now check if the name is already registered NetBarrierLocation loc = (NetBarrierLocation)this.registeredBarriers[message.name]; // If the location is null, then the name has not yet been registered if (loc == null) { // The name is not registered. We need to queue the resolve until it is // Log the queueing of the resolve Node.log.log(this.GetType(), message.name + " not registered. Queueing resolve by " + message.serviceLocation.getNodeID().toString()); // Check if any other resolvers are waiting for the channel ArrayList pending = (ArrayList)this.waitingResolves[message.name]; // If the ArrayList is null, no one else is waiting if (pending == null) { // No one else is waiting. Create a new list and add it to the waiting // resolves pending = new ArrayList(); this.waitingResolves.Add(message.name, pending); } // Add this resolve message to the list of waiting resolvers pending.Add(message); } else { // The location is not null. Send it to the resolver Node.log.log(this.GetType(), "Resolve request completed. " + message.name + " location being sent to " + message.serviceLocation.getNodeID()); // Create channel to the resolver NetChannelOutput toPending = NetChannel.one2net(message.serviceLocation, new BNSNetworkMessageFilter.FilterTX()); // Create the reply message BNSMessage reply = new BNSMessage(); reply.type = BNSMessageProtocol.RESOLVE_REPLY; reply.location = loc; reply.success = true; // Write the reply to the resolver asynchronously toPending.asyncWrite(reply); // Destroy the temporary channel toPending.destroy(); } } } catch (JCSPNetworkException jne) { // Something went wrong during the resolution. Ignore } break; } } break; } } } }