restart vBNG based on XOS's record

re-set up the private IP address to public IP address mapping
based on the mapping record in XOS.

re-calculates and re-installs all the intents.

Change-Id: I89aa75662da596b9793e02ba41398a43517ccecf
diff --git a/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngManager.java b/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngManager.java
index 775cff4..8fae896 100644
--- a/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngManager.java
+++ b/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngManager.java
@@ -17,8 +17,12 @@
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.google.common.collect.Maps;
 
+import java.util.Iterator;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentHashMap;
@@ -66,6 +70,7 @@
 public class VbngManager implements VbngService {
 
     private static final String APP_NAME = "org.onosproject.virtualbng";
+    private static final String VBNG_MAP_NAME = "vbng_mapping";
 
     private final Logger log = LoggerFactory.getLogger(getClass());
 
@@ -113,6 +118,9 @@
         hostService.addListener(hostListener);
 
         log.info("vBNG Started");
+
+        // Recover the status before vBNG restarts
+        statusRecovery();
     }
 
     @Deactivate
@@ -122,6 +130,42 @@
     }
 
     /**
+     * Recovers from XOS record. Re-sets up the mapping between private IP
+     * address and public IP address, re-calculates intents and re-installs
+     * those intents.
+     */
+    private void statusRecovery() {
+        log.info("vBNG starts to recover from XOS record......");
+        RestClient restClient = new RestClient();
+        ObjectNode map = restClient.getRest();
+        if (map == null) {
+            log.info("Stop to recover vBNG status due to the vBNG map "
+                    + "is null!");
+            return;
+        }
+
+        log.info("Get record from XOS: {}", map);
+
+        ArrayNode array = (ArrayNode) map.get(VBNG_MAP_NAME);
+        Iterator<JsonNode> entries = array.elements();
+        while (entries.hasNext()) {
+            ObjectNode entry = (ObjectNode) entries.next();
+
+            IpAddress hostIpAdddress =
+                    IpAddress.valueOf(entry.get("private_ip").asText());
+            IpAddress publicIpAddress =
+                    IpAddress.valueOf(entry.get("routeable_subnet").asText());
+            MacAddress macAddress =
+                    MacAddress.valueOf(entry.get("mac").asText());
+            String hostName = entry.get("hostname").asText();
+
+            // Create vBNG
+            createVbng(hostIpAdddress, publicIpAddress, macAddress, hostName);
+
+        }
+    }
+
+    /**
      * Sets up mapping from hostname to connect point.
      */
     private void setupMap() {
@@ -136,6 +180,39 @@
                                         PortNumber.portNumber(47)));
     }
 
+    /**
+     * Creates a new vBNG.
+     *
+     * @param privateIpAddress a private IP address
+     * @param publicIpAddress the public IP address for the private IP address
+     * @param hostMacAddress the MAC address for the private IP address
+     * @param hostName the host name for the private IP address
+     */
+    private void createVbng(IpAddress privateIpAddress,
+                            IpAddress publicIpAddress,
+                            MacAddress hostMacAddress,
+                            String hostName) {
+        boolean result = vbngConfigurationService
+                .assignSpecifiedPublicIp(publicIpAddress, privateIpAddress);
+        if (!result) {
+            log.info("Assign public IP address {} for private IP address {} "
+                    + "failed!", publicIpAddress, privateIpAddress);
+            log.info("Failed to create vBNG for private IP address {}",
+                     privateIpAddress);
+            return;
+        }
+        log.info("[ADD] Private IP to Public IP mapping: {} --> {}",
+                 privateIpAddress, publicIpAddress);
+
+        // Setup paths between the host configured with private IP and
+        // next hop
+        if (!setupForwardingPaths(privateIpAddress, publicIpAddress,
+                                  hostMacAddress, hostName)) {
+            privateIpAddressMap.put(privateIpAddress,
+                                    new VcpeHost(hostMacAddress, hostName));
+        }
+    }
+
     @Override
     public IpAddress createVbng(IpAddress privateIpAddress,
                                 MacAddress hostMacAddress,