com.eislab.af.translator.Translator_hub_i.java Source code

Java tutorial

Introduction

Here is the source code for com.eislab.af.translator.Translator_hub_i.java

Source

/**
 * Copyright (c) <2016> <hasder>
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *    
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * 
*/

package com.eislab.af.translator;

import com.eislab.af.translator.spokes.BaseSpokeConsumer;
import com.eislab.af.translator.spokes.BaseSpokeProvider;
import com.eislab.af.translator.spokes.CoapClient_spoke;
import com.eislab.af.translator.spokes.CoapServer_spoke;
import com.eislab.af.translator.spokes.HttpClient_spoke;
import com.eislab.af.translator.spokes.HttpServer_spoke;
import com.eislab.af.translator.spokes.MqttClient_spoke;
import com.eislab.af.translator.spokes.MqttServer_spoke;
import com.eislab.af.translator.spokes.UaClient_spoke;
import com.eislab.af.translator.spokes.UaServer_spoke;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.net.util.SubnetUtils;

interface Translator_hub_i {
    void writeToConsole(String msg);
}

public class Translator_hub extends Observable {//implements Runnable {

    private int id = 0;

    public static Properties properties;
    public boolean noactivity = false;
    private int fingerprint = 0;

    BaseSpokeProvider pSpoke;
    private String pSpoke_ConsumerName = null;
    private String pSpoke_ConsumerType = null;
    private String pSpoke_ConsumerAddress = null;
    private String pSpokeAddress = null;
    private String pSpokeIp = null;
    private String pSpokePort = null;
    //   private String    pSpokePath;      //translationPath;//    = "*";

    BaseSpokeConsumer cSpoke;
    private String cSpoke_ProviderName = null;
    private String cSpoke_ProviderType = null;
    //private String  cSpoke_ProviderAddress = null;
    private String cSpoke_ProviderAddress;//    = "coap://127.0.0.1:5692/";
    private String cSpoke_ProviderPath;

    public Translator_hub(String StubConfiguration) {
        //this();

    }

    class SpokeActivityMonitor implements Runnable {

        int counter = 0;

        public SpokeActivityMonitor() {

        }

        @Override
        public void run() {
            while (true) {
                // Start a timer
                try {
                    Thread.sleep(60000);//60,000 ms = 1minute
                    //Thread.sleep(10000); //10,000 ms = 10 seconds for testing
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                if ((cSpoke.getLastActivity() > 0) || (pSpoke.getLastActivity() > 0)) {
                    cSpoke.clearActivity();
                    pSpoke.clearActivity();
                    counter = 0;
                } else if (counter < 1) {
                    counter++;
                } else {
                    noactivity = true;//request translation service to release reference to the hub.

                    pSpoke.close();
                    cSpoke.close();

                    Translator_hub.this.setChanged();
                    Translator_hub.this.notifyObservers(Translator_hub.this.getFingerprint());

                    return;
                }
                // else if (activity grace period not over)
                //count missed activity
                // else
                // close the hub and remove from list in translator service

            }
        }
    }

    private static String findOutgoingIpForGivenAdress(String remoteIP) {

        if (System.getProperty("os.name").contains("Windows")) {
            final String COMMAND = "route print -4";
            List<RouteInfo> routes = new ArrayList<>();
            try {
                Process exec = Runtime.getRuntime().exec(COMMAND);
                BufferedReader reader = new BufferedReader(new InputStreamReader(exec.getInputStream()));

                System.out.println(System.getProperty("os.name"));
                String line;
                /* examples:
                  0.0.0.0          0.0.0.0     10.172.180.1    10.172.180.36     20
                  0.0.0.0          0.0.0.0      10.187.20.1    10.187.20.225     25
                   10.172.180.0    255.255.255.0         On-link     10.172.180.36    276
                  10.172.180.36  255.255.255.255         On-link     10.172.180.36    276
                */
                Pattern p = Pattern.compile(
                        "^\\s*(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s+(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s+\\S+?\\s+(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s+(\\d+)\\s*$");
                while ((line = reader.readLine()) != null) {
                    Matcher match = p.matcher(line);
                    if (match.matches()) {
                        String network = match.group(1);
                        String mask = match.group(2);
                        String address = match.group(3);
                        short maskLength = 0;
                        boolean networkMatch = network.contentEquals("0.0.0.0");

                        if (!networkMatch) {
                            SubnetUtils subnet = new SubnetUtils(network, mask);
                            SubnetUtils.SubnetInfo info = subnet.getInfo();
                            networkMatch = info.isInRange(remoteIP);
                            maskLength = Short.valueOf(info.getCidrSignature().split("/")[1]);
                        }

                        if (networkMatch) {
                            short metric = Short.valueOf(match.group(4));
                            routes.add(new RouteInfo(address, (short) 0, maskLength, metric));
                        }

                    }
                }
                Collections.sort(routes);
                for (RouteInfo route : routes) {
                }

                if (!routes.isEmpty())
                    return routes.get(0).source;

            } catch (Exception ex) {
                ex.printStackTrace();
            }
        } else if (System.getProperty("os.name").contains("Linux")) {

            List<RouteInfo> routes = new ArrayList<>();
            try {
                //ipv6 ^(.+)/(\d+)\s+(.+)\s(\d+)\s+(\d+)\s+(\d)\s+(.+)$
                //ipv4 ^\s+inet\s\addr:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+Bcast:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+Mask:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$
                //linux route get command parsing: ipv4 ^.*via.*\s+dev\s+.*\s+src\s((?:[0-9\.]{1,3})+)
                //linux route get comand parsing: ipv6 ^.*\sfrom\s::\svia.*\sdev\s.*\ssrc\s((?:[:]{1,2}|[0-9|a|b|c|d|e|f]{1,4})+)
                //final String COMMAND = "/sbin/ifconfig";
                final String COMMAND = "ip route get " + remoteIP;

                Process exec = Runtime.getRuntime().exec(COMMAND);
                BufferedReader reader = new BufferedReader(new InputStreamReader(exec.getInputStream()));

                System.out.println(System.getProperty("os.name"));
                String line;
                /* examples:
                 * 10.10.2.130 via 10.0.2.2 dev eth0  src 10.0.2.255
                */
                Pattern p = Pattern.compile("^.*via.*\\s+dev\\s+.*\\s+src\\s((?:[0-9|\\.]{1,3})+)");

                while ((line = reader.readLine()) != null) {
                    Matcher match = p.matcher(line);
                    if (match.matches()) {

                        String address = match.group(1);

                        routes.add(new RouteInfo(address, (short) 0, (short) 0, (short) 0));//metric is always 0, because we do not extract it from the ifconfig command.

                    }
                }
                Collections.sort(routes);

                if (!routes.isEmpty())
                    return routes.get(0).source;

            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }

    private static String findOutgoingIpV6GivenAddress(String remoteIP) throws Exception {

        System.out.println("remoteIP: " + remoteIP);
        if (remoteIP.startsWith("[")) {
            remoteIP = remoteIP.substring(1, remoteIP.length() - 1);
            System.out.println("remoteIP: " + remoteIP);
        }

        if (System.getProperty("os.name").contains("Windows")) {
            NetworkInterface networkInterface;

            //if ipv6 then find the ipaddress of the network interface
            String line;
            short foundIfIndex = 0;
            final String COMMAND = "route print -6";
            List<RouteInfo> routes = new ArrayList<>();
            try {
                Process exec = Runtime.getRuntime().exec(COMMAND);
                BufferedReader reader = new BufferedReader(new InputStreamReader(exec.getInputStream()));
                //\s+addr:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+Bcast:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+Mask:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$
                Pattern p = Pattern.compile("^\\s*(\\d+)\\s+(\\d+)\\s+(.*)\\s+(.*)$");
                while ((line = reader.readLine()) != null) {
                    //do not check persistent routes. Only active routes
                    if (line.startsWith("Persistent Routes")) {
                        break;
                    }

                    Matcher match = p.matcher(line);
                    if (match.matches()) {
                        //                     System.out.println("line match: " + line);
                        String network = match.group(3).split("/")[0];
                        //String mask = match.group(2);
                        //String address = match.group(3);
                        short maskLength = Short.valueOf(match.group(3).split("/")[1].trim());

                        boolean networkMatch = ipv6InRange(network, maskLength, remoteIP);

                        if (networkMatch) {
                            short interfaceIndex = Short.valueOf(match.group(1));
                            short metric = Short.valueOf(match.group(2));
                            routes.add(new RouteInfo("", interfaceIndex, maskLength, metric));
                            System.out.println("added route: " + line);
                        }
                    }
                }
                Collections.sort(routes);
                for (RouteInfo route : routes) {
                }

                if (!routes.isEmpty()) {
                    foundIfIndex = routes.get(0).ifIndex;

                    //based o nthe network interface index get the ip address
                    networkInterface = NetworkInterface.getByIndex(foundIfIndex);

                    Enumeration<InetAddress> test = networkInterface.getInetAddresses();

                    while (test.hasMoreElements()) {
                        InetAddress inetaddress = test.nextElement();
                        if (inetaddress.isLinkLocalAddress()) {
                            continue;
                        } else {
                            if (inetaddress instanceof Inet6Address) {
                                System.out.println("interface host address: " + inetaddress.getHostAddress());
                                return "[" + inetaddress.getHostAddress() + "]";
                            } else
                                continue;
                        }
                    }
                } else { //routes is Empty!
                    System.out.println("No routable interface for remote IP");
                    throw new Exception("No routable interface for remote IP");
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                throw ex;
            }
        } else {

            List<RouteInfo> routes = new ArrayList<>();
            try {
                //ipv6 ^(.+)/(\d+)\s+(.+)\s(\d+)\s+(\d+)\s+(\d)\s+(.+)$
                //ipv4 ^\s+inet\s\addr:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+Bcast:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+Mask:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$
                //linux route get command parsing: ipv4^.*via.*\s+dev\s+.*\s+src\s((?:[0-9\.]{1,3})+)
                //linux route get comand parsing: ipv6 ^.*\sfrom\s::\svia.*\sdev\s.*\ssrc\s((?:[:]{1,2}|[0-9|a|b|c|d|e|f]{1,4})+)
                //new one ^.*\s+from\s+::\s+via.*\s+dev\s+.*\ssrc\s+((?:[:]{1,2}|[0-9|a|b|c|d|e|f]{1,4})+)\s+metric\s+\d+
                //final String COMMAND = "/sbin/ifconfig";
                final String COMMAND = "ip route get " + remoteIP;

                System.out.println("command = " + COMMAND);

                Process exec = Runtime.getRuntime().exec(COMMAND);
                BufferedReader reader = new BufferedReader(new InputStreamReader(exec.getInputStream()));

                System.out.println(System.getProperty("os.name"));
                String line;
                /* examples:
                 * fdfd:55::98ac from :: via fdfd:55::98ac dev usb0  src fdfd:55::80fe  metric 0
                */
                Pattern p = Pattern.compile(
                        "^.*\\s+from\\s+::\\s+via.*\\sdev\\s+.*\\s+src\\s+((?:[:]{1,2}|[0-9|a|b|c|d|e|f]{1,4})+)\\s+metric\\s+\\d+.*");
                //String test = "fdfd:55::80ff from :: via fdfd:55::80ff dev usb0  src fdfd:55::80fe  metric 0";
                while ((line = reader.readLine()) != null) {
                    System.out.println("result of command = " + line);
                    Matcher match = p.matcher(line);
                    if (match.matches()) {

                        String address = match.group(1);
                        System.out.println("match found. address = " + address);
                        routes.add(new RouteInfo(address, (short) 0, (short) 0, (short) 0));//metric is always 0, because we do not extract it from the ifconfig command.

                    }
                }
                Collections.sort(routes);

                if (!routes.isEmpty())
                    return routes.get(0).source;

            } catch (Exception ex) {
                ex.printStackTrace();
            }

            //^\s+inet6\s+addr:\s+((?:[:]{1,2}|[0-9|a|b|c|d|e|f]{1,4})+)/(\d{1,3})\s+\Scope:Global$
            //           NetworkInterface networkInterface;
            //         
            //         //if ipv6 then find the ipaddress of the network interface
            //          String line;
            //          short foundIfIndex = 0;
            //         final String COMMAND = "/sbin/ifconfig";
            //         List<RouteInfo> routes = new ArrayList<>();
            //         try {
            //            Process exec = Runtime.getRuntime().exec(COMMAND);
            //            BufferedReader reader = new BufferedReader(new InputStreamReader(exec.getInputStream()));
            //            //\s+addr:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+Bcast:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+Mask:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$
            //            Pattern p = Pattern.compile("^\\s+inet6\\s+addr:\\s+((?:[:]{1,2}|[0-9|a|b|c|d|e|f]{1,4})+)/(\\d{1,3})\\s+\\Scope:Global$");
            //              while ((line = reader.readLine()) != null) {
            //                 //do not check persistent routes. Only active routes
            //                 if(line.startsWith("Persistent Routes")) {
            //                    break;
            //                 }
            //                 
            //                  Matcher match = p.matcher(line);
            //                  if (match.matches()) {
            //                      String network = match.group(1).trim();
            //                      short maskLength = Short.valueOf(match.group(2).trim());
            //                      
            //                      boolean networkMatch = ipv6InRange(network, maskLength, remoteIP);
            //                      
            //                      if (networkMatch) {
            //                         short interfaceIndex = Short.valueOf(match.group(1));
            //                          short metric = Short.valueOf(match.group(2));
            //                          routes.add(new RouteInfo("", interfaceIndex, maskLength, metric));
            //                          System.out.println("added route: " + line);
            //                      }
            //                  }
            //              }
            //              Collections.sort(routes);
            //              for (RouteInfo route : routes) {
            //              }
            //              
            //              if (!routes.isEmpty()) {
            //                 foundIfIndex = routes.get(0).ifIndex;
            //         
            //               //based o nthe network interface index get the ip address
            //               networkInterface = NetworkInterface.getByIndex(foundIfIndex);
            //            
            //               Enumeration<InetAddress> test = networkInterface.getInetAddresses();
            //               
            //               while (test.hasMoreElements()) {
            //                  InetAddress inetaddress = test.nextElement();
            //                  if (inetaddress.isLinkLocalAddress()) {
            //                     continue;
            //                  } else {
            //                     if (inetaddress instanceof Inet6Address) {
            //                        System.out.println("interface host address: " + inetaddress.getHostAddress());
            //                        return "[" + inetaddress.getHostAddress() + "]";
            //                     } else continue;
            //                  }
            //               }
            //              } else { //routes is Empty!
            //                 System.out.println("No routable interface for remote IP");
            //               throw new Exception("No routable interface for remote IP");
            //              }
            //         } catch (Exception ex) {
            //            ex.printStackTrace();
            //            throw ex;
            //         }

        }

        return null;
    }

    public static boolean ipv6InRange(String localIp, int localMask, String remoteIp) {
        InetAddress remoteAddress = parseAddress(remoteIp);
        InetAddress requiredAddress = parseAddress(localIp);
        int nMaskBits = localMask;

        if (!requiredAddress.getClass().equals(remoteAddress.getClass())) {
            return false;
        }

        if (nMaskBits <= 0) {
            return remoteAddress.equals(requiredAddress);
        }

        byte[] remAddr = remoteAddress.getAddress();
        byte[] reqAddr = requiredAddress.getAddress();

        int oddBits = nMaskBits % 8;
        int nMaskBytes = nMaskBits / 8 + (oddBits == 0 ? 0 : 1);
        byte[] mask = new byte[nMaskBytes];

        Arrays.fill(mask, 0, oddBits == 0 ? mask.length : mask.length - 1, (byte) 0xFF);

        if (oddBits != 0) {
            int finalByte = (1 << oddBits) - 1;
            finalByte <<= 8 - oddBits;
            mask[mask.length - 1] = (byte) finalByte;
        }

        //       System.out.println("Mask is " + new sun.misc.HexDumpEncoder().encode(mask));

        for (int i = 0; i < mask.length; i++) {
            if ((remAddr[i] & mask[i]) != (reqAddr[i] & mask[i])) {
                return false;
            }
        }

        return true;
    }

    private static InetAddress parseAddress(String address) {
        try {
            return InetAddress.getByName(address);
        } catch (UnknownHostException e) {
            throw new IllegalArgumentException("Failed to parse address" + address, e);
        }
    }

    public Translator_hub(Observer observer) {
        //loadProperties("translator.properties");
        this.addObserver(observer);

        SpokeActivityMonitor activityMonitor = new SpokeActivityMonitor();
        new Thread(activityMonitor).start();

    }

    // spoke is responsible for translating from protocol specific domain to a generic domain
    // hub is used for chaining spokes in series.
    // the chain must start with a baseprovider and finish with a baseconsumer
    // each spoke in the chain has a generic interface

    public void closeProvider(String msg) {
        pSpoke.close();
    }

    public void closeConsumer(String msg) {
        cSpoke.close();
    }

    public void online() throws Exception {
        //find the network interface or the ipaddress (IPv4)
        String source = findOutgoingIpForGivenAdress(this.getpSpoke_ConsumerAddress());
        if (source == null) {
            source = findOutgoingIpV6GivenAddress(this.getpSpoke_ConsumerAddress());
        }

        System.out.println("interface host address: " + source);

        try {

            System.out.println(
                    "go online: ConsumerSpoke: " + cSpoke_ProviderName + " ProviderSpoke: " + pSpoke_ConsumerName);

            if (pSpoke_ConsumerType.contains("coap")) {
                //pSpoke = new CoapServer_spoke(properties.getProperty("translator.interface.ipaddress"));
                pSpoke = new CoapServer_spoke(source);
            } else if (pSpoke_ConsumerType.contains("http")) {
                //HttpServer_spoke httpserver = new HttpServer_spoke(translationPort, translationPath);
                //pSpoke = new HttpServer_spoke(properties.getProperty("translator.interface.ipaddress"), "/*");
                pSpoke = new HttpServer_spoke(source, "/*");
                //         }  else if (pSpoke_ConsumerType.contains("ua")) {
            } else if (pSpoke_ConsumerType.contains("opc")) {
                //pSpoke = new UaServer_spoke(properties.getProperty("translator.interface.ipaddress"), "/*");
                pSpoke = new UaServer_spoke(source, "/*");
            } else if (pSpoke_ConsumerType.contains("mqtt")) {
                String brokerUri = "tcp://localhost:1883";//TODO: get these values from ORCHESTRaTOR OR METADATA
                int maxPublishDelay = 1000; //1 second
                boolean MqttServer_spoke = true;
                //home/garden/fountain
                String serviceProviderPath = "/home/garden/fountain";
                pSpoke = new MqttServer_spoke(brokerUri, serviceProviderPath, maxPublishDelay, MqttServer_spoke);
            } else {

                System.exit(1);
            }

            if (cSpoke_ProviderType.contains("coap")) {
                cSpoke = new CoapClient_spoke(cSpoke_ProviderAddress);
            } else if (cSpoke_ProviderType.contains("http")) {
                cSpoke = new HttpClient_spoke(cSpoke_ProviderAddress);
            } else if (cSpoke_ProviderType.contains("mqtt")) {
                //            String brokerUri = "tcp://localhost:1883";//TODO: get these values from ORCHESTRaTOR OR METADATA
                cSpoke = new MqttClient_spoke(cSpoke_ProviderAddress);
                //         } else if(cSpoke_ProviderType.contains("ua")) {
            } else if (cSpoke_ProviderType.contains("opc")) {
                cSpoke = new UaClient_spoke(cSpoke_ProviderAddress);
            } else {
                System.exit(1);
            }

            // link the spoke connections 
            pSpoke.setNextSpoke(cSpoke);
            cSpoke.setNextSpoke(pSpoke);

            Runtime.getRuntime().addShutdownHook(new Thread() {
                @Override
                public void run() {
                    System.out.println("===END===");
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                    }
                }
            });

        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }
    }

    public int getId() {
        if (id == 0) {
            id = (int) (Math.random() * 100000);
        }
        return id;
    }

    public int getFingerprint() {
        return fingerprint;
    }

    public void setFingerprint(int fingerprint) {
        this.fingerprint = fingerprint;
    }

    public String getPSpoke_ConsumerName() {
        return pSpoke_ConsumerName;
    }

    public void setPSpoke_ConsumerName(String pSpoke_ConsumerName) {
        this.pSpoke_ConsumerName = pSpoke_ConsumerName;
    }

    public String getCSpoke_ProviderName() {
        return cSpoke_ProviderName;
    }

    public void setCSpoke_ProviderName(String cSpoke_ProviderName) {
        this.cSpoke_ProviderName = cSpoke_ProviderName;
    }

    //TODO must be composed as url = scheme://ip:port/path or scheme://ip:port/topic or XMPP??? or OPC-UA??? 
    public String getPSpokeAddress() {
        if (pSpokeAddress == null) {
            String address = this.pSpoke.getAddress();
            this.setPSpokeAddress(address);
        }
        return pSpokeAddress;
    }

    private void setPSpokeAddress(String pSpokeAddress) {
        this.pSpokeAddress = pSpokeAddress;
    }

    // 
    public String getPSpokeIp() {
        if (pSpokeIp == null) {
            String temp = this.pSpoke.getAddress();
            temp = temp.substring(temp.indexOf("//") + 2);
            if (temp.startsWith("[")) {
                temp = temp.substring(0, temp.indexOf("]") + 1);
            } else {
                temp = temp.substring(0, temp.indexOf(":"));
            }
            String pSpokeIp = temp;
            this.setPSpokeIp(pSpokeIp);
        }
        return pSpokeIp;
    }

    private void setPSpokeIp(String pSpokeIp) {
        this.pSpokeIp = pSpokeIp;
    }

    // 
    public String getPSpokePort() {
        if (pSpokePort == null) {
            String temp = this.pSpoke.getAddress();
            temp = temp.substring(temp.indexOf("//") + 2);
            if (temp.startsWith("[")) {
                temp = temp.substring(temp.indexOf("]") + 2);
                temp = temp.substring(0, temp.indexOf("/"));
            } else {
                temp = temp.substring(temp.indexOf(":") + 1);
            }

            String pSpokePort = temp;

            this.setPSpokePort(pSpokePort);
        }
        return pSpokePort;
    }

    private void setPSpokePort(String pSpokePort) {
        this.pSpokePort = pSpokePort;
    }

    //   public String getPSpokePath() {
    //      return pSpokePath;
    //   }
    //
    //   public void setPSpokePath(String pSpokePath) {
    //      this.pSpokePath = pSpokePath;
    //   }

    public String getCSpoke_ProviderAddress() {
        return cSpoke_ProviderAddress;
    }

    public void setCSpoke_ProviderAddress(String cSpoke_ProviderAddress) {
        this.cSpoke_ProviderAddress = cSpoke_ProviderAddress;
    }

    public String getpSpoke_ConsumerType() {
        return pSpoke_ConsumerType;
    }

    public void setpSpoke_ConsumerType(String pSpoke_ConsumerType) {
        this.pSpoke_ConsumerType = pSpoke_ConsumerType;
    }

    public String getpSpoke_ConsumerAddress() {
        return pSpoke_ConsumerAddress;
    }

    public void setpSpoke_ConsumerAddress(String pSpoke_ConsumerAddress) {
        this.pSpoke_ConsumerAddress = pSpoke_ConsumerAddress;
    }

    public String getcSpoke_ProviderType() {
        return cSpoke_ProviderType;
    }

    public void setcSpoke_ProviderType(String cSpoke_ProviderType) {
        this.cSpoke_ProviderType = cSpoke_ProviderType;
    }

    /** 
     * Reads the properties from the file .properties
     *
     */
    private static boolean loadProperties(String propertiesFileName) {
        boolean result = false;
        /* Setting up Globals */
        String fileName = propertiesFileName;

        /* Read the input properties file and set the properties */
        try {
            Properties props = new Properties();
            props.load(new FileInputStream(fileName));
            properties = props;
            result = true;
        } catch (IOException e) {
            //LOG.severe("Failed to read property file " + fileName + ". Reason: " + e.getMessage());
            System.out.println("Failed to read property file " + fileName + ". Reason: " + e.getMessage());
            //System.exit(-1);
        }
        return result;
    }

}

class RouteInfo implements Comparable<RouteInfo> {
    public final String source;
    public final short ifIndex;
    public final short maskLength;
    public final short metric;

    public RouteInfo(String src, short interfaceIndex, short mask, short mtr) {
        source = src;
        ifIndex = interfaceIndex;
        maskLength = mask;
        metric = mtr;
    }

    @Override
    public int compareTo(RouteInfo ri) {
        if (ri.maskLength != maskLength)
            return ri.maskLength - maskLength;
        return metric - ri.metric;
    }
}