REST API for FPM Accept Routes

Change-Id: I2cd2f2ac5e7c7079ae87bfe32e76baeb97567e02
diff --git a/apps/routing/fpm/web/src/main/java/org/onosproject/fpm/web/FpmAcceptRoutesCodec.java b/apps/routing/fpm/web/src/main/java/org/onosproject/fpm/web/FpmAcceptRoutesCodec.java
new file mode 100644
index 0000000..9161ee6
--- /dev/null
+++ b/apps/routing/fpm/web/src/main/java/org/onosproject/fpm/web/FpmAcceptRoutesCodec.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.fpm.web;
+
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.routing.fpm.FpmPeer;
+
+import org.onlab.packet.IpAddress;
+import org.onosproject.routing.fpm.FpmPeerAcceptRoutes;
+
+/**
+ * Codec of FpmPeerInfo class.
+ */
+public final class FpmAcceptRoutesCodec extends JsonCodec<FpmPeerAcceptRoutes> {
+
+    // JSON field names
+    private static final String PEER_ADDRESS = "peerAddress";
+    private static final String PEER_PORT = "peerPort";
+    private static final String ACCEPT_ROUTES = "acceptRoutes";
+
+    @Override
+    public FpmPeerAcceptRoutes decode(ObjectNode json, CodecContext context) {
+        if (json == null || !json.isObject()) {
+            return null;
+        }
+
+        IpAddress address = IpAddress.valueOf(json.path(PEER_ADDRESS).asText());
+        int port = Integer.parseInt(json.path(PEER_PORT).asText());
+        boolean isAcceptRoutes = Boolean.valueOf(json.path(ACCEPT_ROUTES).asText());
+        FpmPeer peer = new FpmPeer(address, port);
+        FpmPeerAcceptRoutes updatedPeer = new FpmPeerAcceptRoutes(peer, isAcceptRoutes);
+        return updatedPeer;
+    }
+}
diff --git a/apps/routing/fpm/web/src/main/java/org/onosproject/fpm/web/FpmCodec.java b/apps/routing/fpm/web/src/main/java/org/onosproject/fpm/web/FpmCodec.java
index fda14db..fa127e4 100755
--- a/apps/routing/fpm/web/src/main/java/org/onosproject/fpm/web/FpmCodec.java
+++ b/apps/routing/fpm/web/src/main/java/org/onosproject/fpm/web/FpmCodec.java
@@ -22,6 +22,7 @@
 import org.onosproject.codec.JsonCodec;
 import org.onosproject.routing.fpm.FpmPeerInfo;
 
+
 /**
  * Codec of FpmPeerInfo class.
  */
@@ -33,6 +34,7 @@
     private static final String CONNECTED_TO = "connectedTo";
     private static final String CONNECTION_TIME = "connectionTime";
     private static final String LOCAL_ROUTES = "localRoutes";
+    private static final String ACCEPT_ROUTES = "acceptRoutes";
 
 
     @Override
@@ -47,6 +49,7 @@
             fpmNode.put(CONNECTED_TO, connection.connectedTo().toString());
             fpmNode.put(CONNECTION_TIME, Tools.timeAgo(connection.connectTime()));
             fpmNode.put(LOCAL_ROUTES, fpmPeerInfo.routes());
+            fpmNode.put(ACCEPT_ROUTES, connection.isAcceptRoutes());
             connectionArray.add(fpmNode);
         });
 
diff --git a/apps/routing/fpm/web/src/main/java/org/onosproject/fpm/web/FpmWebResource.java b/apps/routing/fpm/web/src/main/java/org/onosproject/fpm/web/FpmWebResource.java
index 6b6ea92..51bb0fe 100644
--- a/apps/routing/fpm/web/src/main/java/org/onosproject/fpm/web/FpmWebResource.java
+++ b/apps/routing/fpm/web/src/main/java/org/onosproject/fpm/web/FpmWebResource.java
@@ -25,15 +25,25 @@
 import org.onosproject.routing.fpm.FpmPeerInfo;
 import org.onosproject.routing.fpm.FpmInfoService;
 import org.onosproject.routing.fpm.FpmPeer;
+import org.onosproject.routing.fpm.FpmPeerAcceptRoutes;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
+import java.io.IOException;
+import static org.onlab.util.Tools.nullIsIllegal;
+import static org.onlab.util.Tools.readTreeFromStream;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import java.io.InputStream;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-
 import java.util.Comparator;
 import java.util.Map;
+import java.util.List;
 
 /**
  * FPM REST API.
@@ -41,9 +51,17 @@
 @Path("")
 public class FpmWebResource extends AbstractWebResource {
 
+    private static final String ACCEPT_ROUTES = "acceptRoutes";
+    private static final String PEER_ADDRESS = "peerAddress";
+    private static final String PEER_PORT = "peerPort";
+    protected static final String PEERS = "peers";
+    protected static final String PEERS_KEY_ERROR = "Peers key must be present";
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
     /**
      * To get all fpm connections.
      * @return 200 OK with component properties of given component and variable.
+     * @onos.rsModel FpmConnectionsGet
      */
     @GET
     @Produces(MediaType.APPLICATION_JSON)
@@ -53,6 +71,60 @@
         return Response.status(200).entity(node).build();
     }
 
+    /**
+     * Performs disabling of FPM Peer.
+     *
+     * @param stream array of peer address and accept route flag
+     * @return 200 OK disable peer.
+     * @onos.rsModel FpmPeerSetAcceptRouteFlag
+     */
+    @POST
+    @Path("acceptRoutes")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response updateAcceptRouteFlagForConnection(InputStream stream) {
+        FpmInfoService fpmService = get(FpmInfoService.class);
+        try {
+            ObjectNode jsonTree = readTreeFromStream(mapper(), stream);
+            ArrayNode peersArray = nullIsIllegal((ArrayNode) jsonTree.get(PEERS),
+                    PEERS_KEY_ERROR);
+            List<FpmPeerAcceptRoutes> fpmPeerRouteInfo = (new FpmAcceptRoutesCodec()).decode(peersArray, this);
+            fpmService.updateAcceptRouteFlag(fpmPeerRouteInfo);
+        } catch (IOException ex) {
+            throw new IllegalArgumentException(ex);
+        }
+
+        return Response.ok().build();
+
+    }
+
+    /**
+     * Gets peers acceptRoute Flag details.
+     * @param peerAddress peer identifier
+     * @return 200 OK with a collection of peerInfo
+     * @onos.rsModel FpmPeerGetAcceptRoutes
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("acceptRoutes/{peerAddress}")
+    public Response getPeerAcceptRouteInfo(@PathParam("peerAddress") String peerAddress) {
+        ObjectNode node = getFpmPeerAcceptFlagInfoJsonOutput(peerAddress);
+        return Response.status(200).entity(node).build();
+    }
+
+    /**
+     * Gets all peers acceptRoute Flag details.
+     * @return 200 OK with a collection of peerInfo
+     * @onos.rsModel FpmGetAcceptRoutes
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("acceptRoutes/")
+    public Response getAllPeerAcceptRouteInfo() {
+        ObjectNode node = getFpmPeerRouteInfoJsonOutput();
+        return Response.status(200).entity(node).build();
+    }
+
 
     private ObjectNode getFpmConnectionsJsonOutput() {
 
@@ -72,6 +144,54 @@
         return node;
 
     }
+
+    private ObjectNode getFpmPeerRouteInfoJsonOutput() {
+
+        FpmInfoService fpmService = get(FpmInfoService.class);
+        ObjectNode node = mapper().createObjectNode();
+        ArrayNode connectionArray = mapper().createArrayNode();
+        Map<FpmPeer, FpmPeerInfo> fpmPeers = fpmService.peers();
+        fpmPeers.entrySet().stream()
+                .sorted(Comparator.<Map.Entry<FpmPeer, FpmPeerInfo>, IpAddress>comparing(e -> e.getKey().address())
+                        .thenComparing(e -> e.getKey().port()))
+                .map(Map.Entry::getValue)
+                .forEach(fpmPeerInfo -> {
+                    fpmPeerInfo.connections().forEach(connection -> {
+                        ObjectNode fpmNode = mapper().createObjectNode();
+                        fpmNode.put(PEER_ADDRESS, connection.peer().address().toString());
+                        fpmNode.put(PEER_PORT, connection.peer().port());
+                        fpmNode.put(ACCEPT_ROUTES, connection.isAcceptRoutes());
+                        connectionArray.add(fpmNode);
+                    });
+
+                });
+
+        node.put("fpm-peer-info", connectionArray);
+        return node;
+
+
+    }
+
+    private ObjectNode getFpmPeerAcceptFlagInfoJsonOutput(String address) {
+
+        FpmInfoService fpmService = get(FpmInfoService.class);
+        ObjectNode fpmNode = mapper().createObjectNode();
+        Map<FpmPeer, FpmPeerInfo> fpmPeers = fpmService.peers();
+        IpAddress peerAddress = IpAddress.valueOf(address);
+        fpmPeers.entrySet().stream()
+                .filter(peer -> peer.getKey().address().equals(peerAddress))
+                .map(Map.Entry::getValue)
+                .forEach(fpmPeerInfo -> {
+                    fpmPeerInfo.connections().forEach(connection -> {
+                        fpmNode.put(ACCEPT_ROUTES, connection.isAcceptRoutes());
+                    });
+                });
+
+
+        return fpmNode;
+
+
+    }
 }
 
 
diff --git a/apps/routing/fpm/web/src/main/resources/definitions/FpmConnectionsGet.json b/apps/routing/fpm/web/src/main/resources/definitions/FpmConnectionsGet.json
new file mode 100644
index 0000000..207453c
--- /dev/null
+++ b/apps/routing/fpm/web/src/main/resources/definitions/FpmConnectionsGet.json
@@ -0,0 +1,37 @@
+{
+  "type": "object",
+  "required": [
+    "peerAddress",
+    "peerPort",
+    "connectedTo",
+    "connectionTime",
+    "localRoutes",
+    "acceptRoutes"
+  ],
+  "properties": {
+    "peerAddress": {
+      "type": "string",
+      "example": "10.255.0.0"
+    },
+    "peerPort": {
+      "type": "int",
+      "example": "34455"
+    },
+    "connectedTo": {
+      "type": "string",
+      "example": "10.2.2.5"
+    },
+    "connectionTime": {
+      "type": "string",
+      "example": "3m ago"
+    },
+    "localRoutes": {
+      "type": "int",
+      "example": "2"
+    },
+    "acceptRoutes": {
+      "type": "boolean",
+      "example": "true"
+    }
+  }
+}
\ No newline at end of file
diff --git a/apps/routing/fpm/web/src/main/resources/definitions/FpmGetAcceptRoutes.json b/apps/routing/fpm/web/src/main/resources/definitions/FpmGetAcceptRoutes.json
new file mode 100644
index 0000000..ce23582
--- /dev/null
+++ b/apps/routing/fpm/web/src/main/resources/definitions/FpmGetAcceptRoutes.json
@@ -0,0 +1,22 @@
+{
+  "type": "object",
+  "required": [
+    "peerAddress",
+    "peerPort",
+    "acceptRoutes"
+  ],
+  "properties": {
+    "peerAddress": {
+      "type": "String",
+      "example": "10.0.0.1"
+    },
+    "peerPort": {
+      "type": "Integer",
+      "example": "56789"
+    },
+    "acceptRoutes": {
+      "type": "boolean",
+      "example": "true"
+    }
+  }
+}
diff --git a/apps/routing/fpm/web/src/main/resources/definitions/FpmPeerGetAcceptRoutes.json b/apps/routing/fpm/web/src/main/resources/definitions/FpmPeerGetAcceptRoutes.json
new file mode 100644
index 0000000..87e0c6e
--- /dev/null
+++ b/apps/routing/fpm/web/src/main/resources/definitions/FpmPeerGetAcceptRoutes.json
@@ -0,0 +1,12 @@
+{
+  "type": "object",
+  "required": [
+    "acceptRoutes"
+  ],
+  "properties": {
+    "acceptRoutes": {
+      "type": "boolean",
+      "example": "true"
+    }
+  }
+}
diff --git a/apps/routing/fpm/web/src/main/resources/definitions/FpmPeerSetAcceptRouteFlag.json b/apps/routing/fpm/web/src/main/resources/definitions/FpmPeerSetAcceptRouteFlag.json
new file mode 100644
index 0000000..652f552
--- /dev/null
+++ b/apps/routing/fpm/web/src/main/resources/definitions/FpmPeerSetAcceptRouteFlag.json
@@ -0,0 +1,40 @@
+{
+  "type": "object",
+  "title": "peers",
+  "required": [
+    "peers"
+  ],
+  "properties": {
+    "peers": {
+      "type": "array",
+      "xml": {
+        "name": "peers",
+        "wrapped": true
+      },
+      "items": {
+        "type": "object",
+        "title": "peer",
+        "required": [
+          "peerAddress",
+          "port",
+          "acceptRoutes"
+        ],
+        "properties": {
+          "peerAddress": {
+            "type": "string",
+            "example": "10.255.0.0"
+          },
+          "peerPort": {
+            "type": "int",
+            "example": "23456"
+          },
+          "acceptRoutes": {
+            "type": "boolean",
+            "example": "true"
+          }
+        }
+      }
+    }
+  }
+}
+