Merge "Tenant dialogs"
authorMartin Sunal <msunal@cisco.com>
Thu, 19 May 2016 10:04:00 +0000 (10:04 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 19 May 2016 10:04:00 +0000 (10:04 +0000)
56 files changed:
groupbasedpolicy-ui/module/src/main/resources/gbp/common/gbp.controller.js
groupbasedpolicy-ui/module/src/main/resources/gbp/common/gbp.module.js
groupbasedpolicy-ui/module/src/main/resources/gbp/common/views/index.tpl.html
groupbasedpolicy-ui/module/src/main/resources/gbp/contract/add-contract.controller.js [new file with mode: 0644]
groupbasedpolicy-ui/module/src/main/resources/gbp/contract/contract-list.service.js [new file with mode: 0644]
groupbasedpolicy-ui/module/src/main/resources/gbp/contract/contract.controller.js
groupbasedpolicy-ui/module/src/main/resources/gbp/contract/contract.service.js [new file with mode: 0644]
groupbasedpolicy-ui/module/src/main/resources/gbp/contract/contract.tpl.html
groupbasedpolicy-ui/module/src/main/resources/gbp/contract/dialog-add-contract.tpl.html [new file with mode: 0644]
groupbasedpolicy-ui/module/src/main/resources/gbp/epg/add-epg.controller.js [new file with mode: 0644]
groupbasedpolicy-ui/module/src/main/resources/gbp/epg/dialog-add-epg.tpl.html [new file with mode: 0644]
groupbasedpolicy-ui/module/src/main/resources/gbp/epg/epg.controller.js
groupbasedpolicy-ui/module/src/main/resources/gbp/epg/epg.service.js
groupbasedpolicy-ui/module/src/main/resources/gbp/epg/epg.tpl.html
groupbasedpolicy/pom.xml
groupbasedpolicy/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/GroupbasedpolicyModule.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/base_endpoint/BaseEndpointRpcRegistry.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/location/resolver/LocationResolver.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/AddressEndpointUtils.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ContainmentEndpointUtils.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/EndpointInfo.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/EndpointLocationInfo.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/EndpointLocationUtils.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/RendererConfigurationBuilder.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/RendererManager.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/RendererUtils.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ResolvedPolicyInfo.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/listener/EndpointLocationsListener.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/listener/EndpointsListener.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/listener/ForwardingListener.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/listener/RenderersListener.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/listener/ResolvedPoliciesListener.java [new file with mode: 0644]
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/IidFactory.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/PolicyInfoUtils.java
groupbasedpolicy/src/main/yang/model/base-endpoint.yang
groupbasedpolicy/src/main/yang/model/endpoint-location-provider.yang
groupbasedpolicy/src/main/yang/model/forwarding.yang
groupbasedpolicy/src/main/yang/model/renderer.yang
groupbasedpolicy/src/main/yang/renderermanager/resolved-policy.yang
groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/base_endpoint/BaseEndpointRpcRegistryTest.java
groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/location/resolver/LocationResolverTest.java [new file with mode: 0644]
groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/renderer/RendererManagerDataBrokerTest.java [new file with mode: 0644]
groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/renderer/RendererManagerTest.java [new file with mode: 0644]
groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/renderer/TestDataFactory.java [new file with mode: 0644]
groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/util/IidFactoryTest.java
location-providers/ne-location-provider/src/main/java/org/opendaylight/groupbasedpolicy/ne/location/provider/NeLocationProvider.java
location-providers/ne-location-provider/src/test/java/org/opendaylight/groupbasedpolicy/ne/location/provider/NeLocationProviderTest.java
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/endpoint/EndpointManagerListenerTest.java [changed mode: 0644->0755]
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ActionDefinitionListenerTest.java [new file with mode: 0755]
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ClassifierDefinitionListenerTest.java [new file with mode: 0755]
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/statistics/ResolvedPolicyClassifierListenerTest.java [new file with mode: 0755]
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/statistics/SflowClientSettingsListenerTest.java [new file with mode: 0755]
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/statistics/flowcache/FlowCacheFactoryTest.java
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/test/DataChangeListenerTester.java [new file with mode: 0755]
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/test/ParameterValueList.java [new file with mode: 0755]
sxp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/sxp/mapper/impl/SxpMapperReactorImpl.java

index 0b6d52cb93794bcc4017f12cada0cc7ada33b0f9..8575dad5f0d477f840e42c8fa500b875d720dcd8 100644 (file)
@@ -3,25 +3,46 @@ define(['app/gbp/common/gbp.service'], function () {
 
     angular.module('app.gbp').controller('RootGbpCtrl', RootGbpCtrl);
 
-    RootGbpCtrl.$inject = ['$state', '$scope', 'RootGbpService'];
+    RootGbpCtrl.$inject = ['$state', '$scope', 'RootGbpService', 'TenantListService', 'TenantService', 'ContractService'];
 
-    function RootGbpCtrl($state, $scope, RootGbpService) {
+    function RootGbpCtrl($state, $scope, RootGbpService, TenantListService, TenantService, ContractService) {
         /* properties */
         $scope.stateUrl = null;
         $scope.sidePanelPage = false;
+        $scope.rootTenant = TenantService.createObject();
+        $scope.rootTenants = TenantListService.createList();
+        $scope.policyDisabled = true;
 
         /* methods */
+        $scope.broadcastFromRoot = broadcastFromRoot;
         $scope.closeSidePanel = closeSidePanel;
         $scope.openSidePanel = openSidePanel;
+        $scope.setRootTenant = setRootTenant;
 
         RootGbpService.setMainClass();
         console.log('RootGbpCtrl initialized');
 
+        init();
+
         /* implementations */
         /**
          * Sets '$scope.sidePanelPage' to false. This variable is watched in index.tpl.html template
          * and opens/closes side panel
          */
+        function init() {
+            $scope.rootTenants.clearData();
+            $scope.rootTenants.get('config');
+        }
+
+        function broadcastFromRoot(eventName, val) {
+            $scope.$broadcast(eventName, val);
+        }
+
+        function setRootTenant() {
+            $scope.broadcastFromRoot('ROOT_TENANT_CHANGED');
+            enableButtons();
+        }
+
         function closeSidePanel() {
             $scope.sidePanelPage = false;
         }
@@ -42,6 +63,9 @@ define(['app/gbp/common/gbp.service'], function () {
             $scope.sidePanelPage = true;
         }
 
+        function enableButtons() {
+            $scope.policyDisabled = false;
+        }
         /* event listeners */
         /**
          * Event fired after content loaded, setStateUrl function is called to fill stateUrl method
index 37773cfb2fbcf4d2251582b88ab6c5778ad052fb..11db2640daf02e98c98011cf26fa7a1365433806 100644 (file)
@@ -27,6 +27,7 @@ define([
         /*$translatePartialLoaderProvider.addPart('app/gbp/assets/data/locale');*/
 
         NavHelperProvider.addControllerUrl('app/gbp/common/gbp.controller');
+        NavHelperProvider.addControllerUrl('app/gbp/contract/add-contract.controller');
         NavHelperProvider.addControllerUrl('app/gbp/contract/contract.controller');
         NavHelperProvider.addControllerUrl('app/gbp/epg/epg.controller');
         NavHelperProvider.addControllerUrl('app/gbp/policy/policy.controller');
@@ -86,9 +87,13 @@ define([
             access: access.admin,
             templateUrl: 'src/app/gbp/common/views/index.tpl.html',
             views: {
-                '': {
-                    controller: 'PolicyController',
-                    templateUrl: 'src/app/gbp/policy/policy.tpl.html',
+                'main_top': {
+                    controller: 'EpgController',
+                    templateUrl: 'src/app/gbp/epg/epg.tpl.html',
+                },
+                'main_bottom': {
+                    controller: 'ContractController',
+                    templateUrl: 'src/app/gbp/contract/contract.tpl.html',
                 },
             },
         });
@@ -109,16 +114,24 @@ define([
             },
         });
 
-        $stateProvider.state('main.gbp.index.policy.contract', {
-            url: '/contract',
+        $stateProvider.state('main.gbp.index.contract', {
+            url: '/policy/contract',
             access: access.admin,
             templateUrl: 'src/app/gbp/common/views/index.tpl.html',
             views: {
                 '': {
-                    controller: 'PolicyController',
-                    templateUrl: 'src/app/gbp/policy/policy.tpl.html',
+                    controller: 'ContractController',
+                    templateUrl: 'src/app/gbp/contract/contract.tpl.html',
                 },
-                'sidePanel': {
+            },
+        });
+
+        $stateProvider.state('main.gbp.index.contractId', {
+            url: '/policy/contract/{contractId}',
+            access: access.admin,
+            templateUrl: 'src/app/gbp/common/views/index.tpl.html',
+            views: {
+                '': {
                     controller: 'ContractController',
                     templateUrl: 'src/app/gbp/contract/contract.tpl.html',
                 },
index e515d2e177e21e0d461e95ae80b4d5bd447ae7ea..ebe4f386063130a1b4d28eda69c5048c16024f93 100644 (file)
@@ -3,15 +3,31 @@
         <md-toolbar>
             <div class="md-toolbar-tools">
                 <md-button ng-href="#/gbp/index/tenant" ng-click="closeSidePanel()" class="md-primary">Tenant</md-button>
-                <md-button ng-href="#/gbp/index/policy" ng-click="closeSidePanel()" class="md-primary">Policy</md-button>
+                <!-- <md-button ng-href="#/gbp/index/policy" ng-click="closeSidePanel()" class="md-primary">Policy</md-button> -->
+
+                <md-menu class="md-primary" class="md-toolbar-tools" style="background-color:rgb(33,150,243);color:black;">
+                    <md-button ng-click="$mdOpenMenu($event)" style="background-color:rgb(33,150,243);color:black;">Policy</md-button>
+                    <md-menu-content style="background-color:rgb(33,150,243);color:black;">
+                        <md-button ng-click="" ng-disabled="policyDisabled" ng-href="#/gbp/index/policy/epg" style="background-color:rgb(33,150,243);color:black;">EPGs</md-button>
+                        <md-button ng-click="" ng-disabled="policyDisabled" ng-href="#/gbp/index/policy/contract" style="background-color:rgb(33,150,243);color:black;">Contracts</md-button>
+                    </md-menu-content>
+                </md-menu>
+
                 <span flex></span>
-                <md-button ng-if="stateUrl === '/policy'" ng-href="#/gbp/index/policy/epg" ng-click="openSidePanel()" class="md-primary">EPGs</md-button>
-                <md-button ng-if="stateUrl === '/policy'" ng-href="#/gbp/index/policy/contract" ng-click="openSidePanel()" class="md-primary">Contracts</md-button>
+                <md-select ng-model="rootTenant" ng-change="setRootTenant()">
+                    <md-option ng-repeat="item in rootTenants.data" ng-value="{{item}}">{{item.data.id}}</md-option>
+                </md-select>
+                <!-- <md-button ng-if="stateUrl === '/policy'" ng-href="#/gbp/index/policy/epg" ng-click="openSidePanel()" class="md-primary">EPGs</md-button>
+                <md-button ng-if="stateUrl === '/policy'" ng-href="#/gbp/index/policy/contract" ng-click="openSidePanel()" class="md-primary">Contracts</md-button> -->
             </div>
         </md-toolbar>
-        <md-content md-scroll-y flex ui-view></md-content>
+        <!-- <md-content md-scroll-y flex ui-view></md-content> -->
+        <md-content md-scroll-y flex ui-view>
+            <md-content md-scroll-y flex ui-view="main_top" class="col-md-6"></md-content>
+            <md-content md-scroll-y flex ui-view="main_bottom" class="col-md-6"></md-content>
+        </md-content>
     </div>
-    <md-sidenav class="md-sidenav-right md-whiteframe-z1 detail-view" md-is-locked-open="sidePanelPage">
+    <!-- <md-sidenav class="md-sidenav-right md-whiteframe-z1 detail-view" md-is-locked-open="sidePanelPage">
         <md-toolbar>
             <div class="md-toolbar-tools">
                 <h2>
@@ -24,5 +40,5 @@
         <md-content flex>
             <div flex layout="column" ui-view="sidePanel"></div>
         </md-content>
-    </md-sidenav>
+    </md-sidenav> -->
 </div>
diff --git a/groupbasedpolicy-ui/module/src/main/resources/gbp/contract/add-contract.controller.js b/groupbasedpolicy-ui/module/src/main/resources/gbp/contract/add-contract.controller.js
new file mode 100644 (file)
index 0000000..199d78f
--- /dev/null
@@ -0,0 +1,32 @@
+define([
+    'app/gbp/contract/contract.service'
+], function () {
+    'use strict';
+
+    angular.module('app.gbp').controller('AddContractController', AddContractController);
+
+    AddContractController.$inject = ['$mdDialog', '$scope', 'ContractService', 'contract'];
+    /* @ngInject */
+    function AddContractController($mdDialog, $scope, ContractService, contract) {
+        /* properties */
+        $scope.contract = contract ? contract : ContractService.createObject();
+
+        /* methods */
+        $scope.closeDialog = closeDialog;
+        $scope.save = save;
+        /* Implementations */
+
+        function closeDialog(){
+            $mdDialog.cancel();
+            $scope.getContractList();
+        }
+
+        function save() {
+            $scope.contract.put($scope.rootTenant.data.id, function (data) {
+                $scope.closeDialog();
+            }, function (err) {
+            } );
+        }
+
+    }
+});
diff --git a/groupbasedpolicy-ui/module/src/main/resources/gbp/contract/contract-list.service.js b/groupbasedpolicy-ui/module/src/main/resources/gbp/contract/contract-list.service.js
new file mode 100644 (file)
index 0000000..c33ece8
--- /dev/null
@@ -0,0 +1,59 @@
+define([], function () {
+    'use strict';
+
+    angular.module('app.gbp').service('ContractListService', ContractListService);
+
+    ContractListService.$inject = ['Restangular', 'ContractService'];
+
+    function ContractListService(Restangular, ContractService) {
+        /* methods */
+        this.createList = createList;
+
+        function ContractList() {
+            /* properties */
+            this.data = [];
+
+            /* methods */
+            this.setData = setData;
+            this.get = get;
+            this.clearData = clearData;
+
+            /* Implementation */
+            /**
+             * fills ContractList object with data
+             * @param data
+             */
+            function setData(data) {
+                var self = this;
+                data.forEach(function (dataElement) {
+                    self.data.push(ContractService.createObject(dataElement));
+                });
+            }
+
+            function clearData() {
+                var self = this;
+                self.data = [];
+            }
+
+            function get(tenantId) {
+                /* jshint validthis:true */
+                var self = this;
+
+                var restObj = Restangular.one('restconf').one('config').one('policy:tenants')
+                    .one('tenant').one(tenantId).one('policy');
+
+                return restObj.get().then(function (data) {
+                    self.setData(data.policy.contract);
+                });
+            }
+        }
+
+        function createList() {
+            var obj = new ContractList();
+
+            return obj;
+        }
+    }
+
+    return ContractListService;
+});
index 5d3fa1dea90ba0b7b513a915e7e25dc26690152c..b4827603357e3e9aab6fd157745349284a585960 100644 (file)
@@ -1,13 +1,65 @@
 define([
-
+    'app/gbp/contract/contract.service',
+    'app/gbp/contract/contract-list.service',
 ], function () {
     'use strict';
 
     angular.module('app.gbp').controller('ContractController', ContractController);
 
-    ContractController.$inject = ['$scope'];
+    ContractController.$inject = ['$mdDialog', '$scope', 'TenantListService', 'TenantService', 'ContractService', 'ContractListService', '$stateParams'];
+
+    function ContractController($mdDialog, $scope, TenantListService, TenantService, ContractService, ContractListService, $stateParams) {
+        $scope.contracts = ContractListService.createList();
+        $scope.openContractDialog = openContractDialog;
+        $scope.contractsTableQuery = {
+            order: 'data.id',
+            limit: 25,
+            page: 1,
+            options: [25, 50, 100],
+            filter: '',
+        };
+        $scope.getContractList = getContractList;
+        $scope.deleteContractDialog = deleteContractDialog;
+
+        getContractList();
+
+        function getContractList() {
+            $scope.contracts.clearData();
+            $scope.contracts.get($scope.rootTenant.data.id);
+        }
+
+        function openContractDialog(contractData) {
+            $mdDialog.show({
+                clickOutsideToClose: true,
+                controller: 'AddContractController',
+                preserveScope: true,
+                templateUrl: 'src/app/gbp/contract/dialog-add-contract.tpl.html',
+                parent: angular.element(document.body),
+                scope: $scope,
+                locals: {
+                    contract: contractData,
+                },
+            });
+        }
+
+        function deleteContractDialog(contractData) {
+            var confirm = $mdDialog.confirm()
+                .title('Delete contract')
+                .textContent('Do you want to delete contract ' + contractData.data.id + '?')
+                .ok('Delete')
+                .cancel('Cancel');
+
+            $mdDialog.show(confirm).then(function () {
+                contractData.deleteContract($scope.rootTenant.data.id,
+                    function () {
+                        $scope.getContractList();
+                    }
+                );
+            }, function () {
 
-    function ContractController($scope) {
+            });
+        }
 
+        $scope.$on('ROOT_TENANT_CHANGED', getContractList);
     }
 });
diff --git a/groupbasedpolicy-ui/module/src/main/resources/gbp/contract/contract.service.js b/groupbasedpolicy-ui/module/src/main/resources/gbp/contract/contract.service.js
new file mode 100644 (file)
index 0000000..4f7073d
--- /dev/null
@@ -0,0 +1,105 @@
+define([], function () {
+    'use strict';
+
+    angular.module('app.gbp').service('ContractService', ContractService);
+
+    ContractService.$inject = ['Restangular'];
+
+    function ContractService(Restangular) {
+        /* methods */
+        this.createObject = createObject;
+
+        /**
+         * Contract constructor
+         * @constructor
+         */
+        function Contract() {
+            /* properties */
+            this.data = {};
+            /* methods */
+            this.setData = setData;
+            this.get = get;
+            this.put = put;
+            this.deleteContract = deleteContract;
+
+            /* Implementation */
+            /**
+             * fills Contract object with data
+             * @param data
+             */
+            function setData(data) {
+                this.data.id = data.id;
+                this.data.description = data.description;
+                this.data.parent = data.parent;
+
+                // TODO: use objects
+                this.data['forwarding-context'] = data['forwarding-context'];
+                this.data.target = data.target;
+                this.data.subject = data.subject;
+                this.data.clause = data.clause;
+                this.data.quality = data.quality;
+            }
+
+            /**
+             * gets one Contract object from Restconf
+             * @param id
+             * @returns {*}
+             */
+            function get(id) {
+                var self = this;
+
+                var restObj = Restangular.one('restconf').one('config').one('policy:tenants')
+                            .one('tenant').one(id).one('policy').one('contract').one(id);
+
+                return restObj.get().then(function (data) {
+                    self.setData(data.contract[0]);
+                });
+            }
+
+            function put(id, successCallback) {
+                var self = this;
+
+                var restObj = Restangular.one('restconf').one('config').one('policy:tenants').one('tenant')
+                    .one(id).one('policy').one('contract').one(self.data.id),
+                    dataObj = { contract: [self.data] };
+
+                return restObj.customPUT(dataObj).then(function (data) {
+                    successCallback(data);
+                }, function (res) {
+
+                });
+            }
+
+            function deleteContract(id, successCallback) {
+                var self = this;
+
+                var restObj = Restangular.one('restconf').one('config').one('policy:tenants').one('tenant')
+                    .one(id).one('policy').one('contract').one(self.data.id);
+
+                return restObj.remove().then(function (data) {
+                    successCallback(data);
+                }, function (res) {
+
+                });
+            }
+
+        }
+
+        /**
+         * creates Contract object and fills it with data if available
+         * @param data
+         * @returns {Contract}
+         */
+        function createObject(data) {
+            var obj = new Contract();
+
+            if (data) {
+                obj.setData(data);
+            }
+
+            return obj;
+        }
+    }
+
+    return ContractService;
+});
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..071990e5721446ea4905d9448236d4076f6f75f3 100644 (file)
@@ -0,0 +1,54 @@
+<section flex layout="column">
+    <div flex layout="row">
+        <md-button ng-click="openContractDialog()" class="md-primary">Add</md-button>
+        <md-button ng-click="getContractList()" class="md-primary">Reload</md-button>
+    </div>
+    <md-table-container ng-if="contracts.data.length" ng-hide="contractId.length">
+        <table md-table>
+            <thead md-head md-order="contractsTableQuery.order">
+            <tr md-row>
+                <th md-column md-order-by="data.id"><span>Id</span></th>
+                <th md-column md-order-by="data.parent"><span>Parent</span></th>
+                <th md-column md-order-by="data.description"><span>Description</span></th>
+                <th md-column><span>Actions</span></th>
+            </tr>
+            </thead>
+            <tbody md-body>
+            <tr md-row ng-repeat="contract in contracts.data | filter: contractsTableQuery.filter  | orderBy : contractsTableQuery.order | limitTo: contractsTableQuery.limit : (contractsTableQuery.page -1) * contractsTableQuery.limit">
+                <td md-cell>{{contract.data.id}}</td>
+                <td md-cell>{{contract.data.parent}}</td>
+                <td md-cell>{{contract.data.description}}</td>
+                <td md-cell>
+                    <md-button class="md-icon-button" ng-click="openContractDialog(contract)">
+                        <md-icon>edit</md-icon>
+                    </md-button>
+                    <md-button class="md-icon-button" ng-click="deleteContractDialog(contract)">
+                        <md-icon>delete</md-icon>
+                    </md-button>
+                </td>
+            </tr>
+
+            </tbody>
+        </table>
+        <md-table-pagination md-limit="contractsTableQuery.limit"
+                             md-page="contractsTableQuery.page"
+                             md-options="contractsTableQuery.options"
+                             md-total="{{contracts.data.length}}"
+                             md-page-select="options.pageSelect">
+        </md-table-pagination>
+    </md-table-container>
+
+    <section ng-if="contractId.length">
+        Details of contract: <u>{{contract1}}</u><br /><br />
+        <u>contract1:</u><br />
+        id: {{contract.data.id}}<br />
+        description: {{contract.data.description}}<br />
+        parent:{{contract.data.parent}}<br />
+        his containers:</b><br />
+        <u>Target object:</u><br />{{contract.data.target}}
+        <u>Subject object:</u><br />{{contract.data.subject}}
+        <u>Clause object:</u><br />{{contract.data.clause}}
+        <u>Quality object:</u><br />{{contract.data.quality}}
+    </section>
+
+</section>
diff --git a/groupbasedpolicy-ui/module/src/main/resources/gbp/contract/dialog-add-contract.tpl.html b/groupbasedpolicy-ui/module/src/main/resources/gbp/contract/dialog-add-contract.tpl.html
new file mode 100644 (file)
index 0000000..8e84c1a
--- /dev/null
@@ -0,0 +1,50 @@
+<md-dialog ng-cloak class="gbpDialogWrapper">
+    <form name="contractForm">
+        <md-toolbar>
+            <div class="md-toolbar-tools">
+                <h2>contract</h2>
+                <span flex></span>
+                <md-button ng-click="closeDialog()" class="md-button">Close dialog</md-button>
+            </div>
+        </md-toolbar>
+        <md-dialog-content style="width:350px;">
+            <div layout="column" class="layout-padding-lr15">
+                <div layout="row">
+                    <md-input-container flex>
+                        <label>Id</label>
+                        <input name="id" ng-model="contract.data.id" ng-required="true">
+                        <div ng-messages="contractForm.id.$error">
+                            <div ng-message="required">Required field</div>
+                        </div>
+                    </md-input-container>
+                    <md-input-container flex>
+                        <label>Parent</label>
+                        <input name="parent" ng-model="contract.data.parent" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\\-_.])*$/" ng-required="true">
+                        <div ng-messages="contractForm.parent.$error">
+                            <div ng-message="required">Required field.</div>
+                            <div ng-message="pattern">
+                                Invalid pattern.
+                                <md-tooltip md-direction="right" style="padding-left: 10px;">Value must match: ^[a-zA-Z]([a-zA-Z0-9\\-_.])*$</md-tooltip>
+                            </div>
+                        </div>
+                    </md-input-container>
+                </div>
+                <div layout="row">
+                    <md-input-container flex>
+                        <label>Description</label>
+                        <input name="description" ng-model="contract.data.description">
+                    </md-input-container>
+                </div>
+            </div>
+        </md-dialog-content>
+        <md-dialog-actions layout="row">
+            <span flex></span>
+            <md-button ng-click="closeDialog()" class="md-primary">
+                Close
+            </md-button>
+            <md-button ng-click="save()" style="margin-right:20px;" ng-disabled="contractForm.$invalid" class="md-primary">
+                Save
+            </md-button>
+        </md-dialog-actions>
+    </form>
+</md-dialog>
diff --git a/groupbasedpolicy-ui/module/src/main/resources/gbp/epg/add-epg.controller.js b/groupbasedpolicy-ui/module/src/main/resources/gbp/epg/add-epg.controller.js
new file mode 100644 (file)
index 0000000..eee5e77
--- /dev/null
@@ -0,0 +1,32 @@
+define([
+    'app/gbp/epg/epg.service'
+], function () {
+    'use strict';
+
+    angular.module('app.gbp').controller('AddEpgController', AddEpgController);
+
+    AddEpgController.$inject = ['$mdDialog', '$scope', 'EpgService', 'epg'];
+    /* @ngInject */
+    function AddEpgController($mdDialog, $scope, EpgService, epg) {
+        /* properties */
+        $scope.epg = epg ? epg : EpgService.createObject();
+
+        /* methods */
+        $scope.closeDialog = closeDialog;
+        $scope.save = save;
+
+        /* Implementations */
+
+        function closeDialog(){
+            $mdDialog.cancel();
+            $scope.getEpgList();
+        }
+
+        function save() {
+            $scope.epg.put($scope.rootTenant, function(data) {
+                $scope.closeDialog();
+            }, function(err) {
+            } );
+        }
+    }
+});
diff --git a/groupbasedpolicy-ui/module/src/main/resources/gbp/epg/dialog-add-epg.tpl.html b/groupbasedpolicy-ui/module/src/main/resources/gbp/epg/dialog-add-epg.tpl.html
new file mode 100644 (file)
index 0000000..65b0483
--- /dev/null
@@ -0,0 +1,68 @@
+<md-dialog ng-cloak class="gbpDialogWrapper">
+    <form name="epgForm">
+        <md-toolbar>
+            <div class="md-toolbar-tools">
+                <h2>EPG</h2>
+                <span flex></span>
+                <md-button ng-click="closeDialog()" class="md-button">Close dialog</md-button>
+            </div>
+        </md-toolbar>
+        <md-dialog-content style="width:350px;">
+            <div layout="column" class="layout-padding-lr15">
+                <div layout="row">
+                    <md-input-container flex>
+                        <label>Id</label>
+                        <input name="id" ng-model="epg.data.id" ng-required="true">
+                        <div ng-messages="epgForm.id.$error" md-auto-hide="false">
+                            <div ng-message="required">Required field</div>
+                        </div>
+                    </md-input-container>
+                    <md-input-container flex>
+                        <label>Name</label>
+                        <input name="name" ng-model="epg.data.name" ng-required="true" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\\-_.])*$/">
+                        <div ng-messages="epgForm.name.$error" md-auto-hide="false">
+                            <div ng-message="required">Required field</div>
+                            <div ng-message="pattern">
+                                Invalid pattern.
+                                <md-tooltip md-direction="right" style="padding-left: 10px;">Value must matches: ^[a-zA-Z]([a-zA-Z0-9\\-_.])*$</md-tooltip>
+                            </div>
+                        </div>
+                    </md-input-container>
+                </div>
+                <div layout="row">
+                    <md-input-container flex>
+                        <label>Description</label>
+                        <input name="description" ng-model="epg.data.description">
+                    </md-input-container>
+                </div>
+                <div layout="row">
+                    <md-input-container flex>
+                        <label>intra-group-policy</label>
+                        <md-select name="intraGroupPolicy" ng-model="epg.data['intra-group-policy']">
+                            <md-option ng-repeat="igp in ['', 'allow', 'require-contract']" ng-value="igp">{{igp}}</md-option>
+                        </md-select>
+                    </md-input-container>
+                </div>
+                <div layout="row">
+                    <md-input-container flex>
+                        <label>network-domain</label>
+                        <input name="networkDomain" ng-model="epg.data['network-domain']">
+                    </md-input-container>
+                    <md-input-container flex>
+                        <label>parent</label>
+                        <input name="parent" ng-model="epg.data.parent">
+                    </md-input-container>
+                </div>
+            </div>
+        </md-dialog-content>
+        <md-dialog-actions layout="row">
+            <span flex></span>
+            <md-button ng-click="closeDialog()" class="md-primary">
+                Close
+            </md-button>
+            <md-button ng-click="save()" style="margin-right:20px;" ng-disabled="epgForm.$invalid" class="md-primary">
+                Save
+            </md-button>
+        </md-dialog-actions>
+    </form>
+</md-dialog>
index 56272301644ae476c6aa1dbaf7a6455842fed135..d3013969d364cc77916d95bd045dd9f7772ad47d 100644 (file)
@@ -6,16 +6,84 @@ define([
 
     angular.module('app.gbp').controller('EpgController', EpgController);
 
-    EpgController.$inject = ['$scope', 'EpgService', 'EpgListService'];
+    EpgController.$inject = ['$scope', '$stateParams', '$mdDialog', 'EpgService', 'EpgListService'];
 
-    function EpgController($scope, EpgService, EpgListService) {
-        $scope.epg = EpgService.createObject();
-        $scope.epg.get('epg_test', 'tenant_test');
-        console.log('Epg', $scope.epg);
+    function EpgController($scope, $stateParams, $mdDialog, EpgService, EpgListService) {
+        $scope.epgsTableQuery = {};
+
+        // $scope.epg = EpgService.createObject();
+        // $scope.epg.get($stateParams.epgId, $stateParams.tenantId);
 
         $scope.epgs = EpgListService.createList();
-        $scope.epgs.get('config', 'tenant2');
 
-        console.log('Epgs', $scope.epgs);
+        /* methods */
+        $scope.getEpgList = getEpgList;
+        $scope.openEpgDialog = openEpgDialog;
+        $scope.deleteEpgDialog = deleteEpgDialog;
+
+        init();
+
+        /* Implementations */
+
+        /**
+         * fills $scope.epgs array with data from data store
+         */
+        function getEpgList() {
+            if($stateParams.tenantId) {
+                $scope.epgs = EpgListService.createList();
+                $scope.epgs.get('config', $stateParams.tenantId);
+            }
+            else {
+                $scope.epgs = EpgListService.createList();
+                $scope.epgs.get('config', $scope.rootTenant);
+            }
+        }
+
+        /**
+         * Initializing function
+         */
+        function init() {
+            $scope.epgsTableQuery = {
+                order: 'data.id',
+                limit: 25,
+                page: 1,
+                options: [25, 50, 100],
+                filter: ''
+            };
+
+            getEpgList();
+        }
+
+        function openEpgDialog(epgData) {
+            $mdDialog.show({
+                clickOutsideToClose: true,
+                controller: 'AddEpgController',
+                preserveScope: true,
+                templateUrl: 'src/app/gbp/epg/dialog-add-epg.tpl.html',
+                parent: angular.element(document.body),
+                scope: $scope,
+                locals: {
+                    epg: epgData
+                }
+            });
+        }
+
+        function deleteEpgDialog(epgData) {
+            var confirm = $mdDialog.confirm()
+                .title('Delete EPG')
+                .textContent('Do you want to delete EPG ' + epgData.data.name + '?')
+                .ok('Delete')
+                .cancel('Cancel');
+
+            $mdDialog.show(confirm).then(function() {
+                epgData.deleteEpg($scope.rootTenant,
+                    function() {
+                        $scope.getEpgList();
+                    }
+                );
+            }, function() {
+
+            });
+        }
     }
 });
\ No newline at end of file
index bd2c0c58ee36dd858fa26e98d7497bfa11bbe93a..aee88c73ba4f862d749dd8af8b97d8b226051876 100644 (file)
@@ -20,6 +20,8 @@ define([], function() {
             /* methods */
             this.setData = setData;
             this.get = get;
+            this.put = put;
+            this.deleteEpg = deleteEpg;
 
             /* Implementation */
             /**
@@ -30,14 +32,14 @@ define([], function() {
                 this.data.id = data.id;
                 this.data.name = data.name;
                 this.data.description = data.description;
-                this.data.intraGroupPolicy = data['intra-group-policy'];
+                this.data['intra-group-policy'] = data['intra-group-policy'];
 
-                this.data.consumerNamedSelector = data['consumer-named-selector'];
-                this.data.providerNamedSelector = data['provider-named-selector'];
-                this.data.consumerTargetSelector = data['consumer-target-selector'];
-                this.data.providerTargerSelector = data['provider-target-selector'];
+                this.data['consumer-named-selector'] = data['consumer-named-selector'];
+                this.data['provider-named-selector'] = data['provider-named-selector'];
+                this.data['consumer-target-selector'] = data['consumer-target-selector'];
+                this.data['provider-target-selector'] = data['provider-target-selector'];
 
-                this.data.networkDomain = data['network-domain'];
+                this.data['network-domain'] = data['network-domain'];
                 this.data.parent = data.parent;
 
                 this.data.requirement = data.requirement;
@@ -59,6 +61,33 @@ define([], function() {
                     self.setData(data['endpoint-group'][0]);
                 });
             }
+
+            function put(idTenant, successCallback) {
+                var self = this;
+
+                var restObj = Restangular.one('restconf').one('config').one('policy:tenants').one('tenant')
+                    .one(idTenant).one('policy').one('endpoint-group').one(self.data.id),
+                    dataObj = {'endpoint-group': [self.data]};
+
+                return restObj.customPUT(dataObj).then(function(data) {
+                    successCallback(data);
+                }, function(res) {
+
+                });
+            }
+
+            function deleteEpg(idTenant, successCallback) {
+                var self = this;
+
+                var restObj = Restangular.one('restconf').one('config').one('policy:tenants').one('tenant')
+                    .one(idTenant).one('policy').one('endpoint-group').one(self.data.id);
+
+                return restObj.remove().then(function(data) {
+                    successCallback(data);
+                }, function(res) {
+
+                });
+            }
         }
 
         /**
index f391cc8bf88e1e268377f734c554c23121a1d759..52aec48a8ee3a82efea8a248e7d4c98210731f92 100644 (file)
@@ -1,9 +1,45 @@
-EPG<br/>
-id: {{epg.data.id}}<br/>
-name: {{epg.data.name}}<br/>
-description: {{epg.data.description}}<br/>
-intra-group-policy: {{epg.data.intraGroupPolicy}}<br/>
+<section flex layout="column">
+       <div flex layout="row">
+           <md-button ng-click="openEpgDialog()" class="md-primary">Add</md-button>
+           <md-button ng-click="getEpgList()" class="md-primary">Reload</md-button>
+       </div>
+    <md-table-container ng-if="epgs.data.length">
+        <table md-table>
+            <thead md-head md-order="epgsTableQuery.order">
+            <tr md-row>
+                   <th md-column md-order-by="data.id"><span>Id</span></th>
+                   <th md-column md-order-by="data.name"><span>Name</span></th>
+                   <th md-column md-order-by="data.description"><span>Description</span></th>
+                   <th md-column md-order-by="data['intra-group-policy']"><span>intra-group-policy</span></th>
+                   <th md-column md-order-by="data['network-domain']"><span>network-domain</span></th>
+                   <th md-column md-order-by="data.parent"><span>Parent</span></th>
+            </tr>
+            </thead>
+            <tbody md-body>
+            <tr md-row ng-repeat="epg in epgs.data | filter: epgsTableQuery.filter  | orderBy : epgsTableQuery.order | limitTo: epgsTableQuery.limit : (epgsTableQuery.page -1) * epgsTableQuery.limit">
+                   <td md-cell>{{epg.data.id}}</td>
+                   <td md-cell>{{epg.data.name}}</td>
+                   <td md-cell>{{epg.data.description}}</td>
+                   <td md-cell>{{epg.data['intra-group-policy']}}</td>
+                   <td md-cell>{{epg.data['network-domain']}}</td>
+                   <td md-cell>{{epg.data.parent}}</td>
+                <td md-cell>
+                    <md-button class="md-icon-button" ng-click="openEpgDialog(epg)">
+                        <md-icon>edit</md-icon>
+                    </md-button>
+                    <md-button class="md-icon-button" ng-click="deleteEpgDialog(epg)">
+                        <md-icon>delete</md-icon>
+                    </md-button>
+                </td>
+            </tr>
 
-<div ng-repeat="epgElement in epgs.data">
-    {{epgElement.data.id}}, {{epgElement.data.name}}, {{epgElement.data.description}}, {{epgElement.data.intraGroupPolicy}}, {{epgElement.data.networkDomain}}<br/>
-</div>
+            </tbody>
+        </table>
+        <md-table-pagination md-limit="epgsTableQuery.limit"
+                             md-page="epgsTableQuery.page"
+                             md-options="epgsTableQuery.options"
+                             md-total="{{epgs.data.length}}"
+                             md-page-select="options.pageSelect">
+        </md-table-pagination>
+    </md-table-container>
+</section>
\ No newline at end of file
index d4db9198546f631fea2bbb3dbaef3207abe43a19..f18597d715214c85344b76deef436120cde2bb83 100755 (executable)
       <type>test-jar</type>
       <scope>test</scope>
     </dependency>
+    <dependency>
+        <groupId>org.opendaylight.controller.model</groupId>
+        <artifactId>model-inventory</artifactId>
+        <scope>test</scope>
+    </dependency>
   </dependencies>
 
 <!-- project build -->
index d8bb3b796b959419170d3150fed017bf9ee98357..3ba11fa66ed98de515637835653c3ba748c4c626 100644 (file)
@@ -11,6 +11,8 @@ package org.opendaylight.controller.config.yang.config.groupbasedpolicy;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.groupbasedpolicy.api.PolicyValidatorRegistry;
+import org.opendaylight.groupbasedpolicy.location.resolver.LocationResolver;
+import org.opendaylight.groupbasedpolicy.renderer.RendererManager;
 import org.opendaylight.groupbasedpolicy.sf.SubjectFeatureDefinitionProvider;
 import org.opendaylight.groupbasedpolicy.sf.SupportedActionDefinitionListener;
 import org.opendaylight.groupbasedpolicy.sf.SupportedClassifierDefinitionListener;
@@ -60,11 +62,15 @@ public class GroupbasedpolicyModule extends org.opendaylight.controller.config.y
         private final SubjectFeatureDefinitionProvider sfdp;
         private final SupportedClassifierDefinitionListener supportedClassifierDefinitionListener;
         private final SupportedActionDefinitionListener supportedActionDefinitionListener;
+        private final LocationResolver locationResolver;
+        private final RendererManager rendererManager;
 
         Instance(DataBroker dataProvider, PolicyValidatorRegistry validatorRegistry) throws TransactionCommitFailedException {
             sfdp = new SubjectFeatureDefinitionProvider(dataProvider);
             supportedClassifierDefinitionListener = new SupportedClassifierDefinitionListener(dataProvider, validatorRegistry);
             supportedActionDefinitionListener = new SupportedActionDefinitionListener(dataProvider);
+            locationResolver = new LocationResolver(dataProvider);
+            rendererManager = new RendererManager(dataProvider);
         }
 
         @Override
@@ -72,6 +78,8 @@ public class GroupbasedpolicyModule extends org.opendaylight.controller.config.y
             sfdp.close();
             supportedClassifierDefinitionListener.close();
             supportedActionDefinitionListener.close();
+            locationResolver.close();
+            rendererManager.close();
         }
     }
 
index d92edd19666014b4fe059472cc34c11fa7f1888f..899e29e8b00b081ded0f84d0f8535382b4983cdf 100644 (file)
@@ -9,38 +9,55 @@
 package org.opendaylight.groupbasedpolicy.base_endpoint;
 
 import com.google.common.base.Function;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.groupbasedpolicy.api.BaseEndpointRendererAugmentation;
 import org.opendaylight.groupbasedpolicy.api.BaseEndpointRendererAugmentationRegistry;
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
 import org.opendaylight.groupbasedpolicy.util.IidFactory;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.UnregisterEndpointInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.ParentEndpointChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.ParentContainmentEndpointCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.ParentContainmentEndpointCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.ParentEndpointCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.ParentEndpointCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.containment.endpoint._case.ParentContainmentEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.containment.endpoint._case.ParentContainmentEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpointBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointRegKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointRegKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.unregister.endpoint.input.AddressEndpointUnreg;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.unregister.endpoint.input.ContainmentEndpointUnreg;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.Nullable;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -48,10 +65,13 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.Future;
 
+import javax.annotation.Nullable;
+
 public class BaseEndpointRpcRegistry
-    implements BaseEndpointService, BaseEndpointRendererAugmentationRegistry, AutoCloseable {
+        implements BaseEndpointService, BaseEndpointRendererAugmentationRegistry, AutoCloseable {
 
-    static final ConcurrentMap<String, BaseEndpointRendererAugmentation> registeredRenderers = new ConcurrentHashMap<>();
+    static final ConcurrentMap<String, BaseEndpointRendererAugmentation> registeredRenderers =
+            new ConcurrentHashMap<>();
     private static final Logger LOG = LoggerFactory.getLogger(BaseEndpointRpcRegistry.class);
     private final DataBroker dataProvider;
     private final BindingAwareBroker.RpcRegistration<BaseEndpointService> rpcRegistration;
@@ -65,33 +85,11 @@ public class BaseEndpointRpcRegistry
     };
 
     public BaseEndpointRpcRegistry(DataBroker dataProvider, RpcProviderRegistry rpcRegistry) {
-        this.dataProvider = dataProvider;
-
-        if (rpcRegistry != null) {
-            rpcRegistration = rpcRegistry.addRpcImplementation(BaseEndpointService.class, this);
-            LOG.debug("Added Endpoints RPC Implementation Correctly");
-        } else {
-            rpcRegistration = null;
-        }
-
-        if (dataProvider != null) {
-            InstanceIdentifier<Endpoints> iid = InstanceIdentifier.builder(Endpoints.class).build();
-            WriteTransaction t = this.dataProvider.newWriteOnlyTransaction();
-            t.put(LogicalDatastoreType.OPERATIONAL, iid, new EndpointsBuilder().build());
-            CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();
-            Futures.addCallback(f, new FutureCallback<Void>() {
-
-                @Override
-                public void onFailure(Throwable t) {
-                    LOG.error("Could not write Endpoints base container", t);
-                }
+        Preconditions.checkNotNull(dataProvider);
+        Preconditions.checkNotNull(rpcRegistry);
 
-                @Override
-                public void onSuccess(Void result) {
-                    LOG.info("Endpoints container write successful");
-                }
-            });
-        }
+        this.dataProvider = dataProvider;
+        this.rpcRegistration = rpcRegistry.addRpcImplementation(BaseEndpointService.class, this);
     }
 
     /**
@@ -104,7 +102,7 @@ public class BaseEndpointRpcRegistry
     public void register(BaseEndpointRendererAugmentation baseEndpointRendererAugmentation) {
         if (baseEndpointRendererAugmentation != null) {
             registeredRenderers.putIfAbsent(baseEndpointRendererAugmentation.getClass().getName(),
-                baseEndpointRendererAugmentation);
+                    baseEndpointRendererAugmentation);
             LOG.info("Registered {}", baseEndpointRendererAugmentation.getClass().getName());
         }
     }
@@ -138,25 +136,294 @@ public class BaseEndpointRpcRegistry
         WriteTransaction t = dataProvider.newWriteOnlyTransaction();
 
         List<ContainmentEndpointReg> endpoints = input.getContainmentEndpointReg();
-        for (ContainmentEndpointReg ce : nullToEmpty(endpoints)) {
-            long stamp = (ce.getTimestamp() == null || ce.getTimestamp() == 0) ? timestamp : ce.getTimestamp();
-            ContainmentEndpoint endpoint = buildContainmentEndpoint(ce).setTimestamp(stamp).build();
-            t.put(LogicalDatastoreType.OPERATIONAL, IidFactory.containmentEndpointIid(endpoint.getKey()), endpoint,
-                    true);
-        }
+        ListenableFuture<RpcResult<Void>> failResult = verifyRegisterEndpointInput(input);
+        if (failResult == null) {
+            for (ContainmentEndpointReg ce : nullToEmpty(endpoints)) {
+                long stamp = (ce.getTimestamp() == null || ce.getTimestamp() == 0) ? timestamp : ce.getTimestamp();
+                ContainmentEndpoint endpoint = buildContainmentEndpoint(ce).setTimestamp(stamp).build();
+                t.put(LogicalDatastoreType.OPERATIONAL, IidFactory.containmentEndpointIid(endpoint.getKey()), endpoint,
+                        true);
+
+                updateContainmentEndpointRegChilds(t, endpoint);
+            }
+
+            List<AddressEndpointReg> addressEndpoints = input.getAddressEndpointReg();
+            for (AddressEndpointReg ae : nullToEmpty(addressEndpoints)) {
+                long stamp = (ae.getTimestamp() == null || ae.getTimestamp() == 0) ? timestamp : ae.getTimestamp();
+                AddressEndpoint endpoint = buildAddressEndpoint(ae).setTimestamp(stamp).build();
+                t.put(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(endpoint.getKey()), endpoint,
+                        true);
+
+                updateAddressEndpointRegChilds(t, endpoint);
 
-        List<AddressEndpointReg> addressEndpoints = input.getAddressEndpointReg();
-        for (AddressEndpointReg ae : nullToEmpty(addressEndpoints)) {
-            long stamp = (ae.getTimestamp() == null || ae.getTimestamp() == 0) ? timestamp : ae.getTimestamp();
-            AddressEndpoint endpoint = buildAddressEndpoint(ae).setTimestamp(stamp).build();
-            t.put(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(endpoint.getKey()), endpoint, true);
+                updateAddressEndpointRegParents(t, endpoint);
+            }
+        } else {
+            return failResult;
         }
 
         ListenableFuture<Void> r = t.submit();
         return Futures.transform(r, futureTrans);
     }
 
+    private void updateContainmentEndpointRegChilds(WriteTransaction t, ContainmentEndpoint containmentEndpoint) {
+        ReadOnlyTransaction readTransaction = dataProvider.newReadOnlyTransaction();
+
+        for (ChildEndpoint child : nullToEmpty(containmentEndpoint.getChildEndpoint())) {
+            AddressEndpointKey key = new AddressEndpointKey(child.getAddress(), child.getAddressType(),
+                    child.getContextId(), child.getContextType());
+            Optional<AddressEndpoint> addressEndpointOptional = DataStoreHelper
+                .readFromDs(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(key), readTransaction);
+
+            if (addressEndpointOptional.isPresent()) {
+                ParentEndpointChoice parentEndpointChoice = addressEndpointOptional.get().getParentEndpointChoice();
+                List<ParentContainmentEndpoint> parentContainmentEndpoints =
+                        getParentContainmentEndpoints(parentEndpointChoice);
+
+                ParentContainmentEndpoint parentContainmentEndpoint =
+                        new ParentContainmentEndpointBuilder().setContextId(containmentEndpoint.getContextId())
+                            .setContextType(containmentEndpoint.getContextType())
+                            .build();
+
+                if (!nullToEmpty(parentContainmentEndpoints).contains(parentContainmentEndpoint)) {
+                    parentContainmentEndpoints.add(parentContainmentEndpoint);
+                    AddressEndpoint updatedAddressEndpoint = new AddressEndpointBuilder(addressEndpointOptional.get())
+                        .setParentEndpointChoice(new ParentContainmentEndpointCaseBuilder()
+                            .setParentContainmentEndpoint(parentContainmentEndpoints).build())
+                        .build();
+
+                    t.put(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(key), updatedAddressEndpoint);
+                }
+            }
+        }
+    }
+
+    private ListenableFuture<RpcResult<Void>> verifyRegisterEndpointInput(RegisterEndpointInput input) {
+        ListenableFuture<RpcResult<Void>> result;
+        List<AddressEndpointReg> addressEndpointRegs = nullToEmpty(input.getAddressEndpointReg());
+        List<ContainmentEndpointReg> containmentEndpointRegs = nullToEmpty(input.getContainmentEndpointReg());
+
+        for (AddressEndpointReg addressEndpointReg : nullToEmpty(addressEndpointRegs)) {
+            result = verifyAddressEndpointChilds(addressEndpointRegs, addressEndpointReg);
+            if (result != null) {
+                return result;
+            }
+
+            result = verifyAddressEndpointParents(addressEndpointRegs, addressEndpointReg);
+            if (result != null) {
+                return result;
+            }
+        }
+
+        result = verifyContainmentEndpointChilds(addressEndpointRegs, containmentEndpointRegs);
+        if (result != null) {
+            return result;
+        }
+
+        return null;
+    }
+
+    private ListenableFuture<RpcResult<Void>> verifyContainmentEndpointChilds(
+            List<AddressEndpointReg> addressEndpointRegs, List<ContainmentEndpointReg> containmentEndpointRegs) {
+        for (ContainmentEndpointReg containmentEndpointReg : nullToEmpty(containmentEndpointRegs)) {
+            for (ChildEndpoint childEndpoint : nullToEmpty(containmentEndpointReg.getChildEndpoint())) {
+                AddressEndpointRegKey key = new AddressEndpointRegKey(childEndpoint.getAddress(),
+                        childEndpoint.getAddressType(), childEndpoint.getContextId(), childEndpoint.getContextType());
+                AddressEndpointReg addressEndpointRegChild = findAddressEndpointReg(key, addressEndpointRegs);
+                if (addressEndpointRegChild == null) {
+                    // todo this can be optimized if we move this to
+                    // updateContainmentEndpointRegChilds and verify child in one step with update.
+                    Optional<AddressEndpoint> addressEndpointOptional =
+                            DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                                    IidFactory.addressEndpointIid(new AddressEndpointKey(key.getAddress(),
+                                            key.getAddressType(), key.getContextId(), key.getContextType())),
+                                    dataProvider.newReadOnlyTransaction());
+                    if (!addressEndpointOptional.isPresent()) {
+                        LOG.debug("Child AddressEndpoint {} does not exist in RPC and DS.", childEndpoint);
+                        return buildFailFeature(
+                                String.format("Child AddressEndpoint %s does not exist in RPC and DS.", childEndpoint));
+                    }
+                } else {
+
+                    if (!containmentEndpointReg.getKey().equals(new ContainmentEndpointRegKey(
+                            addressEndpointRegChild.getContextId(), addressEndpointRegChild.getContextType()))) {
+                        LOG.debug(
+                                "Child AddressEndpoint {} in ContainmentEndpoint->ChildEndpoints does not contain a valid ContainmentEndpointRegKey.",
+                                addressEndpointRegChild);
+                        return buildFailFeature(String
+                            .format("AddressEndpoint in ContainmentEndpoint->ChildEndpoints does not contain a valid ContainmentEndpointRegKey."
+                                    + "\nChild element: %s", addressEndpointRegChild));
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    private ListenableFuture<RpcResult<Void>> verifyAddressEndpointParents(List<AddressEndpointReg> addressEndpointRegs,
+            AddressEndpointReg addressEndpointReg) {
+        ParentEndpointChoice parentEndpointChoice = addressEndpointReg.getParentEndpointChoice();
+        List<ParentEndpoint> parentEndpoints;
+        parentEndpoints =
+                (parentEndpointChoice instanceof ParentEndpointCase) ? ((ParentEndpointCase) parentEndpointChoice)
+                    .getParentEndpoint() : null;
+
+        for (ParentEndpoint parentEndpoint : nullToEmpty(parentEndpoints)) {
+            AddressEndpointRegKey key = new AddressEndpointRegKey(parentEndpoint.getAddress(),
+                    parentEndpoint.getAddressType(), parentEndpoint.getContextId(), parentEndpoint.getContextType());
+            AddressEndpointReg addressEndpointRegParent = findAddressEndpointReg(key, addressEndpointRegs);
+
+            if (addressEndpointRegParent == null) {
+                // todo this can be optimized if we move this to updateAddressEndpointRegParents and
+                // verify child in one step with update.
+                Optional<AddressEndpoint> addressEndpointOptional =
+                        DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                                IidFactory.addressEndpointIid(new AddressEndpointKey(key.getAddress(),
+                                        key.getAddressType(), key.getContextId(), key.getContextType())),
+                                dataProvider.newReadOnlyTransaction());
+                if (!addressEndpointOptional.isPresent()) {
+                    LOG.debug("Parent AddressEndpoint {} does not exist in RPC and DS.", parentEndpoint);
+                    return buildFailFeature(
+                            String.format("Parent AddressEndpoint %s does not exist in RPC and DS.", parentEndpoint));
+                }
+            } else {
+
+                List<ChildEndpoint> childEndpoints = addressEndpointRegParent.getChildEndpoint();
+
+                if (!nullToEmpty(childEndpoints).contains(new ChildEndpointBuilder(addressEndpointReg).build())) {
+                    LOG.debug("Parent AddressEndpoint {} does not contain a valid child AddressEndpoint.",
+                            addressEndpointRegParent);
+                    return buildFailFeature(String.format(
+                            "Parent AddressEndpoint does not contain a valid child AddressEndpoint."
+                                    + "\nParent AddressEndpoint: %s" + "\nChild AddressEndpoint: %s",
+                            addressEndpointRegParent, addressEndpointReg));
+                }
+            }
+        }
+        return null;
+    }
+
+    private ListenableFuture<RpcResult<Void>> verifyAddressEndpointChilds(List<AddressEndpointReg> addressEndpointRegs,
+            AddressEndpointReg addressEndpointReg) {
+        for (ChildEndpoint childEndpoint : nullToEmpty(addressEndpointReg.getChildEndpoint())) {
+            AddressEndpointRegKey key = new AddressEndpointRegKey(childEndpoint.getAddress(),
+                    childEndpoint.getAddressType(), childEndpoint.getContextId(), childEndpoint.getContextType());
+            AddressEndpointReg addressEndpointRegChild = findAddressEndpointReg(key, addressEndpointRegs);
+            if (addressEndpointRegChild == null) {
+                // todo this can be optimized if we move this to updateAddressEndpointRegChilds and
+                // verify child in one step with update.
+                Optional<AddressEndpoint> addressEndpointOptional =
+                        DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                                IidFactory.addressEndpointIid(new AddressEndpointKey(key.getAddress(),
+                                        key.getAddressType(), key.getContextId(), key.getContextType())),
+                                dataProvider.newReadOnlyTransaction());
+                if (!addressEndpointOptional.isPresent()) {
+                    LOG.debug("Child AddressEndpoint {} does not exist in RPC and DS.", childEndpoint);
+                    return buildFailFeature(
+                            String.format("Child AddressEndpoint %s does not exist in RPC and DS.", childEndpoint));
+                }
+            } else {
+
+                ParentEndpointChoice parentEndpointChoice = addressEndpointRegChild.getParentEndpointChoice();
+
+                if (!(parentEndpointChoice instanceof ParentEndpointCase)) {
+                    LOG.debug("Child AddressEndpoint {} does not contain list of parent elements.", childEndpoint);
+                    return buildFailFeature(String.format(
+                            "Child AddressEndpoint does not contain list of parent elements." + "\nChild element: %s",
+                            childEndpoint));
+                }
+
+                List<ParentEndpoint> parentEndpoints =
+                        nullToEmpty(((ParentEndpointCase) parentEndpointChoice).getParentEndpoint());
+                if (!parentEndpoints.contains(new ParentEndpointBuilder(addressEndpointReg).build())) {
+                    LOG.debug("Child AddressEndpoint {} does not contain a valid parent AddressEndpoint.",
+                            addressEndpointRegChild);
+                    return buildFailFeature(String.format(
+                            "Child AddressEndpoint does not contain a valid parent AddressEndpoint."
+                                    + "\nChild element: %s" + "\nparent AddressEndpoint: %s",
+                            addressEndpointRegChild, addressEndpointReg));
+                }
+            }
+        }
+        return null;
+    }
+
+    private AddressEndpointReg findAddressEndpointReg(AddressEndpointRegKey key, List<AddressEndpointReg> addressEndpointRegs) {
+        for (AddressEndpointReg addressEndpointReg : addressEndpointRegs) {
+            if (addressEndpointReg.getKey().equals(key)) {
+                return addressEndpointReg;
+            }
+        }
+        return null;
+    }
+
+    private void updateAddressEndpointRegParents(WriteTransaction t, AddressEndpoint endpoint) {
+        ParentEndpointCase parentEndpointCase = (ParentEndpointCase) endpoint.getParentEndpointChoice();
+        List<ParentEndpoint> parentEndpoints;
+        ReadOnlyTransaction readTransaction = dataProvider.newReadOnlyTransaction();
+
+        parentEndpoints = getParentEndpoints(parentEndpointCase);
+
+        for (ParentEndpoint parent : nullToEmpty(parentEndpoints)) {
+            Optional<AddressEndpoint> addressEndpointOptional =
+                    DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                            IidFactory.addressEndpointIid(new AddressEndpointKey(parent.getAddress(),
+                                    parent.getAddressType(), parent.getContextId(), parent.getContextType())),
+                            readTransaction);
+
+            if (addressEndpointOptional.isPresent()) {
+
+                List<ChildEndpoint> childEndpoints;
+
+                childEndpoints = (addressEndpointOptional.get() == null || addressEndpointOptional.get()
+                    .getChildEndpoint() == null) ? new ArrayList<>() : addressEndpointOptional.get().getChildEndpoint();
+
+                ChildEndpoint childEndpoint = new ChildEndpointBuilder(endpoint).build();
+                if (!childEndpoints.contains(childEndpoint)) {
+                    childEndpoints.add(childEndpoint);
+                    AddressEndpoint parentAddressEndpoint = new AddressEndpointBuilder(addressEndpointOptional.get())
+                        .setChildEndpoint(childEndpoints).build();
+                    t.put(LogicalDatastoreType.OPERATIONAL,
+                            IidFactory.addressEndpointIid(parentAddressEndpoint.getKey()), parentAddressEndpoint);
+                }
+            }
+        }
+    }
+
+    private void updateAddressEndpointRegChilds(WriteTransaction t, AddressEndpoint endpoint) {
+        ReadTransaction readTransaction = dataProvider.newReadOnlyTransaction();
+
+        for (ChildEndpoint child : nullToEmpty(endpoint.getChildEndpoint())) {
+            Optional<AddressEndpoint> addressEndpointOptional =
+                    DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                            IidFactory.addressEndpointIid(new AddressEndpointKey(child.getAddress(),
+                                    child.getAddressType(), child.getContextId(), child.getContextType())),
+                            readTransaction);
+
+            if (addressEndpointOptional.isPresent()) {
+                ParentEndpointCase parentEndpointCase =
+                        (ParentEndpointCase) addressEndpointOptional.get().getParentEndpointChoice();
+                List<ParentEndpoint> parentEndpoints;
+
+                parentEndpoints = getParentEndpoints(parentEndpointCase);
+
+                ParentEndpoint parentEndpoint = new ParentEndpointBuilder(endpoint).build();
+                if (!parentEndpoints.contains(parentEndpoint)) {
+                    parentEndpoints.add(parentEndpoint);
+                    AddressEndpoint childAddressEndpoint =
+                            new AddressEndpointBuilder(addressEndpointOptional.get())
+                                .setParentEndpointChoice(
+                                        new ParentEndpointCaseBuilder().setParentEndpoint(parentEndpoints).build())
+                                .build();
+                    t.put(LogicalDatastoreType.OPERATIONAL,
+                            IidFactory.addressEndpointIid(childAddressEndpoint.getKey()), childAddressEndpoint);
+                }
+            }
+        }
+    }
+
     private ContainmentEndpointBuilder buildContainmentEndpoint(ContainmentEndpointReg input) {
+
         ContainmentEndpointBuilder eb = new ContainmentEndpointBuilder().setChildEndpoint(input.getChildEndpoint())
             .setCondition(input.getCondition())
             .setContextType(input.getContextType())
@@ -165,7 +432,8 @@ public class BaseEndpointRpcRegistry
             .setKey(new ContainmentEndpointKey(input.getContextId(), input.getContextType()))
             .setNetworkContainment(input.getNetworkContainment())
             .setTenant(input.getTenant())
-            .setTimestamp(input.getTimestamp());
+            .setTimestamp(input.getTimestamp())
+            .setChildEndpoint(input.getChildEndpoint());
 
         for (Map.Entry<String, BaseEndpointRendererAugmentation> entry : registeredRenderers.entrySet()) {
             try {
@@ -225,18 +493,157 @@ public class BaseEndpointRpcRegistry
             AddressEndpointKey key = new AddressEndpointKey(ae.getAddress(), ae.getAddressType(), ae.getContextId(),
                     ae.getContextType());
             t.delete(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(key));
+
+            updateAddressEndpointUnregChilds(t, ae);
+
+            updateAddressEndpointUnregParents(t, ae);
         }
 
         List<ContainmentEndpointUnreg> endpoints = input.getContainmentEndpointUnreg();
         for (ContainmentEndpointUnreg ce : nullToEmpty(endpoints)) {
             ContainmentEndpointKey key = new ContainmentEndpointKey(ce.getContextId(), ce.getContextType());
             t.delete(LogicalDatastoreType.OPERATIONAL, IidFactory.containmentEndpointIid(key));
+
+            updateContainmentEndpointUnregChilds(t, ce);
         }
 
         ListenableFuture<Void> r = t.submit();
         return Futures.transform(r, futureTrans);
     }
 
+    private void updateAddressEndpointUnregParents(WriteTransaction t, AddressEndpointUnreg ae) {
+        ReadTransaction readTransaction = dataProvider.newReadOnlyTransaction();
+
+        Optional<AddressEndpoint> addressEndpointOptional = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                IidFactory.addressEndpointIid(new AddressEndpointKey(ae.getAddress(), ae.getAddressType(),
+                        ae.getContextId(), ae.getContextType())),
+                readTransaction);
+
+        if (addressEndpointOptional.isPresent()) {
+            ParentEndpointCase parentEndpointCase =
+                    (ParentEndpointCase) addressEndpointOptional.get().getParentEndpointChoice();
+            List<ParentEndpoint> parentEndpoints;
+
+            parentEndpoints = getParentEndpoints(parentEndpointCase);
+
+            for (ParentEndpoint parentEndpoint : parentEndpoints) {
+                Optional<AddressEndpoint> parentAddressEndpointOptional =
+                        DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                                IidFactory.addressEndpointIid(new AddressEndpointKey(parentEndpoint.getAddress(),
+                                        parentEndpoint.getAddressType(), parentEndpoint.getContextId(),
+                                        parentEndpoint.getContextType())),
+                                readTransaction);
+
+                AddressEndpoint parent =
+                        parentAddressEndpointOptional.isPresent() ? parentAddressEndpointOptional.get() : null;
+
+                ChildEndpoint endpointToRemove = new ChildEndpointBuilder(addressEndpointOptional.get()).build();
+
+                if (parent != null && nullToEmpty(parent.getChildEndpoint()).contains(endpointToRemove)) {
+                    parent.getChildEndpoint().remove(endpointToRemove);
+                    t.put(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(parent.getKey()), parent);
+                }
+
+            }
+        }
+    }
+
+    private void updateAddressEndpointUnregChilds(WriteTransaction t, AddressEndpointUnreg ae) {
+        ReadTransaction readTransaction = dataProvider.newReadOnlyTransaction();
+
+        Optional<AddressEndpoint> addressEndpointOptional = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                IidFactory.addressEndpointIid(new AddressEndpointKey(ae.getAddress(), ae.getAddressType(),
+                        ae.getContextId(), ae.getContextType())),
+                readTransaction);
+
+        if (addressEndpointOptional.isPresent()) {
+            AddressEndpoint endpoint = addressEndpointOptional.get();
+            List<ChildEndpoint> childEndpoints = endpoint.getChildEndpoint();
+
+            for (ChildEndpoint childEndpoint : nullToEmpty(childEndpoints)) {
+                Optional<AddressEndpoint> childAddressEndpointOptional =
+                        DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                                IidFactory.addressEndpointIid(new AddressEndpointKey(childEndpoint.getAddress(),
+                                        childEndpoint.getAddressType(), childEndpoint.getContextId(),
+                                        childEndpoint.getContextType())),
+                                readTransaction);
+
+                AddressEndpoint child =
+                        childAddressEndpointOptional.isPresent() ? childAddressEndpointOptional.get() : null;
+                ParentEndpointCase parentEndpointCase =
+                        (child != null) ? (ParentEndpointCase) child.getParentEndpointChoice() : null;
+                List<ParentEndpoint> parentEndpoints;
+
+                parentEndpoints = getParentEndpoints(parentEndpointCase);
+
+                ParentEndpoint endpointToRemove = new ParentEndpointBuilder(endpoint).build();
+
+                if (child != null && nullToEmpty(parentEndpoints).contains(endpointToRemove)) {
+                    parentEndpoints.remove(endpointToRemove);
+                    AddressEndpoint newChild =
+                            new AddressEndpointBuilder(child)
+                                .setParentEndpointChoice(
+                                        new ParentEndpointCaseBuilder().setParentEndpoint(parentEndpoints).build())
+                                .build();
+
+                    t.put(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(newChild.getKey()), newChild);
+                }
+            }
+        }
+    }
+
+    private void updateContainmentEndpointUnregChilds(WriteTransaction t,
+            ContainmentEndpointUnreg containmentEndpointUnreg) {
+        ReadOnlyTransaction readTransaction = dataProvider.newReadOnlyTransaction();
+
+        ContainmentEndpointKey key = new ContainmentEndpointKey(containmentEndpointUnreg.getContextId(),
+                containmentEndpointUnreg.getContextType());
+        Optional<ContainmentEndpoint> containmentEndpointOptional = DataStoreHelper
+            .readFromDs(LogicalDatastoreType.OPERATIONAL, IidFactory.containmentEndpointIid(key), readTransaction);
+
+        if (!containmentEndpointOptional.isPresent()) {
+            return;
+        }
+
+        for (ChildEndpoint child : nullToEmpty(containmentEndpointOptional.get().getChildEndpoint())) {
+            AddressEndpointKey aeKey = new AddressEndpointKey(child.getAddress(), child.getAddressType(),
+                    child.getContextId(), child.getContextType());
+            Optional<AddressEndpoint> addressEndpointOptional = DataStoreHelper
+                .readFromDs(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(aeKey), readTransaction);
+
+            if (addressEndpointOptional.isPresent()) {
+                ParentEndpointChoice parentEndpointChoice = addressEndpointOptional.get().getParentEndpointChoice();
+                List<ParentContainmentEndpoint> parentContainmentEndpoints;
+                parentContainmentEndpoints = getParentContainmentEndpoints(parentEndpointChoice);
+
+                ParentContainmentEndpoint parentContainmentEndpoint =
+                        new ParentContainmentEndpointBuilder().setContextId(containmentEndpointUnreg.getContextId())
+                            .setContextType(containmentEndpointUnreg.getContextType())
+                            .build();
+                if (nullToEmpty(parentContainmentEndpoints).contains(parentContainmentEndpoint)) {
+                    t.delete(LogicalDatastoreType.OPERATIONAL,
+                            IidFactory.parentContainmentEndpointIid(aeKey, parentContainmentEndpoint.getKey()));
+                }
+            }
+        }
+    }
+
+    private List<ParentContainmentEndpoint> getParentContainmentEndpoints(ParentEndpointChoice parentEndpointChoice) {
+        return (parentEndpointChoice instanceof ParentContainmentEndpointCase) ? ((ParentContainmentEndpointCase) parentEndpointChoice)
+            .getParentContainmentEndpoint() : new ArrayList<>();
+    }
+
+    private List<ParentEndpoint> getParentEndpoints(ParentEndpointCase parentEndpointCase) {
+        return (parentEndpointCase == null
+                || parentEndpointCase.getParentEndpoint() == null) ? new ArrayList<>() : parentEndpointCase
+                    .getParentEndpoint();
+    }
+
+    private ListenableFuture<RpcResult<Void>> buildFailFeature(String message) {
+        return Futures
+            .immediateFuture(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.PROTOCOL, message).build());
+    }
+
     @Override
     public void close() throws Exception {
         if (rpcRegistration != null) {
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/location/resolver/LocationResolver.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/location/resolver/LocationResolver.java
new file mode 100644 (file)
index 0000000..dfbf4d0
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.location.resolver;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.util.IidFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocationKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.ContainmentEndpointLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.ContainmentEndpointLocationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.ContainmentEndpointLocationKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.ExternalLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.InternalLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.LocationProviders;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.LocationProvider;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocationKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderContainmentEndpointLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderContainmentEndpointLocationKey;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LocationResolver implements DataTreeChangeListener<LocationProvider>, AutoCloseable {
+
+    private static final Logger LOG = LoggerFactory.getLogger(LocationResolver.class);
+    private Map<AddressEndpointLocationKey, Map<Long, AbsoluteLocation>> realLocations;
+    private DataBroker dataBroker;
+    private ListenerRegistration<LocationResolver> listenerRegistation;
+
+    public LocationResolver(DataBroker dataBroker) {
+        this.dataBroker = dataBroker;
+        this.realLocations = new HashMap<>();
+        this.listenerRegistation = dataBroker.registerDataTreeChangeListener(
+                new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+                        InstanceIdentifier.builder(LocationProviders.class).child(LocationProvider.class).build()),
+                this);
+    }
+
+    @Override
+    public synchronized void onDataTreeChanged(Collection<DataTreeModification<LocationProvider>> changes) {
+        for (DataTreeModification<LocationProvider> change : changes) {
+            WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
+            switch (change.getRootNode().getModificationType()) {
+                case DELETE: {
+                    processRemovedLocationProviderData(change.getRootNode().getDataBefore(), wtx);
+                    LOG.debug("Data from location provider {} has been removed",
+                            change.getRootNode().getDataBefore().getProvider().getValue());
+                    break;
+                }
+                case WRITE: {
+                    if (change.getRootNode().getDataBefore() != null) {
+                        processRemovedLocationProviderData(change.getRootNode().getDataBefore(), wtx);
+                    }
+                    processCreatedLocationProviderData(change.getRootNode().getDataAfter(), wtx);
+                    LOG.debug("Data from location provider {} has been created",
+                            change.getRootNode().getDataAfter().getProvider().getValue());
+                    break;
+                }
+                case SUBTREE_MODIFIED: {
+                    processRemovedLocationProviderData(change.getRootNode().getDataBefore(), wtx);
+                    processCreatedLocationProviderData(change.getRootNode().getDataAfter(), wtx);
+                    LOG.debug("Data from location provider {} has been changed",
+                            change.getRootNode().getDataAfter().getProvider().getValue());
+                    break;
+                }
+            }
+            wtx.submit();
+        }
+    }
+
+    private void processRemovedLocationProviderData(LocationProvider provider, WriteTransaction wtx) {
+        for (ProviderAddressEndpointLocation addressEndpointLocation : nullToEmpty(
+                provider.getProviderAddressEndpointLocation())) {
+            AddressEndpointLocationKey epKey = createAddressEndpointLocationKey(addressEndpointLocation.getKey());
+            long priority;
+            if (provider.getPriority() == null) {
+                priority = 0;
+                LOG.debug("{} provider doesn't provide priority. Using 0 as priority instead.",
+                        provider.getProvider().getValue());
+            } else {
+                priority = provider.getPriority();
+            }
+            realLocations.get(epKey).remove(priority);
+            AbsoluteLocation newAbsoluteLocation = getBestAbsoluteLocation(epKey);
+            if (newAbsoluteLocation == null) {
+                InstanceIdentifier<AbsoluteLocation> iid = IidFactory.absoluteLocationIid(epKey);
+                wtx.delete(LogicalDatastoreType.OPERATIONAL, iid);
+            } else {
+                AddressEndpointLocationBuilder newEP =
+                        new AddressEndpointLocationBuilder().setKey(epKey).setAbsoluteLocation(newAbsoluteLocation);
+                InstanceIdentifier<AddressEndpointLocation> iid = IidFactory.addressEndpointLocationIid(newEP.getKey());
+                wtx.merge(LogicalDatastoreType.OPERATIONAL, iid, newEP.build(), true);
+            }
+            if (addressEndpointLocation.getRelativeLocations() != null) {
+                for (InternalLocation location : nullToEmpty(
+                        addressEndpointLocation.getRelativeLocations().getInternalLocation())) {
+                    InstanceIdentifier<InternalLocation> iid = IidFactory.internalLocationIid(epKey, location.getKey());
+                    wtx.delete(LogicalDatastoreType.OPERATIONAL, iid);
+                }
+                for (ExternalLocation location : nullToEmpty(
+                        addressEndpointLocation.getRelativeLocations().getExternalLocation())) {
+                    InstanceIdentifier<ExternalLocation> iid = IidFactory.externalLocationIid(epKey, location.getKey());
+                    wtx.delete(LogicalDatastoreType.OPERATIONAL, iid);
+                }
+            }
+        }
+        for (ProviderContainmentEndpointLocation containmentEndpoint : nullToEmpty(
+                provider.getProviderContainmentEndpointLocation())) {
+            ContainmentEndpointLocationKey epKey = createContainmentEndpointLocationKey(containmentEndpoint.getKey());
+            if (containmentEndpoint.getRelativeLocations() != null) {
+                for (InternalLocation location : nullToEmpty(
+                        containmentEndpoint.getRelativeLocations().getInternalLocation())) {
+                    InstanceIdentifier<InternalLocation> iid = IidFactory.internalLocationIid(epKey, location.getKey());
+                    wtx.delete(LogicalDatastoreType.OPERATIONAL, iid);
+                }
+                for (ExternalLocation location : nullToEmpty(
+                        containmentEndpoint.getRelativeLocations().getExternalLocation())) {
+                    InstanceIdentifier<ExternalLocation> iid = IidFactory.externalLocationIid(epKey, location.getKey());
+                    wtx.delete(LogicalDatastoreType.OPERATIONAL, iid);
+                }
+            }
+        }
+    }
+
+    private void processCreatedLocationProviderData(LocationProvider provider, WriteTransaction wtx) {
+        for (ProviderAddressEndpointLocation addressEndpointLocation : nullToEmpty(
+                provider.getProviderAddressEndpointLocation())) {
+            AddressEndpointLocationKey epKey = createAddressEndpointLocationKey(addressEndpointLocation.getKey());
+            AddressEndpointLocationBuilder newEP = new AddressEndpointLocationBuilder().setKey(epKey);
+            if (addressEndpointLocation.getAbsoluteLocation() != null) {
+                if (realLocations.get(epKey) == null) {
+                    realLocations.put(epKey, new HashMap<>());
+                }
+                long priority;
+                if (provider.getPriority() == null) {
+                    priority = 0;
+                    LOG.debug("{} provider doesnt provide priority. Using 0 as priority instead.",
+                            provider.getProvider().getValue());
+                } else {
+                    priority = provider.getPriority();
+                }
+                realLocations.get(epKey).put(priority, addressEndpointLocation.getAbsoluteLocation());
+            }
+            AbsoluteLocation bestLocation = getBestAbsoluteLocation(epKey);
+            if (bestLocation != null) {
+                newEP.setAbsoluteLocation(bestLocation);
+            }
+            if (addressEndpointLocation.getRelativeLocations() != null) {
+                newEP.setRelativeLocations(addressEndpointLocation.getRelativeLocations());
+            }
+            InstanceIdentifier<AddressEndpointLocation> iid = IidFactory.addressEndpointLocationIid(newEP.getKey());
+            wtx.merge(LogicalDatastoreType.OPERATIONAL, iid, newEP.build(), true);
+        }
+        for (ProviderContainmentEndpointLocation containmentEndpointLocation : nullToEmpty(
+                provider.getProviderContainmentEndpointLocation())) {
+            if (containmentEndpointLocation.getRelativeLocations() != null) {
+                ContainmentEndpointLocationKey key =
+                        createContainmentEndpointLocationKey(containmentEndpointLocation.getKey());
+                ContainmentEndpointLocationBuilder newEP = new ContainmentEndpointLocationBuilder().setKey(key);
+                newEP.setRelativeLocations(containmentEndpointLocation.getRelativeLocations());
+                InstanceIdentifier<ContainmentEndpointLocation> iid =
+                        IidFactory.containmentEndpointLocationIid(newEP.getKey());
+                wtx.merge(LogicalDatastoreType.OPERATIONAL, iid, newEP.build(), true);
+            }
+        }
+    }
+
+    private AbsoluteLocation getBestAbsoluteLocation(AddressEndpointLocationKey epKey) {
+        if (realLocations.get(epKey) == null) {
+            return null;
+        }
+        long bestPriority = -1;
+        for (long priority : realLocations.get(epKey).keySet()) {
+            bestPriority = bestPriority > priority ? bestPriority : priority;
+        };
+        if (bestPriority == -1) {
+            return null;
+        }
+        return (realLocations.get(epKey).get(new Long(bestPriority)));
+    }
+
+    private AddressEndpointLocationKey createAddressEndpointLocationKey(ProviderAddressEndpointLocationKey key) {
+        return new AddressEndpointLocationKey(key.getAddress(), key.getAddressType(), key.getContextId(),
+                key.getContextType());
+    }
+
+    private ContainmentEndpointLocationKey createContainmentEndpointLocationKey(
+            ProviderContainmentEndpointLocationKey key) {
+        return new ContainmentEndpointLocationKey(key.getContextId(), key.getContextType());
+    }
+
+    private <T> List<T> nullToEmpty(@Nullable List<T> list) {
+        return list == null ? Collections.emptyList() : list;
+    }
+
+    @Override
+    public void close() throws Exception {
+        listenerRegistation.close();
+    }
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/AddressEndpointUtils.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/AddressEndpointUtils.java
new file mode 100644 (file)
index 0000000..1675bb8
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.renderer;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.endpoints.PeerEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.external.endpoints.PeerExternalEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
+
+public class AddressEndpointUtils {
+
+    public static RendererEndpointKey toRendererEpKey(AddressEndpointKey rendererAdrEpKey) {
+        return new RendererEndpointKey(rendererAdrEpKey.getAddress(), rendererAdrEpKey.getAddressType(),
+                rendererAdrEpKey.getContextId(), rendererAdrEpKey.getContextType());
+    }
+
+    public static PeerEndpointKey toPeerEpKey(AddressEndpointKey peerAdrEpKey) {
+        return new PeerEndpointKey(peerAdrEpKey.getAddress(), peerAdrEpKey.getAddressType(),
+                peerAdrEpKey.getContextId(), peerAdrEpKey.getContextType());
+    }
+
+    public static PeerExternalEndpointKey toPeerExtEpKey(AddressEndpointKey peerAdrEpKey) {
+        return new PeerExternalEndpointKey(peerAdrEpKey.getAddress(), peerAdrEpKey.getAddressType(),
+                peerAdrEpKey.getContextId(), peerAdrEpKey.getContextType());
+    }
+
+    public static AddressEndpointKey fromRendererEpKey(RendererEndpointKey rendererEpKey) {
+        return new AddressEndpointKey(rendererEpKey.getAddress(), rendererEpKey.getAddressType(),
+                rendererEpKey.getContextId(), rendererEpKey.getContextType());
+    }
+
+    public static AddressEndpointKey fromPeerEpKey(PeerEndpointKey peerEpKey) {
+        return new AddressEndpointKey(peerEpKey.getAddress(), peerEpKey.getAddressType(), peerEpKey.getContextId(),
+                peerEpKey.getContextType());
+    }
+
+    public static AddressEndpointKey fromPeerExtEpKey(PeerExternalEndpointKey peerExtEpKey) {
+        return new AddressEndpointKey(peerExtEpKey.getAddress(), peerExtEpKey.getAddressType(),
+                peerExtEpKey.getContextId(), peerExtEpKey.getContextType());
+    }
+
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ContainmentEndpointUtils.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ContainmentEndpointUtils.java
new file mode 100644 (file)
index 0000000..86a5d0c
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.renderer;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.external.containment.endpoints.PeerExternalContainmentEndpointKey;
+
+public class ContainmentEndpointUtils {
+
+    public static PeerExternalContainmentEndpointKey toPeerExtContEpKey(ContainmentEndpointKey peerContEpKey) {
+        return new PeerExternalContainmentEndpointKey(peerContEpKey.getContextId(), peerContEpKey.getContextType());
+    }
+
+    public static ContainmentEndpointKey fromPeerExtContEpKey(PeerExternalContainmentEndpointKey peerExtContEpKey) {
+        return new ContainmentEndpointKey(peerExtContEpKey.getContextId(), peerExtContEpKey.getContextType());
+    }
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/EndpointInfo.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/EndpointInfo.java
new file mode 100644 (file)
index 0000000..b8ef7c0
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.renderer;
+
+import java.util.Set;
+
+import org.opendaylight.groupbasedpolicy.dto.EpgKey;
+import org.opendaylight.groupbasedpolicy.dto.EpgKeyDto;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.Endpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSet.Builder;
+import com.google.common.collect.ImmutableSetMultimap;
+
+public class EndpointInfo {
+
+    private final ImmutableMap<AddressEndpointKey, AddressEndpoint> addressEpByKey;
+    private final ImmutableMap<ContainmentEndpointKey, ContainmentEndpoint> containmentEpByKey;
+    private final ImmutableSetMultimap<EpgKey, AddressEndpointKey> addressEpsByEpg;
+    private final ImmutableSetMultimap<EpgKey, ContainmentEndpointKey> containmentEpsByEpg;
+
+    public EndpointInfo(Endpoints endpoints) {
+        if (endpoints.getAddressEndpoints() == null || endpoints.getAddressEndpoints().getAddressEndpoint() == null) {
+            addressEpByKey = ImmutableMap.of();
+            addressEpsByEpg = ImmutableSetMultimap.of();
+        } else {
+            com.google.common.collect.ImmutableMap.Builder<AddressEndpointKey, AddressEndpoint> addressEpsByKeyBuilder =
+                    ImmutableMap.builder();
+            com.google.common.collect.ImmutableSetMultimap.Builder<EpgKey, AddressEndpointKey> addressEpsByEpgBuilder =
+                    ImmutableSetMultimap.builder();
+            com.google.common.collect.ImmutableMultimap.Builder<Set<EpgKey>, AddressEndpointKey> addressEpsByEpgsBuilder =
+                    ImmutableMultimap.builder();
+            for (AddressEndpoint ep : endpoints.getAddressEndpoints().getAddressEndpoint()) {
+                addressEpsByKeyBuilder.put(ep.getKey(), ep);
+                Builder<EpgKey> epgsBuilder = ImmutableSet.builder();
+                for (EndpointGroupId epgId : ep.getEndpointGroup()) {
+                    EpgKey epgKey = new EpgKeyDto(epgId, ep.getTenant());
+                    addressEpsByEpgBuilder.put(epgKey, ep.getKey());
+                    epgsBuilder.add(epgKey);
+                }
+                addressEpsByEpgsBuilder.put(epgsBuilder.build(), ep.getKey());
+            }
+            addressEpByKey = addressEpsByKeyBuilder.build();
+            addressEpsByEpg = addressEpsByEpgBuilder.build();
+        }
+        if (endpoints.getContainmentEndpoints() == null
+                || endpoints.getContainmentEndpoints().getContainmentEndpoint() == null) {
+            containmentEpByKey = ImmutableMap.of();
+            containmentEpsByEpg = ImmutableSetMultimap.of();
+        } else {
+            com.google.common.collect.ImmutableSetMultimap.Builder<EpgKey, ContainmentEndpointKey> containmentEpsByEpgBuilder =
+                    ImmutableSetMultimap.builder();
+            com.google.common.collect.ImmutableMap.Builder<ContainmentEndpointKey, ContainmentEndpoint> containmentEpsByKeyBuilder =
+                    ImmutableMap.builder();
+            com.google.common.collect.ImmutableMultimap.Builder<Set<EpgKey>, ContainmentEndpointKey> containmentEpsByEpgsBuilder =
+                    ImmutableMultimap.builder();
+            for (ContainmentEndpoint ep : endpoints.getContainmentEndpoints().getContainmentEndpoint()) {
+                containmentEpsByKeyBuilder.put(ep.getKey(), ep);
+                Builder<EpgKey> epgsBuilder = ImmutableSet.builder();
+                for (EndpointGroupId epgId : ep.getEndpointGroup()) {
+                    EpgKey epgKey = new EpgKeyDto(epgId, ep.getTenant());
+                    containmentEpsByEpgBuilder.put(epgKey, ep.getKey());
+                    epgsBuilder.add(epgKey);
+                }
+                containmentEpsByEpgsBuilder.put(epgsBuilder.build(), ep.getKey());
+            }
+            containmentEpByKey = containmentEpsByKeyBuilder.build();
+            containmentEpsByEpg = containmentEpsByEpgBuilder.build();
+        }
+    }
+
+    public Optional<AddressEndpoint> getEndpoint(AddressEndpointKey key) {
+        return Optional.fromNullable(addressEpByKey.get(key));
+    }
+
+    public Optional<ContainmentEndpoint> getContainmentEndpoint(ContainmentEndpointKey key) {
+        return Optional.fromNullable(containmentEpByKey.get(key));
+    }
+
+    public ImmutableSet<AddressEndpointKey> findAddressEpsWithEpg(EpgKey epg) {
+        return addressEpsByEpg.get(epg);
+    }
+
+    public ImmutableSet<ContainmentEndpointKey> findContainmentEpsWithEpg(EpgKey epg) {
+        return containmentEpsByEpg.get(epg);
+    }
+
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/EndpointLocationInfo.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/EndpointLocationInfo.java
new file mode 100644 (file)
index 0000000..a961e1e
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.renderer;
+
+import java.util.List;
+import java.util.Set;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.EndpointLocations;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocationKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.ContainmentEndpointLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.ContainmentEndpointLocationKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.LocationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.RelativeLocations;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.InternalLocation;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+
+public class EndpointLocationInfo {
+
+    private final ImmutableMultimap<InstanceIdentifier<?>, AddressEndpointLocation> endpointsByAbsNodeLocation;
+    private final ImmutableMap<AddressEndpointKey, AddressEndpointLocation> adrEpLocByAdrEpKey;
+    private final ImmutableMap<ContainmentEndpointKey, ContainmentEndpointLocation> contEpLocBycontEpKey;
+
+    public EndpointLocationInfo(EndpointLocations epLocations) {
+        List<AddressEndpointLocation> addressEndpointLocations = epLocations.getAddressEndpointLocation();
+        endpointsByAbsNodeLocation = EndpointLocationUtils.resolveEndpointsByAbsoluteNodeLocation(addressEndpointLocations);
+        if (addressEndpointLocations == null) {
+            adrEpLocByAdrEpKey = ImmutableMap.of();
+        } else {
+            com.google.common.collect.ImmutableMap.Builder<AddressEndpointKey, AddressEndpointLocation> adrEpLocByAdrEpKeyBuilder =
+                    ImmutableMap.builder();
+            for (AddressEndpointLocation adrEpLoc : addressEndpointLocations) {
+                adrEpLocByAdrEpKeyBuilder.put(toAdrEpKey(adrEpLoc.getKey()), adrEpLoc);
+            }
+            adrEpLocByAdrEpKey = adrEpLocByAdrEpKeyBuilder.build();
+        }
+        List<ContainmentEndpointLocation> containmentEndpointLocations = epLocations.getContainmentEndpointLocation();
+        if (containmentEndpointLocations == null) {
+            contEpLocBycontEpKey = ImmutableMap.of();
+        } else {
+            com.google.common.collect.ImmutableMap.Builder<ContainmentEndpointKey, ContainmentEndpointLocation> contEpLocBycontEpKeyBuilder =
+                    ImmutableMap.builder();
+            for (ContainmentEndpointLocation contEpLoc : containmentEndpointLocations) {
+                contEpLocBycontEpKeyBuilder.put(toContEpKey(contEpLoc.getKey()), contEpLoc);
+            }
+            contEpLocBycontEpKey = contEpLocBycontEpKeyBuilder.build();
+        }
+    }
+
+    public Optional<AddressEndpointLocation> getAdressEndpointLocation(AddressEndpointKey epKey) {
+        return Optional.fromNullable(adrEpLocByAdrEpKey.get(epKey));
+    }
+
+    public Optional<ContainmentEndpointLocation> getContainmentEndpointLocation(ContainmentEndpointKey contEpKey) {
+        return Optional.fromNullable(contEpLocBycontEpKey.get(contEpKey));
+    }
+
+    private AddressEndpointKey toAdrEpKey(AddressEndpointLocationKey adrEpLocKey) {
+        return new AddressEndpointKey(adrEpLocKey.getAddress(), adrEpLocKey.getAddressType(),
+                adrEpLocKey.getContextId(), adrEpLocKey.getContextType());
+    }
+
+    private ContainmentEndpointKey toContEpKey(ContainmentEndpointLocationKey contEpLocKey) {
+        return new ContainmentEndpointKey(contEpLocKey.getContextId(), contEpLocKey.getContextType());
+    }
+
+    public Set<InstanceIdentifier<?>> getAllAbsoluteNodeLocations() {
+        return endpointsByAbsNodeLocation.keySet();
+    }
+
+    public ImmutableSet<AddressEndpointKey> getAddressEpsWithAbsoluteNodeLocation(InstanceIdentifier<?> realNodeLocation) {
+        return FluentIterable.from(endpointsByAbsNodeLocation.get(realNodeLocation))
+                .transform(new Function<AddressEndpointLocation, AddressEndpointKey>() {
+
+                    @Override
+                    public AddressEndpointKey apply(AddressEndpointLocation epLoc) {
+                        return new AddressEndpointKey(epLoc.getAddress(),
+                                epLoc.getAddressType(), epLoc.getContextId(), epLoc.getContextType());
+                    }
+                })
+                .toSet();
+    }
+
+    public boolean hasRealLocation(AddressEndpointKey adrEpKey) {
+        AddressEndpointLocation adrEpLoc = adrEpLocByAdrEpKey.get(adrEpKey);
+        if (adrEpLoc == null) {
+            return false;
+        }
+        AbsoluteLocation absLocation = adrEpLoc.getAbsoluteLocation();
+        if (absLocation == null) {
+            return false;
+        }
+        LocationType locationType = absLocation.getLocationType();
+        if (locationType == null) {
+            return false;
+        }
+        return true;
+    }
+
+    public boolean hasRelativeLocation(AddressEndpointKey adrEpKey) {
+        AddressEndpointLocation adrEpLoc = adrEpLocByAdrEpKey.get(adrEpKey);
+        if (adrEpLoc == null) {
+            return false;
+        }
+        RelativeLocations relLocations = adrEpLoc.getRelativeLocations();
+        if (relLocations == null) {
+            return false;
+        }
+        List<InternalLocation> locs = relLocations.getInternalLocation();
+        if (locs == null) {
+            return false;
+        }
+        return true;
+    }
+
+    public boolean hasRelativeLocation(ContainmentEndpointKey contEpKey) {
+        ContainmentEndpointLocation contEpLoc = contEpLocBycontEpKey.get(contEpKey);
+        if (contEpLoc == null) {
+            return false;
+        }
+        RelativeLocations relLocations = contEpLoc.getRelativeLocations();
+        if (relLocations == null) {
+            return false;
+        }
+        List<InternalLocation> locs = relLocations.getInternalLocation();
+        if (locs == null) {
+            return false;
+        }
+        return true;
+    }
+
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/EndpointLocationUtils.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/EndpointLocationUtils.java
new file mode 100644 (file)
index 0000000..6e7f81f
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.renderer;
+
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.LocationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.InternalLocationCase;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableMultimap.Builder;
+
+public class EndpointLocationUtils {
+
+    public static ImmutableMultimap<InstanceIdentifier<?>, AddressEndpointLocation> resolveEndpointsByAbsoluteNodeLocation(
+            @Nullable List<AddressEndpointLocation> addressEndpointLocations) {
+        if (addressEndpointLocations == null) {
+            return ImmutableMultimap.of();
+        }
+        Builder<InstanceIdentifier<?>, AddressEndpointLocation> resultBuilder = ImmutableMultimap.builder();
+        for (AddressEndpointLocation epLoc : addressEndpointLocations) {
+            Optional<InstanceIdentifier<?>> potentialAbsIntNodeLocation = resolveAbsoluteInternalNodeLocation(epLoc);
+            if (potentialAbsIntNodeLocation.isPresent()) {
+                resultBuilder.put(potentialAbsIntNodeLocation.get(), epLoc);
+            } else {
+                Optional<InstanceIdentifier<?>> potentialAbsExtNodeMpLocation =
+                        resolveAbsoluteExternalNodeMountPointLocation(epLoc);
+                if (potentialAbsExtNodeMpLocation.isPresent()) {
+                    resultBuilder.put(potentialAbsExtNodeMpLocation.get(), epLoc);
+                }
+            }
+        }
+        return resultBuilder.build();
+    }
+
+    public static Optional<InstanceIdentifier<?>> resolveAbsoluteInternalNodeLocation(AddressEndpointLocation epLoc) {
+        AbsoluteLocation absLoc = epLoc.getAbsoluteLocation();
+        if (absLoc != null) {
+            LocationType locType = absLoc.getLocationType();
+            if (locType instanceof InternalLocationCase) {
+                InternalLocationCase absRegularLoc = (InternalLocationCase) locType;
+                if (absRegularLoc.getInternalNode() != null) {
+                    return Optional.of(absRegularLoc.getInternalNode());
+                }
+            }
+        }
+        return Optional.absent();
+    }
+
+    public static Optional<InstanceIdentifier<?>> resolveAbsoluteExternalNodeMountPointLocation(
+            AddressEndpointLocation epLoc) {
+        AbsoluteLocation absLoc = epLoc.getAbsoluteLocation();
+        if (absLoc != null) {
+            LocationType locType = absLoc.getLocationType();
+            if (locType instanceof ExternalLocationCase) {
+                ExternalLocationCase realExtLoc = (ExternalLocationCase) locType;
+                if (realExtLoc.getExternalNodeMountPoint() != null) {
+                    return Optional.of(realExtLoc.getExternalNodeMountPoint());
+                }
+            }
+        }
+        return Optional.absent();
+    }
+
+    public static Optional<InstanceIdentifier<?>> resolveAbsoluteNodeLocation(AddressEndpointLocation epLoc) {
+        if (epLoc.getAbsoluteLocation() == null) {
+            return Optional.absent();
+        }
+        LocationType locType = epLoc.getAbsoluteLocation().getLocationType();
+        if (locType instanceof InternalLocationCase) {
+            InternalLocationCase absLoc = (InternalLocationCase) locType;
+            if (absLoc.getInternalNode() != null) {
+                return Optional.of(absLoc.getInternalNode());
+            }
+        } else if (locType instanceof ExternalLocationCase) {
+            ExternalLocationCase absLoc = (ExternalLocationCase) locType;
+            if (absLoc.getExternalNodeMountPoint() != null) {
+                return Optional.of(absLoc.getExternalNodeMountPoint());
+            }
+        }
+        return Optional.absent();
+    }
+
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/RendererConfigurationBuilder.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/RendererConfigurationBuilder.java
new file mode 100644 (file)
index 0000000..c3bbf7f
--- /dev/null
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.renderer;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.annotation.Nonnull;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.ContainmentEndpointLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.Forwarding;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.ForwardingByTenant;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.endpoints.PeerEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.external.containment.endpoints.PeerExternalContainmentEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.external.endpoints.PeerExternalEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.Endpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.EndpointsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.ForwardingContexts;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.ForwardingContextsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RendererEndpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RendererEndpointsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RuleGroups;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RuleGroupsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.ContainmentEndpointWithLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.ContainmentEndpointWithLocationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.forwarding.contexts.ForwardingContextByTenant;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.forwarding.contexts.ForwardingContextByTenantBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicyKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalContainmentEndpointWithPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalContainmentEndpointWithPolicyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalContainmentEndpointWithPolicyKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalEndpointWithPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalEndpointWithPolicyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalEndpointWithPolicyKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.policy.rule.group.with.endpoint.constraints.PolicyRuleGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.policy.rule.group.with.endpoint.constraints.PolicyRuleGroupKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.HashBasedTable;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableTable;
+import com.google.common.collect.Table;
+
+public class RendererConfigurationBuilder {
+
+    private final Table<RendererEndpointKey, PeerEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByEpAndPeerEp =
+            HashBasedTable.create();
+    private final Table<RendererEndpointKey, PeerExternalEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByEpAndPeerExtEp =
+            HashBasedTable.create();
+    private final Table<RendererEndpointKey, PeerExternalContainmentEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByEpAndPeerExtCtxEp =
+            HashBasedTable.create();
+    private final Set<AddressEndpointKey> adrEpKeys = new HashSet<>();
+    private final Set<ContainmentEndpointKey> contEpKeys = new HashSet<>();
+    private final Set<PolicyRuleGroupKey> policyRuleGrpKeys = new HashSet<>();
+
+    public void add(RendererEndpointKey rendererEpKey, PeerEndpointKey peerEpKey, PolicyRuleGroupKey ruleGrpKey,
+            EndpointPolicyParticipation rendererEpParticipation) {
+        Set<RuleGroupWithRendererEndpointParticipation> ruleGrpWithRendererEpParticipation =
+                policiesByEpAndPeerEp.get(rendererEpKey, peerEpKey);
+        if (ruleGrpWithRendererEpParticipation == null) {
+            ruleGrpWithRendererEpParticipation = new HashSet<>();
+            policiesByEpAndPeerEp.put(rendererEpKey, peerEpKey, ruleGrpWithRendererEpParticipation);
+            adrEpKeys.add(AddressEndpointUtils.fromRendererEpKey(rendererEpKey));
+            adrEpKeys.add(AddressEndpointUtils.fromPeerEpKey(peerEpKey));
+        }
+        policyRuleGrpKeys.add(ruleGrpKey);
+        ruleGrpWithRendererEpParticipation
+            .add(toRuleGroupWithRendererEndpointParticipation(ruleGrpKey, rendererEpParticipation));
+    }
+
+    public void add(RendererEndpointKey rendererEpKey, PeerExternalEndpointKey peerExtEpKey,
+            PolicyRuleGroupKey ruleGrpKey, EndpointPolicyParticipation rendererEpParticipation) {
+        Set<RuleGroupWithRendererEndpointParticipation> ruleGrpWithRendererEpParticipation =
+                policiesByEpAndPeerExtEp.get(rendererEpKey, peerExtEpKey);
+        if (ruleGrpWithRendererEpParticipation == null) {
+            ruleGrpWithRendererEpParticipation = new HashSet<>();
+            policiesByEpAndPeerExtEp.put(rendererEpKey, peerExtEpKey, ruleGrpWithRendererEpParticipation);
+            adrEpKeys.add(AddressEndpointUtils.fromRendererEpKey(rendererEpKey));
+            adrEpKeys.add(AddressEndpointUtils.fromPeerExtEpKey(peerExtEpKey));
+        }
+        policyRuleGrpKeys.add(ruleGrpKey);
+        ruleGrpWithRendererEpParticipation
+            .add(toRuleGroupWithRendererEndpointParticipation(ruleGrpKey, rendererEpParticipation));
+    }
+
+    public void add(RendererEndpointKey rendererEpKey, PeerExternalContainmentEndpointKey peerExtContainmentEpKey,
+            PolicyRuleGroupKey ruleGrpKey, EndpointPolicyParticipation rendererEpParticipation) {
+        Set<RuleGroupWithRendererEndpointParticipation> ruleGrpWithRendererEpParticipation =
+                policiesByEpAndPeerExtCtxEp.get(rendererEpKey, peerExtContainmentEpKey);
+        if (ruleGrpWithRendererEpParticipation == null) {
+            ruleGrpWithRendererEpParticipation = new HashSet<>();
+            policiesByEpAndPeerExtCtxEp.put(rendererEpKey, peerExtContainmentEpKey, ruleGrpWithRendererEpParticipation);
+            adrEpKeys.add(AddressEndpointUtils.fromRendererEpKey(rendererEpKey));
+            contEpKeys.add(ContainmentEndpointUtils.fromPeerExtContEpKey(peerExtContainmentEpKey));
+        }
+        policyRuleGrpKeys.add(ruleGrpKey);
+        ruleGrpWithRendererEpParticipation
+            .add(toRuleGroupWithRendererEndpointParticipation(ruleGrpKey, rendererEpParticipation));
+    }
+
+    public static RuleGroupWithRendererEndpointParticipation toRuleGroupWithRendererEndpointParticipation(
+            PolicyRuleGroupKey ruleGrpKey, EndpointPolicyParticipation rendererEpParticipation) {
+        return new RuleGroupWithRendererEndpointParticipationBuilder().setTenantId(ruleGrpKey.getTenantId())
+            .setContractId(ruleGrpKey.getContractId())
+            .setSubjectName(ruleGrpKey.getSubjectName())
+            .setRendererEndpointParticipation(rendererEpParticipation)
+            .build();
+    }
+
+    public ImmutableTable<RendererEndpointKey, PeerEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> getPoliciesByEpAndPeerEp() {
+        return ImmutableTable.copyOf(policiesByEpAndPeerEp);
+    }
+
+    public ImmutableTable<RendererEndpointKey, PeerExternalEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> getPoliciesByEpAndPeerExtEp() {
+        return ImmutableTable.copyOf(policiesByEpAndPeerExtEp);
+    }
+
+    public ImmutableTable<RendererEndpointKey, PeerExternalContainmentEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> getPoliciesByEpAndPeerExtConEp() {
+        return ImmutableTable.copyOf(policiesByEpAndPeerExtCtxEp);
+    }
+
+    public ImmutableSet<AddressEndpointKey> getAddressEndpointKeys() {
+        return ImmutableSet.copyOf(adrEpKeys);
+    }
+
+    public ImmutableSet<ContainmentEndpointKey> getContainmentEndpointKeys() {
+        return ImmutableSet.copyOf(contEpKeys);
+    }
+
+    public ImmutableSet<PolicyRuleGroupKey> getPolicyRuleGroupKeys() {
+        return ImmutableSet.copyOf(policyRuleGrpKeys);
+    }
+
+    public @Nonnull RendererEndpoints buildRendererEndpoints() {
+        Map<RendererEndpointKey, RendererEndpointBuilder> rendererEpBuilderByKey = new HashMap<>();
+        for (RendererEndpointKey rendererEpKey : policiesByEpAndPeerEp.rowKeySet()) {
+            RendererEndpointBuilder rendererEpBuilder =
+                    resolveRendererEndpointBuilder(rendererEpKey, rendererEpBuilderByKey);
+            List<PeerEndpointWithPolicy> peerEpsWithPolicy =
+                    toListPeerEndpointWithPolicy(policiesByEpAndPeerEp.row(rendererEpKey));
+            rendererEpBuilder.setPeerEndpointWithPolicy(peerEpsWithPolicy);
+            rendererEpBuilderByKey.put(rendererEpKey, rendererEpBuilder);
+        }
+        for (RendererEndpointKey rendererEpKey : policiesByEpAndPeerExtEp.rowKeySet()) {
+            RendererEndpointBuilder rendererEpBuilder =
+                    resolveRendererEndpointBuilder(rendererEpKey, rendererEpBuilderByKey);
+            List<PeerExternalEndpointWithPolicy> peerExtEpsWithPolicy =
+                    toListPeerExternalEndpointWithPolicy(policiesByEpAndPeerExtEp.row(rendererEpKey));
+            rendererEpBuilder.setPeerExternalEndpointWithPolicy(peerExtEpsWithPolicy);
+            rendererEpBuilderByKey.put(rendererEpKey, rendererEpBuilder);
+        }
+        for (RendererEndpointKey rendererEpKey : policiesByEpAndPeerExtCtxEp.rowKeySet()) {
+            RendererEndpointBuilder rendererEpBuilder =
+                    resolveRendererEndpointBuilder(rendererEpKey, rendererEpBuilderByKey);
+            List<PeerExternalContainmentEndpointWithPolicy> peerExtContEpsWithPolicy =
+                    toListPeerExternalContainmentEndpointWithPolicy(policiesByEpAndPeerExtCtxEp.row(rendererEpKey));
+            rendererEpBuilder.setPeerExternalContainmentEndpointWithPolicy(peerExtContEpsWithPolicy);
+            rendererEpBuilderByKey.put(rendererEpKey, rendererEpBuilder);
+        }
+        List<RendererEndpoint> rendererEps = new ArrayList<>();
+        for (RendererEndpointBuilder builder : rendererEpBuilderByKey.values()) {
+            rendererEps.add(builder.build());
+        }
+        return new RendererEndpointsBuilder().setRendererEndpoint(rendererEps).build();
+    }
+
+    private static RendererEndpointBuilder resolveRendererEndpointBuilder(RendererEndpointKey rendererEpKey,
+            Map<RendererEndpointKey, RendererEndpointBuilder> rendererEpBuilderByKey) {
+        RendererEndpointBuilder rendererEpBuilder = rendererEpBuilderByKey.get(rendererEpKey);
+        if (rendererEpBuilder == null) {
+            rendererEpBuilder = new RendererEndpointBuilder();
+            rendererEpBuilder.setKey(rendererEpKey);
+        }
+        return rendererEpBuilder;
+    }
+
+    private static List<PeerEndpointWithPolicy> toListPeerEndpointWithPolicy(
+            Map<PeerEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByPeerEp) {
+        List<PeerEndpointWithPolicy> peerEpsWithPolicy = new ArrayList<>();
+        for (Entry<PeerEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> entry : policiesByPeerEp
+            .entrySet()) {
+            PeerEndpointKey peerEpKey = entry.getKey();
+            PeerEndpointWithPolicyKey peerEndpointWithPolicyKey = new PeerEndpointWithPolicyKey(peerEpKey.getAddress(),
+                    peerEpKey.getAddressType(), peerEpKey.getContextId(), peerEpKey.getContextType());
+            PeerEndpointWithPolicy peerEndpointWithPolicy =
+                    new PeerEndpointWithPolicyBuilder().setKey(peerEndpointWithPolicyKey)
+                        .setRuleGroupWithRendererEndpointParticipation(new ArrayList<>(entry.getValue()))
+                        .build();
+            peerEpsWithPolicy.add(peerEndpointWithPolicy);
+        }
+        return peerEpsWithPolicy;
+    }
+
+    private static List<PeerExternalEndpointWithPolicy> toListPeerExternalEndpointWithPolicy(
+            Map<PeerExternalEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByPeerExtEp) {
+        List<PeerExternalEndpointWithPolicy> peerExtEpsWithPolicy = new ArrayList<>();
+        for (Entry<PeerExternalEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> entry : policiesByPeerExtEp
+            .entrySet()) {
+            PeerExternalEndpointKey peerEpKey = entry.getKey();
+            PeerExternalEndpointWithPolicyKey peerExternalEpWithPolicyKey =
+                    new PeerExternalEndpointWithPolicyKey(peerEpKey.getAddress(), peerEpKey.getAddressType(),
+                            peerEpKey.getContextId(), peerEpKey.getContextType());
+            PeerExternalEndpointWithPolicy peerExternalEpWithPolicy =
+                    new PeerExternalEndpointWithPolicyBuilder().setKey(peerExternalEpWithPolicyKey)
+                        .setRuleGroupWithRendererEndpointParticipation(new ArrayList<>(entry.getValue()))
+                        .build();
+            peerExtEpsWithPolicy.add(peerExternalEpWithPolicy);
+        }
+        return peerExtEpsWithPolicy;
+    }
+
+    private static List<PeerExternalContainmentEndpointWithPolicy> toListPeerExternalContainmentEndpointWithPolicy(
+            Map<PeerExternalContainmentEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByPeerExtContEp) {
+        List<PeerExternalContainmentEndpointWithPolicy> peerExtContEpsWithPolicy = new ArrayList<>();
+        for (Entry<PeerExternalContainmentEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> entry : policiesByPeerExtContEp
+            .entrySet()) {
+            PeerExternalContainmentEndpointKey peerEpKey = entry.getKey();
+            PeerExternalContainmentEndpointWithPolicyKey peerExternalContEpWithPolicyKey =
+                    new PeerExternalContainmentEndpointWithPolicyKey(peerEpKey.getContextId(),
+                            peerEpKey.getContextType());
+            PeerExternalContainmentEndpointWithPolicy peerExternalContEpWithPolicy =
+                    new PeerExternalContainmentEndpointWithPolicyBuilder().setKey(peerExternalContEpWithPolicyKey)
+                        .setRuleGroupWithRendererEndpointParticipation(new ArrayList<>(entry.getValue()))
+                        .build();
+            peerExtContEpsWithPolicy.add(peerExternalContEpWithPolicy);
+        }
+        return peerExtContEpsWithPolicy;
+    }
+
+    public Endpoints buildEndoints(EndpointInfo epInfo, EndpointLocationInfo epLocInfo,
+            Map<InstanceIdentifier<?>, RendererName> rendererByNode) {
+        List<AddressEndpointWithLocation> epsWithLoc =
+                resolveEpsWithLoc(getAddressEndpointKeys(), epInfo, epLocInfo, rendererByNode);
+        List<ContainmentEndpointWithLocation> contEpsWithLoc =
+                resolveContEpsWithLoc(getContainmentEndpointKeys(), epInfo, epLocInfo);
+        return new EndpointsBuilder().setAddressEndpointWithLocation(epsWithLoc)
+            .setContainmentEndpointWithLocation(contEpsWithLoc)
+            .build();
+    }
+
+    private static List<AddressEndpointWithLocation> resolveEpsWithLoc(Set<AddressEndpointKey> epKeys,
+            EndpointInfo epInfo, EndpointLocationInfo epLocInfo,
+            Map<InstanceIdentifier<?>, RendererName> rendererByNode) {
+        List<AddressEndpointWithLocation> result = new ArrayList<>();
+        for (AddressEndpointKey epKey : epKeys) {
+            Optional<AddressEndpoint> potentialEp = epInfo.getEndpoint(epKey);
+            Preconditions.checkArgument(potentialEp.isPresent());
+            Optional<AddressEndpointLocation> potentionalEpLoc = epLocInfo.getAdressEndpointLocation(epKey);
+            Preconditions.checkArgument(potentionalEpLoc.isPresent());
+            RendererName rendererName = resolveRendererName(potentionalEpLoc.get(), rendererByNode);
+            result.add(createEpWithLoc(potentialEp.get(), potentionalEpLoc.get(), rendererName));
+        }
+        return result;
+    }
+
+    private static RendererName resolveRendererName(AddressEndpointLocation epLoc,
+            Map<InstanceIdentifier<?>, RendererName> rendererByNode) {
+        Optional<InstanceIdentifier<?>> potentialAbsNodeLoc = EndpointLocationUtils.resolveAbsoluteNodeLocation(epLoc);
+        if (potentialAbsNodeLoc.isPresent()) {
+            return rendererByNode.get(potentialAbsNodeLoc.get());
+        }
+        return null;
+    }
+
+    private static AddressEndpointWithLocation createEpWithLoc(AddressEndpoint ep, AddressEndpointLocation epLoc,
+            RendererName rendererName) {
+        return new AddressEndpointWithLocationBuilder().setAddress(ep.getAddress())
+            .setAddressType(ep.getAddressType())
+            .setContextId(ep.getContextId())
+            .setContextType(ep.getContextType())
+            .setTenant(ep.getTenant())
+            .setChildEndpoint(ep.getChildEndpoint())
+            .setParentEndpointChoice(ep.getParentEndpointChoice())
+            .setEndpointGroup(ep.getEndpointGroup())
+            .setCondition(ep.getCondition())
+            .setNetworkContainment(ep.getNetworkContainment())
+            .setTimestamp(ep.getTimestamp())
+            .setAbsoluteLocation(epLoc.getAbsoluteLocation())
+            .setRelativeLocations(epLoc.getRelativeLocations())
+            .setRendererName(rendererName)
+            .build();
+    }
+
+    private static List<ContainmentEndpointWithLocation> resolveContEpsWithLoc(Set<ContainmentEndpointKey> contEpKeys,
+            EndpointInfo epInfo, EndpointLocationInfo epLocInfo) {
+        List<ContainmentEndpointWithLocation> result = new ArrayList<>();
+        for (ContainmentEndpointKey contEpKey : contEpKeys) {
+            Optional<ContainmentEndpoint> potentialContEp = epInfo.getContainmentEndpoint(contEpKey);
+            Preconditions.checkArgument(potentialContEp.isPresent());
+            Optional<ContainmentEndpointLocation> potentialContEpLoc =
+                    epLocInfo.getContainmentEndpointLocation(contEpKey);
+            Preconditions.checkArgument(potentialContEpLoc.isPresent());
+            result.add(createContEpWithLoc(potentialContEp.get(), potentialContEpLoc.get()));
+        }
+        return result;
+    }
+
+    private static ContainmentEndpointWithLocation createContEpWithLoc(ContainmentEndpoint contEp,
+            ContainmentEndpointLocation contEpLoc) {
+        return new ContainmentEndpointWithLocationBuilder().setContextId(contEp.getContextId())
+            .setContextType(contEp.getContextType())
+            .setTenant(contEp.getTenant())
+            .setChildEndpoint(contEp.getChildEndpoint())
+            .setEndpointGroup(contEp.getEndpointGroup())
+            .setCondition(contEp.getCondition())
+            .setNetworkContainment(contEp.getNetworkContainment())
+            .setTimestamp(contEp.getTimestamp())
+            .setRelativeLocations(contEpLoc.getRelativeLocations())
+            .build();
+    }
+
+    public RuleGroups buildRuluGroups(ResolvedPolicyInfo policyInfo) {
+        List<RuleGroup> ruleGroups = resolveRuleGroups(getPolicyRuleGroupKeys(), policyInfo);
+        return new RuleGroupsBuilder().setRuleGroup(ruleGroups).build();
+    }
+
+    private List<RuleGroup> resolveRuleGroups(Set<PolicyRuleGroupKey> policyRuleGrpKeys,
+            ResolvedPolicyInfo policyInfo) {
+        List<RuleGroup> result = new ArrayList<>();
+        for (PolicyRuleGroupKey policyRuleGrpKey : policyRuleGrpKeys) {
+            Optional<PolicyRuleGroup> potentialPolicyRuleGrp = policyInfo.getPolicyRuleGroup(policyRuleGrpKey);
+            Preconditions.checkArgument(potentialPolicyRuleGrp.isPresent());
+            result.add(createRuleGroup(potentialPolicyRuleGrp.get()));
+        }
+        return result;
+    }
+
+    private RuleGroup createRuleGroup(PolicyRuleGroup policyRuleGrp) {
+        return new RuleGroupBuilder().setTenantId(policyRuleGrp.getTenantId())
+            .setContractId(policyRuleGrp.getContractId())
+            .setSubjectName(policyRuleGrp.getSubjectName())
+            .setResolvedRule(policyRuleGrp.getResolvedRule())
+            .setOrder(policyRuleGrp.getOrder())
+            .build();
+    }
+
+    // TODO this copies entire Forwarding to ForwardingContexts - it could copy only forwarding used
+    // in EPs (renderer EPs + peers)
+    public ForwardingContexts buildForwardingContexts(Forwarding forwarding) {
+        List<ForwardingContextByTenant> forwardingContextByTenant =
+                resolveForwardingContextByTenant(forwarding.getForwardingByTenant());
+        return new ForwardingContextsBuilder().setForwardingContextByTenant(forwardingContextByTenant).build();
+    }
+
+    private static List<ForwardingContextByTenant> resolveForwardingContextByTenant(
+            List<ForwardingByTenant> forwardingByTenant) {
+        List<ForwardingContextByTenant> result = new ArrayList<>();
+        for (ForwardingByTenant fwdByTenant : forwardingByTenant) {
+            result.add(new ForwardingContextByTenantBuilder(fwdByTenant).build());
+        }
+        return result;
+    }
+
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/RendererManager.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/RendererManager.java
new file mode 100644 (file)
index 0000000..becf45e
--- /dev/null
@@ -0,0 +1,427 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.renderer;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.dto.ConsEpgKey;
+import org.opendaylight.groupbasedpolicy.dto.EpgKeyDto;
+import org.opendaylight.groupbasedpolicy.dto.ProvEpgKey;
+import org.opendaylight.groupbasedpolicy.renderer.listener.EndpointLocationsListener;
+import org.opendaylight.groupbasedpolicy.renderer.listener.EndpointsListener;
+import org.opendaylight.groupbasedpolicy.renderer.listener.ForwardingListener;
+import org.opendaylight.groupbasedpolicy.renderer.listener.RenderersListener;
+import org.opendaylight.groupbasedpolicy.renderer.listener.ResolvedPoliciesListener;
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.EndpointLocations;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.Endpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.Forwarding;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RenderersBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.endpoints.PeerEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.external.containment.endpoints.PeerExternalContainmentEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.external.endpoints.PeerExternalEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.RendererBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.ConfigurationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Status;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.ForwardingContexts;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RendererEndpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RuleGroups;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPolicies;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicy.ExternalImplicitGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.PolicyRuleGroupWithEndpointConstraints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.policy.rule.group.with.endpoint.constraints.PolicyRuleGroup;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableCollection;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+
+public class RendererManager implements AutoCloseable {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RendererManager.class);
+
+    private static long version = 0;
+
+    private final DataBroker dataProvider;
+    private final Set<RendererName> processingRenderers = new HashSet<>();
+    private Map<InstanceIdentifier<?>, RendererName> rendererByNode = new HashMap<>();
+    private ResolvedPolicyInfo policyInfo;
+    private EndpointInfo epInfo;
+    private EndpointLocationInfo epLocInfo;
+    private Forwarding forwarding;
+
+    private final EndpointsListener endpointsListener;
+    private final EndpointLocationsListener endpointLocationsListener;
+    private final ResolvedPoliciesListener resolvedPoliciesListener;
+    private final ForwardingListener forwardingListener;
+    private final RenderersListener renderersListener;
+
+    public RendererManager(DataBroker dataProvider) {
+        this.dataProvider = checkNotNull(dataProvider);
+        endpointsListener = new EndpointsListener(this, dataProvider);
+        endpointLocationsListener = new EndpointLocationsListener(this, dataProvider);
+        resolvedPoliciesListener = new ResolvedPoliciesListener(this, dataProvider);
+        forwardingListener = new ForwardingListener(this, dataProvider);
+        renderersListener = new RenderersListener(this, dataProvider);
+    }
+
+    public synchronized void endpointsUpdated(final Endpoints endpoints) {
+        epInfo = new EndpointInfo(endpoints);
+        processState();
+    }
+
+    public synchronized void endpointLocationsUpdated(final EndpointLocations epLocations) {
+        epLocInfo = new EndpointLocationInfo(epLocations);
+        processState();
+    }
+
+    public synchronized void resolvedPoliciesUpdated(final ResolvedPolicies resolvedPolicies) {
+        policyInfo = new ResolvedPolicyInfo(resolvedPolicies);
+        processState();
+    }
+
+    public synchronized void forwardingUpdated(final Forwarding forwarding) {
+        this.forwarding = forwarding;
+        processState();
+    }
+
+    public synchronized void renderersUpdated(final Renderers renderersCont) {
+        ImmutableMultimap<InstanceIdentifier<?>, RendererName> renderersByNode =
+                RendererUtils.resolveRenderersByNodes(renderersCont.getRenderer());
+        rendererByNode = new HashMap<>();
+        for (InstanceIdentifier<?> nodePath : renderersByNode.keySet()) {
+            ImmutableCollection<RendererName> renderers = renderersByNode.get(nodePath);
+            // only first renderer is used
+            rendererByNode.put(nodePath, renderers.asList().get(0));
+        }
+        if (processingRenderers.isEmpty()) {
+            processState();
+        } else {
+            LOG.debug("Waiting for renderers. Version {} needs to be processed by renderers: {}", version,
+                    processingRenderers);
+            ImmutableMap<RendererName, Renderer> rendererByName =
+                    RendererUtils.resolveRendererByName(renderersCont.getRenderer());
+            for (RendererName configuredRenderer : processingRenderers) {
+                Renderer renderer = rendererByName.get(configuredRenderer);
+                RendererPolicy rendererPolicy = renderer.getRendererPolicy();
+                if (rendererPolicy != null && rendererPolicy.getVersion() != null
+                        && renderer.getRendererPolicy().getVersion().equals(version)) {
+                    processingRenderers.remove(configuredRenderer);
+                    Status status = rendererPolicy.getStatus();
+                    if (status != null && status.getUnconfiguredRule() != null) {
+                        LOG.warn("Renderer {} did not configure policy with version {} successfully. \n{}",
+                                configuredRenderer.getValue(), version, status);
+                    } else {
+                        LOG.debug("Renderer {} configured policy with version {} successfully.",
+                                configuredRenderer.getValue(), version);
+                    }
+                }
+            }
+        }
+    }
+
+    private void processState() {
+        if (!processingRenderers.isEmpty()) {
+            LOG.debug("Waiting for renderers. Version {} needs to be processed by renderers: {}", version,
+                    processingRenderers);
+            return;
+        }
+        if (rendererByNode.values().isEmpty()) {
+            return;
+        }
+
+        version++;
+        Map<RendererName, RendererConfigurationBuilder> rendererConfigBuilderByRendererName = createRendererConfigBuilders();
+        List<Renderer> renderers = new ArrayList<>();
+        Set<RendererName> rendererNames = new HashSet<>(rendererByNode.values());
+        for (RendererName rendererName : rendererNames) {
+            RendererConfigurationBuilder rendererPolicyBuilder = rendererConfigBuilderByRendererName.get(rendererName);
+            Optional<Configuration> potentialConfig = createConfiguration(rendererPolicyBuilder);
+            RendererPolicy rendererPolicy = null;
+            if (potentialConfig.isPresent()) {
+                LOG.debug("Created configuration for renderer with version {}", rendererName.getValue(), version);
+                rendererPolicy =
+                        new RendererPolicyBuilder().setVersion(version).setConfiguration(potentialConfig.get()).build();
+            } else {
+                rendererPolicy =
+                        new RendererPolicyBuilder().setVersion(version).build();
+            }
+            renderers.add(new RendererBuilder().setName(rendererName).setRendererPolicy(rendererPolicy).build());
+            processingRenderers.add(rendererName);
+        }
+        WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
+        wTx.put(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Renderers.class),
+                new RenderersBuilder().setRenderer(renderers).build());
+        if (!DataStoreHelper.submitToDs(wTx)) {
+            LOG.warn("Version {} was not dispatched successfully. Previous version is valid till next update.",
+                    version);
+            for (RendererName rendererName : rendererConfigBuilderByRendererName.keySet()) {
+                processingRenderers.remove(rendererName);
+            }
+            version--;
+        }
+    }
+
+    /**
+     * Entry is added to the result map only if:<br>
+     * 1. There is at least one Address EP with absolute location
+     * 2. There is a renderer responsible for that EP
+     * 
+     * @return
+     */
+    private Map<RendererName, RendererConfigurationBuilder> createRendererConfigBuilders() {
+        if (!isStateValid()) {
+            return Collections.emptyMap();
+        }
+        Map<RendererName, RendererConfigurationBuilder> rendererConfigBuilderByRendererName = new HashMap<>();
+        for (InstanceIdentifier<?> absEpLocation : epLocInfo.getAllAbsoluteNodeLocations()) {
+            RendererName rendererName = rendererByNode.get(absEpLocation);
+            if (rendererName == null) {
+                LOG.trace("Renderer does not exist for EP with location: {}", absEpLocation);
+                continue;
+            }
+            RendererConfigurationBuilder rendererConfigBuilder = rendererConfigBuilderByRendererName.get(rendererName);
+            if (rendererConfigBuilder == null) {
+                rendererConfigBuilder = new RendererConfigurationBuilder();
+                rendererConfigBuilderByRendererName.put(rendererName, rendererConfigBuilder);
+            }
+            for (AddressEndpointKey rendererAdrEpKey : epLocInfo.getAddressEpsWithAbsoluteNodeLocation(absEpLocation)) {
+                Optional<AddressEndpoint> potentialAddressEp = epInfo.getEndpoint(rendererAdrEpKey);
+                if (!potentialAddressEp.isPresent()) {
+                    LOG.trace("Endpoint does not exist but has location: {}", rendererAdrEpKey);
+                    continue;
+                }
+                AddressEndpoint rendererAdrEp = potentialAddressEp.get();
+                resolveRendererConfigForEndpoint(rendererAdrEp, rendererConfigBuilder);
+            }
+        }
+        return rendererConfigBuilderByRendererName;
+    }
+
+    private boolean isStateValid() {
+        if (rendererByNode.isEmpty() || policyInfo == null || epInfo == null || epLocInfo == null
+                || forwarding == null) {
+            return false;
+        }
+        return true;
+    }
+
+    private Optional<Configuration> createConfiguration(@Nullable RendererConfigurationBuilder rendererPolicyBuilder) {
+        if (rendererPolicyBuilder == null) {
+            return Optional.absent();
+        }
+        ConfigurationBuilder configBuilder = new ConfigurationBuilder();
+        RendererEndpoints rendererEndpoints = rendererPolicyBuilder.buildRendererEndpoints();
+        if (isRendererEndpointsEmpty(rendererEndpoints)) {
+            return Optional.absent();
+        }
+        configBuilder.setRendererEndpoints(rendererEndpoints);
+
+        org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.Endpoints endpoints =
+                rendererPolicyBuilder.buildEndoints(epInfo, epLocInfo, rendererByNode);
+        configBuilder.setEndpoints(endpoints);
+
+        RuleGroups ruleGroups = rendererPolicyBuilder.buildRuluGroups(policyInfo);
+        configBuilder.setRuleGroups(ruleGroups);
+
+        ForwardingContexts forwardingContexts = rendererPolicyBuilder.buildForwardingContexts(forwarding);
+        configBuilder.setForwardingContexts(forwardingContexts);
+
+        return Optional.of(configBuilder.build());
+    }
+
+    private boolean isRendererEndpointsEmpty(RendererEndpoints rendererEndpoints) {
+        if (rendererEndpoints == null || rendererEndpoints.getRendererEndpoint() == null
+                || rendererEndpoints.getRendererEndpoint().isEmpty()) {
+            return true;
+        }
+        return false;
+    }
+
+    @VisibleForTesting
+    void resolveRendererConfigForEndpoint(AddressEndpoint rendererAdrEp,
+            RendererConfigurationBuilder rendererPolicyBuilder) {
+        Set<EpgKeyDto> rendererEpgs = toEpgKeys(rendererAdrEp.getEndpointGroup(), rendererAdrEp.getTenant());
+        RendererEndpointKey rendererEpKey = AddressEndpointUtils.toRendererEpKey(rendererAdrEp.getKey());
+        for (EpgKeyDto rendererEpg : rendererEpgs) {
+            ImmutableSet<ConsEpgKey> consPeerEpgs = policyInfo.findConsumerPeers(rendererEpg);
+            for (ConsEpgKey consPeerEpg : consPeerEpgs) {
+                Optional<ResolvedPolicy> potentialPolicy = policyInfo.findPolicy(consPeerEpg, rendererEpg);
+                ResolvedPolicy policy = potentialPolicy.get();
+                ImmutableSet<AddressEndpointKey> consPeerAdrEps = epInfo.findAddressEpsWithEpg(consPeerEpg);
+                resolveRendererPolicyBetweenEpAndPeers(rendererEpKey, consPeerAdrEps, policy,
+                        EndpointPolicyParticipation.PROVIDER, rendererPolicyBuilder);
+                ImmutableSet<ContainmentEndpointKey> consPeerContEps = epInfo.findContainmentEpsWithEpg(consPeerEpg);
+                resolveRendererPolicyBetweenEpAndContPeers(rendererEpKey, consPeerContEps, policy,
+                        EndpointPolicyParticipation.PROVIDER, rendererPolicyBuilder);
+            }
+            ImmutableSet<ProvEpgKey> provPeerEpgs = policyInfo.findProviderPeers(rendererEpg);
+            for (ProvEpgKey provPeerEpg : provPeerEpgs) {
+                Optional<ResolvedPolicy> potentialPolicy = policyInfo.findPolicy(rendererEpg, provPeerEpg);
+                ResolvedPolicy policy = potentialPolicy.get();
+                ImmutableSet<AddressEndpointKey> provPeerAdrEps = epInfo.findAddressEpsWithEpg(provPeerEpg);
+                resolveRendererPolicyBetweenEpAndPeers(rendererEpKey, provPeerAdrEps, policy,
+                        EndpointPolicyParticipation.CONSUMER, rendererPolicyBuilder);
+                ImmutableSet<ContainmentEndpointKey> provPeerContEps = epInfo.findContainmentEpsWithEpg(provPeerEpg);
+                resolveRendererPolicyBetweenEpAndContPeers(rendererEpKey, provPeerContEps, policy,
+                        EndpointPolicyParticipation.CONSUMER, rendererPolicyBuilder);
+            }
+        }
+    }
+
+    private void resolveRendererPolicyBetweenEpAndContPeers(RendererEndpointKey rendererEpKey,
+            Set<ContainmentEndpointKey> peerContEps, ResolvedPolicy policy,
+            EndpointPolicyParticipation rendererEpParticipation, RendererConfigurationBuilder rendererPolicyBuilder) {
+        if (isRendererEpInEig(policy, rendererEpParticipation)) {
+            LOG.info("Renderer EP cannot be in EIG therefore it is ignored: {}. \nPolicy: {}", rendererEpKey);
+            LOG.debug("Renderer EP participation: {}, Policy: {}", rendererEpParticipation, policy);
+            return;
+        }
+        for (ContainmentEndpointKey peerContEpKey : peerContEps) {
+            ExternalImplicitGroup eig = policy.getExternalImplicitGroup();
+            if (eig != null) { // peers are in EIG
+                if (!epLocInfo.hasRelativeLocation(peerContEpKey)) {
+                    LOG.debug("EIG Containment Peer does not have relative location therefore it is ignored: {}",
+                            peerContEpKey);
+                    continue;
+                }
+                PeerExternalContainmentEndpointKey peerExtContEpKey =
+                        ContainmentEndpointUtils.toPeerExtContEpKey(peerContEpKey);
+                for (PolicyRuleGroupWithEndpointConstraints ruleGrpsWithEpConstraints : policy
+                    .getPolicyRuleGroupWithEndpointConstraints()) {
+                    // TODO filter based on endpoint constraints
+                    for (PolicyRuleGroup ruleGrp : ruleGrpsWithEpConstraints.getPolicyRuleGroup()) {
+                        rendererPolicyBuilder.add(rendererEpKey, peerExtContEpKey, ruleGrp.getKey(),
+                                rendererEpParticipation);
+                    }
+                }
+            } else {
+                LOG.info("Peer Containment EP cannot be in other EPG than EIG therefore it is ignored: {}",
+                        peerContEpKey);
+            }
+        }
+    }
+
+    private void resolveRendererPolicyBetweenEpAndPeers(RendererEndpointKey rendererEpKey,
+            Set<AddressEndpointKey> peerAdrEps, ResolvedPolicy policy,
+            EndpointPolicyParticipation rendererEpParticipation, RendererConfigurationBuilder rendererPolicyBuilder) {
+        if (isRendererEpInEig(policy, rendererEpParticipation)) {
+            LOG.info("Renderer EP cannot be in EIG therefore it is ignored: {}. \nPolicy: {}", rendererEpKey);
+            LOG.debug("Renderer EP participation: {}, Policy: {}", rendererEpParticipation, policy);
+            return;
+        }
+        for (AddressEndpointKey peerAdrEpKey : peerAdrEps) {
+            ExternalImplicitGroup eig = policy.getExternalImplicitGroup();
+            if (eig != null) {
+                if (!epLocInfo.hasRelativeLocation(peerAdrEpKey)) {
+                    LOG.debug("EIG Peer does not have relative location therefore it is ignored: {}", peerAdrEpKey);
+                    continue;
+                }
+                PeerExternalEndpointKey peerExtEpKey = AddressEndpointUtils.toPeerExtEpKey(peerAdrEpKey);
+                for (PolicyRuleGroupWithEndpointConstraints ruleGrpsWithEpConstraints : policy
+                    .getPolicyRuleGroupWithEndpointConstraints()) {
+                    // TODO filter based on endpoint constraints
+                    for (PolicyRuleGroup ruleGrp : ruleGrpsWithEpConstraints.getPolicyRuleGroup()) {
+                        rendererPolicyBuilder.add(rendererEpKey, peerExtEpKey, ruleGrp.getKey(),
+                                rendererEpParticipation);
+                    }
+                }
+            } else {
+                if (!epLocInfo.hasRealLocation(peerAdrEpKey)) {
+                    LOG.debug("Peer does not have real location therefore it is ignored: {}", peerAdrEpKey);
+                    continue;
+                }
+                PeerEndpointKey peerEpKey = AddressEndpointUtils.toPeerEpKey(peerAdrEpKey);
+                for (PolicyRuleGroupWithEndpointConstraints ruleGrpsWithEpConstraints : policy
+                    .getPolicyRuleGroupWithEndpointConstraints()) {
+                    // TODO filter based on endpoint constraints
+                    for (PolicyRuleGroup ruleGrp : ruleGrpsWithEpConstraints.getPolicyRuleGroup()) {
+                        rendererPolicyBuilder.add(rendererEpKey, peerEpKey, ruleGrp.getKey(), rendererEpParticipation);
+                    }
+                }
+            }
+        }
+    }
+
+    private boolean isRendererEpInEig(ResolvedPolicy policy, EndpointPolicyParticipation rendererEpParticipation) {
+        ExternalImplicitGroup eig = policy.getExternalImplicitGroup();
+        if (rendererEpParticipation == EndpointPolicyParticipation.PROVIDER
+                && ExternalImplicitGroup.ProviderEpg == eig) {
+            return true;
+        } else if (rendererEpParticipation == EndpointPolicyParticipation.CONSUMER
+                && ExternalImplicitGroup.ConsumerEpg == eig) {
+            return true;
+        }
+        return false;
+    }
+
+    private Set<EpgKeyDto> toEpgKeys(List<EndpointGroupId> epgIds, TenantId tenantId) {
+        return FluentIterable.from(epgIds).transform(new Function<EndpointGroupId, EpgKeyDto>() {
+
+            @Override
+            public EpgKeyDto apply(EndpointGroupId input) {
+                return new EpgKeyDto(input, tenantId);
+            }
+        }).toSet();
+    }
+
+    @VisibleForTesting
+    Set<RendererName> getProcessingRenderers() {
+        return processingRenderers;
+    }
+
+    @VisibleForTesting
+    static void resetVersion() {
+        version = 0;
+    }
+
+    @Override
+    public void close() throws Exception {
+        endpointsListener.close();
+        endpointLocationsListener.close();
+        resolvedPoliciesListener.close();
+        forwardingListener.close();
+        renderersListener.close();
+    }
+
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/RendererUtils.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/RendererUtils.java
new file mode 100644 (file)
index 0000000..08cec8c
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.renderer;
+
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNode;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableMultimap.Builder;
+import com.google.common.collect.Maps;
+
+public class RendererUtils {
+
+    public static @Nonnull ImmutableMultimap<InstanceIdentifier<?>, RendererName> resolveRenderersByNodes(
+            @Nullable List<Renderer> renderers) {
+        if (renderers == null) {
+            return ImmutableMultimap.of();
+        }
+        Builder<InstanceIdentifier<?>, RendererName> renderersByNodeBuilder = ImmutableMultimap.builder();
+        for (Renderer renderer : renderers) {
+            List<RendererNode> rendererNodes = renderer.getRendererNodes().getRendererNode();
+            if (rendererNodes == null) {
+                continue;
+            }
+            for (RendererNode rendererNode : rendererNodes) {
+                if (rendererNode.getNodePath() != null) {
+                    renderersByNodeBuilder.put(rendererNode.getNodePath(), renderer.getName());
+                }
+            }
+        }
+        return renderersByNodeBuilder.build();
+    }
+
+    public static @Nonnull ImmutableMap<RendererName, Renderer> resolveRendererByName(
+            @Nullable List<Renderer> renderers) {
+        if (renderers == null) {
+            return ImmutableMap.of();
+        }
+        return Maps.uniqueIndex(renderers, Renderer::getName);
+    }
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ResolvedPolicyInfo.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ResolvedPolicyInfo.java
new file mode 100644 (file)
index 0000000..3bb8b89
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.renderer;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.opendaylight.groupbasedpolicy.dto.ConsEpgKey;
+import org.opendaylight.groupbasedpolicy.dto.EpgKeyDto;
+import org.opendaylight.groupbasedpolicy.dto.ProvEpgKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPolicies;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.PolicyRuleGroupWithEndpointConstraints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.policy.rule.group.with.endpoint.constraints.PolicyRuleGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.policy.rule.group.with.endpoint.constraints.PolicyRuleGroupKey;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableTable;
+import com.google.common.collect.ImmutableTable.Builder;
+
+public class ResolvedPolicyInfo {
+
+    private final ImmutableTable<ConsEpgKey, ProvEpgKey, ResolvedPolicy> policyByEpgs;
+    private final Map<PolicyRuleGroupKey, PolicyRuleGroup> policyRuleGrpByKey = new HashMap<>();
+
+    public ResolvedPolicyInfo(ResolvedPolicies resolvedPolicies) {
+        if (resolvedPolicies.getResolvedPolicy() == null) {
+            policyByEpgs = ImmutableTable.of();
+        } else {
+            Builder<ConsEpgKey, ProvEpgKey, ResolvedPolicy> policyByEpgsBuilder = new Builder<>();
+            for (ResolvedPolicy resolvedPolicy : resolvedPolicies.getResolvedPolicy()) {
+                policyByEpgsBuilder.put(
+                        new EpgKeyDto(resolvedPolicy.getConsumerEpgId(), resolvedPolicy.getConsumerTenantId()),
+                        new EpgKeyDto(resolvedPolicy.getProviderEpgId(), resolvedPolicy.getProviderTenantId()),
+                        resolvedPolicy);
+                for (PolicyRuleGroupWithEndpointConstraints ruleGrpWithEpConstraints : resolvedPolicy
+                    .getPolicyRuleGroupWithEndpointConstraints()) {
+                    for (PolicyRuleGroup ruleGrp : ruleGrpWithEpConstraints.getPolicyRuleGroup()) {
+                        policyRuleGrpByKey.put(ruleGrp.getKey(), ruleGrp);
+                    }
+                }
+            }
+            policyByEpgs = policyByEpgsBuilder.build();
+        }
+    }
+
+    public Optional<PolicyRuleGroup> getPolicyRuleGroup(PolicyRuleGroupKey policyRuleGrpKey) {
+        return Optional.fromNullable(policyRuleGrpByKey.get(policyRuleGrpKey));
+    }
+
+    public ImmutableSet<ProvEpgKey> findProviderPeers(ConsEpgKey consKey) {
+        return policyByEpgs.row(consKey).keySet();
+    }
+
+    public ImmutableSet<ConsEpgKey> findConsumerPeers(ProvEpgKey provKey) {
+        return policyByEpgs.column(provKey).keySet();
+    }
+
+    public Optional<ResolvedPolicy> findPolicy(ConsEpgKey consKey, ProvEpgKey provKey) {
+        return Optional.fromNullable(policyByEpgs.get(consKey, provKey));
+    }
+
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/listener/EndpointLocationsListener.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/listener/EndpointLocationsListener.java
new file mode 100644 (file)
index 0000000..1a0c05b
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.renderer.listener;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.renderer.RendererManager;
+import org.opendaylight.groupbasedpolicy.util.DataTreeChangeHandler;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.EndpointLocations;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class EndpointLocationsListener extends DataTreeChangeHandler<EndpointLocations> implements AutoCloseable {
+
+    private final RendererManager rendererManager;
+
+    public EndpointLocationsListener(RendererManager rendererManager, DataBroker dataProvider) {
+        super(dataProvider);
+        this.rendererManager = rendererManager;
+        registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+                InstanceIdentifier.create(EndpointLocations.class)));
+    }
+
+    @Override
+    protected void onWrite(DataObjectModification<EndpointLocations> rootNode,
+            InstanceIdentifier<EndpointLocations> rootIdentifier) {
+        rendererManager.endpointLocationsUpdated(rootNode.getDataAfter());
+    }
+
+    @Override
+    protected void onDelete(DataObjectModification<EndpointLocations> rootNode,
+            InstanceIdentifier<EndpointLocations> rootIdentifier) {
+        rendererManager.endpointLocationsUpdated(rootNode.getDataAfter());
+    }
+
+    @Override
+    protected void onSubtreeModified(DataObjectModification<EndpointLocations> rootNode,
+            InstanceIdentifier<EndpointLocations> rootIdentifier) {
+        rendererManager.endpointLocationsUpdated(rootNode.getDataAfter());
+    }
+
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/listener/EndpointsListener.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/listener/EndpointsListener.java
new file mode 100644 (file)
index 0000000..6a642ed
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.renderer.listener;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.renderer.RendererManager;
+import org.opendaylight.groupbasedpolicy.util.DataTreeChangeHandler;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.Endpoints;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class EndpointsListener extends DataTreeChangeHandler<Endpoints> implements AutoCloseable {
+
+    private final RendererManager rendererManager;
+
+    public EndpointsListener(RendererManager rendererManager, DataBroker dataProvider) {
+        super(dataProvider);
+        this.rendererManager = rendererManager;
+        registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Endpoints.class)));
+    }
+
+    @Override
+    protected void onWrite(DataObjectModification<Endpoints> rootNode, InstanceIdentifier<Endpoints> rootIdentifier) {
+        rendererManager.endpointsUpdated(rootNode.getDataAfter());
+    }
+
+    @Override
+    protected void onDelete(DataObjectModification<Endpoints> rootNode, InstanceIdentifier<Endpoints> rootIdentifier) {
+        rendererManager.endpointsUpdated(rootNode.getDataAfter());
+    }
+
+    @Override
+    protected void onSubtreeModified(DataObjectModification<Endpoints> rootNode,
+            InstanceIdentifier<Endpoints> rootIdentifier) {
+        rendererManager.endpointsUpdated(rootNode.getDataAfter());
+    }
+
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/listener/ForwardingListener.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/listener/ForwardingListener.java
new file mode 100644 (file)
index 0000000..dbb3101
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.renderer.listener;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.renderer.RendererManager;
+import org.opendaylight.groupbasedpolicy.util.DataTreeChangeHandler;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.Forwarding;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class ForwardingListener extends DataTreeChangeHandler<Forwarding> implements AutoCloseable {
+
+    private final RendererManager rendererManager;
+
+    public ForwardingListener(RendererManager rendererManager, DataBroker dataProvider) {
+        super(dataProvider);
+        this.rendererManager = rendererManager;
+        registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+                InstanceIdentifier.create(Forwarding.class)));
+    }
+
+    @Override
+    protected void onWrite(DataObjectModification<Forwarding> rootNode, InstanceIdentifier<Forwarding> rootIdentifier) {
+        rendererManager.forwardingUpdated(rootNode.getDataAfter());
+    }
+
+    @Override
+    protected void onDelete(DataObjectModification<Forwarding> rootNode,
+            InstanceIdentifier<Forwarding> rootIdentifier) {
+        rendererManager.forwardingUpdated(rootNode.getDataAfter());
+    }
+
+    @Override
+    protected void onSubtreeModified(DataObjectModification<Forwarding> rootNode,
+            InstanceIdentifier<Forwarding> rootIdentifier) {
+        rendererManager.forwardingUpdated(rootNode.getDataAfter());
+    }
+
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/listener/RenderersListener.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/listener/RenderersListener.java
new file mode 100644 (file)
index 0000000..0e840b5
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.renderer.listener;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.renderer.RendererManager;
+import org.opendaylight.groupbasedpolicy.util.DataTreeChangeHandler;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class RenderersListener extends DataTreeChangeHandler<Renderers> implements AutoCloseable {
+
+    private final RendererManager rendererManager;
+
+    public RenderersListener(RendererManager rendererManager, DataBroker dataProvider) {
+        super(dataProvider);
+        this.rendererManager = rendererManager;
+        registerDataTreeChangeListener(
+                new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Renderers.class)));
+    }
+
+    @Override
+    protected void onWrite(DataObjectModification<Renderers> rootNode, InstanceIdentifier<Renderers> rootIdentifier) {
+        rendererManager.renderersUpdated(rootNode.getDataAfter());
+    }
+
+    @Override
+    protected void onDelete(DataObjectModification<Renderers> rootNode, InstanceIdentifier<Renderers> rootIdentifier) {
+        rendererManager.renderersUpdated(rootNode.getDataAfter());
+    }
+
+    @Override
+    protected void onSubtreeModified(DataObjectModification<Renderers> rootNode,
+            InstanceIdentifier<Renderers> rootIdentifier) {
+        rendererManager.renderersUpdated(rootNode.getDataAfter());
+    }
+
+}
diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/listener/ResolvedPoliciesListener.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/listener/ResolvedPoliciesListener.java
new file mode 100644 (file)
index 0000000..f7ed106
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.renderer.listener;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.renderer.RendererManager;
+import org.opendaylight.groupbasedpolicy.util.DataTreeChangeHandler;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPolicies;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class ResolvedPoliciesListener extends DataTreeChangeHandler<ResolvedPolicies> implements AutoCloseable {
+
+    private final RendererManager rendererManager;
+
+    public ResolvedPoliciesListener(RendererManager rendererManager, DataBroker dataProvider) {
+        super(dataProvider);
+        this.rendererManager = rendererManager;
+        registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+                InstanceIdentifier.create(ResolvedPolicies.class)));
+    }
+
+    @Override
+    protected void onWrite(DataObjectModification<ResolvedPolicies> rootNode,
+            InstanceIdentifier<ResolvedPolicies> rootIdentifier) {
+        rendererManager.resolvedPoliciesUpdated(rootNode.getDataAfter());
+    }
+
+    @Override
+    protected void onDelete(DataObjectModification<ResolvedPolicies> rootNode,
+            InstanceIdentifier<ResolvedPolicies> rootIdentifier) {
+        rendererManager.resolvedPoliciesUpdated(rootNode.getDataAfter());
+    }
+
+    @Override
+    protected void onSubtreeModified(DataObjectModification<ResolvedPolicies> rootNode,
+            InstanceIdentifier<ResolvedPolicies> rootIdentifier) {
+        rendererManager.resolvedPoliciesUpdated(rootNode.getDataAfter());
+    }
+
+}
index 2116d12e1cc838a1f5871b85e630fd7b62c3a503..4e1835cb143c73827a04d3a05d5130ab81e9339f 100644 (file)
@@ -11,12 +11,25 @@ package org.opendaylight.groupbasedpolicy.util;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.EndpointLocations;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocationKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.ContainmentEndpointLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.ContainmentEndpointLocationKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.AddressEndpoints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.ContainmentEndpoints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.containment.endpoint._case.ParentContainmentEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.containment.endpoint._case.ParentContainmentEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.RelativeLocations;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.ExternalLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.ExternalLocationKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.InternalLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.InternalLocationKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionDefinitionId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
@@ -106,7 +119,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.StatisticRecord;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.StatisticRecordKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
 
 public class IidFactory {
 
@@ -393,11 +405,78 @@ public class IidFactory {
             .build();
     }
 
-    public static InstanceIdentifierBuilder<ProviderAddressEndpointLocation> providerAddressEndpointLocationIid(String provider,
+    public static InstanceIdentifier<ParentContainmentEndpoint> parentContainmentEndpointIid(
+            AddressEndpointKey addressEndpointKey, ParentContainmentEndpointKey parentContainmentEndpointKey) {
+        return InstanceIdentifier
+            .builder(
+                    org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.Endpoints.class)
+            .child(AddressEndpoints.class)
+            .child(AddressEndpoint.class, addressEndpointKey)
+            .child(ParentContainmentEndpoint.class, parentContainmentEndpointKey)
+            .build();
+    }
+
+    public static InstanceIdentifier<AddressEndpointLocation> addressEndpointLocationIid(AddressEndpointLocationKey addrEndpointLocationKey) {
+        return InstanceIdentifier.builder(EndpointLocations.class)
+                .child(AddressEndpointLocation.class, addrEndpointLocationKey)
+                .build();
+    }
+
+    public static InstanceIdentifier<ContainmentEndpointLocation> containmentEndpointLocationIid(ContainmentEndpointLocationKey addrEndpointLocationKey) {
+        return InstanceIdentifier.builder(EndpointLocations.class)
+                .child(ContainmentEndpointLocation.class, addrEndpointLocationKey)
+                .build();
+    }
+
+    public static InstanceIdentifier<InternalLocation> internalLocationIid(AddressEndpointLocationKey addrEndpointLocationKey,
+            InternalLocationKey internalLocationKey) {
+        return InstanceIdentifier.builder(EndpointLocations.class)
+                .child(AddressEndpointLocation.class, addrEndpointLocationKey)
+                .child(RelativeLocations.class)
+                .child(InternalLocation.class, internalLocationKey)
+                .build();
+    }
+
+    public static InstanceIdentifier<InternalLocation> internalLocationIid(ContainmentEndpointLocationKey contEndpointLocationKey,
+            InternalLocationKey internalLocationKey) {
+        return InstanceIdentifier.builder(EndpointLocations.class)
+                .child(ContainmentEndpointLocation.class, contEndpointLocationKey)
+                .child(RelativeLocations.class)
+                .child(InternalLocation.class, internalLocationKey)
+                .build();
+    }
+
+    public static InstanceIdentifier<ExternalLocation> externalLocationIid(AddressEndpointLocationKey addrEndpointLocationKey,
+            ExternalLocationKey externalLocationKey) {
+        return InstanceIdentifier.builder(EndpointLocations.class)
+                .child(AddressEndpointLocation.class, addrEndpointLocationKey)
+                .child(RelativeLocations.class)
+                .child(ExternalLocation.class, externalLocationKey)
+                .build();
+    }
+
+    public static InstanceIdentifier<ExternalLocation> externalLocationIid(ContainmentEndpointLocationKey contEndpointLocationKey,
+            ExternalLocationKey externalLocationKey) {
+        return InstanceIdentifier.builder(EndpointLocations.class)
+                .child(ContainmentEndpointLocation.class, contEndpointLocationKey)
+                .child(RelativeLocations.class)
+                .child(ExternalLocation.class, externalLocationKey)
+                .build();
+    }
+
+    public static InstanceIdentifier<AbsoluteLocation> absoluteLocationIid(AddressEndpointLocationKey addrEndpointLocationKey) {
+        return InstanceIdentifier.builder(EndpointLocations.class)
+                .child(AddressEndpointLocation.class, addrEndpointLocationKey)
+                .child(AbsoluteLocation.class)
+                .build();
+    }
+
+    public static InstanceIdentifier<ProviderAddressEndpointLocation> providerAddressEndpointLocationIid(String provider,
             Class<? extends AddressType> addrType, String addr, Class<? extends ContextType> cType,
             ContextId containment) {
         return InstanceIdentifier.builder(LocationProviders.class)
                 .child(LocationProvider.class, new LocationProviderKey(new ProviderName(provider)))
-            .child(ProviderAddressEndpointLocation.class, new ProviderAddressEndpointLocationKey(addr, addrType, containment, cType));
+            .child(ProviderAddressEndpointLocation.class, new ProviderAddressEndpointLocationKey(addr, addrType, containment, cType))
+            .build();
     }
 }
index 100c54f30612396317f036caecdf1ec9daea27fc..4384d5d88da219e27b1dc639de908fd78cf5e322 100644 (file)
@@ -167,6 +167,7 @@ public class PolicyInfoUtils {
                 policyRuleGroupBuilder.setContractId(ruleGrp.getRelatedContract().getId());
                 policyRuleGroupBuilder.setSubjectName(ruleGrp.getRelatedSubject());
                 policyRuleGroupBuilder.setTenantId(ruleGrp.getContractTenant().getId());
+                policyRuleGroupBuilder.setOrder(ruleGrp.getOrder());
                 policyRuleGroupBuilder
                     .setResolvedRule(buildResolvedRules(ruleGrp.getRules(), ruleGrp.getContractTenant()));
                 policyRuleGroups.add(policyRuleGroupBuilder.build());
index dbecfb9a1a7991b65ba667051be4529c699dc829..2d4d388d30bd4c5dc691f054fa23825e2342b23a 100644 (file)
@@ -62,10 +62,17 @@ module base-endpoint {
                         "The tenant with which this endpoint is associated";
         }
         container network-containment {
-            description
-                        "The network domain associated with this endpoint's fowarding
-                        context.";
-            uses forwarding:network-domain-key;
+            choice containment {
+                description
+                            "The network domain associated with this endpoint's fowarding
+                            context.";
+                case network-domain-containment {
+                    uses forwarding:network-domain-key;
+                }
+                case forwarding-context-containment {
+                    uses forwarding:context-key;
+                }
+            }
         }
         leaf-list endpoint-group {
             type gbp-common:endpoint-group-id;
@@ -118,22 +125,27 @@ module base-endpoint {
         }
     }
 
-    grouping has-regular-location {
-        leaf node {
+    grouping internal-location-fields {
+        description "Location inside ODL - node and node-connector
+            are represented directly in ODL.";
+        leaf internal-node {
             mandatory true;
             type instance-identifier;
         }
-        leaf node-connector {
+        leaf internal-node-connector {
             type instance-identifier;
         }
     }
 
-    grouping has-external-location {
+    grouping external-location-fields {
+        description "Location outside of ODL - node and node-connector
+            are outside of ODL. external-node-mount-point is path
+            to external system where node and node-connector are located.";
         leaf external-node-mount-point {
             mandatory true;
             type instance-identifier;
         }
-        leaf external-node-location {
+        leaf external-node {
             type string; // TODO switch to external-reference
         }
         leaf external-node-connector {
@@ -141,29 +153,37 @@ module base-endpoint {
         }
     }
 
-    grouping has-location {
-        container real-location {
+    grouping has-absolute-location {
+        container absolute-location {
             choice location-type {
-                case regular-location-case {
-                    uses has-regular-location;
+                case internal-location-case {
+                    uses internal-location-fields;
                 }
                 case external-location-case {
-                    uses has-external-location;
+                    uses external-location-fields;
                 }
             }
         }
-        container relative-location {
-            list location {
-                key "node node-connector";
-                uses has-regular-location;
+    }
+
+    grouping has-relative-location {
+        container relative-locations {
+            list internal-location {
+                key "internal-node internal-node-connector";
+                uses internal-location-fields;
             }
             list external-location {
                 key "external-node-mount-point external-node-connector";
-                uses has-external-location;
+                uses external-location-fields;
             }
         }
     }
 
+    grouping has-location {
+        uses has-absolute-location;
+        uses has-relative-location;
+    }
+
     container endpoints {
         description
                 "Repository for operational state data about endpoints needed
@@ -195,7 +215,7 @@ module base-endpoint {
         list containment-endpoint-location {
             key "context-type context-id";
             uses forwarding:context-key;
-            uses has-location;
+            uses has-relative-location;
         }
     }
 
@@ -214,7 +234,7 @@ module base-endpoint {
             list containment-endpoint-reg {
                 key "context-type context-id";
                 uses containment-endpoint-fields;
-                uses has-location;
+                uses has-relative-location;
             }
         }
     }
index 9e1f19b39a825aa0c2fd5f883093934995aeb7b2..7af2d7d94688baf0c806b392dfa98250246701c8 100644 (file)
@@ -33,6 +33,9 @@ module endpoint-location-provider {
             leaf provider {\r
                 type provider-name;\r
             }\r
+            leaf priority {\r
+                type uint32;\r
+            }\r
             list provider-address-endpoint-location {\r
                 key "context-type context-id address-type address";\r
                 uses base-endpoint:address-endpoint-key;\r
@@ -41,7 +44,7 @@ module endpoint-location-provider {
             list provider-containment-endpoint-location {\r
                 key "context-type context-id";\r
                 uses forwarding:context-key;\r
-                uses base-endpoint:has-location;\r
+                uses base-endpoint:has-relative-location;\r
             }\r
         }\r
     }\r
index d39e0e4a4d985189fb83fc50c341e08390f4baed..d3394699f433e27311ab82a32101d994dae36c86 100644 (file)
@@ -29,7 +29,6 @@ module forwarding {
 
     identity context-type {
         description "Type of context.";
-        base network-domain;
     }
 
     typedef address-type-ref {
index 2b15e8487c5ceff3b2c19efd0ab4f891569e0268..8d052d433eb823a707511809c849e96e24e34962 100755 (executable)
@@ -141,9 +141,6 @@ module renderer {
     }
 
     container renderers {
-        description
-            "Leaf containing all renderers' description.";
-
         list renderer {
             description
                 "A renderer provides a list of capabilities and status about configured policy.
@@ -164,7 +161,9 @@ module renderer {
                 list renderer-node {
                     key "node-path";
                     leaf node-path {
-                        description "Path to the node where policy needs to be enforced.";
+                        description "Path to the node where policy needs to be enforced.
+                            This field is matched against internal-node and external-node-mount-point
+                            from base-endoint:endpoint-locations.";
                         type instance-identifier;
                     }
                 }
@@ -186,6 +185,7 @@ module renderer {
                     description "Renderer tries to apply given policy on devices.";
                     container renderer-endpoints {
                         list renderer-endpoint {
+                            min-elements 1;
                             description "Policy between renderer-endpoint and peer-endpoints (peers).
                                 Renderer configures policy for renderer endpoints.";
                             key "context-type context-id address-type address";
@@ -213,6 +213,7 @@ module renderer {
 
                     container rule-groups {
                         list rule-group {
+                            min-elements 1;
                             description "A specific policy rule group that apply to pair of endpoints.
                                 The policy rule group represents the subject with resolved rules.";
                             key "tenant-id contract-id subject-name";
@@ -225,6 +226,7 @@ module renderer {
 
                     container endpoints {
                         list address-endpoint-with-location {
+                            min-elements 1;
                             key "context-type context-id address-type address";
                             uses base-endpoint:address-endpoint-fields;
                             uses base-endpoint:has-location;
@@ -233,13 +235,14 @@ module renderer {
 
                         list containment-endpoint-with-location {
                             key "context-type context-id";
-                            uses base-endpoint:address-endpoint-fields;
-                            uses base-endpoint:has-location;
+                            uses base-endpoint:containment-endpoint-fields;
+                            uses base-endpoint:has-relative-location;
                         }
                     }
 
                     container forwarding-contexts {
                         list forwarding-context-by-tenant {
+                            min-elements 1;
                             key tenant-id;
                             uses forwarding:forwarding-with-tenant-fields;
                         }
index 4e9775cd51a4c7dc6f1d8b8a4fb442346e682ee8..b088b06709502325630ae7b2e0ede5621a48f396 100644 (file)
@@ -220,6 +220,7 @@ module resolved-policy {
                        The policy rule group represents the subject with resolved rules.";
                    key "tenant-id contract-id subject-name";
                    uses has-subject-key;
+                   uses policy:has-order;
                    uses has-resolved-rules;
                }
            }
index c26576f57ddd9dddc027f021e6ca84b5ede5bc45..b83bcc5417f6b05d7fc8729ad64a82d18eeedaf4 100644 (file)
 
 package org.opendaylight.groupbasedpolicy.base_endpoint;
 
-import com.google.common.util.concurrent.CheckedFuture;
+import static org.mockito.Mockito.mock;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.groupbasedpolicy.api.BaseEndpointRendererAugmentation;
-import org.opendaylight.groupbasedpolicy.base_endpoint.BaseEndpointRpcRegistry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointRegKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointRegKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.*;
+import org.opendaylight.groupbasedpolicy.test.CustomDataBrokerTest;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.NetworkContainmentBuilder;
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
+import org.opendaylight.groupbasedpolicy.util.IidFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.Endpoints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.UnregisterEndpointInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.UnregisterEndpointInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.NetworkContainmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.containment.NetworkDomainContainment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.containment.NetworkDomainContainmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.AddressEndpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.ContainmentEndpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.ParentEndpointChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.ParentContainmentEndpointCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.ParentEndpointCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.ParentEndpointCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpointBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointRegBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointReg;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointRegBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.unregister.endpoint.input.AddressEndpointUnregBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.unregister.endpoint.input.ContainmentEndpointUnreg;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.unregister.endpoint.input.ContainmentEndpointUnregBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L2FloodDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.MacAddressType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.Subnet;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.AddressType;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
 
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Future;
 
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.*;
-import static org.mockito.internal.verification.VerificationModeFactory.times;
+import javax.annotation.Nonnull;
 
-public class BaseEndpointRpcRegistryTest {
+public class BaseEndpointRpcRegistryTest extends CustomDataBrokerTest {
 
     private static final String MAC_ADDRESS = "01:23:45:67:89:AB";
+    private static final String IP_ADDRESS = "192.168.100.1/24";
     private static final String TENANT = "admin";
     private static final String DOMAIN = "test.domain";
     private static final String CONTEXT_ID = "testContext";
-    private static final String FLOOD_DOMAIN = "testFloodDomain";
+    private static final long timestamp = 1234567890L;
+
+    private enum AddressEndpointRegistration {
+        CHILD, PARENT, BOTH, NONE
+    }
+    private enum AddressEndpointType {
+        L2, L3, BOTH, NONE
+    }
 
     private DataBroker dataProvider;
     private BaseEndpointRendererAugmentation baseEndpointRendererAugmentation;
     private BaseEndpointRpcRegistry baseEndpointRpcRegistry;
+    private AddressEndpoint basel2Ep;
+    private AddressEndpoint basel3Ep;
+    private ContainmentEndpoint baseContainmentEp;
+    private ParentEndpoint basel3Parent;
+    private ChildEndpoint basel2Child;
+
+    @Nonnull
+    @Override
+    public Collection<Class<?>> getClassesFromModules() {
+        return ImmutableList.of(Endpoints.class, AddressEndpoints.class, ContainmentEndpoints.class,
+                MacAddressType.class, IpPrefixType.class);
+    }
 
     @Before
     public void init() {
-        dataProvider = mock(DataBroker.class);
+        dataProvider = getDataBroker();
         baseEndpointRendererAugmentation = mock(BaseEndpointRendererAugmentation.class);
-        WriteTransaction wt = newWriteTransactionMock();
         RpcProviderRegistry rpcRegistry = mock(RpcProviderRegistry.class);
 
         baseEndpointRpcRegistry = new BaseEndpointRpcRegistry(dataProvider, rpcRegistry);
+
+        NetworkDomainContainment
+            networkDomainContainment =
+            new NetworkDomainContainmentBuilder().setNetworkDomainId(new NetworkDomainId(DOMAIN)).setNetworkDomainType(
+                Subnet.class).build();
+
+        basel3Parent = new ParentEndpointBuilder().setAddress(IP_ADDRESS)
+            .setAddressType(IpPrefixType.class)
+            .setContextId(new ContextId(CONTEXT_ID))
+            .setContextType(L3Context.class)
+            .build();
+
+        basel2Child = new ChildEndpointBuilder().setAddress(MAC_ADDRESS)
+            .setAddressType(MacAddressType.class)
+            .setContextId(new ContextId(CONTEXT_ID))
+            .setContextType(L2FloodDomain.class)
+            .build();
+
+        basel2Ep = new AddressEndpointBuilder().setTimestamp(timestamp)
+            .setContextId(new ContextId(CONTEXT_ID))
+            .setContextType(L2FloodDomain.class)
+            .setTenant(new TenantId(TENANT))
+            .setAddress(MAC_ADDRESS)
+            .setAddressType(MacAddressType.class)
+            .setNetworkContainment(new NetworkContainmentBuilder().setContainment(networkDomainContainment).build())
+            .setTimestamp(timestamp)
+            .setParentEndpointChoice(
+                    new ParentEndpointCaseBuilder().setParentEndpoint(Collections.singletonList(basel3Parent)).build())
+            .build();
+
+        basel3Ep = new AddressEndpointBuilder().setTimestamp(timestamp)
+            .setContextId(new ContextId(CONTEXT_ID))
+            .setContextType(L3Context.class)
+            .setTenant(new TenantId(TENANT))
+            .setAddress(IP_ADDRESS)
+            .setAddressType(IpPrefixType.class)
+            .setNetworkContainment(new NetworkContainmentBuilder().setContainment(networkDomainContainment).build())
+            .setTimestamp(timestamp)
+            .setChildEndpoint(Collections.singletonList(basel2Child))
+            .build();
+
+        baseContainmentEp = new ContainmentEndpointBuilder().setTimestamp(timestamp)
+            .setContextId(new ContextId(CONTEXT_ID))
+            .setContextType(L2FloodDomain.class)
+            .setTenant(new TenantId(TENANT))
+            .setNetworkContainment(new NetworkContainmentBuilder().setContainment(networkDomainContainment).build())
+            .setChildEndpoint(Collections.singletonList(basel2Child))
+            .build();
     }
 
     @Test
@@ -85,60 +179,357 @@ public class BaseEndpointRpcRegistryTest {
 
     @Test
     public void testRegisterEndpoint() throws Exception {
-        WriteTransaction wt = newWriteTransactionMock();
+        RegisterEndpointInput input =
+                createRegisterEndpointInputVariablesForTest(AddressEndpointRegistration.BOTH, AddressEndpointType.BOTH, true);
 
-        baseEndpointRpcRegistry.registerEndpoint(createRegisterEndpointInputVariablesForTest());
+        baseEndpointRpcRegistry.registerEndpoint(input);
 
-        verify(wt, times(2)).put(eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class),
-                any(DataObject.class), eq(true));
+        ReadOnlyTransaction transaction = dataProvider.newReadOnlyTransaction();
+
+        AddressEndpointKey key = new AddressEndpointKey(MAC_ADDRESS, MacAddressType.class, new ContextId(CONTEXT_ID),
+                L2FloodDomain.class);
+        Optional<AddressEndpoint> addressEndpointL2 = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                IidFactory.addressEndpointIid(key), transaction);
+
+        Assert.assertTrue(addressEndpointL2.isPresent());
+
+        if (addressEndpointL2.isPresent()) {
+            Assert.assertEquals(basel2Ep, addressEndpointL2.get());
+        }
+
+        key = new AddressEndpointKey(IP_ADDRESS, IpPrefixType.class, new ContextId(CONTEXT_ID), L3Context.class);
+
+        Optional<AddressEndpoint> addressEndpointL3 = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                IidFactory.addressEndpointIid(key), transaction);
+
+        Assert.assertTrue(addressEndpointL3.isPresent());
+
+        if (addressEndpointL3.isPresent()) {
+            Assert.assertEquals(basel3Ep, addressEndpointL3.get());
+        }
+
+        ContainmentEndpointKey containmentEndpointKey =
+                new ContainmentEndpointKey(new ContextId(CONTEXT_ID), L2FloodDomain.class);
+
+        Optional<ContainmentEndpoint> ContainmentEndpoint = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                IidFactory.containmentEndpointIid(containmentEndpointKey), transaction);
+
+        Assert.assertTrue(ContainmentEndpoint.isPresent());
+
+        if (ContainmentEndpoint.isPresent()) {
+            Assert.assertEquals(baseContainmentEp, ContainmentEndpoint.get());
+        }
     }
 
-    private RegisterEndpointInput createRegisterEndpointInputVariablesForTest() throws Exception {
-        RegisterEndpointInputBuilder registerEndpointInputBuilder = new RegisterEndpointInputBuilder();
-        long timestamp = System.currentTimeMillis();
+    @Test
+    public void testRegisterEndpointWithParentUpdate() throws Exception {
+        setupBasicDataStore();
+        RegisterEndpointInput input =
+                createRegisterEndpointInputVariablesForTest(AddressEndpointRegistration.BOTH, AddressEndpointType.L2, true);
 
-        registerEndpointInputBuilder.setAddressEndpointReg(new ArrayList<>());
-        registerEndpointInputBuilder.setContainmentEndpointReg(new ArrayList<>());
+        baseEndpointRpcRegistry.registerEndpoint(input);
 
-        registerEndpointInputBuilder.getAddressEndpointReg().add(
-                new AddressEndpointRegBuilder().setTimestamp(timestamp)
-                    .setContextId(new ContextId(CONTEXT_ID))
-                    .setContextType(L2FloodDomain.class)
-                    .setTenant(new TenantId(TENANT))
-                    .setAddress(MAC_ADDRESS)
-                    .setAddressType(MacAddressType.class)
-                    .setAddressType(AddressType.class)
-                    .setNetworkContainment(new NetworkContainmentBuilder()
-                        .setNetworkDomainId(new NetworkDomainId(DOMAIN)).setNetworkDomainType(Subnet.class).build())
-                    .setKey(new AddressEndpointRegKey(MAC_ADDRESS,MacAddressType.class, new ContextId(CONTEXT_ID), L2FloodDomain.class))
-                    .setTimestamp(timestamp).build());
-
-        registerEndpointInputBuilder.getContainmentEndpointReg().add(
-                new ContainmentEndpointRegBuilder()
-                    .setTimestamp(timestamp)
-                    .setContextId(new L2FloodDomainId(FLOOD_DOMAIN))
-                    .setContextType(L2FloodDomain.class)
-                    .setTenant(new TenantId(TENANT))
-                    .setNetworkContainment(new NetworkContainmentBuilder()
-                        .setNetworkDomainId(new NetworkDomainId(DOMAIN)).setNetworkDomainType(Subnet.class).build())
-                    .setKey(new ContainmentEndpointRegKey(new L2FloodDomainId(FLOOD_DOMAIN),L2FloodDomain.class))
-                    .build());
+        AddressEndpointKey key = new AddressEndpointKey(MAC_ADDRESS, MacAddressType.class, new ContextId(CONTEXT_ID),
+                L2FloodDomain.class);
+        Optional<AddressEndpoint> addressEndpointL2 = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                IidFactory.addressEndpointIid(key), dataProvider.newReadOnlyTransaction());
 
-        return registerEndpointInputBuilder.build();
+        Assert.assertTrue(addressEndpointL2.isPresent());
+
+        if (addressEndpointL2.isPresent()) {
+            ParentEndpointCase parentEndpointCase =
+                    (ParentEndpointCase) addressEndpointL2.get().getParentEndpointChoice();
+            List<ParentEndpoint> parentEndpoints = parentEndpointCase.getParentEndpoint();
+            Assert.assertEquals(parentEndpoints.size(), 1);
+        }
+
+        key = new AddressEndpointKey(IP_ADDRESS, IpPrefixType.class, new ContextId(CONTEXT_ID), L3Context.class);
+
+        Optional<AddressEndpoint> addressEndpointL3 = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                IidFactory.addressEndpointIid(key), dataProvider.newReadOnlyTransaction());
+
+        Assert.assertTrue(addressEndpointL3.isPresent());
+
+        if (addressEndpointL3.isPresent()) {
+            Assert.assertEquals(addressEndpointL3.get().getChildEndpoint().size(), 1);
+        }
+    }
+
+    @Test
+    public void testRegisterEndpointWithParentUpdateFail() throws Exception {
+        RegisterEndpointInput input = createRegisterEndpointInputVariablesForTest(AddressEndpointRegistration.BOTH,
+                AddressEndpointType.L2, true);
+
+        Future<RpcResult<Void>> rpcResultFuture = baseEndpointRpcRegistry.registerEndpoint(input);
+
+        Assert.assertFalse(rpcResultFuture.get().isSuccessful());
+        Assert.assertNotNull(rpcResultFuture.get().getErrors());
+        Assert.assertEquals(rpcResultFuture.get().getErrors().size(), 1);
+    }
+
+    @Test
+    public void testRegisterEndpointWithChildUpdate() throws Exception {
+        setupBasicDataStore();
+        RegisterEndpointInput input =
+                createRegisterEndpointInputVariablesForTest(AddressEndpointRegistration.BOTH, AddressEndpointType.L3, true);
+
+        baseEndpointRpcRegistry.registerEndpoint(input);
+
+        AddressEndpointKey key = new AddressEndpointKey(MAC_ADDRESS, MacAddressType.class, new ContextId(CONTEXT_ID),
+                L2FloodDomain.class);
+        Optional<AddressEndpoint> addressEndpointL2 = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                IidFactory.addressEndpointIid(key), dataProvider.newReadOnlyTransaction());
+
+        Assert.assertTrue(addressEndpointL2.isPresent());
+
+        if (addressEndpointL2.isPresent()) {
+            ParentEndpointCase parentEndpointCase =
+                    (ParentEndpointCase) addressEndpointL2.get().getParentEndpointChoice();
+            List<ParentEndpoint> parentEndpoints = parentEndpointCase.getParentEndpoint();
+            Assert.assertEquals(parentEndpoints.size(), 1);
+        }
+
+        key = new AddressEndpointKey(IP_ADDRESS, IpPrefixType.class, new ContextId(CONTEXT_ID), L3Context.class);
+
+        Optional<AddressEndpoint> addressEndpointL3 = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                IidFactory.addressEndpointIid(key), dataProvider.newReadOnlyTransaction());
+
+        Assert.assertTrue(addressEndpointL3.isPresent());
+
+        if (addressEndpointL3.isPresent()) {
+            Assert.assertEquals(addressEndpointL3.get().getChildEndpoint().size(), 1);
+        }
+    }
+
+    @Test
+    public void testRegisterEndpointWithChildUpdateFail() throws Exception {
+        RegisterEndpointInput input = createRegisterEndpointInputVariablesForTest(AddressEndpointRegistration.BOTH,
+                AddressEndpointType.L3, true);
+
+        Future<RpcResult<Void>> rpcResultFuture = baseEndpointRpcRegistry.registerEndpoint(input);
+
+        Assert.assertFalse(rpcResultFuture.get().isSuccessful());
+        Assert.assertNotNull(rpcResultFuture.get().getErrors());
+        Assert.assertEquals(rpcResultFuture.get().getErrors().size(), 1);
+    }
+
+    private void setupBasicDataStore() throws Exception {
+        InstanceIdentifier<Endpoints> id = InstanceIdentifier.builder(Endpoints.class).build();
+        dataProvider.newWriteOnlyTransaction().delete(LogicalDatastoreType.OPERATIONAL, id);
+
+        RegisterEndpointInput input =
+                createRegisterEndpointInputVariablesForTest(AddressEndpointRegistration.NONE, AddressEndpointType.BOTH, true);
+
+        baseEndpointRpcRegistry.registerEndpoint(input);
+
+        AddressEndpointKey key = new AddressEndpointKey(MAC_ADDRESS, MacAddressType.class, new ContextId(CONTEXT_ID),
+                L2FloodDomain.class);
+        Optional<AddressEndpoint> addressEndpointL2 = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                IidFactory.addressEndpointIid(key), dataProvider.newReadOnlyTransaction());
+
+        Assert.assertTrue(addressEndpointL2.isPresent());
+
+        if (addressEndpointL2.isPresent()) {
+            ParentEndpointCase parentEndpointCase =
+                    (ParentEndpointCase) addressEndpointL2.get().getParentEndpointChoice();
+            Assert.assertEquals(parentEndpointCase.getParentEndpoint().size(), 0);
+        }
+
+        key = new AddressEndpointKey(IP_ADDRESS, IpPrefixType.class, new ContextId(CONTEXT_ID), L3Context.class);
+
+        Optional<AddressEndpoint> addressEndpointL3 = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                IidFactory.addressEndpointIid(key), dataProvider.newReadOnlyTransaction());
+
+        Assert.assertTrue(addressEndpointL3.isPresent());
+
+        if (addressEndpointL3.isPresent()) {
+            Assert.assertEquals(addressEndpointL3.get().getChildEndpoint().size(), 0);
+        }
     }
 
     @Test
-    public void testUnregisterEndpoint() throws Exception {
-        WriteTransaction wt = newWriteTransactionMock();
+    public void testRegisterEndpointParentFail() throws Exception {
+        Future<RpcResult<Void>> rpcResultFuture =
+                baseEndpointRpcRegistry.registerEndpoint(createRegisterEndpointInputVariablesForTest(
+                        AddressEndpointRegistration.PARENT, AddressEndpointType.BOTH, true));
+
+        RpcResult<Void> rpcResult = rpcResultFuture.get();
+
+        Assert.assertFalse(rpcResult.isSuccessful());
+        Assert.assertNull(rpcResult.getResult());
+        Assert.assertEquals(rpcResult.getErrors().size(), 1);
+
+    }
+
+    @Test
+    public void testRegisterEndpointChildFail() throws Exception {
+        Future<RpcResult<Void>> rpcResultFuture =
+                baseEndpointRpcRegistry.registerEndpoint(createRegisterEndpointInputVariablesForTest(
+                        AddressEndpointRegistration.CHILD, AddressEndpointType.BOTH, true));
+
+        RpcResult<Void> rpcResult = rpcResultFuture.get();
+
+        Assert.assertFalse(rpcResult.isSuccessful());
+        Assert.assertNull(rpcResult.getResult());
+        Assert.assertEquals(rpcResult.getErrors().size(), 1);
+    }
+
+    @Test
+    public void testUnregisterEndpointWithParent() throws Exception {
+        RegisterEndpointInput input =
+                createRegisterEndpointInputVariablesForTest(AddressEndpointRegistration.BOTH, AddressEndpointType.BOTH, true);
+
+        baseEndpointRpcRegistry.registerEndpoint(input);
 
-        UnregisterEndpointInput unregisterEndpointInput = unregisterEndpointInput();
+        AddressEndpointKey key = new AddressEndpointKey(MAC_ADDRESS, MacAddressType.class, new ContextId(CONTEXT_ID),
+                L2FloodDomain.class);
+        ContainmentEndpointKey cKey = new ContainmentEndpointKey(new ContextId(CONTEXT_ID), L2FloodDomain.class);
 
-        baseEndpointRpcRegistry.unregisterEndpoint(unregisterEndpointInput);
+        Optional<AddressEndpoint> addressEndpointL2 = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                IidFactory.addressEndpointIid(key), dataProvider.newReadOnlyTransaction());
 
-        verify(wt, times(2)).delete(eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class));
+        Assert.assertTrue(addressEndpointL2.isPresent());
+
+        if (addressEndpointL2.isPresent()) {
+            Assert.assertEquals(basel2Ep, addressEndpointL2.get());
+        }
+
+        Optional<ContainmentEndpoint> ContainmentEndpoint = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                IidFactory.containmentEndpointIid(cKey), dataProvider.newReadOnlyTransaction());
+
+        Assert.assertTrue(ContainmentEndpoint.isPresent());
+
+        if (ContainmentEndpoint.isPresent()) {
+            Assert.assertEquals(baseContainmentEp, ContainmentEndpoint.get());
+        }
+
+        baseEndpointRpcRegistry.unregisterEndpoint(unregisterEndpointInputParent());
+        Optional<AddressEndpoint> endpointOptional = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                IidFactory.addressEndpointIid(key), dataProvider.newReadOnlyTransaction());
+
+        Assert.assertFalse(endpointOptional.isPresent());
+
+        Optional<ContainmentEndpoint> containmentEndpointOptional =
+                DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, IidFactory.containmentEndpointIid(cKey),
+                        dataProvider.newReadOnlyTransaction());
+
+        Assert.assertFalse(containmentEndpointOptional.isPresent());
     }
 
-    private UnregisterEndpointInput unregisterEndpointInput() {
+    @Test
+    public void testUnregisterEndpointWithChild() throws Exception {
+        RegisterEndpointInput input =
+                createRegisterEndpointInputVariablesForTest(AddressEndpointRegistration.BOTH, AddressEndpointType.BOTH, true);
+
+        baseEndpointRpcRegistry.registerEndpoint(input);
+
+        AddressEndpointKey key =
+                new AddressEndpointKey(IP_ADDRESS, IpPrefixType.class, new ContextId(CONTEXT_ID), L3Context.class);
+
+        Optional<AddressEndpoint> addressEndpointL3 = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                IidFactory.addressEndpointIid(key), dataProvider.newReadOnlyTransaction());
+
+        Assert.assertTrue(addressEndpointL3.isPresent());
+
+        if (addressEndpointL3.isPresent()) {
+            Assert.assertEquals(basel3Ep, addressEndpointL3.get());
+        }
+
+        baseEndpointRpcRegistry.unregisterEndpoint(unregisterEndpointInputChild());
+        Optional<AddressEndpoint> endpointOptional = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                IidFactory.addressEndpointIid(key), dataProvider.newReadOnlyTransaction());
+
+        Assert.assertFalse(endpointOptional.isPresent());
+
+    }
+
+    @Test
+    public void testRegisterContainmentEndpointWithChildFail() throws Exception {
+        Future<RpcResult<Void>> rpcResultFuture =
+                baseEndpointRpcRegistry.registerEndpoint(createRegisterEndpointInputVariablesForTest(
+                        AddressEndpointRegistration.NONE, AddressEndpointType.NONE, true));
+
+        RpcResult<Void> rpcResult = rpcResultFuture.get();
+
+        Assert.assertFalse(rpcResult.isSuccessful());
+        Assert.assertNull(rpcResult.getResult());
+        Assert.assertEquals(rpcResult.getErrors().size(), 1);
+    }
+
+    @Test
+    public void testUnregisterContainmentEndpointWithChild() throws Exception {
+        InstanceIdentifier<Endpoints> id = InstanceIdentifier.builder(Endpoints.class).build();
+        dataProvider.newWriteOnlyTransaction().delete(LogicalDatastoreType.OPERATIONAL, id);
+
+        RegisterEndpointInput input =
+            createRegisterEndpointInputVariablesForTest(AddressEndpointRegistration.NONE, AddressEndpointType.L2, false);
+
+        baseEndpointRpcRegistry.registerEndpoint(input);
+
+        AddressEndpointKey key = new AddressEndpointKey(MAC_ADDRESS, MacAddressType.class, new ContextId(CONTEXT_ID),
+            L2FloodDomain.class);
+
+        Optional<AddressEndpoint> addressEndpointL2 = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+            IidFactory.addressEndpointIid(key), dataProvider.newReadOnlyTransaction());
+
+        Assert.assertTrue(addressEndpointL2.isPresent());
+        if (addressEndpointL2.isPresent()){
+            ParentEndpointChoice parentEndpointChoice = addressEndpointL2.get().getParentEndpointChoice();
+            if(parentEndpointChoice instanceof ParentContainmentEndpointCase){
+                ParentContainmentEndpointCase
+                    parentEndpointCase = (ParentContainmentEndpointCase) parentEndpointChoice;
+                Assert.assertNull(parentEndpointCase.getParentContainmentEndpoint());
+            }
+        }
+
+        ContainmentEndpointReg containmentEndpointReg = new ContainmentEndpointRegBuilder().setTimestamp(baseContainmentEp.getTimestamp())
+            .setContextId(baseContainmentEp.getContextId())
+            .setContextType(baseContainmentEp.getContextType())
+            .setTenant(baseContainmentEp.getTenant())
+            .setNetworkContainment(baseContainmentEp.getNetworkContainment())
+            .setChildEndpoint(Collections.singletonList(basel2Child))
+            .build();
+
+        baseEndpointRpcRegistry.registerEndpoint(new RegisterEndpointInputBuilder().setContainmentEndpointReg(Collections.singletonList(containmentEndpointReg)).build());
+
+        addressEndpointL2 = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+            IidFactory.addressEndpointIid(key), dataProvider.newReadOnlyTransaction());
+
+        Assert.assertTrue(addressEndpointL2.isPresent());
+        if (addressEndpointL2.isPresent()) {
+            ParentEndpointChoice parentEndpointChoice = addressEndpointL2.get().getParentEndpointChoice();
+            if(parentEndpointChoice instanceof ParentContainmentEndpointCase){
+                ParentContainmentEndpointCase
+                    parentEndpointCase = (ParentContainmentEndpointCase) parentEndpointChoice;
+                Assert.assertNotNull(parentEndpointCase.getParentContainmentEndpoint());
+                Assert.assertEquals(parentEndpointCase.getParentContainmentEndpoint().size(),1);
+            }
+        }
+
+        ContainmentEndpointUnreg containmentEndpointUnreg = new ContainmentEndpointUnregBuilder()
+            .setContextId(baseContainmentEp.getContextId())
+            .setContextType(baseContainmentEp.getContextType())
+            .build();
+
+        baseEndpointRpcRegistry.unregisterEndpoint(new UnregisterEndpointInputBuilder().setContainmentEndpointUnreg(Collections.singletonList(containmentEndpointUnreg)).build());
+
+        addressEndpointL2 = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+            IidFactory.addressEndpointIid(key), dataProvider.newReadOnlyTransaction());
+
+        Assert.assertTrue(addressEndpointL2.isPresent());
+        if (addressEndpointL2.isPresent()) {
+            ParentEndpointChoice parentEndpointChoice = addressEndpointL2.get().getParentEndpointChoice();
+            if(parentEndpointChoice instanceof ParentContainmentEndpointCase){
+                ParentContainmentEndpointCase
+                    parentEndpointCase = (ParentContainmentEndpointCase) parentEndpointChoice;
+                Assert.assertNotNull(parentEndpointCase.getParentContainmentEndpoint());
+                Assert.assertEquals(parentEndpointCase.getParentContainmentEndpoint().size(),0);
+            }
+        }
+
+    }
+
+    private UnregisterEndpointInput unregisterEndpointInputParent() {
         UnregisterEndpointInputBuilder builder = new UnregisterEndpointInputBuilder();
 
         builder.setAddressEndpointUnreg(new ArrayList<>());
@@ -156,13 +547,77 @@ public class BaseEndpointRpcRegistryTest {
         return builder.build();
     }
 
-    private WriteTransaction newWriteTransactionMock() {
-        WriteTransaction wt = mock(WriteTransaction.class);
-        CheckedFuture<Void, TransactionCommitFailedException> f = mock(CheckedFuture.class);
+    private UnregisterEndpointInput unregisterEndpointInputChild() {
+        UnregisterEndpointInputBuilder builder = new UnregisterEndpointInputBuilder();
+
+        builder.setAddressEndpointUnreg(new ArrayList<>());
+        builder.setContainmentEndpointUnreg(new ArrayList<>());
 
-        when(dataProvider.newWriteOnlyTransaction()).thenReturn(wt);
-        when(wt.submit()).thenReturn(f);
-        return wt;
+        builder.getAddressEndpointUnreg().add(new AddressEndpointUnregBuilder().setContextId(new ContextId(CONTEXT_ID))
+            .setContextType(L3Context.class)
+            .setAddress(IP_ADDRESS)
+            .setAddressType(IpPrefixType.class)
+            .build());
+
+        return builder.build();
     }
 
+    private RegisterEndpointInput createRegisterEndpointInputVariablesForTest(AddressEndpointRegistration registration,
+            AddressEndpointType type, boolean containmentEpPresent) throws Exception {
+        RegisterEndpointInputBuilder registerEndpointInputBuilder = new RegisterEndpointInputBuilder();
+        long timestamp = System.currentTimeMillis();
+
+        List<ParentEndpoint> parentEndpoints = new ArrayList<>();
+        if (registration == AddressEndpointRegistration.BOTH || registration == AddressEndpointRegistration.PARENT) {
+            parentEndpoints.add(basel3Parent);
+        }
+
+        List<ChildEndpoint> childEndpoints = new ArrayList<>();
+        if (registration == AddressEndpointRegistration.BOTH || registration == AddressEndpointRegistration.CHILD) {
+            childEndpoints.add(basel2Child);
+        }
+
+        registerEndpointInputBuilder.setAddressEndpointReg(new ArrayList<>());
+        registerEndpointInputBuilder.setContainmentEndpointReg(new ArrayList<>());
+
+        if (type == AddressEndpointType.BOTH || type == AddressEndpointType.L2) {
+            registerEndpointInputBuilder.getAddressEndpointReg()
+                .add(new AddressEndpointRegBuilder().setTimestamp(timestamp)
+                    .setContextId(basel2Ep.getContextId())
+                    .setContextType(basel2Ep.getContextType())
+                    .setTenant(basel2Ep.getTenant())
+                    .setAddress(basel2Ep.getAddress())
+                    .setAddressType(basel2Ep.getAddressType())
+                    .setNetworkContainment(basel2Ep.getNetworkContainment())
+                    .setTimestamp(basel2Ep.getTimestamp())
+                    .setParentEndpointChoice(new ParentEndpointCaseBuilder().setParentEndpoint(parentEndpoints).build())
+                    .build());
+        }
+
+        if (type == AddressEndpointType.BOTH || type == AddressEndpointType.L3) {
+            registerEndpointInputBuilder.getAddressEndpointReg()
+                .add(new AddressEndpointRegBuilder().setContextId(basel3Ep.getContextId())
+                    .setContextType(basel3Ep.getContextType())
+                    .setTenant(basel3Ep.getTenant())
+                    .setAddress(basel3Ep.getAddress())
+                    .setAddressType(basel3Ep.getAddressType())
+                    .setNetworkContainment(basel3Ep.getNetworkContainment())
+                    .setTimestamp(basel3Ep.getTimestamp())
+                    .setChildEndpoint(childEndpoints)
+                    .build());
+        }
+
+        if(containmentEpPresent) {
+            registerEndpointInputBuilder.getContainmentEndpointReg()
+                .add(new ContainmentEndpointRegBuilder().setTimestamp(baseContainmentEp.getTimestamp())
+                    .setContextId(baseContainmentEp.getContextId())
+                    .setContextType(baseContainmentEp.getContextType())
+                    .setTenant(baseContainmentEp.getTenant())
+                    .setNetworkContainment(baseContainmentEp.getNetworkContainment())
+                    .setChildEndpoint(Collections.singletonList(basel2Child))
+                    .build());
+        }
+
+        return registerEndpointInputBuilder.build();
+    }
 }
diff --git a/groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/location/resolver/LocationResolverTest.java b/groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/location/resolver/LocationResolverTest.java
new file mode 100644 (file)
index 0000000..7e8c5ef
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.location.resolver;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.test.CustomDataBrokerTest;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.EndpointLocations;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocationKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.ContainmentEndpointLocationKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.InternalLocationCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.RelativeLocations;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.RelativeLocationsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.InternalLocationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.LocationProviders;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.ProviderName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.LocationProvider;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.LocationProviderBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.LocationProviderKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocationKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderContainmentEndpointLocationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+
+public class LocationResolverTest extends CustomDataBrokerTest {
+
+    private final String PROVIDER_NAME = "location-provider";
+    private final String ADDRESS = "192.168.50.20/24";
+    private final String NODE_1 = "node1";
+    private final String NODE_2 = "node2";
+    private final String NODE_CONNNECTOR = "connector";
+    private final ContextId contextId = new ContextId("context");
+
+    private InstanceIdentifier<Node> nodeIid1 =
+            InstanceIdentifier.builder(Nodes.class).child(Node.class, new NodeKey(new NodeId(NODE_1))).build();
+    private InstanceIdentifier<Node> nodeIid2 =
+            InstanceIdentifier.builder(Nodes.class).child(Node.class, new NodeKey(new NodeId(NODE_2))).build();
+    private InstanceIdentifier<NodeConnector> connectorIid = InstanceIdentifier.builder(Nodes.class)
+        .child(Node.class, new NodeKey(new NodeId(NODE_1)))
+        .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId(NODE_CONNNECTOR)))
+        .build();
+    private DataBroker dataBroker;
+    private LocationResolver resolver;
+
+    @Before
+    public void init() {
+        dataBroker = getDataBroker();
+        resolver = new LocationResolver(dataBroker);
+    }
+
+    @Override
+    public Collection<Class<?>> getClassesFromModules() {
+        return ImmutableList.<Class<?>>of(LocationProvider.class, Nodes.class, L3Context.class,
+                EndpointLocations.class);
+    }
+
+    @Test
+    public void test_LocationProviderWrite() throws Exception {
+        AbsoluteLocation absoluteLocation =
+                new AbsoluteLocationBuilder().setLocationType(new InternalLocationCaseBuilder()
+                    .setInternalNode(nodeIid1).setInternalNodeConnector(connectorIid).build()).build();
+        RelativeLocations relativeLocations = new RelativeLocationsBuilder()
+            .setInternalLocation(Collections.singletonList(new InternalLocationBuilder().setInternalNode(nodeIid1)
+                .setInternalNodeConnector(connectorIid)
+                .build()))
+            .build();
+        LocationProvider provider = new LocationProviderBuilder().setProvider(new ProviderName(PROVIDER_NAME))
+            .setProviderAddressEndpointLocation(
+                    Collections.singletonList(new ProviderAddressEndpointLocationBuilder()
+                        .setKey(new ProviderAddressEndpointLocationKey(ADDRESS, IpPrefixType.class, contextId,
+                                L3Context.class))
+                        .setAbsoluteLocation(absoluteLocation)
+                        .setRelativeLocations(relativeLocations)
+                        .build()))
+            .setProviderContainmentEndpointLocation(
+                    Collections.singletonList(new ProviderContainmentEndpointLocationBuilder().setContextId(contextId)
+                        .setContextType(L3Context.class)
+                        .setRelativeLocations(relativeLocations)
+                        .build()))
+            .build();
+        InstanceIdentifier<LocationProvider> iid = InstanceIdentifier.builder(LocationProviders.class)
+            .child(LocationProvider.class, provider.getKey())
+            .build();
+        WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
+        wtx.put(LogicalDatastoreType.OPERATIONAL, iid, provider);
+        wtx.submit().get();
+
+        ReadOnlyTransaction rtx = dataBroker.newReadOnlyTransaction();
+        InstanceIdentifier<EndpointLocations> readIid = InstanceIdentifier.builder(EndpointLocations.class).build();
+        Optional<EndpointLocations> read = rtx.read(LogicalDatastoreType.OPERATIONAL, readIid).get();
+        assertTrue(read.isPresent());
+        EndpointLocations readLocations = read.get();
+        assertNotNull(readLocations.getAddressEndpointLocation());
+        assertEquals(1, readLocations.getAddressEndpointLocation().size());
+        assertEquals(new AddressEndpointLocationKey(ADDRESS, IpPrefixType.class, contextId, L3Context.class),
+                readLocations.getAddressEndpointLocation().get(0).getKey());
+        assertEquals(absoluteLocation, readLocations.getAddressEndpointLocation().get(0).getAbsoluteLocation());
+        assertNotNull(readLocations.getContainmentEndpointLocation());
+        assertEquals(1, readLocations.getContainmentEndpointLocation().size());
+        assertEquals(new ContainmentEndpointLocationKey(contextId, L3Context.class),
+                readLocations.getContainmentEndpointLocation().get(0).getKey());
+        assertEquals(relativeLocations, readLocations.getContainmentEndpointLocation().get(0).getRelativeLocations());
+    }
+
+    @Test
+    public void test_LocationProviderOverWrite() throws Exception {
+        test_LocationProviderWrite();
+        AbsoluteLocation absoluteLocation =
+                new AbsoluteLocationBuilder().setLocationType(new InternalLocationCaseBuilder()
+                    .setInternalNode(nodeIid2).setInternalNodeConnector(connectorIid).build()).build();
+        RelativeLocations relativeLocations = new RelativeLocationsBuilder()
+            .setInternalLocation(Collections.singletonList(new InternalLocationBuilder().setInternalNode(nodeIid2)
+                .setInternalNodeConnector(connectorIid)
+                .build()))
+            .build();
+        LocationProvider provider = new LocationProviderBuilder().setProvider(new ProviderName(PROVIDER_NAME))
+            .setProviderAddressEndpointLocation(
+                    Collections.singletonList(new ProviderAddressEndpointLocationBuilder()
+                        .setKey(new ProviderAddressEndpointLocationKey(ADDRESS, IpPrefixType.class, contextId,
+                                L3Context.class))
+                        .setAbsoluteLocation(absoluteLocation)
+                        .setRelativeLocations(relativeLocations)
+                        .build()))
+            .setProviderContainmentEndpointLocation(
+                    Collections.singletonList(new ProviderContainmentEndpointLocationBuilder().setContextId(contextId)
+                        .setContextType(L3Context.class)
+                        .setRelativeLocations(relativeLocations)
+                        .build()))
+            .build();
+        InstanceIdentifier<LocationProvider> iid = InstanceIdentifier.builder(LocationProviders.class)
+            .child(LocationProvider.class, provider.getKey())
+            .build();
+        WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
+        wtx.put(LogicalDatastoreType.OPERATIONAL, iid, provider);
+        wtx.submit().get();
+
+        ReadOnlyTransaction rtx = dataBroker.newReadOnlyTransaction();
+        InstanceIdentifier<EndpointLocations> readIid = InstanceIdentifier.builder(EndpointLocations.class).build();
+        Optional<EndpointLocations> read = rtx.read(LogicalDatastoreType.OPERATIONAL, readIid).get();
+        assertTrue(read.isPresent());
+        EndpointLocations readLocations = read.get();
+        assertNotNull(readLocations.getAddressEndpointLocation());
+        assertEquals(1, readLocations.getAddressEndpointLocation().size());
+        assertEquals(new AddressEndpointLocationKey(ADDRESS, IpPrefixType.class, contextId, L3Context.class),
+                readLocations.getAddressEndpointLocation().get(0).getKey());
+        assertEquals(absoluteLocation, readLocations.getAddressEndpointLocation().get(0).getAbsoluteLocation());
+        assertNotNull(readLocations.getContainmentEndpointLocation());
+        assertEquals(1, readLocations.getContainmentEndpointLocation().size());
+        assertEquals(new ContainmentEndpointLocationKey(contextId, L3Context.class),
+                readLocations.getContainmentEndpointLocation().get(0).getKey());
+        assertEquals(relativeLocations, readLocations.getContainmentEndpointLocation().get(0).getRelativeLocations());
+    }
+
+    @Test
+    public void test_LocationProviderDelete() throws Exception {
+        test_LocationProviderWrite();
+        InstanceIdentifier<LocationProvider> iid = InstanceIdentifier.builder(LocationProviders.class)
+            .child(LocationProvider.class, new LocationProviderKey(new ProviderName(PROVIDER_NAME)))
+            .build();
+        WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
+        wtx.delete(LogicalDatastoreType.OPERATIONAL, iid);
+        wtx.submit().get();
+
+        ReadOnlyTransaction rtx = dataBroker.newReadOnlyTransaction();
+        InstanceIdentifier<EndpointLocations> readIid = InstanceIdentifier.builder(EndpointLocations.class).build();
+        Optional<EndpointLocations> read = rtx.read(LogicalDatastoreType.OPERATIONAL, readIid).get();
+        assertTrue(read.isPresent());
+        EndpointLocations readLocations = read.get();
+        assertEquals(1, readLocations.getAddressEndpointLocation().size());
+        assertNull(readLocations.getAddressEndpointLocation().get(0).getAbsoluteLocation());
+        assertTrue(readLocations.getAddressEndpointLocation()
+            .get(0)
+            .getRelativeLocations()
+            .getInternalLocation()
+            .isEmpty());
+        assertNull(readLocations.getAddressEndpointLocation().get(0).getRelativeLocations().getExternalLocation());
+        assertEquals(1, readLocations.getContainmentEndpointLocation().size());
+        assertTrue(readLocations.getAddressEndpointLocation()
+            .get(0)
+            .getRelativeLocations()
+            .getInternalLocation()
+            .isEmpty());
+        assertNull(readLocations.getAddressEndpointLocation().get(0).getRelativeLocations().getExternalLocation());
+    }
+
+    @Test
+    public void test_LocationProviderModify() throws Exception {
+        test_LocationProviderWrite();
+        AbsoluteLocation absoluteLocation =
+                new AbsoluteLocationBuilder().setLocationType(new InternalLocationCaseBuilder()
+                    .setInternalNode(nodeIid2).setInternalNodeConnector(connectorIid).build()).build();
+        InstanceIdentifier<AbsoluteLocation> iid = InstanceIdentifier.builder(LocationProviders.class)
+            .child(LocationProvider.class, new LocationProviderKey(new ProviderName(PROVIDER_NAME)))
+            .child(ProviderAddressEndpointLocation.class,
+                    new ProviderAddressEndpointLocationKey(ADDRESS, IpPrefixType.class, contextId, L3Context.class))
+            .child(AbsoluteLocation.class)
+            .build();
+        WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
+        wtx.put(LogicalDatastoreType.OPERATIONAL, iid, absoluteLocation);
+        wtx.submit().get();
+
+        ReadOnlyTransaction rtx = dataBroker.newReadOnlyTransaction();
+        InstanceIdentifier<EndpointLocations> readIid = InstanceIdentifier.builder(EndpointLocations.class).build();
+        Optional<EndpointLocations> read = rtx.read(LogicalDatastoreType.OPERATIONAL, readIid).get();
+        assertTrue(read.isPresent());
+        EndpointLocations readLocations = read.get();
+        assertNotNull(readLocations.getAddressEndpointLocation());
+        assertEquals(1, readLocations.getAddressEndpointLocation().size());
+        assertEquals(new AddressEndpointLocationKey(ADDRESS, IpPrefixType.class, contextId, L3Context.class),
+                readLocations.getAddressEndpointLocation().get(0).getKey());
+        assertEquals(absoluteLocation, readLocations.getAddressEndpointLocation().get(0).getAbsoluteLocation());
+    }
+}
diff --git a/groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/renderer/RendererManagerDataBrokerTest.java b/groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/renderer/RendererManagerDataBrokerTest.java
new file mode 100644 (file)
index 0000000..1fde0ca
--- /dev/null
@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.renderer;
+
+import java.util.Arrays;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.EndpointLocations;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.EndpointLocationsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.EndpointsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.ContainmentEndpointLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.AddressEndpointsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.ContainmentEndpointsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.InternalLocationCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.InternalLocationCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.InternalLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.InternalLocationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RuleName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.ForwardingBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.ForwardingByTenantBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.with.tenant.fields.ForwardingContextBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Tenants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RenderersBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.RendererBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererNodesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.Endpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.ForwardingContexts;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RendererEndpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RuleGroups;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPolicies;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPoliciesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRule;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicy.ExternalImplicitGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.policy.rule.group.with.endpoint.constraints.PolicyRuleGroup;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.CheckedFuture;
+
+@RunWith(MockitoJUnitRunner.class)
+public class RendererManagerDataBrokerTest {
+
+    private static final RendererName RENDERER_NAME_R1 = new RendererName("R1");
+    private static final EndpointGroupId EPG_BLUE = new EndpointGroupId("blue_epg");
+    private static final EndpointGroupId EPG_PURPLE = new EndpointGroupId("purple_epg");
+    private static final ContractId CONTRACT_1 = new ContractId("contract_1");
+    private static final SubjectName SUBJECT_1 = new SubjectName("subject_1");
+    private static final RuleName RULE_1 = new RuleName("rule_1");
+    private static final String ADR_1 = "adr_1";
+    private static final String ADR_2 = "adr_2";
+    private static final InstanceIdentifier<?> NODE_PATH_1 = InstanceIdentifier.create(Tenants.class);
+    private static final InternalLocationCase INT_LOC_CASE_NODE_PATH_1 =
+            new InternalLocationCaseBuilder().setInternalNode(NODE_PATH_1).build();
+    private static final InternalLocation INT_LOC_NODE_PATH_1 =
+            new InternalLocationBuilder().setInternalNode(NODE_PATH_1).build();
+    private static final ExternalLocationCase EXT_LOC_CASE_NODE_PATH_1 =
+            new ExternalLocationCaseBuilder().setExternalNodeMountPoint(NODE_PATH_1).build();
+
+    @Mock
+    private DataBroker dataProvider;
+    @Mock
+    private WriteTransaction wTx;
+    @Mock
+    private CheckedFuture<Void, TransactionCommitFailedException> submitFuture;
+
+    private RendererManager rendererManager;
+
+    @Before
+    public void init() {
+        Mockito.when(dataProvider.newWriteOnlyTransaction()).thenReturn(wTx);
+        Mockito.when(wTx.submit()).thenReturn(submitFuture);
+        rendererManager = new RendererManager(dataProvider);
+        RendererManager.resetVersion();
+    }
+
+    /**
+     * EP1--EPG_BLUE---SUBJECT_1---(P)EPG_PURPLE--EP2
+     */
+    @Test
+    public void testProcessState_dispatchOnePolicy_rendererFeedbackPositive() throws Exception {
+        ArgumentCaptor<Renderers> acRenderers = ArgumentCaptor.forClass(Renderers.class);
+        ResolvedRule rule1 = TestDataFactory.defaultResolvedRule(RULE_1).build();
+        PolicyRuleGroup ruleGrp1 = TestDataFactory.defaultPolicyRuleGrp(CONTRACT_1, SUBJECT_1, rule1).build();
+        ResolvedPolicy resolvedPolicy = TestDataFactory.defaultResolvedPolicy(EPG_BLUE, EPG_PURPLE, ruleGrp1).build();
+        ResolvedPolicies resolvedPolicies =
+                new ResolvedPoliciesBuilder().setResolvedPolicy(ImmutableList.of(resolvedPolicy)).build();
+        rendererManager.resolvedPoliciesUpdated(resolvedPolicies);
+
+        AddressEndpoint ep1 = TestDataFactory.defaultAdrEp(ADR_1, EPG_BLUE).build();
+        AddressEndpoint ep2 = TestDataFactory.defaultAdrEp(ADR_2, EPG_PURPLE).build();
+        rendererManager.endpointsUpdated(new EndpointsBuilder()
+            .setAddressEndpoints(new AddressEndpointsBuilder().setAddressEndpoint(ImmutableList.of(ep1, ep2)).build())
+            .build());
+
+        AddressEndpointLocation ep1Loc =
+                TestDataFactory.defaultAdrEpLoc(ep1.getKey(), INT_LOC_CASE_NODE_PATH_1).build();
+        AddressEndpointLocation ep2Loc =
+                TestDataFactory.defaultAdrEpLoc(ep2.getKey(), INT_LOC_CASE_NODE_PATH_1).build();
+        EndpointLocations endpointLocations =
+                new EndpointLocationsBuilder().setAddressEndpointLocation(ImmutableList.of(ep1Loc, ep2Loc)).build();
+        rendererManager.endpointLocationsUpdated(endpointLocations);
+
+        rendererManager
+            .forwardingUpdated(new ForwardingBuilder()
+                .setForwardingByTenant(
+                        Arrays.asList(new ForwardingByTenantBuilder().setTenantId(TestDataFactory.TENANT_ID)
+                            .setForwardingContext(Arrays.asList(new ForwardingContextBuilder()
+                                .setContextType(TestDataFactory.DummyContextType.class)
+                                .setContextId(TestDataFactory.CTX_1)
+                                .build()))
+                            .build()))
+                .build());
+
+        rendererManager.renderersUpdated(new RenderersBuilder()
+            .setRenderer(Arrays.asList(new RendererBuilder().setName(RENDERER_NAME_R1)
+                .setRendererNodes(new RendererNodesBuilder()
+                    .setRendererNode(Arrays.asList(new RendererNodeBuilder().setNodePath(NODE_PATH_1).build())).build())
+                .build()))
+            .build());
+
+        // assert dispatch one policy
+        Assert.assertEquals(1, rendererManager.getProcessingRenderers().size());
+        Mockito.verify(wTx).put(Mockito.eq(LogicalDatastoreType.CONFIGURATION),
+                Mockito.eq(InstanceIdentifier.create(Renderers.class)),
+                acRenderers.capture());
+
+        Renderers renderers = acRenderers.getValue();
+        Assert.assertNotNull(renderers);
+        Assert.assertNotNull(renderers.getRenderer());
+        Assert.assertEquals(1, renderers.getRenderer().size());
+        Renderer renderer = renderers.getRenderer().get(0);
+        Assert.assertEquals(RENDERER_NAME_R1, renderer.getName());
+        RendererPolicy rendererPolicy = renderer.getRendererPolicy();
+        Assert.assertNotNull(rendererPolicy);
+        Assert.assertEquals(1, rendererPolicy.getVersion().longValue());
+
+        Configuration configuration = rendererPolicy.getConfiguration();
+        Assert.assertNotNull(configuration);
+        RendererEndpoints rendererEndpoints = configuration.getRendererEndpoints();
+        Assert.assertNotNull(rendererEndpoints);
+        Assert.assertEquals(2, rendererEndpoints.getRendererEndpoint().size());
+
+        ForwardingContexts forwardingContexts = configuration.getForwardingContexts();
+        Assert.assertNotNull(forwardingContexts);
+        Assert.assertEquals(1, forwardingContexts.getForwardingContextByTenant().size());
+
+        Endpoints endpoints = configuration.getEndpoints();
+        Assert.assertNotNull(endpoints);
+        Assert.assertEquals(2, endpoints.getAddressEndpointWithLocation().size());
+
+        RuleGroups ruleGroups = configuration.getRuleGroups();
+        Assert.assertNotNull(ruleGroups);
+        Assert.assertEquals(1, ruleGroups.getRuleGroup().size());
+
+        rendererManager
+            .renderersUpdated(
+                    new RenderersBuilder()
+                        .setRenderer(
+                                Arrays.asList(new RendererBuilder().setName(RENDERER_NAME_R1)
+                                    .setRendererNodes(new RendererNodesBuilder()
+                                        .setRendererNode(Arrays
+                                            .asList(new RendererNodeBuilder().setNodePath(NODE_PATH_1).build()))
+                                        .build())
+                                    .setRendererPolicy(new RendererPolicyBuilder().setVersion(1L).build())
+                                    .build()))
+                        .build());
+        Assert.assertEquals(0, rendererManager.getProcessingRenderers().size());
+    }
+
+    /**
+     * EP1--EPG_BLUE---SUBJECT_1---(P)EPG_PURPLE(EIG)--EP2(containment)
+     */
+    @Test
+    public void testProcessState_dispatchOneExternalPolicyWithContainmentEp_noRendererFeedback() throws Exception {
+        ArgumentCaptor<Renderers> acRenderers = ArgumentCaptor.forClass(Renderers.class);
+        ResolvedRule rule1 = TestDataFactory.defaultResolvedRule(RULE_1).build();
+        PolicyRuleGroup ruleGrp1 = TestDataFactory.defaultPolicyRuleGrp(CONTRACT_1, SUBJECT_1, rule1).build();
+        ResolvedPolicy resolvedPolicy = TestDataFactory.defaultResolvedPolicy(EPG_BLUE, EPG_PURPLE, ruleGrp1)
+            .setExternalImplicitGroup(ExternalImplicitGroup.ProviderEpg)
+            .build();
+        ResolvedPolicies resolvedPolicies =
+                new ResolvedPoliciesBuilder().setResolvedPolicy(ImmutableList.of(resolvedPolicy)).build();
+        rendererManager.resolvedPoliciesUpdated(resolvedPolicies);
+
+        AddressEndpoint ep1 = TestDataFactory.defaultAdrEp(ADR_1, EPG_BLUE).build();
+        ContainmentEndpoint ep2 = TestDataFactory.defaultContEp(EPG_PURPLE).build();
+        rendererManager
+            .endpointsUpdated(new EndpointsBuilder()
+                .setAddressEndpoints(new AddressEndpointsBuilder().setAddressEndpoint(ImmutableList.of(ep1)).build())
+                .setContainmentEndpoints(
+                        new ContainmentEndpointsBuilder().setContainmentEndpoint(ImmutableList.of(ep2)).build())
+                .build());
+
+        AddressEndpointLocation ep1Loc =
+                TestDataFactory.defaultAdrEpLoc(ep1.getKey(), INT_LOC_CASE_NODE_PATH_1).build();
+        ContainmentEndpointLocation ep2Loc =
+                TestDataFactory.defaultContEpLoc(ep2.getKey(), INT_LOC_NODE_PATH_1).build();
+        EndpointLocations endpointLocations =
+                new EndpointLocationsBuilder().setAddressEndpointLocation(ImmutableList.of(ep1Loc))
+                    .setContainmentEndpointLocation(ImmutableList.of(ep2Loc))
+                    .build();
+        rendererManager.endpointLocationsUpdated(endpointLocations);
+
+        rendererManager
+            .forwardingUpdated(new ForwardingBuilder()
+                .setForwardingByTenant(
+                        Arrays.asList(new ForwardingByTenantBuilder().setTenantId(TestDataFactory.TENANT_ID)
+                            .setForwardingContext(Arrays.asList(new ForwardingContextBuilder()
+                                .setContextType(TestDataFactory.DummyContextType.class)
+                                .setContextId(TestDataFactory.CTX_1)
+                                .build()))
+                            .build()))
+                .build());
+
+        rendererManager.renderersUpdated(new RenderersBuilder()
+            .setRenderer(Arrays.asList(new RendererBuilder().setName(RENDERER_NAME_R1)
+                .setRendererNodes(new RendererNodesBuilder()
+                    .setRendererNode(Arrays.asList(new RendererNodeBuilder().setNodePath(NODE_PATH_1).build())).build())
+                .build()))
+            .build());
+
+        // assert dispatch one policy
+        Assert.assertEquals(1, rendererManager.getProcessingRenderers().size());
+        Mockito.verify(wTx).put(Mockito.eq(LogicalDatastoreType.CONFIGURATION),
+                Mockito.eq(InstanceIdentifier.create(Renderers.class)),
+                acRenderers.capture());
+
+        Renderers renderers = acRenderers.getValue();
+        Assert.assertNotNull(renderers);
+        Assert.assertNotNull(renderers.getRenderer());
+        Assert.assertEquals(1, renderers.getRenderer().size());
+        Renderer renderer = renderers.getRenderer().get(0);
+        Assert.assertEquals(RENDERER_NAME_R1, renderer.getName());
+        RendererPolicy rendererPolicy = renderer.getRendererPolicy();
+        Assert.assertNotNull(rendererPolicy);
+        Assert.assertEquals(1, rendererPolicy.getVersion().longValue());
+
+        Configuration configuration = rendererPolicy.getConfiguration();
+        Assert.assertNotNull(configuration);
+        RendererEndpoints rendererEndpoints = configuration.getRendererEndpoints();
+        Assert.assertNotNull(rendererEndpoints);
+        Assert.assertEquals(1, rendererEndpoints.getRendererEndpoint().size());
+
+        ForwardingContexts forwardingContexts = configuration.getForwardingContexts();
+        Assert.assertNotNull(forwardingContexts);
+        Assert.assertEquals(1, forwardingContexts.getForwardingContextByTenant().size());
+
+        Endpoints endpoints = configuration.getEndpoints();
+        Assert.assertNotNull(endpoints);
+        Assert.assertEquals(1, endpoints.getAddressEndpointWithLocation().size());
+        Assert.assertEquals(1, endpoints.getContainmentEndpointWithLocation().size());
+
+        RuleGroups ruleGroups = configuration.getRuleGroups();
+        Assert.assertNotNull(ruleGroups);
+        Assert.assertEquals(1, ruleGroups.getRuleGroup().size());
+    }
+
+    /**
+     * EP1--EPG_BLUE---SUBJECT_1---(P)EPG_PURPLE(EIG)--EP2()
+     */
+    @Test
+    public void testProcessState_dispatchOneExternalPolicyWithEp_noRendererFeedback() {
+        ArgumentCaptor<Renderers> acRenderers = ArgumentCaptor.forClass(Renderers.class);
+        ResolvedRule rule1 = TestDataFactory.defaultResolvedRule(RULE_1).build();
+        PolicyRuleGroup ruleGrp1 = TestDataFactory.defaultPolicyRuleGrp(CONTRACT_1, SUBJECT_1, rule1).build();
+        ResolvedPolicy resolvedPolicy = TestDataFactory.defaultResolvedPolicy(EPG_BLUE, EPG_PURPLE, ruleGrp1)
+            .setExternalImplicitGroup(ExternalImplicitGroup.ProviderEpg)
+            .build();
+        ResolvedPolicies resolvedPolicies =
+                new ResolvedPoliciesBuilder().setResolvedPolicy(ImmutableList.of(resolvedPolicy)).build();
+        rendererManager.resolvedPoliciesUpdated(resolvedPolicies);
+
+        AddressEndpoint ep1 = TestDataFactory.defaultAdrEp(ADR_1, EPG_BLUE).build();
+        AddressEndpoint ep2 = TestDataFactory.defaultAdrEp(ADR_2, EPG_PURPLE).build();
+        rendererManager.endpointsUpdated(new EndpointsBuilder()
+            .setAddressEndpoints(new AddressEndpointsBuilder().setAddressEndpoint(ImmutableList.of(ep1, ep2)).build())
+            .build());
+
+        AddressEndpointLocation ep1Loc =
+                TestDataFactory.defaultAdrEpLoc(ep1.getKey(), INT_LOC_CASE_NODE_PATH_1).build();
+        AddressEndpointLocation ep2Loc =
+                TestDataFactory.defaultAdrEpLoc(ep2.getKey(), EXT_LOC_CASE_NODE_PATH_1).build();
+        EndpointLocations endpointLocations =
+                new EndpointLocationsBuilder().setAddressEndpointLocation(ImmutableList.of(ep1Loc, ep2Loc)).build();
+        rendererManager.endpointLocationsUpdated(endpointLocations);
+
+        rendererManager
+            .forwardingUpdated(new ForwardingBuilder()
+                .setForwardingByTenant(
+                        Arrays.asList(new ForwardingByTenantBuilder().setTenantId(TestDataFactory.TENANT_ID)
+                            .setForwardingContext(Arrays.asList(new ForwardingContextBuilder()
+                                .setContextType(TestDataFactory.DummyContextType.class)
+                                .setContextId(TestDataFactory.CTX_1)
+                                .build()))
+                            .build()))
+                .build());
+
+        rendererManager.renderersUpdated(new RenderersBuilder()
+            .setRenderer(Arrays.asList(new RendererBuilder().setName(RENDERER_NAME_R1)
+                .setRendererNodes(new RendererNodesBuilder()
+                    .setRendererNode(Arrays.asList(new RendererNodeBuilder().setNodePath(NODE_PATH_1).build())).build())
+                .build()))
+            .build());
+
+        // assert dispatch one policy
+        Assert.assertEquals(1, rendererManager.getProcessingRenderers().size());
+        Mockito.verify(wTx).put(Mockito.eq(LogicalDatastoreType.CONFIGURATION),
+                Mockito.eq(InstanceIdentifier.create(Renderers.class)),
+                acRenderers.capture());
+
+        Renderers renderers = acRenderers.getValue();
+        Assert.assertNotNull(renderers);
+        Assert.assertNotNull(renderers.getRenderer());
+        Assert.assertEquals(1, renderers.getRenderer().size());
+        Renderer renderer = renderers.getRenderer().get(0);
+        Assert.assertEquals(RENDERER_NAME_R1, renderer.getName());
+        RendererPolicy rendererPolicy = renderer.getRendererPolicy();
+        Assert.assertNotNull(rendererPolicy);
+        Assert.assertEquals(1, rendererPolicy.getVersion().longValue());
+
+        Configuration configuration = rendererPolicy.getConfiguration();
+        Assert.assertNotNull(configuration);
+        RendererEndpoints rendererEndpoints = configuration.getRendererEndpoints();
+        Assert.assertNotNull(rendererEndpoints);
+        Assert.assertEquals(1, rendererEndpoints.getRendererEndpoint().size());
+
+        ForwardingContexts forwardingContexts = configuration.getForwardingContexts();
+        Assert.assertNotNull(forwardingContexts);
+        Assert.assertEquals(1, forwardingContexts.getForwardingContextByTenant().size());
+
+        Endpoints endpoints = configuration.getEndpoints();
+        Assert.assertNotNull(endpoints);
+        Assert.assertEquals(2, endpoints.getAddressEndpointWithLocation().size());
+
+        RuleGroups ruleGroups = configuration.getRuleGroups();
+        Assert.assertNotNull(ruleGroups);
+        Assert.assertEquals(1, ruleGroups.getRuleGroup().size());
+    }
+
+}
diff --git a/groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/renderer/RendererManagerTest.java b/groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/renderer/RendererManagerTest.java
new file mode 100644 (file)
index 0000000..6c792d8
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.renderer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.EndpointLocations;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.EndpointLocationsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.Endpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.EndpointsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.AddressEndpointsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.InternalLocationCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.InternalLocationCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RuleName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Tenants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.endpoints.PeerEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPolicies;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPoliciesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRule;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.policy.rule.group.with.endpoint.constraints.PolicyRuleGroup;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableTable;
+
+@RunWith(MockitoJUnitRunner.class)
+public class RendererManagerTest {
+
+    private static final EndpointGroupId EPG_BLUE = new EndpointGroupId("blue_epg");
+    private static final EndpointGroupId EPG_PURPLE = new EndpointGroupId("purple_epg");
+    private static final EndpointGroupId EPG_RED = new EndpointGroupId("red_epg");
+    private static final EndpointGroupId EPG_GREY = new EndpointGroupId("grey_epg");
+    private static final ContractId CONTRACT_1 = new ContractId("contract_1");
+    private static final SubjectName SUBJECT_1 = new SubjectName("subject_1");
+    private static final RuleName RULE_1 = new RuleName("rule_1");
+    private static final ContractId CONTRACT_2 = new ContractId("contract_2");
+    private static final SubjectName SUBJECT_2 = new SubjectName("subject_2");
+    private static final String ADR_1 = "adr_1";
+    private static final String ADR_2 = "adr_2";
+    private static final String ADR_3 = "adr_3";
+    private static final String ADR_4 = "adr_4";
+    private static final InstanceIdentifier<?> NODE_PATH_1 = InstanceIdentifier.create(Tenants.class);
+    private static final InternalLocationCase REG_LOC_NODE_PATH_1 =
+            new InternalLocationCaseBuilder().setInternalNode(NODE_PATH_1).build();
+
+    @Mock
+    private DataBroker dataProvider;
+
+    private RendererManager rendererManager;
+
+    @Before
+    public void init() {
+        rendererManager = new RendererManager(dataProvider);
+    }
+
+    /**
+     * EP1--EPG_BLUE---SUBJECT_1---(P)EPG_PURPLE--EP2
+     */
+    @Test
+    public void testResolveRendererPolicyForEndpoint_onePolicy() {
+        ResolvedRule rule1 = TestDataFactory.defaultResolvedRule(RULE_1).build();
+        PolicyRuleGroup ruleGrp1 = TestDataFactory.defaultPolicyRuleGrp(CONTRACT_1, SUBJECT_1, rule1).build();
+        ResolvedPolicy resolvedPolicy = TestDataFactory.defaultResolvedPolicy(EPG_BLUE, EPG_PURPLE, ruleGrp1).build();
+        ResolvedPolicies resolvedPolicies =
+                new ResolvedPoliciesBuilder().setResolvedPolicy(ImmutableList.of(resolvedPolicy)).build();
+        rendererManager.resolvedPoliciesUpdated(resolvedPolicies);
+
+        AddressEndpoint ep1 = TestDataFactory.defaultAdrEp(ADR_1, EPG_BLUE).build();
+        AddressEndpoint ep2 = TestDataFactory.defaultAdrEp(ADR_2, EPG_PURPLE).build();
+        Endpoints endpoints = new EndpointsBuilder()
+            .setAddressEndpoints(new AddressEndpointsBuilder().setAddressEndpoint(ImmutableList.of(ep1, ep2)).build())
+            .build();
+        rendererManager.endpointsUpdated(endpoints);
+
+        AddressEndpointLocation ep1Loc = TestDataFactory.defaultAdrEpLoc(ep1.getKey(), REG_LOC_NODE_PATH_1).build();
+        AddressEndpointLocation ep2Loc = TestDataFactory.defaultAdrEpLoc(ep2.getKey(), REG_LOC_NODE_PATH_1).build();
+        EndpointLocations endpointLocations =
+                new EndpointLocationsBuilder().setAddressEndpointLocation(ImmutableList.of(ep1Loc, ep2Loc)).build();
+        rendererManager.endpointLocationsUpdated(endpointLocations);
+
+        RendererConfigurationBuilder rendererPolicyBuilder = new RendererConfigurationBuilder();
+        rendererManager.resolveRendererConfigForEndpoint(ep1, rendererPolicyBuilder);
+        ImmutableTable<RendererEndpointKey, PeerEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByEpAndPeerEp =
+                rendererPolicyBuilder.getPoliciesByEpAndPeerEp();
+        assertFalse(policiesByEpAndPeerEp.isEmpty());
+        assertTrue(rendererPolicyBuilder.getPoliciesByEpAndPeerExtEp().isEmpty());
+        assertTrue(rendererPolicyBuilder.getPoliciesByEpAndPeerExtConEp().isEmpty());
+        assertEquals(1, policiesByEpAndPeerEp.rowKeySet().size());
+        assertEquals(1, policiesByEpAndPeerEp.columnKeySet().size());
+        // check EP1--EPG_BLUE---SUBJECT_1---(P)EPG_PURPLE--EP2
+        RendererEndpointKey rendererEpKey = AddressEndpointUtils.toRendererEpKey(ep1.getKey());
+        assertEquals(rendererEpKey, policiesByEpAndPeerEp.rowKeySet().iterator().next());
+        PeerEndpointKey peerEpKey = AddressEndpointUtils.toPeerEpKey(ep2.getKey());
+        assertEquals(peerEpKey, policiesByEpAndPeerEp.columnKeySet().iterator().next());
+        Set<RuleGroupWithRendererEndpointParticipation> ruleGrpsWithEpPartic =
+                policiesByEpAndPeerEp.get(rendererEpKey, peerEpKey);
+        assertEquals(1, ruleGrpsWithEpPartic.size());
+        RuleGroupWithRendererEndpointParticipation ruleGrpWithEpPartic = ruleGrpsWithEpPartic.iterator().next();
+        assertEquals(ruleGrp1.getTenantId(), ruleGrpWithEpPartic.getTenantId());
+        assertEquals(ruleGrp1.getContractId(), ruleGrpWithEpPartic.getContractId());
+        assertEquals(ruleGrp1.getSubjectName(), ruleGrpWithEpPartic.getSubjectName());
+        assertEquals(EndpointPolicyParticipation.CONSUMER, ruleGrpWithEpPartic.getRendererEndpointParticipation());
+    }
+
+    /**
+     * EP1--EPG_BLUE---SUBJECT_1---(P)EPG_PURPLE--EP2
+     * <br>
+     * EP3--EPG_RED----SUBJECT_1---(P)EPG_GREY--EP4
+     */
+    @Test
+    public void testResolveRendererPolicyForEndpoint_onePolicyTwoUsage() {
+        ResolvedRule rule1 = TestDataFactory.defaultResolvedRule(RULE_1).build();
+        PolicyRuleGroup ruleGrp1 = TestDataFactory.defaultPolicyRuleGrp(CONTRACT_1, SUBJECT_1, rule1).build();
+        ResolvedPolicy bluePurplePolicy = TestDataFactory.defaultResolvedPolicy(EPG_BLUE, EPG_PURPLE, ruleGrp1).build();
+        ResolvedPolicy redGreyPolicy = TestDataFactory.defaultResolvedPolicy(EPG_RED, EPG_GREY, ruleGrp1).build();
+        ResolvedPolicies resolvedPolicies = new ResolvedPoliciesBuilder()
+            .setResolvedPolicy(ImmutableList.of(bluePurplePolicy, redGreyPolicy)).build();
+        rendererManager.resolvedPoliciesUpdated(resolvedPolicies);
+
+        AddressEndpoint ep1 = TestDataFactory.defaultAdrEp(ADR_1, EPG_BLUE).build();
+        AddressEndpoint ep2 = TestDataFactory.defaultAdrEp(ADR_2, EPG_PURPLE).build();
+        AddressEndpoint ep3 = TestDataFactory.defaultAdrEp(ADR_3, EPG_RED).build();
+        AddressEndpoint ep4 = TestDataFactory.defaultAdrEp(ADR_4, EPG_GREY).build();
+        Endpoints endpoints = new EndpointsBuilder()
+            .setAddressEndpoints(
+                    new AddressEndpointsBuilder().setAddressEndpoint(ImmutableList.of(ep1, ep2, ep3, ep4)).build())
+            .build();
+        rendererManager.endpointsUpdated(endpoints);
+
+        AddressEndpointLocation ep1Loc = TestDataFactory.defaultAdrEpLoc(ep1.getKey(), REG_LOC_NODE_PATH_1).build();
+        AddressEndpointLocation ep2Loc = TestDataFactory.defaultAdrEpLoc(ep2.getKey(), REG_LOC_NODE_PATH_1).build();
+        AddressEndpointLocation ep3Loc = TestDataFactory.defaultAdrEpLoc(ep3.getKey(), REG_LOC_NODE_PATH_1).build();
+        AddressEndpointLocation ep4Loc = TestDataFactory.defaultAdrEpLoc(ep4.getKey(), REG_LOC_NODE_PATH_1).build();
+        EndpointLocations endpointLocations = new EndpointLocationsBuilder()
+            .setAddressEndpointLocation(ImmutableList.of(ep1Loc, ep2Loc, ep3Loc, ep4Loc)).build();
+        rendererManager.endpointLocationsUpdated(endpointLocations);
+
+        // EP1, EP3 as renderer endpoints
+        RendererConfigurationBuilder rendererPolicyBuilder = new RendererConfigurationBuilder();
+        rendererManager.resolveRendererConfigForEndpoint(ep1, rendererPolicyBuilder);
+        rendererManager.resolveRendererConfigForEndpoint(ep3, rendererPolicyBuilder);
+        ImmutableTable<RendererEndpointKey, PeerEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByEpAndPeerEp =
+                rendererPolicyBuilder.getPoliciesByEpAndPeerEp();
+        assertFalse(policiesByEpAndPeerEp.isEmpty());
+        assertTrue(rendererPolicyBuilder.getPoliciesByEpAndPeerExtEp().isEmpty());
+        assertTrue(rendererPolicyBuilder.getPoliciesByEpAndPeerExtConEp().isEmpty());
+        assertEquals(2, policiesByEpAndPeerEp.rowKeySet().size());
+        assertEquals(2, policiesByEpAndPeerEp.columnKeySet().size());
+        // check EPG_BLUE---SUBJECT_1---(P)EPG_PURPLE
+        RendererEndpointKey ep1RendererEpKey = AddressEndpointUtils.toRendererEpKey(ep1.getKey());
+        assertTrue(policiesByEpAndPeerEp.containsRow(ep1RendererEpKey));
+        PeerEndpointKey ep2PeerEpKey = AddressEndpointUtils.toPeerEpKey(ep2.getKey());
+        assertTrue(policiesByEpAndPeerEp.containsColumn(ep2PeerEpKey));
+        Set<RuleGroupWithRendererEndpointParticipation> ep1Ep2RuleGrpsWithEpPartic =
+                policiesByEpAndPeerEp.get(ep1RendererEpKey, ep2PeerEpKey);
+        assertEquals(1, ep1Ep2RuleGrpsWithEpPartic.size());
+        RuleGroupWithRendererEndpointParticipation ruleGrp1WithEpPartic = ep1Ep2RuleGrpsWithEpPartic.iterator().next();
+        assertEquals(ruleGrp1.getTenantId(), ruleGrp1WithEpPartic.getTenantId());
+        assertEquals(ruleGrp1.getContractId(), ruleGrp1WithEpPartic.getContractId());
+        assertEquals(ruleGrp1.getSubjectName(), ruleGrp1WithEpPartic.getSubjectName());
+        assertEquals(EndpointPolicyParticipation.CONSUMER, ruleGrp1WithEpPartic.getRendererEndpointParticipation());
+        // check EP3--EPG_RED----SUBJECT_1---(P)EPG_GREY--EP4
+        RendererEndpointKey ep3RendererEpKey = AddressEndpointUtils.toRendererEpKey(ep3.getKey());
+        assertTrue(policiesByEpAndPeerEp.containsRow(ep3RendererEpKey));
+        PeerEndpointKey ep4PeerEpKey = AddressEndpointUtils.toPeerEpKey(ep4.getKey());
+        assertTrue(policiesByEpAndPeerEp.containsColumn(ep4PeerEpKey));
+        Set<RuleGroupWithRendererEndpointParticipation> ep3Ep4RuleGrpsWithEpPartic =
+                policiesByEpAndPeerEp.get(ep3RendererEpKey, ep4PeerEpKey);
+        assertEquals(1, ep3Ep4RuleGrpsWithEpPartic.size());
+        ruleGrp1WithEpPartic = ep3Ep4RuleGrpsWithEpPartic.iterator().next();
+        assertEquals(ruleGrp1.getTenantId(), ruleGrp1WithEpPartic.getTenantId());
+        assertEquals(ruleGrp1.getContractId(), ruleGrp1WithEpPartic.getContractId());
+        assertEquals(ruleGrp1.getSubjectName(), ruleGrp1WithEpPartic.getSubjectName());
+        assertEquals(EndpointPolicyParticipation.CONSUMER, ruleGrp1WithEpPartic.getRendererEndpointParticipation());
+    }
+
+    /**
+     * EP1--EPG_BLUE---SUBJECT_1---(P)EPG_PURPLE--EP2
+     * <br>
+     * EP1--EPG_RED----SUBJECT_2---(P)EPG_GREY--EP2,EP3
+     */
+    @Test
+    public void testResolveRendererPolicyForEndpoint_twoPolicy() {
+        ResolvedRule rule1 = TestDataFactory.defaultResolvedRule(RULE_1).build();
+        PolicyRuleGroup ruleGrp1 = TestDataFactory.defaultPolicyRuleGrp(CONTRACT_1, SUBJECT_1, rule1).build();
+        PolicyRuleGroup ruleGrp2 = TestDataFactory.defaultPolicyRuleGrp(CONTRACT_2, SUBJECT_2, rule1).build();
+        ResolvedPolicy bluePurplePolicy = TestDataFactory.defaultResolvedPolicy(EPG_BLUE, EPG_PURPLE, ruleGrp1).build();
+        ResolvedPolicy redGreyPolicy = TestDataFactory.defaultResolvedPolicy(EPG_RED, EPG_GREY, ruleGrp2).build();
+        ResolvedPolicies resolvedPolicies = new ResolvedPoliciesBuilder()
+            .setResolvedPolicy(ImmutableList.of(bluePurplePolicy, redGreyPolicy)).build();
+        rendererManager.resolvedPoliciesUpdated(resolvedPolicies);
+
+        AddressEndpoint ep1 = TestDataFactory.defaultAdrEp(ADR_1, EPG_BLUE, EPG_RED).build();
+        AddressEndpoint ep2 = TestDataFactory.defaultAdrEp(ADR_2, EPG_PURPLE, EPG_GREY).build();
+        AddressEndpoint ep3 = TestDataFactory.defaultAdrEp(ADR_3, EPG_GREY).build();
+        Endpoints endpoints =
+                new EndpointsBuilder()
+                    .setAddressEndpoints(
+                            new AddressEndpointsBuilder().setAddressEndpoint(ImmutableList.of(ep1, ep2, ep3)).build())
+                    .build();
+        rendererManager.endpointsUpdated(endpoints);
+
+        AddressEndpointLocation ep1Loc = TestDataFactory.defaultAdrEpLoc(ep1.getKey(), REG_LOC_NODE_PATH_1).build();
+        AddressEndpointLocation ep2Loc = TestDataFactory.defaultAdrEpLoc(ep2.getKey(), REG_LOC_NODE_PATH_1).build();
+        AddressEndpointLocation ep3Loc = TestDataFactory.defaultAdrEpLoc(ep3.getKey(), REG_LOC_NODE_PATH_1).build();
+        EndpointLocations endpointLocations = new EndpointLocationsBuilder()
+            .setAddressEndpointLocation(ImmutableList.of(ep1Loc, ep2Loc, ep3Loc)).build();
+        rendererManager.endpointLocationsUpdated(endpointLocations);
+
+        // EP1 as renderer endpoint
+        RendererConfigurationBuilder rendererPolicyBuilder = new RendererConfigurationBuilder();
+        rendererManager.resolveRendererConfigForEndpoint(ep1, rendererPolicyBuilder);
+        ImmutableTable<RendererEndpointKey, PeerEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByEpAndPeerEp =
+                rendererPolicyBuilder.getPoliciesByEpAndPeerEp();
+        assertFalse(policiesByEpAndPeerEp.isEmpty());
+        assertTrue(rendererPolicyBuilder.getPoliciesByEpAndPeerExtEp().isEmpty());
+        assertTrue(rendererPolicyBuilder.getPoliciesByEpAndPeerExtConEp().isEmpty());
+        assertEquals(1, policiesByEpAndPeerEp.rowKeySet().size());
+        assertEquals(2, policiesByEpAndPeerEp.columnKeySet().size());
+        // check EP1--EPG_BLUE---SUBJECT_1---(P)EPG_PURPLE--EP2
+        // check EP1--EPG_RED----SUBJECT_2---(P)EPG_GREY--EP2
+        RendererEndpointKey ep1RendererEpKey = AddressEndpointUtils.toRendererEpKey(ep1.getKey());
+        assertTrue(policiesByEpAndPeerEp.containsRow(ep1RendererEpKey));
+        PeerEndpointKey ep2PeerEpKey = AddressEndpointUtils.toPeerEpKey(ep2.getKey());
+        assertTrue(policiesByEpAndPeerEp.containsColumn(ep2PeerEpKey));
+        Set<RuleGroupWithRendererEndpointParticipation> ep1Ep2RuleGrpsWithEpPartic =
+                policiesByEpAndPeerEp.get(ep1RendererEpKey, ep2PeerEpKey);
+        assertEquals(2, ep1Ep2RuleGrpsWithEpPartic.size());
+        assertTrue(ep1Ep2RuleGrpsWithEpPartic.contains(RendererConfigurationBuilder
+            .toRuleGroupWithRendererEndpointParticipation(ruleGrp1.getKey(), EndpointPolicyParticipation.CONSUMER)));
+        assertTrue(ep1Ep2RuleGrpsWithEpPartic.contains(RendererConfigurationBuilder
+            .toRuleGroupWithRendererEndpointParticipation(ruleGrp2.getKey(), EndpointPolicyParticipation.CONSUMER)));
+        // check EP1--EPG_RED----SUBJECT_2---(P)EPG_GREY--EP3
+        PeerEndpointKey ep3PeerEpKey = AddressEndpointUtils.toPeerEpKey(ep3.getKey());
+        assertTrue(policiesByEpAndPeerEp.containsColumn(ep3PeerEpKey));
+        Set<RuleGroupWithRendererEndpointParticipation> ep1Ep3RuleGrpsWithEpPartic =
+                policiesByEpAndPeerEp.get(ep1RendererEpKey, ep3PeerEpKey);
+        assertEquals(1, ep1Ep3RuleGrpsWithEpPartic.size());
+        assertTrue(ep1Ep3RuleGrpsWithEpPartic.contains(RendererConfigurationBuilder
+            .toRuleGroupWithRendererEndpointParticipation(ruleGrp2.getKey(), EndpointPolicyParticipation.CONSUMER)));
+    }
+
+}
diff --git a/groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/renderer/TestDataFactory.java b/groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/renderer/TestDataFactory.java
new file mode 100644 (file)
index 0000000..b4e8812
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. 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.groupbasedpolicy.renderer;
+
+import java.util.Arrays;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.NetworkContainmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.containment.ForwardingContextContainmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.ContainmentEndpointLocationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.LocationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.RelativeLocationsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.InternalLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionDefinitionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RuleName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.AddressType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.ContextType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.actions.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.actions.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.Classifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.ClassifierBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRule;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRuleBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.PolicyRuleGroupWithEndpointConstraints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.PolicyRuleGroupWithEndpointConstraintsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.policy.rule.group.with.endpoint.constraints.PolicyRuleGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.policy.rule.group.with.endpoint.constraints.PolicyRuleGroupBuilder;
+
+import com.google.common.collect.ImmutableList;
+
+public class TestDataFactory {
+
+    public static final TenantId TENANT_ID = new TenantId("cisco_tenant");
+    public static final ActionDefinitionId AD_1 = new ActionDefinitionId("ad_1");
+    public static final ActionName AN_1 = new ActionName("an_1");
+    public static final ClassifierDefinitionId CD_1 = new ClassifierDefinitionId("cd_1");
+    public static final ClassifierName CN_1 = new ClassifierName("cn_1");
+    public static final ContextId CTX_1 = new ContextId("ctx_1");
+
+    public static AddressEndpointLocationBuilder defaultAdrEpLoc(AddressEndpointKey adrEpKey, LocationType realLoc,
+            InternalLocation... relativeLocs) {
+        AddressEndpointLocationBuilder result =
+                new AddressEndpointLocationBuilder().setContextType(adrEpKey.getContextType())
+                    .setContextId(adrEpKey.getContextId())
+                    .setAddressType(adrEpKey.getAddressType())
+                    .setAddress(adrEpKey.getAddress())
+                    .setAbsoluteLocation(new AbsoluteLocationBuilder().setLocationType(realLoc).build());
+        if (relativeLocs != null) {
+            result.setRelativeLocations(
+                    new RelativeLocationsBuilder().setInternalLocation(Arrays.asList(relativeLocs)).build());
+        }
+        return result;
+    }
+
+    public static ContainmentEndpointLocationBuilder defaultContEpLoc(ContainmentEndpointKey contEpKey,
+            InternalLocation... relativeLocs) {
+        ContainmentEndpointLocationBuilder result = new ContainmentEndpointLocationBuilder()
+            .setContextType(contEpKey.getContextType()).setContextId(contEpKey.getContextId()).setRelativeLocations(
+                    new RelativeLocationsBuilder().setInternalLocation(Arrays.asList(relativeLocs)).build());
+        return result;
+    }
+
+    public static AddressEndpointBuilder defaultAdrEp(String address, EndpointGroupId... epgs) {
+        return new AddressEndpointBuilder().setContextType(DummyContextType.class)
+            .setContextId(CTX_1)
+            .setAddressType(DummyAddressType.class)
+            .setAddress(address)
+            .setTenant(TENANT_ID)
+            .setEndpointGroup(Arrays.asList(epgs))
+            .setNetworkContainment(
+                    new NetworkContainmentBuilder().setContainment(new ForwardingContextContainmentBuilder()
+                        .setContextType(DummyContextType.class).setContextId(CTX_1).build()).build());
+    }
+
+    public static ContainmentEndpointBuilder defaultContEp(EndpointGroupId... epgs) {
+        return new ContainmentEndpointBuilder().setContextType(DummyContextType.class)
+            .setContextId(CTX_1)
+            .setTenant(TENANT_ID)
+            .setEndpointGroup(Arrays.asList(epgs))
+            .setNetworkContainment(
+                    new NetworkContainmentBuilder().setContainment(new ForwardingContextContainmentBuilder()
+                        .setContextType(DummyContextType.class).setContextId(CTX_1).build()).build());
+    }
+
+    public static ResolvedRuleBuilder defaultResolvedRule(RuleName ruleName) {
+        Action action = new ActionBuilder().setActionDefinitionId(AD_1).setName(AN_1).setOrder(0).build();
+        Classifier classifier = new ClassifierBuilder().setClassifierDefinitionId(CD_1)
+            .setName(CN_1)
+            .setDirection(Direction.In)
+            .build();
+        return new ResolvedRuleBuilder().setName(ruleName)
+            .setOrder(0)
+            .setAction(ImmutableList.of(action))
+            .setClassifier(ImmutableList.of(classifier));
+    }
+
+    public static PolicyRuleGroupBuilder defaultPolicyRuleGrp(ContractId contractId, SubjectName subjectName,
+            ResolvedRule... resolvedRules) {
+        return new PolicyRuleGroupBuilder().setTenantId(TENANT_ID)
+            .setContractId(contractId)
+            .setSubjectName(subjectName)
+            .setResolvedRule(Arrays.asList(resolvedRules));
+    }
+
+    public static ResolvedPolicyBuilder defaultResolvedPolicy(EndpointGroupId consEpg, EndpointGroupId provEpg,
+            PolicyRuleGroup... policyRuleGrps) {
+        PolicyRuleGroupWithEndpointConstraints blueRuleGrpWithoutCons =
+                new PolicyRuleGroupWithEndpointConstraintsBuilder().setPolicyRuleGroup(Arrays.asList(policyRuleGrps))
+                    .build();
+        return new ResolvedPolicyBuilder().setConsumerEpgId(consEpg)
+            .setConsumerTenantId(TENANT_ID)
+            .setProviderEpgId(provEpg)
+            .setProviderTenantId(TENANT_ID)
+            .setPolicyRuleGroupWithEndpointConstraints(ImmutableList.of(blueRuleGrpWithoutCons));
+    }
+
+    public static abstract class DummyContextType extends ContextType {
+    };
+    public static abstract class DummyAddressType extends AddressType {
+    };
+}
index 30222acf0b8dfcf0199a342e64e7ab4eb769c22d..a168b8fc2f08c5a3f4f0ce4454a4a99471744f17 100755 (executable)
@@ -16,8 +16,17 @@ import org.junit.Test;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocationKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.ContainmentEndpointLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.ContainmentEndpointLocationKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.ExternalLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.ExternalLocationKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.InternalLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.InternalLocationKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionDefinitionId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
@@ -67,6 +76,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.SupportedClassifierDefinition;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.interests.followed.tenants.FollowedTenant;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.interests.followed.tenants.followed.tenant.FollowedEndpointGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 public class IidFactoryTest {
@@ -75,6 +91,7 @@ public class IidFactoryTest {
     private final String IP_ADDRESS = "192.68.50.71";
     private final String IP_PREFIX = "192.168.50.0/24";
     private final String L3_CONTEXT_ID = "l3Context";
+    private final String CONNECTOR = "connector";
 
     private TenantId tenantId;
     private EndpointGroupId epgId;
@@ -83,6 +100,13 @@ public class IidFactoryTest {
     private RuleName ruleName;
     private RendererName rendererName;
 
+    private InstanceIdentifier<Node> nodeIid = InstanceIdentifier.builder(Nodes.class)
+            .child(Node.class, new NodeKey(new NodeId("node"))).build();
+    private InstanceIdentifier<NodeConnector> connectorIid = InstanceIdentifier.builder(Nodes.class)
+            .child(Node.class, new NodeKey(new NodeId("node")))
+            .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId("connector")))
+            .build();
+
     @Before
     public void initialise() {
         tenantId = mock(TenantId.class);
@@ -346,8 +370,7 @@ public class IidFactoryTest {
         InstanceIdentifier<ProviderAddressEndpointLocation> identifier = IidFactory
             .providerAddressEndpointLocationIid(LOCATION_PROVIDER_NAME, IpPrefixType.class, IP_ADDRESS,
                     org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context.class,
-                    l3Context)
-            .build();
+                    l3Context);
         Assert.assertEquals(LOCATION_PROVIDER_NAME,
                 identifier.firstKeyOf(LocationProvider.class).getProvider().getValue());
         Assert.assertEquals(IP_ADDRESS, identifier.firstKeyOf(ProviderAddressEndpointLocation.class).getAddress());
@@ -358,7 +381,7 @@ public class IidFactoryTest {
     public void testAddressEndpointIid() {
         ContextId l3Context = new ContextId(L3_CONTEXT_ID);
         InstanceIdentifier<AddressEndpoint> identifier =
-                IidFactory.addressEndpointIid(new AddressEndpointKey(IP_ADDRESS, IpPrefixType.class, new ContextId(l3Context),
+                IidFactory.addressEndpointIid(new AddressEndpointKey(IP_ADDRESS, IpPrefixType.class, l3Context,
                         org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context.class
                         ));
         Assert.assertEquals(IpPrefixType.class, identifier.firstKeyOf(AddressEndpoint.class).getAddressType());
@@ -368,4 +391,115 @@ public class IidFactoryTest {
                 identifier.firstKeyOf(AddressEndpoint.class).getContextType());
         Assert.assertEquals(l3Context, identifier.firstKeyOf(AddressEndpoint.class).getContextId());
     }
+
+    @Test
+    public void testAddressEndpointLocationIid() {
+        ContextId l3Context = new ContextId(L3_CONTEXT_ID);
+        AddressEndpointLocationKey addrEndpointLocationKey =
+                new AddressEndpointLocationKey(IP_ADDRESS, IpPrefixType.class, l3Context,
+                        org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context.class);
+        InstanceIdentifier<AddressEndpointLocation> iid = IidFactory.addressEndpointLocationIid(addrEndpointLocationKey);
+        Assert.assertEquals(IpPrefixType.class, iid.firstKeyOf(AddressEndpointLocation.class).getAddressType());
+        Assert.assertEquals(IP_ADDRESS, iid.firstKeyOf(AddressEndpointLocation.class).getAddress());
+        Assert.assertEquals(
+                org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context.class,
+                iid.firstKeyOf(AddressEndpointLocation.class).getContextType());
+        Assert.assertEquals(l3Context, iid.firstKeyOf(AddressEndpointLocation.class).getContextId());
+    }
+
+    @Test
+    public void testContainmentEndpointLocationIid() {
+        ContextId l3Context = new ContextId(L3_CONTEXT_ID);
+        ContainmentEndpointLocationKey contEndpointLocationKey =
+                new ContainmentEndpointLocationKey(l3Context,
+                        org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context.class);
+        InstanceIdentifier<ContainmentEndpointLocation> iid = IidFactory.containmentEndpointLocationIid(contEndpointLocationKey);
+        Assert.assertEquals(
+                org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context.class,
+                iid.firstKeyOf(ContainmentEndpointLocation.class).getContextType());
+        Assert.assertEquals(l3Context, iid.firstKeyOf(ContainmentEndpointLocation.class).getContextId());
+    }
+
+    @Test
+    public void internalLocationIid_AddrEndpoint() {
+        ContextId l3Context = new ContextId(L3_CONTEXT_ID);
+        AddressEndpointLocationKey addrEndpointLocationKey =
+                new AddressEndpointLocationKey(IP_ADDRESS, IpPrefixType.class, l3Context,
+                        org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context.class);
+        InternalLocationKey internalLocationKey = new InternalLocationKey(nodeIid, connectorIid);
+        InstanceIdentifier<InternalLocation> iid = IidFactory.internalLocationIid(addrEndpointLocationKey, internalLocationKey);
+        Assert.assertEquals(IpPrefixType.class, iid.firstKeyOf(AddressEndpointLocation.class).getAddressType());
+        Assert.assertEquals(IP_ADDRESS, iid.firstKeyOf(AddressEndpointLocation.class).getAddress());
+        Assert.assertEquals(
+                org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context.class,
+                iid.firstKeyOf(AddressEndpointLocation.class).getContextType());
+        Assert.assertEquals(l3Context, iid.firstKeyOf(AddressEndpointLocation.class).getContextId());
+        Assert.assertEquals(nodeIid, iid.firstKeyOf(InternalLocation.class).getInternalNode());
+        Assert.assertEquals(connectorIid, iid.firstKeyOf(InternalLocation.class).getInternalNodeConnector());
+    }
+
+    @Test
+    public void internalLocationIid_ContEndpoint() {
+        ContextId l3Context = new ContextId(L3_CONTEXT_ID);
+        ContainmentEndpointLocationKey contEndpointLocationKey =
+                new ContainmentEndpointLocationKey(l3Context,
+                        org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context.class);
+        InternalLocationKey internalLocationKey = new InternalLocationKey(nodeIid, connectorIid);
+        InstanceIdentifier<InternalLocation> iid = IidFactory.internalLocationIid(contEndpointLocationKey, internalLocationKey);
+        Assert.assertEquals(
+                org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context.class,
+                iid.firstKeyOf(ContainmentEndpointLocation.class).getContextType());
+        Assert.assertEquals(l3Context, iid.firstKeyOf(ContainmentEndpointLocation.class).getContextId());
+        Assert.assertEquals(nodeIid, iid.firstKeyOf(InternalLocation.class).getInternalNode());
+        Assert.assertEquals(connectorIid, iid.firstKeyOf(InternalLocation.class).getInternalNodeConnector());
+    }
+
+    @Test
+    public void externalLocationIid_AddrEndpoint() {
+        ContextId l3Context = new ContextId(L3_CONTEXT_ID);
+        AddressEndpointLocationKey addrEndpointLocationKey =
+                new AddressEndpointLocationKey(IP_ADDRESS, IpPrefixType.class, l3Context,
+                        org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context.class);
+        ExternalLocationKey externalLocationKey = new ExternalLocationKey(CONNECTOR, nodeIid);
+        InstanceIdentifier<ExternalLocation> iid = IidFactory.externalLocationIid(addrEndpointLocationKey, externalLocationKey);
+        Assert.assertEquals(IpPrefixType.class, iid.firstKeyOf(AddressEndpointLocation.class).getAddressType());
+        Assert.assertEquals(IP_ADDRESS, iid.firstKeyOf(AddressEndpointLocation.class).getAddress());
+        Assert.assertEquals(
+                org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context.class,
+                iid.firstKeyOf(AddressEndpointLocation.class).getContextType());
+        Assert.assertEquals(l3Context, iid.firstKeyOf(AddressEndpointLocation.class).getContextId());
+        Assert.assertEquals(CONNECTOR, iid.firstKeyOf(ExternalLocation.class).getExternalNodeConnector());
+        Assert.assertEquals(nodeIid, iid.firstKeyOf(ExternalLocation.class).getExternalNodeMountPoint());
+    }
+
+    @Test
+    public void externalLocationIid_ContEndpoint() {
+        ContextId l3Context = new ContextId(L3_CONTEXT_ID);
+        ContainmentEndpointLocationKey addrEndpointLocationKey =
+                new ContainmentEndpointLocationKey(l3Context,
+                        org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context.class);
+        ExternalLocationKey externalLocationKey = new ExternalLocationKey(CONNECTOR, nodeIid);
+        InstanceIdentifier<ExternalLocation> iid = IidFactory.externalLocationIid(addrEndpointLocationKey, externalLocationKey);
+        Assert.assertEquals(
+                org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context.class,
+                iid.firstKeyOf(ContainmentEndpointLocation.class).getContextType());
+        Assert.assertEquals(l3Context, iid.firstKeyOf(ContainmentEndpointLocation.class).getContextId());
+        Assert.assertEquals(CONNECTOR, iid.firstKeyOf(ExternalLocation.class).getExternalNodeConnector());
+        Assert.assertEquals(nodeIid, iid.firstKeyOf(ExternalLocation.class).getExternalNodeMountPoint());
+    }
+
+    @Test
+    public void absoluteLocationIid() {
+        ContextId l3Context = new ContextId(L3_CONTEXT_ID);
+        AddressEndpointLocationKey addrEndpointLocationKey =
+                new AddressEndpointLocationKey(IP_ADDRESS, IpPrefixType.class, l3Context,
+                        org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context.class);
+        InstanceIdentifier<AbsoluteLocation> iid = IidFactory.absoluteLocationIid(addrEndpointLocationKey);
+        Assert.assertEquals(IpPrefixType.class, iid.firstKeyOf(AddressEndpointLocation.class).getAddressType());
+        Assert.assertEquals(IP_ADDRESS, iid.firstKeyOf(AddressEndpointLocation.class).getAddress());
+        Assert.assertEquals(
+                org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context.class,
+                iid.firstKeyOf(AddressEndpointLocation.class).getContextType());
+        Assert.assertEquals(l3Context, iid.firstKeyOf(AddressEndpointLocation.class).getContextId());
+    }
 }
index a25469f2112e7d7dde7e100be882aad2ce13ba43..e20046df8dca04e571fe7e3858c088fecc3719dd 100644 (file)
@@ -26,9 +26,9 @@ import org.opendaylight.groupbasedpolicy.util.IidFactory;
 import org.opendaylight.groupbasedpolicy.util.NetUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.location.RealLocation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.location.RealLocationBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.location.real.location.location.type.RegularLocationCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.InternalLocationCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.network.elements.rev160407.NetworkElements;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.network.elements.rev160407.NetworkElementsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.network.elements.rev160407.network.elements.NetworkElement;
@@ -111,11 +111,10 @@ public class NeLocationProvider implements DataTreeChangeListener<NetworkElement
                             && endpoint.getAddressType().isAssignableFrom(IpPrefixType.class) && NetUtils
                                 .samePrefix(new IpPrefix(endpoint.getAddress().toCharArray()), en.getIpPrefix())) {
                         WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
-                        InstanceIdentifier<RealLocation> iid = IidFactory
+                        InstanceIdentifier<AbsoluteLocation> iid = IidFactory
                             .providerAddressEndpointLocationIid(NE_LOCATION_PROVIDER_NAME, IpPrefixType.class,
                                     endpoint.getAddress(), endpoint.getContextType(), endpoint.getContextId())
-                            .child(RealLocation.class)
-                            .build();
+                            .child(AbsoluteLocation.class);
                         wtx.put(LogicalDatastoreType.OPERATIONAL, iid, createRealLocation(ne.getIid(), iface.getIid()),
                                 true);
                         wtx.submit();
@@ -136,11 +135,10 @@ public class NeLocationProvider implements DataTreeChangeListener<NetworkElement
                             && endpoint.getAddressType().isAssignableFrom(IpPrefixType.class) && NetUtils
                                 .samePrefix(new IpPrefix(endpoint.getAddress().toCharArray()), en.getIpPrefix())) {
                         WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
-                        InstanceIdentifier<RealLocation> iid = IidFactory
+                        InstanceIdentifier<AbsoluteLocation> iid = IidFactory
                             .providerAddressEndpointLocationIid(NE_LOCATION_PROVIDER_NAME, IpPrefixType.class,
                                     endpoint.getAddress(), endpoint.getContextType(), endpoint.getContextId())
-                            .child(RealLocation.class)
-                            .build();
+                            .child(AbsoluteLocation.class);
                         wtx.delete(LogicalDatastoreType.OPERATIONAL, iid);
                         wtx.submit();
                         LOG.debug("Location deleted for endpoint {}", endpoint);
@@ -160,7 +158,7 @@ public class NeLocationProvider implements DataTreeChangeListener<NetworkElement
                     for (NetworkElement ne : nullToEmpty(nes.getNetworkElement())) {
                         for (Interface iface : nullToEmpty(ne.getInterface())) {
                             for (EndpointNetwork en : nullToEmpty(iface.getEndpointNetwork())) {
-                                processDeletedEN(en, ne.getIid(), iface.getIid());
+                                processDeletedEN(en);
                             }
                         }
                     }
@@ -174,7 +172,7 @@ public class NeLocationProvider implements DataTreeChangeListener<NetworkElement
                         for (NetworkElement ne : nullToEmpty(nes.getNetworkElement())) {
                             for (Interface iface : nullToEmpty(ne.getInterface())) {
                                 for (EndpointNetwork en : nullToEmpty(iface.getEndpointNetwork())) {
-                                    processDeletedEN(en, ne.getIid(), iface.getIid());
+                                    processDeletedEN(en);
                                 }
                             }
                         }
@@ -225,7 +223,7 @@ public class NeLocationProvider implements DataTreeChangeListener<NetworkElement
                 NetworkElement ne = netElement.getDataBefore();
                 for (Interface iface : nullToEmpty(ne.getInterface())) {
                     for (EndpointNetwork en : nullToEmpty(iface.getEndpointNetwork())) {
-                        processDeletedEN(en, ne.getIid(), iface.getIid());
+                        processDeletedEN(en);
                     }
                 }
                 networkElements.getNetworkElement().remove(ne);
@@ -237,7 +235,7 @@ public class NeLocationProvider implements DataTreeChangeListener<NetworkElement
                 if (ne != null) {
                     for (Interface iface : nullToEmpty(ne.getInterface())) {
                         for (EndpointNetwork en : nullToEmpty(iface.getEndpointNetwork())) {
-                            processDeletedEN(en, ne.getIid(), iface.getIid());
+                            processDeletedEN(en);
                         }
                     }
                     networkElements.getNetworkElement().remove(ne);
@@ -284,7 +282,7 @@ public class NeLocationProvider implements DataTreeChangeListener<NetworkElement
             case DELETE: {
                 Interface iface = modifiedInterface.getDataBefore();
                 for (EndpointNetwork en : nullToEmpty(iface.getEndpointNetwork())) {
-                    processDeletedEN(en, nodeBefore.getIid(), iface.getIid());
+                    processDeletedEN(en);
                 }
                 int nodeIndex = getIndexOf(nodeBefore);
                 networkElements.getNetworkElement().get(nodeIndex).getInterface().remove(iface);
@@ -296,7 +294,7 @@ public class NeLocationProvider implements DataTreeChangeListener<NetworkElement
                 int nodeIndex = getIndexOf(nodeBefore);
                 if (iface != null) {
                     for (EndpointNetwork en : nullToEmpty(iface.getEndpointNetwork())) {
-                        processDeletedEN(en, nodeBefore.getIid(), iface.getIid());
+                        processDeletedEN(en);
                     }
                     networkElements.getNetworkElement().get(nodeIndex).getInterface().remove(iface);
                 }
@@ -339,7 +337,7 @@ public class NeLocationProvider implements DataTreeChangeListener<NetworkElement
             NetworkElement nodeBefore, Interface ifaceBefore) {
         switch (modifiedEN.getModificationType()) {
             case DELETE: {
-                processDeletedEN(modifiedEN.getDataBefore(), nodeBefore.getIid(), ifaceBefore.getIid());
+                processDeletedEN(modifiedEN.getDataBefore());
                 int nodeIndex = getIndexOf(nodeBefore);
                 int ifaceIndex = getIndexOf(ifaceBefore, nodeIndex);
                 networkElements.getNetworkElement()
@@ -379,11 +377,10 @@ public class NeLocationProvider implements DataTreeChangeListener<NetworkElement
                     && endpoint.getContextId().equals(en.getL3ContextId())
                     && endpoint.getAddressType().isAssignableFrom(IpPrefixType.class)
                     && NetUtils.samePrefix(new IpPrefix(endpoint.getAddress().toCharArray()), en.getIpPrefix())) {
-                InstanceIdentifier<RealLocation> iid = IidFactory
+                InstanceIdentifier<AbsoluteLocation> iid = IidFactory
                     .providerAddressEndpointLocationIid(NE_LOCATION_PROVIDER_NAME, IpPrefixType.class,
                             endpoint.getAddress(), endpoint.getContextType(), endpoint.getContextId())
-                    .child(RealLocation.class)
-                    .build();
+                    .child(AbsoluteLocation.class);
                 wtx.put(LogicalDatastoreType.OPERATIONAL, iid, createRealLocation(nodeIID, connectorIID), true);
                 wtx.submit();
                 LOG.debug("New location created for endpoint {}", endpoint);
@@ -392,19 +389,17 @@ public class NeLocationProvider implements DataTreeChangeListener<NetworkElement
         }
     }
 
-    private void processDeletedEN(EndpointNetwork en, InstanceIdentifier<?> nodeIID,
-            InstanceIdentifier<?> connectorIID) {
+    private void processDeletedEN(EndpointNetwork en) {
         WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
         for (AddressEndpoint endpoint : endpoints) {
             if (endpoint.getContextType().isAssignableFrom(L3Context.class)
                     && endpoint.getContextId().equals(en.getL3ContextId())
                     && endpoint.getAddressType().isAssignableFrom(IpPrefixType.class)
                     && NetUtils.samePrefix(new IpPrefix(endpoint.getAddress().toCharArray()), en.getIpPrefix())) {
-                InstanceIdentifier<RealLocation> iid = IidFactory
+                InstanceIdentifier<AbsoluteLocation> iid = IidFactory
                     .providerAddressEndpointLocationIid(NE_LOCATION_PROVIDER_NAME, IpPrefixType.class,
                             endpoint.getAddress(), endpoint.getContextType(), endpoint.getContextId())
-                    .child(RealLocation.class)
-                    .build();
+                    .child(AbsoluteLocation.class);
                 wtx.delete(LogicalDatastoreType.OPERATIONAL, iid);
                 wtx.submit();
                 LOG.debug("Location deleted for endpoint {}", endpoint);
@@ -413,9 +408,9 @@ public class NeLocationProvider implements DataTreeChangeListener<NetworkElement
         }
     }
 
-    private RealLocation createRealLocation(InstanceIdentifier<?> node, InstanceIdentifier<?> iface) {
-        return new RealLocationBuilder()
-            .setLocationType(new RegularLocationCaseBuilder().setNode(node).setNodeConnector(iface).build()).build();
+    private AbsoluteLocation createRealLocation(InstanceIdentifier<?> node, InstanceIdentifier<?> iface) {
+        return new AbsoluteLocationBuilder()
+            .setLocationType(new InternalLocationCaseBuilder().setInternalNode(node).setInternalNodeConnector(iface).build()).build();
     }
 
     private <T> List<T> nullToEmpty(@Nullable List<T> list) {
index fc32605127c280886181714d6af9633d0b5db0b0..8f61ea2bf088f7f56baf6dfd95aca6927051179c 100644 (file)
@@ -39,6 +39,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpo
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.Endpoints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.NetworkContainment;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.NetworkContainmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.containment.NetworkDomainContainmentBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.AddressEndpoints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointBuilder;
@@ -150,7 +151,7 @@ public class NeLocationProviderTest extends CustomDataBrokerTest {
     public void test_AddressEndpointWrite_NoNE_Overwrite() throws Exception {
         test_AddressEndpointWrite_NoNE_NoOverwrite();
         NetworkContainment nc = new NetworkContainmentBuilder()
-                .setNetworkDomainId(new NetworkDomainId(L3_CONTEXT_ID))
+        .setContainment(new NetworkDomainContainmentBuilder().setNetworkDomainId(new NetworkDomainId(L3_CONTEXT_ID)).build())
                 .build();
         InstanceIdentifier<NetworkContainment> iid = InstanceIdentifier
                 .builder(Endpoints.class)
old mode 100644 (file)
new mode 100755 (executable)
index 6ec6191..0f92fac
@@ -5,17 +5,12 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.test.DataChangeListenerTester;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Prefix;
@@ -27,65 +22,55 @@ public class EndpointManagerListenerTest {
     private InstanceIdentifier<DataObject> endpointId;
     private AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change;
     private EndpointManager endpointManager;
-    private EndpointManagerListener endpointManagerListener;
+    private DataChangeListenerTester tester;
 
     @SuppressWarnings("unchecked")
     @Before
     public void init() {
         endpointId = mock(InstanceIdentifier.class);
-        change = mock(AsyncDataChangeEvent.class);
         endpointManager = mock(EndpointManager.class);
-        endpointId = mock(InstanceIdentifier.class);
         DataBroker dataProvider = mock(DataBroker.class);
-        endpointManagerListener = new EndpointManagerListener(dataProvider, endpointManager);
-        Set<InstanceIdentifier<?>> removedPaths = new HashSet<>();
-        removedPaths.add(endpointId);
-        when(change.getRemovedPaths()).thenReturn(removedPaths);
+
+        EndpointManagerListener endpointManagerListener =
+                new EndpointManagerListener(dataProvider, endpointManager);
+        tester = new DataChangeListenerTester(endpointManagerListener);
+        tester.setRemovedPath(endpointId);
     }
 
     @Test
     public void testOnDataChangeEndpoint() {
         DataObject endpoint = mock(Endpoint.class);
+        tester.setDataObject(endpointId, endpoint);
 
-        Map<InstanceIdentifier<?>, DataObject> testData = new HashMap<>();
-        testData.put(endpointId, endpoint);
-        when(change.getCreatedData()).thenReturn(testData);
-        when(change.getOriginalData()).thenReturn(testData);
-        when(change.getUpdatedData()).thenReturn(testData);
+        tester.callOnDataChanged();
 
-        endpointManagerListener.onDataChanged(change);
         verify(endpointManager, times(3)).processEndpoint(any(Endpoint.class), any(Endpoint.class));
-        verify(endpointManager, never()).processL3Endpoint(any(EndpointL3.class), any(EndpointL3.class));
+        verify(endpointManager, never()).processL3Endpoint(any(EndpointL3.class),
+                any(EndpointL3.class));
     }
 
     @Test
     public void testOnDataChangeEndpointL3() {
         DataObject endpoint = mock(EndpointL3.class);
-        Map<InstanceIdentifier<?>, DataObject> testData = new HashMap<>();
-        testData.put(endpointId, endpoint);
+        tester.setDataObject(endpointId, endpoint);
 
-        when(change.getCreatedData()).thenReturn(testData);
-        when(change.getOriginalData()).thenReturn(testData);
-        when(change.getUpdatedData()).thenReturn(testData);
+        tester.callOnDataChanged();
 
-        endpointManagerListener.onDataChanged(change);
         verify(endpointManager, never()).processEndpoint(any(Endpoint.class), any(Endpoint.class));
-        verify(endpointManager, times(3)).processL3Endpoint(any(EndpointL3.class), any(EndpointL3.class));
+        verify(endpointManager, times(3)).processL3Endpoint(any(EndpointL3.class),
+                any(EndpointL3.class));
     }
 
     @Test
     public void testOnDataChangeEndpointL3Prefix() {
         DataObject endpoint = mock(EndpointL3Prefix.class);
-        Map<InstanceIdentifier<?>, DataObject> testData = new HashMap<>();
-        testData.put(endpointId, endpoint);
+        tester.setDataObject(endpointId, endpoint);
 
-        when(change.getCreatedData()).thenReturn(testData);
-        when(change.getOriginalData()).thenReturn(testData);
-        when(change.getUpdatedData()).thenReturn(testData);
+        tester.callOnDataChanged();
 
-        endpointManagerListener.onDataChanged(change);
         verify(endpointManager, never()).processEndpoint(any(Endpoint.class), any(Endpoint.class));
-        verify(endpointManager, never()).processL3Endpoint(any(EndpointL3.class), any(EndpointL3.class));
+        verify(endpointManager, never()).processL3Endpoint(any(EndpointL3.class),
+                any(EndpointL3.class));
     }
 
-}
\ No newline at end of file
+}
diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ActionDefinitionListenerTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ActionDefinitionListenerTest.java
new file mode 100755 (executable)
index 0000000..64c6d10
--- /dev/null
@@ -0,0 +1,113 @@
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf;\r
+\r
+import static org.mockito.Matchers.any;\r
+import static org.mockito.Matchers.eq;\r
+import static org.mockito.Mockito.mock;\r
+import static org.mockito.Mockito.spy;\r
+import static org.mockito.Mockito.verify;\r
+import static org.mockito.Mockito.when;\r
+\r
+import java.util.Set;\r
+\r
+import com.google.common.collect.ImmutableSet;\r
+import com.google.common.util.concurrent.CheckedFuture;\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;\r
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;\r
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.groupbasedpolicy.api.sf.AllowActionDefinition;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.SubjectFeatureDefinitions;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ActionDefinition;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ActionDefinitionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ActionDefinitionKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.SupportedActionDefinition;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+\r
+public class ActionDefinitionListenerTest {\r
+\r
+    private ActionDefinitionListener listener;\r
+    private DataObjectModification<ActionDefinition> rootNode;\r
+    private Set<DataTreeModification<ActionDefinition>> changes;\r
+\r
+    private DataBroker dataProvider;\r
+\r
+    private InstanceIdentifier<ActionDefinition> rootIdentifier;\r
+\r
+    @SuppressWarnings("unchecked")\r
+    @Before\r
+    public void init() {\r
+\r
+        dataProvider = mock(DataBroker.class);\r
+\r
+        listener = spy(new ActionDefinitionListener(dataProvider));\r
+\r
+        ActionDefinitionKey key = mock(ActionDefinitionKey.class);\r
+\r
+        rootNode = mock(DataObjectModification.class);\r
+        rootIdentifier = InstanceIdentifier.builder(SubjectFeatureDefinitions.class)\r
+                .child(ActionDefinition.class, key)\r
+                .build();\r
+        DataTreeIdentifier<ActionDefinition> rootPath =\r
+                new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, rootIdentifier);\r
+\r
+        DataTreeModification<ActionDefinition> change = mock(DataTreeModification.class);\r
+\r
+        when(change.getRootNode()).thenReturn(rootNode);\r
+        when(change.getRootPath()).thenReturn(rootPath);\r
+\r
+        changes = ImmutableSet.of(change);\r
+\r
+        ActionDefinition def = new ActionDefinitionBuilder().setId(AllowActionDefinition.ID).build();\r
+\r
+        when(rootNode.getDataBefore()).thenReturn(def);\r
+        when(rootNode.getDataAfter()).thenReturn(def);\r
+    }\r
+\r
+    @Test\r
+    public void testOnDataTreeChanged_Write() {\r
+        when(rootNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);\r
+\r
+        WriteTransaction wt = resetTransaction();\r
+\r
+        listener.onDataTreeChanged(changes);\r
+\r
+        verify(wt).put(eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class),\r
+                any(SupportedActionDefinition.class), eq(true));\r
+    }\r
+\r
+    @Test\r
+    public void testOnDataTreeChanged_SubtreeModified() {\r
+        when(rootNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED);\r
+\r
+        WriteTransaction wt = resetTransaction();\r
+\r
+        listener.onDataTreeChanged(changes);\r
+\r
+        verify(wt).put(eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class),\r
+                any(SupportedActionDefinition.class), eq(true));\r
+    }\r
+\r
+    @Test\r
+    public void testOnDataTreeChanged_Delete() {\r
+        when(rootNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);\r
+\r
+        WriteTransaction wt = resetTransaction();\r
+\r
+        listener.onDataTreeChanged(changes);\r
+\r
+        verify(wt).delete(eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class));\r
+    }\r
+\r
+    private WriteTransaction resetTransaction() {\r
+        WriteTransaction wt = mock(WriteTransaction.class);\r
+        CheckedFuture checkedFuture = mock(CheckedFuture.class);\r
+        when(wt.submit()).thenReturn(checkedFuture);\r
+        when(dataProvider.newWriteOnlyTransaction()).thenReturn(wt);\r
+        return wt;\r
+    }\r
+\r
+}\r
diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ClassifierDefinitionListenerTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ClassifierDefinitionListenerTest.java
new file mode 100755 (executable)
index 0000000..dc4b387
--- /dev/null
@@ -0,0 +1,117 @@
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf;\r
+\r
+import static org.mockito.Matchers.any;\r
+import static org.mockito.Matchers.eq;\r
+import static org.mockito.Mockito.mock;\r
+import static org.mockito.Mockito.spy;\r
+import static org.mockito.Mockito.verify;\r
+import static org.mockito.Mockito.when;\r
+\r
+import java.util.Set;\r
+\r
+import com.google.common.collect.ImmutableSet;\r
+import com.google.common.util.concurrent.CheckedFuture;\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;\r
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;\r
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.SubjectFeatureDefinitions;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinitionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinitionKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.SupportedClassifierDefinition;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+\r
+public class ClassifierDefinitionListenerTest {\r
+\r
+    private ClassifierDefinitionListener listener;\r
+    private DataObjectModification<ClassifierDefinition> rootNode;\r
+    private Set<DataTreeModification<ClassifierDefinition>> changes;\r
+\r
+    private DataBroker dataProvider;\r
+\r
+    private InstanceIdentifier<ClassifierDefinition> rootIdentifier;\r
+\r
+    @SuppressWarnings("unchecked")\r
+    @Before\r
+    public void init() {\r
+\r
+        dataProvider = mock(DataBroker.class);\r
+\r
+        listener = spy(new ClassifierDefinitionListener(dataProvider));\r
+\r
+        ClassifierDefinitionKey key = mock(ClassifierDefinitionKey.class);\r
+\r
+        rootNode = mock(DataObjectModification.class);\r
+        rootIdentifier = InstanceIdentifier.builder(SubjectFeatureDefinitions.class)\r
+                .child(ClassifierDefinition.class, key)\r
+                .build();\r
+        DataTreeIdentifier<ClassifierDefinition> rootPath =\r
+                new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, rootIdentifier);\r
+\r
+        DataTreeModification<ClassifierDefinition> change = mock(DataTreeModification.class);\r
+\r
+        when(change.getRootNode()).thenReturn(rootNode);\r
+        when(change.getRootPath()).thenReturn(rootPath);\r
+\r
+        changes = ImmutableSet.of(change);\r
+\r
+        ClassifierDefinition def =\r
+                new ClassifierDefinitionBuilder().setId(EtherTypeClassifierDefinition.ID).build();\r
+\r
+        when(rootNode.getDataBefore()).thenReturn(def);\r
+        when(rootNode.getDataAfter()).thenReturn(def);\r
+    }\r
+\r
+    @Test\r
+    public void testOnDataTreeChanged_Write() {\r
+        when(rootNode.getModificationType()).thenReturn(\r
+                DataObjectModification.ModificationType.WRITE);\r
+\r
+        WriteTransaction wt = resetTransaction();\r
+\r
+        listener.onDataTreeChanged(changes);\r
+\r
+        verify(wt).put(eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class),\r
+                any(SupportedClassifierDefinition.class), eq(true));\r
+    }\r
+\r
+    @Test\r
+    public void testOnDataTreeChanged_SubtreeModified() {\r
+        when(rootNode.getModificationType()).thenReturn(\r
+                DataObjectModification.ModificationType.SUBTREE_MODIFIED);\r
+\r
+        WriteTransaction wt = resetTransaction();\r
+\r
+        listener.onDataTreeChanged(changes);\r
+\r
+        verify(wt).put(eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class),\r
+                any(SupportedClassifierDefinition.class), eq(true));\r
+    }\r
+\r
+    @Test\r
+    public void testOnDataTreeChanged_Delete() {\r
+        when(rootNode.getModificationType()).thenReturn(\r
+                DataObjectModification.ModificationType.DELETE);\r
+\r
+        WriteTransaction wt = resetTransaction();\r
+\r
+        listener.onDataTreeChanged(changes);\r
+\r
+        verify(wt).delete(eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class));\r
+    }\r
+\r
+    private WriteTransaction resetTransaction() {\r
+        WriteTransaction wt = mock(WriteTransaction.class);\r
+        CheckedFuture checkedFuture = mock(CheckedFuture.class);\r
+        when(wt.submit()).thenReturn(checkedFuture);\r
+        when(dataProvider.newWriteOnlyTransaction()).thenReturn(wt);\r
+        return wt;\r
+    }\r
+\r
+}\r
diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/statistics/ResolvedPolicyClassifierListenerTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/statistics/ResolvedPolicyClassifierListenerTest.java
new file mode 100755 (executable)
index 0000000..14baad9
--- /dev/null
@@ -0,0 +1,113 @@
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics;\r
+\r
+import static org.mockito.Mockito.mock;\r
+import static org.mockito.Mockito.spy;\r
+import static org.mockito.Mockito.verify;\r
+import static org.mockito.Mockito.when;\r
+\r
+import java.util.Set;\r
+\r
+import com.google.common.collect.ImmutableSet;\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;\r
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;\r
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition;\r
+import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.test.ParameterValueList;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.test.TestUtils;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RuleName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPolicies;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.Classifier;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.ClassifierBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicy;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicyKey;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+\r
+public class ResolvedPolicyClassifierListenerTest {\r
+\r
+    private ResolvedPolicyClassifierListener classifierListener;\r
+    private DataObjectModification<ResolvedPolicy> rootNode;\r
+    private Set<DataTreeModification<ResolvedPolicy>> changes;\r
+\r
+    private InstanceIdentifier<ResolvedPolicy> rootIdentifier;\r
+\r
+    private final EndpointGroupId consumerEpgId = new EndpointGroupId("consumerEpg1");\r
+    private final EndpointGroupId providerEpgId = new EndpointGroupId("providerEpg1");\r
+    private final ContractId contractId = new ContractId("contract1");\r
+    private final TenantId tenantId = new TenantId("tenant1");\r
+    private final ClassifierName classifierName = new ClassifierName("classifier1");\r
+    private final SubjectName subjectName = new SubjectName("subject1");\r
+    private final RuleName ruleName = new RuleName("rule1");\r
+\r
+    @SuppressWarnings("unchecked")\r
+    @Before\r
+    public void init() {\r
+        DataBroker dataProvider = mock(DataBroker.class);\r
+        OFStatisticsManager ofStatisticsManager = mock(OFStatisticsManager.class);\r
+\r
+        classifierListener = spy(new ResolvedPolicyClassifierListener(dataProvider, ofStatisticsManager));\r
+\r
+        ResolvedPolicyKey key = mock(ResolvedPolicyKey.class);\r
+        rootNode = mock(DataObjectModification.class);\r
+        rootIdentifier = InstanceIdentifier.builder(ResolvedPolicies.class).child(ResolvedPolicy.class, key).build();\r
+        DataTreeIdentifier<ResolvedPolicy> rootPath =\r
+                new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, rootIdentifier);\r
+\r
+        DataTreeModification<ResolvedPolicy> change = mock(DataTreeModification.class);\r
+\r
+        when(change.getRootNode()).thenReturn(rootNode);\r
+        when(change.getRootPath()).thenReturn(rootPath);\r
+\r
+        changes = ImmutableSet.of(change);\r
+\r
+        ParameterValueList parameterValues = new ParameterValueList();\r
+        parameterValues.addEthertype(EtherTypeClassifierDefinition.IPv4_VALUE)\r
+            .addProto(IpProtoClassifierDefinition.TCP_VALUE);\r
+\r
+        Classifier classifier = new ClassifierBuilder().setName(classifierName)\r
+            .setClassifierDefinitionId(IpProtoClassifierDefinition.ID)\r
+            .setParameterValue(parameterValues)\r
+            .build();\r
+        ResolvedPolicy rp = TestUtils.newResolvedPolicy(tenantId, contractId, subjectName, ruleName, consumerEpgId,\r
+                providerEpgId, classifier);\r
+        when(rootNode.getDataBefore()).thenReturn(rp);\r
+        when(rootNode.getDataAfter()).thenReturn(rp);\r
+    }\r
+\r
+    @Test\r
+    public void testOnWrite() {\r
+        when(rootNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);\r
+\r
+        classifierListener.onDataTreeChanged(changes);\r
+\r
+        verify(classifierListener).onWrite(rootNode, rootIdentifier);\r
+    }\r
+\r
+    @Test\r
+    public void testOnDelete() {\r
+        when(rootNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);\r
+\r
+        classifierListener.onDataTreeChanged(changes);\r
+\r
+        verify(classifierListener).onDelete(rootNode, rootIdentifier);\r
+    }\r
+\r
+    @Test\r
+    public void testOnSubtreeModified() {\r
+        when(rootNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED);\r
+\r
+        classifierListener.onDataTreeChanged(changes);\r
+\r
+        verify(classifierListener).onSubtreeModified(rootNode, rootIdentifier);\r
+    }\r
+\r
+}\r
diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/statistics/SflowClientSettingsListenerTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/statistics/SflowClientSettingsListenerTest.java
new file mode 100755 (executable)
index 0000000..3495329
--- /dev/null
@@ -0,0 +1,89 @@
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics;\r
+\r
+import static org.mockito.Mockito.mock;\r
+import static org.mockito.Mockito.spy;\r
+import static org.mockito.Mockito.times;\r
+import static org.mockito.Mockito.verify;\r
+import static org.mockito.Mockito.when;\r
+\r
+import java.util.Set;\r
+import java.util.concurrent.ScheduledExecutorService;\r
+\r
+import com.google.common.collect.ImmutableSet;\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;\r
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;\r
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.groupbasedpolicy.api.StatisticsManager;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayConfig;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.sflow.values.SflowClientSettings;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+\r
+public class SflowClientSettingsListenerTest {\r
+\r
+    private SflowClientSettingsListener listener;\r
+    private DataObjectModification<SflowClientSettings> rootNode;\r
+    private Set<DataTreeModification<SflowClientSettings>> changes;\r
+\r
+    private InstanceIdentifier<SflowClientSettings> rootIdentifier;\r
+\r
+    @SuppressWarnings("unchecked")\r
+    @Before\r
+    public void init() {\r
+        DataBroker dataProvider = mock(DataBroker.class);\r
+\r
+        StatisticsManager ofStatisticsManager = mock(StatisticsManager.class);\r
+        ScheduledExecutorService executor = mock(ScheduledExecutorService.class);\r
+        listener = spy(new SflowClientSettingsListener(dataProvider, executor, ofStatisticsManager));\r
+\r
+        SflowClientSettings sflowClientSettings = mock(SflowClientSettings.class);\r
+\r
+        rootNode = mock(DataObjectModification.class);\r
+        rootIdentifier = InstanceIdentifier.builder(OfOverlayConfig.class).child(SflowClientSettings.class).build();\r
+        DataTreeIdentifier<SflowClientSettings> rootPath =\r
+                new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, rootIdentifier);\r
+\r
+        DataTreeModification<SflowClientSettings> change = mock(DataTreeModification.class);\r
+\r
+        when(change.getRootNode()).thenReturn(rootNode);\r
+        when(change.getRootPath()).thenReturn(rootPath);\r
+\r
+        changes = ImmutableSet.of(change);\r
+\r
+        when(rootNode.getDataBefore()).thenReturn(sflowClientSettings);\r
+        when(rootNode.getDataAfter()).thenReturn(sflowClientSettings);\r
+    }\r
+\r
+    @Test\r
+    public void testOnWrite() {\r
+        when(rootNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);\r
+\r
+        listener.onDataTreeChanged(changes);\r
+\r
+        verify(listener).onWrite(rootNode, rootIdentifier);\r
+    }\r
+\r
+    @Test\r
+    public void testOnDelete() {\r
+        when(rootNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);\r
+\r
+        listener.onDataTreeChanged(changes);\r
+\r
+        verify(listener).onDelete(rootNode, rootIdentifier);\r
+    }\r
+\r
+    @Test\r
+    public void testOnSubtreeModified() {\r
+        when(rootNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED);\r
+\r
+        // first call will initialize uninitialized dependencies;\r
+        // second call will call #close on them\r
+        listener.onDataTreeChanged(changes);\r
+        listener.onDataTreeChanged(changes);\r
+        verify(listener, times(2)).onSubtreeModified(rootNode, rootIdentifier);\r
+    }\r
+\r
+}\r
index d6322ffb5edb604a2f8c2d37fb375d68d4eb3cba..4d3ede3f9f81b83633ed0e6e00f6bd2a0d083907 100755 (executable)
@@ -4,7 +4,6 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;\r
 import static org.junit.Assert.assertTrue;\r
 \r
-import java.util.ArrayList;\r
 import java.util.Arrays;\r
 import java.util.List;\r
 \r
@@ -17,17 +16,15 @@ import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.ResolvedPolicyClassifierListener;\r
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.util.FlowCacheCons;\r
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.util.IidSflowNameUtil;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.test.ParameterValueList;\r
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.test.TestUtils;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RuleName;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.Classifier;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.ClassifierBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicy;\r
@@ -241,37 +238,4 @@ public class FlowCacheFactoryTest {
                 FlowCacheCons.Value.BYTES);\r
     }\r
 \r
-    @SuppressWarnings("serial")\r
-    private class ParameterValueList extends ArrayList<ParameterValue> {\r
-\r
-        ParameterValueList() {\r
-            super();\r
-        }\r
-\r
-        private ParameterValueList addEthertype(Long value) {\r
-            this.add(newParameterValue(EtherTypeClassifierDefinition.ETHERTYPE_PARAM, value));\r
-            return this;\r
-        }\r
-\r
-        private ParameterValueList addProto(Long value) {\r
-            this.add(newParameterValue(IpProtoClassifierDefinition.PROTO_PARAM, value));\r
-            return this;\r
-        }\r
-\r
-        private ParameterValueList addDstPort(Long value) {\r
-            this.add(newParameterValue(L4ClassifierDefinition.DST_PORT_PARAM, value));\r
-            return this;\r
-        }\r
-\r
-        private ParameterValueList addSrcPort(Long value) {\r
-            this.add(newParameterValue(L4ClassifierDefinition.SRC_PORT_PARAM, value));\r
-            return this;\r
-        }\r
-\r
-        private ParameterValue newParameterValue(String parameterName, Long intValue) {\r
-            return new ParameterValueBuilder().setName(new ParameterName(parameterName)).setIntValue(intValue).build();\r
-        }\r
-\r
-    }\r
-\r
 }\r
diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/test/DataChangeListenerTester.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/test/DataChangeListenerTester.java
new file mode 100755 (executable)
index 0000000..9a79e8d
--- /dev/null
@@ -0,0 +1,63 @@
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.test;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class DataChangeListenerTester {
+
+    private AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeMock;
+    private DataChangeListener listener;
+
+    private Map<InstanceIdentifier<?>, DataObject> testData;
+    private Set<InstanceIdentifier<?>> removedPaths;
+
+    @SuppressWarnings("unchecked")
+    public DataChangeListenerTester(DataChangeListener listener) {
+        changeMock = mock(AsyncDataChangeEvent.class);
+        testData = new HashMap<>();
+        removedPaths = new HashSet<>();
+
+        this.listener = listener;
+
+        when(changeMock.getCreatedData()).thenReturn(testData);
+        when(changeMock.getOriginalData()).thenReturn(testData);
+        when(changeMock.getUpdatedData()).thenReturn(testData);
+        when(changeMock.getRemovedPaths()).thenReturn(removedPaths);
+    }
+
+    public DataChangeListenerTester setDataObject(InstanceIdentifier<DataObject> iid, DataObject dataObject){
+        testData.clear();
+        return addDataObject(iid, dataObject);
+    }
+
+    public DataChangeListenerTester addDataObject(InstanceIdentifier<DataObject> iid, DataObject dataObject){
+        testData.put(iid, dataObject);
+        return this;
+    }
+
+    public DataChangeListenerTester setRemovedPath(InstanceIdentifier<DataObject> iid){
+        removedPaths.clear();
+        return addRemovedPath(iid);
+    }
+
+    public DataChangeListenerTester addRemovedPath(InstanceIdentifier<DataObject> iid){
+        removedPaths.add(iid);
+        return this;
+    }
+
+    public void callOnDataChanged(){
+        listener.onDataChanged(changeMock);
+    }
+}
diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/test/ParameterValueList.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/test/ParameterValueList.java
new file mode 100755 (executable)
index 0000000..f1a44ac
--- /dev/null
@@ -0,0 +1,44 @@
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.test;
+
+import java.util.ArrayList;
+
+import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition;
+import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition;
+import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.flowcache.FlowCacheFactoryTest;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;
+
+public class ParameterValueList extends ArrayList<ParameterValue> {
+
+    public ParameterValueList() {
+        super();
+    }
+
+    public ParameterValueList addEthertype(Long value) {
+        this.add(newParameterValue(EtherTypeClassifierDefinition.ETHERTYPE_PARAM, value));
+        return this;
+    }
+
+    public ParameterValueList addProto(Long value) {
+        this.add(newParameterValue(IpProtoClassifierDefinition.PROTO_PARAM, value));
+        return this;
+    }
+
+    public ParameterValueList addDstPort(Long value) {
+        this.add(newParameterValue(L4ClassifierDefinition.DST_PORT_PARAM, value));
+        return this;
+    }
+
+    public ParameterValueList addSrcPort(Long value) {
+        this.add(newParameterValue(L4ClassifierDefinition.SRC_PORT_PARAM, value));
+        return this;
+    }
+
+    public ParameterValue newParameterValue(String parameterName, Long intValue) {
+        return new ParameterValueBuilder().setName(new ParameterName(parameterName))
+                .setIntValue(intValue).build();
+    }
+
+}
index 89bc8f48cab0dea1e27dc461a479e214d608bd39..5723fae84ff91eee4214bb3c34d0c3e5298ae4a8 100644 (file)
@@ -23,6 +23,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpo
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.NetworkContainment;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.NetworkContainmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.containment.NetworkDomainContainmentBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.AddressEndpoints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
@@ -73,8 +74,10 @@ public class SxpMapperReactorImpl implements SxpMapperReactor {
         // apply sxpMasterDB to policy template
         final Ipv4Prefix address = new Ipv4Prefix(epForwardingTemplate.getIpPrefix().getIpv4Prefix().getValue());
         final NetworkContainment networkContainment = new NetworkContainmentBuilder()
+            .setContainment(new NetworkDomainContainmentBuilder()
             .setNetworkDomainType(epForwardingTemplate.getNetworkContainment().getNetworkDomainType())
             .setNetworkDomainId(epForwardingTemplate.getNetworkContainment().getNetworkDomainId())
+            .build())
             .build();
         final RegisterEndpointInput epInput = new RegisterEndpointInputBuilder()
                 .setAddressEndpointReg(Collections.singletonList(new AddressEndpointRegBuilder()