FibManager module sync up
[netvirt.git] / vpnservice / fibmanager / fibmanager-impl / src / main / java / org / opendaylight / netvirt / fibmanager / NexthopManager.java
index b4f2917808151342a2f0cd36d6f08004f97b888c..ba7ccbad42562939fb8cefe48272af25b526f909 100644 (file)
@@ -94,25 +94,31 @@ public class NexthopManager implements AutoCloseable {
     private static final String NEXTHOP_ID_POOL_NAME = "nextHopPointerPool";
     private static final long FIXED_DELAY_IN_MILLISECONDS = 4000;
     private L3VPNTransportTypes configuredTransportTypeL3VPN = L3VPNTransportTypes.Invalid;
+    private Long waitTimeForSyncInstall;
 
     private static final FutureCallback<Void> DEFAULT_CALLBACK =
-        new FutureCallback<Void>() {
-            public void onSuccess(Void result) {
-                LOG.debug("Success in Datastore write operation");
-            }
-            public void onFailure(Throwable error) {
-                LOG.error("Error in Datastore write operation", error);
-            }
-        };
+            new FutureCallback<Void>() {
+                @Override
+                public void onSuccess(Void result) {
+                    LOG.debug("Success in Datastore write operation");
+                }
+                @Override
+                public void onFailure(Throwable error) {
+                    LOG.error("Error in Datastore write operation", error);
+                };
+            };
 
     /**
-    * Provides nexthop functions
-    * Creates group ID pool
-    *
-    * @param db - dataBroker reference
-    */
+     * Provides nexthop functions
+     * Creates group ID pool
+     *
+     * @param db - dataBroker reference
+     */
     public NexthopManager(final DataBroker db) {
         broker = db;
+        waitTimeForSyncInstall = Long.getLong("wait.time.sync.install");
+        if (waitTimeForSyncInstall == null)
+            waitTimeForSyncInstall = 1000L;
     }
 
     @Override
@@ -139,10 +145,10 @@ public class NexthopManager implements AutoCloseable {
 
     protected void createNexthopPointerPool() {
         CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
-            .setPoolName(NEXTHOP_ID_POOL_NAME)
-            .setLow(150000L)
-            .setHigh(175000L)
-            .build();
+                .setPoolName(NEXTHOP_ID_POOL_NAME)
+                .setLow(150000L)
+                .setHigh(175000L)
+                .build();
         //TODO: Error handling
         Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
         LOG.trace("NextHopPointerPool result : {}", result);
@@ -167,8 +173,8 @@ public class NexthopManager implements AutoCloseable {
 
     protected long createNextHopPointer(String nexthopKey) {
         AllocateIdInput getIdInput = new AllocateIdInputBuilder()
-            .setPoolName(NEXTHOP_ID_POOL_NAME).setIdKey(nexthopKey)
-            .build();
+                .setPoolName(NEXTHOP_ID_POOL_NAME).setIdKey(nexthopKey)
+                .build();
         //TODO: Proper error handling once IdManager code is complete
         try {
             Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
@@ -182,8 +188,8 @@ public class NexthopManager implements AutoCloseable {
 
     protected void removeNextHopPointer(String nexthopKey) {
         ReleaseIdInput idInput = new ReleaseIdInputBuilder().
-                                       setPoolName(NEXTHOP_ID_POOL_NAME)
-                                       .setIdKey(nexthopKey).build();
+                setPoolName(NEXTHOP_ID_POOL_NAME)
+                .setIdKey(nexthopKey).build();
         try {
             Future<RpcResult<Void>> result = idManager.releaseId(idInput);
             RpcResult<Void> rpcResult = result.get();
@@ -196,30 +202,30 @@ public class NexthopManager implements AutoCloseable {
     }
 
     protected List<ActionInfo> getEgressActionsForInterface(String ifName) {
-        List<ActionInfo> listActionInfo = new ArrayList<>();
+        List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
         try {
             Future<RpcResult<GetEgressActionsForInterfaceOutput>> result =
-                interfaceManager.getEgressActionsForInterface(
-                    new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName).build());
+                    interfaceManager.getEgressActionsForInterface(
+                            new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName).build());
             RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
             if(!rpcResult.isSuccessful()) {
                 LOG.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", ifName, rpcResult.getErrors());
             } else {
                 List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actions =
-                    rpcResult.getResult().getAction();
+                        rpcResult.getResult().getAction();
                 for (Action action : actions) {
                     org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionClass = action.getAction();
                     if (actionClass instanceof OutputActionCase) {
                         listActionInfo.add(new ActionInfo(ActionType.output,
-                                                          new String[] {((OutputActionCase)actionClass).getOutputAction()
-                                                                            .getOutputNodeConnector().getValue()}));
+                                new String[] {((OutputActionCase)actionClass).getOutputAction()
+                                        .getOutputNodeConnector().getValue()}));
                     } else if (actionClass instanceof PushVlanActionCase) {
                         listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {}));
                     } else if (actionClass instanceof SetFieldCase) {
                         if (((SetFieldCase)actionClass).getSetField().getVlanMatch() != null) {
                             int vlanVid = ((SetFieldCase)actionClass).getSetField().getVlanMatch().getVlanId().getVlanId().getValue();
                             listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid,
-                                                              new String[] { Long.toString(vlanVid) }));
+                                    new String[] { Long.toString(vlanVid) }));
                         }
                     }
                 }
@@ -232,11 +238,13 @@ public class NexthopManager implements AutoCloseable {
 
     protected String getTunnelInterfaceName(BigInteger srcDpId, BigInteger dstDpId) {
         Class<? extends TunnelTypeBase> tunType = getReqTunType(getReqTransType().toUpperCase());
+        Future<RpcResult<GetTunnelInterfaceNameOutput>> result;
         try {
-            Future<RpcResult<GetTunnelInterfaceNameOutput>> result = itmManager.getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder()
-                                                                                 .setSourceDpid(srcDpId)
-                                                                                 .setDestinationDpid(dstDpId)
-                                                                                .setTunnelType(tunType).build());
+            result = itmManager.getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder()
+                    .setSourceDpid(srcDpId)
+                    .setDestinationDpid(dstDpId)
+                    .setTunnelType(tunType)
+                    .build());
             RpcResult<GetTunnelInterfaceNameOutput> rpcResult = result.get();
             if(!rpcResult.isSuccessful()) {
                 LOG.warn("RPC Call to getTunnelInterfaceId returned with Errors {}", rpcResult.getErrors());
@@ -246,17 +254,20 @@ public class NexthopManager implements AutoCloseable {
         } catch (InterruptedException | ExecutionException e) {
             LOG.warn("Exception when getting tunnel interface Id for tunnel between {} and  {}", srcDpId, dstDpId, e);
         }
-        
         return null;
     }
 
-    protected String getTunnelInterfaceName(BigInteger srcDpId, IpAddress dstIp) {
+
+
+    protected String getTunnelInterfaceName(BigInteger srcDpId, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress dstIp) {
         Class<? extends TunnelTypeBase> tunType = getReqTunType(getReqTransType().toUpperCase());
+        Future<RpcResult<GetInternalOrExternalInterfaceNameOutput>> result;
         try {
-            Future<RpcResult<GetInternalOrExternalInterfaceNameOutput>> result = itmManager.getInternalOrExternalInterfaceName(new GetInternalOrExternalInterfaceNameInputBuilder()
-                                                                                 .setSourceDpid(srcDpId)
-                                                                                 .setDestinationIp(dstIp)
-                                                                                .setTunnelType(tunType).build());
+            result = itmManager.getInternalOrExternalInterfaceName(new GetInternalOrExternalInterfaceNameInputBuilder()
+                    .setSourceDpid(srcDpId)
+                    .setDestinationIp(dstIp)
+                    .setTunnelType(tunType)
+                    .build());
             RpcResult<GetInternalOrExternalInterfaceNameOutput> rpcResult = result.get();
             if(!rpcResult.isSuccessful()) {
                 LOG.warn("RPC Call to getTunnelInterfaceName returned with Errors {}", rpcResult.getErrors());
@@ -266,7 +277,6 @@ public class NexthopManager implements AutoCloseable {
         } catch (InterruptedException | ExecutionException e) {
             LOG.warn("Exception when getting tunnel interface Id for tunnel between {} and  {}", srcDpId, dstIp, e);
         }
-        
         return null;
     }
 
@@ -276,12 +286,13 @@ public class NexthopManager implements AutoCloseable {
         String nextHopLockStr = new String(vpnId + ipAddress);
         synchronized (nextHopLockStr.intern()) {
             VpnNexthop nexthop = getVpnNexthop(vpnId, ipAddress);
-            LOG.trace("nexthop: {}", nexthop);
+            LOG.trace("nexthop: {} retrieved for vpnId {}, prefix {}, ifName {} on dpn {}", nexthop,
+                    vpnId, ipAddress, ifName, dpnId);
             if (nexthop == null) {
                 Optional<Adjacency> adjacencyData =
                         read(LogicalDatastoreType.OPERATIONAL, getAdjacencyIdentifier(ifName, ipAddress));
                 String macAddress = adjacencyData.isPresent() ? adjacencyData.get().getMacAddress() : null;
-                List<BucketInfo> listBucketInfo = new ArrayList<>();
+                List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
                 List<ActionInfo> listActionInfo = getEgressActionsForInterface(ifName);
                 BucketInfo bucket = new BucketInfo(listActionInfo);
                 // MAC re-write
@@ -294,13 +305,20 @@ public class NexthopManager implements AutoCloseable {
                 }
                 listBucketInfo.add(bucket);
                 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(
-                        dpnId, groupId, ipAddress, GroupTypes.GroupIndirect, listBucketInfo);
-
-                //update MD-SAL DS
-                addVpnNexthopToDS(dpnId, vpnId, ipAddress, groupId);
+                        dpnId, groupId, ipAddress, GroupTypes.GroupAll, listBucketInfo);
+                LOG.trace("Install LNH Group: id {}, mac address {}, interface {} for prefix {}", groupId, macAddress, ifName, ipAddress);
 
                 // install Group
                 mdsalManager.syncInstallGroup(groupEntity, FIXED_DELAY_IN_MILLISECONDS);
+                try{
+                    LOG.info("Sleeping for {} to wait for the groups to get programmed.", waitTimeForSyncInstall);
+                    Thread.sleep(waitTimeForSyncInstall);
+                }catch(InterruptedException error){
+                    LOG.warn("Error while waiting for group {} to install.", groupId);
+                    LOG.debug("{}", error);
+                }
+                //update MD-SAL DS
+                addVpnNexthopToDS(dpnId, vpnId, ipAddress, groupId);
 
             } else {
                 //nexthop exists already; a new flow is going to point to it, increment the flowrefCount by 1
@@ -318,7 +336,7 @@ public class NexthopManager implements AutoCloseable {
     protected void addVpnNexthopToDS(BigInteger dpnId, long vpnId, String ipPrefix, long egressPointer) {
 
         InstanceIdentifierBuilder<VpnNexthops> idBuilder = InstanceIdentifier.builder(
-            L3nexthop.class)
+                L3nexthop.class)
                 .child(VpnNexthops.class, new VpnNexthopsKey(vpnId));
 
         // Add nexthop to vpn node
@@ -349,8 +367,8 @@ public class NexthopManager implements AutoCloseable {
 
         // check if vpn node is there
         InstanceIdentifierBuilder<VpnNexthops> idBuilder =
-            InstanceIdentifier.builder(L3nexthop.class).child(VpnNexthops.class,
-                                                              new VpnNexthopsKey(vpnId));
+                InstanceIdentifier.builder(L3nexthop.class).child(VpnNexthops.class,
+                        new VpnNexthopsKey(vpnId));
         InstanceIdentifier<VpnNexthops> id = idBuilder.build();
         Optional<VpnNexthops> vpnNexthops = read(LogicalDatastoreType.OPERATIONAL, id);
         if (vpnNexthops.isPresent()) {
@@ -369,19 +387,18 @@ public class NexthopManager implements AutoCloseable {
     }
 
 
-    public String getRemoteNextHopPointer(BigInteger localDpnId, BigInteger remoteDpnId,
-                                                    long vpnId, String prefixIp, String nextHopIp) {
+    public String getRemoteNextHopPointer(BigInteger remoteDpnId, long vpnId, String prefixIp, String nextHopIp) {
         String tunnelIfName = null;
-        LOG.trace("getRemoteNextHopPointer: input [localDpnId {} remoteDpnId {}, vpnId {}, prefixIp {}, nextHopIp {} ]",
-                  localDpnId, remoteDpnId, vpnId, prefixIp, nextHopIp);
+        LOG.trace("getRemoteNextHopPointer: input [remoteDpnId {}, vpnId {}, prefixIp {}, nextHopIp {} ]",
+                remoteDpnId, vpnId, prefixIp, nextHopIp);
 
-        LOG.trace("getRemoteNextHopPointer: Calling ITM with localDpnId {} ", localDpnId);
         if (nextHopIp != null && !nextHopIp.isEmpty()) {
             try{
                 // here use the config for tunnel type param
-                tunnelIfName = getTunnelInterfaceName(remoteDpnId, IpAddressBuilder.getDefaultInstance(nextHopIp));
-            }catch(Exception ex){
-            LOG.error("Error while retrieving nexthop pointer for nexthop {} : ", nextHopIp, ex.getMessage());
+                tunnelIfName = getTunnelInterfaceName(remoteDpnId, org.opendaylight.yang.gen.v1.urn.ietf.params.xml
+                        .ns.yang.ietf.inet.types.rev130715.IpAddressBuilder.getDefaultInstance(nextHopIp));
+            } catch(Exception ex){
+                LOG.error("Error while retrieving nexthop pointer for nexthop {} : ", nextHopIp, ex.getMessage());
             }
         }
         return tunnelIfName;
@@ -405,7 +422,7 @@ public class NexthopManager implements AutoCloseable {
         delete(LogicalDatastoreType.OPERATIONAL, id);
     }
 
+
     public void removeLocalNextHop(BigInteger dpnId, Long vpnId, String ipAddress) {
 
         String nextHopLockStr = new String(vpnId + ipAddress);
@@ -415,14 +432,14 @@ public class NexthopManager implements AutoCloseable {
                 int newFlowrefCnt = nh.getFlowrefCount() - 1;
                 if (newFlowrefCnt == 0) { //remove the group only if there are no more flows using this group
                     GroupEntity groupEntity = MDSALUtil.buildGroupEntity(
-                            dpnId, nh.getEgressPointer(), ipAddress, GroupTypes.GroupIndirect, null);
+                            dpnId, nh.getEgressPointer(), ipAddress, GroupTypes.GroupAll, null);
                     // remove Group ...
                     mdsalManager.removeGroup(groupEntity);
                     //update MD-SAL DS
                     removeVpnNexthopFromDS(vpnId, ipAddress);
                     //release groupId
                     removeNextHopPointer(getNextHopKey(vpnId, ipAddress));
-                    LOG.debug("Local Next hop for {} on dpn {} successfully deleted", ipAddress, dpnId);
+                    LOG.debug("Local Next hop {} for {} {} on dpn {} successfully deleted", nh.getEgressPointer(), vpnId, ipAddress, dpnId);
                 } else {
                     //just update the flowrefCount of the vpnNexthop
                     VpnNexthop currNh = new VpnNexthopBuilder().setKey(new VpnNexthopKey(ipAddress)).setFlowrefCount(newFlowrefCnt).build();
@@ -439,7 +456,7 @@ public class NexthopManager implements AutoCloseable {
 
 
     private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
-            InstanceIdentifier<T> path) {
+                                                    InstanceIdentifier<T> path) {
 
         ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
 
@@ -454,14 +471,14 @@ public class NexthopManager implements AutoCloseable {
     }
 
     private <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
-            InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
+                                                   InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
         WriteTransaction tx = broker.newWriteOnlyTransaction();
         tx.merge(datastoreType, path, data, true);
         Futures.addCallback(tx.submit(), callback);
     }
 
     private <T extends DataObject> void syncWrite(LogicalDatastoreType datastoreType,
-            InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
+                                                  InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
         WriteTransaction tx = broker.newWriteOnlyTransaction();
         tx.merge(datastoreType, path, data, true);
         tx.submit();
@@ -475,8 +492,8 @@ public class NexthopManager implements AutoCloseable {
 
     private InstanceIdentifier<Adjacency> getAdjacencyIdentifier(String vpnInterfaceName, String ipAddress) {
         return InstanceIdentifier.builder(VpnInterfaces.class)
-            .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).augmentation(
-                Adjacencies.class).child(Adjacency.class, new AdjacencyKey(ipAddress)).build();
+                .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).augmentation(
+                        Adjacencies.class).child(Adjacency.class, new AdjacencyKey(ipAddress)).build();
     }
 
     InstanceIdentifier<Adjacencies> getAdjListPath(String vpnInterfaceName) {
@@ -485,7 +502,6 @@ public class NexthopManager implements AutoCloseable {
                         Adjacencies.class).build();
     }
 
-
     public void setConfTransType(String service,String transportType) {
 
         if (!service.toUpperCase().equals("L3VPN")) {
@@ -557,7 +573,7 @@ public class NexthopManager implements AutoCloseable {
         return  confTransType;
     }
 
-    Class<? extends TunnelTypeBase> getReqTunType(String transportType) {
+    public Class<? extends TunnelTypeBase> getReqTunType(String transportType) {
         if (transportType.equals("VXLAN")) {
             return TunnelTypeVxlan.class;
         } else if (transportType.equals("GRE")) {
@@ -566,4 +582,16 @@ public class NexthopManager implements AutoCloseable {
             return TunnelTypeMplsOverGre.class;
         }
     }
+
+    public String getTransportTypeStr ( String tunType) {
+        if (tunType.equals(TunnelTypeVxlan.class.toString())) {
+            return ITMConstants.TUNNEL_TYPE_VXLAN;
+        } else if (tunType.equals(TunnelTypeGre.class.toString())) {
+            return ITMConstants.TUNNEL_TYPE_GRE;
+        } else if (tunType.equals(TunnelTypeMplsOverGre.class.toString())){
+            return ITMConstants.TUNNEL_TYPE_MPLS_OVER_GRE;
+        } else {
+            return ITMConstants.TUNNEL_TYPE_INVALID;
+        }
+    }
 }