Merge "Replace dlux with dluxapps features"
authorDavid Goldberg <gdavid@hpe.com>
Mon, 9 Jan 2017 10:07:39 +0000 (10:07 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 9 Jan 2017 10:07:39 +0000 (10:07 +0000)
12 files changed:
dlux/cpeui/cpeui-module/src/main/resources/cpeui/admin.controller.js
dlux/cpeui/cpeui-module/src/main/resources/cpeui/admin.tpl.html
dlux/cpeui/cpeui-module/src/main/resources/cpeui/cpeui.controller.js
dlux/cpeui/cpeui-module/src/main/resources/cpeui/cpeui.module.js
dlux/cpeui/cpeui-module/src/main/resources/cpeui/dialogs/AddProfile.tpl.html
dlux/cpeui/cpeui-module/src/main/resources/cpeui/services/cpeui.dialogs.js
dlux/cpeui/cpeui-module/src/main/resources/cpeui/services/utils.js [new file with mode: 0644]
dlux/cpeui/cpeui-module/src/main/resources/cpeui/utils.js [deleted file]
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/DataWaitListener.java
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/IpvcListener.java
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/NetvirtVpnUtils.java
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/SubnetListener.java

index edcf42a2c9ac8f03d1b10ff514f1da055ad4b7e0..91bad4d7e634b15f2dd65991366acd805195e436 100644 (file)
@@ -47,24 +47,35 @@ define([ 'app/cpeui/cpeui.module' ], function(cpeui) {
           });
         };
 
-        $scope.addProfile = new CpeuiDialogs.Dialog('AddProfile', {}, function(obj) {
-            if (obj.default_cbs) {
-                obj.cbs = Math.floor(obj.cir/10);
+        var profileDialogController = function($scope, $mdDialog) {
+
+            $scope.getDefualtCbs = function(cir) {
+                return Math.round(cir * 0.0125);
             }
+
+            $scope.done = function() {
+                if ($scope.obj.default_cbs) {
+                    $scope.obj.cbs = $scope.getDefualtCbs($scope.obj.cir);
+                }
+                if ($scope.projectForm.$valid) {
+                  $scope.callback($scope.obj);
+                  $mdDialog.hide();
+                }
+              };
+          };
+
+        $scope.addProfile = new CpeuiDialogs.Dialog('AddProfile', {}, function(obj) {
             CpeuiSvc.addProfile(obj['bw-profile'], obj.cir, obj.cbs, function() {
               $scope.updateProfilesView();
             });
-        });
+        }, profileDialogController);
 
         $scope.editProfile = function(profileName, cbs, cir) {
             new CpeuiDialogs.Dialog('AddProfile', {}, function(obj) {
-                if (obj.default_cbs) {
-                    obj.cbs = Math.floor(obj.cir/10);
-                }
                 CpeuiSvc.editProfile(obj['bw-profile'], obj.cir, obj.cbs, function() {
                   $scope.updateProfilesView();
                 });
-            }).show(null,{edit:true, profileName:profileName, cbs:cbs, cir:cir});
+            }, profileDialogController).show(null,{edit:true, profileName:profileName, cbs:cbs, cir:cir});
         };
 
         $scope.deleteProfile = function(profileName) {
index 8827a486c59d5c15367f61bd936c80e61d352fa3..3ded6f0d94a984c84e91fff7d7490ed24e5d0b63 100644 (file)
                        <thead>
                                <tr>
                                        <th>Profile Name</th>
-                                       <th>Committed Information Rate (KB/s)</th>
-                                       <th>Committed Burst Size (bytes)</th>
+                                       <th>Committed Information Rate (kb/s)</th>
+                                       <th>Committed Burst Size (Bytes)</th>
                                        <th></th>
                                </tr>
                        </thead>
index a381bcc9260b7368d32b18df88bdb6106a8b32c4..046e45786093d21c08619074ae98fd51f8897057 100644 (file)
@@ -3,6 +3,7 @@ var controllers = ['app/cpeui/cpeui.controller',
                    'app/cpeui/tenant.controller', 
                    'app/cpeui/tenantsTable.controller' ];
 var services = ['app/cpeui/services/cpeui.services',
+                'app/cpeui/services/utils',
                 'app/cpeui/services/cpeui.dialogs', ];
 var directives = [];
 var modules = [ 'app/cpeui/cpeui.module' ];
@@ -11,10 +12,6 @@ define([].concat(modules).concat(services).concat(directives).concat(controllers
 
   cpeui.controller('CpeuiCtrl', function($scope, $rootScope, $state, $mdDialog,$mdMedia) {
 
-    $rootScope['section_logo'] = 'static/cpe.png'; // Add your topbar logo
-                                                    // location here such as
-                                                    // 'assets/images/logo_topology.gif'
-
     $rootScope.section_logo = 'src/app/cpeui/static/logo_hpe.gif';
 
     var mainTabIndexs = {
index 1bf1e32ec4bf5f72b1073096a8082747ca675189..071e04b7bf435e29d8840aa063b360cb3351efdd 100644 (file)
@@ -3,11 +3,11 @@ define([ 'angularAMD', 'app/routingConfig', 'app/core/core.services',
     'app/cpeui/assets/angular-material.min',
     'app/cpeui/assets/angular-animate.min',
     'app/cpeui/assets/angular-aria.min',
-    'app/cpeui/assets/angular-messages.min', 'app/cpeui/utils' ], function(ng) {
+    'app/cpeui/assets/angular-messages.min'], function(ng) {
 
   var cpeui = angular.module('app.cpeui', [ 'app.core', 'ui.router.state','restangular', 'config', 'ngMaterial', 'ngMessages', 'ngAnimate' ]);
 
-  cpeui.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider) {
+  cpeui.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider, $translateProvider, $urlRouterProvider) {
 
     cpeui.register = cpeui; // for adding services, controllers, directives etc.
                             // to angular module before bootstrap
@@ -19,6 +19,8 @@ define([ 'angularAMD', 'app/routingConfig', 'app/core/core.services',
       service : $provide.service
 
     };
+    
+    $urlRouterProvider.otherwise("/cpeui/admin/");
 
     NavHelperProvider.addControllerUrl('app/cpeui/cpeui.controller');
     NavHelperProvider.addToMenu('cpe', {
index c298373f6570060f4df43a8d60b6ecf1212a4899..dd2355dd2775386d109d45b20d200b60ea8816ea 100644 (file)
                                <md-content layout-padding>
                                        <md-input-container class="md-block" ng-init="obj['bw-profile'] = params.profileName">
                                                <label>Profile Name</label>
-                                               <input name="profilename" ng-model="obj['bw-profile']" ng-disabled="params.edit">
+                                               <input name="profilename" required ng-model="obj['bw-profile']" ng-disabled="params.edit">
                                                <div ng-messages="projectForm.profilename.$error">
                                                        <div ng-message="required">This is required!</div>
                                                </div>
                                        </md-input-container>
                                        <md-input-container class="md-block" ng-init="obj.cir = params.cir">
-                                               <label>Committed Information Rate (KB/s)</label>
+                                               <label>Committed Information Rate (kb/s)</label>
                                                <input type="number" required name="cir" ng-model="obj.cir" min="0">
                                                <div ng-messages="projectForm.cir.$error">
                                                        <div ng-message="required">Number is required!</div>
                                                        <div ng-message="min">Number must be positive!</div>
                                                </div>
                                        </md-input-container>
-                                       <md-checkbox name="" ng-model="obj.default_cbs" ng-init="obj.default_cbs = true">
-                                          Use default Committed Burst Size {{obj.cir ? '('+((obj.cir - (obj.cir % 10)) / 10) + ' bytes)': ''}}
+                                       <md-checkbox name="" ng-model="obj.default_cbs" ng-init="obj.default_cbs = (!params.edit || getDefualtCbs(params.cir) == params.cbs)">
+                                          Use default Committed Burst Size {{obj.cir ? ('(' + getDefualtCbs(obj.cir) + ' Bytes)') : ''}}
                                        </md-checkbox>
                                        <md-input-container class="md-block" ng-if="!obj.default_cbs" ng-init="obj.cbs = params.cbs">
-                                               <label>Committed Burst Size (bytes)</label>
+                                               <label>Committed Burst Size (Bytes)</label>
                                                <input type="number" required name="cbs" ng-model="obj.cbs" min="0">
                                                <div ng-messages="projectForm.cbs.$error">
                                                        <div ng-message="required">Number is required!</div>
index 27b52ec183b7f50ba436eaa75af284881cf3efa7..6d4a45561b07b03becd985ec11f4d86e59a66c42 100644 (file)
@@ -9,6 +9,7 @@ define([ 'app/cpeui/cpeui.module' ], function(cpeui) {
 
       this.dialogController = function($scope, $mdDialog, params) {
         $scope.params = params;
+        $scope.callback = callback;
 
         $scope.obj = {};
         $scope.hide = function() {
@@ -19,7 +20,7 @@ define([ 'app/cpeui/cpeui.module' ], function(cpeui) {
         };
         $scope.done = function() {
           if ($scope.projectForm.$valid) {
-            callback($scope.obj);
+            $scope.callback($scope.obj);
             $mdDialog.hide();
           }
         };
diff --git a/dlux/cpeui/cpeui-module/src/main/resources/cpeui/services/utils.js b/dlux/cpeui/cpeui-module/src/main/resources/cpeui/services/utils.js
new file mode 100644 (file)
index 0000000..c181d24
--- /dev/null
@@ -0,0 +1,11 @@
+define([ 'app/cpeui/cpeui.module' ], function(cpeui) {
+
+  Array.prototype.filterByField = function(field_name, value, to_filter_out) {
+      if (to_filter_out == undefined) {
+          to_filter_out = false;
+      }
+      return this.filter(function(item) {
+          return (item[field_name] == value) != to_filter_out;
+      });
+  };
+});
diff --git a/dlux/cpeui/cpeui-module/src/main/resources/cpeui/utils.js b/dlux/cpeui/cpeui-module/src/main/resources/cpeui/utils.js
deleted file mode 100644 (file)
index 5eb3595..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-Array.prototype.filterByField = function(field_name, value, to_filter_out) {
-  if (to_filter_out == undefined) {
-    to_filter_out = false;
-  }
-  return this.filter(function(item) {
-    return (item[field_name] == value) != to_filter_out;
-  });
-};
\ No newline at end of file
index bd4e599ebe0c6620fa8b56209b5bc382583fd1ca..ecce5e7ebdf8a011f0174458936cfa78b1b063cd 100644 (file)
@@ -26,7 +26,8 @@ public class DataWaitListener<D extends DataObject> extends UnimgrDataTreeChange
     private static final Logger Log = LoggerFactory.getLogger(DataWaitListener.class);
     InstanceIdentifier<D> objectIdentifierId;
     private ListenerRegistration<DataWaitListener> dataWaitListenerRegistration;
-    Boolean dataAvailable = false;
+    private Boolean dataAvailable = false;
+    private final Object lockDataAvailable = new Object();
     private int maxRetries;
     LogicalDatastoreType logicalDatastoreType;
     DataWaitGetter<D> getData;
@@ -65,8 +66,8 @@ public class DataWaitListener<D extends DataObject> extends UnimgrDataTreeChange
         if (newDataObject.getRootPath() != null && newDataObject.getRootNode() != null) {
             Log.info("data {} created", newDataObject.getRootNode().getIdentifier());
         }
-        synchronized (dataAvailable) {
-            dataAvailable.notifyAll();
+        synchronized (lockDataAvailable) {
+            lockDataAvailable.notifyAll();
         }
     }
 
@@ -79,8 +80,8 @@ public class DataWaitListener<D extends DataObject> extends UnimgrDataTreeChange
         if (modifiedDataObject.getRootPath() != null && modifiedDataObject.getRootNode() != null) {
             Log.info("data {} updated", modifiedDataObject.getRootNode().getIdentifier());
         }
-        synchronized (dataAvailable) {
-            dataAvailable.notifyAll();
+        synchronized (lockDataAvailable) {
+            lockDataAvailable.notifyAll();
         }
     }
 
@@ -105,7 +106,7 @@ public class DataWaitListener<D extends DataObject> extends UnimgrDataTreeChange
     }
 
     public boolean waitForData(int retry) {
-        synchronized (dataAvailable) {
+        synchronized (lockDataAvailable) {
             dataAvailable = dataAvailable();
             if (dataAvailable == true) {
                 return true;
@@ -113,7 +114,7 @@ public class DataWaitListener<D extends DataObject> extends UnimgrDataTreeChange
                 return false;
             }
             try {
-                dataAvailable.wait(waitMillisec);
+                lockDataAvailable.wait(waitMillisec);
             } catch (InterruptedException e1) {
             }
         }
index 69f394674af36b1c9f90e9df8c673f7e15265b61..f11ea929e9d972de7fded6005db59c0228cd51b6 100644 (file)
@@ -32,6 +32,8 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface.EtreeInterfaceType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -111,8 +113,8 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> {
                 MdsalUtils.commitTransaction(tx);
 
                 InstanceIdentifier<VpnInstance> vpnId = NetvirtVpnUtils.getVpnInstanceToVpnIdIdentifier(vpnName);
-                DataWaitListener<VpnInstance> vpnInstanceWaiter = new DataWaitListener<VpnInstance>(dataBroker, vpnId,
-                        5, LogicalDatastoreType.CONFIGURATION, vpn -> vpn.getVrfId());
+                DataWaitListener<VpnInstance> vpnInstanceWaiter = new DataWaitListener<>(dataBroker, vpnId, 10,
+                        LogicalDatastoreType.CONFIGURATION, vpn -> vpn.getVrfId());
                 if (!vpnInstanceWaiter.waitForData()) {
                     String errorMessage = String.format("Fail to wait for vrfId for vpn %s", vpnName);
                     Log.error(errorMessage);
@@ -213,7 +215,7 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> {
             String vpnName = operIpvcVpn.getVpnId();
             InstanceIdentifier<VpnInstance> vpnId = NetvirtVpnUtils.getVpnInstanceToVpnIdIdentifier(vpnName);
             @SuppressWarnings("resource")
-            DataWaitListener<VpnInstance> vpnInstanceWaiter = new DataWaitListener<VpnInstance>(dataBroker, vpnId, 5,
+            DataWaitListener<VpnInstance> vpnInstanceWaiter = new DataWaitListener<>(dataBroker, vpnId, 10,
                     LogicalDatastoreType.CONFIGURATION, vpn -> vpn.getVrfId());
             if (!vpnInstanceWaiter.waitForData()) {
                 String errorMessage = String.format("Fail to wait for vrfId for vpn %s", vpnName);
@@ -233,14 +235,14 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> {
                 uniToRemove.removeAll(updateUni);
                 removeUnis(ipvcId, operIpvcVpn, uniToRemove, txRemove);
                 MdsalUtils.commitTransaction(txRemove);
+            }
+            List<Uni> uniToCreate = new ArrayList<>(updateUni);
+            uniToCreate.removeAll(originalUni);
 
-                List<Uni> uniToCreate = new ArrayList<>(updateUni);
-                uniToCreate.removeAll(originalUni);
-                for (Uni uni : uniToCreate) {
-                    createInterfaces(vpnName, uni, ipvcId, rd);
-                }
-                createUnis(ipvcId, uniToCreate);
+            for (Uni uni : uniToCreate) {
+                createInterfaces(vpnName, uni, ipvcId, rd);
             }
+            createUnis(ipvcId, uniToCreate);
 
         } catch (final Exception e) {
             Log.error("Update ipvc failed !", e);
@@ -285,18 +287,35 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> {
             MdsalUtils.commitTransaction(tx);
         }
 
+        waitForInterfaceDpn(vpnName, rd, interfaceName);
+
+        NetvirtVpnUtils.createVpnPortFixedIp(dataBroker, vpnName, interfaceName, ipUni.getIpAddress(),
+                uni.getMacAddress());
+    }
+
+    private void waitForInterfaceDpn(String vpnName, String rd, String interfaceName) {
         InstanceIdentifier<VpnInstanceOpDataEntry> vpnId = NetvirtVpnUtils.getVpnInstanceOpDataIdentifier(rd);
+        DataWaitGetter<VpnInstanceOpDataEntry> getInterfByName = (vpn) -> {
+            if (vpn.getVpnToDpnList() == null)
+                return null;
+            for (VpnToDpnList is : vpn.getVpnToDpnList()) {
+                if (is.getVpnInterfaces() == null)
+                    continue;
+                for (VpnInterfaces i : is.getVpnInterfaces()) {
+                    if (i.getInterfaceName().equals(interfaceName))
+                        return interfaceName;
+                }
+            }
+            return null;
+        };
         @SuppressWarnings("resource")
-        DataWaitListener<VpnInstanceOpDataEntry> vpnInstanceWaiter = new DataWaitListener<VpnInstanceOpDataEntry>(
-                dataBroker, vpnId, 5, LogicalDatastoreType.OPERATIONAL, vpn -> vpn.getVpnToDpnList());
+        DataWaitListener<VpnInstanceOpDataEntry> vpnInstanceWaiter = new DataWaitListener<>(dataBroker, vpnId, 10,
+                LogicalDatastoreType.OPERATIONAL, getInterfByName);
         if (!vpnInstanceWaiter.waitForData()) {
             String errorMessage = String.format("Fail to wait for vpn to dpn list %s", vpnName);
             Log.error(errorMessage);
             throw new UnsupportedOperationException(errorMessage);
         }
-
-        NetvirtVpnUtils.createVpnPortFixedIp(dataBroker, vpnName, interfaceName, ipUni.getIpAddress(),
-                uni.getMacAddress());
     }
 
     private String createElanInterface(String vpnName, InstanceIdentifier<Ipvc> ipvcId, String uniId, String elanName,
index 5e6bcaf0ee44cfbe4350c11adef6628e7f751e6c..a180cb32b3bdea172f1b43d4f0063fb148150c58 100644 (file)
@@ -315,11 +315,11 @@ public class NetvirtVpnUtils {
 
     public static void addDirectSubnetToVpn(DataBroker dataBroker,
             final NotificationPublishService notificationPublishService, String vpnName, String subnetName,
-            IpPrefix subnetIpPrefix, String interfaceName, int waitForElan) {
+            IpPrefix subnetIpPrefix, String interfaceName, String intfMac, int waitForElan) {
         InstanceIdentifier<ElanInstance> elanIdentifierId = NetvirtUtils.getElanInstanceInstanceIdentifier(subnetName);
 
         @SuppressWarnings("resource") // AutoCloseable
-        DataWaitListener<ElanInstance> elanTagWaiter = new DataWaitListener<ElanInstance>(dataBroker, elanIdentifierId,
+        DataWaitListener<ElanInstance> elanTagWaiter = new DataWaitListener<>(dataBroker, elanIdentifierId,
                 10, LogicalDatastoreType.CONFIGURATION, el -> el.getElanTag());
         if (!elanTagWaiter.waitForData()) {
             logger.error("Trying to add invalid elan {} to vpn {}", subnetName, vpnName);
@@ -332,10 +332,10 @@ public class NetvirtVpnUtils {
 
         String subnetIp = getSubnetFromPrefix(ipPrefixToString(subnetIpPrefix));
         logger.info("Adding subnet {} {} to vpn {}", subnetName, subnetIp, vpnName);
-        updateSubnetNode(dataBroker, new Uuid(vpnName), subnetId, subnetIp);
+        updateSubnetNode(dataBroker, new Uuid(vpnName), subnetId, subnetIp, intfMac);
 
         logger.info("Adding port {} to subnet {}", interfaceName, subnetName);
-        updateSubnetmapNodeWithPorts(dataBroker, subnetId, new Uuid(interfaceName), null);
+        updateSubnetmapNodeWithPorts(dataBroker, subnetId, new Uuid(interfaceName), null, vpnName);
 
         Optional<ElanInstance> elanInstance = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
                 elanIdentifierId);
@@ -365,7 +365,7 @@ public class NetvirtVpnUtils {
         publishSubnetRemoveNotification(notificationPublishService, subnetId, vpnName, elanTag);
 
         logger.info("Removing port {} from subnet {}", interfaceName, subnetName);
-        updateSubnetmapNodeWithPorts(dataBroker, subnetId, null, new Uuid(interfaceName));
+        updateSubnetmapNodeWithPorts(dataBroker, subnetId, null, new Uuid(interfaceName), vpnName);
 
         logger.info("Removing subnet {} from vpn {}", subnetName, vpnName);
         removeSubnetNode(dataBroker, new Uuid(vpnName));
@@ -404,7 +404,8 @@ public class NetvirtVpnUtils {
         logger.debug("Deleted subnet-network mapping for  network {}", networkId.getValue());
     }
 
-    protected static void updateSubnetNode(DataBroker dataBroker, Uuid vpnId, Uuid subnetId, String subnetIp) {
+    protected static void updateSubnetNode(DataBroker dataBroker, Uuid vpnId, Uuid subnetId, String subnetIp,
+            String intfMac) {
         Subnetmap subnetmap = null;
         SubnetmapBuilder builder = null;
         InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
@@ -423,6 +424,7 @@ public class NetvirtVpnUtils {
             builder.setSubnetIp(subnetIp);
             builder.setNetworkId(subnetId);
             builder.setVpnId(vpnId);
+            builder.setRouterIntfMacAddress(intfMac);
 
             subnetmap = builder.build();
             logger.debug("Creating/Updating subnetMap node: {} ", subnetId.getValue());
@@ -441,7 +443,7 @@ public class NetvirtVpnUtils {
     }
 
     private static void updateSubnetmapNodeWithPorts(DataBroker dataBroker, Uuid subnetId, Uuid portIdToAdd,
-            Uuid portIdToRemove) {
+            Uuid portIdToRemove, String vpnName) {
         Subnetmap subnetmap = null;
         InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
                 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
@@ -466,6 +468,7 @@ public class NetvirtVpnUtils {
                                 portIdToRemove.getValue());
 
                     }
+                    builder.setRouterId(new Uuid(vpnName));
                     builder.setPortList(portList);
                 }
                 subnetmap = builder.build();
index 147d572400fada995a048cead0d3c415a294390a..e4bbd8045e3097aa8b1156adc5c5f8ebf2d043b4 100644 (file)
@@ -45,7 +45,7 @@ public class SubnetListener extends UnimgrDataTreeChangeListener<Subnet> impleme
     private final int waitForElanInterval;
 
     public SubnetListener(final DataBroker dataBroker, final NotificationPublishService notPublishService,
-             final IGwMacListener gwMacListener, int sleepInterval) {
+            final IGwMacListener gwMacListener, int sleepInterval) {
         super(dataBroker);
         this.notificationPublishService = notPublishService;
         this.gwMacListener = gwMacListener;
@@ -122,7 +122,6 @@ public class SubnetListener extends UnimgrDataTreeChangeListener<Subnet> impleme
         ipUniSubnets.forEach(s -> removeNetwork(s, uniId, ipUniId, ipvcId));
     }
 
-
     private void createNetwork(DataTreeModification<Subnet> newDataObject) {
         Subnet newSubnet = newDataObject.getRootNode().getDataAfter();
 
@@ -184,10 +183,12 @@ public class SubnetListener extends UnimgrDataTreeChangeListener<Subnet> impleme
             return;
         }
 
-        String srcTpAddressStr = NetvirtVpnUtils.getIpAddressFromPrefix(NetvirtVpnUtils.ipPrefixToString(ipUni.getIpAddress()));
+        String srcTpAddressStr = NetvirtVpnUtils
+                .getIpAddressFromPrefix(NetvirtVpnUtils.ipPrefixToString(ipUni.getIpAddress()));
         IpAddress srcIpAddress = new IpAddress(srcTpAddressStr.toCharArray());
         String subnet = NetvirtVpnUtils.ipPrefixToString(newSubnet.getSubnet());
-        gwMacListener.resolveGwMac(ipvcVpn.getVpnId(), vpnElan.getElanPort(), srcIpAddress, newSubnet.getGateway(), subnet);
+        gwMacListener.resolveGwMac(ipvcVpn.getVpnId(), vpnElan.getElanPort(), srcIpAddress, newSubnet.getGateway(),
+                subnet);
     }
 
     private void checkCreateDirectNetwork(Subnet newSubnet, IpvcVpn ipvcVpn, InstanceIdentifier<Ipvc> ipvcId,
@@ -196,8 +197,16 @@ public class SubnetListener extends UnimgrDataTreeChangeListener<Subnet> impleme
             return;
         }
 
+        org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni operUni = MefInterfaceUtils
+                .getUni(dataBroker, newSubnet.getUniId().getValue(), LogicalDatastoreType.OPERATIONAL);
+        if (operUni == null) {
+            Log.error("Uni {} for network {} is not operational", newSubnet.getUniId(), newSubnet.getSubnet());
+            return;
+        }
+        String portMacAddress = operUni.getMacAddress().getValue();
+
         NetvirtVpnUtils.addDirectSubnetToVpn(dataBroker, notificationPublishService, ipvcVpn.getVpnId(),
-                vpnElan.getElanId(), newSubnet.getSubnet(), vpnElan.getElanPort(), waitForElanInterval);
+                vpnElan.getElanId(), newSubnet.getSubnet(), vpnElan.getElanPort(), portMacAddress, waitForElanInterval);
 
     }
 
@@ -243,7 +252,6 @@ public class SubnetListener extends UnimgrDataTreeChangeListener<Subnet> impleme
                 vpnElan.getElanId(), vpnElan.getElanPort(), subnetStr);
     }
 
-
     private void removeDirectNetwork(Subnet deletedSubnet, IpvcVpn ipvcVpn, InstanceIdentifier<Ipvc> ipvcId) {
         if (deletedSubnet.getGateway() != null) {
             return;
@@ -281,10 +289,12 @@ public class SubnetListener extends UnimgrDataTreeChangeListener<Subnet> impleme
             return;
         }
 
-        String srcTpAddressStr = NetvirtVpnUtils.getIpAddressFromPrefix(NetvirtVpnUtils.ipPrefixToString(ipUni.getIpAddress()));
+        String srcTpAddressStr = NetvirtVpnUtils
+                .getIpAddressFromPrefix(NetvirtVpnUtils.ipPrefixToString(ipUni.getIpAddress()));
         IpAddress srcIpAddress = new IpAddress(srcTpAddressStr.toCharArray());
         String subnet = NetvirtVpnUtils.ipPrefixToString(deletedSubnet.getSubnet());
-        gwMacListener.unResolveGwMac(ipvcVpn.getVpnId(), vpnElan.getElanPort(), srcIpAddress, deletedSubnet.getGateway(), subnet);
+        gwMacListener.unResolveGwMac(ipvcVpn.getVpnId(), vpnElan.getElanPort(), srcIpAddress,
+                deletedSubnet.getGateway(), subnet);
 
         NetvirtVpnUtils.removeVpnInterfaceAdjacency(dataBroker, vpnElan.getElanPort(), deletedSubnet.getSubnet());
         NetvirtVpnUtils.removeVpnInterfaceAdjacency(dataBroker, vpnElan.getElanPort(), deletedSubnet.getGateway());