Merge "remove redundant parent data with last child"
authorVladimir Lavor <vlavor@cisco.com>
Thu, 2 Feb 2017 14:00:50 +0000 (14:00 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 2 Feb 2017 14:00:50 +0000 (14:00 +0000)
61 files changed:
domain-extensions/l2-l3/pom.xml
features/pom.xml
features/src/main/features/features.xml
groupbasedpolicy-ui/module/src/main/resources/gbp/common/gbp.module.js
groupbasedpolicy/pom.xml
groupbasedpolicy/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/DomainSpecificRegistryInstance.java
groupbasedpolicy/src/main/java/org/opendaylight/controller/config/yang/config/groupbasedpolicy/EpRendererAugmentationRegistryImplInstance.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/RendererConfigurationBuilder.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/RendererManager.java
groupbasedpolicy/src/main/resources/org/opendaylight/blueprint/groupbasedpolicy.xml
location-providers/ne-location-provider/pom.xml
neutron-mapper/pom.xml
neutron-mapper/src/main/java/org/opendaylight/controller/config/yang/config/neutron_mapper/impl/NeutronMapperInstance.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/EndpointRegistrator.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/NeutronMapper.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAware.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronRouterAware.java
neutron-mapper/src/main/resources/org/opendaylight/blueprint/neutron-mapper.xml
neutron-ovsdb/pom.xml
neutron-ovsdb/src/main/java/org/opendaylight/controller/config/yang/config/neutron_ovsdb/impl/NeutronOvsdbInstance.java
neutron-ovsdb/src/main/resources/org/opendaylight/blueprint/neutron-ovsdb.xml
neutron-vpp-mapper/pom.xml
neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/NeutronVppMapper.java
neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/hostconfigs/VppNodeListener.java
neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/NeutronListener.java
neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/PortHandler.java
neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/NeutronListenerTest.java
neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/PortHandlerTest.java
neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/TestUtils.java
pom.xml
renderers/faas/pom.xml
renderers/ios-xe/pom.xml
renderers/iovisor/pom.xml
renderers/netconf/pom.xml
renderers/ofoverlay/pom.xml
renderers/ovssfc/pom.xml
renderers/vpp/pom.xml
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/adapter/VppRpcServiceImpl.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManager.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/manager/VppNodeManager.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/ForwardingManager.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/PolicyContext.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/RendererResolvedPolicy.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/GbpNetconfTransaction.java
renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/RendererResolvedPolicyTest.java [new file with mode: 0644]
renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/GbpNetconfTransactionTest.java
sxp-integration/ip-sgt-distribution-service/pom.xml [moved from ip-sgt-distribution-service/pom.xml with 95% similarity]
sxp-integration/ip-sgt-distribution-service/src/main/config/default-config.xml [moved from ip-sgt-distribution-service/src/main/config/default-config.xml with 100% similarity]
sxp-integration/ip-sgt-distribution-service/src/main/java/org/opendaylight/controller/config/yang/config/ip/sgt/distribution/service/cfg/IpSgtDistributionServiceInstance.java [moved from ip-sgt-distribution-service/src/main/java/org/opendaylight/controller/config/yang/config/ip/sgt/distribution/service/cfg/IpSgtDistributionServiceInstance.java with 100% similarity]
sxp-integration/ip-sgt-distribution-service/src/main/java/org/opendaylight/controller/config/yang/config/ip/sgt/distribution/service/cfg/IpSgtDistributionServiceModule.java [moved from ip-sgt-distribution-service/src/main/java/org/opendaylight/controller/config/yang/config/ip/sgt/distribution/service/cfg/IpSgtDistributionServiceModule.java with 100% similarity]
sxp-integration/ip-sgt-distribution-service/src/main/java/org/opendaylight/controller/config/yang/config/ip/sgt/distribution/service/cfg/IpSgtDistributionServiceModuleFactory.java [moved from ip-sgt-distribution-service/src/main/java/org/opendaylight/controller/config/yang/config/ip/sgt/distribution/service/cfg/IpSgtDistributionServiceModuleFactory.java with 100% similarity]
sxp-integration/ip-sgt-distribution-service/src/main/java/org/opendaylight/groupbasedpolicy/ip/sgt/distribution/service/impl/IpSgtDistributionServiceImpl.java [moved from ip-sgt-distribution-service/src/main/java/org/opendaylight/groupbasedpolicy/ip/sgt/distribution/service/impl/IpSgtDistributionServiceImpl.java with 100% similarity]
sxp-integration/ip-sgt-distribution-service/src/main/java/org/opendaylight/groupbasedpolicy/ip/sgt/distribution/service/impl/SxpCapableNodeListener.java [moved from ip-sgt-distribution-service/src/main/java/org/opendaylight/groupbasedpolicy/ip/sgt/distribution/service/impl/SxpCapableNodeListener.java with 100% similarity]
sxp-integration/ip-sgt-distribution-service/src/main/resources/org/opendaylight/blueprint/ip-sgt-distribution-service.xml [moved from ip-sgt-distribution-service/src/main/resources/org/opendaylight/blueprint/ip-sgt-distribution-service.xml with 100% similarity]
sxp-integration/ip-sgt-distribution-service/src/main/yang/ip-sgt-distribution-service-cfg.yang [moved from ip-sgt-distribution-service/src/main/yang/ip-sgt-distribution-service-cfg.yang with 100% similarity]
sxp-integration/ip-sgt-distribution-service/src/main/yang/ip-sgt-distribution.yang [moved from ip-sgt-distribution-service/src/main/yang/ip-sgt-distribution.yang with 100% similarity]
sxp-integration/ip-sgt-distribution-service/src/test/java/org/opendaylight/groupbasedpolicy/ip/sgt/distribution/service/impl/IpSgtDistributionServiceImplTest.java [moved from ip-sgt-distribution-service/src/test/java/org/opendaylight/groupbasedpolicy/ip/sgt/distribution/service/impl/IpSgtDistributionServiceImplTest.java with 100% similarity]
sxp-integration/ip-sgt-distribution-service/src/test/java/org/opendaylight/groupbasedpolicy/ip/sgt/distribution/service/impl/SxpCapableNodeListenerTest.java [moved from ip-sgt-distribution-service/src/test/java/org/opendaylight/groupbasedpolicy/ip/sgt/distribution/service/impl/SxpCapableNodeListenerTest.java with 79% similarity]
sxp-integration/pom.xml
sxp-integration/sxp-ep-provider/pom.xml
sxp-integration/sxp-ise-adapter/pom.xml

index ea2e327f30af7f4de5988e5c6dc7f51f73a86ea3..dee13bee2fe9c9f5e288d4cf5f376582bf82ae00 100644 (file)
@@ -26,7 +26,7 @@
     </dependency>
     <dependency>
       <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
+      <artifactId>mockito-core</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
index 658a9d4baa3562b426d3dbfa63ef5ed263865aa2..70b4452e8aa8fbf8e82fe270122f08525d3c7f41 100755 (executable)
@@ -39,6 +39,8 @@
     <sxp.version>1.4.0-SNAPSHOT</sxp.version>
     <netconf.version>1.2.0-SNAPSHOT</netconf.version>
     <vbd.version>1.1.0-SNAPSHOT</vbd.version>
+    <!-- for jolokia -->
+    <feature.controller.extras.version>1.8.0-SNAPSHOT</feature.controller.extras.version>
   </properties>
 
   <dependencyManagement>
         <type>pom</type>
       </dependency>
 
+      <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>features-extras</artifactId>
+        <version>${feature.controller.extras.version}</version>
+        <classifier>features</classifier>
+        <type>xml</type>
+      </dependency>
+
+
       <!-- netconf -->
       <dependency>
         <groupId>org.opendaylight.netconf</groupId>
       <type>xml</type>
       <scope>runtime</scope>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>features-extras</artifactId>
+      <classifier>features</classifier>
+      <type>xml</type>
+    </dependency>
 
     <!-- Openflow plugin -->
     <dependency>
index 09ade0412db20dadaf9de45ae3621f9e15b18c70..a555ef27877a9da3a66aa0a2e2d7978abea6b263 100755 (executable)
@@ -15,6 +15,7 @@
     <repository>mvn:org.opendaylight.mdsal/features-mdsal/{{VERSION}}/xml/features</repository>
     <repository>mvn:org.opendaylight.controller/features-mdsal/{{VERSION}}/xml/features</repository>
     <repository>mvn:org.opendaylight.mdsal.model/features-mdsal-model/{{VERSION}}/xml/features</repository>
+    <repository>mvn:org.opendaylight.controller/features-extras/{{VERSION}}/xml/features</repository>
     <!-- Repos needed by the OpenFlow Overlay renderer -->
     <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/{{VERSION}}/xml/features</repository>
     <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin-extension/{{VERSION}}/xml/features</repository>
     <feature name='odl-groupbasedpolicy-vpp' version='${project.version}' description='OpenDaylight :: groupbasedpolicy :: VPP renderer '>
         <feature version="${project.version}">odl-groupbasedpolicy-base</feature>
         <feature version="${netconf.version}">odl-netconf-clustered-topology</feature>
-        <feature version="${vbd.version}">odl-vbd-api</feature>
+        <feature version="${vbd.version}">odl-vbd</feature>
         <bundle>mvn:org.opendaylight.groupbasedpolicy/l2-l3-domain-extension/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.groupbasedpolicy/vpp-renderer/{{VERSION}}</bundle>
         <configfile finalname="${config.configfile.directory}/15-l2-l3-domain-extension.xml">mvn:org.opendaylight.groupbasedpolicy/l2-l3-domain-extension/{{VERSION}}/xml/config</configfile>
         <bundle>mvn:org.opendaylight.groupbasedpolicy/sxp-ep-provider/{{VERSION}}</bundle>
         <configfile finalname="${config.configfile.directory}/15-groupbasedpolicy-sxp-ep-provider.xml">mvn:org.opendaylight.groupbasedpolicy/sxp-ep-provider/{{VERSION}}/xml/config</configfile>
     </feature>
-    <feature name='odl-groupbasedpolicy-sxp-mapper' version='${project.version}' description='OpenDaylight :: groupbasedpolicy :: sxp-mapper'>
-        <!-- TODO: remove later - this is temporary "feature-forwarding" in order to keep integration feature test working -->
-        <feature version="${project.version}">odl-groupbasedpolicy-sxp-ep-provider</feature>
-    </feature>
 
     <!--
        GBP-SXP integration : ise-adapter
index b5217026382a0becc82e9f639b253bbd2b9f6e3a..61ead7564207f5687c8dac4d546242340d25c087 100644 (file)
@@ -18,7 +18,7 @@ define([
     gbp.register = gbp; // for adding services, controllers, directives etc. to angular module before bootstrap
 
     gbp.config(function ($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider,
-                         $translateProvider, $translatePartialLoaderProvider, $mdThemingProvider) {
+                         $translateProvider, $translatePartialLoaderProvider, $urlRouterProvider, $mdThemingProvider) {
         gbp.register = {
             controller: $controllerProvider.register,
             directive: $compileProvider.directive,
@@ -26,6 +26,8 @@ define([
             service: $provide.service,
         };
 
+        $urlRouterProvider.otherwise('/gbp/index');
+
         /*$translatePartialLoaderProvider.addPart('app/gbp/assets/data/locale');*/
 
         NavHelperProvider.addControllerUrl('app/gbp/common/gbp.controller');
index e4961e4e55ce52d482e194b04b25fd67795981fe..c8573aea2b24f01cf3cbbb3cb5ef12b67f441224 100755 (executable)
@@ -56,7 +56,7 @@
     </dependency>
     <dependency>
       <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
+      <artifactId>mockito-core</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
index 6034b415687e376f50da1567e22f3198f10376ae..02653c691eebe2949670b0bf11c975a466b8b32b 100644 (file)
@@ -8,11 +8,13 @@
 
 package org.opendaylight.controller.config.yang.config.groupbasedpolicy;
 
-import java.util.concurrent.Future;
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.Future;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.groupbasedpolicy.api.DomainSpecificRegistry;
 import org.opendaylight.groupbasedpolicy.api.EndpointAugmentorRegistry;
 import org.opendaylight.groupbasedpolicy.api.NetworkDomainAugmentorRegistry;
@@ -39,16 +41,20 @@ public class DomainSpecificRegistryInstance implements ClusterSingletonService,
             ServiceGroupIdentifier.create(GroupbasedpolicyInstance.GBP_SERVICE_GROUP_IDENTIFIER);
     private final DataBroker dataBroker;
     private ClusterSingletonServiceProvider clusterSingletonService;
+    private final RpcProviderRegistry rpcProviderRegistry;
     private ClusterSingletonServiceRegistration singletonServiceRegistration;
     private EndpointAugmentorRegistryImpl endpointAugmentorRegistryImpl;
     private NetworkDomainAugmentorRegistryImpl netDomainAugmentorRegistryImpl;
     private BaseEndpointServiceImpl baseEndpointServiceImpl;
     private RendererManager rendererManager;
+    private BindingAwareBroker.RpcRegistration<BaseEndpointService> baseEndpointServiceRpcRegistration;
 
     public DomainSpecificRegistryInstance(final DataBroker dataBroker,
-                                          final ClusterSingletonServiceProvider clusterSingletonService) {
+                                          final ClusterSingletonServiceProvider clusterSingletonService,
+                                          final RpcProviderRegistry rpcProviderRegistry) {
         this.dataBroker = Preconditions.checkNotNull(dataBroker);
         this.clusterSingletonService = Preconditions.checkNotNull(clusterSingletonService);
+        this.rpcProviderRegistry = Preconditions.checkNotNull(rpcProviderRegistry);
     }
 
     @Override
@@ -83,13 +89,17 @@ public class DomainSpecificRegistryInstance implements ClusterSingletonService,
         netDomainAugmentorRegistryImpl = new NetworkDomainAugmentorRegistryImpl();
         baseEndpointServiceImpl = new BaseEndpointServiceImpl(dataBroker, endpointAugmentorRegistryImpl);
         rendererManager = new RendererManager(dataBroker, netDomainAugmentorRegistryImpl, endpointAugmentorRegistryImpl);
+
+        baseEndpointServiceRpcRegistration = rpcProviderRegistry.addRpcImplementation(BaseEndpointService.class, this);
     }
 
     @Override
     public ListenableFuture<Void> closeServiceInstance() {
         LOG.info("Instance {} closed", this.getClass().getSimpleName());
         baseEndpointServiceImpl.close();
+        baseEndpointServiceRpcRegistration.close();
         rendererManager.close();
+
         return Futures.immediateFuture(null);
     }
 
index 3a5374c9fa52ebc9ccbd97f434d21c855bfadd58..c498ab37029ff96f9e28632e1e45170355ec691b 100644 (file)
@@ -8,11 +8,13 @@
 
 package org.opendaylight.controller.config.yang.config.groupbasedpolicy;
 
-import java.util.concurrent.Future;
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.Future;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.groupbasedpolicy.api.EpRendererAugmentation;
 import org.opendaylight.groupbasedpolicy.api.EpRendererAugmentationRegistry;
 import org.opendaylight.groupbasedpolicy.endpoint.EndpointRpcRegistry;
@@ -38,13 +40,17 @@ public class EpRendererAugmentationRegistryImplInstance implements ClusterSingle
             ServiceGroupIdentifier.create(GroupbasedpolicyInstance.GBP_SERVICE_GROUP_IDENTIFIER);
     private final DataBroker dataBroker;
     private ClusterSingletonServiceProvider clusterSingletonService;
+    private final RpcProviderRegistry rpcProviderRegistry;
     private ClusterSingletonServiceRegistration singletonServiceRegistration;
     private EndpointRpcRegistry endpointRpcRegistry;
+    private BindingAwareBroker.RpcRegistration<EndpointService> serviceRpcRegistration;
 
     public EpRendererAugmentationRegistryImplInstance(final DataBroker dataBroker,
-                                                      final ClusterSingletonServiceProvider clusterSingletonService) {
+                                                      final ClusterSingletonServiceProvider clusterSingletonService,
+                                                      final RpcProviderRegistry rpcProviderRegistry) {
         this.dataBroker = Preconditions.checkNotNull(dataBroker);
         this.clusterSingletonService = Preconditions.checkNotNull(clusterSingletonService);
+        this.rpcProviderRegistry = rpcProviderRegistry;
     }
 
     @Override
@@ -91,12 +97,15 @@ public class EpRendererAugmentationRegistryImplInstance implements ClusterSingle
     public void instantiateServiceInstance() {
         LOG.info("Instantiating {}", this.getClass().getSimpleName());
         endpointRpcRegistry = new EndpointRpcRegistry(dataBroker);
+
+        serviceRpcRegistration = rpcProviderRegistry.addRpcImplementation(EndpointService.class, this);
     }
 
     @Override
     public ListenableFuture<Void> closeServiceInstance() {
         LOG.info("Instance {} closed", this.getClass().getSimpleName());
         endpointRpcRegistry.close();
+        serviceRpcRegistration.close();
         return Futures.immediateFuture(null);
     }
 
index 00b343670899bea860a900363b7426550cdd4150..4799c960d8090c14316e93c89b1461a177fabe3c 100644 (file)
@@ -78,9 +78,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.p
 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.Augmentation;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class RendererConfigurationBuilder {
 
+    private static final Logger LOG = LoggerFactory.getLogger(RendererConfigurationBuilder.class);
+
     private final Table<RendererEndpointKey, PeerEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByEpAndPeerEp =
             HashBasedTable.create();
     private final Table<RendererEndpointKey, PeerExternalEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByEpAndPeerExtEp =
@@ -265,8 +269,8 @@ public class RendererConfigurationBuilder {
         return peerExtContEps;
     }
 
-    public Endpoints buildEndoints(EndpointInfo epInfo, EndpointLocationInfo epLocInfo,
-            Map<InstanceIdentifier<?>, RendererName> rendererByNode, Set<EndpointAugmentor> augmentors) {
+    public Endpoints buildEndpoints(EndpointInfo epInfo, EndpointLocationInfo epLocInfo,
+                                    Map<InstanceIdentifier<?>, RendererName> rendererByNode, Set<EndpointAugmentor> augmentors) {
         List<AddressEndpointWithLocation> epsWithLoc =
                 resolveEpsWithLoc(getAddressEndpointKeys(), epInfo, epLocInfo, rendererByNode, augmentors);
         List<ContainmentEndpointWithLocation> contEpsWithLoc =
@@ -286,6 +290,10 @@ public class RendererConfigurationBuilder {
             Optional<AddressEndpointLocation> potentionalEpLoc = epLocInfo.getAdressEndpointLocation(epKey);
             Preconditions.checkArgument(potentionalEpLoc.isPresent());
             RendererName rendererName = resolveRendererName(potentionalEpLoc.get(), rendererByNode);
+            if (rendererName == null) {
+                LOG.debug("Endpoint {} has no location, skipped", epKey);
+                continue;
+            }
             result.add(createEpWithLoc(potentialEp.get(), potentionalEpLoc.get(), rendererName, augmentors));
         }
         return result;
index c4590ee04d80f9330a8363d31411c1f6efb3efb5..5393971525bb36ceeb1e7ba23475f0fb0183e08c 100644 (file)
@@ -290,7 +290,7 @@ public class RendererManager implements AutoCloseable {
     private boolean writeRenderersConfigs(Map<RendererName, Optional<Configuration>> configsByRendererName) {
         List<Renderer> renderers = new ArrayList<>();
         for (RendererName rendererName : configsByRendererName.keySet()) {
-            RendererPolicy rendererPolicy = null;
+            RendererPolicy rendererPolicy;
             if (configsByRendererName.get(rendererName).isPresent()) {
                 rendererPolicy = new RendererPolicyBuilder().setVersion(version)
                         .setConfiguration(configsByRendererName.get(rendererName).get())
@@ -358,7 +358,7 @@ public class RendererManager implements AutoCloseable {
         configBuilder.setRendererEndpoints(rendererEndpoints);
 
         org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.Endpoints endpoints =
-                rendererPolicyBuilder.buildEndoints(currentState.epInfo, currentState.epLocInfo,
+                rendererPolicyBuilder.buildEndpoints(currentState.epInfo, currentState.epLocInfo,
                         currentState.rendererByNode, epAugmentorRegistry.getEndpointAugmentors());
         configBuilder.setEndpoints(endpoints);
 
index c18645872991e24e26d9c3374935e9a496ffd041..45b657c43b4e344f9d4c89cd42c609183fbd56e0 100644 (file)
@@ -5,31 +5,34 @@
 
     <reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"/>
     <reference id="clusterSingletonService" interface="org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider"/>
+    <reference id="rpcRegistry" interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry"/>
 
     <!-- Modules /-->
     <bean id="groupbasedpolicy" class="org.opendaylight.controller.config.yang.config.groupbasedpolicy.GroupbasedpolicyInstance"
-        init-method="initialize" destroy-method="close">
+          init-method="initialize" destroy-method="close">
         <argument ref="dataBroker"/>
         <argument ref="policyValidatorRegistry"/>
         <argument ref="clusterSingletonService"/>
     </bean>
     <bean id="domainSpecificRegistry" class="org.opendaylight.controller.config.yang.config.groupbasedpolicy.DomainSpecificRegistryInstance"
-        init-method="initialize" destroy-method="close">
+          init-method="initialize" destroy-method="close">
         <argument ref="dataBroker"/>
         <argument ref="clusterSingletonService"/>
+        <argument ref="rpcRegistry"/>
     </bean>
     <bean id="epRendererAugmentationRegistry" class="org.opendaylight.controller.config.yang.config.groupbasedpolicy.EpRendererAugmentationRegistryImplInstance"
-        init-method="initialize" destroy-method="close">
+          init-method="initialize" destroy-method="close">
         <argument ref="dataBroker"/>
         <argument ref="clusterSingletonService"/>
+        <argument ref="rpcRegistry"/>
     </bean>
     <bean id="statisticsManagerImpl" class="org.opendaylight.controller.config.yang.config.groupbasedpolicy.StatisticsManagerImplInstance"
-        init-method="initialize" destroy-method="close">
+          init-method="initialize" destroy-method="close">
         <argument ref="dataBroker"/>
         <argument ref="clusterSingletonService"/>
     </bean>
     <bean id="policyValidatorRegistry" class="org.opendaylight.controller.config.yang.config.groupbasedpolicy.PolicyValidatorRegistryInstance"
-        init-method="initialize" destroy-method="close">
+          init-method="initialize" destroy-method="close">
         <argument ref="dataBroker"/>
         <argument ref="clusterSingletonService"/>
     </bean>
@@ -40,7 +43,4 @@
     <service ref="policyValidatorRegistry" interface="org.opendaylight.groupbasedpolicy.api.PolicyValidatorRegistry" odl:type="default"/>
     <service ref="statisticsManagerImpl" interface="org.opendaylight.groupbasedpolicy.api.StatisticsManager" odl:type="default"/>
 
-    <!-- RPC implementations -->
-    <odl:rpc-implementation ref="domainSpecificRegistry"/>
-    <odl:rpc-implementation ref="epRendererAugmentationRegistry"/>
 </blueprint>
\ No newline at end of file
index ddeaa8f2b8c0fa88073c9ca10b10a37f71a3ab6b..49213530cbfade0db75e6ff610e2703a478c1621 100644 (file)
@@ -31,7 +31,7 @@
     </dependency>
     <dependency>
       <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
+      <artifactId>mockito-core</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
index 517ea8f3cc1786d457a6b58b3823045f7b996454..f39cb271017bd119fe9c41d2dbf355ce0ba1555b 100644 (file)
@@ -45,7 +45,7 @@
     </dependency>
     <dependency>
       <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
+      <artifactId>mockito-core</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
index a220e5018fe14e0c899f4f3d1182dd4cbb88a6ef..9b25add6a9b3ee1a9712efb11a91d800bbcf90cb 100644 (file)
@@ -13,6 +13,7 @@ import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import org.opendaylight.controller.config.yang.config.groupbasedpolicy.GroupbasedpolicyInstance;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.NeutronMapper;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
@@ -30,19 +31,16 @@ public class NeutronMapperInstance implements ClusterSingletonService, AutoClose
     private static final ServiceGroupIdentifier IDENTIFIER =
             ServiceGroupIdentifier.create(GroupbasedpolicyInstance.GBP_SERVICE_GROUP_IDENTIFIER);
     private final DataBroker dataBroker;
-    private final EndpointService epService;
-    private final BaseEndpointService baseEndpointService;
     private final ClusterSingletonServiceProvider clusterSingletonService;
+    private final RpcProviderRegistry rpcBroker;
     private ClusterSingletonServiceRegistration singletonServiceRegistration;
     private NeutronMapper mapper;
 
     public NeutronMapperInstance(final DataBroker dataBroker,
-                                 final EndpointService epService,
-                                 final BaseEndpointService baseEndpointService,
+                                 final RpcProviderRegistry rpcBroker,
                                  final ClusterSingletonServiceProvider clusterSingletonService) {
         this.dataBroker = Preconditions.checkNotNull(dataBroker);
-        this.epService = Preconditions.checkNotNull(epService);
-        this.baseEndpointService = Preconditions.checkNotNull(baseEndpointService);
+        this.rpcBroker = Preconditions.checkNotNull(rpcBroker);
         this.clusterSingletonService = Preconditions.checkNotNull(clusterSingletonService);
     }
 
@@ -54,6 +52,8 @@ public class NeutronMapperInstance implements ClusterSingletonService, AutoClose
     @Override
     public void instantiateServiceInstance() {
         LOG.info("Instantiating {}", this.getClass().getSimpleName());
+        final EndpointService epService = rpcBroker.getRpcService(EndpointService.class);
+        final BaseEndpointService baseEndpointService = rpcBroker.getRpcService(BaseEndpointService.class);
         mapper = new NeutronMapper(dataBroker, epService, baseEndpointService);
     }
 
index 8bdfa6bf33194ba3a322dc5f9ecac1484d65618d..0a95f3fc1aea7a9070d308a06bd41693279d212f 100644 (file)
@@ -8,12 +8,12 @@
 
 package org.opendaylight.groupbasedpolicy.neutron.mapper;
 
+import javax.annotation.Nullable;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
-
-import javax.annotation.Nullable;
-
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
@@ -22,15 +22,9 @@ 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.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.NetworkDomainContainmentBuilder;
 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.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.AddressEndpointUnreg;
 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.common.rev140421.ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
@@ -40,14 +34,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.l3.prefix.fields.EndpointL3Gateways;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.l3.prefix.fields.EndpointL3GatewaysBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L3Builder;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-
 public class EndpointRegistrator {
 
     private static final Logger LOG = LoggerFactory.getLogger(EndpointRegistrator.class);
@@ -188,4 +179,26 @@ public class EndpointRegistrator {
         return true;
     }
 
+    @Deprecated
+    public boolean unregisterL3EpAsExternalGateway(IpAddress ipAddress, L3ContextId l3Context) {
+        org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInput unregisterEndpointInput =
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInputBuilder()
+                .setL3(ImmutableList.of(new L3Builder().setL3Context(l3Context)
+                    .setIpAddress(ipAddress)
+                    .build()))
+                .build();
+
+        try {
+            RpcResult<Void> rpcResult = epService.unregisterEndpoint(unregisterEndpointInput).get();
+            if (!rpcResult.isSuccessful()) {
+                LOG.warn("Illegal state - unregisterL3EndpointAsExternalGateway was not successful. Input of RPC: {}",
+                    unregisterEndpointInput);
+                return false;
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("unregisterL3EndpointAsExternalGateway failed. {}", unregisterEndpointInput, e);
+            return false;
+        }
+        return true;
+    }
 }
index ac008035ce48a012999f3cff3287d6641af6422a..f5f1939b3f1bdaa92e2506a03af862e938f421fb 100644 (file)
@@ -7,12 +7,12 @@
  */
 package org.opendaylight.groupbasedpolicy.neutron.mapper;
 
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 
+import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
@@ -67,7 +67,7 @@ import com.google.common.collect.PeekingIterator;
 
 public class NeutronMapper implements ClusteredDataTreeChangeListener<Neutron>, AutoCloseable {
 
-    public static final String EXC_MSG_UNKNOWN_MODIFICATION_TYPE_WITHIN_DATA = "Unknown modification type within data ";
+    private static final String EXC_MSG_UNKNOWN_MODIFICATION_TYPE_WITHIN_DATA = "Unknown modification type within data ";
 
     private final static SecurityRuleBuilder EIG_INGRESS_IPV4_SEC_RULE_BUILDER = new SecurityRuleBuilder()
         .setUuid(new Uuid("0a629f80-2408-11e6-b67b-9e71128cae77"))
@@ -120,7 +120,7 @@ public class NeutronMapper implements ClusteredDataTreeChangeListener<Neutron>,
     }
 
     @Override
-    public void onDataTreeChanged(Collection<DataTreeModification<Neutron>> changes) {
+    public void onDataTreeChanged(@Nonnull Collection<DataTreeModification<Neutron>> changes) {
         for (DataTreeModification<Neutron> change : changes) {
             DataObjectModification<Neutron> neutronModif = change.getRootNode();
             resolveAndSetNeutron(neutronModif);
@@ -164,24 +164,19 @@ public class NeutronMapper implements ClusteredDataTreeChangeListener<Neutron>,
     private <T extends DataObject> void onDataObjectModification(List<DataObjectModification<T>> dataModifs,
             NeutronAware<T> neutronAware) {
         for (DataObjectModification<T> dataModif : dataModifs) {
-            switch (dataModif.getModificationType()) {
-                case DELETE:
-                    neutronAware.onDeleted(dataModif.getDataBefore(), neutronBefore, neutronAfter);
-                    break;
-                case SUBTREE_MODIFIED:
-                    neutronAware.onUpdated(dataModif.getDataBefore(), dataModif.getDataAfter(), neutronBefore,
-                            neutronAfter);
-                    break;
-                case WRITE:
-                    if (dataModif.getDataBefore() == null) {
-                        neutronAware.onCreated(dataModif.getDataAfter(), neutronAfter);
-                    } else {
-                        neutronAware.onUpdated(dataModif.getDataBefore(), dataModif.getDataAfter(), neutronBefore,
-                                neutronAfter);
-                    }
-                    break;
-                default:
-                    throw new IllegalStateException(EXC_MSG_UNKNOWN_MODIFICATION_TYPE_WITHIN_DATA + dataModif);
+            final T dataBefore = dataModif.getDataBefore();
+            final T dataAfter = dataModif.getDataAfter();
+            if (dataBefore == null && dataAfter != null) {
+                neutronAware.onCreated(dataAfter, neutronAfter);
+            }
+            else if (dataBefore != null && dataAfter != null) {
+                neutronAware.onUpdated(dataBefore, dataAfter, neutronBefore, neutronAfter);
+            }
+            else if (dataBefore != null) {
+                neutronAware.onDeleted(dataBefore, neutronBefore, neutronAfter);
+            }
+            else {
+                throw new IllegalStateException(EXC_MSG_UNKNOWN_MODIFICATION_TYPE_WITHIN_DATA + dataModif);
             }
         }
     }
index e240de078eb5452bf67f5f1faed56e8033529f03..cb177af8fb36c11cda2d42a00ab489037fb55b99 100644 (file)
@@ -291,6 +291,10 @@ public class NeutronPortAware implements NeutronAware<Port> {
     }
 
     private void changeL3ContextForEpsInSubnet(Uuid subnetUuid, Neutron neutron) {
+        if (neutron == null) {
+            LOG.debug("No new data are written, there is no L3 context in subnet {} to update", subnetUuid);
+            return;
+        }
         Set<Port> portsInSameSubnet = PortUtils.findPortsBySubnet(subnetUuid, neutron.getPorts());
         for (Port portInSameSubnet : portsInSameSubnet) {
             if (PortUtils.isNormalPort(portInSameSubnet) || PortUtils.isDhcpPort(portInSameSubnet)
@@ -544,15 +548,15 @@ public class NeutronPortAware implements NeutronAware<Port> {
     @Override
     public void onUpdated(Port oldPort, Port newPort, Neutron oldNeutron, Neutron newNeutron) {
         LOG.trace("updated port - OLD: {}\nNEW: {}", oldPort, newPort);
-        onDeleted(oldPort, oldNeutron, false);
+        onDeleted(oldPort, oldNeutron, newNeutron, false);
         onCreated(newPort, newNeutron, false);
     }
 
     @Override public void onDeleted(Port deletedItem, Neutron oldNeutron, Neutron newNeutron) {
-        onDeleted(deletedItem, oldNeutron, true);
+        onDeleted(deletedItem, oldNeutron, newNeutron, true);
     }
 
-    public void onDeleted(Port port, Neutron oldNeutron, boolean removeBaseEpMapping) {
+    public void onDeleted(Port port, Neutron oldNeutron, Neutron newNeutron, boolean removeBaseEpMapping) {
         LOG.trace("deleted port - {}", port);
         if (PortUtils.isRouterInterfacePort(port)) {
             LOG.trace("Port is router interface port: {}", port.getUuid().getValue());
@@ -565,8 +569,8 @@ public class NeutronPortAware implements NeutronAware<Port> {
             }
             FixedIps portIpWithSubnet = potentialPortIpWithSubnet.get();
             L3ContextId l3Context = new L3ContextId(port.getNetworkId().getValue());
-            // change L3Context for all EPs with same subnet as router port
-            changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), oldNeutron);
+            // change L3Context for all new EPs with same subnet as router port
+            changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), newNeutron);
             // set L3Context as parent for bridge domain which is parent of subnet
             TenantId tenantId = new TenantId(port.getTenantId().getValue());
             Optional<Subnet> potentialRouterPortSubnet = SubnetUtils.findSubnet(portIpWithSubnet.getSubnetId(),
@@ -588,12 +592,8 @@ public class NeutronPortAware implements NeutronAware<Port> {
             NetworkDomain subnet = NeutronSubnetAware.createSubnet(routerPortSubnet, null);
             rwTx.put(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.subnetIid(tenantId, subnet.getNetworkDomainId()),
                     subnet);
-            UniqueId portId = new UniqueId(port.getUuid().getValue());
-            PortByBaseEndpointKey portByBaseEndpointKey = new PortByBaseEndpointKey(port.getMacAddress().getValue(),
-                    MacAddressType.class, new ContextId(port.getNetworkId().getValue()), MappingUtils.L2_BRDIGE_DOMAIN);
-            if (removeBaseEpMapping) {
-                removeBaseEndpointMappings(portByBaseEndpointKey, portId, rwTx);
-            }
+            unregisterEndpointAndRemoveMapping(createUnregisterEndpointInput(port, oldNeutron), port, rwTx);
+            unregisterEndpointAndRemoveMapping(createUnregisterBaseEndpointInput(port, oldNeutron), port, rwTx, removeBaseEpMapping);
             DataStoreHelper.submitToDs(rwTx);
         } else if (PortUtils.isDhcpPort(port)) {
             LOG.trace("Port is DHCP port: {}", port.getUuid().getValue());
index a7d14bc1b596596882cfd96e516de716f03a87b3..5f634e55a0e89a7dc08f234c74e893ad08bd71a3 100644 (file)
@@ -32,6 +32,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.
 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.register.endpoint.input.AddressEndpointRegBuilder;
+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.common.rev140421.ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
@@ -40,12 +41,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.Endpoints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Key;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3PrefixKey;
 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.SubnetAugmentForwarding;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.SubnetAugmentForwardingBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.has.subnet.Subnet;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.has.subnet.SubnetBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.fields.Parent;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContextBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.NetworkDomain;
@@ -206,6 +211,15 @@ public class NeutronRouterAware implements NeutronAware<Router> {
         return epRegistrator.registerEndpoint(addrEpBuilder.build());
     }
 
+    private boolean unregisterExternalGateway(IpPrefix ipPrefix, ContextId routerl3ContextId) {
+        AddressEndpointUnregBuilder addrEpBuilder = new AddressEndpointUnregBuilder();
+        addrEpBuilder.setAddressType(IpPrefixType.class);
+        addrEpBuilder.setAddress(MappingUtils.ipPrefixToStringIpAddress(ipPrefix));
+        addrEpBuilder.setContextId(routerl3ContextId);
+        addrEpBuilder.setContextType(MappingUtils.L3_CONTEXT);
+        return epRegistrator.unregisterEndpoint(addrEpBuilder.build());
+    }
+
     private NetworkDomain createSubnetWithVirtualRouterIp(IpPrefix gatewayIp, NetworkDomainId subnetId) {
         Subnet subnet = new SubnetBuilder().setVirtualRouterIp(MappingUtils.ipPrefixToIpAddress(gatewayIp.getValue())).build();
         return new NetworkDomainBuilder().setKey(new NetworkDomainKey(subnetId, MappingUtils.SUBNET))
@@ -296,7 +310,84 @@ public class NeutronRouterAware implements NeutronAware<Router> {
                  .build();
              rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId),
                      l2BdWithGw);
-         } 
+         }
+    }
+
+    private void deleteTenantForwarding(Neutron newNeutron, Router oldRouter, L3ContextId l3ContextId, TenantId tenantId, ReadWriteTransaction rwTx) {
+        InstanceIdentifier<L3Context> l3ContextIid = IidFactory.l3ContextIid(tenantId, l3ContextId);
+
+        LOG.trace("Deleting router from TenantForwarding {}", l3ContextIid);
+        DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, l3ContextIid, rwTx);
+
+        if (oldRouter.getGatewayPortId() != null) {
+            // external network is attached to router
+            Uuid gatewayPortId = oldRouter.getGatewayPortId();
+            Optional<Port> potentialGwPort = PortUtils.findPort(gatewayPortId, newNeutron.getPorts());
+            if (!potentialGwPort.isPresent()) {
+                LOG.trace("Gateway port {} is not present. Skipping delete of extGW from TenantForwarding",
+                    gatewayPortId);
+                return;
+            }
+
+            Port gwPort = potentialGwPort.get();
+            List<FixedIps> fixedIpsFromGwPort = gwPort.getFixedIps();
+            if (fixedIpsFromGwPort == null || fixedIpsFromGwPort.isEmpty()) {
+                LOG.trace("Gateway port {} does not contain fixed IPs. Skipping delete of extGW from TenantForwarding",
+                    gatewayPortId);
+                return;
+            }
+
+            // router can have only one external network
+            FixedIps ipWithSubnetFromGwPort = fixedIpsFromGwPort.get(0);
+            Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet>
+                potentialSubnet =
+                SubnetUtils.findSubnet(ipWithSubnetFromGwPort.getSubnetId(), newNeutron.getSubnets());
+            if (!potentialSubnet.isPresent()) {
+                LOG.trace("Gateway port {} does not contain fixed IPs. Skipping delete of extGW from TenantForwarding",
+                    gatewayPortId);
+                return;
+            }
+            IpAddress gatewayIp = potentialSubnet.get().getGatewayIp();
+            boolean registeredExternalGateway = epRegistrator.unregisterL3EpAsExternalGateway(gatewayIp, l3ContextId);
+            if (!registeredExternalGateway) {
+                LOG.trace("L3 Gateway endpoint {} with IP {} was not unregistered.", l3ContextId, gatewayIp);
+                return;
+            } else {
+                LOG.trace("L3 Gateway endpoint {} with IP {} was unregistered successfully.", l3ContextId, gatewayIp);
+            }
+            EndpointL3Key epL3Key = new EndpointL3Key(gatewayIp, l3ContextId);
+
+            DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
+                NeutronGbpIidFactory.externalGatewayAsL3Endpoint(epL3Key.getL3Context(), epL3Key.getIpAddress()), rwTx);
+
+            DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.builder(Endpoints.class)
+                .child(EndpointL3Prefix.class, new EndpointL3PrefixKey(MappingUtils.DEFAULT_ROUTE, l3ContextId))
+                .build(), rwTx);
+
+            Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet>
+                subnetOptional = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.subnetIid(tenantId, new SubnetId(ipWithSubnetFromGwPort.getSubnetId().getValue())),
+                dataProvider.newReadOnlyTransaction());
+
+            org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet
+                subnet =
+                new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.SubnetBuilder(
+                    subnetOptional.get()).setVirtualRouterIp(null).build();
+            LOG.trace("Removing VirtualRouterIp from subnet {}.", subnetOptional.get());
+            rwTx.put(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.subnetIid(tenantId, new SubnetId(ipWithSubnetFromGwPort.getSubnetId().getValue())), subnet);
+
+            L2BridgeDomainId l2BdId = new L2BridgeDomainId(potentialSubnet.get().getNetworkId().getValue());
+            L3ContextId l3Context = new L3ContextId( potentialSubnet.get().getNetworkId().getValue());
+            Optional<L2BridgeDomain> optBd = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.l2BridgeDomainIid(tenantId, l2BdId), rwTx);
+            if (optBd.isPresent()) {
+                L2BridgeDomain l2BdWithGw = new L2BridgeDomainBuilder(optBd.get()).setParent(l3Context).build();
+                LOG.trace("Setting parent for L2BridgeDomain {} back to network {}.", l2BdWithGw, l3Context);
+                rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId),
+                    l2BdWithGw);
+            }
+        }
     }
 
     private static @Nonnull ForwardingContext createL3ContextFromRouter(
@@ -341,7 +432,90 @@ public class NeutronRouterAware implements NeutronAware<Router> {
 
     @Override
     public void onDeleted(Router router, Neutron oldNeutron, Neutron newNeutron) {
-        LOG.trace("deleted router - {}", router);
+        LOG.debug("deleted router - {}", router);
+        ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
+        ContextId routerl3ContextId = new ContextId(router.getUuid().getValue());
+        TenantId tenantId = new TenantId(router.getTenantId().getValue());
+        deleteExtGw(router, tenantId, newNeutron, rwTx);
+        InstanceIdentifier<ForwardingContext> routerL3CtxIid = L2L3IidFactory.l3ContextIid(tenantId, routerl3ContextId);
+
+        LOG.trace("Removing router from forwardingByTenant. Router: {} Path: {}", router, routerL3CtxIid);
+        DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, routerL3CtxIid, rwTx);
+
+        InstanceIdentifier<L3Context> l3ContextInstanceIdentifier =
+            IidFactory.l3ContextIid(tenantId, new L3ContextId(routerl3ContextId));
+        LOG.trace("Removing router from Tenant`s forwarding context. Router: {} Path: {}", router,
+            l3ContextInstanceIdentifier);
+        DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, l3ContextInstanceIdentifier, rwTx);
+
+        DataStoreHelper.submitToDs(rwTx);
+    }
+
+    private void deleteExtGw(Router router, TenantId tenantId, Neutron newNeutron, ReadWriteTransaction rwTx) {
+        ContextId routerL3CtxId = new ContextId(router.getUuid().getValue());
+        if (router.getGatewayPortId() != null) {
+            // external network is attached to router
+            Uuid gatewayPortId = router.getGatewayPortId();
+            Optional<Port> potentialGwPort = PortUtils.findPort(gatewayPortId, newNeutron.getPorts());
+            if (!potentialGwPort.isPresent()) {
+                LOG.trace("Gateway port {} is not present. Skipping delete for external gateway", gatewayPortId);
+                return;
+            }
+
+            Port gwPort = potentialGwPort.get();
+            List<FixedIps> fixedIpsFromGwPort = gwPort.getFixedIps();
+            if (fixedIpsFromGwPort == null || fixedIpsFromGwPort.isEmpty()) {
+                LOG.trace("Gateway port {} with does not contain fixed IPs. Skipping delete for external gateway",
+                    gatewayPortId);
+                return;
+            }
+
+            FixedIps ipWithSubnetFromGwPort = fixedIpsFromGwPort.get(0);
+            Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet>
+                potentialSubnet = SubnetUtils.findSubnet(ipWithSubnetFromGwPort.getSubnetId(), newNeutron.getSubnets());
+            if (!potentialSubnet.isPresent()) {
+                LOG.trace("Subnet for GW port {} is not present. Skipping delete for external gateway",
+                    gatewayPortId);
+                return;
+            }
+            IpPrefix gatewayIp = MappingUtils.ipAddressToIpPrefix(potentialSubnet.get().getGatewayIp());
+
+            if (!unregisterExternalGateway(gatewayIp, routerL3CtxId)) {
+                LOG.warn("Could not unregister routerL3Prefix as gateway of default route. Gateway port {}", gwPort);
+                return;
+            }
+            DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
+                NeutronGbpIidFactory.externalGatewayAsEndpoint(routerL3CtxId, gatewayIp, MappingUtils.L3_CONTEXT),
+                rwTx);
+            NetworkDomainId domainId = new NetworkDomainId(ipWithSubnetFromGwPort.getSubnetId().getValue());
+            Optional<NetworkDomain> domainOptional =
+                DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
+                    L2L3IidFactory.subnetIid(tenantId, domainId), dataProvider.newReadWriteTransaction());
+
+            if (domainOptional.isPresent()) {
+                Subnet originalSubnet = domainOptional.get().getAugmentation(SubnetAugmentForwarding.class).getSubnet();
+                if (originalSubnet != null) {
+                    LOG.trace("Deleting virtual router IP from Subnet {} in gateway {}", originalSubnet, gatewayPortId);
+                    SubnetBuilder subnetBuilder = new SubnetBuilder(originalSubnet).setVirtualRouterIp(null);
+                    rwTx.put(LogicalDatastoreType.CONFIGURATION,
+                        L2L3IidFactory.subnetIid(tenantId, domainId)
+                            .augmentation(SubnetAugmentForwarding.class)
+                            .child(Subnet.class),
+                        subnetBuilder.build());
+                }
+            }
+            ContextId l2BdId = new ContextId(potentialSubnet.get().getNetworkId().getValue());
+            Optional<ForwardingContext> optBd = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
+                L2L3IidFactory.l2BridgeDomainIid(tenantId, l2BdId), rwTx);
+            Parent parent = MappingUtils.createParent(l2BdId, MappingUtils.L3_CONTEXT);
+            if (optBd.isPresent()) {
+                ForwardingContext bridgeDomain = new ForwardingContextBuilder(optBd.get()).setParent(parent).build();
+                LOG.trace("Setting parent for L2BridgeDomain {} back to network {}.", bridgeDomain, parent);
+                rwTx.put(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.l2BridgeDomainIid(tenantId, l2BdId),
+                    bridgeDomain);
+            }
+        }
+        deleteTenantForwarding(newNeutron, router, new L3ContextId(routerL3CtxId), tenantId, rwTx);
     }
 
 }
index 305bcc51eaa5bb935494ca3c937ba8ec2936d9e5..e06639d7b5294816b0b3c45d7caaae9dc8c30fe1 100644 (file)
@@ -4,15 +4,13 @@
            odl:use-default-for-reference-types="true">
 
     <reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"/>
-    <odl:rpc-service id="epService" interface="org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointService"/>
-    <odl:rpc-service id="baseEpService" interface="org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService"/>
+    <reference id="rpcRegistry" interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry"/>
     <reference id="clusterSingletonService" interface="org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider"/>
 
     <bean id="neutronMapper" class="org.opendaylight.controller.config.yang.config.neutron_mapper.impl.NeutronMapperInstance"
-        init-method="instantiate" destroy-method="close">
+          init-method="instantiate" destroy-method="close">
         <argument ref="dataBroker"/>
-        <argument ref="epService"/>
-        <argument ref="baseEpService"/>
-        <argument ref="clusterSingletonService" />
+        <argument ref="rpcRegistry"/>
+        <argument ref="clusterSingletonService"/>
     </bean>
 </blueprint>
\ No newline at end of file
index be5021c4086d5b11a1bf3c58f7db73b972c2f6c8..4b76201372e01cbbfd79d01a0df16ef5bcf9fed8 100644 (file)
@@ -60,7 +60,7 @@
     </dependency>
     <dependency>
       <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
+      <artifactId>mockito-core</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
index 66e2991463179121ecf9d4bbb892c4b595119223..07f3fb460f7a5c40b4a626ad919ef4b3b3c028d8 100644 (file)
@@ -13,6 +13,7 @@ import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import org.opendaylight.controller.config.yang.config.groupbasedpolicy.GroupbasedpolicyInstance;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.groupbasedpolicy.neutron.ovsdb.NeutronOvsdb;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
@@ -30,18 +31,18 @@ public class NeutronOvsdbInstance implements ClusterSingletonService, AutoClosea
     private static final ServiceGroupIdentifier IDENTIFIER =
             ServiceGroupIdentifier.create(GroupbasedpolicyInstance.GBP_SERVICE_GROUP_IDENTIFIER);
     private final DataBroker dataBroker;
-    private final EndpointService epService;
     private final IntegrationBridgeSetting settings;
     private final ClusterSingletonServiceProvider clusterSingletonService;
+    private final RpcProviderRegistry rpcBroker;
     private ClusterSingletonServiceRegistration singletonServiceRegistration;
     private NeutronOvsdb neutronOvsdb;
 
     public NeutronOvsdbInstance(final DataBroker dataBroker,
-                                final EndpointService epService,
+                                final RpcProviderRegistry rpcBroker,
                                 final IntegrationBridgeSetting settings,
                                 final ClusterSingletonServiceProvider clusterSingletonService) {
         this.dataBroker = Preconditions.checkNotNull(dataBroker);
-        this.epService = Preconditions.checkNotNull(epService);
+        this.rpcBroker = Preconditions.checkNotNull(rpcBroker);
         this.settings = Preconditions.checkNotNull(settings);
         this.clusterSingletonService = Preconditions.checkNotNull(clusterSingletonService);
     }
@@ -54,6 +55,7 @@ public class NeutronOvsdbInstance implements ClusterSingletonService, AutoClosea
     @Override
     public void instantiateServiceInstance() {
         LOG.info("Instantiating {}", this.getClass().getSimpleName());
+        final EndpointService epService = rpcBroker.getRpcService(EndpointService.class);
         neutronOvsdb = new NeutronOvsdb(dataBroker, epService, settings);
     }
 
index 26e12bdb75e608600941a29ded31151010f389b0..277862ee69cb48e3d0b9ab759ce1d37dd5d3d1f6 100644 (file)
@@ -4,11 +4,11 @@
            odl:use-default-for-reference-types="true">
 
     <reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"/>
-    <odl:rpc-service id="epService" interface="org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointService"/>
+    <reference id="rpcRegistry" interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry"/>
     <reference id="clusterSingletonService" interface="org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider"/>
 
     <odl:clustered-app-config id="moduleConfig"
-        binding-class="org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.ovsdb.params.rev160812.IntegrationBridgeSetting">
+                              binding-class="org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.ovsdb.params.rev160812.IntegrationBridgeSetting">
         <odl:default-config><![CDATA[
             <integration-bridge-setting xmlns="urn:opendaylight:groupbasedpolicy:neutron:ovsdb:params">
                 <name>br-int</name>
     </odl:clustered-app-config>
 
     <bean id="neutronOvsdb" class="org.opendaylight.controller.config.yang.config.neutron_ovsdb.impl.NeutronOvsdbInstance"
-        init-method="initialize" destroy-method="close">
+          init-method="initialize" destroy-method="close">
         <argument ref="dataBroker"/>
-        <argument ref="epService"/>
+        <argument ref="rpcRegistry"/>
         <argument ref="moduleConfig"/>
-        <argument ref="clusterSingletonService" />
+        <argument ref="clusterSingletonService"/>
     </bean>
 </blueprint>
\ No newline at end of file
index da8f5ed2fd7ccac8c7d398da87dff3c74f62f7fa..2c3d01c244ddcd8728d1997f7079db31458cd4d0 100644 (file)
@@ -53,7 +53,7 @@
     </dependency>
     <dependency>
       <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
+      <artifactId>mockito-core</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
index 994778564c6897e8bfec8c93c7eb3c968482bac0..861202f7407d35151bee484dc13485ce3b9c2f6c 100644 (file)
@@ -23,7 +23,7 @@ public class NeutronVppMapper implements AutoCloseable {
     public NeutronVppMapper(String socketPath, String socketPrefix, DataBroker dataBroker) {\r
         SocketInfo socketInfo = new SocketInfo(socketPath, socketPrefix);\r
         vppNodeListener = new VppNodeListener(dataBroker, socketInfo);\r
-        neutronListener = new NeutronListener(dataBroker, socketInfo);\r
+        neutronListener = new NeutronListener(dataBroker);\r
         LOG.info("Neutron VPP started!");\r
     }\r
 \r
index 39b3a85d36f327713108af68c89adb90d6151c03..c79b875dafd7303bf00b4dc85865d515069c28ea 100644 (file)
@@ -72,8 +72,8 @@ public class VppNodeListener extends DataTreeChangeHandler<RendererNode> {
     @Override\r
     protected void onSubtreeModified(DataObjectModification<RendererNode> rootNode,\r
             InstanceIdentifier<RendererNode> rootIdentifier) {\r
-        deleteData(rootNode.getDataAfter());\r
-        writeData(rootNode.getDataBefore());\r
+        deleteData(rootNode.getDataBefore());\r
+        writeData(rootNode.getDataAfter());\r
     }\r
 \r
     private void writeData(RendererNode rendererNode) {\r
index 988469baaafff0fc8ca24c09f9f723c548bb3611..e4fe158c57cd8f7c669a855ffd100cab29449d2f 100644 (file)
@@ -23,7 +23,6 @@ import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.Mod
 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.neutron.vpp.mapper.SocketInfo;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;\r
 import org.opendaylight.yangtools.concepts.ListenerRegistration;\r
 import org.opendaylight.yangtools.yang.binding.DataObject;\r
@@ -43,14 +42,14 @@ public class NeutronListener implements ClusteredDataTreeChangeListener<Neutron>
     private final Set<MappingProvider<? extends DataObject>> dataChangeProviders = new LinkedHashSet<>();\r
     protected ListenerRegistration<NeutronListener> registeredListener;\r
 \r
-    public NeutronListener(DataBroker dataBroker, SocketInfo socketInfo) {\r
-        registerHandlersAndListeners(dataBroker, socketInfo);\r
+    public NeutronListener(DataBroker dataBroker) {\r
+        registerHandlersAndListeners(dataBroker);\r
         registeredListener = dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(\r
                 LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.builder(Neutron.class).build()), this);\r
     }\r
 \r
-    private void registerHandlersAndListeners(DataBroker dataBroker, SocketInfo socketInfo) {\r
-        PortHandler portHandler = new PortHandler(dataBroker, socketInfo);\r
+    private void registerHandlersAndListeners(DataBroker dataBroker) {\r
+        PortHandler portHandler = new PortHandler(dataBroker);\r
         dataChangeProviders.add(new PortAware(portHandler, dataBroker));\r
         dataChangeProviders.add(new NetworkAware(dataBroker));\r
     }\r
index 3c25a8c913e0b9b56c8bd3a157bc08105b0b2501..01c2152cc0309627e18c489ee87464937916f265 100644 (file)
@@ -21,7 +21,6 @@ import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;\r
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;\r
-import org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.SocketInfo;\r
 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;\r
@@ -64,26 +63,27 @@ import org.slf4j.LoggerFactory;
 import com.google.common.annotations.VisibleForTesting;\r
 import com.google.common.base.Optional;\r
 \r
+import javax.annotation.Nonnull;\r
 public class PortHandler implements TransactionChainListener {\r
 \r
-    private static final Logger LOG = LoggerFactory.getLogger(MappingProvider.class);\r
+    private static final Logger LOG = LoggerFactory.getLogger(PortHandler.class);\r
 \r
     private static final String COMPUTE_OWNER = "compute";\r
     private static final String DHCP_OWNER = "dhcp";\r
     private static final String ROUTER_OWNER = "network:router_interface";\r
     private static final String[] SUPPORTED_DEVICE_OWNERS = {COMPUTE_OWNER, DHCP_OWNER, ROUTER_OWNER};\r
     private static final String VHOST_USER = "vhostuser";\r
+    private static final String UNBOUND = "unbound";\r
     private static final String VPP_INTERFACE_NAME_PREFIX = "neutron_port_";\r
     private static final String TAP_PORT_NAME_PREFIX = "tap";\r
     private static final String RT_PORT_NAME_PREFIX = "qr-";\r
+    private static final String VHOST_SOCKET_KEY = "vhostuser_socket";\r
 \r
     private BindingTransactionChain transactionChain;\r
     private DataBroker dataBroker;\r
-    private SocketInfo socketInfo;\r
 \r
-    PortHandler(DataBroker dataBroker, SocketInfo socketInfo) {\r
+    PortHandler(DataBroker dataBroker) {\r
         this.dataBroker = dataBroker;\r
-        this.socketInfo = socketInfo;\r
         transactionChain = this.dataBroker.createTransactionChain(this);\r
     }\r
 \r
@@ -158,18 +158,38 @@ public class PortHandler implements TransactionChainListener {
         processCreated(delta);\r
     }\r
 \r
-    private boolean isUpdateNeeded(Port oldPort, Port newPort) {\r
+    private boolean isUpdateNeeded(final Port oldPort, final Port newPort) {\r
         //TODO fix this to better support update of ports for VPP\r
-        PortBindingExtension oldPortAugmentation = oldPort.getAugmentation(PortBindingExtension.class);\r
-        PortBindingExtension newPortAugmentation = newPort.getAugmentation(PortBindingExtension.class);\r
-\r
-        List<VifDetails> vifDetails = oldPortAugmentation.getVifDetails();\r
+        final PortBindingExtension oldPortAugmentation = oldPort.getAugmentation(PortBindingExtension.class);\r
+        final PortBindingExtension newPortAugmentation = newPort.getAugmentation(PortBindingExtension.class);\r
 \r
         if (newPortAugmentation == null) {\r
             LOG.trace("Port {} is no longer a vhost type port, updating port...");\r
             return true;\r
         }\r
 \r
+        final String oldDeviceOwner = oldPort.getDeviceOwner();\r
+        final String oldVifType = oldPortAugmentation.getVifType();\r
+        final String newDeviceOwner = newPort.getDeviceOwner();\r
+        final String newVifType = newPortAugmentation.getVifType();\r
+\r
+        // TODO potential bug here\r
+        // Temporary change for Openstack Mitaka: If old neutron-binding:vif-type is vhost, new one is unbound and\r
+        // device owner is ROUTER_OWNER, skip update. Openstack (or ml2) sometimes sends router update messages in\r
+        // incorrect order which causes unwanted port removal\r
+        if (oldVifType.equals(VHOST_USER) && newVifType.equals(UNBOUND) && oldDeviceOwner != null &&\r
+                ROUTER_OWNER.equals(oldDeviceOwner) && ROUTER_OWNER.equals(newDeviceOwner)) {\r
+            LOG.warn("Port vif-type was updated from vhost to unbound. This update is currently disabled and will be skipped");\r
+            return false;\r
+        }\r
+\r
+        if (newVifType != null && !newVifType.equals(oldVifType)) {\r
+            LOG.trace("Vif type changed, old: {} new {}", oldVifType, newVifType);\r
+            return true;\r
+        }\r
+\r
+        final List<VifDetails> vifDetails = oldPortAugmentation.getVifDetails();\r
+\r
         if (!oldPortAugmentation.getHostId().equals(newPortAugmentation.getHostId()) ||\r
             nullToEmpty(vifDetails).size() != nullToEmpty(newPortAugmentation.getVifDetails()).size()) {\r
             return true;\r
@@ -217,9 +237,10 @@ public class PortHandler implements TransactionChainListener {
             .setAddressType(bebp.getAddressType())\r
             .setVppInterfaceName(VPP_INTERFACE_NAME_PREFIX + bebp.getPortId().getValue())\r
             .setVppNodeId(new NodeId(portBinding.getHostId()));\r
+\r
         if (port.getDeviceOwner().contains(COMPUTE_OWNER)) {\r
-            String socket = socketInfo.getSocketPath() + socketInfo.getSocketPrefix() + bebp.getPortId().getValue();\r
-            vppEpBuilder.setInterfaceTypeChoice(new VhostUserCaseBuilder().setSocket(socket).build());\r
+            vppEpBuilder.setInterfaceTypeChoice(\r
+                new VhostUserCaseBuilder().setSocket(getSocketFromPortBinding(portBinding)).build());\r
         } else if (port.getDeviceOwner().contains(DHCP_OWNER) && port.getMacAddress() != null) {\r
             TapCase tapCase = new TapCaseBuilder().setPhysicalAddress(new PhysAddress(port.getMacAddress().getValue()))\r
                 .setName(createPortName(port.getUuid()))\r
@@ -236,6 +257,17 @@ public class PortHandler implements TransactionChainListener {
         return vppEpBuilder.build();\r
     }\r
 \r
+    private String getSocketFromPortBinding(@Nonnull PortBindingExtension portBindingExtension) {\r
+        List<VifDetails> vifDetails = nullToEmpty(portBindingExtension.getVifDetails());\r
+\r
+        for (VifDetails detail : vifDetails) {\r
+            if (VHOST_SOCKET_KEY.equalsIgnoreCase(detail.getDetailsKey())) {\r
+                return detail.getValue();\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+\r
     private LoopbackCase getLoopbackCase(Port port) {\r
         LoopbackCaseBuilder loopbackCase = new LoopbackCaseBuilder()\r
             .setPhysAddress(new PhysAddress(port.getMacAddress().getValue()));\r
index 0c81dfedc51de340543e945dd0119294c1e72aee..1ed99947e658506df20d745b1b12e4f1d35d0822 100644 (file)
@@ -46,19 +46,18 @@ public class NeutronListenerTest extends AbstractDataBrokerTest {
     public void init() {\r
         port = TestUtils.createValidVppPort();\r
         bebp = TestUtils.createBaseEndpointByPortForPort();\r
-        socketInfo = new SocketInfo("/tmp/", "_socket");\r
         dataBroker = getDataBroker();\r
-        neutronListener = new NeutronListener(dataBroker, socketInfo);\r
+        neutronListener = new NeutronListener(dataBroker);\r
         neutronListener.clearDataChangeProviders();\r
         baseEpByPortListener = Mockito.spy(new PortAware(new PortHandler(\r
-                dataBroker, socketInfo), dataBroker));\r
+                dataBroker), dataBroker));\r
         neutronListener.addDataChangeProvider(baseEpByPortListener);\r
     }\r
 \r
     @Test\r
     public void constructorTest() {\r
         dataBroker = Mockito.spy(dataBroker);\r
-        NeutronListener neutronListener = new NeutronListener(dataBroker, socketInfo);\r
+        NeutronListener neutronListener = new NeutronListener(dataBroker);\r
         verify(dataBroker).registerDataTreeChangeListener(\r
                 eq(new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,\r
                         InstanceIdentifier.builder(Neutron.class)\r
index 7e2eadf2cefd01b1cb9d75f69650f9383cc9e91f..f94809c447fbc91505bd5f5ac9ec0a7ce1053c96 100644 (file)
@@ -51,7 +51,6 @@ public class PortHandlerTest extends AbstractDataBrokerTest {
     private BindingTransactionChain transactionChain;
 
     private Port port;
-    private SocketInfo socketInfo;
     private BaseEndpointByPort bebp;
 
     @Rule
@@ -61,11 +60,10 @@ public class PortHandlerTest extends AbstractDataBrokerTest {
     public void init() {
         port = TestUtils.createValidVppPort();
         bebp = TestUtils.createBaseEndpointByPortForPort();
-        socketInfo = new SocketInfo("/tmp/", "_socket");
         dataBroker = Mockito.spy(getDataBroker());
         transactionChain = mock(BindingTransactionChain.class);
         when(dataBroker.createTransactionChain(any(PortHandler.class))).thenReturn(transactionChain);
-        portHandler = new PortHandler(dataBroker, socketInfo);
+        portHandler = new PortHandler(dataBroker);
         when(transactionChain.newReadOnlyTransaction()).thenAnswer(new Answer<ReadTransaction>() {
 
             @Override
@@ -92,8 +90,7 @@ public class PortHandlerTest extends AbstractDataBrokerTest {
         assertTrue(vppEp.getInterfaceTypeChoice() instanceof VhostUserCase);
         VhostUserCase vhostUserCase = (VhostUserCase) vppEp.getInterfaceTypeChoice();
         assertNotNull(vhostUserCase);
-        assertEquals(vhostUserCase.getSocket(), socketInfo.getSocketPath() + socketInfo.getSocketPrefix()
-                + bebp.getPortId().getValue());
+        assertEquals(TestUtils.TEST_SOCKET, vhostUserCase.getSocket());
     }
 
     @Test
index 2c1f2a31251f08e8cb38b12e6506f8a2072c1c0a..8d114024701779618fcb776b789190751764ec77 100644 (file)
@@ -12,6 +12,7 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;\r
 import static org.junit.Assert.assertTrue;\r
 \r
+import java.util.Collections;\r
 import java.util.Iterator;\r
 \r
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;\r
@@ -32,6 +33,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_render
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointKey;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.PortBindingExtension;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.PortBindingExtensionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.binding.attributes.VifDetailsBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.binding.attributes.VifDetailsKey;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortBuilder;\r
@@ -41,10 +44,15 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;\r
 \r
 public class TestUtils {\r
+    public static String TEST_SOCKET = "/tmp/socket_testsocket";\r
 \r
     public static Port createValidVppPort() {\r
         PortBindingExtension portBindingExt = new PortBindingExtensionBuilder().setHostId("devstack-control")\r
             .setVifType("vhostuser")\r
+            .setVifDetails(Collections.singletonList(\r
+                new VifDetailsBuilder().setKey(new VifDetailsKey("vhostuser_socket"))\r
+                    .setValue(TEST_SOCKET)\r
+                    .build()))\r
             .build();\r
         return new PortBuilder().setUuid(new Uuid("00000000-1111-2222-3333-444444444444"))\r
             .setDeviceOwner("compute")\r
diff --git a/pom.xml b/pom.xml
index 8ff08dec66f906a0d45ef51d1701d98ff27eb094..eb27a1274038540f14d9a51a8a6b84523100ba70 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -35,7 +35,6 @@
     <module>distribution-karaf</module>
     <module>features</module>
     <module>sxp-integration</module>
-    <module>ip-sgt-distribution-service</module>
   </modules>
 
   <build>
index 748d3b73d6c14cf18e8d16ed49e10f4271029f8e..d946551c38246bf45ffbd1f6ec59ebc2b81e176f 100644 (file)
@@ -42,7 +42,7 @@
     </dependency>
     <dependency>
       <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
+      <artifactId>mockito-core</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
index 74be385f1a6474243f1a75e612b7071732a41b6f..26c1febcac5d8bbd8f4122fa7065db3b7618053c 100755 (executable)
@@ -49,7 +49,7 @@
         </dependency>
         <dependency>
             <groupId>org.mockito</groupId>
-            <artifactId>mockito-all</artifactId>
+            <artifactId>mockito-core</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
index c3a99d5266cc7617bbcc25e017df9f5fd782e36b..bd268827005207365ff9904832d1455746e7bbfa 100755 (executable)
@@ -69,7 +69,7 @@
     </dependency>
     <dependency>
       <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
+      <artifactId>mockito-core</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
index 142df39ec632b456375d8df3900cbab33fd3f760..63f383ded6373d9dc9e7e22a4b3f57db52ccc472 100644 (file)
@@ -29,7 +29,7 @@
     </dependency>
     <dependency>
       <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
+      <artifactId>mockito-core</artifactId>
       <scope>test</scope>
     </dependency>
   </dependencies>
index bfc81f9b04451e42810b5c071e3470cd786adde3..227b3681d902e687b630622f1cb46e94d13369ca 100755 (executable)
@@ -67,7 +67,7 @@
     </dependency>
     <dependency>
       <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
+      <artifactId>mockito-core</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
index 55b9639f20555c5246210b918aa5f31b66ec5f31..cf0f06cc4769a3614d16ba392d752c1b1956ba79 100644 (file)
@@ -29,7 +29,7 @@
     </dependency>
     <dependency>
       <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
+      <artifactId>mockito-core</artifactId>
       <scope>test</scope>
     </dependency>
   </dependencies>
index cad8fab5d0b6430e64b04c850e4ced21e36fba93..63f679dea7ff19634a3d138876e1e74cf525586e 100644 (file)
@@ -85,7 +85,7 @@
     </dependency>
     <dependency>
       <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
+      <artifactId>mockito-core</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
         <configuration>
           <instructions>
             <Export-Package>
-              org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.*
+              org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.*,
+              org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_adapter.rev161201.*
             </Export-Package>
           </instructions>
         </configuration>
index af9d3b597d0aef8dedb6cf3e376f35357121be1b..7ea0f37114c178d45d5e979518c035dab3a09671 100644 (file)
-/*\r
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.groupbasedpolicy.renderer.vpp.adapter;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-import java.util.concurrent.Future;\r
-import java.util.stream.Collectors;\r
-\r
-import javax.annotation.Nonnull;\r
-\r
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\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.controller.md.sal.common.api.data.ReadFailedException;\r
-import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager;\r
-import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.ConfigCommand;\r
-import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.TapPortCommand;\r
-import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.VhostUserCommand;\r
-import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.VhostUserCommand.VhostUserCommandBuilder;\r
-import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;\r
-import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General.Operations;\r
-import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;\r
-import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;\r
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;\r
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_adapter.rev161201.AddInterfaceToBridgeDomainInput;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_adapter.rev161201.CreateInterfaceOnNodeInput;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_adapter.rev161201.CreateVirtualBridgeDomainOnNodesInput;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_adapter.rev161201.DelInterfaceFromBridgeDomainInput;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_adapter.rev161201.DeleteInterfaceFromNodeInput;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_adapter.rev161201.DeleteVirtualBridgeDomainFromNodesInput;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_adapter.rev161201.CloneVirtualBridgeDomainOnNodesInput;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_adapter.rev161201.bridge.domain.attributes.tunnel.type.Vlan;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_adapter.rev161201.bridge.domain.attributes.tunnel.type.Vxlan;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425._interface.attributes.InterfaceTypeChoice;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425._interface.attributes._interface.type.choice.TapCase;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425._interface.attributes._interface.type.choice.VhostUserCase;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUserRole;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanVni;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyVbridgeAugment;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vlan.rev160429.network.topology.topology.tunnel.parameters.VlanNetworkParameters;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vxlan.rev160429.network.topology.topology.tunnel.parameters.VxlanTunnelParameters;\r
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;\r
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;\r
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;\r
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;\r
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;\r
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
-import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;\r
-import org.opendaylight.yangtools.yang.common.RpcResult;\r
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-import com.google.common.base.Optional;\r
-import com.google.common.util.concurrent.AsyncFunction;\r
-import com.google.common.util.concurrent.CheckedFuture;\r
-import com.google.common.util.concurrent.Futures;\r
-import com.google.common.util.concurrent.ListenableFuture;\r
-\r
-public class VppRpcServiceImpl {\r
-\r
-    private static final Logger LOG = LoggerFactory.getLogger(VppRpcServiceImpl.class);\r
-\r
-    private final DataBroker dataBroker;\r
-    private final BridgeDomainManager bridgeDomainManager;\r
-    private final InterfaceManager interfaceManager;\r
-    private final MountedDataBrokerProvider mountDataProvider;\r
-\r
-    public VppRpcServiceImpl(@Nonnull DataBroker dataBroker, @Nonnull MountedDataBrokerProvider mountDataProvider,\r
-            BridgeDomainManager bridgeDomainManager, InterfaceManager interfaceManager) {\r
-        this.dataBroker = dataBroker;\r
-        this.bridgeDomainManager = bridgeDomainManager;\r
-        this.interfaceManager = interfaceManager;\r
-        this.mountDataProvider = mountDataProvider;\r
-    }\r
-\r
-    public Future<RpcResult<Void>> createVirtualBridgeDomain(CreateVirtualBridgeDomainOnNodesInput input) {\r
-        LOG.info("Processing a remote call for creating bridge domain {}", input.getId());\r
-        if (input.getTunnelType() == null) {\r
-            return Futures.immediateFuture(RpcResultBuilder.<Void>failed()\r
-                .withError(ErrorType.RPC,\r
-                        "Failed to create bridge domain" + input.getId() + "." + "Tunnel type not specified")\r
-                .build());\r
-        }\r
-        List<ListenableFuture<Void>> futures = new ArrayList<>();\r
-        List<NodeId> nodeIds = input.getPhysicalLocationRef()\r
-            .stream()\r
-            .map(locationRef -> locationRef.getNodeId())\r
-            .collect(Collectors.toList());\r
-        LOG.trace("Corresponding nodes for bridge-domain {}", input.getPhysicalLocationRef());\r
-        if (input.getTunnelType() instanceof Vxlan) {\r
-            LOG.trace("Detected VXLAN type for bridge domain {}", input.getId());\r
-            Vxlan tunnelType = (Vxlan) input.getTunnelType();\r
-            VxlanVni vxlanVni = new VxlanVni(tunnelType.getVni().getValue());\r
-            nodeIds.forEach(nodeId -> {\r
-                futures.add(bridgeDomainManager.createVxlanBridgeDomainOnVppNode(input.getId(), vxlanVni, nodeId));\r
-            });\r
-        } else if (input.getTunnelType() instanceof Vlan) {\r
-            LOG.trace("Detected VLAN type for bridge domain {}", input.getId());\r
-            Vlan vlan = (Vlan) input.getTunnelType();\r
-            VlanId vlanId = new VlanId(vlan.getVlanId().getValue());\r
-            nodeIds.forEach(nodeId -> {\r
-                futures.add(bridgeDomainManager.createVlanBridgeDomainOnVppNode(input.getId(), vlanId, nodeId));\r
-            });\r
-        }\r
-        return Futures.transform(Futures.allAsList(futures), voidsToRpcResult());\r
-    }\r
-\r
-    public Future<RpcResult<Void>> deleteVirtualBridgeDomain(DeleteVirtualBridgeDomainFromNodesInput input) {\r
-        LOG.info("Processing a remote call for removing bridge domain {}", input.getBridgeDomainId());\r
-        List<ListenableFuture<Void>> futures = new ArrayList<>();\r
-        input.getBridgeDomainNode().forEach(nodeId -> {\r
-            futures.add(bridgeDomainManager.removeBridgeDomainFromVppNode(input.getBridgeDomainId(), nodeId));\r
-        });\r
-        return Futures.transform(Futures.allAsList(futures), voidsToRpcResult());\r
-    }\r
-\r
-    public ListenableFuture<RpcResult<Void>> cloneVirtualBridgeDomainOnNode(CloneVirtualBridgeDomainOnNodesInput input) {\r
-        LOG.info("Processing a remote call for clonning  bridge domain {}", input.getBridgeDomainId());\r
-        List<ListenableFuture<Void>> futures = new ArrayList<>();\r
-        ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();\r
-        InstanceIdentifier<Topology> topologyIid = VppIidFactory.getTopologyIid(new TopologyKey(new TopologyId(\r
-                input.getBridgeDomainId())));\r
-        return Futures.transform(rTx.read(LogicalDatastoreType.CONFIGURATION, topologyIid),\r
-                new AsyncFunction<Optional<Topology>, RpcResult<Void>>() {\r
-\r
-                    @Override\r
-                    public ListenableFuture<RpcResult<Void>> apply(Optional<Topology> optTopology) throws Exception {\r
-                        if (!optTopology.isPresent()) {\r
-\r
-                            return Futures.immediateFuture(RpcResultBuilder.<Void>failed()\r
-                                .withError(\r
-                                        ErrorType.RPC,\r
-                                        "Failed to clone bridge domain. Bridge domain " + input.getBridgeDomainId()\r
-                                                + " does not exist.")\r
-                                .build());\r
-                        }\r
-                        TopologyVbridgeAugment vBridgeAug = optTopology.get().getAugmentation(TopologyVbridgeAugment.class);\r
-                        if (vBridgeAug == null) {\r
-                            return Futures.immediateFuture(RpcResultBuilder.<Void>failed()\r
-                                .withError(\r
-                                        ErrorType.RPC,\r
-                                        "Failed to clone bridge domain. Topology " + input.getBridgeDomainId()\r
-                                                + " is not bridge domain type.")\r
-                                .build());\r
-                        }\r
-                        if (vBridgeAug.getTunnelParameters() instanceof VxlanTunnelParameters) {\r
-                            LOG.debug("Clonning VXLAN type bridge domain {} on nodes {}", input.getBridgeDomainId(),\r
-                                    input.getBridgeDomainNode());\r
-                            VxlanTunnelParameters vxlanTunnelParams = (VxlanTunnelParameters) vBridgeAug.getTunnelParameters();\r
-                            VxlanVni vni = vxlanTunnelParams.getVni();\r
-                            input.getBridgeDomainNode().forEach(\r
-                                    nodeId -> {\r
-                                        futures.add(bridgeDomainManager.createVxlanBridgeDomainOnVppNode(\r
-                                                input.getBridgeDomainId(), vni, nodeId));\r
-                                    });\r
-                        } else if (vBridgeAug.getTunnelParameters() instanceof VlanNetworkParameters) {\r
-                            LOG.debug("Clonning VLAN type bridge domain {} on nodes {}", input.getBridgeDomainId(),\r
-                                    input.getBridgeDomainNode());\r
-                            VlanNetworkParameters vlanTunnelParams = (VlanNetworkParameters) vBridgeAug.getTunnelParameters();\r
-                            VlanId vlanId = vlanTunnelParams.getVlanId();\r
-                            input.getBridgeDomainNode().forEach(\r
-                                    nodeId -> {\r
-                                        futures.add(bridgeDomainManager.createVlanBridgeDomainOnVppNode(\r
-                                                input.getBridgeDomainId(), vlanId, nodeId));\r
-                                    });\r
-                        }\r
-                        return Futures.transform(Futures.allAsList(futures), voidsToRpcResult());\r
-                    }\r
-                });\r
-    }\r
-\r
-    public ListenableFuture<RpcResult<Void>> createInterfaceOnNodes(CreateInterfaceOnNodeInput input) {\r
-        InterfaceTypeChoice interfaceType = input.getInterfaceTypeChoice();\r
-        ConfigCommand ifaceCommand = null;\r
-        if (interfaceType instanceof VhostUserCase) {\r
-            VhostUserCommandBuilder vhostBuilder = VhostUserCommand.builder();\r
-            vhostBuilder.setName(input.getVppInterfaceName());\r
-            VhostUserCase vhostCase = (VhostUserCase) input.getInterfaceTypeChoice();\r
-            vhostBuilder.setSocket(vhostCase.getSocket());\r
-            vhostBuilder.setRole(VhostUserRole.Client);\r
-            vhostBuilder.setDescription(input.getDescription());\r
-            vhostBuilder.setOperation(Operations.PUT);\r
-            ifaceCommand = vhostBuilder.build();\r
-        }\r
-        if (interfaceType instanceof TapCase) {\r
-            TapPortCommand.TapPortCommandBuilder tapBuilder = TapPortCommand.builder();\r
-            TapCase tapIface = (TapCase) input.getInterfaceTypeChoice();\r
-            tapBuilder.setTapName(tapIface.getName());\r
-            tapBuilder.setPhysAddress(tapIface.getPhysicalAddress());\r
-            tapBuilder.setInterfaceName(input.getVppInterfaceName());\r
-            tapBuilder.setDescription(input.getDescription());\r
-            tapBuilder.setOperation(Operations.PUT);\r
-            ifaceCommand = tapBuilder.build();\r
-        }\r
-        InstanceIdentifier<Node> vppNodeIid = VppIidFactory.getNetconfNodeIid(input.getVppNodeId());\r
-        Optional<DataBroker> optDataBroker = mountDataProvider.getDataBrokerForMountPoint(vppNodeIid);\r
-        if (!optDataBroker.isPresent()) {\r
-            return Futures.immediateFuture(RpcResultBuilder.<Void>failed()\r
-                .withError(ErrorType.RPC, "Cannot find data broker for mount point " + vppNodeIid)\r
-                .build());\r
-        }\r
-        return Futures.transform(interfaceManager.createInterfaceOnVpp(ifaceCommand, optDataBroker.get()),\r
-                voidToRpcResult());\r
-    }\r
+/*
+ * 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.vpp.adapter;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Future;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nonnull;
+
+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.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.ConfigCommand;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.TapPortCommand;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.VhostUserCommand;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.VhostUserCommand.VhostUserCommandBuilder;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General.Operations;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_adapter.rev161201.AddInterfaceToBridgeDomainInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_adapter.rev161201.CreateInterfaceOnNodeInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_adapter.rev161201.CreateVirtualBridgeDomainOnNodesInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_adapter.rev161201.DelInterfaceFromBridgeDomainInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_adapter.rev161201.DeleteInterfaceFromNodeInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_adapter.rev161201.DeleteVirtualBridgeDomainFromNodesInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_adapter.rev161201.CloneVirtualBridgeDomainOnNodesInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_adapter.rev161201.bridge.domain.attributes.tunnel.type.Vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_adapter.rev161201.bridge.domain.attributes.tunnel.type.Vxlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425._interface.attributes.InterfaceTypeChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425._interface.attributes._interface.type.choice.TapCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425._interface.attributes._interface.type.choice.VhostUserCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUserRole;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanVni;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyVbridgeAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vlan.rev160429.network.topology.topology.tunnel.parameters.VlanNetworkParameters;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vxlan.rev160429.network.topology.topology.tunnel.parameters.VxlanTunnelParameters;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
+public class VppRpcServiceImpl {
+
+    private static final Logger LOG = LoggerFactory.getLogger(VppRpcServiceImpl.class);
+
+    private final DataBroker dataBroker;
+    private final BridgeDomainManager bridgeDomainManager;
+    private final InterfaceManager interfaceManager;
+    private final MountedDataBrokerProvider mountDataProvider;
+
+    public VppRpcServiceImpl(@Nonnull DataBroker dataBroker, @Nonnull MountedDataBrokerProvider mountDataProvider,
+            BridgeDomainManager bridgeDomainManager, InterfaceManager interfaceManager) {
+        this.dataBroker = dataBroker;
+        this.bridgeDomainManager = bridgeDomainManager;
+        this.interfaceManager = interfaceManager;
+        this.mountDataProvider = mountDataProvider;
+    }
+
+    public Future<RpcResult<Void>> createVirtualBridgeDomain(CreateVirtualBridgeDomainOnNodesInput input) {
+        LOG.info("Processing a remote call for creating bridge domain {}", input.getId());
+        if (input.getTunnelType() == null) {
+            return Futures.immediateFuture(RpcResultBuilder.<Void>failed()
+                .withError(ErrorType.RPC,
+                        "Failed to create bridge domain" + input.getId() + "." + "Tunnel type not specified")
+                .build());
+        }
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        List<NodeId> nodeIds = (input.getPhysicalLocationRef() == null) ? new ArrayList<>() : input
+            .getPhysicalLocationRef().stream().map(locationRef -> locationRef.getNodeId()).collect(Collectors.toList());
+        LOG.trace("Corresponding nodes for bridge-domain {}", input.getPhysicalLocationRef());
+        if (input.getTunnelType() instanceof Vxlan) {
+            LOG.trace("Detected VXLAN type for bridge domain {}", input.getId());
+            Vxlan tunnelType = (Vxlan) input.getTunnelType();
+            VxlanVni vxlanVni = new VxlanVni(tunnelType.getVni().getValue());
+            nodeIds.forEach(nodeId -> {
+                futures.add(bridgeDomainManager.createVxlanBridgeDomainOnVppNode(input.getId(), vxlanVni, nodeId));
+            });
+        } else if (input.getTunnelType() instanceof Vlan) {
+            LOG.trace("Detected VLAN type for bridge domain {}", input.getId());
+            Vlan vlan = (Vlan) input.getTunnelType();
+            VlanId vlanId = new VlanId(vlan.getVlanId().getValue());
+            nodeIds.forEach(nodeId -> {
+                futures.add(bridgeDomainManager.createVlanBridgeDomainOnVppNode(input.getId(), vlanId, nodeId));
+            });
+        }
+        return Futures.transform(Futures.allAsList(futures), voidsToRpcResult());
+    }
+
+    public Future<RpcResult<Void>> deleteVirtualBridgeDomain(DeleteVirtualBridgeDomainFromNodesInput input) {
+        LOG.info("Processing a remote call for removing bridge domain {}", input.getBridgeDomainId());
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        input.getBridgeDomainNode().forEach(nodeId -> {
+            futures.add(bridgeDomainManager.removeBridgeDomainFromVppNode(input.getBridgeDomainId(), nodeId));
+        });
+        return Futures.transform(Futures.allAsList(futures), voidsToRpcResult());
+    }
+
+    public ListenableFuture<RpcResult<Void>> cloneVirtualBridgeDomainOnNode(CloneVirtualBridgeDomainOnNodesInput input) {
+        LOG.info("Processing a remote call for clonning  bridge domain {}", input.getBridgeDomainId());
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
+        InstanceIdentifier<Topology> topologyIid = VppIidFactory.getTopologyIid(new TopologyKey(new TopologyId(
+                input.getBridgeDomainId())));
+        return Futures.transform(rTx.read(LogicalDatastoreType.CONFIGURATION, topologyIid),
+                new AsyncFunction<Optional<Topology>, RpcResult<Void>>() {
+
+                    @Override
+                    public ListenableFuture<RpcResult<Void>> apply(Optional<Topology> optTopology) throws Exception {
+                        if (!optTopology.isPresent()) {
+
+                            return Futures.immediateFuture(RpcResultBuilder.<Void>failed()
+                                .withError(
+                                        ErrorType.RPC,
+                                        "Failed to clone bridge domain. Bridge domain " + input.getBridgeDomainId()
+                                                + " does not exist.")
+                                .build());
+                        }
+                        TopologyVbridgeAugment vBridgeAug = optTopology.get().getAugmentation(TopologyVbridgeAugment.class);
+                        if (vBridgeAug == null) {
+                            return Futures.immediateFuture(RpcResultBuilder.<Void>failed()
+                                .withError(
+                                        ErrorType.RPC,
+                                        "Failed to clone bridge domain. Topology " + input.getBridgeDomainId()
+                                                + " is not bridge domain type.")
+                                .build());
+                        }
+                        if (vBridgeAug.getTunnelParameters() instanceof VxlanTunnelParameters) {
+                            LOG.debug("Clonning VXLAN type bridge domain {} on nodes {}", input.getBridgeDomainId(),
+                                    input.getBridgeDomainNode());
+                            VxlanTunnelParameters vxlanTunnelParams = (VxlanTunnelParameters) vBridgeAug.getTunnelParameters();
+                            VxlanVni vni = vxlanTunnelParams.getVni();
+                            input.getBridgeDomainNode().forEach(
+                                    nodeId -> {
+                                        futures.add(bridgeDomainManager.createVxlanBridgeDomainOnVppNode(
+                                                input.getBridgeDomainId(), vni, nodeId));
+                                    });
+                        } else if (vBridgeAug.getTunnelParameters() instanceof VlanNetworkParameters) {
+                            LOG.debug("Clonning VLAN type bridge domain {} on nodes {}", input.getBridgeDomainId(),
+                                    input.getBridgeDomainNode());
+                            VlanNetworkParameters vlanTunnelParams = (VlanNetworkParameters) vBridgeAug.getTunnelParameters();
+                            VlanId vlanId = vlanTunnelParams.getVlanId();
+                            input.getBridgeDomainNode().forEach(
+                                    nodeId -> {
+                                        futures.add(bridgeDomainManager.createVlanBridgeDomainOnVppNode(
+                                                input.getBridgeDomainId(), vlanId, nodeId));
+                                    });
+                        }
+                        return Futures.transform(Futures.allAsList(futures), voidsToRpcResult());
+                    }
+                });
+    }
+
+    public ListenableFuture<RpcResult<Void>> createInterfaceOnNodes(CreateInterfaceOnNodeInput input) {
+        LOG.info("Processing a remote call for creating interface {} on node {}", input.getVppInterfaceName(),
+                input.getVppNodeId());
+        InterfaceTypeChoice interfaceType = input.getInterfaceTypeChoice();
+        ConfigCommand ifaceCommand = null;
+        if (interfaceType instanceof VhostUserCase) {
+            VhostUserCommandBuilder vhostBuilder = VhostUserCommand.builder();
+            vhostBuilder.setName(input.getVppInterfaceName());
+            VhostUserCase vhostCase = (VhostUserCase) input.getInterfaceTypeChoice();
+            vhostBuilder.setSocket(vhostCase.getSocket());
+            vhostBuilder.setRole(VhostUserRole.Client);
+            vhostBuilder.setDescription(input.getDescription());
+            vhostBuilder.setOperation(Operations.PUT);
+            ifaceCommand = vhostBuilder.build();
+        }
+        if (interfaceType instanceof TapCase) {
+            TapPortCommand.TapPortCommandBuilder tapBuilder = TapPortCommand.builder();
+            TapCase tapIface = (TapCase) input.getInterfaceTypeChoice();
+            tapBuilder.setTapName(tapIface.getName());
+            tapBuilder.setPhysAddress(tapIface.getPhysicalAddress());
+            tapBuilder.setInterfaceName(input.getVppInterfaceName());
+            tapBuilder.setDescription(input.getDescription());
+            tapBuilder.setOperation(Operations.PUT);
+            ifaceCommand = tapBuilder.build();
+        }
+        InstanceIdentifier<Node> vppNodeIid = VppIidFactory.getNetconfNodeIid(input.getVppNodeId());
+        Optional<DataBroker> optDataBroker = mountDataProvider.getDataBrokerForMountPoint(vppNodeIid);
+        if (!optDataBroker.isPresent()) {
+            return Futures.immediateFuture(RpcResultBuilder.<Void>failed()
+                .withError(ErrorType.RPC, "Cannot find data broker for mount point " + vppNodeIid)
+                .build());
+        }
+        return Futures.transform(interfaceManager.createInterfaceOnVpp(ifaceCommand, optDataBroker.get()),
+                voidToRpcResult());
+    }
 
     public ListenableFuture<RpcResult<Void>> deleteInterfaceFromNodes(DeleteInterfaceFromNodeInput input) {
-        InstanceIdentifier<Node> vppNodeIid = VppIidFactory.getNetconfNodeIid(input.getVppNodeId());\r
-        return Futures.transform(readInterface(vppNodeIid, input.getVppInterfaceName()),\r
-                new AsyncFunction<Optional<Interface>, RpcResult<Void>>() {\r
-\r
-                    @Override\r
-                    public ListenableFuture<RpcResult<Void>> apply(Optional<Interface> optIface) throws Exception {\r
-                        InterfaceKey iKey = new InterfaceKey(input.getVppInterfaceName());\r
-                        if (!optIface.isPresent()) {\r
-                            return Futures.immediateFuture(RpcResultBuilder.<Void>failed()\r
-                                .withError(\r
-                                        ErrorType.RPC,\r
-                                        "Cannot delete interface " + iKey + " on node " + vppNodeIid\r
-                                                + ". Not found or already deleted.")\r
-                                .build());\r
-                        }\r
-                        Optional<DataBroker> dataBroker = mountDataProvider.getDataBrokerForMountPoint(vppNodeIid);\r
-                        WriteTransaction wTx = dataBroker.get().newWriteOnlyTransaction();\r
-                        wTx.delete(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getInterfaceIID(iKey));\r
-                        return Futures.transform(wTx.submit(), voidToRpcResult());\r
-                    }\r
-                });\r
-    }\r
-\r
-    public ListenableFuture<RpcResult<Void>> addInterfaceToBridgeDomain(AddInterfaceToBridgeDomainInput input) {\r
-        InstanceIdentifier<Node> vppNodeIid = VppIidFactory.getNetconfNodeIid(input.getVppNodeId());\r
-        return Futures.transform(readInterface(vppNodeIid, input.getVppInterfaceName()),\r
-                new AsyncFunction<Optional<Interface>, RpcResult<Void>>() {\r
-\r
-                    @Override\r
-                    public ListenableFuture<RpcResult<Void>> apply(Optional<Interface> optIface) throws Exception {\r
-                        InterfaceKey iKey = new InterfaceKey(input.getVppInterfaceName());\r
-                        if (!optIface.isPresent()) {\r
-                            return Futures.immediateFuture(RpcResultBuilder.<Void>failed()\r
-                                .withError(\r
-                                        ErrorType.RPC,\r
-                                        "Cannot add interface " + iKey + " to bridge domain on node "\r
-                                                + vppNodeIid + ". Not found or deleted.")\r
-                                .build());\r
-                        }\r
-                        Optional<DataBroker> dataBroker = mountDataProvider.getDataBrokerForMountPoint(vppNodeIid);\r
-                        return Futures.transform(interfaceManager.configureInterface(dataBroker.get(), iKey,\r
-                                input.getBridgeDomainId(), null), voidToRpcResult());\r
-                    }\r
-                });\r
-    }\r
-\r
-    public ListenableFuture<RpcResult<Void>> delInterfaceFromBridgeDomain(DelInterfaceFromBridgeDomainInput input) {\r
-        InstanceIdentifier<Node> vppNodeIid = VppIidFactory.getNetconfNodeIid(input.getVppNodeId());\r
-        return Futures.transform(readInterface(vppNodeIid, input.getVppInterfaceName()),\r
-                new AsyncFunction<Optional<Interface>, RpcResult<Void>>() {\r
-\r
-                    @Override\r
-                    public ListenableFuture<RpcResult<Void>> apply(Optional<Interface> optIface) throws Exception {\r
-                        if (!optIface.isPresent()) {\r
-                            return Futures.immediateFuture(RpcResultBuilder.<Void>failed()\r
-                                .withError(\r
-                                        ErrorType.RPC,\r
-                                        "Cannot remove interface " + input.getVppInterfaceName()\r
-                                                + " from bridge domain on node " + vppNodeIid\r
-                                                + ". Not found or deleted.")\r
-                                .build());\r
-                        }\r
-                        Optional<DataBroker> dataBroker = mountDataProvider.getDataBrokerForMountPoint(vppNodeIid);\r
-                        return Futures.transform(interfaceManager.removeInterfaceFromBridgeDomain(dataBroker.get(),\r
-                                optIface.get().getKey()), voidToRpcResult());\r
-                    }\r
-                });\r
-    }\r
-\r
-    private CheckedFuture<Optional<Interface>, ReadFailedException> readInterface(InstanceIdentifier<?> nodeIid,\r
-            String interfaceName) {\r
-        Optional<DataBroker> optDataBroker = mountDataProvider.getDataBrokerForMountPoint(nodeIid);\r
-        if (!optDataBroker.isPresent()) {\r
-            LOG.error("Cannot find data broker for node {}", nodeIid);\r
-            return Futures.immediateCheckedFuture(Optional.absent());\r
-        }\r
-        ReadOnlyTransaction rwTx = optDataBroker.get().newReadOnlyTransaction();\r
-        InterfaceKey iKey = new InterfaceKey(interfaceName);\r
-        InstanceIdentifier<Interface> interfaceIID = VppIidFactory.getInterfaceIID(iKey);\r
-        CheckedFuture<Optional<Interface>, ReadFailedException> readInterface = rwTx.read(\r
-                LogicalDatastoreType.CONFIGURATION, interfaceIID);\r
-        rwTx.close();\r
-        return readInterface;\r
-    }\r
-\r
-    private AsyncFunction<Void, RpcResult<Void>> voidToRpcResult() {\r
-        return new AsyncFunction<Void, RpcResult<Void>>() {\r
-\r
-            @Override\r
-            public ListenableFuture<RpcResult<Void>> apply(Void input) throws Exception {\r
-                return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());\r
-            }\r
-        };\r
-    }\r
-\r
-    private AsyncFunction<List<Void>, RpcResult<Void>> voidsToRpcResult() {\r
-        return new AsyncFunction<List<Void>, RpcResult<Void>>() {\r
-\r
-            @Override\r
-            public ListenableFuture<RpcResult<Void>> apply(List<Void> input) throws Exception {\r
-                return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());\r
-            }\r
-        };\r
-    }\r
-}\r
+        LOG.info("Processing a remote call for removing interface {} from node {}", input.getVppInterfaceName(),
+                input.getVppNodeId());
+        InstanceIdentifier<Node> vppNodeIid = VppIidFactory.getNetconfNodeIid(input.getVppNodeId());
+        return Futures.transform(readInterface(vppNodeIid, input.getVppInterfaceName()),
+                new AsyncFunction<Optional<Interface>, RpcResult<Void>>() {
+
+                    @Override
+                    public ListenableFuture<RpcResult<Void>> apply(Optional<Interface> optIface) throws Exception {
+                        InterfaceKey iKey = new InterfaceKey(input.getVppInterfaceName());
+                        if (!optIface.isPresent()) {
+                            return Futures.immediateFuture(RpcResultBuilder.<Void>failed()
+                                .withError(
+                                        ErrorType.RPC,
+                                        "Cannot delete interface " + iKey + " on node " + vppNodeIid
+                                                + ". Not found or already deleted.")
+                                .build());
+                        }
+                        Optional<DataBroker> dataBroker = mountDataProvider.getDataBrokerForMountPoint(vppNodeIid);
+                        WriteTransaction wTx = dataBroker.get().newWriteOnlyTransaction();
+                        wTx.delete(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getInterfaceIID(iKey));
+                        return Futures.transform(wTx.submit(), voidToRpcResult());
+                    }
+                });
+    }
+
+    public ListenableFuture<RpcResult<Void>> addInterfaceToBridgeDomain(AddInterfaceToBridgeDomainInput input) {
+        LOG.info("Processing a remote call for adding interface {} to bridge domain {}", input.getVppInterfaceName(),
+                input.getBridgeDomainId());
+        InstanceIdentifier<Node> vppNodeIid = VppIidFactory.getNetconfNodeIid(input.getVppNodeId());
+        return Futures.transform(readInterface(vppNodeIid, input.getVppInterfaceName()),
+                new AsyncFunction<Optional<Interface>, RpcResult<Void>>() {
+
+                    @Override
+                    public ListenableFuture<RpcResult<Void>> apply(Optional<Interface> optIface) throws Exception {
+                        InterfaceKey iKey = new InterfaceKey(input.getVppInterfaceName());
+                        if (!optIface.isPresent()) {
+                            return Futures.immediateFuture(RpcResultBuilder.<Void>failed()
+                                .withError(
+                                        ErrorType.RPC,
+                                        "Cannot add interface " + iKey + " to bridge domain on node "
+                                                + vppNodeIid + ". Not found or deleted.")
+                                .build());
+                        }
+                        Optional<DataBroker> dataBroker = mountDataProvider.getDataBrokerForMountPoint(vppNodeIid);
+                        return Futures.transform(interfaceManager.configureInterface(dataBroker.get(), iKey,
+                                input.getBridgeDomainId(), null), voidToRpcResult());
+                    }
+                });
+    }
+
+    public ListenableFuture<RpcResult<Void>> delInterfaceFromBridgeDomain(DelInterfaceFromBridgeDomainInput input) {
+        LOG.info("Processing a remote call for removing interface {} from bridge domain.", input.getVppInterfaceName());
+        InstanceIdentifier<Node> vppNodeIid = VppIidFactory.getNetconfNodeIid(input.getVppNodeId());
+        return Futures.transform(readInterface(vppNodeIid, input.getVppInterfaceName()),
+                new AsyncFunction<Optional<Interface>, RpcResult<Void>>() {
+
+                    @Override
+                    public ListenableFuture<RpcResult<Void>> apply(Optional<Interface> optIface) throws Exception {
+                        if (!optIface.isPresent()) {
+                            return Futures.immediateFuture(RpcResultBuilder.<Void>failed()
+                                .withError(
+                                        ErrorType.RPC,
+                                        "Cannot remove interface " + input.getVppInterfaceName()
+                                                + " from bridge domain on node " + vppNodeIid
+                                                + ". Not found or deleted.")
+                                .build());
+                        }
+                        Optional<DataBroker> dataBroker = mountDataProvider.getDataBrokerForMountPoint(vppNodeIid);
+                        return Futures.transform(interfaceManager.removeInterfaceFromBridgeDomain(dataBroker.get(),
+                                optIface.get().getKey()), voidToRpcResult());
+                    }
+                });
+    }
+
+    private CheckedFuture<Optional<Interface>, ReadFailedException> readInterface(InstanceIdentifier<?> nodeIid,
+            String interfaceName) {
+        Optional<DataBroker> optDataBroker = mountDataProvider.getDataBrokerForMountPoint(nodeIid);
+        if (!optDataBroker.isPresent()) {
+            LOG.error("Cannot find data broker for node {}", nodeIid);
+            return Futures.immediateCheckedFuture(Optional.absent());
+        }
+        ReadOnlyTransaction rwTx = optDataBroker.get().newReadOnlyTransaction();
+        InterfaceKey iKey = new InterfaceKey(interfaceName);
+        InstanceIdentifier<Interface> interfaceIID = VppIidFactory.getInterfaceIID(iKey);
+        CheckedFuture<Optional<Interface>, ReadFailedException> readInterface = rwTx.read(
+                LogicalDatastoreType.CONFIGURATION, interfaceIID);
+        rwTx.close();
+        return readInterface;
+    }
+
+    private AsyncFunction<Void, RpcResult<Void>> voidToRpcResult() {
+        return new AsyncFunction<Void, RpcResult<Void>>() {
+
+            @Override
+            public ListenableFuture<RpcResult<Void>> apply(Void input) throws Exception {
+                return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
+            }
+        };
+    }
+
+    private AsyncFunction<List<Void>, RpcResult<Void>> voidsToRpcResult() {
+        return new AsyncFunction<List<Void>, RpcResult<Void>>() {
+
+            @Override
+            public ListenableFuture<RpcResult<Void>> apply(List<Void> input) throws Exception {
+                return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
+            }
+        };
+    }
+}
index bba5f19e44a7aea9a1525e178f0729f67b647e5b..ac6cc065aa5a8107aab7465e894c2f266f4b03a5 100644 (file)
@@ -191,7 +191,7 @@ public class InterfaceManager implements AutoCloseable {
 
     private ListenableFuture<Void> deleteIfaceOnVpp(ConfigCommand deleteIfaceWithoutBdCommand,
             DataBroker vppDataBroker, VppEndpoint vppEndpoint, InstanceIdentifier<?> vppNodeIid) {
-        final boolean transactionState = GbpNetconfTransaction.delete(vppDataBroker, deleteIfaceWithoutBdCommand,
+        final boolean transactionState = GbpNetconfTransaction.deleteIfExists(vppDataBroker, deleteIfaceWithoutBdCommand,
                 GbpNetconfTransaction.RETRY_COUNT);
         if (transactionState) {
             LOG.debug("Delete interface on VPP command was successful: VPP: {} Command: {}", vppNodeIid,
@@ -408,7 +408,7 @@ public class InterfaceManager implements AutoCloseable {
             LOG.warn("Interface already not in bridge domain {} ", ifaceKey);
             return Futures.immediateFuture(null);
         }
-        final boolean transactionState = GbpNetconfTransaction.delete(mountPoint,
+        final boolean transactionState = GbpNetconfTransaction.deleteIfExists(mountPoint,
                 VppIidFactory.getL2ForInterfaceIid(ifaceKey), GbpNetconfTransaction.RETRY_COUNT);
         if (transactionState) {
             LOG.debug("Removing bridge domain from interface {}", VppIidFactory.getInterfaceIID(ifaceKey));
@@ -484,7 +484,7 @@ public class InterfaceManager implements AutoCloseable {
         InstanceIdentifier<L2> l2Iid =
                 interfaceIid.builder().augmentation(VppInterfaceAugmentation.class).child(L2.class).build();
         LOG.debug("Deleting bridge domain from interface {}", interfacePath);
-        final boolean transactionState = GbpNetconfTransaction.delete(mountpoint, l2Iid,
+        final boolean transactionState = GbpNetconfTransaction.deleteIfExists(mountpoint, l2Iid,
                 GbpNetconfTransaction.RETRY_COUNT);
         if (transactionState) {
             return vppEndpointLocationProvider.replaceLocationForEndpoint(new ExternalLocationCaseBuilder()
index 0859505ba0e18be35a69852cf1c26d39bded8c25..007201673cf2768cd4e15a09c5204b710c4dab20 100644 (file)
@@ -11,8 +11,14 @@ package org.opendaylight.groupbasedpolicy.renderer.vpp.manager;
 import static org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus.Connected;
 import static org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus.Connecting;
 
+import javax.annotation.Nullable;
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
 import java.util.stream.Collectors;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
@@ -45,6 +51,7 @@ import org.slf4j.LoggerFactory;
 
 public class VppNodeManager {
 
+    private static final short DURATION = 3000;
     private static final TopologyId TOPOLOGY_ID = new TopologyId("topology-netconf");
     private static final Logger LOG = LoggerFactory.getLogger(VppNodeManager.class);
     private static final String V3PO_CAPABILITY = "(urn:opendaylight:params:xml:ns:yang:v3po?revision=2016-12-14)v3po";
@@ -163,23 +170,31 @@ public class VppNodeManager {
         }
     }
 
+    @Nullable
     private DataBroker getNodeMountPoint(InstanceIdentifier<Node> mountPointIid) {
-        Optional<MountPoint> optionalObject = mountService.getMountPoint(mountPointIid);
-        MountPoint mountPoint;
-        if (optionalObject.isPresent()) {
-            mountPoint = optionalObject.get();
-            if (mountPoint != null) {
-                Optional<DataBroker> optionalDataBroker = mountPoint.getService(DataBroker.class);
-                if (optionalDataBroker.isPresent()) {
-                    return optionalDataBroker.get();
+        final Future<Optional<MountPoint>> futureOptionalObject = getMountpointFromSal(mountPointIid);
+        try {
+            final Optional<MountPoint> optionalObject = futureOptionalObject.get();
+            LOG.debug("Optional mountpoint object: {}", optionalObject);
+            MountPoint mountPoint;
+            if (optionalObject.isPresent()) {
+                mountPoint = optionalObject.get();
+                if (mountPoint != null) {
+                    Optional<DataBroker> optionalDataBroker = mountPoint.getService(DataBroker.class);
+                    if (optionalDataBroker.isPresent()) {
+                        return optionalDataBroker.get();
+                    } else {
+                        LOG.warn("Cannot obtain data broker from mountpoint {}", mountPoint);
+                    }
                 } else {
-                    LOG.warn("Cannot obtain data broker from mountpoint {}", mountPoint);
+                    LOG.warn("Cannot obtain mountpoint with IID {}", mountPointIid);
                 }
-            } else {
-                LOG.warn("Cannot obtain mountpoint with IID {}", mountPointIid);
             }
+            return null;
+        } catch (ExecutionException | InterruptedException e) {
+            LOG.warn("Unable to obtain mountpoint ... {}", e);
+            return null;
         }
-        return null;
     }
 
     private RendererNode remapNode(InstanceIdentifier<Node> path) {
@@ -242,4 +257,30 @@ public class VppNodeManager {
         return Arrays.asList(capabilityEntries);
     }
 
+    // TODO bug 7699
+    // This works as a workaround for mountpoint registration in cluster. If application is registered on different
+    // node as netconf service, it obtains mountpoint registered by SlaveSalFacade (instead of MasterSalFacade). However
+    // this service registers mountpoint a moment later then connectionStatus is set to "Connected". If NodeManager hits
+    // state where device is connected but mountpoint is not yet available, try to get it again in a while
+    private Future<Optional<MountPoint>> getMountpointFromSal(final InstanceIdentifier<Node> iid) {
+        final ExecutorService executorService = Executors.newSingleThreadExecutor();
+        final Callable<Optional<MountPoint>> task = () -> {
+            byte attempt = 0;
+            do {
+                try {
+                    final Optional<MountPoint> optionalMountpoint = mountService.getMountPoint(iid);
+                    if (optionalMountpoint.isPresent()) {
+                        return optionalMountpoint;
+                    }
+                    LOG.warn("Mountpoint {} is not registered yet", iid);
+                    Thread.sleep(DURATION);
+                } catch (InterruptedException e) {
+                    LOG.warn("Thread interrupted to ", e);
+                }
+                attempt ++;
+            } while (attempt <= 3);
+            return Optional.absent();
+        };
+        return executorService.submit(task);
+    }
 }
index 96bc7fdea411a7c57a7f698ca4c082154775fb3d..461ce4bd0296ba8e42804fc5453e2ac34a6851a7 100644 (file)
@@ -24,7 +24,6 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory;
-import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppRendererProcessingException;
 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
 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.network.containment.Containment;
@@ -33,8 +32,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpo
 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.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.L2FloodDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.NetworkDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.fields.Parent;
 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.renderer.endpoints.RendererEndpointKey;
@@ -258,10 +259,17 @@ public final class ForwardingManager {
             }
         }
         if (containment instanceof NetworkDomainContainment) {
-            NetworkDomainContainment netDomainCont = (NetworkDomainContainment) containment;
-            RendererNetworkDomain rendererNetworkDomain =
-                    policyCtx.getNetworkDomainTable().get(ep.getTenant(), new RendererNetworkDomainKey(
-                            netDomainCont.getNetworkDomainId(), netDomainCont.getNetworkDomainType()));
+            final NetworkDomainContainment netDomainCont = (NetworkDomainContainment) containment;
+            final TenantId tenantId = ep.getTenant();
+            final NetworkDomainId domainId = netDomainCont.getNetworkDomainId();
+            final Class<? extends NetworkDomain> domainKey = netDomainCont.getNetworkDomainType();
+            final RendererNetworkDomainKey rendererNetworkDomainKey = new RendererNetworkDomainKey(domainId, domainKey);
+            final RendererNetworkDomain rendererNetworkDomain =
+                    policyCtx.getNetworkDomainTable().get(tenantId, rendererNetworkDomainKey);
+            if (rendererNetworkDomain == null) {
+                LOG.debug("Network domain not found. Containment: {}", containment);
+                return java.util.Optional.empty();
+            }
             java.util.Optional<String> optL2Fd = getForwardingCtxForParent(ep.getTenant(),
                     rendererNetworkDomain.getParent(), policyCtx.getForwardingCtxTable())
                         .filter(fwdCtx -> L2FloodDomain.class.equals(fwdCtx.getContextType()))
index 3eb2c406340798a0a763e78c860295da3e0ce299..b8bf8acca1f4fcdce38472fbb24c7c6f353251ee 100644 (file)
@@ -8,12 +8,6 @@
 
 package org.opendaylight.groupbasedpolicy.renderer.vpp.policy;
 
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.ImmutableTable;
-import com.google.common.collect.ImmutableTable.Builder;
-import com.google.common.collect.Maps;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -22,11 +16,12 @@ import java.util.Optional;
 import java.util.TreeSet;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
+
 import javax.annotation.Nonnull;
+
 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory;
 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.common.rev140421.TenantId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Policy;
 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.renderer.policy.Configuration;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
@@ -40,6 +35,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.renderer.policy.configuration.rule.groups.RuleGroup;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroupKey;
 
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.ImmutableTable;
+import com.google.common.collect.ImmutableTable.Builder;
+import com.google.common.collect.Maps;
+
 public class PolicyContext {
 
     private final RendererPolicy policy;
index b5f18d604f6f4fb92dd7940c0fafc07afa78379f..ff7a79adf40fa11a70b7abd0fb41b032e912d7df 100644 (file)
@@ -36,8 +36,13 @@ public class RendererResolvedPolicy implements Comparable<RendererResolvedPolicy
     }
 
     @Override
-    public int compareTo(RendererResolvedPolicy arg0) {
-        return ruleGroup.compareTo(arg0.getRuleGroup());
+    public int compareTo(RendererResolvedPolicy resolvedPolicy) {
+        int comp = ruleGroup.compareTo(resolvedPolicy.getRuleGroup());
+        if (comp == 0 && (rendererEndpointParticipation.getIntValue() != resolvedPolicy
+            .getRendererEndpointParticipation().getIntValue())) {
+            return 1;
+        }
+        return comp;
     }
 
     @Override
index f0e820daaf1810f95b5b0dc955b1cbfdaff113a1..ac4d715f6f0f2054c5715bb313c98cf0c6b9005c 100644 (file)
@@ -18,6 +18,7 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.ConfigCommand;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
@@ -25,7 +26,7 @@ import org.slf4j.LoggerFactory;
 
 public class GbpNetconfTransaction {
 
-    public static final byte RETRY_COUNT = 5;
+    public static final byte RETRY_COUNT = 3;
     private static final Logger LOG = LoggerFactory.getLogger(GbpNetconfTransaction.class);
 
     /**
@@ -36,7 +37,7 @@ public class GbpNetconfTransaction {
      * @param retryCounter number of attempts
      * @return true if transaction is successful, false otherwise
      */
-    public synchronized static boolean write(final DataBroker mountpoint, final ConfigCommand command,
+    public static synchronized boolean write(final DataBroker mountpoint, final ConfigCommand command,
                                              byte retryCounter) {
         LOG.trace("Netconf WRITE transaction started. RetryCounter: {}", retryCounter);
         Preconditions.checkNotNull(mountpoint);
@@ -45,20 +46,17 @@ public class GbpNetconfTransaction {
             command.execute(rwTx);
             final CheckedFuture<Void, TransactionCommitFailedException> futureTask = rwTx.submit();
             futureTask.get();
-            LOG.trace("Netconf WRITE transaction done. Retry counter: {}", retryCounter);
+            LOG.trace("Netconf WRITE transaction done for command {}", command);
             return true;
-        } catch (IllegalStateException e) {
+        } catch (Exception e) {
             // Retry
             if (retryCounter > 0) {
-                LOG.warn("Assuming that netconf write-transaction failed, restarting ...", e.getMessage());
+                LOG.warn("Netconf WRITE transaction failed to {}. Restarting transaction ... ", e.getMessage());
                 return write(mountpoint, command, --retryCounter);
             } else {
-                LOG.warn("Netconf write-transaction failed. Maximal number of attempts reached", e.getMessage());
+                LOG.warn("Netconf WRITE transaction unsuccessful. Maximal number of attempts reached. Trace: {}", e);
                 return false;
             }
-        } catch (Exception e) {
-            LOG.warn("Exception while writing data ...", e.getMessage());
-            return false;
         }
     }
 
@@ -72,7 +70,7 @@ public class GbpNetconfTransaction {
      * @param <T>          generic data type. Has to be child of {@link DataObject}
      * @return true if transaction is successful, false otherwise
      */
-    public synchronized static <T extends DataObject> boolean write(final DataBroker mountpoint,
+    public static synchronized <T extends DataObject> boolean write(final DataBroker mountpoint,
                                                                     final InstanceIdentifier<T> iid,
                                                                     final T data,
                                                                     byte retryCounter) {
@@ -83,20 +81,17 @@ public class GbpNetconfTransaction {
             rwTx.put(LogicalDatastoreType.CONFIGURATION, iid, data, true);
             final CheckedFuture<Void, TransactionCommitFailedException> futureTask = rwTx.submit();
             futureTask.get();
-            LOG.trace("Netconf WRITE transaction done. Retry counter: {}", retryCounter);
+            LOG.trace("Netconf WRITE transaction done for {}", iid);
             return true;
-        } catch (IllegalStateException e) {
+        } catch (Exception e) {
             // Retry
             if (retryCounter > 0) {
-                LOG.warn("Assuming that netconf write-transaction failed, restarting ...", e.getMessage());
+                LOG.warn("Netconf WRITE transaction failed to {}. Restarting transaction ... ", e.getMessage());
                 return write(mountpoint, iid, data, --retryCounter);
             } else {
-                LOG.warn("Netconf write-transaction failed. Maximal number of attempts reached", e.getMessage());
+                LOG.warn("Netconf WRITE transaction unsuccessful. Maximal number of attempts reached. Trace: {}", e);
                 return false;
             }
-        } catch (Exception e) {
-            LOG.warn("Exception while writing data ...", e.getMessage());
-            return false;
         }
     }
 
@@ -110,7 +105,7 @@ public class GbpNetconfTransaction {
      * @param <T>           generic data type. Has to be child of {@link DataObject}
      * @return optional data object if successful, {@link Optional#absent()} if failed
      */
-    public synchronized static <T extends DataObject> Optional<T> read(final DataBroker mountpoint,
+    public static synchronized <T extends DataObject> Optional<T> read(final DataBroker mountpoint,
                                                                        final LogicalDatastoreType datastoreType,
                                                                        final InstanceIdentifier<T> iid,
                                                                        byte retryCounter) {
@@ -122,61 +117,38 @@ public class GbpNetconfTransaction {
             final CheckedFuture<Optional<T>, ReadFailedException> futureData =
                     rTx.read(datastoreType, iid);
             data = futureData.get();
-            LOG.trace("Netconf READ transaction done. Data present: {}, Retry counter: {}",
-                    data.isPresent(), retryCounter);
+            LOG.trace("Netconf READ transaction done. Data present: {}", data.isPresent());
             return data;
-        } catch (IllegalStateException e) {
+        } catch (Exception e) {
             // Retry
             if (retryCounter > 0) {
-                LOG.warn("Assuming that netconf read-transaction failed, restarting ...", e.getMessage());
+                LOG.warn("Netconf READ transaction failed to {}. Restarting transaction ... ", e.getMessage());
                 rTx.close();
                 return read(mountpoint, datastoreType, iid, --retryCounter);
             } else {
-                LOG.warn("Netconf read-transaction failed. Maximal number of attempts reached", e.getMessage());
+                LOG.warn("Netconf READ transaction unsuccessful. Maximal number of attempts reached. Trace: {}", e);
                 return Optional.absent();
             }
-        } catch (Exception e) {
-            LOG.warn("Exception while reading data ...", e.getMessage());
-            return Optional.absent();
         }
     }
 
     /**
-     * Remove data from remote device using {@link ConfigCommand}. Transaction is restarted if failed.
+     * Remove data from remote device using {@link ConfigCommand}
      *
      * @param mountpoint   to access remote device
      * @param command      config command with data, datastore type and iid
      * @param retryCounter number of attempts
      * @return true if transaction is successful, false otherwise
      */
-    public synchronized static boolean delete(final DataBroker mountpoint, final ConfigCommand command,
+    public static synchronized boolean deleteIfExists(final DataBroker mountpoint, final ConfigCommand command,
                                               byte retryCounter) {
-        LOG.trace("Netconf DELETE transaction started. RetryCounter: {}", retryCounter);
         Preconditions.checkNotNull(mountpoint);
-        final ReadWriteTransaction rwTx = mountpoint.newReadWriteTransaction();
-        try {
-            command.execute(rwTx);
-            final CheckedFuture<Void, TransactionCommitFailedException> futureTask = rwTx.submit();
-            futureTask.get();
-            LOG.trace("Netconf DELETE transaction done. Retry counter: {}", retryCounter);
-            return true;
-        } catch (IllegalStateException e) {
-            // Retry
-            if (retryCounter > 0) {
-                LOG.warn("Assuming that netconf delete-transaction failed, restarting ...", e.getMessage());
-                return delete(mountpoint, command, --retryCounter);
-            } else {
-                LOG.warn("Netconf delete-transaction failed. Maximal number of attempts reached", e.getMessage());
-                return false;
-            }
-        } catch (Exception e) {
-            LOG.warn("Exception while removing data ...", e.getMessage());
-            return false;
-        }
+        InstanceIdentifier<Interface> iid = VppIidFactory.getInterfaceIID(command.getInterfaceBuilder().getKey());
+        return deleteIfExists(mountpoint, iid, retryCounter);
     }
 
     /**
-     * Remove data from remote device. Transaction is restarted if failed.
+     * Remove data from remote device. Data presence is verified before removal. Transaction is restarted if failed.
      *
      * @param mountpoint   to access remote device
      * @param iid          data identifier
@@ -184,31 +156,34 @@ public class GbpNetconfTransaction {
      * @param <T>          generic data type. Has to be child of {@link DataObject}
      * @return true if transaction is successful, false otherwise
      */
-    public synchronized static <T extends DataObject> boolean delete(final DataBroker mountpoint,
+    public static synchronized <T extends DataObject> boolean deleteIfExists(final DataBroker mountpoint,
                                                                      final InstanceIdentifier<T> iid,
                                                                      byte retryCounter) {
-        LOG.trace("Netconf DELETE transaction started. RetryCounter: {}", retryCounter);
+        LOG.trace("Netconf DELETE transaction started. Data will be read at first. RetryCounter: {}", retryCounter);
         Preconditions.checkNotNull(mountpoint);
+        final Optional<T> optionalObject = read(mountpoint, LogicalDatastoreType.CONFIGURATION, iid, RETRY_COUNT);
+        if (!optionalObject.isPresent()) {
+            LOG.warn("Netconf DELETE transaction aborted. Data to remove are not present or cannot be read. Iid: {}",
+                    iid);
+            // Return true, this state is not considered as an error
+            return true;
+        }
         final ReadWriteTransaction rwTx = mountpoint.newReadWriteTransaction();
         try {
             rwTx.delete(LogicalDatastoreType.CONFIGURATION, iid);
             final CheckedFuture<Void, TransactionCommitFailedException> futureTask = rwTx.submit();
             futureTask.get();
-            LOG.trace("Netconf DELETE transaction done. Retry counter: {}", retryCounter);
+            LOG.trace("Netconf DELETE transaction done for {}", iid);
             return true;
-        } catch (IllegalStateException e) {
+        } catch (Exception e) {
             // Retry
             if (retryCounter > 0) {
-                LOG.warn("Assuming that netconf delete-transaction failed, restarting ...", e.getMessage());
-                return delete(mountpoint, iid, --retryCounter);
+                LOG.warn("Netconf DELETE transaction failed to {}. Restarting transaction ... ", e.getMessage());
+                return deleteIfExists(mountpoint, iid, --retryCounter);
             } else {
-                LOG.warn("Netconf delete-transaction failed. Maximal number of attempts reached", e.getMessage());
+                LOG.warn("Netconf DELETE transaction unsuccessful. Maximal number of attempts reached. Trace: {}", e);
                 return false;
             }
-        } catch (Exception e) {
-            LOG.warn("Exception while removing data ...", e.getMessage());
-            return false;
         }
     }
-
-}
+}
\ No newline at end of file
diff --git a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/RendererResolvedPolicyTest.java b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/RendererResolvedPolicyTest.java
new file mode 100644 (file)
index 0000000..5169346
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017 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.vpp;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.RendererResolvedPolicy;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.ResolvedRuleGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation;
+
+/**
+ * It's important not to lose any resolved rule when caching policy.
+ */
+public class RendererResolvedPolicyTest {
+
+    private ResolvedRuleGroup resolvedRuleGroup1;
+    private ResolvedRuleGroup resolvedRuleGroup2;
+    private RendererResolvedPolicy rendResPolicy1;
+    private RendererResolvedPolicy rendResPolicy2;
+    private Set<RendererResolvedPolicy> testSet;
+
+    @Before
+    public void init() {
+        resolvedRuleGroup1 = Mockito.mock(ResolvedRuleGroup.class);
+        resolvedRuleGroup2 = Mockito.mock(ResolvedRuleGroup.class);
+    }
+
+    @Test
+    public void testCompareTo_sameParticipation() {
+        rendResPolicy1 = new RendererResolvedPolicy(EndpointPolicyParticipation.PROVIDER, resolvedRuleGroup1);
+        rendResPolicy2 = new RendererResolvedPolicy(EndpointPolicyParticipation.PROVIDER, resolvedRuleGroup1);
+        testSet = createSet(rendResPolicy1, rendResPolicy2);
+        Assert.assertEquals(testSet.size(), 1);
+        rendResPolicy2 = new RendererResolvedPolicy(EndpointPolicyParticipation.PROVIDER, resolvedRuleGroup2);
+        testSet = createSet(rendResPolicy1, rendResPolicy2);
+        Assert.assertEquals(testSet.size(), 2);
+    }
+
+    @Test
+    public void testCompareTo_differentParticipation() {
+        rendResPolicy1 = new RendererResolvedPolicy(EndpointPolicyParticipation.PROVIDER, resolvedRuleGroup1);
+        rendResPolicy2 = new RendererResolvedPolicy(EndpointPolicyParticipation.CONSUMER, resolvedRuleGroup1);
+        testSet = createSet(rendResPolicy1, rendResPolicy2);
+        Assert.assertEquals(testSet.size(), 2);
+        rendResPolicy2 = new RendererResolvedPolicy(EndpointPolicyParticipation.PROVIDER, resolvedRuleGroup2);
+        testSet = createSet(rendResPolicy1, rendResPolicy2);
+        Assert.assertEquals(testSet.size(), 2);
+    }
+
+    private Set<RendererResolvedPolicy> createSet(RendererResolvedPolicy... rendResolvedPolicies) {
+        Set<RendererResolvedPolicy> policies = new TreeSet<>();
+        Collections.addAll(policies, rendResolvedPolicies);
+        return policies;
+    }
+}
index 29e33ca437a39a1d5589a770cbaf64355093547a..7fa27d596da4f639227fc80f98b950822039d608 100644 (file)
@@ -19,6 +19,7 @@ import static org.mockito.Mockito.when;
 
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.CheckedFuture;
+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;
@@ -27,6 +28,10 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.ConfigCommand;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.LoopbackCommand;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
@@ -35,6 +40,8 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 public class GbpNetconfTransactionTest {
 
+    private final String INTERFACE_KEY = "interface-key";
+    private final String NODE_ID = "node-id";
     private final DataBroker dataBroker = mock(DataBroker.class);
     private final ReadWriteTransaction rwTx = mock(ReadWriteTransaction.class);
     private final ReadOnlyTransaction rTx = mock(ReadOnlyTransaction.class);
@@ -45,22 +52,19 @@ public class GbpNetconfTransactionTest {
     private final CheckedFuture<Void, TransactionCommitFailedException> future = mock(CheckedFuture.class);
     @SuppressWarnings("unchecked")
     private final CheckedFuture<Optional<Node>, ReadFailedException> futureNode = mock(CheckedFuture.class);
-    private final ConfigCommand command = mock(ConfigCommand.class);
+    @SuppressWarnings("unchecked")
+    private final CheckedFuture<Optional<Interface>, ReadFailedException> futureInterface = mock(CheckedFuture.class);
+    private final ConfigCommand command = mock(LoopbackCommand.class);
+    private final InterfaceBuilder interfaceBuilder = new InterfaceBuilder().setKey(new InterfaceKey(INTERFACE_KEY));
 
-    @Test
-    public void writeConfigCommandExceptionTest() {
+    @Before
+    public void init() {
+        when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx);
         when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx);
-        doThrow(new RuntimeException()).when(command).execute(rwTx);
-
-        final boolean result = GbpNetconfTransaction.write(dataBroker, command, (byte)5);
-        verify(dataBroker, times(1)).newReadWriteTransaction();
-        assertFalse(result);
-
     }
 
     @Test
     public void writeConfigCommandReattemptTest() {
-        when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx);
         doThrow(new IllegalStateException()).when(command).execute(rwTx);
 
         final boolean result = GbpNetconfTransaction.write(dataBroker, command, (byte)5);
@@ -70,7 +74,6 @@ public class GbpNetconfTransactionTest {
 
     @Test
     public void writeConfigCommandTest() throws Exception {
-        when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx);
         when(rwTx.submit()).thenReturn(future);
         doNothing().when(command).execute(rwTx);
         when(future.get()).thenReturn(null);
@@ -80,19 +83,8 @@ public class GbpNetconfTransactionTest {
         assertTrue(result);
     }
 
-    @Test
-    public void writeDataExceptionTest() {
-        when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx);
-        doThrow(new RuntimeException()).when(rwTx).put(LogicalDatastoreType.CONFIGURATION, nodeIid, node, true);
-
-        final boolean result = GbpNetconfTransaction.write(dataBroker, nodeIid, node, (byte)5);
-        verify(dataBroker, times(1)).newReadWriteTransaction();
-        assertFalse(result);
-    }
-
     @Test
     public void writeDataReattemptTest() {
-        when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx);
         doThrow(new IllegalStateException()).when(rwTx).put(LogicalDatastoreType.CONFIGURATION, nodeIid, node, true);
 
         final boolean result = GbpNetconfTransaction.write(dataBroker, nodeIid, node, (byte)5);
@@ -102,7 +94,6 @@ public class GbpNetconfTransactionTest {
 
     @Test
     public void writeDataTest() throws Exception {
-        when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx);
         when(rwTx.submit()).thenReturn(future);
         doNothing().when(rwTx).put(LogicalDatastoreType.CONFIGURATION, nodeIid, node, true);
         when(future.get()).thenReturn(null);
@@ -112,20 +103,8 @@ public class GbpNetconfTransactionTest {
         assertTrue(result);
     }
 
-    @Test
-    public void readDataExceptionTest() {
-        when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx);
-        doThrow(new RuntimeException()).when(rTx).read(LogicalDatastoreType.CONFIGURATION, nodeIid);
-
-        final Optional<Node> result = GbpNetconfTransaction.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
-                nodeIid, (byte)5);
-        verify(dataBroker, times(1)).newReadOnlyTransaction();
-        assertFalse(result.isPresent());
-    }
-
     @Test
     public void readDataReattemptTest() {
-        when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx);
         doThrow(new IllegalStateException()).when(rTx).read(LogicalDatastoreType.CONFIGURATION, nodeIid);
 
         final Optional<Node> result = GbpNetconfTransaction.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
@@ -136,10 +115,9 @@ public class GbpNetconfTransactionTest {
 
     @Test
     public void readDataTest() throws Exception {
-        when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx);
         when(rTx.read(LogicalDatastoreType.CONFIGURATION, nodeIid)).thenReturn(futureNode);
         when(futureNode.get()).thenReturn(Optional.of(new NodeBuilder()
-                .setKey(new NodeKey(new NodeId("node"))).build()));
+                .setKey(new NodeKey(new NodeId(NODE_ID))).build()));
 
         final Optional<Node> result = GbpNetconfTransaction.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
                 nodeIid, (byte)5);
@@ -148,65 +126,81 @@ public class GbpNetconfTransactionTest {
     }
 
     @Test
-    public void deleteConfigCommandExceptionTest() {
-        when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx);
-        doThrow(new RuntimeException()).when(command).execute(rwTx);
+    public void deleteConfigCommandMissingDataTest() throws Exception {
+        final InstanceIdentifier<Interface> iid = VppIidFactory.getInterfaceIID(interfaceBuilder.getKey());
+        when(command.getInterfaceBuilder()).thenReturn(interfaceBuilder);
+        when(rTx.read(LogicalDatastoreType.CONFIGURATION, iid)).thenReturn(futureInterface);
+        when(futureInterface.get()).thenReturn(Optional.absent());
+        doThrow(new IllegalStateException()).when(command).execute(rwTx);
 
-        final boolean result = GbpNetconfTransaction.delete(dataBroker, command, (byte)5);
-        verify(dataBroker, times(1)).newReadWriteTransaction();
-        assertFalse(result);
+        final boolean result = GbpNetconfTransaction.deleteIfExists(dataBroker, command, (byte)5);
+        verify(dataBroker, times(1)).newReadOnlyTransaction();
+        assertTrue(result);
     }
 
     @Test
-    public void deleteConfigCommandReattemptTest() {
-        when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx);
+    public void deleteConfigCommandReattemptTest() throws Exception {
+        final InstanceIdentifier<Interface> iid = VppIidFactory.getInterfaceIID(interfaceBuilder.getKey());
+        when(command.getInterfaceBuilder()).thenReturn(interfaceBuilder);
+        when(rTx.read(LogicalDatastoreType.CONFIGURATION, iid)).thenReturn(futureInterface);
+        when(futureInterface.get()).thenReturn(Optional.of(new InterfaceBuilder()
+                .setKey(new InterfaceKey(INTERFACE_KEY)).build()));
         doThrow(new IllegalStateException()).when(command).execute(rwTx);
 
-        final boolean result = GbpNetconfTransaction.delete(dataBroker, command, (byte)5);
+        final boolean result = GbpNetconfTransaction.deleteIfExists(dataBroker, command, (byte)5);
         verify(dataBroker, times(6)).newReadWriteTransaction();
         assertFalse(result);
     }
 
     @Test
     public void deleteConfigCommandTest() throws Exception {
-        when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx);
+        final InstanceIdentifier<Interface> iid = VppIidFactory.getInterfaceIID(interfaceBuilder.getKey());
+        when(command.getInterfaceBuilder()).thenReturn(interfaceBuilder);
+        when(rTx.read(LogicalDatastoreType.CONFIGURATION, iid)).thenReturn(futureInterface);
+        when(futureInterface.get()).thenReturn(Optional.of(new InterfaceBuilder()
+                .setKey(new InterfaceKey(INTERFACE_KEY)).build()));
         when(rwTx.submit()).thenReturn(future);
         doNothing().when(command).execute(rwTx);
         when(future.get()).thenReturn(null);
 
-        final boolean result = GbpNetconfTransaction.delete(dataBroker, command, (byte)5);
+        final boolean result = GbpNetconfTransaction.deleteIfExists(dataBroker, command, (byte)5);
         verify(dataBroker, times(1)).newReadWriteTransaction();
         assertTrue(result);
     }
 
     @Test
-    public void deleteDataExceptionTest() {
-        when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx);
-        doThrow(new RuntimeException()).when(rwTx).delete(LogicalDatastoreType.CONFIGURATION, nodeIid);
+    public void deleteDataMissingDataTest() throws Exception {
+        when(rTx.read(LogicalDatastoreType.CONFIGURATION, nodeIid)).thenReturn(futureNode);
+        when(futureNode.get()).thenReturn(Optional.absent());
+        doThrow(new IllegalStateException()).when(command).execute(rwTx);
 
-        final boolean result = GbpNetconfTransaction.delete(dataBroker, nodeIid, (byte)5);
-        verify(dataBroker, times(1)).newReadWriteTransaction();
-        assertFalse(result);
+        final boolean result = GbpNetconfTransaction.deleteIfExists(dataBroker, nodeIid, (byte)5);
+        verify(dataBroker, times(1)).newReadOnlyTransaction();
+        assertTrue(result);
     }
 
     @Test
-    public void deleteDataReattemptTest() {
-        when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx);
+    public void deleteDataReattemptTest() throws Exception {
+        when(rTx.read(LogicalDatastoreType.CONFIGURATION, nodeIid)).thenReturn(futureNode);
+        when(futureNode.get()).thenReturn(Optional.of(new NodeBuilder()
+                .setKey(new NodeKey(new NodeId(NODE_ID))).build()));
         doThrow(new IllegalStateException()).when(rwTx).delete(LogicalDatastoreType.CONFIGURATION, nodeIid);
 
-        final boolean result = GbpNetconfTransaction.delete(dataBroker, nodeIid, (byte)5);
+        final boolean result = GbpNetconfTransaction.deleteIfExists(dataBroker, nodeIid, (byte)5);
         verify(dataBroker, times(6)).newReadWriteTransaction();
         assertFalse(result);
     }
 
     @Test
     public void deleteDataTest() throws Exception {
-        when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx);
+        when(rTx.read(LogicalDatastoreType.CONFIGURATION, nodeIid)).thenReturn(futureNode);
+        when(futureNode.get()).thenReturn(Optional.of(new NodeBuilder()
+                .setKey(new NodeKey(new NodeId(NODE_ID))).build()));
         when(rwTx.submit()).thenReturn(future);
         doNothing().when(rwTx).delete(LogicalDatastoreType.CONFIGURATION, nodeIid);
         when(future.get()).thenReturn(null);
 
-        final boolean result = GbpNetconfTransaction.delete(dataBroker, nodeIid, (byte)5);
+        final boolean result = GbpNetconfTransaction.deleteIfExists(dataBroker, nodeIid, (byte)5);
         verify(dataBroker, times(1)).newReadWriteTransaction();
         assertTrue(result);
     }
similarity index 95%
rename from ip-sgt-distribution-service/pom.xml
rename to sxp-integration/ip-sgt-distribution-service/pom.xml
index 6d3279216a44017088bd1d51ef3189cff081fc57..40046ca6aa10bf9fa51754062159a5f8d4f9735c 100644 (file)
@@ -92,7 +92,7 @@
         </dependency>
         <dependency>
             <groupId>org.mockito</groupId>
-            <artifactId>mockito-all</artifactId>
+            <artifactId>mockito-core</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
             <artifactId>powermock-api-mockito</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-log4j12</artifactId>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-broker-impl</artifactId>
@@ -19,9 +19,12 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.CheckedFuture;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
@@ -43,6 +46,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.SxpNodeI
 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.SxpDomains;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.SxpDomainsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.sxp.domains.SxpDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.sxp.domains.SxpDomainBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.sxp.domains.SxpDomainKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.sxp.connections.fields.Connections;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.sxp.connections.fields.connections.Connection;
@@ -58,10 +62,6 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableList;
-import com.google.common.util.concurrent.CheckedFuture;
-
 public class SxpCapableNodeListenerTest extends CustomDataBrokerTest {
 
     private final String SXP_NODE_ID = "sxp_node";
@@ -71,6 +71,7 @@ public class SxpCapableNodeListenerTest extends CustomDataBrokerTest {
     private final String TOPOLOGY_ID = "topology";
     private final String DOMAIN_ID = TOPOLOGY_ID + "/" + NODE_ID;
     private final PortNumber SXP_PORT = new PortNumber(64999);
+    private static final String SXP_DOMAIN_NAME = "JUNIT_SXP_DOMAIN_NAME";
     private DataBroker dataBroker;
     private SxpCapableNodeListener nodeListener;
 
@@ -91,11 +92,11 @@ public class SxpCapableNodeListenerTest extends CustomDataBrokerTest {
         nodeListener = new SxpCapableNodeListener(dataBroker, SXP_NODE_ID);
         DataTreeIdentifier<SxpConnection> iid = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
                 InstanceIdentifier.builder(NetworkTopology.class)
-                    .child(Topology.class)
-                    .child(Node.class)
-                    .augmentation(SxpConnectionAugmentation.class)
-                    .child(SxpConnection.class)
-                    .build());
+                        .child(Topology.class)
+                        .child(Node.class)
+                        .augmentation(SxpConnectionAugmentation.class)
+                        .child(SxpConnection.class)
+                        .build());
         verify(dataBroker).registerDataTreeChangeListener(iid, nodeListener);
     }
 
@@ -104,7 +105,7 @@ public class SxpCapableNodeListenerTest extends CustomDataBrokerTest {
         dataBroker = mock(DataBroker.class);
         ListenerRegistration<SxpCapableNodeListener> registration = mock(ListenerRegistration.class);
         when(dataBroker.registerDataTreeChangeListener(any(), isA(SxpCapableNodeListener.class)))
-            .thenReturn(registration);
+                .thenReturn(registration);
         nodeListener = new SxpCapableNodeListener(dataBroker, SXP_NODE_ID);
         nodeListener.close();
         verify(registration).close();
@@ -114,37 +115,42 @@ public class SxpCapableNodeListenerTest extends CustomDataBrokerTest {
     public void testOnDataTreeChange_createAndDeleteNode() throws Exception {
         Node sxpNode =
                 new NodeBuilder().setNodeId(new NodeId(SXP_NODE_ID))
-                    .addAugmentation(SxpNodeIdentity.class,
-                            new SxpNodeIdentityBuilder().setSxpDomains(new SxpDomainsBuilder().build()).build())
-                    .build();
+                        .addAugmentation(SxpNodeIdentity.class,
+                                new SxpNodeIdentityBuilder().setSxpDomains(new SxpDomainsBuilder()
+                                        .setSxpDomain(Collections.singletonList(
+                                                new SxpDomainBuilder()
+                                                        .setDomainName(SXP_DOMAIN_NAME)
+                                                        .build()))
+                                        .build()).build())
+                        .build();
         InstanceIdentifier<Node> sxpNodeIid =
                 InstanceIdentifier.builder(NetworkTopology.class)
-                    .child(Topology.class,
-                            new TopologyKey(new TopologyId(IpSgtDistributionServiceImpl.SXP_TOPOLOGY_ID)))
-                    .child(Node.class, new NodeKey(new NodeId(SXP_NODE_ID)))
-                    .build();
+                        .child(Topology.class,
+                                new TopologyKey(new TopologyId(IpSgtDistributionServiceImpl.SXP_TOPOLOGY_ID)))
+                        .child(Node.class, new NodeKey(new NodeId(SXP_NODE_ID)))
+                        .build();
         WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
         wtx.put(LogicalDatastoreType.CONFIGURATION, sxpNodeIid, sxpNode, true);
         Node node = new NodeBuilder().setNodeId(new NodeId(NODE_ID))
-            .addAugmentation(SxpConnectionAugmentation.class, new SxpConnectionAugmentationBuilder()
-                .setSxpConnection(new SxpConnectionBuilder().setIpAddress(IP_ADDR).setPassword(PASSWD).build()).build())
-            .build();
+                .addAugmentation(SxpConnectionAugmentation.class, new SxpConnectionAugmentationBuilder()
+                        .setSxpConnection(new SxpConnectionBuilder().setIpAddress(IP_ADDR).setPassword(PASSWD).build()).build())
+                .build();
         InstanceIdentifier<Node> nodeIid = InstanceIdentifier.builder(NetworkTopology.class)
-            .child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID)))
-            .child(Node.class, new NodeKey(new NodeId(NODE_ID)))
-            .build();
+                .child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID)))
+                .child(Node.class, new NodeKey(new NodeId(NODE_ID)))
+                .build();
         wtx.put(LogicalDatastoreType.CONFIGURATION, nodeIid, node, true);
         wtx.submit().get();
         assertEquals(DOMAIN_ID, nodeListener.getDomainIdForPeer(nodeIid));
         InstanceIdentifier<SxpDomain> domainIid =
                 InstanceIdentifier.builder(NetworkTopology.class)
-                    .child(Topology.class,
-                            new TopologyKey(new TopologyId(IpSgtDistributionServiceImpl.SXP_TOPOLOGY_ID)))
-                    .child(Node.class, new NodeKey(new NodeId(SXP_NODE_ID)))
-                    .augmentation(SxpNodeIdentity.class)
-                    .child(SxpDomains.class)
-                    .child(SxpDomain.class, new SxpDomainKey(DOMAIN_ID))
-                    .build();
+                        .child(Topology.class,
+                                new TopologyKey(new TopologyId(IpSgtDistributionServiceImpl.SXP_TOPOLOGY_ID)))
+                        .child(Node.class, new NodeKey(new NodeId(SXP_NODE_ID)))
+                        .augmentation(SxpNodeIdentity.class)
+                        .child(SxpDomains.class)
+                        .child(SxpDomain.class, new SxpDomainKey(DOMAIN_ID))
+                        .build();
         ReadOnlyTransaction rtx = dataBroker.newReadOnlyTransaction();
         CheckedFuture<Optional<SxpDomain>, ReadFailedException> read =
                 rtx.read(LogicalDatastoreType.CONFIGURATION, domainIid);
index 40b42ab3b5e8a0053809b9d1e4bb7c3732ba07f5..043806f6e801d718ee21966200e57dc49003f8d6 100644 (file)
@@ -26,6 +26,7 @@
     <modules>
         <module>sxp-ep-provider</module>
         <module>sxp-ise-adapter</module>
+        <module>ip-sgt-distribution-service</module>
     </modules>
 
     <dependencyManagement>
index 84afb4c9df4a74d96770d749314f99122a66bb92..3841d46ec6bd833435d738bcc1ba5860bd422c23 100755 (executable)
@@ -55,7 +55,7 @@
         </dependency>
         <dependency>
             <groupId>org.mockito</groupId>
-            <artifactId>mockito-all</artifactId>
+            <artifactId>mockito-core</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
index 50e00c34216d85a0fba769ff2a2696779c18e9e6..a3b7e18eb2692e5299997a36f2ad9f30f0e98aa9 100755 (executable)
@@ -51,7 +51,7 @@
         </dependency>
         <dependency>
             <groupId>org.mockito</groupId>
-            <artifactId>mockito-all</artifactId>
+            <artifactId>mockito-core</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>