[ONOS] cherry pick from onos1.6 to master all defects merges

Change-Id: I0ff6595a55b1104cf59a270ac2b10a7f831f6555
diff --git a/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProvider.java b/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProvider.java
index 8d45e08..f9740b5 100644
--- a/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProvider.java
+++ b/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProvider.java
@@ -449,28 +449,30 @@
             return;
         }
 
-        // If delegation flag is set then only send update message[means delegated PCE can send update msg for that
-        // LSP].If annotation is null D flag is not set else it is set.
-        Short localLspId = 0;
-        for (Tunnel t : tunnels) {
-            if (!t.tunnelId().equals(tunnel.tunnelId()) && t.tunnelName().equals(tunnel.tunnelName())) {
-                localLspId = Short.valueOf(t.annotations().value(LOCAL_LSP_ID));
-            }
-        }
-
-        if (localLspId == 0) {
-            log.error("Local LSP ID for old tunnel not found");
-            return;
-        }
-
         //PCInitiate tunnels are always have D flag set, else check for tunnels who are delegated via LspKey
         if (pc.capability().statefulPceCapability()) {
             if (tunnel.annotations().value(PCE_INIT) != null && tunnel.annotations().value(PCE_INIT).equals("true")) {
                 pcepUpdateTunnel(tunnel, path, pc);
-            } else if (pc.delegationInfo(
-                    new LspKey(Integer.valueOf(tunnel.annotations().value(PLSP_ID)),
-                            localLspId.shortValue())) != null) {
-                pcepUpdateTunnel(tunnel, path, pc);
+            } else {
+                // If delegation flag is set then only send update message[means delegated PCE can send update msg for
+                // that LSP. If annotation is null D flag is not set else it is set.
+                Short localLspId = 0;
+                for (Tunnel t : tunnels) {
+                    if (!t.tunnelId().equals(tunnel.tunnelId()) && t.tunnelName().equals(tunnel.tunnelName())) {
+                        localLspId = Short.valueOf(t.annotations().value(LOCAL_LSP_ID));
+                    }
+                }
+
+                if (localLspId == 0) {
+                    log.error("Local LSP ID for old tunnel not found");
+                    return;
+                }
+
+                if (pc.delegationInfo(new LspKey(Integer.valueOf(tunnel.annotations().value(PLSP_ID)),
+                                                 localLspId.shortValue())) != null) {
+
+                    pcepUpdateTunnel(tunnel, path, pc);
+                }
             }
         }
     }
@@ -571,18 +573,22 @@
         return tunnelId;
     }
 
-    private void tunnelUpdated(Tunnel tunnel, Path path) {
-        handleTunnelUpdate(tunnel, path);
+    private void tunnelUpdated(Tunnel tunnel, Path path, State tunnelState) {
+        handleTunnelUpdate(tunnel, path, tunnelState);
     }
 
     //Handles tunnel updated using tunnel admin service[specially to update annotations].
-    private void handleTunnelUpdate(Tunnel tunnel, Path path) {
+    private void handleTunnelUpdate(Tunnel tunnel, Path path, State tunnelState) {
 
         if (tunnel.type() == MPLS) {
             pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.tunnelId());
 
-            tunnelAdminService.updateTunnel(tunnel, path);
+            TunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(), tunnel.dst(),
+                    tunnel.type(), tunnel.groupId(), tunnel.providerId(),
+                    tunnel.tunnelName(), path, tunnel.resource(),
+                    (SparseAnnotations) tunnel.annotations());
 
+            service.tunnelUpdated(td, tunnelState);
             return;
         }
 
@@ -1059,7 +1065,7 @@
                             tunnel.path(),
                             tunnel.resource(),
                             tunnel.annotations());
-                    break;
+                            break;
                 }
             }
 
@@ -1238,14 +1244,12 @@
                 tlv = new SymbolicPathNameTlv(tunnel.tunnelName().value().getBytes());
                 llOptionalTlv.add(tlv);
             }
-
             boolean delegated = (tunnel.annotations().value(DELEGATE) == null) ? false
                                                                                : Boolean.valueOf(tunnel.annotations()
                                                                                        .value(DELEGATE));
             boolean initiated = (tunnel.annotations().value(PCE_INIT) == null) ? false
                                                                                : Boolean.valueOf(tunnel.annotations()
                                                                                        .value(PCE_INIT));
-
             // build lsp object
             PcepLspObject lspobj = pc.factory().buildLspObject().setAFlag(true)
                     .setPlspId(Integer.valueOf(tunnel.annotations().value(PLSP_ID)))
@@ -1254,7 +1258,6 @@
                     .setOptionalTlv(llOptionalTlv).build();
             // build ero object
             PcepEroObject eroobj = pc.factory().buildEroObject().setSubObjects(llSubObjects).build();
-
             float iBandwidth = DEFAULT_BANDWIDTH_VALUE;
             if (tunnel.annotations().value(BANDWIDTH) != null) {
                 iBandwidth = Float.parseFloat(tunnel.annotations().value(BANDWIDTH));
@@ -1449,10 +1452,8 @@
         }
 
         private SparseAnnotations getAnnotations(PcepLspObject lspObj, StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv,
-                float bandwidth, LspType lspType, String costType) {
-
+                String bandwidth, LspType lspType, String costType, boolean isPceInit) {
             Builder builder = DefaultAnnotations.builder();
-
             /*
              * [RFC 5440] The absence of the METRIC object MUST be interpreted by the PCE as a path computation request
              * for which no constraints need be applied to any of the metrics.
@@ -1461,8 +1462,16 @@
                 builder.set(COST_TYPE, costType);
             }
 
+            if (isPceInit) {
+                builder.set(PCE_INIT, String.valueOf(isPceInit));
+            }
+
+            if (bandwidth != null) {
+                builder.set(BANDWIDTH, bandwidth);
+            }
+
             SparseAnnotations annotations = builder
-                    .set(BANDWIDTH, (new Float(bandwidth)).toString()).set(LSP_SIG_TYPE, lspType.name())
+                    .set(LSP_SIG_TYPE, lspType.name())
                     .set(PCC_TUNNEL_ID, String.valueOf(ipv4LspIdenTlv.getTunnelId()))
                     .set(PLSP_ID, String.valueOf(lspObj.getPlspId()))
                     .set(LOCAL_LSP_ID, String.valueOf(ipv4LspIdenTlv.getLspId()))
@@ -1502,7 +1511,6 @@
                 log.error("ERO object is null in report message.");
                 return;
             }
-
             PcepAttribute attributes = msgPath.getPcepAttribute();
             float bandwidth = 0;
             int cost = 0;
@@ -1529,6 +1537,7 @@
                     bandwidth = attributes.getBandwidthObject().getBandwidth();
                 }
             }
+            PcepLspObject lspObj = stateRpt.getLspObject();
             List<Object> eroSubObjList = buildPathFromEroObj(eroObj, providerId);
             List<Link> links = new ArrayList<>();
             List<LabelResourceId> labels = new ArrayList<>();
@@ -1539,18 +1548,20 @@
                     labels.add(LabelResourceId.labelResourceId(((Integer) linkOrLabel).longValue()));
                 }
             }
-            Path path = new DefaultPath(providerId, links, cost, EMPTY);
+            Path path = null;
+            if (!links.isEmpty()) {
+                path = new DefaultPath(providerId, links, cost, EMPTY);
+            } else if (!lspObj.getRFlag()) {
+                return;
+            }
             NetworkResource labelStack = new DefaultLabelStack(labels);
             // To carry PST TLV, SRP object can be present with value 0 even when PCRpt is not in response to any action
             // from PCE.
             PcepSrpObject srpObj = stateRpt.getSrpObject();
             LspType lspType = getLspType(srpObj);
-
-            PcepLspObject lspObj = stateRpt.getLspObject();
             ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
             StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv = null;
             SymbolicPathNameTlv pathNameTlv = null;
-
             while (listTlvIterator.hasNext()) {
                 PcepValueType tlv = listTlvIterator.next();
                 switch (tlv.getType()) {
@@ -1577,7 +1588,6 @@
             IpTunnelEndPoint tunnelEndPointDst = IpTunnelEndPoint
                     .ipTunnelPoint(IpAddress.valueOf(ipv4LspIdenTlv.getIpv4EgressAddress()));
             Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(tunnelEndPointSrc, tunnelEndPointDst);
-
             // Store delegation flag info and that LSP info because only delegated PCE sends update message
             // Storing if D flag is set, if not dont store. while checking whether delegation if annotation for D flag
             // not present then non-delegated , if present it is delegated.
@@ -1586,6 +1596,7 @@
                         new LspKey(lspObj.getPlspId(), ipv4LspIdenTlv.getLspId()), lspObj.getDFlag());
             }
             Tunnel tunnel = null;
+            SparseAnnotations oldTunnelAnnotations = null;
             // Asynchronous status change message from PCC for LSP reported earlier.
             for (Tunnel tunnelObj : tunnelQueryResult) {
                 if (tunnelObj.annotations().value(PLSP_ID) == null) {
@@ -1603,13 +1614,17 @@
                     }
                     continue;
                 }
-                if ((Integer.valueOf(tunnelObj.annotations().value(PLSP_ID)) == lspObj.getPlspId()) && (Integer
-                        .valueOf(tunnelObj.annotations().value(LOCAL_LSP_ID)) == ipv4LspIdenTlv.getLspId())) {
-                    tunnel = tunnelObj;
-                    break;
+                if ((Integer.valueOf(tunnelObj.annotations().value(PLSP_ID)) == lspObj.getPlspId())) {
+                    if ((Integer
+                            .valueOf(tunnelObj.annotations().value(LOCAL_LSP_ID)) == ipv4LspIdenTlv.getLspId())) {
+                        tunnel = tunnelObj;
+                    }
+                    if ((Integer
+                            .valueOf(tunnelObj.annotations().value(LOCAL_LSP_ID)) != ipv4LspIdenTlv.getLspId())) {
+                        oldTunnelAnnotations = (SparseAnnotations) tunnelObj.annotations();
+                    }
                 }
             }
-
             DefaultTunnelDescription td;
             SparseAnnotations annotations = null;
             State tunnelState = PcepLspStatus.getTunnelStatusFromLspStatus(PcepLspStatus.values()[lspObj.getOFlag()]);
@@ -1621,24 +1636,27 @@
                      */
                     return;
                 }
-
                 DeviceId deviceId = getDevice(pccId);
                 if (deviceId == null) {
                     log.error("Ingress deviceId not found");
                     return;
                 }
-                annotations = getAnnotations(lspObj, ipv4LspIdenTlv, bandwidth, lspType, costType);
-
+                String tempBandwidth = null;
+                String temoCostType = null;
+                if (oldTunnelAnnotations != null) {
+                    tempBandwidth = oldTunnelAnnotations.value(BANDWIDTH);
+                    temoCostType = oldTunnelAnnotations.value(COST_TYPE);
+                }
+                annotations = getAnnotations(lspObj, ipv4LspIdenTlv, tempBandwidth, lspType,
+                    temoCostType, lspObj.getCFlag());
                 td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
                         0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())), path, labelStack,
                         annotations);
-
                 // Do not support PCC initiated LSP after LSP DB sync is completed.
                 if (!lspObj.getSFlag() && !lspObj.getCFlag()) {
                     log.error("Received PCC initiated LSP while not in sync.");
                     return;
                 }
-
                 /*
                  * If ONOS instance is master for PCC then set delegated flag as annotation and add the tunnel to store.
                  * Because all LSPs need not be delegated, hence mastership for the PCC is confirmed whereas not the
@@ -1670,43 +1688,54 @@
                     pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
                 } else if (!mastershipService.isLocalMaster(deviceId) && lspObj.getDFlag()) {
                     //Start timer then update the tunnel with D flag
-                    tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId);
+                    tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId, tunnelState, ipv4LspIdenTlv);
                 }
                 return;
             }
-
             //delegated owner will update can be a master or non-master
-            if (lspObj.getDFlag()) {
-
-                if (tunnel.annotations().value(BANDWIDTH) != null) {
-                    bandwidth = Float.parseFloat(tunnel.annotations().value(BANDWIDTH));
-                }
-                annotations = getAnnotations(lspObj, ipv4LspIdenTlv,
-                        bandwidth, lspType,
-                        tunnel.annotations().value(COST_TYPE));
-                td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
-                        0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())),
-                        tunnel.path(), labelStack, annotations);
-                tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId);
+            if (lspObj.getDFlag() && !lspObj.getRFlag()) {
+                tunnelUpdateForDelegatedLsp(tunnel, lspObj,
+                        lspType, tunnelState, pccId, labelStack, ipv4LspIdenTlv);
+                return;
             }
-            removeOrUpdatetunnel(tunnel, pccId, lspObj, providerId, tunnelState);
-            return;
+            removeOrUpdatetunnel(tunnel, lspObj, providerId, tunnelState, ipv4LspIdenTlv);
         }
 
-        private void removeOrUpdatetunnel(Tunnel tunnel, PccId pccId, PcepLspObject lspObj, ProviderId providerId,
-                State tunnelState) {
+        private void tunnelUpdateForDelegatedLsp(Tunnel tunnel, PcepLspObject lspObj,
+                                                 LspType lspType, State tunnelState, PccId pccId,
+                                                 NetworkResource labelStack,
+                                                 StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv) {
+            SparseAnnotations annotations = null;
+            DefaultTunnelDescription td;
+            boolean isPceInit = tunnel.annotations().value(PCE_INIT) == null ? false :
+                    Boolean.valueOf((tunnel.annotations().value(PCE_INIT))).booleanValue();
+            annotations = getAnnotations(lspObj, ipv4LspIdenTlv,
+                    tunnel.annotations().value(BANDWIDTH), lspType,
+                    tunnel.annotations().value(COST_TYPE), isPceInit);
+            td = new DefaultTunnelDescription(null, tunnel.src(), tunnel.dst(), MPLS, new DefaultGroupId(
+                    0), tunnel.providerId(), tunnel.tunnelName(),
+                    tunnel.path(), labelStack, annotations);
+            tunnelUpdateInDelegatedCase(pccId, annotations, td, tunnel.providerId(), tunnelState, ipv4LspIdenTlv);
+        }
+
+        private void removeOrUpdatetunnel(Tunnel tunnel, PcepLspObject lspObj, ProviderId providerId,
+                State tunnelState, StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv) {
             DefaultTunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(), tunnel.dst(),
                     tunnel.type(), tunnel.groupId(), providerId, tunnel.tunnelName(), tunnel.path(),
                     (SparseAnnotations) tunnel.annotations());
             if (lspObj.getRFlag()) {
                 tunnelRemoved(td);
             } else {
+                PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, tunnel.path(), LSP_STATE_RPT);
+                pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspIdenTlv);
+                pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
                 tunnelUpdated(td, tunnelState);
             }
         }
 
         private void tunnelUpdateInDelegatedCase(PccId pccId, SparseAnnotations annotations,
-                DefaultTunnelDescription td, ProviderId providerId) {
+                DefaultTunnelDescription td, ProviderId providerId, State tunnelState,
+                                                 StatefulIPv4LspIdentifiersTlv ipv4LspIdentifiersTlv) {
             //Wait for 2sec then query tunnel based on ingress PLSP-ID and local LSP-ID
 
             /*
@@ -1717,7 +1746,7 @@
 
             // Thread is started after 2 seconds first time later periodically after 2 seconds to update the tunnel
             executor.scheduleAtFixedRate(new UpdateDelegation(td, providerId, annotations, pccId,
-                    executor), DELAY, DELAY, TimeUnit.SECONDS);
+                    executor, tunnelState, ipv4LspIdentifiersTlv), DELAY, DELAY, TimeUnit.SECONDS);
         }
 
         /**
@@ -1733,7 +1762,7 @@
             LinkedList<PcepValueType> llSubObj = eroObj.getSubObjects();
             if (0 == llSubObj.size()) {
                 log.error("ERO in report message does not have hop information");
-                return null;
+                return new ArrayList<>();
             }
             ListIterator<PcepValueType> tlvIterator = llSubObj.listIterator();
 
@@ -1787,10 +1816,29 @@
 
                     if (srEroSubObj.getSt() == PcepNaiIpv4Adjacency.ST_TYPE) {
                         PcepNaiIpv4Adjacency nai = (PcepNaiIpv4Adjacency) (srEroSubObj.getNai());
-                        IpAddress srcIp = IpAddress.valueOf(nai.getLocalIpv4Addr());
-                        src = new ConnectPoint(IpElementId.ipElement(srcIp), PortNumber.portNumber(0));
-                        IpAddress dstIp = IpAddress.valueOf(nai.getRemoteIpv4Addr());
-                        dst = new ConnectPoint(IpElementId.ipElement(dstIp), PortNumber.portNumber(0));
+                        int srcIp = nai.getLocalIpv4Addr();
+                        int dstIp = nai.getRemoteIpv4Addr();
+                        Iterable<Link> links = linkService.getActiveLinks();
+                        for (Link l : links) {
+                            long lSrc = l.src().port().toLong();
+                            long lDst = l.dst().port().toLong();
+                            if (lSrc == srcIp) {
+                                src = l.src();
+                            } else if (lDst == srcIp) {
+                                src = l.dst();
+                            }
+                            if (lSrc == dstIp) {
+                                dst = l.src();
+                            } else if (lDst == dstIp) {
+                                dst = l.dst();
+                            }
+                            if (src != null && dst != null) {
+                                break;
+                            }
+                        }
+                        if (src == null || dst == null) {
+                            return new ArrayList<>();
+                        }
                         Link link = DefaultLink.builder()
                                 .providerId(providerId)
                                 .src(src)
@@ -1803,7 +1851,6 @@
                     // the other sub objects are not required
                 }
             }
-
             return subObjList;
         }
 
@@ -1861,7 +1908,6 @@
         return service.tunnelQueryById(tunnelId);
     }
 
-
     private DeviceId getDevice(PccId pccId) {
         // Get lsrId of the PCEP client from the PCC ID. Session info is based on lsrID.
         IpAddress lsrId = pccId.ipAddress();
@@ -1888,6 +1934,8 @@
         SparseAnnotations annotations;
         PccId pccId;
         ScheduledExecutorService executor;
+        State tunnelState;
+        StatefulIPv4LspIdentifiersTlv ipv4LspIdentifiersTlv;
 
         /**
          * Creates an instance of UpdateDelegation.
@@ -1899,12 +1947,15 @@
          * @param executor service of delegated owner
          */
         public UpdateDelegation(DefaultTunnelDescription td, ProviderId providerId, SparseAnnotations annotations,
-                PccId pccId, ScheduledExecutorService executor) {
+                PccId pccId, ScheduledExecutorService executor, State tunnelState,
+                                StatefulIPv4LspIdentifiersTlv ipv4LspIdentifiersTlv) {
             this.td = td;
             this.providerId = providerId;
             this.annotations = annotations;
             this.pccId = pccId;
             this.executor = executor;
+            this.tunnelState = tunnelState;
+            this.ipv4LspIdentifiersTlv = ipv4LspIdentifiersTlv;
         }
 
         //Temporary using annotations later will use projection/network config service
@@ -1930,7 +1981,11 @@
             if (tempTunnelId != null) {
                 Tunnel tunnel = new DefaultTunnel(providerId, td.src(), td.dst(), MPLS, new DefaultGroupId(0),
                         tempTunnelId, td.tunnelName(), td.path(), annotations);
-                tunnelUpdated(tunnel, td.path());
+                PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, tunnel.path(), LSP_STATE_RPT);
+                pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspIdentifiersTlv);
+                pcepTunnelData.setLspDFlag(Boolean.valueOf(tunnel.annotations().value(DELEGATE)));
+                pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
+                tunnelUpdated(tunnel, td.path(), tunnelState);
                 executor.shutdown();
                 try {
                     executor.awaitTermination(WAIT_TIME, TimeUnit.SECONDS);