BGP encode multiple flow spec action issue fix.

Change-Id: Ieb173be9edb86bc717bfe1e55271873645e4a5b1
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/flowspec/BgpFlowSpecDetails.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/flowspec/BgpFlowSpecDetails.java
index cc6384c..994f656 100755
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/flowspec/BgpFlowSpecDetails.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/flowspec/BgpFlowSpecDetails.java
@@ -27,7 +27,7 @@
  */
 public class BgpFlowSpecDetails {
     private List<BgpValueType> flowSpecComponents;
-    private BgpValueType fsActionTlv;
+    private List<BgpValueType> fsActionTlv;
     private RouteDistinguisher routeDistinguisher;
 
     /**
@@ -44,7 +44,7 @@
      *
      * @return flow specification action tlv
      */
-    public BgpValueType fsActionTlv() {
+    public List<BgpValueType> fsActionTlv() {
         return this.fsActionTlv;
     }
 
@@ -53,7 +53,7 @@
      *
      * @param fsActionTlv flow specification action tlv
      */
-    public void setFsActionTlv(BgpValueType fsActionTlv) {
+    public void setFsActionTlv(List<BgpValueType> fsActionTlv) {
         this.fsActionTlv = fsActionTlv;
     }
 
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpExtendedCommunity.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpExtendedCommunity.java
index 880b332..31a85da 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpExtendedCommunity.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpExtendedCommunity.java
@@ -23,6 +23,10 @@
 import org.onosproject.bgpio.util.Validation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
 import java.util.Objects;
 
 /**
@@ -33,14 +37,14 @@
     private static final Logger log = LoggerFactory.getLogger(BgpExtendedCommunity.class);
     public static final short TYPE = Constants.BGP_EXTENDED_COMMUNITY;
     public static final byte FLAGS = (byte) 0xC0;
-    private BgpValueType fsActionTlv;
+    private List<BgpValueType> fsActionTlv;
 
     /**
      * Constructor to initialize the value.
      *
      * @param fsActionTlv flow specification action type
      */
-    public BgpExtendedCommunity(BgpValueType fsActionTlv) {
+    public BgpExtendedCommunity(List<BgpValueType> fsActionTlv) {
         this.fsActionTlv = fsActionTlv;
     }
 
@@ -49,7 +53,7 @@
      *
      * @return extended community
      */
-    public BgpValueType fsActionTlv() {
+    public List<BgpValueType> fsActionTlv() {
         return this.fsActionTlv;
     }
 
@@ -64,7 +68,7 @@
 
         ChannelBuffer tempCb = cb.copy();
         Validation validation = Validation.parseAttributeHeader(cb);
-        BgpValueType fsActionTlv = null;
+        List<BgpValueType> fsActionTlvs = new LinkedList<>();
 
         if (cb.readableBytes() < validation.getLength()) {
             Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR,
@@ -80,27 +84,33 @@
 
         ChannelBuffer tempBuf = cb.readBytes(validation.getLength());
         if (tempBuf.readableBytes() > 0) {
+            BgpValueType fsActionTlv = null;
             ChannelBuffer actionBuf = tempBuf.readBytes(validation.getLength());
-            short actionType = actionBuf.readShort();
-            short length = (short) validation.getLength();
-            switch (actionType) {
-                case Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_ACTION:
-                    fsActionTlv = BgpFsActionTrafficAction.read(actionBuf);
-                    break;
-                case Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_MARKING:
-                    fsActionTlv = BgpFsActionTrafficMarking.read(actionBuf);
-                    break;
-                case Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_RATE:
-                    fsActionTlv = BgpFsActionTrafficRate.read(actionBuf);
-                    break;
-                case Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_REDIRECT:
-                    fsActionTlv = BgpFsActionReDirect.read(actionBuf);
-                    break;
-                default: log.debug("Other type Not Supported:" + actionType);
-                    break;
+
+            while (actionBuf.readableBytes() > 0) {
+                short actionType = actionBuf.readShort();
+                switch (actionType) {
+                    case Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_ACTION:
+                        fsActionTlv = BgpFsActionTrafficAction.read(actionBuf);
+                        break;
+                    case Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_MARKING:
+                        fsActionTlv = BgpFsActionTrafficMarking.read(actionBuf);
+                        break;
+                    case Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_RATE:
+                        fsActionTlv = BgpFsActionTrafficRate.read(actionBuf);
+                        break;
+                    case Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_REDIRECT:
+                        fsActionTlv = BgpFsActionReDirect.read(actionBuf);
+                        break;
+                    default: log.debug("Other type Not Supported:" + actionType);
+                        break;
+                }
+            }
+            if (fsActionTlv != null) {
+                fsActionTlvs.add(fsActionTlv);
             }
         }
-        return new BgpExtendedCommunity(fsActionTlv);
+        return new BgpExtendedCommunity(fsActionTlvs);
     }
 
     @Override
@@ -136,24 +146,29 @@
     @Override
     public int write(ChannelBuffer cb) {
         int iLenStartIndex = cb.writerIndex();
+        ListIterator<BgpValueType> listIterator = fsActionTlv().listIterator();
+
         cb.writeByte(FLAGS);
         cb.writeByte(getType());
 
         int iActionLenIndex = cb.writerIndex();
         cb.writeByte(0);
 
-        if (fsActionTlv.getType() == Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_ACTION) {
-            BgpFsActionTrafficAction trafficAction = (BgpFsActionTrafficAction) fsActionTlv;
-            trafficAction.write(cb);
-        } else if (fsActionTlv.getType() == Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_MARKING) {
-            BgpFsActionTrafficMarking trafficMarking = (BgpFsActionTrafficMarking) fsActionTlv;
-            trafficMarking.write(cb);
-        } else if (fsActionTlv.getType() == Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_RATE) {
-            BgpFsActionTrafficRate trafficRate = (BgpFsActionTrafficRate) fsActionTlv;
-            trafficRate.write(cb);
-        } else if (fsActionTlv.getType() == Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_REDIRECT) {
-            BgpFsActionReDirect trafficRedirect = (BgpFsActionReDirect) fsActionTlv;
-            trafficRedirect.write(cb);
+        while (listIterator.hasNext()) {
+            BgpValueType fsTlv = listIterator.next();
+            if (fsTlv.getType() == Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_ACTION) {
+                BgpFsActionTrafficAction trafficAction = (BgpFsActionTrafficAction) fsTlv;
+                trafficAction.write(cb);
+            } else if (fsTlv.getType() == Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_MARKING) {
+                BgpFsActionTrafficMarking trafficMarking = (BgpFsActionTrafficMarking) fsTlv;
+                trafficMarking.write(cb);
+            } else if (fsTlv.getType() == Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_RATE) {
+                BgpFsActionTrafficRate trafficRate = (BgpFsActionTrafficRate) fsTlv;
+                trafficRate.write(cb);
+            } else if (fsTlv.getType() == Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_REDIRECT) {
+                BgpFsActionReDirect trafficRedirect = (BgpFsActionReDirect) fsTlv;
+                trafficRedirect.write(cb);
+            }
         }
 
         int fsActionLen = cb.writerIndex() - iActionLenIndex;
diff --git a/protocols/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/flowspec/BgpFlowSpecDetailsTest.java b/protocols/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/flowspec/BgpFlowSpecDetailsTest.java
index 3152b26..15dfd4c 100644
--- a/protocols/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/flowspec/BgpFlowSpecDetailsTest.java
+++ b/protocols/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/flowspec/BgpFlowSpecDetailsTest.java
@@ -54,21 +54,29 @@
         operatorValue1.add(new BgpFsOperatorValue((byte) 0x81, port1));
         byte[] port11 = new byte[] {(byte) 0x1 };
         operatorValue1.add(new BgpFsOperatorValue((byte) 0x82, port11));
-        flowSpecDetails1.setFsActionTlv(new BgpFsActionTrafficRate((short) 1, 1));
+
+        List<BgpValueType> fsTlvs1 = new LinkedList<>();
+        fsTlvs1.add(new BgpFsActionTrafficRate((short) 1, 1));
+        flowSpecDetails1.setFsActionTlv(fsTlvs1);
 
         flowSpecComponents.add(portNum);
         byte[] port = new byte[] {(byte) 0x1 };
         operatorValue.add(new BgpFsOperatorValue((byte) 0x81, port));
         byte[] port4 = new byte[] {(byte) 0x1 };
         operatorValue.add(new BgpFsOperatorValue((byte) 0x82, port4));
-        flowSpecDetails.setFsActionTlv(new BgpFsActionTrafficRate((short) 1, 1));
+
+        List<BgpValueType> fsTlvs = new LinkedList<>();
+        fsTlvs.add(new BgpFsActionTrafficRate((short) 1, 1));
 
         flowSpecComponents2.add(portNum2);
         byte[] port2 = new byte[] {(byte) 0x1 };
         operatorValue2.add(new BgpFsOperatorValue((byte) 0x82, port2));
         byte[] port22 = new byte[] {(byte) 0x1 };
         operatorValue2.add(new BgpFsOperatorValue((byte) 0x82, port22));
-        flowSpecDetails2.setFsActionTlv(new BgpFsActionTrafficRate((short) 1, 1));
+
+        List<BgpValueType> fsTlvs2 = new LinkedList<>();
+        fsTlvs2.add(new BgpFsActionTrafficRate((short) 1, 1));
+        flowSpecDetails2.setFsActionTlv(fsTlvs2);
 
         new EqualsTester()
         .addEqualityGroup(flowSpecDetails1, flowSpecDetails)
diff --git a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java
index ce7a33c..b7480b0 100644
--- a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java
+++ b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java
@@ -252,8 +252,20 @@
 
         if (operType == FlowSpecOperation.ADD) {
             if (flowSpec.routeDistinguisher() == null) {
+                if (flowSpecRibOut.flowSpecTree().containsKey(prefix)) {
+                    sendFlowSpecUpdateMessageToPeer(FlowSpecOperation.DELETE,
+                                                    flowSpecRibOut.flowSpecTree().get(prefix));
+                }
                 flowSpecRibOut.add(prefix, flowSpec);
             } else {
+                if (vpnFlowSpecRibOut.vpnFlowSpecTree().containsKey(flowSpec.routeDistinguisher())) {
+                    Map<BgpFlowSpecPrefix, BgpFlowSpecDetails> fsTree;
+                    fsTree = vpnFlowSpecRibOut.vpnFlowSpecTree().get(flowSpec.routeDistinguisher());
+                    if (fsTree.containsKey(prefix)) {
+                        sendFlowSpecUpdateMessageToPeer(FlowSpecOperation.DELETE,
+                                                        fsTree.get(prefix));
+                    }
+                }
                 vpnFlowSpecRibOut.add(flowSpec.routeDistinguisher(), prefix, flowSpec);
             }
         } else if (operType == FlowSpecOperation.DELETE) {