The FreePastry Tutorial.

This tutorial is designed to get you cooking quickly with the FreePastry API and software toolkit.

Version @tutorial_version@; @tutorial_date@. For FreePastry version @freepastry_version@. Maintained by @maintainer@.

Forwarding

Intercept application messages along the route.



A powerful feature of Key Based Routing in the commonAPI is the ability for your application to intercept and modify a routed message along its path to the key. For example, Past uses this feature to cache popular immutable data along the lookup path. Scribe uses it to implement anycast.

Download the tutorial files: DistTutorial.java MyApp.java, MyMsg.java into a directory called rice/tutorial/rawserialization2/.

In previous tutorials, you had to implement the forward() method because it is part of the Application interface, but we didn't do anything with it except return true. In this tutorial, we will add a "passport" to MyMsg.java. Each hop along ther route will add its NodeHandle to the MyMsg so that the destination can see how the message got there.

First, we'll take a look at the changes to MyMsg from tutorial 4. We added the passport (an ArrayList), and modified the toString to print the path. We also created the addHop() method which simply appends the NodeHandle to the passport.

  ArrayList passport = new ArrayList();
  public void addHop(NodeHandle hop) {
    passport.add(hop);
  }

  public String toString() {
    String path = "";
    for (int i = 0; i < passport.size(); i++) {
      path+=passport.get(i)+",";
    }
    return "MyMsg along path "+path;
  }
Note that we are using Java Serialization. If you extend the RawSerialization tutorial to have this function, you will need to encode the passport in the serialize() method and the deserialization constructor.

Now we need MyApp to call addHop() on the message at each hop. To improve performance, FreePastry only deserializes the message along the intermediate hops if you actually examine/modify the message. For this reason, we have to first deserialize the internal message before we can modify it.

    try {
      MyMsg msg = (MyMsg)message.getMessage(endpoint.getDeserializer());
    } catch (IOException ioe) {
      ioe.printStackTrace(); 
    }
Note that we assume the message will be the MyMsg. If your application routes multiple messages, you will have to do one of the following to disambiguate the messages: Now that we've deserialized the message, just call addHop() with our NodeHandle.
      msg.addHop(endpoint.getLocalNodeHandle());

Finally, we return true to tell the message to continue to be forwarded. If the message can be satisfied at this hop, we can return false. This will cause the message to be delivered to your application on the local node rather than forwarding it to the next hop.

    return true;

Note: You may need to increase the size of the network to be able to see more than 1 hop in the passport. Do this by increasing the number of nodes when you execute the DistTutorial. (The last parameter.)

Congratulations! You have learned to intercept messages along a route path!