Merge "Unit tests for NeutronSubnetAware"
authorMartin Sunal <msunal@cisco.com>
Mon, 27 Jun 2016 11:59:28 +0000 (11:59 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 27 Jun 2016 11:59:28 +0000 (11:59 +0000)
33 files changed:
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/AddressEndpointUtils.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ContainmentEndpointUtils.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/RendererConfigurationBuilder.java
groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/RendererManager.java
groupbasedpolicy/src/main/yang/model/renderer.yang
groupbasedpolicy/src/test/java/org/opendaylight/groupbasedpolicy/renderer/RendererManagerTest.java
location-providers/ne-location-provider/src/main/java/org/opendaylight/groupbasedpolicy/ne/location/provider/NeLocationProvider.java
location-providers/ne-location-provider/src/main/yang/network-elements.yang
location-providers/ne-location-provider/src/test/java/org/opendaylight/groupbasedpolicy/ne/location/provider/NeLocationProviderTest.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronSubnetAware.java
neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/NetworkAware.java
renderers/ios-xe/pom.xml
renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/IosXeRendererProviderImpl.java
renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/NodeManager.java
renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyConfigurationContext.java [new file with mode: 0644]
renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImpl.java
renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/PolicyManagerUtil.java
renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/ServiceChainingUtil.java
renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/StatusUtil.java [new file with mode: 0644]
renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/NetconfTransactionCreator.java [new file with mode: 0644]
renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/NodeWriter.java
renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/PolicyWriter.java
renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/PolicyWriterUtil.java [new file with mode: 0644]
renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImplTest.java
renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/PolicyManagerUtilTest.java
renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/ServiceChainingUtilTest.java
renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/StatusUtilTest.java [new file with mode: 0644]
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/OfWriter.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowTable.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/BridgeDomainManagerImpl.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/PolicyContext.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/KeyFactory.java
renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/VppRendererPolicyManagerTest.java

index 1675bb803485c6c8696a70a201f7c9766dab43ae..8342f579edf653255e494534c2528a07851e4b55 100644 (file)
@@ -9,9 +9,9 @@
 package org.opendaylight.groupbasedpolicy.renderer;
 
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.endpoints.PeerEndpointKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.external.endpoints.PeerExternalEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalEndpointKey;
 
 public class AddressEndpointUtils {
 
index 86a5d0cfbe6dfcfe2fa39f322077c846b966484c..de3f9681cc6df7a53fc792c68163cbbab8536164 100644 (file)
@@ -9,7 +9,7 @@
 package org.opendaylight.groupbasedpolicy.renderer;
 
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.external.containment.endpoints.PeerExternalContainmentEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalContainmentEndpointKey;
 
 public class ContainmentEndpointUtils {
 
index 33908b4b1422bb399939d032d11f0ca1e73dcadd..00b343670899bea860a900363b7426550cdd4150 100644 (file)
@@ -8,6 +8,14 @@
 
 package org.opendaylight.groupbasedpolicy.renderer;
 
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.HashBasedTable;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableTable;
+import com.google.common.collect.Table;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -16,10 +24,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
-
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
-
 import org.opendaylight.groupbasedpolicy.api.EndpointAugmentor;
 import org.opendaylight.groupbasedpolicy.api.NetworkDomainAugmentor;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocation;
@@ -34,9 +40,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.NetworkDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.endpoints.PeerEndpointKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.external.containment.endpoints.PeerExternalContainmentEndpointKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.external.endpoints.PeerExternalEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.Endpoints;
@@ -54,15 +57,15 @@ 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.renderer.endpoints.RendererEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicy;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicyBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicyKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalContainmentEndpointWithPolicy;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalContainmentEndpointWithPolicyBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalContainmentEndpointWithPolicyKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalEndpointWithPolicy;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalEndpointWithPolicyBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalEndpointWithPolicyKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalContainmentEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalContainmentEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalContainmentEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.RendererForwardingByTenant;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.RendererForwardingByTenantBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.renderer.forwarding.by.tenant.RendererForwardingContext;
@@ -76,15 +79,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.p
 import org.opendaylight.yangtools.yang.binding.Augmentation;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableTable;
-import com.google.common.collect.Table;
-
 public class RendererConfigurationBuilder {
 
     private final Table<RendererEndpointKey, PeerEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByEpAndPeerEp =
@@ -180,25 +174,25 @@ public class RendererConfigurationBuilder {
         for (RendererEndpointKey rendererEpKey : policiesByEpAndPeerEp.rowKeySet()) {
             RendererEndpointBuilder rendererEpBuilder =
                     resolveRendererEndpointBuilder(rendererEpKey, rendererEpBuilderByKey);
-            List<PeerEndpointWithPolicy> peerEpsWithPolicy =
-                    toListPeerEndpointWithPolicy(policiesByEpAndPeerEp.row(rendererEpKey));
-            rendererEpBuilder.setPeerEndpointWithPolicy(peerEpsWithPolicy);
+            List<PeerEndpoint> peerEps =
+                    toListPeerEndpoint(policiesByEpAndPeerEp.row(rendererEpKey));
+            rendererEpBuilder.setPeerEndpoint(peerEps);
             rendererEpBuilderByKey.put(rendererEpKey, rendererEpBuilder);
         }
         for (RendererEndpointKey rendererEpKey : policiesByEpAndPeerExtEp.rowKeySet()) {
             RendererEndpointBuilder rendererEpBuilder =
                     resolveRendererEndpointBuilder(rendererEpKey, rendererEpBuilderByKey);
-            List<PeerExternalEndpointWithPolicy> peerExtEpsWithPolicy =
-                    toListPeerExternalEndpointWithPolicy(policiesByEpAndPeerExtEp.row(rendererEpKey));
-            rendererEpBuilder.setPeerExternalEndpointWithPolicy(peerExtEpsWithPolicy);
+            List<PeerExternalEndpoint> peerExtEps =
+                    toListPeerExternalEndpoint(policiesByEpAndPeerExtEp.row(rendererEpKey));
+            rendererEpBuilder.setPeerExternalEndpoint(peerExtEps);
             rendererEpBuilderByKey.put(rendererEpKey, rendererEpBuilder);
         }
         for (RendererEndpointKey rendererEpKey : policiesByEpAndPeerExtCtxEp.rowKeySet()) {
             RendererEndpointBuilder rendererEpBuilder =
                     resolveRendererEndpointBuilder(rendererEpKey, rendererEpBuilderByKey);
-            List<PeerExternalContainmentEndpointWithPolicy> peerExtContEpsWithPolicy =
-                    toListPeerExternalContainmentEndpointWithPolicy(policiesByEpAndPeerExtCtxEp.row(rendererEpKey));
-            rendererEpBuilder.setPeerExternalContainmentEndpointWithPolicy(peerExtContEpsWithPolicy);
+            List<PeerExternalContainmentEndpoint> peerExtContEps =
+                    toListPeerExternalContainmentEndpoint(policiesByEpAndPeerExtCtxEp.row(rendererEpKey));
+            rendererEpBuilder.setPeerExternalContainmentEndpoint(peerExtContEps);
             rendererEpBuilderByKey.put(rendererEpKey, rendererEpBuilder);
         }
         List<RendererEndpoint> rendererEps = new ArrayList<>();
@@ -218,57 +212,57 @@ public class RendererConfigurationBuilder {
         return rendererEpBuilder;
     }
 
-    private static List<PeerEndpointWithPolicy> toListPeerEndpointWithPolicy(
+    private static List<PeerEndpoint> toListPeerEndpoint(
             Map<PeerEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByPeerEp) {
-        List<PeerEndpointWithPolicy> peerEpsWithPolicy = new ArrayList<>();
+        List<PeerEndpoint> peerEps = new ArrayList<>();
         for (Entry<PeerEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> entry : policiesByPeerEp
             .entrySet()) {
             PeerEndpointKey peerEpKey = entry.getKey();
-            PeerEndpointWithPolicyKey peerEndpointWithPolicyKey = new PeerEndpointWithPolicyKey(peerEpKey.getAddress(),
+            PeerEndpointKey peerEndpointKey = new PeerEndpointKey(peerEpKey.getAddress(),
                     peerEpKey.getAddressType(), peerEpKey.getContextId(), peerEpKey.getContextType());
-            PeerEndpointWithPolicy peerEndpointWithPolicy =
-                    new PeerEndpointWithPolicyBuilder().setKey(peerEndpointWithPolicyKey)
+            PeerEndpoint peerEndpoint =
+                    new PeerEndpointBuilder().setKey(peerEndpointKey)
                         .setRuleGroupWithRendererEndpointParticipation(new ArrayList<>(entry.getValue()))
                         .build();
-            peerEpsWithPolicy.add(peerEndpointWithPolicy);
+            peerEps.add(peerEndpoint);
         }
-        return peerEpsWithPolicy;
+        return peerEps;
     }
 
-    private static List<PeerExternalEndpointWithPolicy> toListPeerExternalEndpointWithPolicy(
+    private static List<PeerExternalEndpoint> toListPeerExternalEndpoint(
             Map<PeerExternalEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByPeerExtEp) {
-        List<PeerExternalEndpointWithPolicy> peerExtEpsWithPolicy = new ArrayList<>();
+        List<PeerExternalEndpoint> peerExtEps = new ArrayList<>();
         for (Entry<PeerExternalEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> entry : policiesByPeerExtEp
             .entrySet()) {
             PeerExternalEndpointKey peerEpKey = entry.getKey();
-            PeerExternalEndpointWithPolicyKey peerExternalEpWithPolicyKey =
-                    new PeerExternalEndpointWithPolicyKey(peerEpKey.getAddress(), peerEpKey.getAddressType(),
+            PeerExternalEndpointKey peerExternalEpKey =
+                    new PeerExternalEndpointKey(peerEpKey.getAddress(), peerEpKey.getAddressType(),
                             peerEpKey.getContextId(), peerEpKey.getContextType());
-            PeerExternalEndpointWithPolicy peerExternalEpWithPolicy =
-                    new PeerExternalEndpointWithPolicyBuilder().setKey(peerExternalEpWithPolicyKey)
+            PeerExternalEndpoint peerExternalEp =
+                    new PeerExternalEndpointBuilder().setKey(peerExternalEpKey)
                         .setRuleGroupWithRendererEndpointParticipation(new ArrayList<>(entry.getValue()))
                         .build();
-            peerExtEpsWithPolicy.add(peerExternalEpWithPolicy);
+            peerExtEps.add(peerExternalEp);
         }
-        return peerExtEpsWithPolicy;
+        return peerExtEps;
     }
 
-    private static List<PeerExternalContainmentEndpointWithPolicy> toListPeerExternalContainmentEndpointWithPolicy(
+    private static List<PeerExternalContainmentEndpoint> toListPeerExternalContainmentEndpoint(
             Map<PeerExternalContainmentEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> policiesByPeerExtContEp) {
-        List<PeerExternalContainmentEndpointWithPolicy> peerExtContEpsWithPolicy = new ArrayList<>();
+        List<PeerExternalContainmentEndpoint> peerExtContEps = new ArrayList<>();
         for (Entry<PeerExternalContainmentEndpointKey, Set<RuleGroupWithRendererEndpointParticipation>> entry : policiesByPeerExtContEp
             .entrySet()) {
             PeerExternalContainmentEndpointKey peerEpKey = entry.getKey();
-            PeerExternalContainmentEndpointWithPolicyKey peerExternalContEpWithPolicyKey =
-                    new PeerExternalContainmentEndpointWithPolicyKey(peerEpKey.getContextId(),
+            PeerExternalContainmentEndpointKey peerExternalContEpKey =
+                    new PeerExternalContainmentEndpointKey(peerEpKey.getContextId(),
                             peerEpKey.getContextType());
-            PeerExternalContainmentEndpointWithPolicy peerExternalContEpWithPolicy =
-                    new PeerExternalContainmentEndpointWithPolicyBuilder().setKey(peerExternalContEpWithPolicyKey)
+            PeerExternalContainmentEndpoint peerExternalContEp =
+                    new PeerExternalContainmentEndpointBuilder().setKey(peerExternalContEpKey)
                         .setRuleGroupWithRendererEndpointParticipation(new ArrayList<>(entry.getValue()))
                         .build();
-            peerExtContEpsWithPolicy.add(peerExternalContEpWithPolicy);
+            peerExtContEps.add(peerExternalContEp);
         }
-        return peerExtContEpsWithPolicy;
+        return peerExtContEps;
     }
 
     public Endpoints buildEndoints(EndpointInfo epInfo, EndpointLocationInfo epLocInfo,
index 772d0583c33285a653a17b2b1e9ad561b0ba44ce..6200db755446ad6199220280c7379ff60b855af7 100644 (file)
@@ -10,6 +10,14 @@ package org.opendaylight.groupbasedpolicy.renderer;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableCollection;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -17,9 +25,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-
 import javax.annotation.Nullable;
-
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -46,9 +52,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RenderersBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.endpoints.PeerEndpointKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.external.containment.endpoints.PeerExternalContainmentEndpointKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.external.endpoints.PeerExternalEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.RendererBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicy;
@@ -60,6 +63,9 @@ 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.RendererForwarding;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RuleGroups;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalContainmentEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPolicies;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicy;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicy.ExternalImplicitGroup;
@@ -69,15 +75,6 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableCollection;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.ImmutableSet;
-
 public class RendererManager implements AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(RendererManager.class);
@@ -235,7 +232,7 @@ public class RendererManager implements AutoCloseable {
                         && renderer.getRendererPolicy().getVersion().equals(version)) {
                     processingRenderers.remove(configuredRenderer);
                     Status status = rendererPolicy.getStatus();
-                    if (status != null && status.getUnconfiguredRule() != null) {
+                    if (status != null && status.getUnconfiguredEndpoints() != null) {
                         LOG.warn("Renderer {} did not configure policy with version {} successfully. \n{}",
                                 configuredRenderer.getValue(), version, status);
                     } else {
index 444a1c5e5f91c813b36bc1cae8b86b04f55062ff..20990c044060088ece2393f7fbe83aefb37b9199 100755 (executable)
@@ -100,27 +100,6 @@ module renderer {
         }
     }
 
-    grouping has-peer-endpoints {
-        list peer-endpoint {
-            key "context-type context-id address-type address";
-            uses base-endpoint:address-endpoint-key;
-        }
-    }
-
-    grouping has-peer-external-endpoints {
-        list peer-external-endpoint {
-            key "context-type context-id address-type address";
-            uses base-endpoint:address-endpoint-key;
-        }
-    }
-
-    grouping has-peer-external-containment-endpoints {
-        list peer-external-containment-endpoint {
-            key "context-type context-id";
-            uses forwarding:context-key;
-        }
-    }
-
     grouping has-renderer-name {
         leaf renderer-name {
             type renderer-name;
@@ -140,6 +119,22 @@ module renderer {
         }
     }
 
+    grouping has-unconfigured-rule-groups {
+        list unconfigured-rule-group {
+            key "tenant-id contract-id subject-name renderer-endpoint-participation";
+            uses resolved-policy:has-subject-key;
+            leaf renderer-endpoint-participation {
+                type endpoint-policy-participation;
+            }
+            list unconfigured-resolved-rule {
+                key "rule-name";
+                leaf rule-name {
+                    type gbp-common:rule-name;
+                }
+            }
+        }
+    }
+
     container renderers {
         list renderer {
             description
@@ -191,19 +186,22 @@ module renderer {
                             key "context-type context-id address-type address";
                             uses base-endpoint:address-endpoint-key;
 
-                            list peer-endpoint-with-policy {
+                            list peer-endpoint {
+                                description "peer endpoint with-policy - keys";
                                 key "context-type context-id address-type address";
                                 uses base-endpoint:address-endpoint-key;
                                 uses has-rule-group-with-renderer-endpoint-participation;
                             }
 
-                            list peer-external-endpoint-with-policy {
+                            list peer-external-endpoint {
+                                description "peer external endpoint with-policy - keys";
                                 key "context-type context-id address-type address";
                                 uses base-endpoint:address-endpoint-key;
                                 uses has-rule-group-with-renderer-endpoint-participation;
                             }
 
-                            list peer-external-containment-endpoint-with-policy {
+                            list peer-external-containment-endpoint {
+                                description "peer external endpoint with containment and policy - keys";
                                 key "context-type context-id";
                                 uses forwarding:context-key;
                                 uses has-rule-group-with-renderer-endpoint-participation;
@@ -272,24 +270,33 @@ module renderer {
                     description "The renderer exposes status of policy here.";
                     config false;
 
-                    list unconfigured-rule {
-                        key "tenant-id contract-id subject-name renderer-endpoint-participation rule-name";
-                        uses resolved-policy:has-subject-key;
-                        leaf renderer-endpoint-participation {
-                            type endpoint-policy-participation;
-                        }
-                        leaf rule-name {
-                            type gbp-common:rule-name;
-                        }
+                    container unconfigured-endpoints {
+                        list unconfigured-renderer-endpoint {
+                            description "Renderer-endpoint with unconfigured rules.";
+                            key "context-type context-id address-type address";
+                            uses base-endpoint:address-endpoint-key;
+
+                            list unconfigured-peer-endpoint {
+                                key "context-type context-id address-type address";
+                                uses base-endpoint:address-endpoint-key;
+                                uses has-unconfigured-rule-groups;
+                            }
 
-                        container renderer-endpoints-with-peers {
-                            list renderer-endpoint-with-peers {
+                            list unconfigured-peer-external-endpoint {
                                 key "context-type context-id address-type address";
                                 uses base-endpoint:address-endpoint-key;
+                                uses has-unconfigured-rule-groups;
+                            }
+
+                            list unconfigured-peer-external-containment-endpoint {
+                                key "context-type context-id";
+                                uses forwarding:context-key;
+                                uses has-unconfigured-rule-groups;
+                            }
 
-                                uses has-peer-endpoints;
-                                uses has-peer-external-endpoints;
-                                uses has-peer-external-containment-endpoints;
+                            leaf info {
+                                description "More details on reason for configuration failure.";
+                                type string;
                             }
                         }
                     }
index 84973e308ad827d047e7a2d6c026154976100904..801c2bbeb82fc73bc619cc738f5f8d42eaa8ad0b 100644 (file)
@@ -12,9 +12,10 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableTable;
 import java.util.Collections;
 import java.util.Set;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -39,9 +40,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Tenants;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.endpoints.PeerEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPolicies;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPoliciesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRule;
@@ -49,9 +50,6 @@ 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.PolicyRuleGroup;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableTable;
-
 @RunWith(MockitoJUnitRunner.class)
 public class RendererManagerTest {
 
index 29583bf1779af387a3ab6cbdd3d820cfd4aeff17..cc8d7cd69bfdebfe943abb9f45bc6ab3e9e473d8 100644 (file)
@@ -371,7 +371,7 @@ public class NeLocationProvider implements DataTreeChangeListener<NetworkElement
     }
 
     private void processCreatedEN(EndpointNetwork en, InstanceIdentifier<?> nodeIID,
-            InstanceIdentifier<?> connectorIID, WriteTransaction wtx) {
+            String connectorIID, WriteTransaction wtx) {
         for (AddressEndpoint endpoint : endpoints) {
             if (endpoint.getContextType().isAssignableFrom(L3Context.class)
                     && endpoint.getContextId().equals(en.getL3ContextId())
@@ -405,10 +405,10 @@ public class NeLocationProvider implements DataTreeChangeListener<NetworkElement
         }
     }
 
-    private AbsoluteLocation createRealLocation(InstanceIdentifier<?> node, InstanceIdentifier<?> iface) {
+    private AbsoluteLocation createRealLocation(InstanceIdentifier<?> node, String iface) {
         return new AbsoluteLocationBuilder()
             .setLocationType(new ExternalLocationCaseBuilder().setExternalNodeMountPoint(node)
-                    .setExternalNodeConnector(iface.toString()).build()).build();
+                    .setExternalNodeConnector(iface).build()).build();
     }
 
     private <T> List<T> nullToEmpty(@Nullable List<T> list) {
index c0b3a510967ae58c70164580a4cc68db3f5e37b1..b0c071d8035dee032698877f6a2cb45ab2bc1b01 100644 (file)
@@ -45,7 +45,7 @@
                          represented in topology of southbound plugin.
                          This should be more like RelativeSchemaPath
                          from network-element's IID to interface.";
-                     type instance-identifier;
+                     type string;
                  }
                  list endpoint-network {
                      description "Set of networks somewhere behind the interface.
index 08c0053d7cce17d6d4a7623733175f53f51d92fe..4d6e20acba1bf0d2f1e123c7778dd4bc53d29c9c 100644 (file)
@@ -281,13 +281,13 @@ public class NeLocationProviderTest extends CustomDataBrokerTest {
         EndpointNetwork en = createEndpointNetwork(L3_CONTEXT_ID, IPv4_NETWORK_ADDRESS_2);
         InstanceIdentifier<EndpointNetwork> iid = InstanceIdentifier.builder(NetworkElements.class)
             .child(NetworkElement.class, new NetworkElementKey(createNetworkElementIid(NODE_ID_1)))
-            .child(Interface.class, new InterfaceKey(createInterfaceIid(NODE_ID_1, CONNECTOR_ID_1)))
+            .child(Interface.class, new InterfaceKey(CONNECTOR_ID_1))
             .child(EndpointNetwork.class, new EndpointNetworkKey(en.getKey()))
             .build();
         InstanceIdentifier<EndpointNetwork> removeIid =
                 InstanceIdentifier.builder(NetworkElements.class)
                     .child(NetworkElement.class, new NetworkElementKey(createNetworkElementIid(NODE_ID_1)))
-                    .child(Interface.class, new InterfaceKey(createInterfaceIid(NODE_ID_1, CONNECTOR_ID_1)))
+                    .child(Interface.class, new InterfaceKey(CONNECTOR_ID_1))
                     .child(EndpointNetwork.class, new EndpointNetworkKey(
                             new IpPrefix(new Ipv4Prefix(IPv4_NETWORK_ADDRESS_1)),new ContextId(L3_CONTEXT_ID)))
                     .build();
@@ -338,7 +338,7 @@ public class NeLocationProviderTest extends CustomDataBrokerTest {
         writeBaseNetworkElements();
         InstanceIdentifier<Interface> iid = InstanceIdentifier.builder(NetworkElements.class)
             .child(NetworkElement.class, new NetworkElementKey(createNetworkElementIid(NODE_ID_1)))
-            .child(Interface.class, new InterfaceKey(createInterfaceIid(NODE_ID_1, CONNECTOR_ID_1)))
+            .child(Interface.class, new InterfaceKey(CONNECTOR_ID_1))
             .build();
         WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
         wtx.delete(LogicalDatastoreType.CONFIGURATION, iid);
@@ -386,8 +386,7 @@ public class NeLocationProviderTest extends CustomDataBrokerTest {
                                     .setAbsoluteLocation(new AbsoluteLocationBuilder()
                                             .setLocationType(new ExternalLocationCaseBuilder()
                                                     .setExternalNodeMountPoint(createNetworkElementIid(NODE_ID_1))
-                                                    .setExternalNodeConnector(createInterfaceIid(
-                                                            NODE_ID_1, CONNECTOR_ID_1).toString())
+                                                    .setExternalNodeConnector(CONNECTOR_ID_1)
                                                     .build())
                                             .build())
                                     .build()))
@@ -429,8 +428,7 @@ public class NeLocationProviderTest extends CustomDataBrokerTest {
                                     .setAbsoluteLocation(new AbsoluteLocationBuilder()
                                             .setLocationType(new ExternalLocationCaseBuilder()
                                                     .setExternalNodeMountPoint(createNetworkElementIid(NODE_ID_1))
-                                                    .setExternalNodeConnector(createInterfaceIid(
-                                                            NODE_ID_1, CONNECTOR_ID_1).toString())
+                                                    .setExternalNodeConnector(CONNECTOR_ID_1)
                                                     .build())
                                             .build())
                                     .build()))
@@ -474,8 +472,7 @@ public class NeLocationProviderTest extends CustomDataBrokerTest {
                                     .setAbsoluteLocation(new AbsoluteLocationBuilder()
                                             .setLocationType(new ExternalLocationCaseBuilder()
                                                     .setExternalNodeMountPoint(createNetworkElementIid(NODE_ID_1))
-                                                    .setExternalNodeConnector(createInterfaceIid(
-                                                            NODE_ID_1, CONNECTOR_ID_1).toString())
+                                                    .setExternalNodeConnector(CONNECTOR_ID_1)
                                                     .build())
                                             .build())
                                     .build()))
@@ -521,7 +518,7 @@ public class NeLocationProviderTest extends CustomDataBrokerTest {
     }
 
     private Interface createInterface(String node, String iface, String l3c, String prefix) {
-        return new InterfaceBuilder().setIid(createInterfaceIid(node, iface))
+        return new InterfaceBuilder().setIid(iface)
             .setEndpointNetwork(Collections.singletonList(createEndpointNetwork(l3c, prefix)))
             .build();
     }
index c4971c03a305205e5f8126245825b61b91ca467e..43d21d56751bf043670f2b9f2a08f5cf8e78876e 100644 (file)
@@ -118,7 +118,7 @@ public class NeutronSubnetAware implements
         }
         ndb.setNetworkDomainId(new NetworkDomainId(subnet.getUuid().getValue()));
         ndb.setNetworkDomainType(MappingUtils.SUBNET);
-        ndb.setParent(MappingUtils.createParent(new NetworkDomainId(subnet.getUuid().getValue()), L2FloodDomain.class));
+        ndb.setParent(MappingUtils.createParent(new NetworkDomainId(subnet.getNetworkId().getValue()), L2FloodDomain.class));
         ndb.addAugmentation(SubnetAugmentForwarding.class, new SubnetAugmentForwardingBuilder().setSubnet(sb.build())
             .build());
         return ndb.build();
index 03c27ecb0d899dd549ad0a3fcd4b0d2a32d1ad5e..19c684a2f777594d76fabf7a1d171a73183d6e67 100644 (file)
@@ -14,6 +14,7 @@ import java.util.List;
 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.ReadWriteTransaction;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config;\r
@@ -83,8 +84,12 @@ public class NetworkAware implements MappingProvider<Network> {
             LOG.error("Cannot create VPP bridge domain. Network type not specified in neutron network: {}", network);\r
             return null;\r
         }\r
+        Class<? extends NetworkTypeBase> netType = convertNetworkType(providerAug.getNetworkType());\r
+        if (netType == null) {\r
+            return null;\r
+        }\r
         bridgeDomainBuilder.setPhysicalLocationRef(resolveDomainLocations(providerAug));\r
-        bridgeDomainBuilder.setType(convertNetworkType(providerAug.getNetworkType()));\r
+        bridgeDomainBuilder.setType(netType);\r
         if (providerAug.getNetworkType().isAssignableFrom(NetworkTypeVlan.class)\r
                 && providerAug.getSegmentationId() != null) {\r
             try {\r
@@ -134,7 +139,7 @@ public class NetworkAware implements MappingProvider<Network> {
         if (base.isAssignableFrom(NetworkTypeVlan.class)) {\r
             return VlanNetwork.class;\r
         }\r
-        throw new IllegalStateException("Unsupported network type: " + base);\r
+        return null;\r
     }\r
 \r
     InstanceIdentifier<Topology> getTopologyIid(TopologyId topologyId) {\r
@@ -150,10 +155,13 @@ public class NetworkAware implements MappingProvider<Network> {
     @Override\r
     public void processUpdatedNeutronDto(Network originalNetwork, Network updatedNetwork) {\r
         InstanceIdentifier<BridgeDomain> bdId = getBridgeDomainIid(originalNetwork.getUuid().getValue());\r
-        ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();\r
-        rwTx.delete(LogicalDatastoreType.CONFIGURATION, bdId);\r
-        rwTx.put(LogicalDatastoreType.CONFIGURATION, bdId, createBridgeDomain(updatedNetwork));\r
-        DataStoreHelper.submitToDs(rwTx);\r
+        WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();\r
+        wTx.delete(LogicalDatastoreType.CONFIGURATION, bdId);\r
+        BridgeDomain updatedBridgeDomain = createBridgeDomain(updatedNetwork);\r
+        if (updatedBridgeDomain != null) {\r
+            wTx.put(LogicalDatastoreType.CONFIGURATION, bdId, updatedBridgeDomain);\r
+        }\r
+        DataStoreHelper.submitToDs(wTx);\r
     }\r
 \r
     @Override\r
index da4bf774ee18d3ca7ce78d6c5cf963f3ddcec480..43e555265b444a0c07cc045100f98c795ab9e4bb 100755 (executable)
@@ -93,6 +93,7 @@
         <dependency>
             <groupId>org.opendaylight.mdsal.model</groupId>
             <artifactId>ietf-inet-types-2013-07-15</artifactId>
+            <version>1.1.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.powermock</groupId>
index c1c1eca9cf16c897283c6037e0a30ddcfcfa6ab8..4dc9323ba430245e0036c3c7f3e5c77c7b81f885 100644 (file)
@@ -9,8 +9,10 @@
 package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl;
 
 import com.google.common.base.Preconditions;
-import java.util.List;
-
+import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -24,6 +26,7 @@ import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.listener.
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.NodeManager;
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl;
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerZipImpl;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.NetconfTransactionCreator;
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.sf.ChainAction;
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.sf.Classifier;
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.sf.EtherTypeClassifier;
@@ -42,10 +45,9 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
+import java.util.List;
+import java.util.Optional;
+
 /**
  * Purpose: bootstrap provider implementation of Ios-xe renderer
  */
@@ -83,12 +85,12 @@ public class IosXeRendererProviderImpl implements IosXeRendererProvider, Binding
         LOG.info("starting ios-xe renderer");
         //TODO register listeners:
         // node-manager
-        NodeManager nodeManager = new NodeManager(dataBroker, providerContext);
+        final NodeManager nodeManager = new NodeManager(dataBroker, providerContext);
         // network-topology
         iosXeCapableNodeListener = new IosXeCapableNodeListenerImpl(dataBroker, nodeManager);
 
         // policy-manager and delegates
-        PolicyManager policyManager = new PolicyManagerImpl(dataBroker, nodeManager);
+        final PolicyManager policyManager = new PolicyManagerImpl(dataBroker, nodeManager);
         final PolicyManager policyManagerZip = new PolicyManagerZipImpl(policyManager);
 
         // renderer-configuration endpoints
@@ -101,37 +103,42 @@ public class IosXeRendererProviderImpl implements IosXeRendererProvider, Binding
     }
 
     private void writeRendererCapabilities() {
-        WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
-
-        ChainAction action = new ChainAction();
-        List<SupportedActionDefinition> actionDefinitions =
+        final Optional<WriteTransaction> optionalWriteTransaction =
+                NetconfTransactionCreator.netconfWriteOnlyTransaction(dataBroker);
+        if (!optionalWriteTransaction.isPresent()) {
+            LOG.warn("Failed to create transaction, mountpoint: {}", dataBroker);
+            return;
+        }
+        final WriteTransaction writeTransaction = optionalWriteTransaction.get();
+        final ChainAction action = new ChainAction();
+        final List<SupportedActionDefinition> actionDefinitions =
                 ImmutableList.of(new SupportedActionDefinitionBuilder().setActionDefinitionId(action.getId())
-                    .setSupportedParameterValues(action.getSupportedParameterValues())
-                    .build());
-
-        Classifier etherClassifier = new EtherTypeClassifier(null);
-        Classifier ipProtoClassifier = new IpProtoClassifier(etherClassifier.getId());
-        List<SupportedClassifierDefinition> classifierDefinitions = ImmutableList
-            .of(new SupportedClassifierDefinitionBuilder().setClassifierDefinitionId(etherClassifier.getId())
-                .setParentClassifierDefinitionId(etherClassifier.getParent())
-                .setSupportedParameterValues(etherClassifier.getSupportedParameterValues())
-                .build(),
-                new SupportedClassifierDefinitionBuilder().setClassifierDefinitionId(ipProtoClassifier.getId())
-                .setParentClassifierDefinitionId(ipProtoClassifier.getParent())
-                .setSupportedParameterValues(ipProtoClassifier.getSupportedParameterValues())
-                .build());
-
-        Renderer renderer = new RendererBuilder().setName(NodeManager.iosXeRenderer)
-            .setCapabilities(new CapabilitiesBuilder().setSupportedActionDefinition(actionDefinitions)
-                .setSupportedClassifierDefinition(classifierDefinitions)
-                .build())
-            .build();
-
-        InstanceIdentifier<Renderer> iid = InstanceIdentifier.builder(Renderers.class)
-        .child(Renderer.class, new RendererKey(new RendererName(NodeManager.iosXeRenderer)))
-        .build();
+                        .setSupportedParameterValues(action.getSupportedParameterValues())
+                        .build());
+
+        final Classifier etherClassifier = new EtherTypeClassifier(null);
+        final Classifier ipProtoClassifier = new IpProtoClassifier(etherClassifier.getId());
+        final List<SupportedClassifierDefinition> classifierDefinitions = ImmutableList
+                .of(new SupportedClassifierDefinitionBuilder().setClassifierDefinitionId(etherClassifier.getId())
+                                .setParentClassifierDefinitionId(etherClassifier.getParent())
+                                .setSupportedParameterValues(etherClassifier.getSupportedParameterValues())
+                                .build(),
+                        new SupportedClassifierDefinitionBuilder().setClassifierDefinitionId(ipProtoClassifier.getId())
+                                .setParentClassifierDefinitionId(ipProtoClassifier.getParent())
+                                .setSupportedParameterValues(ipProtoClassifier.getSupportedParameterValues())
+                                .build());
+
+        final Renderer renderer = new RendererBuilder().setName(NodeManager.iosXeRenderer)
+                .setCapabilities(new CapabilitiesBuilder().setSupportedActionDefinition(actionDefinitions)
+                        .setSupportedClassifierDefinition(classifierDefinitions)
+                        .build())
+                .build();
+
+        final InstanceIdentifier<Renderer> iid = InstanceIdentifier.builder(Renderers.class)
+                .child(Renderer.class, new RendererKey(new RendererName(NodeManager.iosXeRenderer)))
+                .build();
         writeTransaction.merge(LogicalDatastoreType.OPERATIONAL, iid, renderer, true);
-        CheckedFuture<Void, TransactionCommitFailedException> future = writeTransaction.submit();
+        final CheckedFuture<Void, TransactionCommitFailedException> future = writeTransaction.submit();
         Futures.addCallback(future, new FutureCallback<Void>() {
 
             @Override
index 9916b3446d129f7acaabfeca4e30042fcf2b57a8..26a0963f017a0504875c77daa62e540f0067dd74 100644 (file)
@@ -14,10 +14,11 @@ import com.google.common.util.concurrent.CheckedFuture;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.MountPoint;
 import org.opendaylight.controller.md.sal.binding.api.MountPointService;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.NetconfTransactionCreator;
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.NodeWriter;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName;
@@ -218,10 +219,16 @@ public class NodeManager {
         InstanceIdentifier<Node> nodeIid = InstanceIdentifier.builder(NetworkTopology.class)
                 .child(Topology.class, new TopologyKey(new TopologyId(NodeManager.TOPOLOGY_ID)))
                 .child(Node.class, new NodeKey(nodeId)).build();
-        ReadWriteTransaction rwt = dataBroker.newReadWriteTransaction();
+        java.util.Optional<ReadOnlyTransaction> optionalTransaction =
+                NetconfTransactionCreator.netconfReadOnlyTransaction(dataBroker);
+        if (!optionalTransaction.isPresent()) {
+            LOG.warn("Failed to create transaction, mountpoint: {}", dataBroker);
+            return null;
+        }
+        ReadOnlyTransaction transaction = optionalTransaction.get();
         try {
             CheckedFuture<Optional<Node>, ReadFailedException> submitFuture =
-                    rwt.read(LogicalDatastoreType.CONFIGURATION, nodeIid);
+                    transaction.read(LogicalDatastoreType.CONFIGURATION, nodeIid);
             Optional<Node> optional = submitFuture.checkedGet();
             if (optional != null && optional.isPresent()) {
                 Node node = optional.get();
diff --git a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyConfigurationContext.java b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyConfigurationContext.java
new file mode 100644 (file)
index 0000000..a6c7bc8
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * 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.ios_xe_provider.impl.manager;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Status;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.status.unconfigured.endpoints.UnconfiguredRendererEndpoint;
+
+/**
+ * Purpose: placeholder for
+ * <ul>
+ *     <li>{@link PolicyWriter}</li>
+ *     <li>{@link Status} parts</li>
+ * </ul>
+ */
+public class PolicyConfigurationContext {
+
+    private final List<UnconfiguredRendererEndpoint> unconfiguredRendererEPBag;
+    private PolicyWriter policyWriter;
+    private RendererEndpoint currentRendererEP;
+
+    public PolicyConfigurationContext() {
+        unconfiguredRendererEPBag = new ArrayList<>();
+    }
+
+    /**
+     * @return policyWriter for mountpoint currently being configured
+     */
+    public PolicyWriter getPolicyWriter() {
+        return policyWriter;
+    }
+
+    /**
+     * @param policyWriter for mountpoint currently being configured
+     */
+    public void setPolicyWriter(final PolicyWriter policyWriter) {
+        this.policyWriter = policyWriter;
+    }
+
+    /**
+     * @return list of not configurable policies
+     */
+    public List<UnconfiguredRendererEndpoint> getUnconfiguredRendererEPBag() {
+        return unconfiguredRendererEPBag;
+    }
+
+    /**
+     * append given endpoint to collection of not configurable policies
+     * @param endpoint not configurable endpoint
+     */
+    public void appendUnconfiguredRendererEP(UnconfiguredRendererEndpoint endpoint) {
+        unconfiguredRendererEPBag.add(endpoint);
+    }
+
+    /**
+     * @param currentRendererEP endpoint currently being configured
+     */
+    public void setCurrentRendererEP(final RendererEndpoint currentRendererEP) {
+        this.currentRendererEP = currentRendererEP;
+    }
+
+    /**
+     * @return endpoint currently being configured
+     */
+    public RendererEndpoint getCurrentRendererEP() {
+        return currentRendererEP;
+    }
+}
index b1cd010cf9472cfb937e6759afd3f9debfa9c7ed..6873c6e05d12100603cca3a245fe8719eb7f8680 100644 (file)
@@ -11,23 +11,23 @@ package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager;
 import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Create;
 import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Delete;
 
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-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;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
+
+import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
+
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.manager.PolicyManager;
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.StatusUtil;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.NetconfTransactionCreator;
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriter;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer;
@@ -35,15 +35,24 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicy;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicyBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Status;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.StatusBuilder;
 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.RendererEndpoint;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.status.UnconfiguredEndpointsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+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 PolicyManagerImpl implements PolicyManager {
 
     private static final Logger LOG = LoggerFactory.getLogger(PolicyManagerImpl.class);
@@ -58,60 +67,59 @@ public class PolicyManagerImpl implements PolicyManager {
     }
 
     @Override
-    public ListenableFuture<Boolean> syncPolicy(final Configuration dataAfter, final Configuration dataBefore,
+    @Nonnull
+    public ListenableFuture<Boolean> syncPolicy(@Nullable final Configuration dataAfter, @Nullable final Configuration dataBefore,
                                                 final long version) {
-        final ListenableFuture<Boolean> result;
+        final ListenableFuture<Optional<Status>> result;
         if (dataBefore == null && dataAfter != null) {
             result = syncPolicy(dataAfter, Create);
         } else if (dataBefore != null && dataAfter == null) {
             result = syncPolicy(dataBefore, Delete);
         } else {
-            // TODO implement
-            result = Futures.immediateFuture(false);
+            syncPolicy(dataBefore, Delete);
+            syncPolicy(dataAfter, Create);
+            result = Futures.immediateFuture(Optional.empty());
         }
 
-        reportVersion(version);
-
-        // chain version update (TODO: status)
-        return Futures.transform(result, new AsyncFunction<Boolean, Boolean>() {
+        return Futures.transform(result, new AsyncFunction<Optional<Status>, Boolean>() {
             @Override
-            public ListenableFuture<Boolean> apply(final Boolean input) throws Exception {
-                if (input != null && input) {
-                    return Futures.transform(reportVersion(version), new Function<Void, Boolean>() {
-                        @Nullable
-                        @Override
-                        public Boolean apply(@Nullable final Void input) {
-                            return Boolean.TRUE;
-                        }
-                    });
-                } else {
-                    return Futures.immediateFuture(input);
-                }
+            public ListenableFuture<Boolean> apply(@Nullable final Optional<Status> statusValue) throws Exception {
+                Preconditions.checkArgument(statusValue != null, "provided status must not be null");
+                return Futures.transform(reportPolicy(version, statusValue), new Function<Void, Boolean>() {
+                    @Override
+                    public Boolean apply(@Nullable final Void input) {
+                        return Boolean.TRUE;
+                    }
+                });
             }
         });
     }
 
-    private ListenableFuture<Boolean> syncPolicy(final Configuration dataAfter, DsAction action) {
+    private ListenableFuture<Optional<Status>> syncPolicy(final Configuration dataAfter, DsAction action) {
         if (dataAfter.getRendererEndpoints() == null
                 || dataAfter.getRendererEndpoints().getRendererEndpoint() == null) {
             LOG.debug("no configuration obtained - skipping");
-            return Futures.immediateFuture(true);
+            return Futures.immediateFuture(Optional.empty());
         }
+
+        final PolicyConfigurationContext context = new PolicyConfigurationContext();
         final Map<DataBroker, PolicyWriter> policyWriterPerDeviceCache = new HashMap<>();
         for (RendererEndpoint rendererEndpoint : dataAfter.getRendererEndpoints().getRendererEndpoint()) {
+            // store the endpoint currently being configured
+            context.setCurrentRendererEP(rendererEndpoint);
+
             if (dataAfter.getEndpoints() == null || dataAfter.getEndpoints().getAddressEndpointWithLocation() == null) {
-                LOG.debug("renderer-endpoint: missing address-endpoint-with-location");
-                //TODO: dump all resolvedRule-rule-peerEP-EP combinantions to status
+                final String info = "renderer-endpoint: missing address-endpoint-with-location";
+                context.appendUnconfiguredRendererEP(StatusUtil.assembleFullyNotConfigurableRendererEP(context, info));
                 continue;
             }
-
             final List<AddressEndpointWithLocation> endpointsWithLocation = dataAfter.getEndpoints()
                     .getAddressEndpointWithLocation();
             final InstanceIdentifier mountpointIid = PolicyManagerUtil.getAbsoluteLocationMountpoint(rendererEndpoint, endpointsWithLocation);
             final DataBroker mountpoint = nodeManager.getNodeMountPoint(mountpointIid);
             if (mountpoint == null) {
-                LOG.debug("no data-broker for mount-point [{}] available", mountpointIid);
-                //TODO: dump all resolvedRule-rule-peerEP-EP combinantions to status
+                final String info = String.format("no data-broker for mount-point [%s] available", mountpointIid);
+                context.appendUnconfiguredRendererEP(StatusUtil.assembleFullyNotConfigurableRendererEP(context, info));
                 continue;
             }
 
@@ -123,61 +131,81 @@ public class PolicyManagerImpl implements PolicyManager {
                 final NodeId nodeId = nodeManager.getNodeIdByMountpointIid(mountpointIid);
                 final String managementIpAddress = nodeManager.getNodeManagementIpByMountPointIid(mountpointIid);
                 if (interfaceName == null || managementIpAddress == null) {
-                    LOG.debug("can not create policyWriter: interface={}, managementIpAddress={}",
+                    final String info = String.format("can not create policyWriter: interface=%s, managementIpAddress=%s",
                             interfaceName, managementIpAddress);
-                    //TODO: dump all resolvedRule-rule-peerEP-EP combinantions to status
+                    context.appendUnconfiguredRendererEP(StatusUtil.assembleFullyNotConfigurableRendererEP(context, info));
                     continue;
                 }
                 policyWriter = new PolicyWriter(mountpoint, interfaceName, managementIpAddress, policyMapName, nodeId);
                 policyWriterPerDeviceCache.put(mountpoint, policyWriter);
             }
 
+            // assign policyWriter for current mount-point
+            context.setPolicyWriter(policyWriter);
+
             final Sgt sourceSgt = PolicyManagerUtil.findSgtTag(rendererEndpoint, dataAfter.getEndpoints()
                     .getAddressEndpointWithLocation());
             // Peer Endpoint
-            for (PeerEndpointWithPolicy peerEndpoint : rendererEndpoint.getPeerEndpointWithPolicy()) {
+            for (PeerEndpoint peerEndpoint : rendererEndpoint.getPeerEndpoint()) {
                 final Sgt destinationSgt = PolicyManagerUtil.findSgtTag(peerEndpoint, dataAfter.getEndpoints()
                         .getAddressEndpointWithLocation());
                 if (sourceSgt == null || destinationSgt == null) {
-                    LOG.debug("endpoint-policy: missing sgt value(sourceSgt={}, destinationSgt={})",
+                    final String info = String.format("endpoint-policy: missing sgt value(sourceSgt=%s, destinationSgt=%s)",
                             sourceSgt, destinationSgt);
-                    //TODO: dump particular resolvedRule-rule-peerEP-EP combinantions to status
+                    context.appendUnconfiguredRendererEP(
+                            StatusUtil.assembleNotConfigurableRendererEPForPeer(context, peerEndpoint, info));
                     continue;
                 }
-                PolicyManagerUtil.syncPolicyEntities(sourceSgt, destinationSgt, policyWriter, dataAfter, peerEndpoint);
+                PolicyManagerUtil.syncPolicyEntities(sourceSgt, destinationSgt, context, dataAfter, peerEndpoint,
+                        dataBroker, action);
             }
         }
 
-        //TODO: return real (cumulated) future
-        final List<CheckedFuture<Void, TransactionCommitFailedException>> allFutureResults = new ArrayList<>();
+        final List<CheckedFuture<Boolean, TransactionCommitFailedException>> allFutureResults = new ArrayList<>();
         if (action.equals(Create)) {
-            policyWriterPerDeviceCache.values().forEach(pw -> allFutureResults.add(pw.commitToDatastore()));
+            policyWriterPerDeviceCache.values().forEach((pw) -> allFutureResults.add(pw.commitToDatastore()));
         } else if (action.equals(Delete)) {
-            policyWriterPerDeviceCache.values().forEach(pw -> allFutureResults.add(pw.removeFromDatastore()));
+            policyWriterPerDeviceCache.values().forEach((pw) -> allFutureResults.add(pw.removeFromDatastore()));
         } else {
             LOG.info("unsupported policy manage action: {}", action);
-
         }
+        final ListenableFuture<List<Boolean>> cumulativeResult = Futures.allAsList(allFutureResults);
 
-        final ListenableFuture<List<Void>> cumulativeResult = Futures.allAsList(allFutureResults);
-
-        return Futures.transform(cumulativeResult, new Function<List<Void>, Boolean>() {
+        return Futures.transform(cumulativeResult, new Function<List<Boolean>, Optional<Status>>() {
             @Nullable
             @Override
-            public Boolean apply(@Nullable final List<Void> input) {
+            public Optional<Status> apply(@Nullable final List<Boolean> input) {
+                //TODO: inspect if all booleans are true
+
                 LOG.trace("considering all submits as successful - otherwise there will be exception");
-                return Boolean.TRUE;
+                final Status status = new StatusBuilder()
+                        .setUnconfiguredEndpoints(new UnconfiguredEndpointsBuilder()
+                                .setUnconfiguredRendererEndpoint(context.getUnconfiguredRendererEPBag())
+                                .build())
+                        .build();
+
+                return Optional.of(status);
             }
         });
     }
 
-    private CheckedFuture<Void, TransactionCommitFailedException> reportVersion(long version) {
-        WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
-        InstanceIdentifier<RendererPolicy> iid = InstanceIdentifier.create(Renderers.class)
+    private CheckedFuture<Void, TransactionCommitFailedException> reportPolicy(long version, @Nonnull final Optional<Status> statusValue) {
+        final Optional<ReadWriteTransaction> optionalReadWriteTransaction =
+                NetconfTransactionCreator.netconfReadWriteTransaction(dataBroker);
+        if (!optionalReadWriteTransaction.isPresent()) {
+            LOG.warn("Failed to create transaction, mountpoint: {}", dataBroker);
+            return Futures.immediateCheckedFuture(null);
+        }
+        final ReadWriteTransaction readWriteTransaction = optionalReadWriteTransaction.get();
+        final InstanceIdentifier<RendererPolicy> iid = InstanceIdentifier.create(Renderers.class)
                 .child(Renderer.class, new RendererKey(NodeManager.iosXeRenderer))
                 .child(RendererPolicy.class);
-        wtx.merge(LogicalDatastoreType.OPERATIONAL, iid, new RendererPolicyBuilder().setVersion(version).build());
-        return wtx.submit();
+        final RendererPolicy rendererPolicy = new RendererPolicyBuilder()
+                .setVersion(version)
+                .setStatus(statusValue.orElse(null))
+                .build();
+        readWriteTransaction.merge(LogicalDatastoreType.OPERATIONAL, iid, rendererPolicy);
+        return readWriteTransaction.submit();
     }
 
     @Override
@@ -185,7 +213,7 @@ public class PolicyManagerImpl implements PolicyManager {
         //NOOP
     }
 
-    enum DsAction {Create, Delete}
+    public enum DsAction {Create, Delete}
 
     public enum ActionCase {ALLOW, CHAIN}
 }
index 55ed2993c0aa5635c6d956c11968bda75531e3c1..520784b41e74a481cb599358480bb45ccb9baeea 100644 (file)
@@ -9,18 +9,19 @@
 package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util;
 
 import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.ActionCase.CHAIN;
-import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction.In;
-import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction.Out;
-import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation.CONSUMER;
-import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation.PROVIDER;
+import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Create;
+import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Delete;
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyConfigurationContext;
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriter;
 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308.ClassNameType;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308.PolicyActionType;
@@ -49,7 +50,6 @@ import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.ClassKe
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.ActionList;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.ActionListBuilder;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.ActionListKey;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.AppnavPolicyBuilder;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.ForwardCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.ForwardBuilder;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.forward.ServicePath;
@@ -63,16 +63,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
 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.RendererEndpoint;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpoint;
 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.resolved.policy.rev150828.has.actions.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.Classifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRule;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.AddressEndpointWithLocationAug;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
@@ -83,24 +80,29 @@ import org.slf4j.LoggerFactory;
 public class PolicyManagerUtil {
 
     private static final Logger LOG = LoggerFactory.getLogger(PolicyManagerUtil.class);
+    private static final String DEFAULT = "class-default";
 
-    public static void syncPolicyEntities(final Sgt sourceSgt, final Sgt destinationSgt, PolicyWriter policyWriter,
-                                          final Configuration dataAfter, final PeerEndpointWithPolicy peerEndpoint) {
-        // Class map
-        final String classMapName = PolicyManagerUtil.generateClassMapName(sourceSgt.getValue(), destinationSgt.getValue());
-        final Match match = PolicyManagerUtil.createSecurityGroupMatch(sourceSgt.getValue(), destinationSgt.getValue());
-        final ClassMap classMap = PolicyManagerUtil.createClassMap(classMapName, match);
+    public static void syncPolicyEntities(final Sgt sourceSgt, final Sgt destinationSgt, final PolicyConfigurationContext context,
+                                          final Configuration dataAfter, final PeerEndpoint peerEndpoint,
+                                          final DataBroker dataBroker, final PolicyManagerImpl.DsAction action) {
+        // Action
         final Map<PolicyManagerImpl.ActionCase, Action> actionMap = PolicyManagerUtil.getActionInDirection(dataAfter, peerEndpoint);
         if (actionMap == null || actionMap.isEmpty()) {
             LOG.debug("no usable action found for EP-sgt[{}] | peerEP-sgt[{}]",
                     sourceSgt, destinationSgt);
             return;
         }
-        policyWriter.cache(classMap);
 
-        // Policy map entry
-        if (actionMap.containsKey(PolicyManagerImpl.ActionCase.CHAIN)) {
-            ServiceChainingUtil.resolveChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, classMapName, policyWriter);
+        // TODO allow action not supported
+
+        // Resolve chain action - create
+        if (actionMap.containsKey(PolicyManagerImpl.ActionCase.CHAIN) && action.equals(Create)) {
+            ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, context,
+                    dataBroker);
+        }
+        if (actionMap.containsKey(PolicyManagerImpl.ActionCase.CHAIN) && action.equals(Delete)) {
+            ServiceChainingUtil.removeChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap,
+                    context.getPolicyWriter());
         }
     }
 
@@ -119,7 +121,7 @@ public class PolicyManagerUtil {
         return augmentation.getSgt();
     }
 
-    private static Match createSecurityGroupMatch(final int sourceTag, final int destinationTag) {
+    static Match createSecurityGroupMatch(final int sourceTag, final int destinationTag) {
         final SecurityGroupBuilder sgBuilder = new SecurityGroupBuilder();
         final Source source = new SourceBuilder().setTag(sourceTag).build();
         final Destination destination = new DestinationBuilder().setTag(destinationTag).build();
@@ -140,7 +142,7 @@ public class PolicyManagerUtil {
         return cmBuilder.build();
     }
 
-    static TenantId getTenantId(final PeerEndpointWithPolicy peer) {
+    static TenantId getTenantId(final PeerEndpoint peer) {
         for (RuleGroupWithRendererEndpointParticipation ruleGroup :
                 peer.getRuleGroupWithRendererEndpointParticipation()) {
             if (ruleGroup.getTenantId() != null) {
@@ -187,12 +189,10 @@ public class PolicyManagerUtil {
 
     public static PolicyMap createPolicyMap(final String policyMapName, final List<Class> policyMapEntries) {
         // Create default class entry
-        final AppnavPolicyBuilder appnavPolicyBuilder = new AppnavPolicyBuilder();
-        appnavPolicyBuilder.setPassThrough(true);
         final ClassBuilder defaultBuilder = new ClassBuilder();
-        defaultBuilder.setName(new ClassNameType("class-default"))
-                .setKey(new ClassKey(new ClassNameType("class-default")))
-                .setAppnavPolicy(appnavPolicyBuilder.build());
+        defaultBuilder.setName(new ClassNameType(DEFAULT))
+                .setKey(new ClassKey(new ClassNameType(DEFAULT)));
+        // TODO add pass-through value
         policyMapEntries.add(defaultBuilder.build());
         // Construct policy map
         final PolicyMapBuilder policyMapBuilder = new PolicyMapBuilder();
@@ -255,12 +255,11 @@ public class PolicyManagerUtil {
     }
 
 
-    private static Map<PolicyManagerImpl.ActionCase, Action> getActionInDirection(final Configuration data, final PeerEndpointWithPolicy peer) {
-        final List<ResolvedRule> rulesInDirection = new ArrayList<>();
+    private static Map<PolicyManagerImpl.ActionCase, Action> getActionInDirection(final Configuration data, final PeerEndpoint peer) {
+        final Set<ResolvedRule> rulesInDirection = new HashSet<>();
         // Find all rules in desired direction
         for (RuleGroupWithRendererEndpointParticipation ruleGroupKey :
                 peer.getRuleGroupWithRendererEndpointParticipation()) {
-            final EndpointPolicyParticipation participation = ruleGroupKey.getRendererEndpointParticipation();
             final RuleGroup ruleGroup = findRuleGroup(data, ruleGroupKey);
             if (ruleGroup == null || ruleGroup.getResolvedRule() == null) {
                 continue;
@@ -273,13 +272,7 @@ public class PolicyManagerUtil {
                 if (resolvedRule.getClassifier() == null || resolvedRule.getAction() == null) {
                     continue;
                 }
-                // TODO only first Classifier used
-                final Classifier classifier = resolvedRule.getClassifier().get(0);
-                final HasDirection.Direction direction = classifier.getDirection();
-                if ((participation.equals(PROVIDER) && direction.equals(Out)) ||
-                        (participation.equals(CONSUMER) && direction.equals(In))) {
-                    rulesInDirection.add(resolvedRule);
-                }
+                rulesInDirection.add(resolvedRule);
             }
         }
         if (rulesInDirection.isEmpty()) {
@@ -320,5 +313,4 @@ public class PolicyManagerUtil {
         }
         return null;
     }
-
 }
index e029ae136f0aa25b3170b98925f533e8525a73d2..757c2e9338bdc088d0bab96d0ef1704b151a72f4 100644 (file)
@@ -9,24 +9,27 @@
 package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util;
 
 import com.google.common.base.Optional;
-import com.google.common.collect.Iterables;
 import com.google.common.util.concurrent.CheckedFuture;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
 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.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyConfigurationContext;
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.NetconfTransactionCreator;
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriter;
 import org.opendaylight.sfc.provider.api.SfcProviderRenderedPathAPI;
 import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI;
 import org.opendaylight.sfc.provider.api.SfcProviderServicePathAPI;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.rsp.manager.rev160421.RendererPathStates;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.rsp.manager.rev160421.renderer.path.states.RendererPathState;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.rsp.manager.rev160421.renderer.path.states.RendererPathStateKey;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.rsp.manager.rev160421.renderer.path.states.renderer.path.state.ConfiguredRenderedPaths;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.rsp.manager.rev160421.renderer.path.states.renderer.path.state.configured.rendered.paths.ConfiguredRenderedPath;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.rsp.manager.rev160421.renderer.path.states.renderer.path.state.configured.rendered.paths.ConfiguredRenderedPathKey;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.RendererName;
 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.RspName;
 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfcName;
 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SffName;
@@ -40,8 +43,10 @@ import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev1407
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308.Native;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChainBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._class.map.Match;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.config.service.chain.grouping.IpBuilder;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePath;
@@ -60,16 +65,27 @@ import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.serv
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.services.service.type.choice.ServiceFunctionForwarderBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.actions.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.security.cert.PKIXRevocationChecker;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
 public class ServiceChainingUtil {
 
     private static final Logger LOG = LoggerFactory.getLogger(ServiceChainingUtil.class);
+    private static final String RSP_SUFFIX = "-gbp-rsp";
+    private static final String RSP_REVERSED_SUFFIX = "-gbp-rsp-Reverse";
 
     static ServiceFunctionPath getServicePath(final List<ParameterValue> params) {
         if (params == null || params.isEmpty()) {
@@ -104,57 +120,111 @@ public class ServiceChainingUtil {
         return serviceFunctionPath;
     }
 
-    static void resolveChainAction(final PeerEndpointWithPolicy peerEndpoint, final Sgt sourceSgt,
-                                   final Sgt destinationSgt, final Map<PolicyManagerImpl.ActionCase, Action> actionMap,
-                                   final String classMapName, PolicyWriter policyWriter) {
-        final List<Class> entries = new ArrayList<>();
+    static void resolveNewChainAction(final PeerEndpoint peerEndpoint, final Sgt sourceSgt,
+                                      final Sgt destinationSgt, final Map<PolicyManagerImpl.ActionCase, Action> actionMap,
+                                      final PolicyConfigurationContext context, final DataBroker dataBroker) {
+        final List<Class> policyMapEntries = new ArrayList<>();
         final Action action = actionMap.get(PolicyManagerImpl.ActionCase.CHAIN);
         final ServiceFunctionPath servicePath = ServiceChainingUtil.getServicePath(action.getParameterValue());
-        if (servicePath == null) {
-            //TODO: dump particular resolvedRule-rule-peerEP-EP combinantions to status
+        if (servicePath == null || servicePath.getName() == null) {
+            final String info = String.format("service-path not found (sourceSgt=%s, destinationSgt=%s)",
+                    sourceSgt, destinationSgt);
+            context.appendUnconfiguredRendererEP(StatusUtil.assembleNotConfigurableRendererEPForPeer(context, peerEndpoint, info));
             return;
         }
         final TenantId tenantId = PolicyManagerUtil.getTenantId(peerEndpoint);
         if (tenantId == null) {
-            //TODO: dump particular resolvedRule-rule-peerEP-EP combinantions to status
+            final String info = String.format("tenant-id not found (sourceSgt=%s, destinationSgt=%s)",
+                    sourceSgt, destinationSgt);
+            context.appendUnconfiguredRendererEP(StatusUtil.assembleNotConfigurableRendererEPForPeer(context, peerEndpoint, info));
             return;
         }
-        final RenderedServicePath renderedPath = ServiceChainingUtil.createRenderedPath(servicePath, tenantId);
+        final RenderedServicePath directPath = ServiceChainingUtil.createRenderedPath(servicePath, tenantId, dataBroker);
+        // Rsp found, create class-map and policy-map entry
+        final String classMapName = PolicyManagerUtil.generateClassMapName(sourceSgt.getValue(), destinationSgt.getValue());
+        final Match match = PolicyManagerUtil.createSecurityGroupMatch(sourceSgt.getValue(), destinationSgt.getValue());
+        final ClassMap classMap = PolicyManagerUtil.createClassMap(classMapName, match);
+        policyMapEntries.add(PolicyManagerUtil.createPolicyEntry(classMapName, directPath, PolicyManagerImpl.ActionCase.CHAIN));
+        RenderedServicePath reversedPath = null;
+        if (servicePath.isSymmetric()) {
+            // symmetric path is in opposite direction. Roles of renderer and peer endpoint will invert
+            reversedPath = ServiceChainingUtil.createSymmetricRenderedPath(servicePath, directPath, tenantId, dataBroker);
+            // Reversed Rsp found, create class-map and policy-map entry in opposite direction
+            final String oppositeClassMapName = PolicyManagerUtil.generateClassMapName(destinationSgt.getValue(), sourceSgt.getValue());
+            final Match oppositeMatch = PolicyManagerUtil.createSecurityGroupMatch(destinationSgt.getValue(), sourceSgt.getValue());
+            final ClassMap oppositeClassMap = PolicyManagerUtil.createClassMap(oppositeClassMapName, oppositeMatch);
+            policyMapEntries.add(PolicyManagerUtil.createPolicyEntry(oppositeClassMapName, reversedPath, PolicyManagerImpl.ActionCase.CHAIN));
+            context.getPolicyWriter().cache(oppositeClassMap);
+        }
         // Create appropriate service path && remote forwarder
-        final boolean sfcPartSucessful = setSfcPart(renderedPath, policyWriter);
-        if (!sfcPartSucessful) {
-            //TODO: dump particular resolvedRule-rule-peerEP-EP combinantions to status
+        final boolean sfcPartSuccessful = setSfcPart(servicePath, directPath, reversedPath, context.getPolicyWriter());
+        if (!sfcPartSuccessful) {
+            //TODO: extract resolved-rule name
+            final String info = String.format("failed during sfc-part execution (sourceSgt=%s, destinationSgt=%s)",
+                    sourceSgt, destinationSgt);
+            //context.appendUnconfiguredRendererEP(StatusUtil.assembleNotConfigurableRendererEPForPeerAndAction(context, peerEndpoint, info));
             return;
         }
+        context.getPolicyWriter().cache(classMap);
+        context.getPolicyWriter().cache(policyMapEntries);
+    }
 
-        // atomic creation of symmetric policy-entries
-        final Class policyEntry = PolicyManagerUtil.createPolicyEntry(classMapName, renderedPath, PolicyManagerImpl.ActionCase.CHAIN);
-        if (!servicePath.isSymmetric()) {
-            entries.add(policyEntry);
-        } else {
-            // symmetric path is in opposite direction. Roles of renderer and peer endpoint will invert
-            final RenderedServicePath symmetricPath = ServiceChainingUtil
-                    .createSymmetricRenderedPath(servicePath, renderedPath, tenantId);
-            if (symmetricPath == null) {
-                //TODO: dump particular resolvedRule-rule-peerEP-EP combinantions to status
-                return;
-            } else {
-                final String oppositeClassMapName = PolicyManagerUtil.generateClassMapName(destinationSgt.getValue(),
-                        sourceSgt.getValue());
-                final Class policyEntrySymmetric = PolicyManagerUtil.createPolicyEntry(oppositeClassMapName,
-                        symmetricPath, PolicyManagerImpl.ActionCase.CHAIN);
+    static void removeChainAction(final PeerEndpoint peerEndpoint, final Sgt sourceSgt, final Sgt destinationSgt,
+                                  final Map<PolicyManagerImpl.ActionCase, Action> actionMap, PolicyWriter policyWriter) {
+        final Action action = actionMap.get(PolicyManagerImpl.ActionCase.CHAIN);
+        final ServiceFunctionPath servicePath = ServiceChainingUtil.getServicePath(action.getParameterValue());
+        if (servicePath == null || servicePath.getName() == null) {
+            return;
+        }
+        final TenantId tenantId = PolicyManagerUtil.getTenantId(peerEndpoint);
+        if (tenantId == null) {
+            return;
+        }
+        // Cache class-maps, appropriate policy-map entries and service-chains
+        final List<Class> policyMapEntries = new ArrayList<>();
+        final String classMapName = PolicyManagerUtil.generateClassMapName(sourceSgt.getValue(), destinationSgt.getValue());
+        final ClassMap classMap = PolicyManagerUtil.createClassMap(classMapName, null);
+        final RspName rspName = generateRspName(servicePath, tenantId);
+        final ServiceChain serviceChain = findServiceChainToRsp(rspName);
+        policyMapEntries.add(PolicyManagerUtil.createPolicyEntry(classMapName, null, PolicyManagerImpl.ActionCase.CHAIN));
+        policyWriter.cache(classMap);
+        policyWriter.cache(serviceChain);
+        if (servicePath.isSymmetric()) {
+            final String oppositeClassMapName = PolicyManagerUtil.generateClassMapName(destinationSgt.getValue(), sourceSgt.getValue());
+            final ClassMap oppositeClassMap = PolicyManagerUtil.createClassMap(oppositeClassMapName, null);
+            final RspName reversedRspName = generateReversedRspName(servicePath, tenantId);
+            final ServiceChain reversedServiceChain = findServiceChainToRsp(reversedRspName);
+            policyMapEntries.add(PolicyManagerUtil.createPolicyEntry(oppositeClassMapName, null, PolicyManagerImpl.ActionCase.CHAIN));
+            policyWriter.cache(oppositeClassMap);
+            policyWriter.cache(reversedServiceChain);
+        }
+        policyWriter.cache(policyMapEntries);
+        // TODO remove other sfc stuff - forwarders, etc.
+    }
 
-                entries.add(policyEntry);
-                entries.add(policyEntrySymmetric);
-            }
+    private static ServiceChain findServiceChainToRsp(final RspName rspName) {
+        // Do not actually remove rsp from DS, could be used by someone else
+        final RenderedServicePath renderedServicePath = SfcProviderRenderedPathAPI.readRenderedServicePath(rspName);
+        if (renderedServicePath == null) {
+            LOG.debug("Rendered service path not found, if there is service-path created according to that rsp, " +
+                    "it cannot be removed. Rendered path name: {} ", rspName.getValue());
+            return null;
         }
-        policyWriter.cache(entries);
+        // Construct service chain with key
+        final Long pathId = renderedServicePath.getPathId();
+        final ServicePathBuilder servicePathBuilder = new ServicePathBuilder();
+        final ServiceChainBuilder serviceChainBuilder = new ServiceChainBuilder();
+        servicePathBuilder.setServicePathId(pathId)
+                .setKey(new ServicePathKey(pathId));
+        serviceChainBuilder.setServicePath(Collections.singletonList(servicePathBuilder.build()));
+        return serviceChainBuilder.build();
     }
 
-    static RenderedServicePath createRenderedPath(final ServiceFunctionPath sfp, final TenantId tenantId) {
+    static RenderedServicePath createRenderedPath(final ServiceFunctionPath sfp, final TenantId tenantId,
+                                                  final DataBroker dataBroker) {
         RenderedServicePath renderedServicePath;
         // Try to read existing RSP
-        final RspName rspName = new RspName(sfp.getName().getValue() + tenantId.getValue() + "-gbp-rsp");
+        final RspName rspName = generateRspName(sfp, tenantId);
         renderedServicePath = SfcProviderRenderedPathAPI.readRenderedServicePath(rspName);
         if (renderedServicePath != null) {
             return renderedServicePath;
@@ -167,21 +237,23 @@ public class ServiceChainingUtil {
                 .build();
         renderedServicePath = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, input);
         LOG.info("Rendered service path {} created", rspName.getValue());
+        checkSfcRspStatus(rspName, dataBroker);
         return renderedServicePath;
     }
 
     static RenderedServicePath createSymmetricRenderedPath(final ServiceFunctionPath sfp, final RenderedServicePath rsp,
-                                                           final TenantId tenantId) {
+                                                           final TenantId tenantId, final DataBroker dataBroker) {
         RenderedServicePath reversedRenderedPath;
         // Try to read existing RSP
-        final RspName rspName = new RspName(sfp.getName().getValue() + tenantId.getValue() + "-gbp-rsp-Reverse");
+        final RspName rspName = generateReversedRspName(sfp, tenantId);
         reversedRenderedPath = SfcProviderRenderedPathAPI.readRenderedServicePath(rspName);
         if (reversedRenderedPath != null) {
             return reversedRenderedPath;
         }
         LOG.info("Reversed rendered service path with name {} not found, creating a new one ..", rspName.getValue());
-        reversedRenderedPath = SfcProviderRenderedPathAPI.createSymmetricRenderedServicePathAndState(rsp);
+        reversedRenderedPath = SfcProviderRenderedPathAPI.createReverseRenderedServicePathEntry(rsp);
         LOG.info("Rendered service path {} created", rspName.getValue());
+        checkSfcRspStatus(rspName, dataBroker);
         return reversedRenderedPath;
     }
 
@@ -191,16 +263,24 @@ public class ServiceChainingUtil {
      * @param mountpoint used to access specific device
      * @return true if Local Forwarder is present, false otherwise
      */
-    static boolean checkLocalForwarderPresence(DataBroker mountpoint) {
+    private static boolean checkLocalForwarderPresence(DataBroker mountpoint) {
         InstanceIdentifier<Local> localSffIid = InstanceIdentifier.builder(Native.class)
                 .child(ServiceChain.class)
                 .child(org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServiceFunctionForwarder.class)
                 .child(Local.class).build();
-        ReadWriteTransaction rwt = mountpoint.newReadWriteTransaction();
-        CheckedFuture<Optional<Local>, ReadFailedException> submitFuture = rwt.read(LogicalDatastoreType.CONFIGURATION,
-                localSffIid);
         try {
+            java.util.Optional<ReadOnlyTransaction> optionalTransaction =
+                    NetconfTransactionCreator.netconfReadOnlyTransaction(mountpoint);
+            if (!optionalTransaction.isPresent()) {
+                LOG.warn("Failed to create transaction, mountpoint: {}", mountpoint);
+                return false;
+            }
+            ReadOnlyTransaction transaction = optionalTransaction.get();
+            CheckedFuture<Optional<Local>, ReadFailedException> submitFuture =
+                    transaction.read(LogicalDatastoreType.CONFIGURATION,
+                    localSffIid);
             Optional<Local> optionalLocalSff = submitFuture.checkedGet();
+            transaction.close(); // Release lock
             return optionalLocalSff.isPresent();
         } catch (ReadFailedException e) {
             LOG.warn("Read transaction failed to {} ", e);
@@ -219,8 +299,14 @@ public class ServiceChainingUtil {
     public static boolean checkServicePathPresence(DataBroker mountpoint) {
         InstanceIdentifier<ServiceChain> serviceChainIid = InstanceIdentifier.builder(Native.class)
                 .child(ServiceChain.class).build();
-        ReadWriteTransaction rwt = mountpoint.newReadWriteTransaction();
-        CheckedFuture<Optional<ServiceChain>, ReadFailedException> submitFuture = rwt.read(LogicalDatastoreType.CONFIGURATION,
+        java.util.Optional<ReadOnlyTransaction> optionalTransaction =
+                NetconfTransactionCreator.netconfReadOnlyTransaction(mountpoint);
+        if (!optionalTransaction.isPresent()) {
+            LOG.warn("Failed to create transaction, mountpoint: {}", mountpoint);
+            return false;
+        }
+        ReadOnlyTransaction transaction = optionalTransaction.get();
+        CheckedFuture<Optional<ServiceChain>, ReadFailedException> submitFuture = transaction.read(LogicalDatastoreType.CONFIGURATION,
                 serviceChainIid);
         try {
             Optional<ServiceChain> optionalServiceChain = submitFuture.checkedGet();
@@ -248,6 +334,14 @@ public class ServiceChainingUtil {
         return null;
     }
 
+    private static RspName generateRspName(final ServiceFunctionPath serviceFunctionPath, final TenantId tenantId) {
+        return new RspName(serviceFunctionPath.getName().getValue() + tenantId.getValue() + RSP_SUFFIX);
+    }
+
+    private static RspName generateReversedRspName(final ServiceFunctionPath serviceFunctionPath, final TenantId tenantId) {
+        return new RspName(serviceFunctionPath.getName().getValue() + tenantId.getValue() + RSP_REVERSED_SUFFIX);
+    }
+
     private static <T> Supplier<Boolean> createNegativePathWithLogSupplier(final T value, final Consumer<T> logCommand) {
         return () -> {
             // fireLog
@@ -256,42 +350,73 @@ public class ServiceChainingUtil {
         };
     }
 
-    static boolean setSfcPart(final RenderedServicePath renderedServicePath, PolicyWriter policyWriter) {
+    static boolean setSfcPart(final ServiceFunctionPath serviceFunctionPath, final RenderedServicePath renderedServicePath,
+                              final RenderedServicePath reversedRenderedServicePath, PolicyWriter policyWriter) {
+        if (!checkLocalForwarderPresence(policyWriter.getCurrentMountpoint())) {
+            appendLocalSff(policyWriter);
+        } else {
+            LOG.info("Local forwarder for node {} is already created", policyWriter.getCurrentNodeId());
+        }
+        boolean outcome = true;
+        // Direct path
         final java.util.Optional<RenderedServicePath> renderedServicePathSafe = java.util.Optional.ofNullable(renderedServicePath);
-        final java.util.Optional<RenderedServicePathHop> renderedServicePathHop = renderedServicePathSafe
-                .map(RenderedServicePath::getRenderedServicePathHop)
-                .map(rspHop -> Iterables.getFirst(rspHop, null));
-
-        final boolean outcome;
-        if (!renderedServicePathHop.isPresent()) {
-            LOG.warn("Rendered service path {} does not contain any hop",
-                    renderedServicePathSafe.map(RenderedServicePath::getName).map(RspName::getValue).orElse("n/a"));
+        if (renderedServicePathSafe.isPresent()) {
+            if (renderedServicePath.getRenderedServicePathHop() != null
+                    && !renderedServicePath.getRenderedServicePathHop().isEmpty()) {
+                if (!resolveRenderedServicePath(renderedServicePath, policyWriter)) {
+                    outcome = false;
+                }
+            }
+            else {
+                LOG.warn("Rendered service path {} does not contain any hop",
+                        renderedServicePathSafe.map(RenderedServicePath::getName).map(RspName::getValue).orElse("n/a"));
+                outcome = false;
+            }
+        }
+        else {
+            LOG.warn("Rendered service path is null");
             outcome = false;
-        } else {
-            final RenderedServicePathHop firstHop = renderedServicePathHop.get();
-            final SffName sffName = firstHop.getServiceFunctionForwarder();
-
-            // Forwarders
-            //
-            // If classifier node is also forwarder, first entry in service path has to point to first service function
-            // (Local case)
-            //
-            // If first hop Sff is on different node, first service path entry has to point to that specific service
-            // forwarder (Remote case)
-
-            // Local case (only when does not exist)
-
-            if (!checkLocalForwarderPresence(policyWriter.getCurrentMountpoint())) {
-                appendLocalSff(policyWriter);
+        }
+        if (serviceFunctionPath.isSymmetric()) {
+            // Reversed path
+            final java.util.Optional<RenderedServicePath> reversedRenderedServicePathSafe = java.util.Optional.ofNullable(reversedRenderedServicePath);
+            if (reversedRenderedServicePathSafe.isPresent()) {
+                if (reversedRenderedServicePath.getRenderedServicePathHop() != null
+                        && !reversedRenderedServicePath.getRenderedServicePathHop().isEmpty()) {
+                    if (!resolveRenderedServicePath(reversedRenderedServicePath, policyWriter)) {
+                        outcome = false;
+                    }
+                } else {
+                    LOG.warn("Rendered service path {} does not contain any hop",
+                            reversedRenderedServicePathSafe.map(RenderedServicePath::getName).map(RspName::getValue).orElse("n/a"));
+                    outcome = false;
+                }
             } else {
-                LOG.info("Local forwarder for node {} is already created", policyWriter.getCurrentNodeId());
+                LOG.warn("Reversed rendered service path is null");
+                outcome = false;
             }
+        }
+        return outcome;
+    }
 
-            // Remote case
-            final java.util.Optional<ServiceFunctionForwarder> serviceFunctionForwarder = java.util.Optional.ofNullable(
-                    SfcProviderServiceForwarderAPI.readServiceFunctionForwarder(sffName));
+    private static boolean resolveRenderedServicePath(final RenderedServicePath renderedServicePath, PolicyWriter policyWriter) {
+        final RenderedServicePathHop firstHop = renderedServicePath.getRenderedServicePathHop().get(0);
+        if (firstHop == null) {
+            return false;
+        }
+        final SffName sffName = firstHop.getServiceFunctionForwarder();
 
-            outcome = serviceFunctionForwarder.map(sff -> java.util.Optional.ofNullable(sff.getIpMgmtAddress())
+        // Forwarders
+        //
+        // If classifier node is also forwarder, first entry in service path has to point to first service function
+        // (Local case)
+        //
+        // If first hop Sff is on different node, first service path entry has to point to that specific service
+        // forwarder (Remote case)
+
+        final java.util.Optional<ServiceFunctionForwarder> serviceFunctionForwarder = java.util.Optional.ofNullable(
+                    SfcProviderServiceForwarderAPI.readServiceFunctionForwarder(sffName));
+        return serviceFunctionForwarder.map(sff -> java.util.Optional.ofNullable(sff.getIpMgmtAddress())
                     .map(IpAddress::getIpv4Address)
                     .map((ipv4Address) -> ipv4Address.getValue())
                     .map(addressValue -> {
@@ -310,10 +435,10 @@ public class ServiceChainingUtil {
 
                         // Service chain
                         final List<Services> services = new ArrayList<>();
-                        //TODO: servicesBuilder is never used
                         final ServicesBuilder servicesBuilder = new ServicesBuilder();
                         servicesBuilder.setServiceIndexId(renderedServicePath.getStartingIndex())
                                 .setServiceTypeChoice(serviceTypeChoice);
+                        services.add(servicesBuilder.build());
                         final List<ServicePath> servicePaths = new ArrayList<>();
                         final ServicePathBuilder servicePathBuilder = new ServicePathBuilder();
                         servicePathBuilder.setKey(new ServicePathKey(renderedServicePath.getPathId()))
@@ -335,9 +460,6 @@ public class ServiceChainingUtil {
             ).orElseGet(createNegativePathWithLogSupplier(sffName.getValue(),
                     (value) -> LOG.error("Sff with name {} does not exist", value))
             );
-        }
-
-        return outcome;
     }
 
     private static void appendLocalSff(final PolicyWriter policyWriter) {
@@ -359,4 +481,60 @@ public class ServiceChainingUtil {
         return sfBuilder.build();
     }
 
+    private static void checkSfcRspStatus(final RspName rspName, final DataBroker dataBroker) {
+        /** TODO A better way to do this is to register listener and wait for notification than using hardcoded timeout
+         *  with Thread.sleep(). Example in class BridgeDomainManagerImpl
+        */
+        ConfiguredRenderedPath renderedPath = null;
+        LOG.info("Waiting for SFC to configure path {} ...", rspName.getValue());
+
+        byte attempt = 0;
+        do {
+            attempt++;
+            // Wait
+            try {
+                Thread.sleep(5000L);
+            } catch (InterruptedException e) {
+                LOG.error("Thread interrupted while waiting ... {} ", e);
+            }
+            // Read actual status
+            final InstanceIdentifier<ConfiguredRenderedPath> statusIid = InstanceIdentifier.builder(RendererPathStates.class)
+                    .child(RendererPathState.class, new RendererPathStateKey(new RendererName("ios-xe-renderer")))
+                    .child(ConfiguredRenderedPaths.class)
+                    .child(ConfiguredRenderedPath.class, new ConfiguredRenderedPathKey(rspName)).build();
+            final java.util.Optional<ReadWriteTransaction> optionalTransaction =
+                    NetconfTransactionCreator.netconfReadWriteTransaction(dataBroker);
+            if (!optionalTransaction.isPresent()) {
+                LOG.warn("Failed to create transaction, mountpoint: {}", dataBroker);
+                return;
+            }
+            ReadWriteTransaction transaction = optionalTransaction.get();
+            try {
+                final CheckedFuture<Optional<ConfiguredRenderedPath>, ReadFailedException> submitFuture =
+                        transaction.read(LogicalDatastoreType.OPERATIONAL, statusIid);
+                final Optional<ConfiguredRenderedPath> optionalPath = submitFuture.checkedGet();
+                if (optionalPath.isPresent()) {
+                    renderedPath = optionalPath.get();
+                }
+            } catch (ReadFailedException e) {
+                LOG.warn("Failed while read rendered path status ... {} ", e.getMessage());
+            }
+            if (renderedPath == null || renderedPath.getPathStatus() == null ||
+                    renderedPath.getPathStatus().equals(ConfiguredRenderedPath.PathStatus.InProgress)) {
+                LOG.info("Still waiting for SFC ... ");
+            } else if (renderedPath.getPathStatus().equals(ConfiguredRenderedPath.PathStatus.Failure)) {
+                LOG.warn("SFC failed to configure rsp");
+            } else if (renderedPath.getPathStatus().equals(ConfiguredRenderedPath.PathStatus.Success)) {
+                LOG.info("RSP {} configured by SFC", rspName.getValue());
+                try {
+                    Thread.sleep(5000); // Just for sure, maybe will be safe to remove this
+                } catch (InterruptedException e) {
+                    LOG.error("Thread interrupted while waiting ... {} ", e);
+                }
+                return;
+            }
+        }
+        while (attempt <= 6);
+        LOG.warn("Maximum number of attempts reached");
+    }
 }
diff --git a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/StatusUtil.java b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/StatusUtil.java
new file mode 100644 (file)
index 0000000..8f8cb20
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * 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.ios_xe_provider.impl.util;
+
+import com.google.common.annotations.VisibleForTesting;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyConfigurationContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.unconfigured.rule.groups.UnconfiguredRuleGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.unconfigured.rule.groups.UnconfiguredRuleGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Status;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.status.unconfigured.endpoints.UnconfiguredRendererEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.status.unconfigured.endpoints.UnconfiguredRendererEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.status.unconfigured.endpoints.unconfigured.renderer.endpoint.UnconfiguredPeerEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.status.unconfigured.endpoints.unconfigured.renderer.endpoint.UnconfiguredPeerEndpointBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Purpose: assembly methods for {@link Status}.
+ */
+public class StatusUtil {
+
+    private static final Logger LOG = LoggerFactory.getLogger(StatusUtil.class);
+
+    private StatusUtil() {
+        throw new IllegalAccessError("instance of util class not supported");
+    }
+
+    /**
+     * @param context holder of actual configuration state
+     * @param info    detailed message for not configurable item
+     * @return ful collection of not configurable items under given endpoint
+     */
+    public static UnconfiguredRendererEndpoint assembleFullyNotConfigurableRendererEP(final PolicyConfigurationContext context,
+                                                                                      final String info) {
+        final RendererEndpoint rendererEndpoint = context.getCurrentRendererEP();
+        LOG.trace("fully not configurable EP: {}", info);
+        return new UnconfiguredRendererEndpointBuilder(rendererEndpoint)
+                .setUnconfiguredPeerEndpoint(assemblePeerEndpoint(rendererEndpoint.getPeerEndpoint().stream()))
+                .setInfo(info)
+                .build();
+    }
+
+    /**
+     * @param context holder of actual configuration state
+     * @param info    detailed message for not configurable item
+     * @return filtered collection of not configurable items under given endpoint and peer
+     */
+    public static UnconfiguredRendererEndpoint assembleNotConfigurableRendererEPForPeer(final PolicyConfigurationContext context,
+                                                                                        final PeerEndpoint peerEndpoint,
+                                                                                        final String info) {
+        final RendererEndpoint rendererEndpoint = context.getCurrentRendererEP();
+        LOG.trace("not configurable EP for peer: {}", info);
+        return new UnconfiguredRendererEndpointBuilder(rendererEndpoint)
+                .setUnconfiguredPeerEndpoint(assemblePeerEndpoint(Stream.of(peerEndpoint)))
+                .setInfo(info)
+                .build();
+    }
+
+    @VisibleForTesting
+    static List<UnconfiguredPeerEndpoint> assemblePeerEndpoint(final Stream<PeerEndpoint> peerEndpoint) {
+        return peerEndpoint
+                .map((peerEP) -> new UnconfiguredPeerEndpointBuilder(peerEP)
+                        .setUnconfiguredRuleGroup(
+                                assembleRuleGroups(peerEP.getRuleGroupWithRendererEndpointParticipation().stream())
+                        ).build())
+                .collect(Collectors.toList());
+    }
+
+    @VisibleForTesting
+    static List<UnconfiguredRuleGroup> assembleRuleGroups(final Stream<RuleGroupWithRendererEndpointParticipation> stream) {
+        return stream
+                .filter(Objects::nonNull)
+                .map((ruleGroup) -> new UnconfiguredRuleGroupBuilder(ruleGroup)
+                        .setRendererEndpointParticipation(ruleGroup.getRendererEndpointParticipation())
+                        // TODO: find rule-group and append names of resolved rules ...setUnconfiguredResolvedRule()
+                        .build())
+                .collect(Collectors.toList());
+    }
+}
diff --git a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/NetconfTransactionCreator.java b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/NetconfTransactionCreator.java
new file mode 100644 (file)
index 0000000..7b7b8b2
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * 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.ios_xe_provider.impl.writer;
+
+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.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.netconf.api.NetconfDocumentedException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Optional;
+
+/**
+ * Purpose: safely create transaction
+ */
+
+public class NetconfTransactionCreator {
+
+    private final static Logger LOG = LoggerFactory.getLogger(NetconfTransactionCreator.class);
+    private static final long TIMEOUT = 5000L;
+
+    public static Optional<ReadOnlyTransaction> netconfReadOnlyTransaction(DataBroker mountpoint) {
+        int attempt = 0;
+        do {
+            try {
+                return Optional.ofNullable(mountpoint.newReadOnlyTransaction());
+            } catch (RuntimeException e) {
+                final Optional<Throwable> optionalCause = Optional.ofNullable(e.getCause());
+                final Optional<Class> optionalCauseClass = optionalCause.map(Throwable::getClass);
+                if (optionalCauseClass.isPresent() && optionalCauseClass.get().equals(NetconfDocumentedException.class)) {
+                    attempt++;
+                    LOG.warn("NetconfDocumentedException thrown, retrying ({})...", attempt);
+                    try {
+                        Thread.sleep(TIMEOUT);
+                    } catch (InterruptedException i) {
+                        LOG.error("Thread interrupted while waiting ... {} ", i);
+                    }
+                } else {
+                    LOG.error("Runtime exception ... {}", e.getMessage(), e);
+                    return Optional.empty();
+                }
+            }
+        } while (attempt <= 5);
+        LOG.error("Maximum number of attempts reached");
+        return Optional.empty();
+    }
+
+    public static Optional<WriteTransaction> netconfWriteOnlyTransaction(DataBroker mountpoint) {
+        int attempt = 0;
+        do {
+            try {
+                return Optional.of(mountpoint.newWriteOnlyTransaction());
+            } catch (RuntimeException e) {
+                final Optional<Throwable> optionalCause = Optional.ofNullable(e.getCause());
+                final Optional<Class> optionalCauseClass = optionalCause.map(Throwable::getClass);
+                if (optionalCauseClass.isPresent() && optionalCauseClass.get().equals(NetconfDocumentedException.class)) {
+                    attempt++;
+                    LOG.warn("NetconfDocumentedException thrown, retrying ({})...", attempt);
+                    try {
+                        Thread.sleep(TIMEOUT);
+                    } catch (InterruptedException i) {
+                        LOG.error("Thread interrupted while waiting ... {} ", i);
+                    }
+                } else {
+                    LOG.error("Runtime exception ... {}", e.getMessage());
+                    return Optional.empty();
+                }
+            }
+        } while (attempt <= 5);
+        LOG.error("Maximum number of attempts reached");
+        return Optional.empty();
+    }
+
+    public static Optional<ReadWriteTransaction> netconfReadWriteTransaction(DataBroker mountpoint) {
+        int attempt = 0;
+        do {
+            try {
+                return Optional.of(mountpoint.newReadWriteTransaction());
+            } catch (RuntimeException e) {
+                final Optional<Throwable> optionalCause = Optional.ofNullable(e.getCause());
+                final Optional<Class> optionalCauseClass = optionalCause.map(Throwable::getClass);
+                if (optionalCauseClass.isPresent() && optionalCauseClass.get().equals(NetconfDocumentedException.class)) {
+                    attempt++;
+                    LOG.warn("NetconfDocumentedException thrown, retrying ({})...", attempt);
+                    try {
+                        Thread.sleep(TIMEOUT);
+                    } catch (InterruptedException i) {
+                        LOG.error("Thread interrupted while waiting ... {} ", i);
+                    }
+                } else {
+                    LOG.error("Runtime exception ... {}", e.getMessage());
+                    return Optional.empty();
+                }
+            }
+        } while (attempt <= 5);
+        LOG.error("Maximum number of attempts reached");
+        return Optional.empty();
+    }
+}
index c7443d99d7ee6f5c0847be5c63115f70137cf05c..bf4cd266c0fdd2ffda9bf3ee42993437a1734603 100644 (file)
@@ -28,11 +28,12 @@ import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 
 public class NodeWriter {
 
     private static final Logger LOG = LoggerFactory.getLogger(NodeWriter.class);
-    private List<RendererNode> rendererNodesCache;
+    private final List<RendererNode> rendererNodesCache;
 
     public NodeWriter() {
         rendererNodesCache = new ArrayList<>();
@@ -49,11 +50,17 @@ public class NodeWriter {
      */
     public void commitToDatastore(DataBroker dataBroker) {
         RendererNodes rendererNodes = buildRendererNodes();
-        WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
-        InstanceIdentifier<RendererNodes> iid = buildRendererNodesIid();
+        final Optional<WriteTransaction> optionalWriteTransaction =
+                NetconfTransactionCreator.netconfWriteOnlyTransaction(dataBroker);
+        if (!optionalWriteTransaction.isPresent()) {
+            LOG.warn("Failed to create transaction, mountpoint: {}", dataBroker);
+            return;
+        }
+        final WriteTransaction writeTransaction = optionalWriteTransaction.get();
+        final InstanceIdentifier<RendererNodes> iid = buildRendererNodesIid();
         try {
-            wtx.merge(LogicalDatastoreType.OPERATIONAL, iid, rendererNodes, true);
-            CheckedFuture<Void, TransactionCommitFailedException> submitFuture = wtx.submit();
+            writeTransaction.merge(LogicalDatastoreType.OPERATIONAL, iid, rendererNodes, true);
+            CheckedFuture<Void, TransactionCommitFailedException> submitFuture = writeTransaction.submit();
             submitFuture.checkedGet();
             // Clear cache
             rendererNodesCache.clear();
@@ -70,12 +77,18 @@ public class NodeWriter {
      * @param dataBroker appropriate data provider
      */
     public void removeFromDatastore(DataBroker dataBroker) {
-        WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
+        final Optional<WriteTransaction> optionalWriteTransaction =
+                NetconfTransactionCreator.netconfWriteOnlyTransaction(dataBroker);
+        if (!optionalWriteTransaction.isPresent()) {
+            LOG.warn("Failed to create transaction, mountpoint: {}", dataBroker);
+            return;
+        }
+        final WriteTransaction writeTransaction = optionalWriteTransaction.get();
         for (RendererNode nodeToRemove : rendererNodesCache) {
             InstanceIdentifier<RendererNode> iid = buildRendererNodeIid(nodeToRemove);
             try {
-                wtx.delete(LogicalDatastoreType.OPERATIONAL, iid);
-                CheckedFuture<Void, TransactionCommitFailedException> submitFuture = wtx.submit();
+                writeTransaction.delete(LogicalDatastoreType.OPERATIONAL, iid);
+                CheckedFuture<Void, TransactionCommitFailedException> submitFuture = writeTransaction.submit();
                 submitFuture.checkedGet();
                 // Clear cache
             } catch (TransactionCommitFailedException e) {
index 4f387bb94334c6718c12f0873378bec9b453f28f..67948290eca79871c2c127bb51cf3094cf307709 100644 (file)
@@ -10,33 +10,15 @@ package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer;
 
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.ServiceChainingUtil;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308.Native;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.ServicePolicy;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChain.Direction;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapKey;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.Interface;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMap;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMapKey;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._interface.GigabitEthernet;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._interface.GigabitEthernetKey;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServiceFunctionForwarder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePath;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePathKey;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.Local;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfName;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfNameKey;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -93,141 +75,37 @@ public class PolicyWriter {
         serviceChains.add(serviceChain);
     }
 
-    public CheckedFuture<Void, TransactionCommitFailedException> commitToDatastore() {
-        WriteTransaction wtx = mountpoint.newWriteOnlyTransaction();
-        // GBP
-        // Class maps
-        for (ClassMap entry : classMapEntries) {
-            InstanceIdentifier<ClassMap> classMapIid = classMapInstanceIdentifier(entry);
-            wtx.merge(LogicalDatastoreType.CONFIGURATION, classMapIid, entry);
-            LOG.info("Created class-map {} on node {}", entry.getName(), nodeId.getValue());
-        }
-
-        // Policy map
-        PolicyMap policyMap = PolicyManagerUtil.createPolicyMap(policyMapName, policyMapEntries);
-        InstanceIdentifier<PolicyMap> policyMapIid = policyMapInstanceIdentifier();
-        wtx.merge(LogicalDatastoreType.CONFIGURATION, policyMapIid, policyMap);
-        LOG.info("Created policy-map {} on node {}", policyMap.getName(), nodeId.getValue());
-
-        // Interface
-        ServicePolicy servicePolicy = PolicyManagerUtil.createServicePolicy(policyMapName, Direction.Input);
-        InstanceIdentifier<ServicePolicy> servicePolicyIid = interfaceInstanceIdentifier(interfaceName);
-        wtx.merge(LogicalDatastoreType.CONFIGURATION, servicePolicyIid, servicePolicy);
-        LOG.info("Service-policy interface {}, bound to policy-map {} created on  node {}",
-                interfaceName, policyMap.getName(), nodeId.getValue());
-
-        //SFC
-        // Local forwarder (if some service chain exists, otherwise is useless)
-        if (!serviceChains.isEmpty()) {
-            InstanceIdentifier<Local> localIid = localSffInstanceIdentifier();
-            wtx.merge(LogicalDatastoreType.CONFIGURATION, localIid, localForwarder);
-            LOG.info("Local forwarder created on node {}", nodeId.getValue());
-        }
-
-        // Remote forwarders
-        for (ServiceFfName forwarder : remoteForwarders) {
-            InstanceIdentifier<ServiceFfName> forwarderIid = remoteSffInstanceIdentifier(forwarder);
-            wtx.merge(LogicalDatastoreType.CONFIGURATION, forwarderIid, forwarder);
-            LOG.info("Remote forwarder {} created on node {}", forwarder.getName(), nodeId.getValue());
-        }
-
-        // Service paths
-        for (ServiceChain serviceChain : serviceChains) {
-            for (ServicePath entry : serviceChain.getServicePath()) {
-                InstanceIdentifier<ServicePath> servicePathIid = servicePathInstanceIdentifier(entry.getKey());
-                wtx.merge(LogicalDatastoreType.CONFIGURATION, servicePathIid, entry);
-                LOG.info("Service path with Id {} created on node {}", entry.getServicePathId(), nodeId.getValue());
-            }
-        }
-
-        return wtx.submit();
-    }
-
-    public CheckedFuture<Void, TransactionCommitFailedException> removeFromDatastore() {
-        ReadWriteTransaction wtx = mountpoint.newReadWriteTransaction();
-        //GBP
-        // Interface
-        InstanceIdentifier<ServicePolicy> servicePolicyIid = interfaceInstanceIdentifier(interfaceName);
-        wtx.delete(LogicalDatastoreType.CONFIGURATION, servicePolicyIid);
-        LOG.info("Service-policy removed from interface {} on node {}", interfaceName, nodeId.getValue());
-
-        // Policy map
-        InstanceIdentifier<PolicyMap> policyMapIid = policyMapInstanceIdentifier();
-        wtx.delete(LogicalDatastoreType.CONFIGURATION, policyMapIid);
-        LOG.info("Policy-map removed from node node {}", nodeId.getValue());
-
-        // Class map
-        for (ClassMap entry : classMapEntries) {
-            InstanceIdentifier<ClassMap> classMapIid = classMapInstanceIdentifier(entry);
-            wtx.delete(LogicalDatastoreType.CONFIGURATION, classMapIid);
-            LOG.info("Class-map {} removed from node {}", entry.getName(), nodeId.getValue());
-        }
-
-        //SFC
-        // Service paths
-        for (ServiceChain serviceChain : serviceChains) {
-            for (ServicePath entry : serviceChain.getServicePath()) {
-                InstanceIdentifier<ServicePath> servicePathIid = servicePathInstanceIdentifier(entry.getKey());
-                wtx.delete(LogicalDatastoreType.CONFIGURATION, servicePathIid);
-                LOG.info("Service path with Id {} removed from node {}", entry.getServicePathId(), nodeId.getValue());
-            }
-        }
-
-        // Remote forwarders
-        for (ServiceFfName forwarder : remoteForwarders) {
-            InstanceIdentifier<ServiceFfName> forwarderIid = remoteSffInstanceIdentifier(forwarder);
-            wtx.delete(LogicalDatastoreType.CONFIGURATION, forwarderIid);
-            LOG.info("Remote forwarder {} removed from node {}", forwarder.getName(), nodeId.getValue());
-        }
-
-        // Local forwarder - remove only if there is no more service-paths on device. If paths removed above were last
-        // ones, remove local forwarder. If there are still some paths present, they were created by sfc and local
-        // forwarder cannot be removed (because it was created by sfc as well)
-        if (ServiceChainingUtil.checkServicePathPresence(mountpoint)) {
-            InstanceIdentifier<Local> localIid = localSffInstanceIdentifier();
-            wtx.delete(LogicalDatastoreType.CONFIGURATION, localIid);
-            LOG.info("Local forwarder removed from node {}", nodeId.getValue());
-        }
-
-        return wtx.submit();
-    }
-
-    private InstanceIdentifier<ClassMap> classMapInstanceIdentifier(ClassMap classMap) {
-        return InstanceIdentifier.builder(Native.class)
-                .child(ClassMap.class, new ClassMapKey(classMap.getName())).build();
-    }
-
-    private InstanceIdentifier<PolicyMap> policyMapInstanceIdentifier() {
-        return InstanceIdentifier.builder(Native.class)
-                .child(PolicyMap.class, new PolicyMapKey(policyMapName)).build();
-    }
-
-    private InstanceIdentifier<ServicePolicy> interfaceInstanceIdentifier(String ethernetName) {
-        return InstanceIdentifier.builder(Native.class)
-                .child(Interface.class)
-                .child(GigabitEthernet.class, new GigabitEthernetKey(ethernetName))
-                .child(ServicePolicy.class)
-                .build();
-    }
-
-    private InstanceIdentifier<Local> localSffInstanceIdentifier() {
-        return InstanceIdentifier.builder(Native.class)
-                .child(ServiceChain.class)
-                .child(ServiceFunctionForwarder.class)
-                .child(Local.class).build();
-    }
-
-    private InstanceIdentifier<ServiceFfName> remoteSffInstanceIdentifier(ServiceFfName sffName) {
-        return InstanceIdentifier.builder(Native.class)
-                .child(ServiceChain.class)
-                .child(org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServiceFunctionForwarder.class)
-                .child(ServiceFfName.class, new ServiceFfNameKey(sffName.getName())).build();
-    }
-
-    private InstanceIdentifier<ServicePath> servicePathInstanceIdentifier(ServicePathKey key) {
-        return InstanceIdentifier.builder(Native.class)
-                .child(ServiceChain.class)
-                .child(ServicePath.class, key).build();
+    public CheckedFuture<Boolean, TransactionCommitFailedException> commitToDatastore() {
+        LOG.info("Configuring policy on node {} ... ", nodeId.getValue());
+        // SFC
+        boolean localResult = PolicyWriterUtil.writeLocal(localForwarder, nodeId, mountpoint);
+        boolean remoteResult = PolicyWriterUtil.writeRemote(remoteForwarders, nodeId, mountpoint);
+        boolean servicePathsResult = PolicyWriterUtil.writeServicePaths(serviceChains, nodeId, mountpoint);
+        // GBP - maintain order!
+        boolean classMapResult = PolicyWriterUtil.writeClassMaps(classMapEntries, nodeId, mountpoint);
+        boolean policyMapResult = PolicyWriterUtil.writePolicyMap(policyMapName, policyMapEntries, nodeId, mountpoint);
+        boolean interfaceResult = PolicyWriterUtil.writeInterface(policyMapName, interfaceName, nodeId, mountpoint);
+        // Result
+        LOG.info("Policy configuration on node {} completed", nodeId.getValue());
+        return Futures.immediateCheckedFuture(classMapResult && policyMapResult && interfaceResult && localResult
+                && remoteResult && servicePathsResult);
+    }
+
+    public CheckedFuture<Boolean, TransactionCommitFailedException> removeFromDatastore() {
+        LOG.info("Removing policy from node {} ... ", nodeId.getValue());
+        // GBP - maintain order!
+        boolean policyMapEntriesResult = PolicyWriterUtil.removePolicyMapEntries(policyMapName, policyMapEntries,
+                nodeId, mountpoint);
+        boolean classMapResult = PolicyWriterUtil.removeClassMaps(classMapEntries, nodeId, mountpoint);
+        // TODO remove class map?
+        // SFC
+        boolean servicePathsResult = PolicyWriterUtil.removeServicePaths(serviceChains, nodeId, mountpoint);
+        boolean localResult = PolicyWriterUtil.removeLocal(nodeId, mountpoint);
+        // TODO remove remote forwarders
+        // Result
+        LOG.info("Policy removed from node {}", nodeId.getValue());
+        return Futures.immediateCheckedFuture(classMapResult && policyMapEntriesResult && servicePathsResult
+                && localResult);
     }
 
     public String getManagementIpAddress() {
diff --git a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/PolicyWriterUtil.java b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/PolicyWriterUtil.java
new file mode 100644 (file)
index 0000000..45e3bb8
--- /dev/null
@@ -0,0 +1,406 @@
+/*
+ * 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.ios_xe_provider.impl.writer;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+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.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.ServiceChainingUtil;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308.ClassNameType;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308.Native;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.ServicePolicy;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChain.Direction;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.Interface;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMap;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMapKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._interface.GigabitEthernet;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._interface.GigabitEthernetKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.ClassKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServiceFunctionForwarder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePath;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePathKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.Local;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfName;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfNameKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+/**
+ * Purpose: Util class for every policy writer
+ */
+class PolicyWriterUtil {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PolicyWriterUtil.class);
+
+    static boolean writeClassMaps(final List<ClassMap> classMapEntries, final NodeId nodeId, final DataBroker mountpoint) {
+        if (classMapEntries == null || classMapEntries.isEmpty()) {
+            return true;
+        }
+        for (ClassMap entry : classMapEntries) {
+            final java.util.Optional<WriteTransaction> optionalWriteTransaction =
+                    NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint);
+            if (!optionalWriteTransaction.isPresent()) {
+                LOG.warn("Failed to create write-only transaction, mountpoint: {}", mountpoint);
+                return false;
+            }
+            final WriteTransaction writeTransaction = optionalWriteTransaction.get();
+            final InstanceIdentifier<ClassMap> classMapIid = classMapInstanceIdentifier(entry);
+            writeMergeTransaction(writeTransaction, classMapIid, entry);
+            // Check
+            final java.util.Optional<ReadOnlyTransaction> optionalTransaction =
+                    NetconfTransactionCreator.netconfReadOnlyTransaction(mountpoint);
+            if (!optionalTransaction.isPresent()) {
+                LOG.warn("Failed to create read-only transaction, mountpoint: {}", mountpoint);
+                return false;
+            }
+            final ReadOnlyTransaction readTransaction = optionalTransaction.get();
+            if (checkWritten(readTransaction, classMapIid) == null) {
+                return false;
+            }
+            LOG.info("Created class-map {} on node {}", entry.getName(), nodeId.getValue());
+        }
+        return true;
+    }
+
+    static boolean removeClassMaps(final List<ClassMap> classMapEntries, final NodeId nodeId, final DataBroker mountpoint) {
+        boolean result = true;
+        if (classMapEntries == null || classMapEntries.isEmpty()) {
+            return true;
+        }
+        for (ClassMap entry : classMapEntries) {
+            final java.util.Optional<WriteTransaction> optionalWriteTransaction =
+                    NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint);
+            if (!optionalWriteTransaction.isPresent()) {
+                LOG.warn("Failed to create write-only transaction, mountpoint: {}", mountpoint);
+                return false;
+            }
+            final WriteTransaction writeTransaction = optionalWriteTransaction.get();
+            final InstanceIdentifier<ClassMap> classMapIid = classMapInstanceIdentifier(entry);
+            deleteTransaction(writeTransaction, classMapIid);
+            // Check
+            final java.util.Optional<ReadOnlyTransaction> optionalReadTransaction =
+                    NetconfTransactionCreator.netconfReadOnlyTransaction(mountpoint);
+            if (!optionalReadTransaction.isPresent()) {
+                LOG.warn("Failed to create read-only transaction, mountpoint: {}", mountpoint);
+                return false;
+            }
+            final ReadOnlyTransaction readTransaction = optionalReadTransaction.get();
+            result = checkRemoved(readTransaction, classMapIid);
+            LOG.info("Class-map {} removed from node {}", entry.getName(), nodeId.getValue());
+        }
+        return result;
+    }
+
+    static boolean writePolicyMap(final String policyMapName, final List<Class> policyMapEntries, NodeId nodeId,
+                                  final DataBroker mountpoint) {
+        final java.util.Optional<WriteTransaction> optionalWriteTransaction =
+                NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint);
+        if (!optionalWriteTransaction.isPresent()) {
+            LOG.warn("Failed to create write-only transaction, mountpoint: {}", mountpoint);
+            return false;
+        }
+        final WriteTransaction writeTransaction = optionalWriteTransaction.get();
+        final PolicyMap policyMap = PolicyManagerUtil.createPolicyMap(policyMapName, policyMapEntries);
+        final InstanceIdentifier<PolicyMap> policyMapIid = policyMapInstanceIdentifier(policyMapName);
+        writeMergeTransaction(writeTransaction, policyMapIid, policyMap);
+        // Check
+        final java.util.Optional<ReadOnlyTransaction> optionalReadTransaction =
+                NetconfTransactionCreator.netconfReadOnlyTransaction(mountpoint);
+        if (!optionalReadTransaction.isPresent()) {
+            LOG.warn("Failed to create read-only transaction, mountpoint: {}", mountpoint);
+            return false;
+        }
+        final ReadOnlyTransaction readTransaction = optionalReadTransaction.get();
+        if (checkWritten(readTransaction, policyMapIid) == null) {
+            return false;
+        }
+        LOG.info("Created policy-map {} on node {}", policyMap.getName(), nodeId.getValue());
+        return true;
+    }
+
+    static boolean removePolicyMapEntries(final String policyMapName, final List<Class> policyMapEntries,
+                                          final NodeId nodeId, final DataBroker mountpoint) {
+        if (policyMapEntries == null || policyMapEntries.isEmpty()) {
+            return true;
+        }
+        for (Class entry : policyMapEntries) {
+            final java.util.Optional<WriteTransaction> optionalWriteTransaction =
+                    NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint);
+            if (!optionalWriteTransaction.isPresent()) {
+                LOG.warn("Failed to create write-only transaction, mountpoint: {}", mountpoint);
+                return false;
+            }
+            final WriteTransaction writeTransaction = optionalWriteTransaction.get();
+            final InstanceIdentifier policyMapEntryIid = policyMapEntryInstanceIdentifier(policyMapName, entry.getName());
+            if (deleteTransaction(writeTransaction, policyMapEntryIid)) {
+                LOG.info("Policy map entry {} removed from node {}", entry.getName(), nodeId.getValue());
+            }
+        }
+        return true;
+    }
+
+    static boolean writeInterface(final String policyMapName, final String interfaceName, final NodeId nodeId,
+                                  final DataBroker mountpoint) {
+        final java.util.Optional<WriteTransaction> optionalWriteTransaction =
+                NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint);
+        if (!optionalWriteTransaction.isPresent()) {
+            LOG.warn("Failed to create write-only transaction, mountpoint: {}", mountpoint);
+            return false;
+        }
+        final WriteTransaction writeTransaction = optionalWriteTransaction.get();
+        final ServicePolicy servicePolicy = PolicyManagerUtil.createServicePolicy(policyMapName, Direction.Input);
+        final InstanceIdentifier<ServicePolicy> servicePolicyIid = interfaceInstanceIdentifier(interfaceName);
+        writeMergeTransaction(writeTransaction, servicePolicyIid, servicePolicy);
+        LOG.info("Service-policy interface {}, bound to policy-map {} created on  node {}",
+                interfaceName, policyMapName, nodeId.getValue());
+        return true;
+    }
+
+    static boolean writeLocal(final Local localForwarder, final NodeId nodeId, final DataBroker mountpoint) {
+        if (localForwarder == null) {
+            return true;
+        }
+        final java.util.Optional<WriteTransaction> optionalWriteTransaction =
+                NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint);
+        if (!optionalWriteTransaction.isPresent()) {
+            LOG.warn("Failed to create write-only transaction, mountpoint: {}", mountpoint);
+            return false;
+        }
+        final WriteTransaction writeTransaction = optionalWriteTransaction.get();
+        final InstanceIdentifier<Local> localIid = localSffInstanceIdentifier();
+        writeMergeTransaction(writeTransaction, localIid, localForwarder);
+        LOG.info("Local forwarder created on node {}", nodeId.getValue());
+        return true;
+    }
+
+    static boolean removeLocal(final NodeId nodeId, final DataBroker mountpoint) {
+        // Remove local forwarder only when there are no more service-paths
+        if (ServiceChainingUtil.checkServicePathPresence(mountpoint)) {
+            final java.util.Optional<WriteTransaction> optionalWriteTransaction =
+                    NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint);
+            if (!optionalWriteTransaction.isPresent()) {
+                LOG.warn("Failed to create write-only transaction, mountpoint: {}", mountpoint);
+                return false;
+            }
+            final WriteTransaction writeTransaction = optionalWriteTransaction.get();
+            final InstanceIdentifier<Local> localIid = localSffInstanceIdentifier();
+            deleteTransaction(writeTransaction, localIid);
+            LOG.info("Local forwarder removed from node {}", nodeId.getValue());
+        }
+        return true;
+    }
+
+    static boolean writeRemote(final List<ServiceFfName> remoteForwarders, final NodeId nodeId,
+                               final DataBroker mountpoint) {
+        if (remoteForwarders == null || remoteForwarders.isEmpty()) {
+            return true;
+        }
+        for (ServiceFfName forwarder : remoteForwarders) {
+            final java.util.Optional<WriteTransaction> optionalWriteTransaction =
+                    NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint);
+            if (!optionalWriteTransaction.isPresent()) {
+                LOG.warn("Failed to create transaction, mountpoint: {}", mountpoint);
+                return false;
+            }
+            final WriteTransaction writeTransaction = optionalWriteTransaction.get();
+            final InstanceIdentifier<ServiceFfName> forwarderIid = remoteSffInstanceIdentifier(forwarder);
+            writeMergeTransaction(writeTransaction, forwarderIid, forwarder);
+            LOG.info("Remote forwarder {} created on node {}", forwarder.getName(), nodeId.getValue());
+        }
+        return true;
+    }
+
+    static boolean writeServicePaths(final List<ServiceChain> serviceChains, final NodeId nodeId,
+                                     final DataBroker mountpoint) {
+        for (org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain serviceChain : serviceChains) {
+            for (ServicePath entry : serviceChain.getServicePath()) {
+                final java.util.Optional<WriteTransaction> optionalWriteTransaction =
+                        NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint);
+                if (!optionalWriteTransaction.isPresent()) {
+                    LOG.warn("Failed to create write-only transaction, mountpoint: {}", mountpoint);
+                    return false;
+                }
+                final WriteTransaction writeTransaction = optionalWriteTransaction.get();
+                final InstanceIdentifier<ServicePath> servicePathIid = servicePathInstanceIdentifier(entry.getKey());
+                writeMergeTransaction(writeTransaction, servicePathIid, entry);
+                LOG.info("Service path with ID: {} created on node {}", entry.getServicePathId(), nodeId.getValue());
+            }
+        }
+        return true;
+    }
+
+    static boolean removeServicePaths(final List<ServiceChain> serviceChains, final NodeId nodeId,
+                                      final DataBroker mountpoint) {
+        if (serviceChains == null || serviceChains.isEmpty()) {
+            return true;
+        }
+        for (ServiceChain chain : serviceChains) {
+            List<ServicePath> servicePaths = chain.getServicePath();
+            if (servicePaths == null || servicePaths.isEmpty()) {
+                continue;
+            }
+            for (ServicePath servicePath : servicePaths) {
+                final java.util.Optional<WriteTransaction> optionalWriteTransaction =
+                        NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint);
+                if (!optionalWriteTransaction.isPresent()) {
+                    LOG.warn("Failed to create write-only transaction, mountpoint: {}", mountpoint);
+                    return false;
+                }
+                final WriteTransaction writeTransaction = optionalWriteTransaction.get();
+                final InstanceIdentifier<ServicePath> servicePathIid = servicePathInstanceIdentifier(servicePath.getKey());
+                if (deleteTransaction(writeTransaction, servicePathIid)) {
+                    LOG.info("Service-path with ID: {} removed from node {}", servicePath.getServicePathId(),
+                            nodeId.getValue());
+                }
+            }
+        }
+        return true;
+    }
+
+    private static InstanceIdentifier<ClassMap> classMapInstanceIdentifier(final ClassMap classMap) {
+        return InstanceIdentifier.builder(Native.class)
+                .child(ClassMap.class, new ClassMapKey(classMap.getName())).build();
+    }
+
+    private static InstanceIdentifier<PolicyMap> policyMapInstanceIdentifier(final String policyMapName) {
+        return InstanceIdentifier.builder(Native.class)
+                .child(PolicyMap.class, new PolicyMapKey(policyMapName)).build();
+    }
+
+    private static InstanceIdentifier<Class> policyMapEntryInstanceIdentifier(final String policyMapName,
+                                                                              final ClassNameType classNameType) {
+        return InstanceIdentifier.builder(Native.class)
+                .child(PolicyMap.class, new PolicyMapKey(policyMapName))
+                .child(Class.class, new ClassKey(classNameType)).build();
+    }
+
+    private static InstanceIdentifier<ServicePolicy> interfaceInstanceIdentifier(final String ethernetName) {
+        return InstanceIdentifier.builder(Native.class)
+                .child(Interface.class)
+                .child(GigabitEthernet.class, new GigabitEthernetKey(ethernetName))
+                .child(ServicePolicy.class)
+                .build();
+    }
+
+    private static InstanceIdentifier<Local> localSffInstanceIdentifier() {
+        return InstanceIdentifier.builder(Native.class)
+                .child(org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain.class)
+                .child(ServiceFunctionForwarder.class)
+                .child(Local.class).build();
+    }
+
+    private static InstanceIdentifier<ServiceFfName> remoteSffInstanceIdentifier(final ServiceFfName sffName) {
+        return InstanceIdentifier.builder(Native.class)
+                .child(org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain.class)
+                .child(org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServiceFunctionForwarder.class)
+                .child(ServiceFfName.class, new ServiceFfNameKey(sffName.getName())).build();
+    }
+
+    private static InstanceIdentifier<ServicePath> servicePathInstanceIdentifier(final ServicePathKey key) {
+        return InstanceIdentifier.builder(Native.class)
+                .child(org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain.class)
+                .child(ServicePath.class, key).build();
+    }
+
+    private static <U extends DataObject> void writeMergeTransaction(final WriteTransaction transaction,
+                                                                     final InstanceIdentifier<U> addIID,
+                                                                     final U data) {
+        try {
+            transaction.merge(LogicalDatastoreType.CONFIGURATION, addIID, data);
+            final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = transaction.submit();
+            submitFuture.checkedGet();
+        } catch (TransactionCommitFailedException e) {
+            LOG.error("Write transaction failed to {}", e.getMessage());
+        } catch (Exception e) {
+            LOG.error("Failed to .. {}", e.getMessage());
+        }
+    }
+
+    private static <U extends DataObject> boolean deleteTransaction(final WriteTransaction transaction,
+                                                                    final InstanceIdentifier<U> addIID) {
+        try {
+            transaction.delete(LogicalDatastoreType.CONFIGURATION, addIID);
+            final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = transaction.submit();
+            submitFuture.checkedGet();
+            return true;
+        } catch (TransactionCommitFailedException e) {
+            LOG.error("Write transaction failed to {}", e.getMessage());
+            return false;
+        } catch (Exception e) {
+            LOG.error("Failed to .. {}", e.getMessage());
+            return false;
+        }
+    }
+
+    private static <U extends DataObject> U checkWritten(final ReadOnlyTransaction transaction,
+                                                         final InstanceIdentifier<U> readIID) {
+        for (int attempt = 1; attempt <= 5; attempt++) {
+            try {
+                final CheckedFuture<Optional<U>, ReadFailedException> submitFuture =
+                        transaction.read(LogicalDatastoreType.CONFIGURATION, readIID);
+                final Optional<U> optional = submitFuture.checkedGet();
+                if (optional != null && optional.isPresent()) {
+                    transaction.close(); // Release lock
+                    return optional.get();
+                } else {
+                    // Could take some time until specific configuration appears on device, try to read a few times
+                    Thread.sleep(2000L);
+                }
+            } catch (InterruptedException i) {
+                LOG.error("Thread interrupted while waiting ... {} ", i);
+            } catch (ReadFailedException e) {
+                LOG.warn("Read transaction failed to {} ", e);
+            } catch (Exception e) {
+                LOG.error("Failed to .. {}", e.getMessage());
+            }
+        }
+        return null;
+    }
+
+    private static <U extends DataObject> boolean checkRemoved(final ReadOnlyTransaction transaction,
+                                                               final InstanceIdentifier<U> readIID) {
+        for (int attempt = 1; attempt <= 5; attempt++) {
+            try {
+                final CheckedFuture<Optional<U>, ReadFailedException> submitFuture =
+                        transaction.read(LogicalDatastoreType.CONFIGURATION, readIID);
+                final Optional<U> optional = submitFuture.checkedGet();
+                if (optional != null && optional.isPresent()) {
+                    // Could take some time until specific configuration is removed from the device
+                    Thread.sleep(2000L);
+                } else {
+                    transaction.close(); // Release lock
+                    return true;
+                }
+            } catch (InterruptedException i) {
+                LOG.error("Thread interrupted while waiting ... {} ", i);
+            } catch (ReadFailedException e) {
+                LOG.warn("Read transaction failed to {} ", e);
+            } catch (Exception e) {
+                LOG.error("Failed to .. {}", e.getMessage());
+            }
+        }
+        return false;
+    }
+
+}
index 100ba97ec93af8d0badf57ec4215c62a4ee703ae..5ce6a8605dab4d64576fd2916eaa89b116404b76 100644 (file)
@@ -10,9 +10,9 @@ import static org.powermock.api.support.membermodification.MemberMatcher.method;
 import static org.powermock.api.support.membermodification.MemberModifier.stub;
 
 import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
 import java.util.Collections;
 import java.util.List;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -65,8 +65,8 @@ 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.renderer.endpoints.RendererEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicyBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicyKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroup;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroupBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroupKey;
@@ -88,8 +88,6 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
 
-import com.google.common.util.concurrent.ListenableFuture;
-
 @RunWith(PowerMockRunner.class)
 @PrepareForTest({RendererPolicyUtil.class, PolicyManagerUtil.class, SfcProviderServiceForwarderAPI.class})
 public class PolicyManagerImplTest {
@@ -355,14 +353,14 @@ public class PolicyManagerImplTest {
 
     private RendererEndpoint createRendererEndpoint(ContextId contextId_1, ContextId contextId_2,
                                                     RuleGroupWithRendererEndpointParticipation ruleGroup) {
-        PeerEndpointWithPolicyBuilder peerEndpointWithPolicyBuilder = new PeerEndpointWithPolicyBuilder();
-        peerEndpointWithPolicyBuilder.setKey(new PeerEndpointWithPolicyKey(address, IpPrefixType.class, contextId_1,
+        PeerEndpointBuilder PeerEndpointBuilder = new PeerEndpointBuilder();
+        PeerEndpointBuilder.setKey(new PeerEndpointKey(address, IpPrefixType.class, contextId_1,
                 L2BridgeDomain.class))
                 .setRuleGroupWithRendererEndpointParticipation(Collections.singletonList(ruleGroup));
         RendererEndpointBuilder rendererEndpointBuilder = new RendererEndpointBuilder();
         rendererEndpointBuilder.setKey(new RendererEndpointKey(address, IpPrefixType.class, contextId_2,
                 L2BridgeDomain.class))
-                .setPeerEndpointWithPolicy(Collections.singletonList(peerEndpointWithPolicyBuilder.build()));
+                .setPeerEndpoint(Collections.singletonList(PeerEndpointBuilder.build()));
         return rendererEndpointBuilder.build();
     }
 
index fba4c12a67e2b2d07911d59f3d1fb79e99344c64..2e5b5a78329c5e57a48fb0cbe45b9aa4cd3428e6 100644 (file)
@@ -35,6 +35,7 @@ import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev1407
 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPathBuilder;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._class.map.Match;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
@@ -102,7 +103,8 @@ public class PolicyManagerUtilTest {
         Mockito.when(roTx.read(Matchers.eq(LogicalDatastoreType.OPERATIONAL), rendererServicePathIICaptor.capture()))
                 .thenReturn(Futures.immediateCheckedFuture(Optional.of(renderedSP)));
 
-        final RenderedServicePath renderedPath = ServiceChainingUtil.createRenderedPath(serviceFunctionPath, tenantId);
+        final RenderedServicePath renderedPath = ServiceChainingUtil.createRenderedPath(serviceFunctionPath, tenantId,
+                dataBroker);
         Assert.assertEquals(renderedSP, renderedPath);
         final InstanceIdentifier<RenderedServicePath> ii = rendererServicePathIICaptor.getValue();
         Assert.assertEquals("sfp-name-01tenant-id-01-gbp-rsp", ii.firstKeyOf(RenderedServicePath.class).getName().getValue());
@@ -119,9 +121,15 @@ public class PolicyManagerUtilTest {
 
 
         final RenderedServicePath symmetricRenderedPath = ServiceChainingUtil.createSymmetricRenderedPath(
-                serviceFunctionPath, renderedServicePath, tenantId);
+                serviceFunctionPath, renderedServicePath, tenantId, dataBroker);
         Assert.assertEquals(renderedServicePath, symmetricRenderedPath);
         final InstanceIdentifier<RenderedServicePath> ii = rendererServicePathIICaptor.getValue();
         Assert.assertEquals("sfp-name-01tenant-id-02-gbp-rsp-Reverse", ii.firstKeyOf(RenderedServicePath.class).getName().getValue());
     }
+
+    @Test
+    public void testMatch() {
+        Match result = PolicyManagerUtil.createSecurityGroupMatch(10, 20);
+        assertNotNull(result);
+    }
 }
\ No newline at end of file
index 2b436b6e4bb521e2909b9bdacfbdee8aa8accf56..cef31b34af3ce5c9a1e6a8ae3bc9452ca758f17d 100644 (file)
@@ -30,9 +30,10 @@ import org.mockito.Mockito;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyConfigurationContext;
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.NetconfTransactionCreator;
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriter;
 import org.opendaylight.sfc.provider.api.SfcProviderRenderedPathAPI;
 import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI;
@@ -54,23 +55,26 @@ import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev1407
 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPathBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChainBuilder;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePathBuilder;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.Local;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.LocalBuilder;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfName;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.services.ServiceTypeChoice;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.services.service.type.choice.ServiceFunction;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.services.service.type.choice.ServiceFunctionForwarder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipationBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicy;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.actions.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.actions.ActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
@@ -88,7 +92,8 @@ import org.powermock.modules.junit4.PowerMockRunner;
         ServiceChainingUtil.class,
         SfcProviderServicePathAPI.class,
         SfcProviderRenderedPathAPI.class,
-        SfcProviderServiceForwarderAPI.class
+        SfcProviderServiceForwarderAPI.class,
+        NetconfTransactionCreator.class
 })
 public class ServiceChainingUtilTest {
 
@@ -104,6 +109,8 @@ public class ServiceChainingUtilTest {
     private ArgumentCaptor<RenderedServicePath> rspCaptor;
     @Captor
     private ArgumentCaptor<List<Class>> listClassCaptor;
+    @Captor
+    private ArgumentCaptor<ClassMap> classMapCaptor;
     @Mock
     private PolicyWriter policyWriter;
     @Mock
@@ -111,6 +118,8 @@ public class ServiceChainingUtilTest {
     @Mock
     private ReadWriteTransaction rwTx;
 
+    private PolicyConfigurationContext policyConfigurationContext;
+
     @Before
     public void setUp() throws Exception {
         final NodeId currentNodeId = new NodeId("unit-node-01");
@@ -121,6 +130,9 @@ public class ServiceChainingUtilTest {
 
         Mockito.when(policyWriter.getCurrentMountpoint()).thenReturn(dataBroker);
         Mockito.when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx);
+
+        policyConfigurationContext = new PolicyConfigurationContext();
+        policyConfigurationContext.setPolicyWriter(policyWriter);
     }
 
     @Test
@@ -145,7 +157,7 @@ public class ServiceChainingUtilTest {
 
     @Test
     public void testResolveChainAction_full() throws Exception {
-        final PeerEndpointWithPolicy peerEndpoint = createPeerEndpointWithPolicy();
+        final PeerEndpoint peerEndpoint = createPeerEndpoint();
         final Sgt sourceSgt = new Sgt(1);
         final Sgt destinationSgt = new Sgt(2);
         final Map<PolicyManagerImpl.ActionCase, Action> actionMap = createActionMap();
@@ -163,8 +175,9 @@ public class ServiceChainingUtilTest {
         stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(rsp);
         stub(method(ServiceChainingUtil.class, "setSfcPart")).toReturn(true);
 
-        ServiceChainingUtil.resolveChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, classMapName, policyWriter);
+        ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, policyConfigurationContext, dataBroker);
 
+        Mockito.verify(policyWriter).cache(classMapCaptor.capture());
         Mockito.verify(policyWriter).cache(listClassCaptor.capture());
         Mockito.verifyNoMoreInteractions(policyWriter);
         Assert.assertEquals(1, listClassCaptor.getValue().size());
@@ -172,7 +185,7 @@ public class ServiceChainingUtilTest {
 
     @Test
     public void testResolveChainAction_fullSymmetric() throws Exception {
-        final PeerEndpointWithPolicy peerEndpoint = createPeerEndpointWithPolicy();
+        final PeerEndpoint peerEndpoint = createPeerEndpoint();
         final Sgt sourceSgt = new Sgt(1);
         final Sgt destinationSgt = new Sgt(2);
         final Map<PolicyManagerImpl.ActionCase, Action> actionMap = createActionMap();
@@ -190,8 +203,9 @@ public class ServiceChainingUtilTest {
         stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(rsp);
         stub(method(ServiceChainingUtil.class, "setSfcPart")).toReturn(true);
 
-        ServiceChainingUtil.resolveChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, classMapName, policyWriter);
+        ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, policyConfigurationContext, dataBroker);
 
+        Mockito.verify(policyWriter, Mockito.times(2)).cache(classMapCaptor.capture());
         Mockito.verify(policyWriter).cache(listClassCaptor.capture());
         Mockito.verifyNoMoreInteractions(policyWriter);
         Assert.assertEquals(2, listClassCaptor.getValue().size());
@@ -199,7 +213,7 @@ public class ServiceChainingUtilTest {
 
     @Test
     public void testResolveChainAction_partial01() throws Exception {
-        final PeerEndpointWithPolicy peerEndpoint = createPeerEndpointWithPolicy();
+        final PeerEndpoint peerEndpoint = createPeerEndpoint();
         final Sgt sourceSgt = new Sgt(1);
         final Sgt destinationSgt = new Sgt(2);
         final Map<PolicyManagerImpl.ActionCase, Action> actionMap = createActionMap();
@@ -218,14 +232,20 @@ public class ServiceChainingUtilTest {
         stub(method(ServiceChainingUtil.class, "setSfcPart")).toReturn(true);
         stub(method(ServiceChainingUtil.class, "createSymmetricRenderedPath")).toReturn(null);
 
-        ServiceChainingUtil.resolveChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, classMapName, policyWriter);
+        policyConfigurationContext.setCurrentRendererEP(createRendererEP(
+                "unit-address", new ContextId("unit-conext-1"), Collections.emptyList())
+        );
 
+        ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap,
+                policyConfigurationContext, dataBroker);
+        Mockito.verify(policyWriter, Mockito.times(2)).cache(classMapCaptor.capture());
+        Mockito.verify(policyWriter).cache(listClassCaptor.capture());
         Mockito.verifyNoMoreInteractions(policyWriter);
     }
 
     @Test
     public void testResolveChainAction_partial02() throws Exception {
-        final PeerEndpointWithPolicy peerEndpoint = createPeerEndpointWithPolicy();
+        final PeerEndpoint peerEndpoint = createPeerEndpoint();
         final Sgt sourceSgt = new Sgt(1);
         final Sgt destinationSgt = new Sgt(2);
         final Map<PolicyManagerImpl.ActionCase, Action> actionMap = createActionMap();
@@ -243,14 +263,14 @@ public class ServiceChainingUtilTest {
         stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(rsp);
         stub(method(ServiceChainingUtil.class, "setSfcPart")).toReturn(false);
 
-        ServiceChainingUtil.resolveChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, classMapName, policyWriter);
+        ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, policyConfigurationContext, dataBroker);
 
         Mockito.verifyNoMoreInteractions(policyWriter);
     }
 
     @Test
     public void testResolveChainAction_partial03() throws Exception {
-        final PeerEndpointWithPolicy peerEndpoint = createPeerEndpointWithPolicy(null);
+        final PeerEndpoint peerEndpoint = createPeerEndpoint(null);
         final Sgt sourceSgt = new Sgt(1);
         final Sgt destinationSgt = new Sgt(2);
         final Map<PolicyManagerImpl.ActionCase, Action> actionMap = createActionMap();
@@ -267,20 +287,28 @@ public class ServiceChainingUtilTest {
         final RenderedServicePath rsp = createRsp("unit-rsp-02");
         stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(rsp);
 
-        ServiceChainingUtil.resolveChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, classMapName, policyWriter);
+        policyConfigurationContext.setCurrentRendererEP(createRendererEP(
+                "unit-address", new ContextId("unit-conext-1"), Collections.emptyList())
+        );
+
+        ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, policyConfigurationContext, dataBroker);
 
         Mockito.verifyNoMoreInteractions(policyWriter);
     }
 
     @Test
     public void testResolveChainAction_partial04() throws Exception {
-        final PeerEndpointWithPolicy peerEndpoint = createPeerEndpointWithPolicy(null);
+        final PeerEndpoint peerEndpoint = createPeerEndpoint(null);
         final Sgt sourceSgt = new Sgt(1);
         final Sgt destinationSgt = new Sgt(2);
         final Map<PolicyManagerImpl.ActionCase, Action> actionMap = createActionMap(false);
         final String classMapName = "unit-class-map-name-01";
 
-        ServiceChainingUtil.resolveChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, classMapName, policyWriter);
+        policyConfigurationContext.setCurrentRendererEP(createRendererEP(
+                "unit-address", new ContextId("unit-conext-1"), Collections.emptyList())
+        );
+
+        ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, policyConfigurationContext, dataBroker);
 
         Mockito.verifyNoMoreInteractions(policyWriter);
     }
@@ -302,12 +330,22 @@ public class ServiceChainingUtilTest {
         return actionMap;
     }
 
-    private PeerEndpointWithPolicy createPeerEndpointWithPolicy() {
-        return createPeerEndpointWithPolicy(new TenantId("unit-tenant-06"));
+    private RendererEndpoint createRendererEP(final String address, final ContextId contextId, final List<PeerEndpoint> peerEndpoints) {
+        return new RendererEndpointBuilder()
+                .setAddress(address)
+                .setAddressType(IpPrefixType.class)
+                .setContextId(contextId)
+                .setContextType(L3Context.class)
+                .setPeerEndpoint(peerEndpoints)
+                .build();
+    }
+
+    private PeerEndpoint createPeerEndpoint() {
+        return createPeerEndpoint(new TenantId("unit-tenant-06"));
     }
 
-    private PeerEndpointWithPolicy createPeerEndpointWithPolicy(final TenantId tenantId) {
-        return new PeerEndpointWithPolicyBuilder()
+    private PeerEndpoint createPeerEndpoint(final TenantId tenantId) {
+        return new PeerEndpointBuilder()
                 .setRuleGroupWithRendererEndpointParticipation(Collections.singletonList(
                         new RuleGroupWithRendererEndpointParticipationBuilder()
                                 .setTenantId(tenantId)
@@ -328,7 +366,7 @@ public class ServiceChainingUtilTest {
         final SfcProviderRenderedPathAPI api = PowerMockito.mock(SfcProviderRenderedPathAPI.class);
         PowerMockito.when(api.readRenderedServicePath(rspNameCaptor.capture())).thenReturn(rsp);
 
-        final RenderedServicePath renderedPath = ServiceChainingUtil.createRenderedPath(sfp, tenantId);
+        final RenderedServicePath renderedPath = ServiceChainingUtil.createRenderedPath(sfp, tenantId, dataBroker);
 
         Assert.assertEquals("123_plainunit-tennant-01-gbp-rsp", rspNameCaptor.getValue().getValue());
         Assert.assertEquals(rsp, renderedPath);
@@ -348,8 +386,11 @@ public class ServiceChainingUtilTest {
         PowerMockito.when(api.createRenderedServicePathAndState(
                 sfpCaptor.capture(), createRspCaptor.capture()
         )).thenReturn(rsp);
+        PowerMockito.mockStatic(NetconfTransactionCreator.class);
+        final NetconfTransactionCreator creator = PowerMockito.mock(NetconfTransactionCreator.class);
+        PowerMockito.when(creator.netconfReadWriteTransaction(dataBroker)).thenReturn(java.util.Optional.empty());
 
-        final RenderedServicePath renderedPath = ServiceChainingUtil.createRenderedPath(sfp, tenantId);
+        final RenderedServicePath renderedPath = ServiceChainingUtil.createRenderedPath(sfp, tenantId, dataBroker);
 
         Assert.assertEquals("123_plainunit-tennant-01-gbp-rsp", rspNameCaptor.getValue().getValue());
 
@@ -397,7 +438,7 @@ public class ServiceChainingUtilTest {
         final SfcProviderRenderedPathAPI api = PowerMockito.mock(SfcProviderRenderedPathAPI.class);
         PowerMockito.when(api.readRenderedServicePath(rspNameCaptor.capture())).thenReturn(rsp);
 
-        final RenderedServicePath symmetricRenderedPath = ServiceChainingUtil.createSymmetricRenderedPath(sfp, rsp, tennantId);
+        final RenderedServicePath symmetricRenderedPath = ServiceChainingUtil.createSymmetricRenderedPath(sfp, rsp, tennantId, dataBroker);
 
         Assert.assertEquals("unit-sfp-02_plaintenant-02-gbp-rsp-Reverse", rspNameCaptor.getValue().getValue());
         Assert.assertEquals(rsp, symmetricRenderedPath);
@@ -412,54 +453,18 @@ public class ServiceChainingUtilTest {
         PowerMockito.mockStatic(SfcProviderRenderedPathAPI.class);
         final SfcProviderRenderedPathAPI api = PowerMockito.mock(SfcProviderRenderedPathAPI.class);
         PowerMockito.when(api.readRenderedServicePath(rspNameCaptor.capture())).thenReturn(null);
-        PowerMockito.when(api.createSymmetricRenderedServicePathAndState(rspCaptor.capture())).thenReturn(rsp);
+        PowerMockito.when(api.createReverseRenderedServicePathEntry(rspCaptor.capture())).thenReturn(rsp);
+        PowerMockito.mockStatic(NetconfTransactionCreator.class);
+        final NetconfTransactionCreator creator = PowerMockito.mock(NetconfTransactionCreator.class);
+        PowerMockito.when(creator.netconfReadWriteTransaction(dataBroker)).thenReturn(java.util.Optional.empty());
 
-        final RenderedServicePath symmetricRenderedPath = ServiceChainingUtil.createSymmetricRenderedPath(sfp, rsp, tennantId);
+        final RenderedServicePath symmetricRenderedPath = ServiceChainingUtil.createSymmetricRenderedPath(sfp, rsp, tennantId, dataBroker);
 
         Assert.assertEquals("unit-sfp-02_plaintenant-02-gbp-rsp-Reverse", rspNameCaptor.getValue().getValue());
         Assert.assertEquals(rsp, rspCaptor.getValue());
         Assert.assertEquals(rsp, symmetricRenderedPath);
     }
 
-    @Test
-    public void testCheckLocalForwarderPresence() throws Exception {
-        final Local local = new LocalBuilder().build();
-
-        Mockito.when(rwTx.read(Matchers.eq(LogicalDatastoreType.CONFIGURATION), Matchers.<InstanceIdentifier<Local>>any()))
-                .thenReturn(Futures.<Optional<Local>, ReadFailedException>immediateCheckedFuture(Optional.of(local)))
-                .thenReturn(Futures.<Optional<Local>, ReadFailedException>immediateCheckedFuture(Optional.absent()))
-                .thenReturn(Futures.<Optional<Local>, ReadFailedException>immediateFailedCheckedFuture(new ReadFailedException("n/a")));
-
-        Assert.assertTrue(ServiceChainingUtil.checkLocalForwarderPresence(dataBroker));
-        Assert.assertFalse(ServiceChainingUtil.checkLocalForwarderPresence(dataBroker));
-        Assert.assertFalse(ServiceChainingUtil.checkLocalForwarderPresence(dataBroker));
-        Assert.assertFalse(ServiceChainingUtil.checkLocalForwarderPresence(dataBroker));
-    }
-
-    @Test
-    public void testCheckServicePathPresence() throws Exception {
-        final ServiceChain serviceChainOk = new ServiceChainBuilder()
-                .setServicePath(Collections.singletonList(new ServicePathBuilder().build()))
-                .build();
-        final ServiceChain serviceChainBad1 = new ServiceChainBuilder()
-                .setServicePath(Collections.emptyList())
-                .build();
-        final ServiceChain serviceChainBad2 = new ServiceChainBuilder().build();
-
-        Mockito.when(rwTx.read(Matchers.eq(LogicalDatastoreType.CONFIGURATION), Matchers.<InstanceIdentifier<ServiceChain>>any()))
-                .thenReturn(Futures.<Optional<ServiceChain>, ReadFailedException>immediateCheckedFuture(Optional.of(serviceChainOk)))
-                .thenReturn(Futures.<Optional<ServiceChain>, ReadFailedException>immediateCheckedFuture(Optional.of(serviceChainBad1)))
-                .thenReturn(Futures.<Optional<ServiceChain>, ReadFailedException>immediateCheckedFuture(Optional.of(serviceChainBad2)))
-                .thenReturn(Futures.<Optional<ServiceChain>, ReadFailedException>immediateCheckedFuture(Optional.absent()))
-                .thenReturn(Futures.<Optional<ServiceChain>, ReadFailedException>immediateFailedCheckedFuture(new ReadFailedException("n/a")));
-
-        Assert.assertFalse(ServiceChainingUtil.checkServicePathPresence(dataBroker));
-        Assert.assertTrue(ServiceChainingUtil.checkServicePathPresence(dataBroker));
-        Assert.assertTrue(ServiceChainingUtil.checkServicePathPresence(dataBroker));
-        Assert.assertTrue(ServiceChainingUtil.checkServicePathPresence(dataBroker));
-        Assert.assertFalse(ServiceChainingUtil.checkServicePathPresence(dataBroker));
-    }
-
     @Test
     public void testFindServiceFunctionPath() throws Exception {
         final String sfcNameValue = "123";
@@ -482,6 +487,9 @@ public class ServiceChainingUtilTest {
                 .setName(new SffName("unit-sff-03"))
                 .setIpMgmtAddress(new IpAddress(new Ipv4Address("1.2.3.4")))
                 .build();
+        final ServiceFunctionPathBuilder sfpBuilder = new ServiceFunctionPathBuilder();
+        sfpBuilder.setSymmetric(false);
+        final ServiceFunctionPath sfp = sfpBuilder.build();
 
         stub(method(ServiceChainingUtil.class, "checkLocalForwarderPresence")).toReturn(true);
 
@@ -489,8 +497,7 @@ public class ServiceChainingUtilTest {
         final SfcProviderServiceForwarderAPI api = PowerMockito.mock(SfcProviderServiceForwarderAPI.class);
         PowerMockito.when(api.readServiceFunctionForwarder(sffNameCaptor.capture())).thenReturn(sff);
 
-
-        final boolean outcome = ServiceChainingUtil.setSfcPart(rsp, policyWriter);
+        final boolean outcome = ServiceChainingUtil.setSfcPart(sfp, rsp, null, policyWriter);
 
         Assert.assertEquals("rsp-hop-01-sf+sff", sffNameCaptor.getValue().getValue());
         Assert.assertTrue(outcome);
@@ -511,6 +518,9 @@ public class ServiceChainingUtilTest {
                 .setName(new SffName("unit-sff-03"))
                 .setIpMgmtAddress(new IpAddress(new Ipv4Address("1.2.3.4")))
                 .build();
+        final ServiceFunctionPathBuilder sfpBuilder = new ServiceFunctionPathBuilder();
+        sfpBuilder.setSymmetric(false);
+        final ServiceFunctionPath sfp = sfpBuilder.build();
 
         stub(method(ServiceChainingUtil.class, "checkLocalForwarderPresence")).toReturn(false);
 
@@ -518,8 +528,7 @@ public class ServiceChainingUtilTest {
         final SfcProviderServiceForwarderAPI api = PowerMockito.mock(SfcProviderServiceForwarderAPI.class);
         PowerMockito.when(api.readServiceFunctionForwarder(sffNameCaptor.capture())).thenReturn(sff);
 
-
-        final boolean outcome = ServiceChainingUtil.setSfcPart(rsp, policyWriter);
+        final boolean outcome = ServiceChainingUtil.setSfcPart(sfp, rsp, null, policyWriter);
 
         Assert.assertEquals("rsp-hop-01-sf+sff", sffNameCaptor.getValue().getValue());
         Assert.assertTrue(outcome);
@@ -534,23 +543,28 @@ public class ServiceChainingUtilTest {
 
     @Test
     public void testSetSfcPart_fail01() throws Exception {
-        Assert.assertFalse(ServiceChainingUtil.setSfcPart(null, policyWriter));
+        final ServiceFunctionPathBuilder sfpBuilder = new ServiceFunctionPathBuilder();
+        sfpBuilder.setSymmetric(false);
+        final ServiceFunctionPath sfp = sfpBuilder.build();
+
+        Assert.assertFalse(ServiceChainingUtil.setSfcPart(sfp, null, null, policyWriter));
 
         final RenderedServicePathBuilder rspBuilder = new RenderedServicePathBuilder().setName(new RspName("unit-rsp-05"));
-        Assert.assertFalse(ServiceChainingUtil.setSfcPart(rspBuilder.build(), policyWriter));
+        Assert.assertFalse(ServiceChainingUtil.setSfcPart(sfp, rspBuilder.build(), null, policyWriter));
 
         rspBuilder.setRenderedServicePathHop(Collections.emptyList());
-        Assert.assertFalse(ServiceChainingUtil.setSfcPart(rspBuilder.build(), policyWriter));
+        Assert.assertFalse(ServiceChainingUtil.setSfcPart(sfp, rspBuilder.build(), null, policyWriter));
 
         rspBuilder.setRenderedServicePathHop(Collections.singletonList(null));
-        Assert.assertFalse(ServiceChainingUtil.setSfcPart(rspBuilder.build(), policyWriter));
-
-        Mockito.verifyNoMoreInteractions(policyWriter);
+        Assert.assertFalse(ServiceChainingUtil.setSfcPart(sfp, rspBuilder.build(), null, policyWriter));
     }
 
     @Test
     public void testSetSfcPart_fail02() throws Exception {
         final RenderedServicePath rsp = createRsp("unit-rsp-03");
+        final ServiceFunctionPathBuilder sfpBuilder = new ServiceFunctionPathBuilder();
+        sfpBuilder.setSymmetric(false);
+        final ServiceFunctionPath sfp = sfpBuilder.build();
 
         Mockito.doReturn(Futures.immediateCheckedFuture(Optional.absent()))
                 .when(rwTx).read(Mockito.eq(LogicalDatastoreType.CONFIGURATION), Mockito.<InstanceIdentifier<Local>>any());
@@ -559,7 +573,7 @@ public class ServiceChainingUtilTest {
         final SfcProviderServiceForwarderAPI api = PowerMockito.mock(SfcProviderServiceForwarderAPI.class);
         PowerMockito.when(api.readServiceFunctionForwarder(sffNameCaptor.capture())).thenReturn(null);
 
-        final boolean outcome = ServiceChainingUtil.setSfcPart(rsp, policyWriter);
+        final boolean outcome = ServiceChainingUtil.setSfcPart(sfp, rsp, null, policyWriter);
 
         Assert.assertEquals("rsp-hop-01-sf+sff", sffNameCaptor.getValue().getValue());
         Assert.assertFalse(outcome);
@@ -576,6 +590,9 @@ public class ServiceChainingUtilTest {
         final ServiceFunctionForwarderBuilder sffBuilder = new ServiceFunctionForwarderBuilder()
                 .setName(new SffName("unit-sff-03"))
                 .setIpMgmtAddress(null);
+        final ServiceFunctionPathBuilder sfpBuilder = new ServiceFunctionPathBuilder();
+        sfpBuilder.setSymmetric(false);
+        final ServiceFunctionPath sfp = sfpBuilder.build();
 
         stub(method(ServiceChainingUtil.class, "checkLocalForwarderPresence")).toReturn(true);
 
@@ -584,7 +601,7 @@ public class ServiceChainingUtilTest {
         PowerMockito.when(api.readServiceFunctionForwarder(sffNameCaptor.capture())).thenReturn(
                 sffBuilder.build());
 
-        Assert.assertFalse(ServiceChainingUtil.setSfcPart(rsp, policyWriter));
+        Assert.assertFalse(ServiceChainingUtil.setSfcPart(sfp, rsp, null, policyWriter));
 
         Assert.assertEquals("rsp-hop-01-sf+sff", sffNameCaptor.getValue().getValue());
 
@@ -599,6 +616,9 @@ public class ServiceChainingUtilTest {
         final ServiceFunctionForwarderBuilder sffBuilder = new ServiceFunctionForwarderBuilder()
                 .setName(new SffName("unit-sff-03"))
                 .setIpMgmtAddress(new IpAddress((Ipv4Address) null));
+        final ServiceFunctionPathBuilder sfpBuilder = new ServiceFunctionPathBuilder();
+        sfpBuilder.setSymmetric(false);
+        final ServiceFunctionPath sfp = sfpBuilder.build();
 
         stub(method(ServiceChainingUtil.class, "checkLocalForwarderPresence")).toReturn(true);
 
@@ -607,7 +627,7 @@ public class ServiceChainingUtilTest {
         PowerMockito.when(api.readServiceFunctionForwarder(sffNameCaptor.capture())).thenReturn(
                 sffBuilder.build());
 
-        Assert.assertFalse(ServiceChainingUtil.setSfcPart(rsp, policyWriter));
+        Assert.assertFalse(ServiceChainingUtil.setSfcPart(sfp, rsp, null, policyWriter));
 
         Assert.assertEquals("rsp-hop-01-sf+sff", sffNameCaptor.getValue().getValue());
 
@@ -616,7 +636,6 @@ public class ServiceChainingUtilTest {
         Mockito.verifyNoMoreInteractions(policyWriter);
     }
 
-
     @Test
     public void testForwarderTypeChoice() throws Exception {
         final String sffValue = "unit-xx";
diff --git a/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/StatusUtilTest.java b/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/StatusUtilTest.java
new file mode 100644 (file)
index 0000000..9b1fdb0
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * 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.ios_xe_provider.impl.util;
+
+import com.google.common.collect.Lists;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Stream;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyConfigurationContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.AddressEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.unconfigured.rule.groups.UnconfiguredRuleGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.status.unconfigured.endpoints.UnconfiguredRendererEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.status.unconfigured.endpoints.unconfigured.renderer.endpoint.UnconfiguredPeerEndpoint;
+
+/**
+ * Test for {@link StatusUtil}.
+ */
+public class StatusUtilTest {
+
+    public static final TenantId TENANT_ID = new TenantId("unit-tenant-1");
+    public static final SubjectName SUBJECT_NAME = new SubjectName("unit-subject-1");
+    public static final ContractId CONTRACT_ID = new ContractId("unit-contract-1");
+    public static final String ADDRESS_1 = "unit-address-1";
+    public static final ContextId CONTEXT_ID_1 = new ContextId("unit-context-1");
+    public static final String ADDRESS_2 = "unit-address-2";
+    public static final ContextId CONTEXT_ID_2 = new ContextId("unit-context-2");
+    public static final String INFO_MESSAGE = "unit-info-1";
+    private PolicyConfigurationContext context;
+
+    @Before
+    public void setUp() throws Exception {
+        context = new PolicyConfigurationContext();
+    }
+
+    @Test
+    public void testAssembleFullyNotConfigurableRendererEP() throws Exception {
+        final PeerEndpoint peer1 = createPeer(ADDRESS_1, CONTEXT_ID_1);
+        final PeerEndpoint peer2 = createPeer(ADDRESS_2, CONTEXT_ID_2);
+        final RendererEndpoint rendererEP = createRendererEP(ADDRESS_1, CONTEXT_ID_1,
+                Lists.newArrayList(peer1, peer2)
+        );
+        context.setCurrentRendererEP(rendererEP);
+
+        final UnconfiguredRendererEndpoint actual = StatusUtil.assembleFullyNotConfigurableRendererEP(context, INFO_MESSAGE);
+
+        compareEPs(rendererEP, actual);
+        Assert.assertNull(actual.getUnconfiguredPeerExternalEndpoint());
+        Assert.assertNull(actual.getUnconfiguredPeerExternalContainmentEndpoint());
+
+        final List<UnconfiguredPeerEndpoint> unconfiguredPeerEndpoints = actual.getUnconfiguredPeerEndpoint();
+        Assert.assertEquals(2, unconfiguredPeerEndpoints.size());
+        compareEPs(peer1, unconfiguredPeerEndpoints.get(0));
+        Assert.assertTrue(unconfiguredPeerEndpoints.get(0).getUnconfiguredRuleGroup().isEmpty());
+        compareEPs(peer2, unconfiguredPeerEndpoints.get(1));
+        Assert.assertTrue(unconfiguredPeerEndpoints.get(1).getUnconfiguredRuleGroup().isEmpty());
+    }
+
+    private PeerEndpoint createPeer(final String address, final ContextId contextId) {
+        return new PeerEndpointBuilder(createRendererEP(address, contextId, Collections.emptyList()))
+                .setRuleGroupWithRendererEndpointParticipation(Collections.emptyList())
+                .build();
+    }
+
+    private RendererEndpoint createRendererEP(final String address, final ContextId contextId, final List<PeerEndpoint> peerEndpoints) {
+        return new RendererEndpointBuilder()
+                .setAddress(address)
+                .setAddressType(IpPrefixType.class)
+                .setContextId(contextId)
+                .setContextType(L3Context.class)
+                .setPeerEndpoint(peerEndpoints)
+                .build();
+    }
+
+    @Test
+    public void testAssembleNotConfigurableRendererEPForPeer() throws Exception {
+        final PeerEndpoint peer1 = createPeer(ADDRESS_1, CONTEXT_ID_1);
+        final PeerEndpoint peer2 = createPeer(ADDRESS_2, CONTEXT_ID_2);
+        final RendererEndpoint rendererEP = createRendererEP(ADDRESS_1, CONTEXT_ID_1,
+                Lists.newArrayList(peer1, peer2)
+        );
+        context.setCurrentRendererEP(rendererEP);
+
+        final UnconfiguredRendererEndpoint actual = StatusUtil.assembleNotConfigurableRendererEPForPeer(context, peer1, INFO_MESSAGE);
+
+        compareEPs(rendererEP, actual);
+        Assert.assertNull(actual.getUnconfiguredPeerExternalEndpoint());
+        Assert.assertNull(actual.getUnconfiguredPeerExternalContainmentEndpoint());
+
+        final List<UnconfiguredPeerEndpoint> unconfiguredPeerEndpoints = actual.getUnconfiguredPeerEndpoint();
+        Assert.assertEquals(1, unconfiguredPeerEndpoints.size());
+        compareEPs(peer1, unconfiguredPeerEndpoints.get(0));
+        Assert.assertTrue(unconfiguredPeerEndpoints.get(0).getUnconfiguredRuleGroup().isEmpty());
+    }
+
+    @Test
+    public void testAssemblePeerEndpoint() throws Exception {
+        final PeerEndpoint peerEndpoint = createPeer(ADDRESS_1, CONTEXT_ID_1);
+        final List<UnconfiguredPeerEndpoint> gatheredPeers = StatusUtil.assemblePeerEndpoint(Stream.of(peerEndpoint));
+
+        Assert.assertEquals(1, gatheredPeers.size());
+        final UnconfiguredPeerEndpoint actual = gatheredPeers.get(0);
+        compareEPs(peerEndpoint, actual);
+        Assert.assertTrue(actual.getUnconfiguredRuleGroup().isEmpty());
+    }
+
+    private void compareEPs(final AddressEndpointKey peerEndpoint, final AddressEndpointKey actual) {
+        Assert.assertEquals(peerEndpoint.getAddress(), actual.getAddress());
+        Assert.assertEquals(peerEndpoint.getAddressType(), actual.getAddressType());
+        Assert.assertEquals(peerEndpoint.getContextId(), actual.getContextId());
+        Assert.assertEquals(peerEndpoint.getContextType(), actual.getContextType());
+    }
+
+    @Test
+    public void testAssembleRuleGroups() throws Exception {
+        final RuleGroupWithRendererEndpointParticipation ruleGroup =
+                new RuleGroupWithRendererEndpointParticipationBuilder()
+                        .setTenantId(TENANT_ID)
+                        .setSubjectName(SUBJECT_NAME)
+                        .setContractId(CONTRACT_ID)
+                        .setRendererEndpointParticipation(EndpointPolicyParticipation.CONSUMER)
+                        .build();
+        final List<UnconfiguredRuleGroup> gatheredRuleGroups = StatusUtil.assembleRuleGroups(Stream.of(ruleGroup));
+
+        Assert.assertEquals(1, gatheredRuleGroups.size());
+        final UnconfiguredRuleGroup actual = gatheredRuleGroups.get(0);
+        Assert.assertEquals(TENANT_ID, actual.getTenantId());
+        Assert.assertEquals(SUBJECT_NAME, actual.getSubjectName());
+        Assert.assertEquals(CONTRACT_ID, actual.getContractId());
+        Assert.assertEquals(null, actual.getUnconfiguredResolvedRule());
+        Assert.assertEquals(EndpointPolicyParticipation.CONSUMER, actual.getRendererEndpointParticipation());
+    }
+}
\ No newline at end of file
index 5a8c77dd6c775ade607f0eb398c86a01042b5cba..72fff6c0d9394924eff0f896c523532c834f9f75 100755 (executable)
@@ -40,6 +40,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.Fl
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.BucketsBuilder;
@@ -168,6 +170,9 @@ public class OfWriter {
         Preconditions.checkNotNull(flow);
         Preconditions.checkNotNull(nodeId);
 
+        if (flow.getMatch() == null) {
+            flow = new FlowBuilder(flow).setMatch(new MatchBuilder().build()).build();
+        }
         TableBuilder tableBuilder = this.getTableBuilderForNode(nodeId, tableId);
         // transforming List<Flow> to Set (with customized equals/hashCode) to eliminate duplicate entries
         List<Flow> flows = tableBuilder.getFlow();
@@ -264,6 +269,9 @@ public class OfWriter {
             for (Equivalence.Wrapper<Flow> wf : additions) {
                 Flow f = wf.get();
                 if (f != null) {
+                    if (f.getMatch() == null) {
+                        f = new FlowBuilder(f).setMatch(new MatchBuilder().build()).build();
+                    }
                     t.put(LogicalDatastoreType.CONFIGURATION,
                             FlowUtils.createFlowPath(tableIid, f.getId()), f, true);
                 }
index 743c519cd0010514b2fe3ca07f750971d3584300..51e756a0837b8a42b07a1a12f61a70c9e3a1b6ab 100755 (executable)
@@ -51,7 +51,8 @@ public abstract class FlowTable extends OfTable {
             .setTableId(getTableId())
             .setBarrier(false)
             .setHardTimeout(0)
-            .setIdleTimeout(0);
+            .setIdleTimeout(0)
+            .setMatch(new MatchBuilder().build());
     }
 
     /**
index 48b26ec9c8276bebf593abf6aa9fa4ac0db9cf0f..e57aed4ad87fbc6956f264a3d1082e850e4fdb9c 100644 (file)
@@ -44,6 +44,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vlan.rev160429.network.topology.topology.tunnel.parameters.VlanNetworkParametersBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vxlan.rev160429.TunnelTypeVxlan;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vxlan.rev160429.network.topology.topology.tunnel.parameters.VxlanTunnelParametersBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527._802dot1q;
 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;
@@ -136,7 +137,8 @@ public class BridgeDomainManagerImpl implements BridgeDomainManager {
             .setUnknownUnicastFlood(true)
             .setTunnelParameters(new VxlanTunnelParametersBuilder().setVni(vni).build())
             .build();
-        return createBridgeDomainOnVppNode(bridgeDomainName, topoAug, createBasicVppNodeBuilder(vppNodeId).build());
+        return createBridgeDomainOnVppNode(bridgeDomainName, topoAug,
+                createBasicVppNodeBuilder(vppNodeId).build());
     }
 
     @Override
@@ -148,7 +150,8 @@ public class BridgeDomainManagerImpl implements BridgeDomainManager {
             .setForward(true)
             .setLearn(true)
             .setUnknownUnicastFlood(true)
-            .setTunnelParameters(new VlanNetworkParametersBuilder().setVlanId(vlanId).build())
+            .setTunnelParameters(
+                    new VlanNetworkParametersBuilder().setVlanId(vlanId).setVlanType(_802dot1q.class).build())
             .build();
         InstanceIdentifier<BridgeDomain> bridgeDomainConfigIid = InstanceIdentifier.builder(Config.class)
             .child(BridgeDomain.class, new BridgeDomainKey(bridgeDomainName))
@@ -167,7 +170,7 @@ public class BridgeDomainManagerImpl implements BridgeDomainManager {
                             NodeVbridgeVlanAugment vppNodeVlanAug = new NodeVbridgeVlanAugmentBuilder()
                                 .setSuperInterface(ref.getInterface().get(0)).build();
                             Node vppNode = createBasicVppNodeBuilder(vppNodeId)
-                                .addAugmentation(vppNodeVlanAug.getClass(), vppNodeVlanAug).build();
+                                .addAugmentation(NodeVbridgeVlanAugment.class, vppNodeVlanAug).build();
                             return createBridgeDomainOnVppNode(bridgeDomainName, topoAug, vppNode);
                         }
                     }
index 815fecacfec51e7d09da0c53aff489458cce3bc6..b6b1ae363e8855483402fd5ab14dfe0f0ab88940 100644 (file)
@@ -8,6 +8,12 @@
 
 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;
@@ -16,18 +22,16 @@ 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.renderer.rev151103.has.peer.endpoints.PeerEndpointKey;
 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;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.renderer.forwarding.by.tenant.RendererForwardingContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.renderer.forwarding.by.tenant.RendererForwardingContextKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.renderer.forwarding.by.tenant.RendererNetworkDomain;
@@ -35,13 +39,6 @@ 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;
@@ -88,7 +85,7 @@ public class PolicyContext {
                 new Builder<>();
         Supplier<TreeSet<RendererResolvedPolicy>> rendererPolicySupplier = () -> new TreeSet<>();
         rendererEps.stream().forEach(rEp -> {
-            rEp.getPeerEndpointWithPolicy().stream().filter(Objects::nonNull).forEach(peer -> {
+            rEp.getPeerEndpoint().stream().filter(Objects::nonNull).forEach(peer -> {
                 ImmutableSortedSet<RendererResolvedPolicy> rPolicy =
                         peer.getRuleGroupWithRendererEndpointParticipation()
                             .stream()
index 6484686f0b7078daeae83bbf7a348b1c5c1af28e..6024bac5b4a3e7b9ec0f5761c71e07043a4f4859 100644 (file)
@@ -10,11 +10,10 @@ package org.opendaylight.groupbasedpolicy.renderer.vpp.util;
 
 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.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocationKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.peer.endpoints.PeerEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipationKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicyKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroupKey;
 
 public class KeyFactory {
@@ -26,7 +25,7 @@ public class KeyFactory {
                 fromKey.getContextId(), fromKey.getContextType());
     }
 
-    public static PeerEndpointKey peerEndpointKey(PeerEndpointWithPolicyKey fromKey) {
+    public static PeerEndpointKey peerEndpointKey(PeerEndpointKey fromKey) {
         return new PeerEndpointKey(fromKey.getAddress(), fromKey.getAddressType(), fromKey.getContextId(),
                 fromKey.getContextType());
     }
@@ -51,8 +50,8 @@ public class KeyFactory {
                 fromKey.getContextType());
     }
 
-    public static PeerEndpointWithPolicyKey peerEndpointWithPolicyKey(AddressEndpointWithLocationKey fromKey) {
-        return new PeerEndpointWithPolicyKey(fromKey.getAddress(), fromKey.getAddressType(), fromKey.getContextId(),
+    public static PeerEndpointKey peerEndpointKey(AddressEndpointWithLocationKey fromKey) {
+        return new PeerEndpointKey(fromKey.getAddress(), fromKey.getAddressType(), fromKey.getContextId(),
                 fromKey.getContextType());
     }
 
index 25c9db47bf2f604cd059627cad79e2e3f3395398..e4665e9f19aa920e62d561dddbd90562ab6f8a3c 100644 (file)
@@ -8,12 +8,14 @@
 
 package org.opendaylight.groupbasedpolicy.renderer.vpp.policy;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Strings;
+import com.google.common.util.concurrent.MoreExecutors;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
-
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -70,8 +72,8 @@ 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.endpoints.AddressEndpointWithLocationKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicy;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroup;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroupBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRuleBuilder;
@@ -98,10 +100,6 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Strings;
-import com.google.common.util.concurrent.MoreExecutors;
-
 @RunWith(MockitoJUnitRunner.class)
 public class VppRendererPolicyManagerTest extends CustomDataBrokerTest {
 
@@ -403,25 +401,25 @@ public class VppRendererPolicyManagerTest extends CustomDataBrokerTest {
                 Stream.concat(consumers.stream(), providers.stream()).collect(Collectors.toList());
         Endpoints endpoints = new EndpointsBuilder().setAddressEndpointWithLocation(eps).build();
         List<RendererEndpoint> consumersAsRendererEps = consumers.stream().map(cons -> {
-            List<PeerEndpointWithPolicy> peers = providers.stream()
-                .map(web -> new PeerEndpointWithPolicyBuilder()
-                    .setKey(KeyFactory.peerEndpointWithPolicyKey(web.getKey()))
+            List<PeerEndpoint> peers = providers.stream()
+                .map(web -> new PeerEndpointBuilder()
+                    .setKey(KeyFactory.peerEndpointKey(web.getKey()))
                     .setRuleGroupWithRendererEndpointParticipation(Arrays.asList(RULE_GROUP_WITH_CONSUMER))
                     .build())
                 .collect(Collectors.toList());
             return new RendererEndpointBuilder().setKey(KeyFactory.rendererEndpointKey(cons.getKey()))
-                .setPeerEndpointWithPolicy(peers)
+                .setPeerEndpoint(peers)
                 .build();
         }).collect(Collectors.toList());
         List<RendererEndpoint> providersAsRendererEps = providers.stream().map(prov -> {
-            List<PeerEndpointWithPolicy> peers = consumers.stream()
-                .map(client -> new PeerEndpointWithPolicyBuilder()
-                    .setKey(KeyFactory.peerEndpointWithPolicyKey(client.getKey()))
+            List<PeerEndpoint> peers = consumers.stream()
+                .map(client -> new PeerEndpointBuilder()
+                    .setKey(KeyFactory.peerEndpointKey(client.getKey()))
                     .setRuleGroupWithRendererEndpointParticipation(Arrays.asList(RULE_GROUP_WITH_PROVIDER))
                     .build())
                 .collect(Collectors.toList());
             return new RendererEndpointBuilder().setKey(KeyFactory.rendererEndpointKey(prov.getKey()))
-                .setPeerEndpointWithPolicy(peers)
+                .setPeerEndpoint(peers)
                 .build();
         }).collect(Collectors.toList());
         List<RendererEndpoint> rendererEps = Stream