Bug 3302: fix for GroupTable 61/27261/1
authorKonstantin Blagov <kblagov@cisco.com>
Thu, 27 Aug 2015 10:37:58 +0000 (12:37 +0200)
committerKonstantin Blagov <kblagov@cisco.com>
Tue, 22 Sep 2015 09:03:58 +0000 (09:03 +0000)
Change-Id: I38065618e28e0ff88fc50cd3c950549049cf04eb
Signed-off-by: Konstantin Blagov <kblagov@cisco.com>
32 files changed:
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/OfWriter.java [new file with mode: 0755]
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/PolicyManager.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/equivalence/BucketsEquivalence.java [new file with mode: 0755]
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/equivalence/EquivalenceFabric.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/equivalence/FlowEquivalence.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/equivalence/GroupEquivalence.java [new file with mode: 0755]
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/equivalence/MatchEquivalence.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/ChainActionFlows.java [changed mode: 0644->0755]
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/DestinationMapper.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/EgressNatMapper.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/ExternalMapper.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowTable.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowUtils.java [changed mode: 0644->0755]
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/GroupTable.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/IngressNatMapper.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/OfTable.java [changed mode: 0644->0755]
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/PolicyEnforcer.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/PortSecurity.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/SourceMapper.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/Action.java [changed mode: 0644->0755]
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/AllowAction.java [changed mode: 0644->0755]
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ChainAction.java [changed mode: 0644->0755]
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/DestinationMapperTest.java
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/EgressNatMapperTest.java [changed mode: 0644->0755]
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/ExternalMapperTest.java [changed mode: 0644->0755]
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowTableTest.java
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/GroupTableTest.java
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/IngressNatMapperTest.java [changed mode: 0644->0755]
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/PolicyEnforcerTest.java
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/PortSecurityTest.java
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/SourceMapperTest.java
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ChainActionTest.java [changed mode: 0644->0755]

diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/OfWriter.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/OfWriter.java
new file mode 100755 (executable)
index 0000000..ecbde44
--- /dev/null
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 2015 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.ofoverlay;
+
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.createGroupPath;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.createNodePath;
+
+import javax.annotation.Nullable;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+
+import com.google.common.base.Equivalence;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Sets;
+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.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.ofoverlay.equivalence.EquivalenceFabric;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+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.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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OfWriter {
+
+    private final ConcurrentMap<InstanceIdentifier<Table>, TableBuilder> flowMap =
+            new ConcurrentHashMap<>();
+    private final ConcurrentMap<InstanceIdentifier<Group>, GroupBuilder> groupByIid =
+            new ConcurrentHashMap<>();
+    private final ConcurrentMap<NodeId, Set<GroupId>> groupIdsByNode = new ConcurrentHashMap<>();
+
+    private static final Logger LOG = LoggerFactory.getLogger(OfWriter.class);
+
+    public Table getTableForNode(NodeId nodeId, short tableId) {
+        return getTableBuilderForNode(nodeId, tableId).build();
+    }
+
+    private TableBuilder getTableBuilderForNode(NodeId nodeId, short tableId) {
+        InstanceIdentifier<Table> tableIid = FlowUtils.createTablePath(nodeId, tableId);
+        if (this.flowMap.get(tableIid) == null) {
+            this.flowMap.put(tableIid,
+                    new TableBuilder().setId(tableId).setFlow(new ArrayList<Flow>()));
+        }
+        return this.flowMap.get(tableIid);
+    }
+
+    public boolean groupExists(NodeId nodeId, long groupId) {
+        return (getGroupForNode(nodeId, groupId) != null);
+    }
+
+    /**
+     * Gets group (or null if group does not exist) for node
+     *
+     * @param nodeId  NodeId
+     * @param groupId long
+     * @return Group or null
+     */
+    private Group getGroupForNode(NodeId nodeId, long groupId) {
+        InstanceIdentifier<Group> giid = FlowUtils.createGroupPath(nodeId, groupId);
+        if (this.groupByIid.get(giid) == null) {
+            return null;
+        }
+        return this.groupByIid.get(giid).build();
+    }
+
+    /**
+     * Short form of {@link #writeGroup(NodeId, GroupId, GroupTypes, String, String, Boolean)} with default parameters:<br>
+     * groupTypes = {@code GroupTypes.GroupAll}<br>
+     * containerName = null<br>
+     * groupName = null<br>
+     * barrier = null
+     *
+     * @param nodeId     NodeId
+     * @param groupId    GroupId
+     * @see OfWriter#writeGroup(NodeId, GroupId, GroupTypes, String, String, Boolean)
+     */
+    public void writeGroup(NodeId nodeId, GroupId groupId) {
+        writeGroup(nodeId, groupId, GroupTypes.GroupAll, null, null, null);
+    }
+
+    /**
+     * Writes a new group for OVS
+     *
+     * @param nodeId        NodeId
+     * @param groupId       GroupId
+     * @param groupTypes    GroupTypes
+     * @param containerName String
+     * @param groupName     String
+     * @param barrier       Boolean
+     */
+    public void writeGroup(NodeId nodeId, GroupId groupId, @Nullable GroupTypes groupTypes,
+            @Nullable String containerName, @Nullable String groupName,
+            @Nullable Boolean barrier) {
+        Preconditions.checkNotNull(nodeId);
+        Preconditions.checkNotNull(groupId);
+
+        GroupBuilder gb = new GroupBuilder().setGroupId(groupId)
+                .setBarrier(barrier)
+                .setContainerName(containerName)
+                .setGroupName(groupName)
+                .setGroupType(groupTypes)
+                .setBuckets(new BucketsBuilder().setBucket(new ArrayList<Bucket>()).build());
+
+        groupByIid.put(FlowUtils.createGroupPath(nodeId, groupId), gb);
+        if (this.groupIdsByNode.get(nodeId) == null) {
+            this.groupIdsByNode.put(nodeId, new HashSet<GroupId>());
+        }
+        this.groupIdsByNode.get(nodeId).add(groupId);
+    }
+
+    /**
+     * Writes a Bucket to Group.<br>
+     * Group has to be created previously,<br>
+     * or an IllegalStateException will be thrown.
+     *
+     * @param nodeId  NodeId
+     * @param groupId GroupId
+     * @param bucket  Bucket to be added to group
+     * @throws IllegalStateException if the Group is absent
+     * @see #writeGroup(NodeId, GroupId, GroupTypes, String, String, Boolean)
+     * @see #writeGroup(NodeId, GroupId)
+     */
+    public void writeBucket(NodeId nodeId, GroupId groupId, Bucket bucket) {
+        Preconditions.checkNotNull(nodeId);
+        Preconditions.checkNotNull(groupId);
+        Preconditions.checkNotNull(bucket);
+
+        GroupBuilder gb = groupByIid.get(FlowUtils.createGroupPath(nodeId, groupId));
+        if (gb != null) {
+            gb.getBuckets().getBucket().add(bucket);
+        } else {
+            LOG.error("Group {} on node {} does not exist", groupId, nodeId);
+            throw new IllegalStateException();
+        }
+    }
+
+    public void writeFlow(NodeId nodeId, short tableId, Flow flow) {
+        Preconditions.checkNotNull(flow);
+        Preconditions.checkNotNull(nodeId);
+
+        TableBuilder tableBuilder = this.getTableBuilderForNode(nodeId, tableId);
+        // transforming List<Flow> to Set (with customized equals/hashCode) to eliminate duplicate entries
+        List<Flow> flows = tableBuilder.getFlow();
+        Set<Equivalence.Wrapper<Flow>> wrappedFlows = new HashSet<>(
+                Collections2.transform(flows, EquivalenceFabric.FLOW_WRAPPER_FUNCTION));
+
+        Equivalence.Wrapper<Flow> wFlow = EquivalenceFabric.FLOW_EQUIVALENCE.wrap(flow);
+
+        if (!wrappedFlows.contains(wFlow)) {
+            tableBuilder.getFlow().add(flow);
+        } else {
+            LOG.debug("Flow already exists in OfData - {}", flow);
+        }
+    }
+
+    public void commitToDataStore(DataBroker dataBroker) {
+        if (dataBroker != null) {
+
+            for (NodeId nodeId : groupIdsByNode.keySet()) {
+                try {
+                    updateGroups(dataBroker, nodeId);
+                } catch (ExecutionException | InterruptedException e) {
+                    LOG.error("Could not update Group table on node {}", nodeId);
+                }
+            }
+
+            for (Map.Entry<InstanceIdentifier<Table>, TableBuilder> entry : flowMap.entrySet()) {
+                try {
+                    /*
+                     * Get the currently configured flows for
+                     * this table.
+                     */
+                    updateFlowTable(dataBroker, entry);
+                } catch (Exception e) {
+                    LOG.warn("Couldn't read flow table {}", entry.getKey());
+                }
+            }
+        }
+    }
+
+    private void updateFlowTable(DataBroker dataBroker,
+            Map.Entry<InstanceIdentifier<Table>, TableBuilder> entry)
+            throws ExecutionException, InterruptedException {
+        // flows to update
+        Set<Flow> update = new HashSet<>(entry.getValue().getFlow());
+        // flows currently in the table
+        Set<Flow> curr = new HashSet<>();
+
+        final InstanceIdentifier<Table> tableIid = entry.getKey();
+        ReadWriteTransaction t = dataBroker.newReadWriteTransaction();
+        Optional<Table> r = t.read(LogicalDatastoreType.CONFIGURATION, tableIid).get();
+
+        if (r.isPresent()) {
+            Table currentTable = r.get();
+            curr = new HashSet<>(currentTable.getFlow());
+        }
+
+        // Sets with custom equivalence rules
+        Set<Equivalence.Wrapper<Flow>> oldFlows = new HashSet<>(
+                Collections2.transform(curr, EquivalenceFabric.FLOW_WRAPPER_FUNCTION));
+        Set<Equivalence.Wrapper<Flow>> updatedFlows = new HashSet<>(
+                Collections2.transform(update, EquivalenceFabric.FLOW_WRAPPER_FUNCTION));
+
+        // what is still there but was not updated, needs to be deleted
+        Sets.SetView<Equivalence.Wrapper<Flow>> deletions = Sets.difference(oldFlows, updatedFlows);
+        // new flows (they were not there before)
+        Sets.SetView<Equivalence.Wrapper<Flow>> additions = Sets.difference(updatedFlows, oldFlows);
+
+        if (!deletions.isEmpty()) {
+            for (Equivalence.Wrapper<Flow> wf : deletions) {
+                Flow f = wf.get();
+                if (f != null) {
+                    t.delete(LogicalDatastoreType.CONFIGURATION,
+                            FlowUtils.createFlowPath(tableIid, f.getId()));
+                }
+            }
+        }
+        if (!additions.isEmpty()) {
+            for (Equivalence.Wrapper<Flow> wf : additions) {
+                Flow f = wf.get();
+                if (f != null) {
+                    t.put(LogicalDatastoreType.CONFIGURATION,
+                            FlowUtils.createFlowPath(tableIid, f.getId()), f, true);
+                }
+            }
+        }
+        CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();
+        Futures.addCallback(f, new FutureCallback<Void>() {
+
+            @Override
+            public void onFailure(Throwable t) {
+                LOG.error("Could not write flow table {}: {}", tableIid, t);
+            }
+
+            @Override
+            public void onSuccess(Void result) {
+                LOG.debug("Flow table {} updated.", tableIid);
+            }
+        });
+    }
+
+    private void updateGroups(DataBroker dataBroker, final NodeId nodeId)
+            throws ExecutionException, InterruptedException {
+
+        if (this.groupIdsByNode.get(nodeId) == null) {
+            this.groupIdsByNode.put(nodeId, new HashSet<GroupId>());
+        }
+        Set<GroupId> createdGroupIds = new HashSet<>(this.groupIdsByNode.get(nodeId));
+        // groups from inner structure
+        Set<Group> createdGroups = new HashSet<>();
+        for (GroupId gid : createdGroupIds) {
+            Group g = getGroupForNode(nodeId, gid.getValue());
+            if (g != null) {
+                createdGroups.add(g);
+            }
+        }
+        // groups from datastore
+        Set<Group> existingGroups = new HashSet<>();
+        ReadWriteTransaction t = dataBroker.newReadWriteTransaction();
+        FlowCapableNode fcn = null;
+        InstanceIdentifier<FlowCapableNode> fcniid =
+                createNodePath(nodeId).builder().augmentation(FlowCapableNode.class).build();
+        Optional<FlowCapableNode> r = t.read(LogicalDatastoreType.OPERATIONAL, fcniid).get();
+        if (!r.isPresent()) {
+            LOG.warn("Node {} is not present", fcniid);
+            return;
+        }
+        fcn = r.get();
+
+        if (fcn.getGroup() != null) {
+            existingGroups = new HashSet<>(fcn.getGroup());
+        }
+
+        Set<Equivalence.Wrapper<Group>> existingGroupsWrap = new HashSet<>(
+                Collections2.transform(existingGroups, EquivalenceFabric.GROUP_WRAPPER_FUNCTION));
+        Set<Equivalence.Wrapper<Group>> createdGroupsWrap = new HashSet<>(
+                Collections2.transform(createdGroups, EquivalenceFabric.GROUP_WRAPPER_FUNCTION));
+
+        Sets.SetView<Equivalence.Wrapper<Group>> deletions =
+                Sets.difference(existingGroupsWrap, createdGroupsWrap);
+        Sets.SetView<Equivalence.Wrapper<Group>> additions =
+                Sets.difference(createdGroupsWrap, existingGroupsWrap);
+
+        if (!deletions.isEmpty()) {
+            for (Equivalence.Wrapper<Group> groupWrapper : deletions) {
+                Group g = groupWrapper.get();
+                if (g != null) {
+                    LOG.debug("Deleting group {} on node {}", g.getGroupId(), nodeId);
+                    t.delete(LogicalDatastoreType.CONFIGURATION,
+                            createGroupPath(nodeId, g.getGroupId()));
+                }
+            }
+        }
+        if (!additions.isEmpty()) {
+            for (Equivalence.Wrapper<Group> groupWrapper : additions) {
+                Group g = groupWrapper.get();
+                if (g != null) {
+                    LOG.debug("Putting node {}, group {}", nodeId, g.getGroupId());
+                    t.put(LogicalDatastoreType.CONFIGURATION,
+                            createGroupPath(nodeId, g.getGroupId()), g, true);
+                }
+            }
+        }
+
+        CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();
+        Futures.addCallback(f, new FutureCallback<Void>() {
+
+            @Override
+            public void onFailure(Throwable t) {
+                LOG.error("Could not write group table on node {}: {}", nodeId, t);
+            }
+
+            @Override
+            public void onSuccess(Void result) {
+                LOG.debug("Group table on node {} updated.", nodeId);
+            }
+        });
+    }
+
+}
index 0e0a1d4e236ea7a99991a03f1314a006d0a33a1e..5e5b660654aa13a357ff8f8447ff4253bb51d27a 100755 (executable)
@@ -9,27 +9,28 @@
 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay;
 
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CompletionService;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorCompletionService;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.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.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.groupbasedpolicy.endpoint.EpKey;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.equivalence.EquivalenceFabric;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.DestinationMapper;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.EgressNatMapper;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.ExternalMapper;
@@ -51,8 +52,6 @@ import org.opendaylight.groupbasedpolicy.resolver.PolicyResolver;
 import org.opendaylight.groupbasedpolicy.resolver.PolicyScope;
 import org.opendaylight.groupbasedpolicy.util.SingletonTask;
 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.groupbasedpolicy.common.rev140421.ActionDefinitionId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayConfig.LearningMode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.SubjectFeatureDefinitions;
@@ -62,19 +61,6 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Equivalence;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.AsyncFunction;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
 /**
  * Manage policies on switches by subscribing to updates from the
  * policy resolver and information about endpoints from the endpoint
@@ -360,116 +346,6 @@ public class PolicyManager
     // Implementation
     // **************
 
-    public class FlowMap{
-        private ConcurrentMap<InstanceIdentifier<Table>, TableBuilder> flowMap = new ConcurrentHashMap<>();
-
-        public FlowMap() {
-        }
-
-        public TableBuilder getTableForNode(NodeId nodeId, short tableId) {
-            InstanceIdentifier<Table> tableIid = FlowUtils.createTablePath(nodeId, tableId);
-            if(this.flowMap.get(tableIid) == null) {
-                this.flowMap.put(tableIid, new TableBuilder().setId(tableId));
-                this.flowMap.get(tableIid).setFlow(new ArrayList<Flow>());
-            }
-            return this.flowMap.get(tableIid);
-        }
-
-        public void writeFlow(NodeId nodeId, short tableId, Flow flow) {
-            TableBuilder tableBuilder = this.getTableForNode(nodeId, tableId);
-            // transforming List<Flow> to Set (with customized equals/hashCode) to eliminate duplicate entries
-            List<Flow> flows = tableBuilder.getFlow();
-            Set<Equivalence.Wrapper<Flow>> wrappedFlows =
-                    new HashSet<>(Collections2.transform(flows, EquivalenceFabric.FLOW_WRAPPER_FUNCTION));
-
-            Equivalence.Wrapper<Flow> wFlow = EquivalenceFabric.FLOW_EQUIVALENCE.wrap(flow);
-
-            if (!wrappedFlows.contains(wFlow)) {
-                tableBuilder.getFlow().add(Preconditions.checkNotNull(flow));
-            } else {
-                LOG.debug("Flow already exists in FlowMap - {}", flow);
-            }
-        }
-
-        public void commitToDataStore() {
-            if (dataBroker != null) {
-                for( Entry<InstanceIdentifier<Table>, TableBuilder> entry : flowMap.entrySet()) {
-                    try {
-                        /*
-                         * Get the currently configured flows for
-                         * this table.
-                         */
-                        updateFlowTable(entry);
-                    } catch (Exception e) {
-                        LOG.warn("Couldn't read flow table {}", entry.getKey());
-                    }
-                }
-            }
-        }
-
-        private void updateFlowTable(Entry<InstanceIdentifier<Table>,
-                                     TableBuilder> entry)  throws Exception {
-            // flows to update
-            Set<Flow> update = new HashSet<>(entry.getValue().getFlow());
-            // flows currently in the table
-            Set<Flow> curr = new HashSet<>();
-
-            ReadWriteTransaction t = dataBroker.newReadWriteTransaction();
-            Optional<Table> r =
-                   t.read(LogicalDatastoreType.CONFIGURATION, entry.getKey()).get();
-
-            if (r.isPresent()) {
-                Table currentTable = r.get();
-                curr = new HashSet<>(currentTable.getFlow());
-            }
-
-            // Sets with custom equivalence rules
-            Set<Equivalence.Wrapper<Flow>> oldFlows =
-                    new HashSet<>(Collections2.transform(curr, EquivalenceFabric.FLOW_WRAPPER_FUNCTION));
-            Set<Equivalence.Wrapper<Flow>> updatedFlows =
-                    new HashSet<>(Collections2.transform(update, EquivalenceFabric.FLOW_WRAPPER_FUNCTION));
-
-            // what is still there but was not updated, needs to be deleted
-            Sets.SetView<Equivalence.Wrapper<Flow>> deletions =
-                    Sets.difference(oldFlows, updatedFlows);
-            // new flows (they were not there before)
-            Sets.SetView<Equivalence.Wrapper<Flow>> additions =
-                    Sets.difference(updatedFlows, oldFlows);
-
-            if (!deletions.isEmpty()) {
-                for (Equivalence.Wrapper<Flow> wf: deletions) {
-                    Flow f = wf.get();
-                    if (f != null) {
-                        t.delete(LogicalDatastoreType.CONFIGURATION,
-                                FlowUtils.createFlowPath(entry.getKey(), f.getId()));
-                    }
-                }
-            }
-            if (!additions.isEmpty()) {
-                for (Equivalence.Wrapper<Flow> wf: additions) {
-                    Flow f = wf.get();
-                    if (f != null) {
-                        t.put(LogicalDatastoreType.CONFIGURATION,
-                                FlowUtils.createFlowPath(entry.getKey(), f.getId()), f, true);
-                    }
-                }
-            }
-            CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();
-            Futures.addCallback(f, new FutureCallback<Void>() {
-                @Override
-                public void onFailure(Throwable t) {
-                    LOG.error("Could not write flow table {}", t);
-                }
-
-                @Override
-                public void onSuccess(Void result) {
-                    LOG.debug("Flow table updated.");
-                }
-            });
-        }
-
-    }
-
     private void scheduleUpdate() {
         if (switchManager != null) {
             LOG.trace("Scheduling flow update task");
@@ -481,11 +357,11 @@ public class PolicyManager
      * Update the flows on a particular switch
      */
     private class SwitchFlowUpdateTask implements Callable<Void> {
-        private FlowMap flowMap;
+        private OfWriter ofWriter;
 
-        public SwitchFlowUpdateTask(FlowMap flowMap) {
+        public SwitchFlowUpdateTask(OfWriter ofWriter) {
             super();
-            this.flowMap = flowMap;
+            this.ofWriter = ofWriter;
         }
 
         @Override
@@ -496,9 +372,9 @@ public class PolicyManager
                     return null;
                 for (OfTable table : flowPipeline) {
                     try {
-                        table.update(node, info, flowMap);
+                        table.update(node, info, ofWriter);
                     } catch (Exception e) {
-                        LOG.error("Failed to write flow table {}",
+                        LOG.error("Failed to write Openflow table {}",
                                 table.getClass().getSimpleName(), e);
                     }
                 }
@@ -520,16 +396,16 @@ public class PolicyManager
                 = new ExecutorCompletionService<>(executor);
             int n = 0;
 
-            FlowMap flowMap = new FlowMap();
+            OfWriter ofWriter = new OfWriter();
 
-            SwitchFlowUpdateTask swut = new SwitchFlowUpdateTask(flowMap);
+            SwitchFlowUpdateTask swut = new SwitchFlowUpdateTask(ofWriter);
             ecs.submit(swut);
             n+=1;
 
             for (int i = 0; i < n; i++) {
                 try {
                     ecs.take().get();
-                    flowMap.commitToDataStore();
+                    ofWriter.commitToDataStore(dataBroker);
                 } catch (InterruptedException | ExecutionException e) {
                     LOG.error("Failed to update flow tables", e);
                 }
diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/equivalence/BucketsEquivalence.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/equivalence/BucketsEquivalence.java
new file mode 100755 (executable)
index 0000000..c597ca8
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2015 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.ofoverlay.equivalence;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import com.google.common.base.Equivalence;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
+
+/**
+ * Custom Equivalence for {@link Buckets}
+ *
+ * @see GroupEquivalence
+ */
+public class BucketsEquivalence extends Equivalence<Buckets> {
+
+    BucketsEquivalence() {
+    }
+
+    @Override
+    protected boolean doEquivalent(Buckets a, Buckets b) {
+
+        Set<Bucket> setA = new HashSet<>();
+        Set<Bucket> setB = new HashSet<>();
+        if (a.getBucket() != null) {
+            setA = new HashSet<>(a.getBucket());
+        }
+        if (b.getBucket() != null) {
+            setB = new HashSet<>(b.getBucket());
+        }
+        return setA.equals(setB);
+    }
+
+    @Override
+    protected int doHash(Buckets buckets) {
+
+        final int prime = 31;
+        int result = 1;
+        List<Bucket> bucketList = buckets.getBucket();
+        Set<Bucket> bucketSet = new HashSet<>();
+        if (bucketList != null) {
+            bucketSet = new HashSet<>(bucketList);
+        }
+        result = prime * result + bucketSet.hashCode();
+
+        return result;
+    }
+
+}
index c7e33efa223038a5c65540e61236d68c97922100..ffd84892bcd923c085cc758189415e7545605d04 100755 (executable)
@@ -8,26 +8,30 @@
 
 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.equivalence;
 
+import javax.annotation.Nullable;
+
 import com.google.common.base.Equivalence;
 import com.google.common.base.Function;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
-
-import javax.annotation.Nullable;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
 
 /**
- * A simple fabric for equivalence rules
- * and for functions used in converting Lists to Sets with our own equivalence rules
- *
+ * A simple fabric for equivalence rules and for functions used<br>
+ *     in converting Lists to Sets with our own equivalence rules
  */
 public class EquivalenceFabric {
 
-    private EquivalenceFabric(){
+    private EquivalenceFabric() {
         throw new UnsupportedOperationException("Can not create an instance");
     }
 
+    // Flow
     public static final FlowEquivalence FLOW_EQUIVALENCE = new FlowEquivalence();
+    public static final MatchEquivalence MATCH_EQUIVALENCE = new MatchEquivalence();
+
     public static final Function<Flow, Equivalence.Wrapper<Flow>> FLOW_WRAPPER_FUNCTION =
             new Function<Flow, Equivalence.Wrapper<Flow>>() {
+
                 @Nullable
                 @Override
                 public Equivalence.Wrapper<Flow> apply(@Nullable Flow input) {
@@ -35,6 +39,18 @@ public class EquivalenceFabric {
                 }
             };
 
-    public static final MatchEquivalence MATCH_EQUIVALENCE = new MatchEquivalence();
+    // Group
+    public static final BucketsEquivalence BUCKETS_EQUIVALENCE = new BucketsEquivalence();
+    public static final GroupEquivalence GROUP_EQUIVALENCE = new GroupEquivalence();
+
+    public static final Function<Group, Equivalence.Wrapper<Group>> GROUP_WRAPPER_FUNCTION =
+            new Function<Group, Equivalence.Wrapper<Group>>() {
+
+                @Nullable
+                @Override
+                public Equivalence.Wrapper<Group> apply(@Nullable Group input) {
+                    return GROUP_EQUIVALENCE.wrap(input);
+                }
+            };
 
 }
index 08a3cdd092847bf162f1febf2ede2464c7ad93ac..ed1186eddd90f6fcd07b5c7ac650e49a7d59af2b 100755 (executable)
@@ -19,7 +19,7 @@ import java.util.Objects;
 import java.util.Set;
 
 /**
- * Custom Equivalence for Flow
+ * Custom {@link Equivalence} for {@link Flow}
  *
  */
 public class FlowEquivalence extends Equivalence<Flow> {
@@ -58,7 +58,7 @@ public class FlowEquivalence extends Equivalence<Flow> {
             setA = new HashSet<>(listA);
         }
         List<Instruction> listB = new ArrayList<>();
-        if (a.getInstructions() != null) {
+        if (b.getInstructions() != null) {
             listB = b.getInstructions().getInstruction();
         }
         Set<Instruction> setB = new HashSet<>();
diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/equivalence/GroupEquivalence.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/equivalence/GroupEquivalence.java
new file mode 100755 (executable)
index 0000000..adf54a2
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015 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.ofoverlay.equivalence;
+
+import java.util.Objects;
+
+import com.google.common.base.Equivalence;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+
+public class GroupEquivalence extends Equivalence<Group> {
+
+    GroupEquivalence() {
+    }
+
+    @Override
+    protected boolean doEquivalent(Group a, Group b) {
+
+        if (!EquivalenceFabric.BUCKETS_EQUIVALENCE.equivalent(a.getBuckets(), b.getBuckets())) {
+            return false;
+        }
+
+        if (!Objects.equals(a.getContainerName(), b.getContainerName())) {
+            return false;
+        }
+
+        if (!Objects.equals(a.getGroupName(), b.getGroupName())) {
+            return false;
+        }
+
+        if (!Objects.equals(a.getGroupType(), b.getGroupType())) {
+            return false;
+        }
+
+        if (!Objects.equals(a.isBarrier(), b.isBarrier())) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    protected int doHash(Group group) {
+        final int prime = 31;
+        int result = 1;
+
+        result = prime * result + ((group.getBuckets() == null) ? 0
+                : EquivalenceFabric.BUCKETS_EQUIVALENCE.wrap(group.getBuckets()).hashCode());
+        result = prime * result + ((group.getContainerName() == null) ? 0
+                : group.getContainerName().hashCode());
+        result = prime * result + ((group.getGroupName() == null) ? 0
+                : group.getGroupName().hashCode());
+        result = prime * result + ((group.getGroupType() == null) ? 0
+                : group.getGroupType().hashCode());
+        result = prime * result + ((group.isBarrier() == null) ? 0 : group.isBarrier().hashCode());
+
+        return result;
+    }
+}
index f75962ff5613ab683df352c1cf1febac2a878e54..5d0385a213c4a0b9bc60a8481d3dae9e75a98a04 100755 (executable)
@@ -19,7 +19,7 @@ import java.util.Objects;
 import java.util.Set;
 
 /**
- * Custom Equivalence for Match
+ * Custom {@link Equivalence} for {@link Match}
  *
  * @see FlowEquivalence
  */
old mode 100644 (file)
new mode 100755 (executable)
index 80f8f43..94ca973
@@ -19,7 +19,7 @@ import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtil
 import java.math.BigInteger;
 
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.PolicyEnforcer.NetworkElements;
@@ -51,7 +51,7 @@ public class ChainActionFlows {
 
     }
 
-    public static void createChainTunnelFlows(SfcNshHeader sfcNshHeader, NetworkElements netElements, FlowMap flowMap,
+    public static void createChainTunnelFlows(SfcNshHeader sfcNshHeader, NetworkElements netElements, OfWriter ofWriter,
             OfContext ctx) {
 
         NodeId localNodeId = netElements.getLocalNodeId();
@@ -65,25 +65,25 @@ public class ChainActionFlows {
                     destNodeId);
             return;
         }
-        flowMap.writeFlow(localNodeId, ctx.getPolicyManager().getTABLEID_PORTSECURITY(),
+        ofWriter.writeFlow(localNodeId, ctx.getPolicyManager().getTABLEID_PORTSECURITY(),
                 allowFromChainPort(localNodeTunPort, ctx.getPolicyManager().getTABLEID_PORTSECURITY(), ctx));
 
-        flowMap.writeFlow(localNodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER(),
+        ofWriter.writeFlow(localNodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER(),
                 allowFromChainTunnel(localNodeTunPort, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()));
 
-        flowMap.writeFlow(
+        ofWriter.writeFlow(
                 localNodeId,
                 ctx.getPolicyManager().getTABLEID_EXTERNAL_MAPPER(),
                 createExternalFlow(sfcNshHeader, localNodeTunPort, netElements, ctx.getPolicyManager()
                     .getTABLEID_EXTERNAL_MAPPER(), ctx));
 
-        flowMap.writeFlow(
+        ofWriter.writeFlow(
                 destNodeId,
                 ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER(),
                 createChainTunnelFlow(sfcNshHeader, destNodeTunPort, epOrds, ctx.getPolicyManager()
                     .getTABLEID_SOURCE_MAPPER(), ctx));
 
-        flowMap.writeFlow(
+        ofWriter.writeFlow(
                 destNodeId,
                 ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER(),
                 createChainBroadcastFlow(sfcNshHeader, destNodeTunPort, epOrds, ctx.getPolicyManager()
index c6d1cf1c5a82e104778345001a5a2d9829fceb3a..7cbfd2b1b234b6d62155e51bbbf5227c92010278 100755 (executable)
@@ -16,8 +16,8 @@ import com.google.common.collect.Sets;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.groupbasedpolicy.endpoint.EpKey;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
 import org.opendaylight.groupbasedpolicy.resolver.EgKey;
@@ -30,7 +30,6 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
 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;
@@ -39,7 +38,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.M
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
@@ -57,7 +55,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Subnet;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
@@ -93,7 +90,6 @@ import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtil
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.IPv6;
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxRegMatch;
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns;
-import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.createNodePath;
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.decNwTtlAction;
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ethernetMatch;
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.getOfPortNum;
@@ -148,11 +144,11 @@ public class DestinationMapper extends FlowTable {
     }
 
     @Override
-    public void sync(NodeId nodeId, PolicyInfo policyInfo, FlowMap flowMap) throws Exception {
+    public void sync(NodeId nodeId, PolicyInfo policyInfo, OfWriter ofWriter) throws Exception {
 
         TenantId currentTenant = null;
 
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
+        ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
 
         SetMultimap<EpKey, EpKey> visitedEps = HashMultimap.create();
         Set<EndpointFwdCtxOrdinals> epOrdSet = new HashSet<>();
@@ -177,7 +173,7 @@ public class DestinationMapper extends FlowTable {
                         if (visitedEps.get(srcEpKey) != null && visitedEps.get(srcEpKey).contains(peerEpKey)) {
                             continue;
                         }
-                        syncEP(flowMap, nodeId, policyInfo, srcEp, peerEp);
+                        syncEP(ofWriter, nodeId, policyInfo, srcEp, peerEp);
                         visitedEps.put(srcEpKey, peerEpKey);
 
                         // Process subnets and flood-domains for epPeer
@@ -205,7 +201,7 @@ public class DestinationMapper extends FlowTable {
                 Flow arpFlow = createRouterArpFlow(currentTenant, nodeId, sn,
                         OrdinalFactory.getContextOrdinal(currentTenant, l3c.getId()));
                 if (arpFlow != null) {
-                    flowMap.writeFlow(nodeId, TABLE_ID, arpFlow);
+                    ofWriter.writeFlow(nodeId, TABLE_ID, arpFlow);
                 } else {
                     LOG.debug(
                             "Gateway ARP flow is not created, because virtual router IP has not been set for subnet {} .",
@@ -216,8 +212,8 @@ public class DestinationMapper extends FlowTable {
 
         // Write broadcast flows per flood domain.
         for (EndpointFwdCtxOrdinals epOrd : epOrdSet) {
-            if (groupExists(nodeId, epOrd.getFdId())) {
-                flowMap.writeFlow(nodeId, TABLE_ID, createBroadcastFlow(epOrd));
+            if (ofWriter.groupExists(nodeId, Integer.valueOf(epOrd.getFdId()).longValue())) {
+                ofWriter.writeFlow(nodeId, TABLE_ID, createBroadcastFlow(epOrd));
             }
         }
 
@@ -233,7 +229,7 @@ public class DestinationMapper extends FlowTable {
                 for (Subnet localSubnet: localSubnets) {
                     Flow prefixFlow = createL3PrefixFlow(prefixEp, policyInfo, nodeId, localSubnet);
                     if (prefixFlow != null) {
-                        flowMap.writeFlow(nodeId, TABLE_ID, prefixFlow);
+                        ofWriter.writeFlow(nodeId, TABLE_ID, prefixFlow);
                         LOG.trace("Wrote L3Prefix flow");
                     }
                 }
@@ -417,11 +413,10 @@ public class DestinationMapper extends FlowTable {
 
     private Flow createBroadcastFlow(EndpointFwdCtxOrdinals epOrd) {
         MatchBuilder mb = new MatchBuilder()
-                            .setEthernetMatch(new EthernetMatchBuilder()
-                            .setEthernetDestination(new EthernetDestinationBuilder().
-                                                        setAddress(MULTICAST_MAC)
-                                                        .setMask(MULTICAST_MAC).build())
-                            .build());
+                .setEthernetMatch(new EthernetMatchBuilder().setEthernetDestination(
+                        new EthernetDestinationBuilder().setAddress(MULTICAST_MAC)
+                                .setMask(MULTICAST_MAC)
+                                .build()).build());
         addNxRegMatch(mb, RegMatch.of(NxmNxReg5.class, Long.valueOf(epOrd.getFdId())));
 
         Match match = mb.build();
@@ -436,32 +431,6 @@ public class DestinationMapper extends FlowTable {
         return flowb.build();
     }
 
-    private boolean groupExists(NodeId nodeId, Integer fdId) throws Exception {
-        // Fetch existing GroupTables
-        if (ctx.getDataBroker() == null) {
-            return false;
-        }
-
-        ReadOnlyTransaction t = ctx.getDataBroker().newReadOnlyTransaction();
-        InstanceIdentifier<Node> niid = createNodePath(nodeId);
-        Optional<Node> r = t.read(LogicalDatastoreType.CONFIGURATION, niid).get();
-        if (!r.isPresent())
-            return false;
-        FlowCapableNode fcn = r.get().getAugmentation(FlowCapableNode.class);
-        if (fcn == null)
-            return false;
-
-        if (fcn.getGroup() != null) {
-            for (Group g : fcn.getGroup()) {
-                if (g.getGroupId().getValue().equals(Long.valueOf(fdId))) { // Group
-                                                                            // Exists.
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
     private MacAddress routerPortMac(L3Context l3c, IpAddress ipAddress) {
 
         if (ctx.getDataBroker() == null) {
@@ -607,7 +576,7 @@ public class DestinationMapper extends FlowTable {
         return flowb.build();
     }
 
-    private void syncEP(FlowMap flowMap, NodeId nodeId, PolicyInfo policyInfo, Endpoint srcEp, Endpoint destEp)
+    private void syncEP(OfWriter ofWriter, NodeId nodeId, PolicyInfo policyInfo, Endpoint srcEp, Endpoint destEp)
             throws Exception {
 
         if (ctx.getPolicyResolver().getTenant(srcEp.getTenant()) == null
@@ -662,7 +631,7 @@ public class DestinationMapper extends FlowTable {
             // port
 
             if (srcEpFwdCtxOrds.getBdId() == destEpFwdCtxOrds.getBdId()) {
-                flowMap.writeFlow(nodeId, TABLE_ID, createLocalL2Flow(destEp, destEpFwdCtxOrds, ofc));
+                ofWriter.writeFlow(nodeId, TABLE_ID, createLocalL2Flow(destEp, destEpFwdCtxOrds, ofc));
             }
             // TODO Li alagalah: Need to move to EndpointL3 for L3 processing.
             // The Endpoint conflation must end!
@@ -680,7 +649,7 @@ public class DestinationMapper extends FlowTable {
                     for (Subnet localSubnet : localSubnets) {
                         Flow flow = createLocalL3RoutedFlow(destEp, l3a, destEpFwdCtxOrds, ofc, localSubnet);
                         if (flow != null) {
-                            flowMap.writeFlow(nodeId, TABLE_ID, flow);
+                            ofWriter.writeFlow(nodeId, TABLE_ID, flow);
                         } else {
                             LOG.trace("Did not write remote L3 flow for endpoint {} and subnet {}", l3a.getIpAddress(),
                                     localSubnet.getIpPrefix().getValue());
@@ -694,7 +663,7 @@ public class DestinationMapper extends FlowTable {
             if (srcEpFwdCtxOrds.getBdId() == destEpFwdCtxOrds.getBdId()) {
                 Flow remoteL2Flow = createRemoteL2Flow(destEp, nodeId, srcEpFwdCtxOrds, destEpFwdCtxOrds, ofc);
                 if (remoteL2Flow != null) {
-                    flowMap.writeFlow(nodeId, TABLE_ID, remoteL2Flow);
+                    ofWriter.writeFlow(nodeId, TABLE_ID, remoteL2Flow);
                 }
             } else {
                 LOG.trace("DestinationMapper: RemoteL2Flow: not created, in different BDs src: {} dst: {}",
@@ -717,7 +686,7 @@ public class DestinationMapper extends FlowTable {
                         Flow remoteL3Flow = createRemoteL3RoutedFlow(destEp, l3a, nodeId, srcEpFwdCtxOrds,
                                 destEpFwdCtxOrds, ofc, localSubnet);
                         if (remoteL3Flow != null) {
-                            flowMap.writeFlow(nodeId, TABLE_ID, remoteL3Flow);
+                            ofWriter.writeFlow(nodeId, TABLE_ID, remoteL3Flow);
                         } else {
                             LOG.trace("Did not write remote L3 flow for endpoint {} and subnet {}", l3a.getIpAddress(),
                                     localSubnet.getIpPrefix().getValue());
index d62512d55818332285df0725a0038586afea8f8e..efedab591ac65633108c003b0ddc29cd7b6d9dda 100755 (executable)
@@ -19,8 +19,8 @@ import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtil
 import java.util.Collection;
 import java.util.List;
 
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
@@ -65,8 +65,8 @@ public class EgressNatMapper extends FlowTable {
     }
 
     @Override
-    public void sync(NodeId nodeId, PolicyInfo policyInfo, FlowMap flowMap) throws Exception {
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
+    public void sync(NodeId nodeId, PolicyInfo policyInfo, OfWriter ofWriter) throws Exception {
+        ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
 
         Collection<EndpointL3> l3Endpoints = ctx.getEndpointManager().getL3EndpointsWithNat();
         for (EndpointL3 l3Ep : l3Endpoints) {
@@ -74,7 +74,7 @@ public class EgressNatMapper extends FlowTable {
             if (flow==null) {
                 continue;
             }
-            flowMap.writeFlow(nodeId, TABLE_ID, flow);
+            ofWriter.writeFlow(nodeId, TABLE_ID, flow);
         }
     }
 
index d2d23662d1ceb1c348db21748064cb5410bbe4b2..bcd73bcc916c282acaf6f744412f080e083db564 100755 (executable)
@@ -12,26 +12,13 @@ import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtil
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.instructions;
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxOutputRegAction;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.Action;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.AllowAction;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.SubjectFeatures;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlanGpe;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -56,20 +43,20 @@ public class ExternalMapper extends FlowTable {
     }
 
     @Override
-    public void sync(NodeId nodeId, PolicyInfo policyInfo, FlowMap flowMap) throws Exception {
+    public void sync(NodeId nodeId, PolicyInfo policyInfo, OfWriter ofWriter) throws Exception {
 
         if (ctx.getSwitchManager().getExternalPorts(nodeId) == null) {
             LOG.trace("No external ports found for node: {}", nodeId);
             return;
         }
         // Default drop all
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
+        ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
 
         /*
          *  Default Egress flow. Other methods may write to this table to augment egress
          *  functionality, such as bypassing/utilising the NAT table, or ServiceFunctionChaining
          */
-        flowMap.writeFlow(nodeId, TABLE_ID, defaultFlow());
+        ofWriter.writeFlow(nodeId, TABLE_ID, defaultFlow());
 
     }
 
index 522935ea005044b80ec0adbbd31715c4c49a9666..bd8ed8b7cb0c86f1305eabe78b977dd926d4a26a 100755 (executable)
@@ -8,8 +8,8 @@
 
 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
 
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
@@ -38,9 +38,9 @@ public abstract class FlowTable extends OfTable {
 
     @Override
     public void update(NodeId nodeId, PolicyInfo policyInfo,
-                       FlowMap flowMap) throws Exception {
+                       OfWriter ofWriter) throws Exception {
 
-        sync(nodeId, policyInfo, flowMap);
+        sync(nodeId, policyInfo, ofWriter);
 
     }
 
@@ -52,7 +52,7 @@ public abstract class FlowTable extends OfTable {
      * Sync flow state using the flow map
      * @throws Exception
      */
-    public abstract void sync(NodeId nodeId, PolicyInfo policyInfo, FlowMap flowMap) throws Exception;
+    public abstract void sync(NodeId nodeId, PolicyInfo policyInfo, OfWriter ofWriter) throws Exception;
 
     /**
      * Get the table ID being manipulated
old mode 100644 (file)
new mode 100755 (executable)
index 3c68563..0eac888
@@ -225,6 +225,10 @@ public final class FlowUtils {
             .build();
     }
 
+    public static InstanceIdentifier<Group> createGroupPath(final NodeId nodeId, final Long groupId) {
+        return createGroupPath(nodeId, new GroupId(groupId));
+    }
+
     /**
      * Creates a group path from a node ID and group ID
      *
index 1ba0fc5b92c64b3dd36517fd966377c7e42d2b8b..99b07671dc0ea0989b7c8eb2100df788b9c8fe3d 100644 (file)
@@ -9,22 +9,19 @@
 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
 
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.actionList;
-import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.createBucketPath;
-import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.createGroupPath;
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.createNodePath;
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.getOfPortNum;
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadTunIPv4Action;
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.outputAction;
 
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.concurrent.ExecutionException;
 
+import com.google.common.base.Optional;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
 import org.opendaylight.groupbasedpolicy.resolver.EgKey;
 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
@@ -33,191 +30,106 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId;
 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.Buckets;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.BucketsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.EndpointLocation.LocationType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import com.google.common.collect.Ordering;
-
 /**
  * Manage the group tables for handling broadcast/multicast
- *
  */
 
 public class GroupTable extends OfTable {
-    private static final Logger LOG =
-            LoggerFactory.getLogger(GroupTable.class);
+
+    private static final Logger LOG = LoggerFactory.getLogger(GroupTable.class);
 
     public GroupTable(OfContext ctx) {
         super(ctx);
     }
 
-    // @Override
+    FlowCapableNode getFCNodeFromDatastore(NodeId nodeId)
+            throws ExecutionException, InterruptedException {
+        FlowCapableNode fcn = null;
+        ReadOnlyTransaction t = ctx.getDataBroker().newReadOnlyTransaction();
+        InstanceIdentifier<FlowCapableNode> fcniid = createNodePath(nodeId).builder()
+                .augmentation(FlowCapableNode.class).build();
+
+        Optional<FlowCapableNode> r = t.read(LogicalDatastoreType.OPERATIONAL, fcniid).get();
+        if (!r.isPresent()) {
+            LOG.warn("Node {} is not present", fcniid);
+            return null;
+        }
+        fcn = r.get();
+        t.close();
+        return fcn;
+    }
+
     @Override
-    public void update(NodeId nodeId, PolicyInfo policyInfo, FlowMap flowMap)
-            throws Exception {
+    public void update(NodeId nodeId, PolicyInfo policyInfo, OfWriter ofWriter) throws Exception {
         // there appears to be no way of getting only the existing group
         // tables unfortunately, so we have to get the whole goddamned node.
         // Since this is happening concurrently with other things that are
         // working in subtrees of nodes, we have to do two transactions
-        ReadOnlyTransaction t = ctx.getDataBroker().newReadOnlyTransaction();
-        InstanceIdentifier<Node> niid = createNodePath(nodeId);
-        Optional<Node> r =
-                t.read(LogicalDatastoreType.OPERATIONAL, niid).get();
-        if (!r.isPresent())
-            return;
-        FlowCapableNode fcn = r.get().getAugmentation(FlowCapableNode.class);
+        FlowCapableNode fcn = getFCNodeFromDatastore(nodeId);
         if (fcn == null)
             return;
 
-        HashMap<GroupId, GroupCtx> groupMap = new HashMap<>();
-
-        if (fcn.getGroup() != null) {
-            for (Group g : fcn.getGroup()) {
-                GroupCtx gctx = new GroupCtx(g.getGroupId());
-                groupMap.put(g.getGroupId(), gctx);
-
-                Buckets bs = g.getBuckets();
-                if (bs != null && bs.getBucket() != null)
-                    for (Bucket b : bs.getBucket()) {
-                        gctx.bucketMap.put(b.getBucketId(), new BucketCtx(b));
-                    }
-            }
-        }
-
-        // sync(nodeId, policyInfo, dirty, groupMap);
-        sync(nodeId, policyInfo, groupMap);
-
-        WriteTransaction wt = ctx.getDataBroker().newWriteOnlyTransaction();
-        boolean wrote = syncGroupToStore(wt, nodeId, groupMap);
-        if (wrote)
-            wt.submit().get();
+        sync(nodeId, policyInfo, ofWriter);
     }
 
-    protected boolean syncGroupToStore(WriteTransaction wt,
-            NodeId nodeId,
-            HashMap<GroupId, GroupCtx> groupMap) {
-        boolean wrote = false;
-        for (GroupCtx gctx : groupMap.values()) {
-            InstanceIdentifier<Group> giid =
-                    createGroupPath(nodeId, gctx.groupId);
-            if (!gctx.visited) {
-                // Remove group table
-                wrote = true;
-                wt.delete(LogicalDatastoreType.CONFIGURATION, giid);
-            } else {
-                ArrayList<Bucket> buckets = new ArrayList<>();
+    public void sync(NodeId nodeId, PolicyInfo policyInfo, OfWriter ofWriter) throws Exception {
 
-                // update group table
-                for (BucketCtx bctx : gctx.bucketMap.values()) {
-                    BucketId bid;
-                    if (bctx.b != null)
-                        bid = bctx.b.getBucketId();
-                    else
-                        bid = bctx.newb.getBucketId();
-                    InstanceIdentifier<Bucket> biid =
-                            createBucketPath(nodeId,
-                                    gctx.groupId,
-                                    bid);
-                    if (!bctx.visited) {
-                        // remove bucket
-                        wrote = true;
-                        wt.delete(LogicalDatastoreType.CONFIGURATION, biid);
-                    } else if (bctx.b == null) {
-                        // new bucket
-                        buckets.add(bctx.newb);
-                    } else if (!Objects.equal(bctx.newb.getAction(),
-                            Ordering.from(ActionComparator.INSTANCE)
-                                    .sortedCopy(bctx.b.getAction()))) {
-                        // update bucket
-                        buckets.add(bctx.newb);
-                    }
-                }
-                if (buckets.size() > 0) {
-                    GroupBuilder gb = new GroupBuilder()
-                            .setGroupId(gctx.groupId)
-                            .setGroupType(GroupTypes.GroupAll)
-                            .setBuckets(new BucketsBuilder()
-                                    .setBucket(buckets)
-                                    .build());
-                    wrote = true;
-                    wt.merge(LogicalDatastoreType.CONFIGURATION,
-                            giid, gb.build(), true);
-                }
+        for (Endpoint localEp : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
+            EndpointFwdCtxOrdinals localEpFwdCtxOrds =
+                    OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, localEp);
+            if (localEpFwdCtxOrds == null) {
+                LOG.debug("getEndpointFwdCtxOrdinals is null for EP {}", localEp);
+                continue;
             }
-        }
-        return wrote;
-    }
-
-    protected void sync(NodeId nodeId, PolicyInfo policyInfo, HashMap<GroupId, GroupCtx> groupMap) throws Exception {
 
+            GroupId gid = new GroupId(Long.valueOf(localEpFwdCtxOrds.getFdId()));
+            if (!ofWriter.groupExists(nodeId, gid.getValue())) {
+                LOG.info("createGroup {} {}", nodeId, gid);
+                ofWriter.writeGroup(nodeId, gid);
+            }
 
-            for (Endpoint localEp : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
-                EndpointFwdCtxOrdinals localEpFwdCtxOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, localEp);
-                if (localEpFwdCtxOrds == null) {
-                    LOG.debug("getEndpointFwdCtxOrdinals is null for EP {}", localEp);
-                    continue;
-                }
+            for (EgKey epg : ctx.getEndpointManager().getGroupsForNode(nodeId)) {
+
+                // we'll use the fdId with the high bit set for remote bucket
+                // and just the local port number for local bucket
+                for (NodeId destNode : ctx.getEndpointManager().getNodesForGroup(epg)) {
+                    if (nodeId.equals(destNode))
+                        continue;
+
+                    long bucketId = OrdinalFactory.getContextOrdinal(destNode);
+                    bucketId |= 1L << 31;
+
+                    IpAddress tunDst = ctx.getSwitchManager().getTunnelIP(destNode, TunnelTypeVxlan.class);
+                    NodeConnectorId tunPort = ctx.getSwitchManager().getTunnelPort(nodeId, TunnelTypeVxlan.class);
+                    if (tunDst == null || tunPort == null)
+                        continue;
+                    Action tundstAction = null;
+                    if (tunDst.getIpv4Address() != null) {
+                        String nextHop = tunDst.getIpv4Address().getValue();
+                        tundstAction = nxLoadTunIPv4Action(nextHop, true);
+                    } else {
+                        LOG.error("IPv6 tunnel destination {} for {} not supported", tunDst.getIpv6Address().getValue(),
+                                destNode);
+                        continue;
+                    }
+                    BucketBuilder bb = new BucketBuilder().setBucketId(new BucketId(Long.valueOf(bucketId)))
+                            .setAction(actionList(tundstAction, outputAction(tunPort)));
 
-                GroupId gid = new GroupId(Long.valueOf(localEpFwdCtxOrds.getFdId()));
-                GroupCtx gctx = groupMap.get(gid);
-                if (gctx == null) {
-                    groupMap.put(gid, gctx = new GroupCtx(gid));
+                    ofWriter.writeBucket(nodeId, gid, bb.build());
                 }
-                gctx.visited = true;
-
-                for (EgKey epg : ctx.getEndpointManager().getGroupsForNode(nodeId)) {
-
-
-                    // we'll use the fdId with the high bit set for remote bucket
-                    // and just the local port number for local bucket
-                    for (NodeId destNode : ctx.getEndpointManager().getNodesForGroup(epg)) {
-                        if (nodeId.equals(destNode))
-                            continue;
-
-                        long bucketId = OrdinalFactory.getContextOrdinal(destNode);
-                        bucketId |= 1L << 31;
-
-                        IpAddress tunDst =
-                                ctx.getSwitchManager().getTunnelIP(destNode, TunnelTypeVxlan.class);
-                        NodeConnectorId tunPort =
-                                ctx.getSwitchManager().getTunnelPort(nodeId, TunnelTypeVxlan.class);
-                        if (tunDst == null || tunPort == null)
-                            continue;
-                        Action tundstAction = null;
-                        if (tunDst.getIpv4Address() != null) {
-                            String nextHop = tunDst.getIpv4Address().getValue();
-                            tundstAction = nxLoadTunIPv4Action(nextHop, true);
-                        } else {
-                            LOG.error("IPv6 tunnel destination {} for {} not supported",
-                                    tunDst.getIpv6Address().getValue(),
-                                    destNode);
-                            continue;
-                        }
-                    BucketBuilder bb = new BucketBuilder().setBucketId(new BucketId(Long.valueOf(bucketId))).setAction(actionList(tundstAction, outputAction(tunPort)));
-
-
-
-                        updateBucket(gctx, bb);
-                    }
-                OfOverlayContext ofc =
-                        localEp.getAugmentation(OfOverlayContext.class);
+                OfOverlayContext ofc = localEp.getAugmentation(OfOverlayContext.class);
                 if (ofc == null || ofc.getNodeConnectorId() == null ||
                         (LocationType.External.equals(ofc.getLocationType())))
                     continue;
@@ -226,49 +138,16 @@ public class GroupTable extends OfTable {
                 try {
                     bucketId = getOfPortNum(ofc.getNodeConnectorId());
                 } catch (NumberFormatException e) {
-                    LOG.warn("Could not parse port number {}",
-                            ofc.getNodeConnectorId(), e);
+                    LOG.warn("Could not parse port number {}", ofc.getNodeConnectorId(), e);
                     continue;
                 }
 
                 Action output = outputAction(ofc.getNodeConnectorId());
-                BucketBuilder bb = new BucketBuilder()
-                        .setBucketId(new BucketId(Long.valueOf(bucketId)))
+                BucketBuilder bb = new BucketBuilder().setBucketId(new BucketId(Long.valueOf(bucketId)))
                         .setAction(actionList(output));
-                updateBucket(gctx, bb);
+                ofWriter.writeBucket(nodeId, gid, bb.build());
             }
         }
     }
 
-    private static void updateBucket(GroupCtx gctx, BucketBuilder bb) {
-        BucketCtx bctx = gctx.bucketMap.get(bb.getBucketId());
-        if (bctx == null) {
-            gctx.bucketMap.put(bb.getBucketId(),
-                    bctx = new BucketCtx(null));
-        }
-        bctx.visited = true;
-        bctx.newb = bb.build();
-    }
-
-    protected static class BucketCtx {
-        Bucket b;
-        Bucket newb;
-        boolean visited = false;
-
-        public BucketCtx(Bucket b) {
-            super();
-            this.b = b;
-        }
-    }
-
-    protected static class GroupCtx {
-        GroupId groupId;
-        Map<BucketId, BucketCtx> bucketMap = new HashMap<>();
-        boolean visited = false;
-
-        public GroupCtx(GroupId groupId) {
-            super();
-            this.groupId = groupId;
-        }
-    }
 }
index 228820f95393eccd5e1064e89d7f038d17ff31da..eac99d8ec15e2ac95414e926e9962a4e6ac3fb94 100755 (executable)
@@ -9,7 +9,6 @@
 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
 
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ARP;
-import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxRegMatch;
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns;
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ethernetMatch;
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.gotoTableIns;
@@ -33,9 +32,8 @@ import java.util.Collection;
 import java.util.List;
 
 import org.opendaylight.groupbasedpolicy.endpoint.EpKey;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
@@ -47,13 +45,9 @@ 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.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.groupbasedpolicy.common.rev140421.TenantId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.napt.translations.fields.napt.translations.NaptTranslation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3Context;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Subnet;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
@@ -90,9 +84,9 @@ public class IngressNatMapper extends FlowTable {
     }
 
     @Override
-    public void sync(NodeId nodeId, PolicyInfo policyInfo, FlowMap flowMap) throws Exception {
+    public void sync(NodeId nodeId, PolicyInfo policyInfo, OfWriter ofWriter) throws Exception {
 
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
+        ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
 
         // TODO Bug 3546 - Difficult: External port is unrelated to Tenant, L3C, L2BD..
 
@@ -102,13 +96,13 @@ public class IngressNatMapper extends FlowTable {
             if (l3Ep.getL2Context() != null && l3Ep.getMacAddress() !=null ) {
                 Endpoint ep = ctx.getEndpointManager().getEndpoint(new EpKey(l3Ep.getL2Context(), l3Ep.getMacAddress()));
                 if (endpointsForNode.contains(ep)) {
-                    createNatFlow(l3Ep, nodeId, flowMap, policyInfo);
+                    createNatFlow(l3Ep, nodeId, ofWriter, policyInfo);
                 }
             }
         }
     }
 
-    private void createNatFlow(EndpointL3 l3Ep, NodeId nodeId, FlowMap flowMap, PolicyInfo policyInfo) throws Exception {
+    private void createNatFlow(EndpointL3 l3Ep, NodeId nodeId, OfWriter ofWriter, PolicyInfo policyInfo) throws Exception {
         List<NaptTranslation> naptAugL3Endpoint = ctx.getEndpointManager().getNaptAugL3Endpoint(l3Ep);
         // Match on L3 Nat Augmentation in Destination, set to IPAddress/Mac, send to SourceMapper
         if (naptAugL3Endpoint == null) {
@@ -126,11 +120,11 @@ public class IngressNatMapper extends FlowTable {
 
             flow = buildNatFlow(nat.getIpAddress(), l3Ep.getIpAddress(), l3Ep.getMacAddress(), epFwdCtxOrds);
             if (flow != null) {
-                flowMap.writeFlow(nodeId, TABLE_ID, flow);
+                ofWriter.writeFlow(nodeId, TABLE_ID, flow);
             }
             flow = createOutsideArpFlow(nat.getIpAddress(), l3Ep.getMacAddress(), nodeId);
             if (flow != null) {
-                flowMap.writeFlow(nodeId, TABLE_ID, flow);
+                ofWriter.writeFlow(nodeId, TABLE_ID, flow);
             }
             break;
         }
old mode 100644 (file)
new mode 100755 (executable)
index a2ccc1a..50b4701
@@ -8,8 +8,8 @@
 
 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
 
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.slf4j.Logger;
@@ -41,10 +41,10 @@ public abstract class OfTable {
      * Update the relevant flow table for the node
      * @param nodeId the node to update
      * @param policyInfo
-     * @param flowMap
+     * @param ofWriter
      * @throws Exception
      */
     public abstract void update(NodeId nodeId,
                                 PolicyInfo policyInfo,
-                                FlowMap flowMap) throws Exception;
+                                OfWriter ofWriter) throws Exception;
 }
index 90e2ad52d63a57196c2ef8b8d84a3f10c622e7da..a6608b68de3cbbde820cd04f1d0b59a3feceb634 100755 (executable)
@@ -26,8 +26,8 @@ import java.util.Set;
 
 import javax.annotation.concurrent.Immutable;
 
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.Action;
@@ -109,13 +109,13 @@ public class PolicyEnforcer extends FlowTable {
     }
 
     @Override
-    public void sync(NodeId nodeId, PolicyInfo policyInfo, FlowMap flowMap) throws Exception {
+    public void sync(NodeId nodeId, PolicyInfo policyInfo, OfWriter ofWriter) throws Exception {
 
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
+        ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
 
         NodeConnectorId tunPort = ctx.getSwitchManager().getTunnelPort(nodeId, TunnelTypeVxlan.class);
         if (tunPort != null) {
-            flowMap.writeFlow(nodeId, TABLE_ID, allowFromTunnel(tunPort));
+            ofWriter.writeFlow(nodeId, TABLE_ID, allowFromTunnel(tunPort));
         }
 
         HashSet<PolicyPair> visitedPairs = new HashSet<>();
@@ -173,7 +173,7 @@ public class PolicyEnforcer extends FlowTable {
                                         srcEp.getKey(), dstEp.getKey());
                                 visitedPairs.add(policyPair);
                             }
-                            syncPolicy(flowMap, netElements, activeRulesByConstraints.getValue(), policyPair);
+                            syncPolicy(ofWriter, netElements, activeRulesByConstraints.getValue(), policyPair);
                         }
 
                         // Reverse
@@ -197,7 +197,7 @@ public class PolicyEnforcer extends FlowTable {
                                 visitedReversePairs.add(policyPair);
 
                             }
-                            syncPolicy(flowMap, netElements, activeRulesByConstraints.getValue(), policyPair);
+                            syncPolicy(ofWriter, netElements, activeRulesByConstraints.getValue(), policyPair);
                         }
                     }
                 }
@@ -231,8 +231,8 @@ public class PolicyEnforcer extends FlowTable {
 
                             int depgId = dstEpFwdCxtOrds.getEpgId();
                             int sepgId = srcEpFwdCxtOrds.getEpgId();
-                            flowMap.writeFlow(nodeId, TABLE_ID, allowSameEpg(sepgId, depgId));
-                            flowMap.writeFlow(nodeId, TABLE_ID, allowSameEpg(depgId, sepgId));
+                            ofWriter.writeFlow(nodeId, TABLE_ID, allowSameEpg(sepgId, depgId));
+                            ofWriter.writeFlow(nodeId, TABLE_ID, allowSameEpg(depgId, sepgId));
                         }
                     }
                 }
@@ -241,7 +241,7 @@ public class PolicyEnforcer extends FlowTable {
 
         // Write ARP flows per flood domain.
         for (Integer fdId : fdIds) {
-            flowMap.writeFlow(nodeId, TABLE_ID, createArpFlow(fdId));
+            ofWriter.writeFlow(nodeId, TABLE_ID, createArpFlow(fdId));
         }
     }
 
@@ -293,14 +293,14 @@ public class PolicyEnforcer extends FlowTable {
 
     }
 
-    private void syncPolicy(FlowMap flowMap, NetworkElements netElements, List<RuleGroup> rgs, PolicyPair policyPair) {
+    private void syncPolicy(OfWriter ofWriter, NetworkElements netElements, List<RuleGroup> rgs, PolicyPair policyPair) {
         int priority = 65000;
         for (RuleGroup rg : rgs) {
             TenantId tenantId = rg.getContractTenant().getId();
             IndexedTenant tenant = ctx.getPolicyResolver().getTenant(tenantId);
             for (Rule r : rg.getRules()) {
-                syncDirection(flowMap, netElements, tenant, policyPair, r, Direction.In, priority);
-                syncDirection(flowMap, netElements, tenant, policyPair, r, Direction.Out, priority);
+                syncDirection(ofWriter, netElements, tenant, policyPair, r, Direction.In, priority);
+                syncDirection(ofWriter, netElements, tenant, policyPair, r, Direction.Out, priority);
 
                 priority -= 1;
             }
@@ -327,7 +327,7 @@ public class PolicyEnforcer extends FlowTable {
 
     }
 
-    private void syncDirection(FlowMap flowMap, NetworkElements netElements, IndexedTenant contractTenant,
+    private void syncDirection(OfWriter ofWriter, NetworkElements netElements, IndexedTenant contractTenant,
             PolicyPair policyPair, Rule rule, Direction direction, int priority) {
 
 
@@ -449,7 +449,8 @@ public class PolicyEnforcer extends FlowTable {
                  * Convert the GBP Action to one or more OpenFlow Actions
                  */
                 if (!(actionRefList.indexOf(actionRule) == (actionRefList.size() - 1) && action.equals(SubjectFeatures.getAction(AllowAction.DEFINITION.getId())))) {
-                    actionBuilderList = action.updateAction(actionBuilderList, params, actionRule.getOrder(), netElements, policyPair, flowMap, ctx, direction);
+                    actionBuilderList = action.updateAction(actionBuilderList, params, actionRule.getOrder(), netElements, policyPair,
+                            ofWriter, ctx, direction);
                 }
 
             }
@@ -474,7 +475,7 @@ public class PolicyEnforcer extends FlowTable {
             } else {
                 flow.setInstructions(instructions(applyActionIns(actionBuilderList), getGotoExternalInstruction()));
             }
-            flowMap.writeFlow(netElements.getLocalNodeId(), TABLE_ID, flow.build());
+            ofWriter.writeFlow(netElements.getLocalNodeId(), TABLE_ID, flow.build());
         }
     }
 
index 5e6991387126399618805d4bbf457d3413d65dc9..d828cbe2f4110f4877caf08a360c2b75a4953b2a 100755 (executable)
@@ -8,12 +8,10 @@
 
 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
 
-import java.util.Collection;
 import java.util.Set;
 
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
-import org.opendaylight.groupbasedpolicy.resolver.EgKey;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
@@ -57,12 +55,12 @@ public class PortSecurity extends FlowTable {
     }
 
     @Override
-    public void sync(NodeId nodeId, PolicyInfo policyInfo, FlowMap flowMap) {
+    public void sync(NodeId nodeId, PolicyInfo policyInfo, OfWriter ofWriter) {
 
         // Allow traffic from tunnel ports
         NodeConnectorId tunnelIf = ctx.getSwitchManager().getTunnelPort(nodeId, TunnelTypeVxlan.class);
         if (tunnelIf != null)
-            flowMap.writeFlow(nodeId, TABLE_ID, allowFromPort(tunnelIf));
+            ofWriter.writeFlow(nodeId, TABLE_ID, allowFromPort(tunnelIf));
 
         // Allow traffic from tunnel ports
         //TODO Bug 3546 - Difficult: External port is unrelated to Tenant, L3C, L2BD..
@@ -70,16 +68,16 @@ public class PortSecurity extends FlowTable {
         Set<NodeConnectorId> external =
                 ctx.getSwitchManager().getExternalPorts(nodeId);
         for (NodeConnectorId extIf : external) {
-            flowMap.writeFlow(nodeId, TABLE_ID, allowFromExternalPort(extIf));
+            ofWriter.writeFlow(nodeId, TABLE_ID, allowFromExternalPort(extIf));
         }
 
         // Default drop all
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
+        ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
 
         // Drop IP traffic that doesn't match a source IP rule
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(110), FlowUtils.ARP, TABLE_ID));
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(111), FlowUtils.IPv4, TABLE_ID));
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(112), FlowUtils.IPv6, TABLE_ID));
+        ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(110), FlowUtils.ARP, TABLE_ID));
+        ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(111), FlowUtils.IPv4, TABLE_ID));
+        ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(112), FlowUtils.IPv6, TABLE_ID));
 
         for (Endpoint ep : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
             OfOverlayContext ofc = ep.getAugmentation(OfOverlayContext.class);
@@ -88,13 +86,13 @@ public class PortSecurity extends FlowTable {
                     && (ofc.getLocationType() == null || LocationType.Internal.equals(ofc.getLocationType()))) {
                 // Allow layer 3 traffic (ARP and IP) with the correct
                 // source IP, MAC, and source port
-                l3flow(flowMap, nodeId, ep, ofc, 120, false);
-                l3flow(flowMap, nodeId, ep, ofc, 121, true);
-                flowMap.writeFlow(nodeId, TABLE_ID, l3DhcpDoraFlow(ep, ofc, 115));
+                l3flow(ofWriter, nodeId, ep, ofc, 120, false);
+                l3flow(ofWriter, nodeId, ep, ofc, 121, true);
+                ofWriter.writeFlow(nodeId, TABLE_ID, l3DhcpDoraFlow(ep, ofc, 115));
 
                 // Allow layer 2 traffic with the correct source MAC and
                 // source port (note lower priority than drop IP rules)
-                flowMap.writeFlow(nodeId, TABLE_ID, l2flow(ep, ofc, 100));
+                ofWriter.writeFlow(nodeId, TABLE_ID, l2flow(ep, ofc, 100));
             }
         }
     }
@@ -168,7 +166,7 @@ public class PortSecurity extends FlowTable {
         return flow;
     }
 
-    private void l3flow(FlowMap flowMap, NodeId nodeId,
+    private void l3flow(OfWriter ofWriter, NodeId nodeId,
                         Endpoint ep, OfOverlayContext ofc,
                         Integer priority, boolean arp) {
         if (ep.getL3Address() == null)
@@ -219,7 +217,7 @@ public class PortSecurity extends FlowTable {
                     .setInstructions(FlowUtils.gotoTableInstructions(ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER()))
                     .build();
 
-            flowMap.writeFlow(nodeId, TABLE_ID,flow);
+            ofWriter.writeFlow(nodeId, TABLE_ID,flow);
         }
     }
 }
index fda93f5cd15c1e0c9fe58b839f30c5f95d770574..e3032813b8f7a736f3be1aedee9090a1a8a4a8da 100755 (executable)
@@ -19,11 +19,10 @@ import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtil
 import java.math.BigInteger;
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
 
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
 import org.opendaylight.groupbasedpolicy.resolver.EgKey;
 import org.opendaylight.groupbasedpolicy.resolver.IndexedTenant;
@@ -36,8 +35,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.M
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.EndpointLocation.LocationType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
@@ -75,9 +72,9 @@ public class SourceMapper extends FlowTable {
     }
 
     @Override
-    public void sync(NodeId nodeId, PolicyInfo policyInfo, FlowMap flowMap) throws Exception {
+    public void sync(NodeId nodeId, PolicyInfo policyInfo, OfWriter ofWriter) throws Exception {
 
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
+        ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
 
         // Handle case where packets from from External
         for (Endpoint ep : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
@@ -93,7 +90,7 @@ public class SourceMapper extends FlowTable {
                 continue;
             }
 
-            createRemoteTunnels(flowMap, nodeId, ep, policyInfo, epFwdCtxOrds);
+            createRemoteTunnels(ofWriter, nodeId, ep, policyInfo, epFwdCtxOrds);
 
             if (ep.getTenant() == null || (ep.getEndpointGroup() == null && ep.getEndpointGroups() == null)) {
                 continue;
@@ -104,12 +101,12 @@ public class SourceMapper extends FlowTable {
                 /**
                  * Sync the local EP information.
                  */
-                syncEP(flowMap, nodeId, ep, ofc.getNodeConnectorId(), epFwdCtxOrds);
+                syncEP(ofWriter, nodeId, ep, ofc.getNodeConnectorId(), epFwdCtxOrds);
             }
         }
     }
 
-    private void createRemoteTunnels(FlowMap flowMap, NodeId nodeId, Endpoint ep, PolicyInfo policyInfo,
+    private void createRemoteTunnels(OfWriter ofWriter, NodeId nodeId, Endpoint ep, PolicyInfo policyInfo,
             EndpointFwdCtxOrdinals epFwdCtxOrds) throws Exception {
         Set<EgKey> epgs = new HashSet<>();
 
@@ -138,8 +135,8 @@ public class SourceMapper extends FlowTable {
                                 nodeId.getValue(), remoteNodeId.getValue());
                         continue;
                     }
-                    flowMap.writeFlow(remoteNodeId, TABLE_ID, createTunnelFlow(tunPort, epFwdCtxOrds));
-                    flowMap.writeFlow(remoteNodeId, TABLE_ID, createBroadcastFlow(tunPort, epFwdCtxOrds));
+                    ofWriter.writeFlow(remoteNodeId, TABLE_ID, createTunnelFlow(tunPort, epFwdCtxOrds));
+                    ofWriter.writeFlow(remoteNodeId, TABLE_ID, createBroadcastFlow(tunPort, epFwdCtxOrds));
                 }
             }
         }
@@ -212,7 +209,7 @@ public class SourceMapper extends FlowTable {
         return flowb.build();
     }
 
-    private void syncEP(FlowMap flowMap, NodeId nodeId, Endpoint ep, NodeConnectorId ncId, EndpointFwdCtxOrdinals epFwdCtxOrds) throws Exception {
+    private void syncEP(OfWriter ofWriter, NodeId nodeId, Endpoint ep, NodeConnectorId ncId, EndpointFwdCtxOrdinals epFwdCtxOrds) throws Exception {
 
         // TODO alagalah Li/Be: We should also match on EndpointL3 with the appropriate
         // network containment. This would solve a lot of problems and prepare for EndpointL3 RPC.
@@ -241,7 +238,7 @@ public class SourceMapper extends FlowTable {
             .setInstructions(
                     instructions(applyActionIns(segReg, scgReg, bdReg, fdReg, vrfReg,tunIdAction),
                             gotoTableIns(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));
-        flowMap.writeFlow(nodeId, TABLE_ID, flowb.build());
+        ofWriter.writeFlow(nodeId, TABLE_ID, flowb.build());
     }
 
 }
old mode 100644 (file)
new mode 100755 (executable)
index f87d266..bbc6242
@@ -12,7 +12,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.PolicyEnforcer.NetworkElements;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.PolicyEnforcer.PolicyPair;
 import org.opendaylight.groupbasedpolicy.resolver.ActionInstanceValidator;
@@ -53,7 +53,7 @@ public abstract class Action implements ActionInstanceValidator{
                                                      Integer order,
                                                      NetworkElements netElements,
                                                      PolicyPair policyPair,
-                                                     FlowMap flowMap,
+                                                     OfWriter ofWriter,
                                                      OfContext ctx,
                                                      Direction direction);
 }
old mode 100644 (file)
new mode 100755 (executable)
index d82c1bd..9e6cafa
@@ -14,7 +14,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.PolicyEnforcer.NetworkElements;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.PolicyEnforcer.PolicyPair;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
@@ -61,7 +61,7 @@ public class AllowAction extends Action {
                                             Integer order,
                                             NetworkElements netElements,
                                             PolicyPair policyPair,
-                                            FlowMap flowMap,
+                                            OfWriter ofWriter,
                                             OfContext ctx,
                                             Direction direction) {
         /*
old mode 100644 (file)
new mode 100755 (executable)
index 07c60b5..43adcb0
@@ -25,15 +25,13 @@ import java.util.Map;
 
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.PolicyEnforcer.NetworkElements;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.PolicyEnforcer.PolicyPair;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sfcutils.SfcIidFactory;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sfcutils.SfcNshHeader;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sfcutils.SfcNshHeader.SfcNshHeaderBuilder;
-import org.opendaylight.groupbasedpolicy.resolver.EgKey;
 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
 import org.opendaylight.sfc.provider.api.SfcProviderRenderedPathAPI;
 import org.opendaylight.sfc.provider.api.SfcProviderServiceChainAPI;
@@ -52,7 +50,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.Parameter.IsRequired;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.Parameter.Type;
@@ -113,7 +110,7 @@ public class ChainAction extends Action {
 
     @Override
     public List<ActionBuilder> updateAction(List<ActionBuilder> actions, Map<String, Object> params, Integer order,
-            NetworkElements netElements, PolicyPair policyPair, FlowMap flowMap, OfContext ctx, Direction direction) {
+            NetworkElements netElements, PolicyPair policyPair, OfWriter ofWriter, OfContext ctx, Direction direction) {
         /*
          * Get the named chain
          */
@@ -222,7 +219,7 @@ public class ChainAction extends Action {
         // chained packets.
         actions = addActionBuilder(actions, nxSetNsiAction(sfcNshHeader.getNshNsiToChain()), order);
         actions = addActionBuilder(actions, nxSetNspAction(sfcNshHeader.getNshNspToChain()), order);
-        createChainTunnelFlows(sfcNshHeader, netElements, flowMap, ctx);
+        createChainTunnelFlows(sfcNshHeader, netElements, ofWriter, ctx);
         return actions;
     }
 
index 85b231dc126eef07dc8dfa6fb146e3a255705f8c..7e0adcc62a45e3949628a689122b303418cc904e 100755 (executable)
@@ -15,9 +15,8 @@ import java.util.List;
 import java.util.Objects;\r
 \r
 import org.junit.Before;\r
-import org.junit.Ignore;\r
 import org.junit.Test;\r
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;\r
@@ -64,14 +63,14 @@ public class DestinationMapperTest extends FlowTableTest {
 \r
     @Test\r
     public void testNoEps() throws Exception {\r
-        FlowMap fm = dosync(null);\r
+        OfWriter fm = dosync(null);\r
         assertEquals(1, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER()).getFlow().size());\r
     }\r
 \r
     private void verifyDMap(Endpoint remoteEp,\r
             Endpoint localEp) throws Exception {\r
 \r
-        FlowMap fm = dosync(null);\r
+        OfWriter fm = dosync(null);\r
         assertNotEquals(0, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER()).getFlow().size());\r
 \r
         // presumably counts flows that have correct matches set up\r
old mode 100644 (file)
new mode 100755 (executable)
index 97ee717..03e1383
@@ -22,8 +22,8 @@ import org.junit.Test;
 import org.opendaylight.groupbasedpolicy.endpoint.EpKey;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.EndpointManager;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
 import org.opendaylight.groupbasedpolicy.resolver.PolicyResolver;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
@@ -43,7 +43,7 @@ public class EgressNatMapperTest {
 
     private NodeId nodeId;
     private PolicyInfo policyInfo;
-    private FlowMap flowMap;
+    private OfWriter ofWriter;
 
     private IpAddress ipAddressNapt;
     private IpAddress ipAddressL3Ep;
@@ -104,7 +104,7 @@ public class EgressNatMapperTest {
 
         nodeId = mock(NodeId.class);
         policyInfo = mock(PolicyInfo.class);
-        flowMap = mock(FlowMap.class);
+        ofWriter = mock(OfWriter.class);
 
         mapper = new EgressNatMapper(ctx, TABLE_ID);
     }
@@ -116,15 +116,15 @@ public class EgressNatMapperTest {
 
     @Test
     public void syncTestIpv4() throws Exception {
-        mapper.sync(nodeId, policyInfo, flowMap);
-        verify(flowMap, times(2)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
+        mapper.sync(nodeId, policyInfo, ofWriter);
+        verify(ofWriter, times(2)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
     }
 
     @Test
     public void syncTestIpv6() throws Exception {
         when(ipAddressNapt.getIpv4Address()).thenReturn(null);
-        mapper.sync(nodeId, policyInfo, flowMap);
-        verify(flowMap, times(2)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
+        mapper.sync(nodeId, policyInfo, ofWriter);
+        verify(ofWriter, times(2)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
     }
 
 }
old mode 100644 (file)
new mode 100755 (executable)
index 06bbc85..a386a31
@@ -22,8 +22,8 @@ import java.util.Set;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;
 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
@@ -38,7 +38,7 @@ public class ExternalMapperTest {
     private short tableId;
     private NodeId nodeId;
     private PolicyInfo policyInfo;
-    private FlowMap flowMap;
+    private OfWriter ofWriter;
     private SwitchManager switchManager;
 
     @Before
@@ -47,7 +47,7 @@ public class ExternalMapperTest {
         tableId = 5;
         nodeId = mock(NodeId.class);
         policyInfo = mock(PolicyInfo.class);
-        flowMap = mock(FlowMap.class);
+        ofWriter = mock(OfWriter.class);
         switchManager = mock(SwitchManager.class);
         when(ctx.getSwitchManager()).thenReturn(switchManager);
 
@@ -65,15 +65,15 @@ public class ExternalMapperTest {
         Set<NodeConnectorId> externalPorts = new HashSet<NodeConnectorId>(Arrays.asList(nodeConnectorId));
         when(switchManager.getExternalPorts(nodeId)).thenReturn(externalPorts);
 
-        mapper.sync(nodeId, policyInfo, flowMap);
-        verify(flowMap, times(2)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
+        mapper.sync(nodeId, policyInfo, ofWriter);
+        verify(ofWriter, times(2)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
     }
 
     @Test
     public void syncTestNoExternalPorts() throws Exception {
         when(switchManager.getExternalPorts(nodeId)).thenReturn(null);
 
-        mapper.sync(nodeId, policyInfo, flowMap);
-        verify(flowMap, never()).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
+        mapper.sync(nodeId, policyInfo, ofWriter);
+        verify(ofWriter, never()).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
     }
 }
index c884bc1bf9de220bccdc14e276cf838723499edf..e155c0c9058669893a0ef34a85126a54fd57fe2b 100755 (executable)
@@ -10,7 +10,7 @@ package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
 \r
 import java.util.Map;\r
 \r
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;\r
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;\r
@@ -24,17 +24,17 @@ public class FlowTableTest extends OfTableTest {
                                          table.getTableId());\r
     }\r
 \r
-    protected FlowMap dosync(Map<String, Flow> flows) throws Exception {\r
-        FlowMap flowMap = policyManager.new FlowMap();\r
+    protected OfWriter dosync(Map<String, Flow> flows) throws Exception {\r
+        OfWriter ofWriter = new OfWriter();\r
         if (flows != null) {\r
             for (String key : flows.keySet()) {\r
                 Flow flow = flows.get(key);\r
                 if (flow != null) {\r
-                    flowMap.writeFlow(nodeId, flow.getTableId(), flow);\r
+                    ofWriter.writeFlow(nodeId, flow.getTableId(), flow);\r
                 }\r
             }\r
         }\r
-        table.sync(nodeId, policyResolver.getCurrentPolicy(), flowMap);\r
-        return flowMap;\r
+        table.sync(nodeId, policyResolver.getCurrentPolicy(), ofWriter);\r
+        return ofWriter;\r
     }\r
 }\r
index 6ef22a0f80a9cd805bfe014ddb6b451d0f98faf3..60c59e65ac399180b7559ff3c391d46f55d07c37 100755 (executable)
@@ -9,47 +9,39 @@
 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
 
 import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyListOf;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 
-import org.junit.Assert;
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+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.ReadFailedException;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.EndpointManager;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.GroupTable.BucketCtx;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.GroupTable.GroupCtx;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.resolver.EgKey;
 import org.opendaylight.groupbasedpolicy.resolver.IndexedTenant;
 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
 import org.opendaylight.groupbasedpolicy.resolver.PolicyResolver;
-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.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
@@ -57,42 +49,40 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.EndpointLocation.LocationType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-
 public class GroupTableTest {
 
     private GroupTable groupTable;
 
     private OfContext ofContext;
+
     private DataBroker dataBroker;
     private ReadOnlyTransaction readOnlyTransaction;
-    private CheckedFuture<Optional<Node>, ReadFailedException> checkedFutureRead;
-    private Optional<Node> optional;
+    private WriteTransaction writeTransaction;
+    private ReadWriteTransaction readWriteTransaction;
+
+    private CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> checkedFutureFCNRead;
+    private CheckedFuture<Void, TransactionCommitFailedException> checkedFutureWrite;
+    private Optional<Node> optionalNode;
+    private Optional<FlowCapableNode> optionalFlowCapableNode;
+
     private Node node;
     private FlowCapableNode flowCapableNode;
     private Group group;
+    private List<Group> groups;
     private Buckets buckets;
     private Bucket bucket;
-    private WriteTransaction writeTransaction;
-    private CheckedFuture<Void, TransactionCommitFailedException> checkedFutureWrite;
     private NodeId nodeId;
     private PolicyInfo policyInfo;
-    private FlowMap flowMap;
+    private OfWriter ofWriter;
     private GroupId groupId;
-    private GroupCtx groupCtx;
-    private HashMap<GroupId, GroupCtx> groupMap;
     private Bucket bucketOther;
-    private BucketCtx bucketCtx;
     private EndpointManager endpointManager;
     private Endpoint localEp;
     private EgKey egKey;
@@ -107,54 +97,56 @@ public class GroupTableTest {
 
         dataBroker = mock(DataBroker.class);
         when(ofContext.getDataBroker()).thenReturn(dataBroker);
+
+        node = mock(Node.class);
+        checkedFutureFCNRead =  mock(CheckedFuture.class);
+        optionalFlowCapableNode = mock(Optional.class);
+        flowCapableNode = mock(FlowCapableNode.class);
+
+        when(checkedFutureFCNRead.get()).thenReturn(optionalFlowCapableNode);
+
+        when(optionalFlowCapableNode.isPresent()).thenReturn(true);
+        when(optionalFlowCapableNode.get()).thenReturn(flowCapableNode);
+
+
         readOnlyTransaction = mock(ReadOnlyTransaction.class);
         when(dataBroker.newReadOnlyTransaction()).thenReturn(readOnlyTransaction);
-        checkedFutureRead = mock(CheckedFuture.class);
-        when(readOnlyTransaction.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))).thenReturn(
-                checkedFutureRead);
-        optional = mock(Optional.class);
-        when(checkedFutureRead.get()).thenReturn(optional);
-        node = mock(Node.class);
-        when(optional.isPresent()).thenReturn(true);
-        when(optional.get()).thenReturn(node);
+        when(readOnlyTransaction.read(any(LogicalDatastoreType.class),
+                any(InstanceIdentifier.class))).thenReturn(checkedFutureFCNRead);
 
         writeTransaction = mock(WriteTransaction.class);
         when(dataBroker.newWriteOnlyTransaction()).thenReturn(writeTransaction);
         checkedFutureWrite = mock(CheckedFuture.class);
         when(writeTransaction.submit()).thenReturn(checkedFutureWrite);
 
-        flowCapableNode = mock(FlowCapableNode.class);
-        when(node.getAugmentation(FlowCapableNode.class)).thenReturn(flowCapableNode);
+        readWriteTransaction = mock(ReadWriteTransaction.class);
+        when(dataBroker.newReadWriteTransaction()).thenReturn(readWriteTransaction);
 
         group = mock(Group.class);
-        List<Group> groups = Arrays.asList(group);
+        groups = Collections.singletonList(group);
         when(flowCapableNode.getGroup()).thenReturn(groups);
 
         buckets = mock(Buckets.class);
         when(group.getBuckets()).thenReturn(buckets);
         bucket = mock(Bucket.class);
-        when(bucket.getAction()).thenReturn(Arrays.asList(mock(Action.class)));
-        List<Bucket> bucketList = Arrays.asList(bucket);
+        when(bucket.getAction()).thenReturn(Collections.singletonList(mock(Action.class)));
+        List<Bucket> bucketList = Collections.singletonList(bucket);
         when(buckets.getBucket()).thenReturn(bucketList);
 
         bucketOther = mock(Bucket.class);
-        when(bucketOther.getAction()).thenReturn(Arrays.asList(mock(Action.class)));
+        when(bucketOther.getAction()).thenReturn(Collections.singletonList(mock(Action.class)));
 
         groupId = mock(GroupId.class);
-        groupCtx = new GroupCtx(groupId);
-        groupMap = new HashMap<>();
-        groupMap.put(groupId, groupCtx);
-        bucketCtx = mock(BucketCtx.class);
-        groupCtx.bucketMap.put(mock(BucketId.class), bucketCtx);
 
         nodeId = mock(NodeId.class);
         policyInfo = mock(PolicyInfo.class);
-        flowMap = mock(FlowMap.class);
+        ofWriter = mock(OfWriter.class);
 
         endpointManager = mock(EndpointManager.class);
         when(ofContext.getEndpointManager()).thenReturn(endpointManager);
         localEp = mock(Endpoint.class);
-        when(endpointManager.getEndpointsForNode(nodeId)).thenReturn(Arrays.asList(localEp));
+        when(endpointManager.getEndpointsForNode(nodeId)).thenReturn(Collections.singletonList(
+                localEp));
         PolicyResolver policyResolver = mock(PolicyResolver.class);
         when(ofContext.getPolicyResolver()).thenReturn(policyResolver);
         IndexedTenant indexedTenant = mock(IndexedTenant.class);
@@ -162,288 +154,47 @@ public class GroupTableTest {
         EndpointGroup epg = mock(EndpointGroup.class);
         when(indexedTenant.getEndpointGroup(any(EndpointGroupId.class))).thenReturn(epg);
         egKey = mock(EgKey.class);
-        when(endpointManager.getGroupsForNode(any(NodeId.class))).thenReturn(new HashSet<EgKey>(Arrays.asList(egKey)));
+        when(endpointManager.getGroupsForNode(any(NodeId.class))).thenReturn(
+                new HashSet<>(Collections.singletonList(egKey)));
         ofc = mock(OfOverlayContext.class);
         when(localEp.getAugmentation(OfOverlayContext.class)).thenReturn(ofc);
         nodeConnectorId = mock(NodeConnectorId.class);
         when(ofc.getNodeConnectorId()).thenReturn(nodeConnectorId);
     }
 
-    @SuppressWarnings("unchecked")
     @Test
     public void updateTest() throws Exception {
-        doNothing().when(groupTable).sync(any(NodeId.class), any(PolicyInfo.class), any(HashMap.class));
-        doReturn(true).when(groupTable).syncGroupToStore(any(WriteTransaction.class), any(NodeId.class),
-                any(HashMap.class));
-
-        groupTable.update(nodeId, policyInfo, flowMap);
-        verify(checkedFutureWrite).get();
-    }
-
-    @Test
-    public void updateTestIsPresentFalse() throws Exception {
-        when(optional.isPresent()).thenReturn(false);
-
-        groupTable.update(nodeId, policyInfo, flowMap);
-        verify(checkedFutureWrite, never()).get();
-    }
-
-    @Test
-    public void updateTestIsFcnNull() throws Exception {
-        when(node.getAugmentation(FlowCapableNode.class)).thenReturn(null);
-
-        groupTable.update(nodeId, policyInfo, flowMap);
-        verify(checkedFutureWrite, never()).get();
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void updateTestIsFcnGroupNull() throws Exception {
-        doNothing().when(groupTable).sync(any(NodeId.class), any(PolicyInfo.class), any(HashMap.class));
-        doReturn(true).when(groupTable).syncGroupToStore(any(WriteTransaction.class), any(NodeId.class),
-                any(HashMap.class));
-        when(flowCapableNode.getGroup()).thenReturn(null);
-
-        groupTable.update(nodeId, policyInfo, flowMap);
-        verify(checkedFutureWrite).get();
-    }
-
-    @Test
-    public void syncGroupToStoreTestVisitedFalse() {
-        groupCtx.visited = false;
-        boolean result = groupTable.syncGroupToStore(writeTransaction, nodeId, groupMap);
-        Assert.assertTrue(result);
-    }
-
-    @Test
-    public void syncGroupToStoreTestBucketMapEmpty() {
-        groupCtx.visited = true;
-        groupCtx.bucketMap = Collections.emptyMap();
-        boolean result = groupTable.syncGroupToStore(writeTransaction, nodeId, groupMap);
-        Assert.assertFalse(result);
-    }
-
-    @Test
-    public void syncGroupToStoreTestBNullBucketVisitedFalse() {
-        groupCtx.visited = true;
-        bucketCtx.visited = false;
-        bucketCtx.newb = bucket;
-
-        boolean result = groupTable.syncGroupToStore(writeTransaction, nodeId, groupMap);
-        Assert.assertTrue(result);
-        verify(bucket).getBucketId();
-        verify(writeTransaction).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
-    }
+        doNothing().when(groupTable).sync(nodeId, policyInfo, ofWriter);
 
-    @SuppressWarnings("unchecked")
-    @Test
-    public void syncGroupToStoreTestBNullBucketVisitedTrue() {
-        groupCtx.visited = true;
-        bucketCtx.visited = true;
-        bucketCtx.newb = bucket;
-
-        boolean result = groupTable.syncGroupToStore(writeTransaction, nodeId, groupMap);
-        Assert.assertTrue(result);
-        verify(bucket).getBucketId();
-        verify(writeTransaction).merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class),
-                any(Group.class), anyBoolean());
+        groupTable.update(nodeId, policyInfo, ofWriter);
+        verify(groupTable).sync(any(NodeId.class), any(PolicyInfo.class), any(OfWriter.class));
     }
 
     @Test
-    public void syncGroupToStoreTestBucketVisitedFalse() {
-        groupCtx.visited = true;
-        bucketCtx.visited = false;
-        bucketCtx.newb = bucket;
-        bucketCtx.b = bucketOther;
-
-        boolean result = groupTable.syncGroupToStore(writeTransaction, nodeId, groupMap);
-        Assert.assertTrue(result);
-        verify(bucketOther).getBucketId();
-        verify(writeTransaction).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
-    }
+    public void updateTestNoFCN() throws Exception {
+        doReturn(null).when(groupTable).getFCNodeFromDatastore(any(NodeId.class));
 
-    @SuppressWarnings("unchecked")
-    @Test
-    public void syncGroupToStoreTestBucketVisitedTrueActionsEqualFalse() {
-        groupCtx.visited = true;
-        bucketCtx.visited = true;
-        bucketCtx.newb = bucket;
-        bucketCtx.b = bucketOther;
-
-        boolean result = groupTable.syncGroupToStore(writeTransaction, nodeId, groupMap);
-        Assert.assertTrue(result);
-        verify(bucketOther).getBucketId();
-        verify(writeTransaction).merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class),
-                any(Group.class), anyBoolean());
+        groupTable.update(nodeId, policyInfo, ofWriter);
+        verify(groupTable, never()).sync(any(NodeId.class), any(PolicyInfo.class), any(OfWriter.class));
     }
 
     @Test
-    public void syncGroupToStoreTestBucketVisitedTrueActionsEqualTrue() {
-        groupCtx.visited = true;
-        bucketCtx.visited = true;
-        bucketCtx.newb = bucket;
-        bucketCtx.b = bucket;
-
-        boolean result = groupTable.syncGroupToStore(writeTransaction, nodeId, groupMap);
-        Assert.assertFalse(result);
-        verify(bucket).getBucketId();
-        verifyNoMoreInteractions(writeTransaction);
-    }
+    public void syncTestNoGroup() throws Exception {
+        when(ofWriter.groupExists(any(NodeId.class), any(Long.class))).thenReturn(false);
+        when(endpointManager.getGroupsForNode(any(NodeId.class))).thenReturn(
+                Collections.<EgKey>emptySet());
 
-    @Test
-    public void syncTestNodeEqualsTrue() throws Exception {
-        groupMap = new HashMap<>();
-
-        when(endpointManager.getNodesForGroup(egKey)).thenReturn(new HashSet<NodeId>(Arrays.asList(nodeId)));
-        when(ofc.getLocationType()).thenReturn(LocationType.Internal);
-        when(nodeConnectorId.getValue()).thenReturn("value:5");
-
-        groupTable.sync(nodeId, policyInfo, groupMap);
-        Assert.assertEquals(1, groupMap.size());
-        GroupCtx resultGroup = groupMap.values().toArray(new GroupCtx[0])[0];
-        Assert.assertEquals(1, resultGroup.bucketMap.size());
-        BucketCtx result = resultGroup.bucketMap.values().toArray(new BucketCtx[0])[0];
-        Assert.assertTrue(result.visited);
-        Assert.assertNotNull(result.newb);
+        groupTable.update(nodeId, policyInfo, ofWriter);
+        verify(ofWriter).writeGroup(any(NodeId.class), any(GroupId.class));
     }
 
     @Test
-    public void syncTestNodeEqualsTruePortNumberException() throws Exception {
-        groupMap = new HashMap<>();
-
-        when(endpointManager.getNodesForGroup(egKey)).thenReturn(new HashSet<NodeId>(Arrays.asList(nodeId)));
-        when(ofc.getLocationType()).thenReturn(LocationType.Internal);
-        when(nodeConnectorId.getValue()).thenReturn("value");
+    public void syncTestGroupExists() throws Exception {
+        when(ofWriter.groupExists(any(NodeId.class), any(Long.class))).thenReturn(true);
+        when(endpointManager.getGroupsForNode(any(NodeId.class))).thenReturn(
+                Collections.<EgKey>emptySet());
 
-        groupTable.sync(nodeId, policyInfo, groupMap);
-        Assert.assertEquals(1, groupMap.size());
-        GroupCtx resultGroup = groupMap.values().toArray(new GroupCtx[0])[0];
-        Assert.assertTrue(resultGroup.bucketMap.isEmpty());
-    }
-
-    @Test
-    public void syncTestNodeEqualsTrueLocalEpExternal() throws Exception {
-        groupMap = new HashMap<>();
-
-        when(endpointManager.getNodesForGroup(egKey)).thenReturn(new HashSet<NodeId>(Arrays.asList(nodeId)));
-        when(ofc.getLocationType()).thenReturn(LocationType.External);
-
-        groupTable.sync(nodeId, policyInfo, groupMap);
-        Assert.assertEquals(1, groupMap.size());
-        GroupCtx resultGroup = groupMap.values().toArray(new GroupCtx[0])[0];
-        Assert.assertTrue(resultGroup.bucketMap.isEmpty());
-    }
-
-    @Test
-    public void syncTestNodeEqualsFalse() throws Exception {
-        groupMap = new HashMap<>();
-
-        NodeId nodeIdOther = mock(NodeId.class);
-        when(nodeIdOther.getValue()).thenReturn("5");
-        SwitchManager switchManager = mock(SwitchManager.class);
-        when(ofContext.getSwitchManager()).thenReturn(switchManager);
-        IpAddress tunDst = mock(IpAddress.class);
-        when(switchManager.getTunnelIP(nodeIdOther, TunnelTypeVxlan.class)).thenReturn(tunDst);
-        NodeConnectorId tunPort = mock(NodeConnectorId.class);
-        when(switchManager.getTunnelPort(nodeId, TunnelTypeVxlan.class)).thenReturn(tunPort);
-        Ipv4Address ipv4Address = mock(Ipv4Address.class);
-        when(tunDst.getIpv4Address()).thenReturn(ipv4Address);
-        when(ipv4Address.getValue()).thenReturn("127.0.0.1");
-        when(tunPort.getValue()).thenReturn("127.0.0.1");
-
-        when(endpointManager.getNodesForGroup(egKey)).thenReturn(new HashSet<NodeId>(Arrays.asList(nodeIdOther)));
-        when(ofc.getLocationType()).thenReturn(LocationType.Internal);
-        when(nodeConnectorId.getValue()).thenReturn("value:5");
-
-        groupTable.sync(nodeId, policyInfo, groupMap);
-        Assert.assertEquals(1, groupMap.size());
-        GroupCtx resultGroup = groupMap.values().toArray(new GroupCtx[0])[0];
-        Assert.assertEquals(2, resultGroup.bucketMap.size());
-        BucketCtx result;
-        result = resultGroup.bucketMap.values().toArray(new BucketCtx[0])[0];
-        Assert.assertTrue(result.visited);
-        Assert.assertNotNull(result.newb);
-        result = resultGroup.bucketMap.values().toArray(new BucketCtx[0])[1];
-        Assert.assertTrue(result.visited);
-        Assert.assertNotNull(result.newb);
-    }
-
-    @Test
-    public void syncTestNodeEqualsFalseIpv4Null() throws Exception {
-        groupMap = new HashMap<>();
-
-        NodeId nodeIdOther = mock(NodeId.class);
-        when(nodeIdOther.getValue()).thenReturn("5");
-        SwitchManager switchManager = mock(SwitchManager.class);
-        when(ofContext.getSwitchManager()).thenReturn(switchManager);
-        IpAddress tunDst = mock(IpAddress.class);
-        when(switchManager.getTunnelIP(nodeIdOther, TunnelTypeVxlan.class)).thenReturn(tunDst);
-        NodeConnectorId tunPort = mock(NodeConnectorId.class);
-        when(switchManager.getTunnelPort(nodeId, TunnelTypeVxlan.class)).thenReturn(tunPort);
-        when(tunDst.getIpv4Address()).thenReturn(null);
-        Ipv6Address ipv6Address = mock(Ipv6Address.class);
-        when(tunDst.getIpv6Address()).thenReturn(ipv6Address);
-
-        when(endpointManager.getNodesForGroup(egKey)).thenReturn(new HashSet<NodeId>(Arrays.asList(nodeIdOther)));
-        when(ofc.getLocationType()).thenReturn(LocationType.Internal);
-        when(nodeConnectorId.getValue()).thenReturn("value:5");
-
-        groupTable.sync(nodeId, policyInfo, groupMap);
-        Assert.assertEquals(1, groupMap.size());
-        GroupCtx resultGroup = groupMap.values().toArray(new GroupCtx[0])[0];
-        Assert.assertEquals(1, resultGroup.bucketMap.size());
-        BucketCtx result = resultGroup.bucketMap.values().toArray(new BucketCtx[0])[0];
-        Assert.assertTrue(result.visited);
-        Assert.assertNotNull(result.newb);
-    }
-
-    @Test
-    public void syncTestNodeEqualsFalseTunDstNull() throws Exception {
-        groupMap = new HashMap<>();
-
-        NodeId nodeIdOther = mock(NodeId.class);
-        when(nodeIdOther.getValue()).thenReturn("5");
-        SwitchManager switchManager = mock(SwitchManager.class);
-        when(ofContext.getSwitchManager()).thenReturn(switchManager);
-        when(switchManager.getTunnelIP(nodeIdOther, TunnelTypeVxlan.class)).thenReturn(null);
-        NodeConnectorId tunPort = mock(NodeConnectorId.class);
-        when(switchManager.getTunnelPort(nodeId, TunnelTypeVxlan.class)).thenReturn(tunPort);
-
-        when(endpointManager.getNodesForGroup(egKey)).thenReturn(new HashSet<NodeId>(Arrays.asList(nodeIdOther)));
-        when(ofc.getLocationType()).thenReturn(LocationType.Internal);
-        when(nodeConnectorId.getValue()).thenReturn("value:5");
-
-        groupTable.sync(nodeId, policyInfo, groupMap);
-        Assert.assertEquals(1, groupMap.size());
-        GroupCtx resultGroup = groupMap.values().toArray(new GroupCtx[0])[0];
-        Assert.assertEquals(1, resultGroup.bucketMap.size());
-        BucketCtx result = resultGroup.bucketMap.values().toArray(new BucketCtx[0])[0];
-        Assert.assertTrue(result.visited);
-        Assert.assertNotNull(result.newb);
-    }
-
-    @Test
-    public void syncTestNodeEqualsFalseTunPortNull() throws Exception {
-        groupMap = new HashMap<>();
-
-        NodeId nodeIdOther = mock(NodeId.class);
-        when(nodeIdOther.getValue()).thenReturn("5");
-        SwitchManager switchManager = mock(SwitchManager.class);
-        when(ofContext.getSwitchManager()).thenReturn(switchManager);
-        IpAddress tunDst = mock(IpAddress.class);
-        when(switchManager.getTunnelIP(nodeIdOther, TunnelTypeVxlan.class)).thenReturn(tunDst);
-        when(switchManager.getTunnelPort(nodeId, TunnelTypeVxlan.class)).thenReturn(null);
-
-        when(endpointManager.getNodesForGroup(egKey)).thenReturn(new HashSet<NodeId>(Arrays.asList(nodeIdOther)));
-        when(ofc.getLocationType()).thenReturn(LocationType.Internal);
-        when(nodeConnectorId.getValue()).thenReturn("value:5");
-
-        groupTable.sync(nodeId, policyInfo, groupMap);
-        Assert.assertEquals(1, groupMap.size());
-        GroupCtx resultGroup = groupMap.values().toArray(new GroupCtx[0])[0];
-        Assert.assertEquals(1, resultGroup.bucketMap.size());
-        BucketCtx result = resultGroup.bucketMap.values().toArray(new BucketCtx[0])[0];
-        Assert.assertTrue(result.visited);
-        Assert.assertNotNull(result.newb);
+        groupTable.update(nodeId, policyInfo, ofWriter);
+        verify(ofWriter, never()).writeGroup(any(NodeId.class), any(GroupId.class));
     }
 }
old mode 100644 (file)
new mode 100755 (executable)
index bb8f030..9fc3b67
@@ -10,7 +10,6 @@ package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
 
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -21,9 +20,9 @@ import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.groupbasedpolicy.endpoint.EpKey;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.EndpointManager;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
 import org.opendaylight.groupbasedpolicy.resolver.PolicyResolver;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
@@ -43,7 +42,7 @@ public class IngressNatMapperTest {
 
     private NodeId nodeId;
     private PolicyInfo policyInfo;
-    private FlowMap flowMap;
+    private OfWriter ofWriter;
 
     private IpAddress ipAddressNapt;
     private IpAddress ipAddressL3Ep;
@@ -104,7 +103,7 @@ public class IngressNatMapperTest {
 
         nodeId = mock(NodeId.class);
         policyInfo = mock(PolicyInfo.class);
-        flowMap = mock(FlowMap.class);
+        ofWriter = mock(OfWriter.class);
 
         mapper = new IngressNatMapper(ctx, TABLE_ID);
     }
@@ -116,15 +115,15 @@ public class IngressNatMapperTest {
 
     @Test
     public void syncTestIpv4() throws Exception {
-        mapper.sync(nodeId, policyInfo, flowMap);
-        verify(flowMap).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
+        mapper.sync(nodeId, policyInfo, ofWriter);
+        verify(ofWriter).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
     }
 
     @Test
     public void syncTestIpv6() throws Exception {
         when(ipAddressL3Ep.getIpv4Address()).thenReturn(null);
-        mapper.sync(nodeId, policyInfo, flowMap);
-        verify(flowMap).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
+        mapper.sync(nodeId, policyInfo, ofWriter);
+        verify(ofWriter).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
     }
 
 }
index ae9c27da043bd4b97c53b521075a2ec491cfbeb0..6857e4c0c4bcd8612ed8282a67bbce5cf92419e7 100755 (executable)
@@ -27,7 +27,7 @@ import java.util.Set;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.PolicyEnforcer.PolicyPair;
 import org.opendaylight.groupbasedpolicy.resolver.ConditionGroup;
@@ -109,7 +109,7 @@ public class PolicyEnforcerTest extends FlowTableTest {
 
     @Test
     public void testNoEps() throws Exception {
-        FlowMap fm = dosync(null);
+        OfWriter fm = dosync(null);
         assertEquals(2, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())
             .getFlow()
             .size());
@@ -124,7 +124,7 @@ public class PolicyEnforcerTest extends FlowTableTest {
         policyResolver.addTenant(baseTenant().setContract(ImmutableList.<Contract>of(baseContract(null).build()))
             .build());
 
-        FlowMap fm = dosync(null);
+        OfWriter fm = dosync(null);
         assertNotEquals(0, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())
             .getFlow()
             .size());
@@ -199,7 +199,7 @@ public class PolicyEnforcerTest extends FlowTableTest {
         policyResolver.addTenant(baseTenant().setContract(ImmutableList.<Contract>of(baseContract(subjects).build()))
             .build());
 
-        FlowMap fm = dosync(null);
+        OfWriter fm = dosync(null);
         assertNotEquals(0, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())
             .getFlow()
             .size());
@@ -306,7 +306,7 @@ public class PolicyEnforcerTest extends FlowTableTest {
                 RegMatch.of(NxmNxReg3.class, Long.valueOf(cg1Id)));
         GeneralAugMatchNodesNodeTableFlow m2 = mb.getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);
         int count = 0;
-        FlowMap fm = dosync(null);
+        OfWriter fm = dosync(null);
         assertEquals(7, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())
             .getFlow()
             .size());
index 6e15fc5d8df8f6c7f5326a3e90469f988c6017bb..4d7409b24912c872bc79496422ca46b447de5976 100755 (executable)
@@ -17,7 +17,7 @@ import java.util.Set;
 \r
 import org.junit.Before;\r
 import org.junit.Test;\r
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;\r
@@ -56,7 +56,7 @@ public class PortSecurityTest extends FlowTableTest {
 \r
     @Test\r
     public void testDefaultDeny() throws Exception {\r
-        FlowMap fm = dosync(null);\r
+        OfWriter fm = dosync(null);\r
         int count = 0;\r
         Map<String, Flow> flowMap = new HashMap<>();\r
         for (Flow f : fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_PORTSECURITY()).getFlow()) {\r
@@ -88,7 +88,7 @@ public class PortSecurityTest extends FlowTableTest {
                                    .setTunnelType(TunnelTypeVxlan.class)\r
                                    .setNodeConnectorId(new NodeConnectorId("openflow:1:1"))\r
                                    .build())).build());\r
-        FlowMap fm = dosync(null);\r
+        OfWriter fm = dosync(null);\r
         assertNotEquals(0 ,fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_PORTSECURITY()).getFlow().size());\r
 \r
         int count = 0;\r
@@ -120,7 +120,7 @@ public class PortSecurityTest extends FlowTableTest {
 \r
         endpointManager.addEndpoint(ep);\r
 \r
-        FlowMap fm = dosync(null);\r
+        OfWriter fm = dosync(null);\r
         assertNotEquals(0 ,fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_PORTSECURITY()).getFlow().size());\r
 \r
         int count = 0;\r
@@ -159,7 +159,7 @@ public class PortSecurityTest extends FlowTableTest {
 \r
         endpointManager.addEndpoint(ep);\r
 \r
-        FlowMap fm = dosync(null);\r
+        OfWriter fm = dosync(null);\r
         assertNotEquals(0 ,fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_PORTSECURITY()).getFlow().size());\r
 \r
         int count = 0;\r
index 1794660fbe9a575975cbf9d38bb08215f248077e..53ac13ed7900d8c49bc5b364531aac449351ed71 100755 (executable)
@@ -23,9 +23,9 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.EndpointManager;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;
 import org.opendaylight.groupbasedpolicy.resolver.EgKey;
 import org.opendaylight.groupbasedpolicy.resolver.IndexedTenant;
@@ -50,7 +50,7 @@ public class SourceMapperTest {
     private short tableId;
     private NodeId nodeId;
     private PolicyInfo policyInfo;
-    private FlowMap flowMap;
+    private OfWriter ofWriter;
     private Endpoint endpoint;
     private EndpointManager endpointManager;
     private IndexedTenant tenant;
@@ -70,7 +70,7 @@ public class SourceMapperTest {
         tableId = 5;
         nodeId = mock(NodeId.class);
         policyInfo = mock(PolicyInfo.class);
-        flowMap = mock(FlowMap.class);
+        ofWriter = mock(OfWriter.class);
 
         mapper = new SourceMapper(ctx, tableId);
 
@@ -117,8 +117,8 @@ public class SourceMapperTest {
         when(endpoint.getEndpointGroup()).thenReturn(endpointGroupIdSingle);
         when(endpoint.getEndpointGroups()).thenReturn(null);
 
-        mapper.sync(nodeId, policyInfo, flowMap);
-        verify(flowMap, times(4)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
+        mapper.sync(nodeId, policyInfo, ofWriter);
+        verify(ofWriter, times(4)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
     }
 
     @Test
@@ -127,8 +127,8 @@ public class SourceMapperTest {
         List<EndpointGroupId> endpointGroups = Arrays.asList(endpointGroupIdList);
         when(endpoint.getEndpointGroups()).thenReturn(endpointGroups);
 
-        mapper.sync(nodeId, policyInfo, flowMap);
-        verify(flowMap, times(4)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
+        mapper.sync(nodeId, policyInfo, ofWriter);
+        verify(ofWriter, times(4)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
     }
 
     @Test
@@ -137,8 +137,8 @@ public class SourceMapperTest {
         when(endpoint.getEndpointGroup()).thenReturn(endpointGroupIdSingle);
         when(endpoint.getEndpointGroups()).thenReturn(null);
 
-        mapper.sync(nodeId, policyInfo, flowMap);
-        verify(flowMap, times(4)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
+        mapper.sync(nodeId, policyInfo, ofWriter);
+        verify(ofWriter, times(4)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
     }
 
     @Test
@@ -148,15 +148,15 @@ public class SourceMapperTest {
         when(endpoint.getEndpointGroups()).thenReturn(null);
         when(switchManager.getTunnelPort(nodeId, TunnelTypeVxlan.class)).thenReturn(null);
 
-        mapper.sync(nodeId, policyInfo, flowMap);
-        verify(flowMap, times(2)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
+        mapper.sync(nodeId, policyInfo, ofWriter);
+        verify(ofWriter, times(2)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
     }
 
     @Test
     public void syncTestTenantNull() throws Exception {
         when(policyResolver.getTenant(tenantId)).thenReturn(null);
 
-        mapper.sync(nodeId, policyInfo, flowMap);
-        verify(flowMap, times(1)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
+        mapper.sync(nodeId, policyInfo, ofWriter);
+        verify(ofWriter, times(1)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
     }
 }
old mode 100644 (file)
new mode 100755 (executable)
index d6011c4..ee8ae00
@@ -29,8 +29,8 @@ 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.groupbasedpolicy.renderer.ofoverlay.EndpointManager;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.PolicyEnforcer.NetworkElements;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.PolicyEnforcer.PolicyPair;
@@ -120,11 +120,12 @@ public class ChainActionTest {
         String chainName = "chainName";
         params.put(ChainAction.SFC_CHAIN_NAME, chainName);
         Integer order = Integer.valueOf(0);
-        FlowMap flowMap = mock(FlowMap.class);
+        OfWriter ofWriter = mock(OfWriter.class);
 
         doReturn(sfcPath).when(chainAction).getSfcPath(chainName);
 
-        List<ActionBuilder> result = chainAction.updateAction(actions, params, order, netElements, policyPair, flowMap,
+        List<ActionBuilder> result = chainAction.updateAction(actions, params, order, netElements, policyPair,
+                ofWriter,
                 ctx, Direction.Out);
         Assert.assertNull(result);
     }
@@ -134,9 +135,10 @@ public class ChainActionTest {
         ActionBuilder actionBuilder = mock(ActionBuilder.class);
         List<ActionBuilder> actions = Arrays.asList(actionBuilder);
         Integer order = Integer.valueOf(0);
-        FlowMap flowMap = mock(FlowMap.class);
+        OfWriter ofWriter = mock(OfWriter.class);
 
-        List<ActionBuilder> result = chainAction.updateAction(actions, null, order, netElements, policyPair, flowMap,
+        List<ActionBuilder> result = chainAction.updateAction(actions, null, order, netElements, policyPair,
+                ofWriter,
                 ctx, Direction.In);
         Assert.assertNull(result);
     }
@@ -150,9 +152,9 @@ public class ChainActionTest {
         Integer order = Integer.valueOf(0);
         NetworkElements netElements = mock(NetworkElements.class);
         PolicyPair policyPair = mock(PolicyPair.class);
-        FlowMap flowMap = mock(FlowMap.class);
+        OfWriter ofWriter = mock(OfWriter.class);
 
-        chainAction.updateAction(actions, params, order, netElements, policyPair, flowMap, ctx, Direction.In);
+        chainAction.updateAction(actions, params, order, netElements, policyPair, ofWriter, ctx, Direction.In);
     }
 
     @Test
@@ -163,12 +165,13 @@ public class ChainActionTest {
         String chainName = "chainName";
         params.put(ChainAction.SFC_CHAIN_NAME, chainName);
         Integer order = Integer.valueOf(0);
-        FlowMap flowMap = mock(FlowMap.class);
+        OfWriter ofWriter = mock(OfWriter.class);
 
         doReturn(sfcPath).when(chainAction).getSfcPath(chainName);
         when(sfcPath.getName()).thenReturn(null);
 
-        List<ActionBuilder> result = chainAction.updateAction(actions, params, order, netElements, policyPair, flowMap,
+        List<ActionBuilder> result = chainAction.updateAction(actions, params, order, netElements, policyPair,
+                ofWriter,
                 ctx, Direction.Out);
         Assert.assertNull(result);
     }