});
};
+ // Profiles
+ $scope.profiles = [];
+ $scope.updateProfilesView = function() {
+ CpeuiSvc.getProfiles(function(profiles) {
+ $scope.profiles = profiles;
+ });
+ };
+
+ $scope.addProfile = new CpeuiDialogs.Dialog('AddProfile', {}, function(obj) {
+ CpeuiSvc.addProfile(obj['bw-profile'], obj.cir, obj.cbs, function() {
+ $scope.updateProfilesView();
+ });
+ });
+
+ $scope.deleteProfile = function(profileName) {
+ CpeuiDialogs.confirm(function() {
+ CpeuiSvc.deleteProfile(profileName, function() {
+ $scope.updateProfilesView();
+ });
+ });
+ };
+
// CEs
$scope.updateCesView = function() {
CpeuiSvc.getCes(function(ces) {
$scope.updateTenantView();
$scope.updateCesView();
$scope.updateUniView();
+ $scope.updateProfilesView()
};
$scope.updateView();
ng-click="setTab('admin',2)"><a id="evcs-configure-tab" href="#/cpeui/admin/cpes">
<i class="icon-tasks"></i> CPEs (Devices)</a></li>
<li ng-class="{ active: isTabSet('admin',3)}"
- ng-click="setTab('admin',3);updateView()"><a id="dashboard-tab" href="#/cpeui/admin/unis">
+ ng-click="setTab('admin',3);updateView()"><a href="#/cpeui/admin/unis">
<i class="icon-exchange"></i> UNIs</a>
</li>
<li ng-class="{ active: isTabSet('admin',4)}"
- ng-click="setTab('admin',4);updateNetworksView()"><a id="dashboard-tab" href="#/cpeui/admin/networks">
+ ng-click="setTab('admin',4);updateNetworksView()"><a href="#/cpeui/admin/networks">
<i class="icon-signal"></i> Networks</a>
</li>
+ <li ng-class="{ active: isTabSet('admin',5)}" ng-click="setTab('admin',5);updateProfilesView()">
+ <a href="#/cpeui/admin/profiles"><i class="icon-signal"></i> Profiles</a>
+ </li>
<li id="refresh_btn" class="active refresh-btn"
ng-click="updateView()"><button class="btn add-row"> <i class="icon-refresh"></i> Refresh</button>
</li>
<th colspan="2">Tenant</th>
</tr>
</thead>
- <tbody id="ces_table">
+ <tbody>
<tr ng-repeat="item in unis | orderBy: '[\'uni-id\']'">
<td ng-init="device = ces.filterByField('dev-id',item.device)[0]">{{ device["device-name"] ? device["device-name"] : item.device}}</td>
<td>{{ item.prettyID }}</td>
<th>Tenant</th>
</tr>
</thead>
- <tbody id="ces_table">
+ <tbody>
<tr ng-repeat="svc in services ">
<td class="minimal-width">{{ svc['svc-id'] }}</td>
<td class="minimal-width">{{ networkNames[svc['svc-id']] }}</td>
</tbody>
</table>
</div>
+ <div ng-show="isTabSet('admin',5)">
+ <div class="table-header">Profiles</div>
+ <table class="footable table table-striped">
+ <thead>
+ <tr>
+ <th>Profile Name</th>
+ <th>Committed Information Rate (Kb/s)</th>
+ <th>Committed Burst Size (bytes)</th>
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="profile in profiles | orderBy: '[\'bw-profile\']'">
+ <td class="minimal-width">{{ profile['bw-profile'] }}</td>
+ <td class="minimal-width">{{ profile.cir }}</td>
+ <td class="minimal-width">{{ profile.cbs }}</td>
+ <td class="delete-tr">
+ <button class="btn btn-md btn-danger" ng-click="deleteProfile(profile['bw-profile'])">
+ <i class="icon-trash"></i>
+ <md-tooltip>Delete Profile</md-tooltip>
+ </button>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <div>
+ <a class="btn add-row" ng-click="addProfile.show($event)">Add Profile</a>
+ </div>
+ </div>
</div>
"tenants" : 1,
"cpes" : 2,
"unis" : 3,
- "networks" : 4
+ "networks" : 4,
+ "profiles" : 5
}
$scope.tab = {
--- /dev/null
+<md-dialog class="cpe-dialog" aria-label="Create Profile" ng-cloak>
+ <md-toolbar>
+ <div class="md-toolbar-tools">
+ <h2>Create Profile</h2>
+ <span flex></span>
+ <md-button class="md-icon-button" aria-label="Close dialog"
+ ng-click="cancel()"> <i class="icon-remove-sign"></i> </md-button>
+ </div>
+ </md-toolbar>
+ <form name="projectForm" novalidate>
+ <md-dialog-content>
+ <div layout="column" ng-cloak>
+ <md-content layout-padding>
+ <md-input-container class="md-block">
+ <label>Profile Name</label>
+ <input name="profilename" ng-model="obj['bw-profile']">
+ <div ng-messages="projectForm.profilename.$error">
+ <div ng-message="required">This is required!</div>
+ </div>
+ </md-input-container>
+ <md-input-container class="md-block">
+ <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-input-container class="md-block">
+ <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>
+ <div ng-message="min">Number must be positive!</div>
+ </div>
+ </md-input-container>
+ </md-content>
+ </div>
+ </md-dialog-content>
+ <md-dialog-actions layout="row">
+ <span flex></span>
+ <md-button ng-click="cancel()"> Cancel </md-button>
+ <md-button type="submit" ng-click="done(obj)"> Create </md-button>
+ </md-dialog-actions>
+ </form>
+</md-dialog>
\ No newline at end of file
<md-option value="leaf" default>Leaf</md-option>
</md-select>
</md-input-container>
+ <md-input-container class="md-block">
+ <label>Profile</label>
+ <md-select ng-model="obj.profile_name" name="profile_name">
+ <md-option ng-value="undefined" > - None - </md-option>
+ <md-option ng-repeat="profile in params.profiles | orderBy: '[\'bw-profile\']'" value="{{ profile['bw-profile'] }}" >{{ profile['bw-profile'] }} <span class="small">(CIR: {{profile.cir}}, CBS: {{profile.cbs}})</span></md-option>
+ </md-select>
+ </md-input-container>
<input type="hidden" name="vlans" ng-model="obj.vlans">
<div ng-if="params.svc.evc['preserve-ce-vlan-id']">
Preserved VLAN: {{params.svc.evc['preserved-vlan']}}
<md-select ng-model="obj.ip_uni" name="ip_uni" ng-disabled="!obj.uni">
<md-option ng-repeat="ipuni in obj.uni['ip-unis']['ip-uni'] " value="{{ ipuni['ip-uni-id'] }}" >{{ ipuni['ip-uni-id'] }} : {{ipuni['ip-address']}}{{ipuni.vlan ? (' (vlan: ' + ipuni.vlan+')') : ''}}</md-option>
</md-select>
+ </md-input-container>
+ <md-input-container class="md-block">
+ <label>Profile</label>
+ <md-select ng-model="obj.profile_name" name="profile_name">
+ <md-option ng-value="undefined" > - None - </md-option>
+ <md-option ng-repeat="profile in params.profiles | orderBy: '[\'bw-profile\']'" value="{{ profile['bw-profile'] }}" >{{ profile['bw-profile'] }} <span class="small">(CIR: {{profile.cir}}, CBS: {{profile.cbs}})</span></md-option>
+ </md-select>
</md-input-container>
</md-content>
</div>
}
});
};
+
+ // Profiles
+ svc.getProfiles = function(callback) {
+ $http({
+ method:'GET',
+ url:"/restconf/config/mef-global:mef-global/profiles/ingress-bwp-flows/"
+ }).then(function successCallback(response) {
+ if (callback != undefined) {
+ callback(response.data["ingress-bwp-flows"]["bwp-flow"]);
+ }
+ }, function errorCallback(response) {
+ if (response.status == 404) {
+ callback([]);
+ }
+ console.log(response);
+ });
+ };
+
+ svc.addProfile = function(name, cir, cbs, callback){
+ $http({
+ method:'POST',
+ url:"/restconf/config/mef-global:mef-global/profiles/ingress-bwp-flows/",
+ data: {"bwp-flow":{
+ "bw-profile" : name,
+ "cir" : cir,
+ "cbs" : cbs
+ }}
+ }).then(function successCallback(response) {
+ if (callback != undefined) {
+ callback();
+ }
+ });
+ };
+
+ svc.deleteProfile = function(name, callback) {
+ $http({
+ method:'DELETE',
+ url:"/restconf/config/mef-global:mef-global/profiles/ingress-bwp-flows/bwp-flow/"+name,
+ }).then(function successCallback(response) {
+ if (callback != undefined) {
+ callback();
+ }
+ });
+ };
+
+ // CEs
svc.addCe = function(id, name, callback) {
$http({
method:'POST',
svc.getCes = function(callback) {
var ces;
+ var operMap = {};
+
$http({
method:'GET',
- url:"/restconf/config/mef-topology:mef-topology/devices/"
+ url:"/restconf/operational/mef-topology:mef-topology/devices/"
}).then(function successCallback(response) {
ces = response.data["devices"]["device"];
- ces.forEach(function(c){
- c.displayName = c['device-name'] ? c['device-name'] : c['dev-id'];
+ ces.forEach(function(c) {
+ c.displayName = c['dev-id'];
+ operMap[c['dev-id']] = c;
+ });
+ }).finally(function() {
+ $http({
+ method:'GET',
+ url:"/restconf/config/mef-topology:mef-topology/devices/"
+ }).then(function(response){
+ var confCes = response.data["devices"]["device"];
+ confCes.forEach(function(c) {
+ c.displayName = c['device-name'] ? c['device-name'] : c['dev-id'];
+ if (operMap[c['dev-id']]) {
+ for (var attrname in c) {
+ operMap[c['dev-id']][attrname] = c[attrname];
+ }
+ } else {
+ operMap[c['dev-id']] = c;
+ }
+ });
+ }).finally(function() {
+ if (callback != undefined) {
+ callback(Object.values(operMap));
+ }
});
- if (callback != undefined) {
- callback(ces);
- }
- }, function errorCallback(response) {
- if (response.status == 404) {
- callback([]);
- }
- console.log(response);
});
-
- return ces;
-
};
+
svc.removeCe = function(ceid, callback) {
$http({
method:'DELETE',
// IPVCs
svc.addIpvc = function(ipvc, tenant, callback) {
-// var uni_json = getJsonUnis(evc.unis);
-// preserved-vlan
var data = {
"mef-service" : {
"svc-id" : ipvc.id,
"ipvc" : {
"ipvc-id" : ipvc.id,
"ipvc-type" : 'multipoint',
-// "unis" : {
-// "uni" : uni_json
-// },
}
}
};
});
};
- svc.addIpvcUni = function(svcid, uni_id, ipuni_id, callback) {
+ svc.addIpvcUni = function(svcid, uni_id, ipuni_id, profile_name, callback) {
var data = {"uni":{
"uni-id":uni_id,
"ip-uni-id":ipuni_id
}
- };
+ };
+ if (profile_name) {
+ data.uni["ingress-bw-profile"] = profile_name;
+ }
$http({
method:'PUT',
url:"/restconf/config/mef-services:mef-services/mef-service/" + svcid + "/ipvc/unis/uni/"+uni_id+"/"+ipuni_id,
- svc.addEvcUni = function(svcid, uni_id, role, vlans, callback) {
+ svc.addEvcUni = function(svcid, uni_id, role, vlans, profile_name, callback) {
var data = {"uni":{
"uni-id":uni_id,
"role":role,
"admin-state-enabled":true
}
};
+ if (profile_name) {
+ data.uni["ingress-bw-profile"] = profile_name;
+ }
if (vlans != undefined) {
data.uni['evc-uni-ce-vlans'] = {"evc-uni-ce-vlan":[]}
for (var i=0; i< vlans.length; ++i) {
$scope.ces = [];
$scope.ipvcs = [];
$scope.subnets = {};
+ $scope.profiles =[];
$scope.cesDisplayNames = {};
$scope.unisMap = {};
$scope.networkNames = {};
$scope.networkNames[net.uuid] = net.name;
});
});
+
+ CpeuiSvc.getProfiles(function(profiles) {
+ $scope.profiles = profiles;
+ });
}
$scope.updateUnis = function(callback) {
$scope.linkIpvcUniDialog = new CpeuiDialogs.Dialog('LinkIpvcUni', {},
function(obj) {
- CpeuiSvc.addIpvcUni(obj.svc_id, obj.uni['uni-id'], obj.ip_uni,
+ CpeuiSvc.addIpvcUni(obj.svc_id, obj.uni['uni-id'], obj.ip_uni, obj.profile_name,
function() {
$scope.updateEvcView();
});
if (!obj.role) {
obj.role = "root";
}
- CpeuiSvc.addEvcUni(obj.svc_id, obj.uni_id, obj.role, obj.vlans,
+ CpeuiSvc.addEvcUni(obj.svc_id, obj.uni_id, obj.role, obj.vlans, obj.profile_name,
function() {
$scope.updateEvcView();
});
<i class="icon-minus"></i>
</button>
</th>
- <th>Device</th>
- <th>UNI</th>
- <th ng-if="item.isTree" >Role</th>
+ <th class="minimal-width">Device</th>
+ <th class="minimal-width">UNI</th>
+ <th class="minimal-width" ng-if="item.isTree" >Role</th>
<th class="minimal-width">VLANs <span style="font-size:small;color:inherit;"> (click to edit)</span></th>
- <th class="delete-tr"><button class="btn btn-md btn-info" ng-click="linkEvcUniDialog.show($event, {'svc':item,'unis':unis,'ces':ces})"> <i class="icon-plus"></i> </button></th>
+ <th class="minimal-width">Profile</th>
+ <th class="delete-tr">
+ <button class="btn btn-md btn-info" ng-click="linkEvcUniDialog.show($event, {svc:item, unis:unis, ces:ces, profiles:profiles})">
+ <i class="icon-plus"></i>
+ </button>
+ </th>
</tr>
</thead>
<tbody>
<tr ng-repeat-start="(ce, unis) in item.device2unis | orderBy : ce ">
- <td colspan="2" rowspan="{{unis.length}}">{{ cesDisplayNames[ce] }}</td>
- <td ng-repeat-start="uni in unis | orderBy: sortUni | limitTo :1">{{ uni.prettyID }}</td>
- <td ng-if="item.isTree">{{ uni['role'] }}</td>
+ <td class="minimal-width" colspan="2" rowspan="{{unis.length}}">{{ cesDisplayNames[ce] }}</td>
+ <td class="minimal-width" ng-repeat-start="uni in unis | orderBy: sortUni | limitTo :1">{{ uni.prettyID }}</td>
+ <td class="minimal-width" ng-if="item.isTree">{{ uni['role'] }}</td>
<td class="clickable" ng-click="!item.evc['preserve-ce-vlan-id'] ? editVlanDialog.show($event, {svcid:item['svc-id'], uniid:uni['uni-id'], vlans:uni.vlans}) : 0">
{{ uni.vlans.join(', ') }} {{item.evc['preserve-ce-vlan-id'] ? '(Preserved)' : ''}}
</td>
+ <td class="minimal-width">{{ uni['ingress-bw-profile'] }}</td>
<td ng-repeat-end class="delete-tr" style="white-space: nowrap;">
<button class="btn btn-md btn-danger" ng-click="deleteEvcUni(item['svc-id'], uni['uni-id'])"> <i class="icon-trash"></i> </button>
</td>
<td class="clickable" ng-click="!item.evc['preserve-ce-vlan-id'] ? editVlanDialog.show($event, {svcid:item['svc-id'], uniid:uni['uni-id'], vlans:uni.vlans}) : 0">
{{ uni.vlans.join(', ') }} {{item.evc['preserve-ce-vlan-id'] ? '(Preserved)' : ''}}
</td>
+ <td class="minimal-width">{{ uni['ingress-bw-profile'] }}</td>
<td class="delete-tr" style="white-space: nowrap;">
<button class="btn btn-md btn-danger" ng-click="deleteEvcUni(item['svc-id'], uni['uni-id'])"> <i class="icon-trash"></i> </button>
</td>
<th>Device</th>
<th>UNI</th>
<th>IP Address</th>
- <th>vlan</th>
- <th class="delete-tr"><button class="btn btn-md btn-info" ng-click="linkIpvcUniDialog.show($event, {'svc':ipvc,'unis':unis,'ces':ces})"> <i class="icon-plus"></i> </button></th>
+ <th>Vlan</th>
+ <th>Profile</th>
+ <th class="delete-tr"><button class="btn btn-md btn-info" ng-click="linkIpvcUniDialog.show($event, {svc:ipvc, unis:unis, ces:ces, profiles:profiles})"> <i class="icon-plus"></i> </button></th>
</tr>
</thead>
<tbody>
- <tr ng-repeat="ipuni in ipvc.ipvc.unis.uni">
+ <tr ng-repeat="ipuni in ipvc.ipvc.unis.uni | orderBy: 'prettyID'">
<td colspan="2" ng-init="serviceIpuni = getMefInterfaceIpvc(ipuni['uni-id'],ipuni['ip-uni-id'])">{{ cesDisplayNames[ipuni.device] }}</td>
<td>{{ ipuni.prettyID }}</td>
<td>{{serviceIpuni['ip-address']}}</td>
<td>{{serviceIpuni.vlan}}</td>
+ <td class="minimal-width">{{ ipuni['ingress-bw-profile'] }}</td>
<td class="delete-tr"><button class="btn btn-md btn-danger" ng-click="deleteIpvcUni(ipvc['svc-id'], ipuni['uni-id'], ipuni['ip-uni-id'])"> <i class="icon-trash"></i> </button></td>
</tr>
</tbody>
leaf ip-uni-id {
type mef-types:identifier45;
}
+ leaf ingress-bw-profile {
+ type mef-types:identifier45;
+ }
container evc-uni-ce-vlans {
description
}
}
}
+ leaf ingress-bw-profile {
+ type mef-types:identifier45;
+ }
container ingress-bwp-flows-per-cos {
presence "Use Ingress Bandwidth Profiles Per CoS";
description
private static final Logger log = LoggerFactory.getLogger(EvcListener.class);
private ListenerRegistration<EvcListener> evcListenerRegistration;
private final IUniPortManager uniPortManager;
+ private final UniQosManager uniQosManager;
- public EvcListener(final DataBroker dataBroker, final UniPortManager uniPortManager) {
+ public EvcListener(final DataBroker dataBroker, final UniPortManager uniPortManager,
+ final UniQosManager uniQosManager) {
super(dataBroker);
this.uniPortManager = uniPortManager;
+ this.uniQosManager = uniQosManager;
registerListener();
}
for (Uni uni : data.getUnis().getUni()) {
createUniElanInterfaces(evcId, instanceName, uni, isEtree);
}
+ updateQos(data.getUnis().getUni());
}
} catch (final Exception e) {
log.error("Add evc failed !", e);
try {
Evc data = removedDataObject.getRootNode().getDataBefore();
InstanceIdentifier<Evc> evcId = removedDataObject.getRootPath().getRootIdentifier();
- List<Uni> uniToRemove = data.getUnis() != null && data.getUnis().getUni() != null
- ? data.getUnis().getUni() : Collections.emptyList();
-
+ List<Uni> uniToRemove = data.getUnis() != null && data.getUnis().getUni() != null ? data.getUnis().getUni()
+ : Collections.emptyList();
synchronized (data.getEvcId().getValue().intern()) {
EvcElan evcElan = getOperEvcElan(evcId);
for (Uni uni : uniToRemove) {
removeUniElanInterfaces(evcId, instanceName, uni);
}
+ updateQos(uniToRemove);
log.info("Removing elan instance: " + instanceName);
NetvirtUtils.deleteElanInstance(dataBroker, instanceName);
for (Uni uni : uniToRemove) {
removeUniElanInterfaces(evcId, instanceName, uni);
}
+ updateQos(uniToRemove);
List<Uni> uniToCreate = new ArrayList<>(updateUni);
uniToCreate.removeAll(originalUni);
for (Uni uni : uniToCreate) {
createUniElanInterfaces(evcId, instanceName, uni, isEtree);
}
+ updateQos(uniToCreate);
}
} catch (final Exception e) {
log.error("Update evc failed !", e);
log.info("Creting elan interface for elan {} vlan {} interface {}", instanceName, 0, interfaceName);
NetvirtUtils.createElanInterface(dataBroker, instanceName, interfaceName, roleToInterfaceType(role),
isEtree);
+ uniQosManager.mapUniPortBandwidthLimits(uni.getUniId().getValue(), interfaceName,
+ uni.getIngressBwProfile());
setOperEvcElanPort(evcId, instanceName, interfaceName);
} else {
for (EvcUniCeVlan ceVlan : evcUniCeVlan) {
log.info("Creting elan interface for elan {} vlan {} interface {}", instanceName, 0, interfaceName);
NetvirtUtils.createElanInterface(dataBroker, instanceName, interfaceName, roleToInterfaceType(role),
isEtree);
+ uniQosManager.mapUniPortBandwidthLimits(uni.getUniId().getValue(), interfaceName,
+ uni.getIngressBwProfile());
setOperEvcElanPort(evcId, instanceName, interfaceName);
}
}
interfaceName);
return;
}
- removeElanInterface(evcId, interfaceName);
+ removeElanInterface(evcId, uni.getUniId().getValue(), interfaceName);
} else {
for (EvcUniCeVlan ceVlan : evcUniCeVlan) {
Long vlan = safeCastVlan(ceVlan.getVid());
vlan, interfaceName);
return;
}
- removeElanInterface(evcId, interfaceName);
+ removeElanInterface(evcId, uni.getUniId().getValue(), interfaceName);
}
}
}
- private void removeElanInterface(InstanceIdentifier<Evc> identifier, String interfaceName) {
+ private void removeElanInterface(InstanceIdentifier<Evc> identifier, String uniId, String interfaceName) {
log.info("Removing elan interface: " + interfaceName);
+ uniQosManager.unMapUniPortBandwidthLimits(uniId, interfaceName);
NetvirtUtils.deleteElanInterface(dataBroker, interfaceName);
EvcElan evcElan = getOperEvcElan(identifier);
if (evcElan == null) {
log.error("Removing non-operational Elan interface {}", interfaceName);
}
+
deleteOperEvcElanPort(identifier, interfaceName);
}
InstanceIdentifier<EvcElan> path = identifier.augmentation(EvcElan.class);
EvcElan evcElan = getOperEvcElan(identifier);
EvcElanBuilder evcElanBuilder = evcElan != null ? new EvcElanBuilder(evcElan) : new EvcElanBuilder();
- List<ElanPorts> exPorts = evcElan != null && evcElan.getElanPorts() != null ? evcElan.getElanPorts() : new ArrayList<>();
+ List<ElanPorts> exPorts = evcElan != null && evcElan.getElanPorts() != null ? evcElan.getElanPorts()
+ : new ArrayList<>();
ElanPortsBuilder portB = new ElanPortsBuilder();
portB.setPortId(elanPort);
MdsalUtils.write(dataBroker, LogicalDatastoreType.OPERATIONAL, path, evcElanBuilder.build());
}
+ private void updateQos(List<Uni> uniToUpdate) {
+ uniToUpdate.forEach(u -> uniQosManager.setUniBandwidthLimits(u.getUniId()));
+ }
+
}
private static final Logger Log = LoggerFactory.getLogger(IpvcListener.class);
private final IUniPortManager uniPortManager;
private final ISubnetManager subnetManager;
+ private final UniQosManager uniQosManager;
private ListenerRegistration<IpvcListener> ipvcListenerRegistration;
public IpvcListener(final DataBroker dataBroker, final IUniPortManager uniPortManager,
- final ISubnetManager subnetManager) {
+ final ISubnetManager subnetManager, final UniQosManager uniQosManager) {
super(dataBroker);
this.uniPortManager = uniPortManager;
this.subnetManager = subnetManager;
-
+ this.uniQosManager = uniQosManager;
registerListener();
}
}
MdsalUtils.commitTransaction(tx);
}
- for (Uni uni : unis) {
- IpUni ipUni = MefInterfaceUtils.getIpUni(dataBroker, uni.getUniId(), uni.getIpUniId(),
- LogicalDatastoreType.CONFIGURATION);
- createDirectSubnet(uni, ipUni);
- subnetManager.assignIpUniNetworks(uni.getUniId(), ipUni.getIpUniId(), ipvcId);
- }
+ createUnis(ipvcId, unis);
} catch (final Exception e) {
Log.error("Add ipvc failed !", e);
}
// remove elan/vpn interfaces
// must be in different transactios
WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
- removeUni(ipvcId, operIpvcVpn, ipvc.getUnis().getUni(), tx);
+ removeUnis(ipvcId, operIpvcVpn, ipvc.getUnis().getUni(), tx);
MdsalUtils.commitTransaction(tx);
// Let to work for listeners
// TODO : change to listener
}
}
- private void removeUni(InstanceIdentifier<Ipvc> ipvcId, IpvcVpn operIpvcVpn, List<Uni> uniToRemove,
+ private void removeUnis(InstanceIdentifier<Ipvc> ipvcId, IpvcVpn operIpvcVpn, List<Uni> uniToRemove,
WriteTransaction tx) {
if (uniToRemove == null) {
Log.trace("No UNI's to remove");
subnetManager.unAssignIpUniNetworks(uni.getUniId(), ipUni.getIpUniId(), ipvcId);
removeInterfaces(ipvcId, operIpvcVpn, uni, ipUni, tx);
}
+ updateQos(uniToRemove);
+ }
+
+ private void createUnis(InstanceIdentifier<Ipvc> ipvcId, List<Uni> uniToCreate) {
+ for (Uni uni : uniToCreate) {
+ IpUni ipUni = MefInterfaceUtils.getIpUni(dataBroker, uni.getUniId(), uni.getIpUniId(),
+ LogicalDatastoreType.CONFIGURATION);
+ createDirectSubnet(uni, ipUni);
+ subnetManager.assignIpUniNetworks(uni.getUniId(), ipUni.getIpUniId(), ipvcId);
+ }
+ updateQos(uniToCreate);
}
private void updateIpvc(DataTreeModification<Ipvc> modifiedDataObject) {
WriteTransaction txRemove = MdsalUtils.createTransaction(dataBroker);
List<Uni> uniToRemove = new ArrayList<>(originalUni);
uniToRemove.removeAll(updateUni);
- removeUni(ipvcId, operIpvcVpn, uniToRemove, txRemove);
+ removeUnis(ipvcId, operIpvcVpn, uniToRemove, txRemove);
MdsalUtils.commitTransaction(txRemove);
WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
}
MdsalUtils.commitTransaction(tx);
- for (Uni uni : uniToCreate) {
- IpUni ipUni = MefInterfaceUtils.getIpUni(dataBroker, uni.getUniId(), uni.getIpUniId(),
- LogicalDatastoreType.CONFIGURATION);
- createDirectSubnet(uni, ipUni);
- subnetManager.assignIpUniNetworks(uni.getUniId(), ipUni.getIpUniId(), ipvcId);
- }
+ createUnis(ipvcId, uniToCreate);
}
} catch (final Exception e) {
IpAddress ipAddress = new IpAddress(srcIpAddressStr.toCharArray());
String interfaceName = createElanInterface(vpnName, ipvcId, uniId, elanName, vlan, ipAddress, tx);
+
+ uniQosManager.mapUniPortBandwidthLimits(uniId, interfaceName, uniInService.getIngressBwProfile());
+
createVpnInterface(vpnName, uni, ipUni, interfaceName, elanName, tx);
MefServicesUtils.addOperIpvcVpnElan(ipvcId, vpnName, uniInService.getUniId(), uniInService.getIpUniId(),
elanName, interfaceName, null, tx);
NetvirtVpnUtils.removeVpnInterfaceAdjacencies(dataBroker, vpnName, vpnElans.getElanPort());
// TODO : change to listener
NetvirtUtils.safeSleep();
+ uniQosManager.unMapUniPortBandwidthLimits(uniId, vpnElans.getElanPort());
removeElan(vpnElans, uniId, ipUni, tx);
+ // record Uni bw limits
removeVpnInterface(vpnName, vpnElans, uniId, ipUni, tx);
MefServicesUtils.removeOperIpvcElan(dataBroker, ipvcId, ipvcVpn.getVpnId(), uniInService.getUniId(),
uniInService.getIpUniId(), vpnElans.getElanId(), vpnElans.getElanPort());
ipUni.getIpUniId(), subnetPrefix);
MdsalUtils.delete(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
}
+
+ private void updateQos(List<Uni> uniToUpdate) {
+ uniToUpdate.forEach(u -> uniQosManager.setUniBandwidthLimits(u.getUniId()));
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.unimgr.mef.netvirt;
+
+import com.google.common.base.Optional;
+
+import jline.internal.Log;
+
+import java.math.BigInteger;
+import java.util.Iterator;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.global.rev150526.MefGlobal;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.global.rev150526.mef.global.Profiles;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.global.rev150526.mef.global.bwp.flows.group.BwpFlow;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.global.rev150526.mef.global.bwp.flows.group.BwpFlowKey;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.global.rev150526.mef.global.profiles.IngressBwpFlows;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.uni.physical.layers.links.Link;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.Identifier45;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class UniQosManager {
+ private static final Logger LOG = LoggerFactory.getLogger(UniQosManager.class);
+ private OdlInterfaceRpcService odlInterfaceRpcService;
+ private DataBroker dataBroker;
+ private final Long noLimit = 0l;
+
+ // key in first map is uniId, key in second map is logical portId
+ private ConcurrentHashMap<String, ConcurrentHashMap<String, BandwidthLimits>> uniPortBandwidthLimits;
+
+ // map of current values per uni
+ private ConcurrentHashMap<String, BandwidthLimits> uniBandwidthLimits;
+
+ private ConcurrentHashMap<String, BigInteger> uniToDpn;
+
+ public UniQosManager(final DataBroker dataBroker, OdlInterfaceRpcService odlInterfaceRpcService) {
+ this.dataBroker = dataBroker;
+ this.odlInterfaceRpcService = odlInterfaceRpcService;
+ this.uniPortBandwidthLimits = new ConcurrentHashMap<>();
+ this.uniBandwidthLimits = new ConcurrentHashMap<>();
+ this.uniToDpn = new ConcurrentHashMap<>();
+ }
+
+ public void mapUniPortBandwidthLimits(String uniId, String portId, Long maxKbps, Long maxBurstKb) {
+ Log.info("Record rate limits for Uni {} port {} maxKbps {} maxBurstKb {}", uniId, portId, maxKbps, maxBurstKb);
+ uniPortBandwidthLimits.putIfAbsent(uniId, new ConcurrentHashMap<>());
+ ConcurrentHashMap<String, BandwidthLimits> uniMap = uniPortBandwidthLimits.get(uniId);
+ uniMap.put(portId, new BandwidthLimits(maxKbps, maxBurstKb));
+ }
+
+ public void mapUniPortBandwidthLimits(String uniId, String portId, Identifier45 bwProfile) {
+ Long maxKbps = noLimit;
+ Long maxBurstKb = noLimit;
+ if (bwProfile != null) {
+
+ Optional<BwpFlow> bwFlowOp = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
+ getBwFlowInstanceIdentifier(bwProfile));
+ if (!bwFlowOp.isPresent()) {
+ Log.trace("Can't read bw profile {} for Uni {}", bwProfile, uniId);
+ return;
+ }
+ // Kbytes per second
+ maxKbps = bwFlowOp.get().getCir().getValue();
+ // burst in bytes, ovs requires in Kb
+ maxBurstKb = bwFlowOp.get().getCbs().getValue() / 1000;
+ Log.info("Record rate limits for Uni {} Profile {}", uniId, bwProfile);
+ }
+ mapUniPortBandwidthLimits(uniId, portId, maxKbps, maxBurstKb);
+ }
+
+ public void unMapUniPortBandwidthLimits(String uniId, String portId) {
+ Log.debug("Delete rate limits for Uni {} port {}", uniId, portId);
+ ConcurrentHashMap<String, BandwidthLimits> uniMap = uniPortBandwidthLimits.get(uniId);
+ if (uniMap == null) {
+ Log.error("Trying to delete limits for non-exsting uni {}", uniId);
+ return;
+ }
+ uniMap.remove(portId);
+ if (uniMap.isEmpty()) {
+ uniMap.put(portId, new BandwidthLimits(noLimit, noLimit));
+ }
+ }
+
+ public void setUniBandwidthLimits(Identifier45 uniIden) {
+ String uniId = uniIden.getValue();
+ if (!uniPortBandwidthLimits.containsKey(uniId)) {
+ Log.debug("Uni {} doesn't have rate limits configured", uniId);
+ return;
+ }
+ Iterator<String> uniPorts = uniPortBandwidthLimits.get(uniId).keySet().iterator();
+ if (uniPorts == null || !uniPorts.hasNext()) {
+ Log.debug("Uni {} doesn't have rate limits configured", uniId);
+ return;
+ }
+ String logicalPort = uniPorts.next();
+
+ BandwidthLimits newLimits = recalculateLimitsForUni(uniId, uniPortBandwidthLimits.get(uniId));
+ if (newLimits.equals(uniBandwidthLimits.get(uniId))) {
+ Log.debug("Uni {} rate limits has not changed", uniId);
+ return;
+ }
+
+ setPortBandwidthLimits(uniId, logicalPort, newLimits.getMaxKbps(), newLimits.getMaxBurstKb());
+ uniBandwidthLimits.put(uniId, newLimits);
+ }
+
+ private BandwidthLimits recalculateLimitsForUni(String uniId,
+ ConcurrentHashMap<String, BandwidthLimits> uniLimits) {
+ Long sumOfRate = noLimit;
+ Long sumOfBurst = noLimit;
+ Boolean hasNullRate = false;
+ Boolean hasNullBurst = false;
+
+ if (uniLimits == null || uniLimits.keySet() == null) {
+ return new BandwidthLimits(sumOfRate, sumOfBurst);
+ }
+
+ for (BandwidthLimits v : uniLimits.values()) {
+ if (v.maxKbps == null) {
+ hasNullRate = true;
+ break;
+ }
+ if (v.maxBurstKb == null) {
+ hasNullBurst = true;
+ }
+ sumOfRate = sumOfRate + v.maxKbps;
+ sumOfBurst = sumOfBurst + v.maxBurstKb;
+
+ }
+ if (hasNullRate) {
+ sumOfRate = noLimit;
+ sumOfBurst = noLimit;
+ } else if (hasNullBurst) {
+ sumOfBurst = noLimit;
+ }
+ return new BandwidthLimits(sumOfRate, sumOfBurst);
+ }
+
+ private void setPortBandwidthLimits(String uniId, String logicalPortId, Long maxKbps, Long maxBurstKb) {
+ LOG.trace("Setting bandwidth limits {} {} on Port {}", maxKbps, maxBurstKb, logicalPortId);
+
+ BigInteger dpId = BigInteger.ZERO;
+ if(uniToDpn.containsKey(uniId)) {
+ dpId = uniToDpn.get(uniId);
+ } else {
+ dpId = getDpnForInterface(odlInterfaceRpcService, logicalPortId);
+ uniToDpn.put(uniId, dpId);
+ }
+ if (dpId.equals(BigInteger.ZERO)) {
+ LOG.error("DPN ID for interface {} not found", logicalPortId);
+ return;
+ }
+
+ OvsdbBridgeRef bridgeRefEntry = getBridgeRefEntryFromOperDS(dpId, dataBroker);
+ Optional<Node> bridgeNode = MDSALUtil.read(LogicalDatastoreType.OPERATIONAL,
+ bridgeRefEntry.getValue().firstIdentifierOf(Node.class), dataBroker);
+ if (bridgeNode == null) {
+ LOG.error("Bridge ref for interface {} not found", logicalPortId);
+ return;
+ }
+
+ String physicalPort = getPhysicalPortForUni(dataBroker, uniId);
+ if (physicalPort == null) {
+ LOG.error("Physical port for interface {} not found", logicalPortId);
+ return;
+ }
+
+ TerminationPoint tp = getTerminationPoint(bridgeNode.get(), physicalPort);
+ if (tp == null) {
+ LOG.error("Termination point for port {} not found", physicalPort);
+ return;
+ }
+
+ OvsdbTerminationPointAugmentation ovsdbTp = tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
+ OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
+ tpAugmentationBuilder.setName(ovsdbTp.getName());
+ tpAugmentationBuilder.setIngressPolicingRate(maxKbps);
+ tpAugmentationBuilder.setIngressPolicingBurst(maxBurstKb);
+
+ TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
+ tpBuilder.setKey(tp.getKey());
+ tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
+ MdsalUtils.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION,
+ InstanceIdentifier.create(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(SouthboundUtils.OVSDB_TOPOLOGY_ID))
+ .child(Node.class, bridgeNode.get().getKey())
+ .child(TerminationPoint.class, new TerminationPointKey(tp.getKey())),
+ tpBuilder.build());
+ }
+
+ private static TerminationPoint getTerminationPoint(Node bridgeNode, String portName) {
+ for (TerminationPoint tp : bridgeNode.getTerminationPoint()) {
+ String tpIdStr = tp.getTpId().getValue();
+ if (tpIdStr != null && tpIdStr.equals(portName))
+ return tp;
+ }
+ return null;
+ }
+
+ private static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
+ BigInteger nodeId = BigInteger.ZERO;
+ try {
+ GetDpidFromInterfaceInput dpIdInput = new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
+ Future<RpcResult<GetDpidFromInterfaceOutput>> dpIdOutput = interfaceManagerRpcService
+ .getDpidFromInterface(dpIdInput);
+ RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
+ if (dpIdResult.isSuccessful()) {
+ nodeId = dpIdResult.getResult().getDpid();
+ } else {
+ LOG.error("Could not retrieve DPN Id for interface {}", ifName);
+ }
+ } catch (NullPointerException | InterruptedException | ExecutionException e) {
+ LOG.error("Exception when getting dpn for interface {}", ifName, e);
+ }
+ return nodeId;
+ }
+
+ private static String getPhysicalPortForUni(DataBroker dataBroker, String uniId) {
+ String nodeId = null;
+ try {
+ Link link = MefInterfaceUtils.getLink(dataBroker, uniId, LogicalDatastoreType.OPERATIONAL);
+ String parentInterfaceName = MefInterfaceUtils.getTrunkParentName(link);
+ return parentInterfaceName.split(":")[1];
+ } catch (Exception e) {
+ LOG.error("Exception when getting physical port for Uni {}", uniId, e);
+ }
+ return nodeId;
+ }
+
+ private static BridgeRefEntry getBridgeRefEntryFromOperDS(InstanceIdentifier<BridgeRefEntry> dpnBridgeEntryIid,
+ DataBroker dataBroker) {
+ Optional<BridgeRefEntry> bridgeRefEntryOptional = MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
+ dpnBridgeEntryIid);
+ if (!bridgeRefEntryOptional.isPresent()) {
+ return null;
+ }
+ return bridgeRefEntryOptional.get();
+ }
+
+ private static OvsdbBridgeRef getBridgeRefEntryFromOperDS(BigInteger dpId, DataBroker dataBroker) {
+ BridgeRefEntryKey bridgeRefEntryKey = new BridgeRefEntryKey(dpId);
+ InstanceIdentifier<BridgeRefEntry> bridgeRefEntryIid = getBridgeRefEntryIdentifier(bridgeRefEntryKey);
+ BridgeRefEntry bridgeRefEntry = getBridgeRefEntryFromOperDS(bridgeRefEntryIid, dataBroker);
+ return (bridgeRefEntry != null) ? bridgeRefEntry.getBridgeReference() : null;
+ }
+
+ private static InstanceIdentifier<BridgeRefEntry> getBridgeRefEntryIdentifier(BridgeRefEntryKey bridgeRefEntryKey) {
+ InstanceIdentifier.InstanceIdentifierBuilder<BridgeRefEntry> bridgeRefEntryInstanceIdentifierBuilder = InstanceIdentifier
+ .builder(BridgeRefInfo.class).child(BridgeRefEntry.class, bridgeRefEntryKey);
+ return bridgeRefEntryInstanceIdentifierBuilder.build();
+ }
+
+ private static InstanceIdentifier<BwpFlow> getBwFlowInstanceIdentifier(Identifier45 bwProfile) {
+ InstanceIdentifier.InstanceIdentifierBuilder<BwpFlow> bwProfileInstanceIdentifierBuilder = InstanceIdentifier
+ .builder(MefGlobal.class).child(Profiles.class).child(IngressBwpFlows.class)
+ .child(BwpFlow.class, new BwpFlowKey(bwProfile));
+ return bwProfileInstanceIdentifierBuilder.build();
+ }
+
+ private class BandwidthLimits {
+ private final Long maxKbps;
+ private final Long maxBurstKb;
+
+ public BandwidthLimits(Long maxKbps, Long maxBurstKb) {
+ this.maxKbps = replaceNull(maxKbps);
+ this.maxBurstKb = replaceNull(maxBurstKb);
+ }
+
+ public Long getMaxKbps() {
+ return maxKbps;
+ }
+
+ public Long getMaxBurstKb() {
+ return maxBurstKb;
+ }
+
+ private Long replaceNull(Long value) {
+ return (value == null) ? Long.valueOf(0) : value;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ BandwidthLimits other = (BandwidthLimits) obj;
+ if (!getOuterType().equals(other.getOuterType()))
+ return false;
+ if (maxBurstKb == null) {
+ if (other.maxBurstKb != null)
+ return false;
+ } else if (!maxBurstKb.equals(other.maxBurstKb))
+ return false;
+ if (maxKbps == null) {
+ if (other.maxKbps != null)
+ return false;
+ } else if (!maxKbps.equals(other.maxKbps))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "BandwidthLimitsBandwidthLimitsalues [maxKbps=" + maxKbps + ", maxBurstKb=" + maxBurstKb + "]";
+ }
+
+ private UniQosManager getOuterType() {
+ return UniQosManager.this;
+ }
+ }
+}
-<!-- Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights
- reserved. This program and the accompanying materials are made available
- under the terms of the Eclipse Public License v1.0 which accompanies this
- distribution, and is available at http://www.eclipse.org/legal/epl-v10.html -->
+<!-- Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights
+ reserved. This program and the accompanying materials are made available
+ under the terms of the Eclipse Public License v1.0 which accompanies this
+ distribution, and is available at http://www.eclipse.org/legal/epl-v10.html -->
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
- xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
- odl:use-default-for-reference-types="true">
-
- <reference id="dataBroker"
- interface="org.opendaylight.controller.md.sal.binding.api.DataBroker" />
- <reference id="notificationPublishService"
- interface="org.opendaylight.controller.md.sal.binding.api.NotificationPublishService" />
- <odl:rpc-service id="odlArputilService"
- interface="org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService" />
-
-
- <bean id="uniPortManager" class="org.opendaylight.unimgr.mef.netvirt.UniPortManager">
- <argument ref="dataBroker" />
- </bean>
-
- <bean id="nodeConnectorListener"
- class="org.opendaylight.unimgr.mef.netvirt.NodeConnectorListener">
- <argument ref="dataBroker" />
- <argument ref="uniPortManager" />
- <argument value="false" />
- </bean>
-
- <bean id="evcListener" class="org.opendaylight.unimgr.mef.netvirt.EvcListener">
- <argument ref="dataBroker" />
- <argument ref="uniPortManager" />
- </bean>
-
- <bean id="ipvcListener" class="org.opendaylight.unimgr.mef.netvirt.IpvcListener">
- <argument ref="dataBroker" />
- <argument ref="uniPortManager" />
- <argument ref="subnetListener" />
- </bean>
-
- <bean id="subnetListener" class="org.opendaylight.unimgr.mef.netvirt.SubnetListener">
- <argument ref="dataBroker" />
- <argument ref="notificationPublishService" />
- <argument ref="qwMacListener" />
- <argument value="5" />
- </bean>
-
- <bean id="qwMacListener" class="org.opendaylight.unimgr.mef.netvirt.GwMacListener">
- <argument ref="dataBroker" />
- <argument ref="odlArputilService" />
- <argument value="10" />
- </bean>
+ xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+ odl:use-default-for-reference-types="true">
+
+ <reference id="dataBroker"
+ interface="org.opendaylight.controller.md.sal.binding.api.DataBroker" />
+ <reference id="notificationPublishService"
+ interface="org.opendaylight.controller.md.sal.binding.api.NotificationPublishService" />
+ <odl:rpc-service id="odlArputilService"
+ interface="org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService" />
+ <odl:rpc-service id="odlInterfaceRpcService"
+ interface="org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService" />
+
+ <bean id="uniPortManager" class="org.opendaylight.unimgr.mef.netvirt.UniPortManager">
+ <argument ref="dataBroker" />
+ </bean>
+
+ <bean id="nodeConnectorListener"
+ class="org.opendaylight.unimgr.mef.netvirt.NodeConnectorListener">
+ <argument ref="dataBroker" />
+ <argument ref="uniPortManager" />
+ <argument value="false" />
+ </bean>
+
+ <bean id="evcListener" class="org.opendaylight.unimgr.mef.netvirt.EvcListener">
+ <argument ref="dataBroker" />
+ <argument ref="uniPortManager" />
+ <argument ref="uniQosManager" />
+ </bean>
+
+ <bean id="ipvcListener" class="org.opendaylight.unimgr.mef.netvirt.IpvcListener">
+ <argument ref="dataBroker" />
+ <argument ref="uniPortManager" />
+ <argument ref="subnetListener" />
+ <argument ref="uniQosManager" />
+ </bean>
+
+ <bean id="subnetListener" class="org.opendaylight.unimgr.mef.netvirt.SubnetListener">
+ <argument ref="dataBroker" />
+ <argument ref="notificationPublishService" />
+ <argument ref="qwMacListener" />
+ <argument value="5" />
+ </bean>
+
+ <bean id="qwMacListener" class="org.opendaylight.unimgr.mef.netvirt.GwMacListener">
+ <argument ref="dataBroker" />
+ <argument ref="odlArputilService" />
+ <argument value="10" />
+ </bean>
+
+ <bean id="uniQosManager" class="org.opendaylight.unimgr.mef.netvirt.UniQosManager">
+ <argument ref="dataBroker" />
+ <argument ref="odlInterfaceRpcService" />
+ </bean>
</blueprint>