Routing-Packets-In-A-Network-Overlay / src / main / java / csx55 / overlay / wireformats / LinkWeights.java
LinkWeights.java
Raw
package csx55.overlay.wireformats;

import java.io.*;
import java.util.ArrayList;
import java.util.Random;
import csx55.overlay.util.OverlayCreator;

/**
 * This is a wireformat used by the registry to send the list of links in the system to all of the
 * messaging nodes. The link weights follow the format host:port host:port weight. It follows the same format 
 * as all of the other wireformats and is built using the provided example in the slides. This wireformat accepts
 * the number of links and an array of the links in the system as one constructor and intializes
 * the instance variables. Another constructor takes in the byte stream and unmarshalls the information
 * sent by the node. It also implemnts the getBytes() method from the Event interface, which marshalls
 * the variables for this wireformat. The first constructor is used when creating an instance of the class
 * and the second is used by the event factory to create a new instance and return a class that the bytes
 * unmarshalled. The getBytes() is used before the data is sent using the sender thread.
 */
public class LinkWeights implements Event {
    private int type;
    private int numLinks;
    private ArrayList<String> links;

    //takes in the topolgy defined by OverlayCreator and assigns weights based on those
    public LinkWeights(OverlayCreator.Node[] topology) {
        Random rand = new Random();
        this.links = new ArrayList<>();
        this.type = Protocol.LINK_WEIGHTS;

        //getting the total number of links 
        for (OverlayCreator.Node n: topology) {
            this.numLinks += n.getNumNeighbors();
        }

        //adding links to the links array list in the format ip:port ip:port weight
        for (OverlayCreator.Node n: topology) {
            for (String neighbor: n.getNeighbors()) {
                links.add(n.connectionInfo + " " + neighbor + " " + Integer.toString(rand.nextInt(10) + 1));
            }
        }
    }

    public LinkWeights(byte[] marshalledByte) throws IOException {
        ByteArrayInputStream baInputStream = new ByteArrayInputStream(marshalledByte);
        DataInputStream din = new DataInputStream(new BufferedInputStream(baInputStream));

        this.type = din.readInt();
        this.numLinks = din.readInt();
        int listSize = din.readInt();

        this.links = new ArrayList<>(listSize);

        for (int i = 0; i < listSize; i++) {
            int size = din.readInt();
            byte[] linkBytes = new byte[size];
            din.readFully(linkBytes);
            this.links.add(i, new String(linkBytes));
        }

        baInputStream.close();
        din.close();
    }

    @Override
    public int getType() {
        return this.type;
    }
    @Override
    public byte[] getBytes() throws IOException {
        byte[] marshalledBytes = null;
        ByteArrayOutputStream baOutputStream = new ByteArrayOutputStream();
        DataOutputStream dout = new DataOutputStream(new BufferedOutputStream(baOutputStream));

        dout.writeInt(type);
        dout.writeInt(numLinks);

        dout.writeInt(links.size());
        for (String s: links) {
            byte[] linkBytes = s.getBytes();
            dout.writeInt(linkBytes.length);
            dout.write(linkBytes);
        }

        dout.flush();
        marshalledBytes = baOutputStream.toByteArray();

        baOutputStream.close();
        dout.close();
        return marshalledBytes;
    }

    //return number of links in the overlay
    public int getNumLinks() {
        return this.numLinks;
    }

    //return the list of links in the overlay
    public ArrayList<String> getLinks() {
        return this.links;
    }

    //searches the links arraylist to see if both the current and next nodes are present
    //allows both nodes to access the weight regardless of wether they are current or next
    public String getWeight(String curr, String next) {
        String str = "";

        for (int i = 0; i < links.size(); i++) {
            String link = links.get(i);
            if (link.contains(curr) && link.contains(next)) {
                str = link.split("\\s+")[2];//split on spaces
            }
        }

        return str;
    }

}