return flowb.build();
}
- @VisibleForTesting
- static Flow createExternalFlow(SfcNshHeader sfcNshHeader, NodeConnectorId tunPort, NetworkElements netElements,
+ private static Flow createExternalFlow(SfcNshHeader sfcNshHeader, NodeConnectorId tunPort, NetworkElements netElements,
PolicyManager policyManager, SwitchManager switchManager, Ipv4Address ipTunDest) {
short tableId = policyManager.getTABLEID_EXTERNAL_MAPPER();
}
- @VisibleForTesting
- static Integer returnOfPortFromNodeConnector(NodeConnectorId nodeConnectorId) {
+ private static Integer returnOfPortFromNodeConnector(NodeConnectorId nodeConnectorId) {
String[] elements = StringUtils.split(nodeConnectorId.getValue(), ":");
if (elements.length != 3)
return null;
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.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.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-
-import org.antlr.v4.runtime.misc.Array2DHashSet;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.groupbasedpolicy.dto.EgKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Optional;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*;
/**
* Manage the group tables for handling broadcast/multicast
super(ctx);
}
- 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 sync(Endpoint endpoint, OfWriter ofWriter) throws Exception {
-
- // TODO: only temporary workaround, use src & dst endpoint in implementation
- NodeId nodeId = ctx.getEndpointManager().getEndpointNodeId(endpoint);
+ NodeId endpointNodeId = ctx.getEndpointManager().getEndpointNodeId(endpoint);
+ if (endpointNodeId == null) {
+ LOG.warn("Endpoint {} has no location specified, skipped", endpoint);
+ return;
+ }
// there appears to be no way of getting only the existing group
- // tables unfortunately, so we have to get the whole goddamned node.
+ // tables unfortunately, so we have to get the whole node.
// Since this is happening concurrently with other things that are
// working in subtrees of nodes, we have to do two transactions
- FlowCapableNode fcn = getFCNodeFromDatastore(nodeId);
+ FlowCapableNode fcn = getFCNodeFromDatastore(endpointNodeId);
if (fcn == null)
return;
+ EndpointFwdCtxOrdinals ordinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, endpoint);
+ if (ordinals == null) {
+ LOG.info("getEndpointFwdCtxOrdinals is null for EP {}", endpoint);
+ return;
+ }
+ GroupId groupId = new GroupId(Long.valueOf(ordinals.getFdId()));
+ if (!ofWriter.groupExists(endpointNodeId, groupId.getValue())) {
+ LOG.info("createGroup {} {}", endpointNodeId, groupId);
+ ofWriter.writeGroup(endpointNodeId, groupId);
+ }
+ syncGroups(endpointNodeId, ordinals, endpoint, groupId, ofWriter);
+ }
- for (Endpoint localEp : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
- EndpointFwdCtxOrdinals localEpFwdCtxOrds =
- OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, localEp);
- if (localEpFwdCtxOrds == null) {
- LOG.info("getEndpointFwdCtxOrdinals is null for EP {}", localEp);
- continue;
- }
-
- GroupId gid = new GroupId(Long.valueOf(localEpFwdCtxOrds.getFdId()));
- if (!ofWriter.groupExists(nodeId, gid.getValue())) {
- LOG.info("createGroup {} {}", nodeId, gid);
- ofWriter.writeGroup(nodeId, gid);
- }
-
- 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 : findPeerNodesForGroup(epg)) {
- if (nodeId.equals(destNode))
+ @VisibleForTesting
+ void syncGroups(NodeId nodeId, EndpointFwdCtxOrdinals ordinals, Endpoint endpoint, GroupId groupId,
+ OfWriter ofWriter) throws Exception {
+ for (EgKey endpointGroupKey : 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 destinationNode : findPeerNodesForGroup(endpointGroupKey)) {
+ if (nodeId.equals(destinationNode))
+ continue;
+ if (isFloodDomainOnNode(ordinals.getFdId(), destinationNode)) {
+ Long bucketId;
+ try {
+ bucketId = (long) OrdinalFactory.getContextOrdinal(destinationNode);
+ } catch (Exception e) {
+ LOG.error("Error during getting of context ordinal, node: {}", destinationNode);
continue;
-
- if(isFloodDomainOnNode(localEpFwdCtxOrds.getFdId(), destNode)) {
- 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)));
- ofWriter.writeBucket(nodeId, gid, bb.build());
}
+ bucketId |= 1L << 31;
+ IpAddress tunDst = ctx.getSwitchManager().getTunnelIP(destinationNode, TunnelTypeVxlan.class);
+ NodeConnectorId tunPort = ctx.getSwitchManager().getTunnelPort(nodeId, TunnelTypeVxlan.class);
+ if (tunDst == null || tunPort == null)
+ continue;
+ Action tunDstAction;
+ 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(),
+ destinationNode);
+ continue;
+ }
+ BucketBuilder bucketBuilder = new BucketBuilder().setBucketId(new BucketId(bucketId))
+ .setAction(actionList(tunDstAction, outputAction(tunPort)));
+ ofWriter.writeBucket(nodeId, groupId, bucketBuilder.build());
}
- // TODO broadcasts are not separated by EPG between endpoints on the same node
- OfOverlayContext ofc = localEp.getAugmentation(OfOverlayContext.class);
- if (EndpointManager.isExternal(localEp, ctx.getTenant(localEp.getTenant()).getExternalImplicitGroups()))
- continue;
-
- long bucketId;
- try {
- bucketId = getOfPortNum(ofc.getNodeConnectorId());
- } catch (NumberFormatException 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))).setAction(
- FlowUtils.actionList(output));
- ofWriter.writeBucket(nodeId, gid, bb.build());
-
- // if boradcast exceeds internal domain
- for (Endpoint extEp : ctx.getEndpointManager().getExtEpsNoLocForGroup(epg)) {
- if (extEp.getNetworkContainment() != null
- && extEp.getNetworkContainment().equals(localEp.getNetworkContainment())) {
- L2FloodDomain l2Fd = ctx.getTenant(extEp.getTenant()).resolveL2FloodDomain(
- extEp.getNetworkContainment());
- if (l2Fd != null) {
- Segmentation segmentation = l2Fd.getAugmentation(Segmentation.class);
- // external endpoints do not have location augmentation
- // however they are beyond external ports
- for (NodeConnectorId extNcId : ctx.getSwitchManager().getExternalPorts(nodeId)) {
- try {
- bucketId = getOfPortNum(extNcId);
- } catch (NumberFormatException e) {
- LOG.warn("Could not parse external port number {}", extNcId, e);
- continue;
- }
- ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder>
+ }
+ // TODO broadcasts are not separated by EPG between endpoints on the same node
+ OfOverlayContext ofc = endpoint.getAugmentation(OfOverlayContext.class);
+ if (EndpointManager.isExternal(endpoint, ctx.getTenant(endpoint.getTenant()).getExternalImplicitGroups()))
+ continue;
+ long bucketId;
+ try {
+ bucketId = getOfPortNum(ofc.getNodeConnectorId());
+ } catch (NumberFormatException e) {
+ LOG.warn("Could not parse port number {}", ofc.getNodeConnectorId(), e);
+ continue;
+ }
+ Action output = outputAction(ofc.getNodeConnectorId());
+ BucketBuilder bb = new BucketBuilder().setBucketId(new BucketId(bucketId)).setAction(
+ FlowUtils.actionList(output));
+ ofWriter.writeBucket(nodeId, groupId, bb.build());
+ // if broadcast exceeds internal domain
+ for (Endpoint extEp : ctx.getEndpointManager().getExtEpsNoLocForGroup(endpointGroupKey)) {
+ if (extEp.getNetworkContainment() != null
+ && extEp.getNetworkContainment().equals(endpoint.getNetworkContainment())) {
+ L2FloodDomain l2Fd = ctx.getTenant(extEp.getTenant())
+ .resolveL2FloodDomain(extEp.getNetworkContainment());
+ if (l2Fd != null) {
+ Segmentation segmentation = l2Fd.getAugmentation(Segmentation.class);
+ // external endpoints do not have location augmentation
+ // however they are beyond external ports
+ for (NodeConnectorId extNcId : ctx.getSwitchManager().getExternalPorts(nodeId)) {
+ try {
+ bucketId = getOfPortNum(extNcId);
+ } catch (NumberFormatException e) {
+ LOG.warn("Could not parse external port number {}", extNcId, e);
+ continue;
+ }
+ ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder>
actionList = new ArrayList<>();
- if (segmentation != null) {
- Integer vlanId = segmentation.getSegmentationId();
- actionList.addAll(FlowUtils.pushVlanActions(vlanId));
- actionList.add(new ActionBuilder().setOrder(2).setAction(outputAction(extNcId)));
- } else {
- actionList.add(new ActionBuilder().setOrder(0).setAction(outputAction(extNcId)));
- }
- bb.setBucketId(new BucketId(Long.valueOf(bucketId))).setAction(
- FlowUtils.actionList(actionList));
- ofWriter.writeBucket(nodeId, gid, bb.build());
+ if (segmentation != null) {
+ Integer vlanId = segmentation.getSegmentationId();
+ actionList.addAll(FlowUtils.pushVlanActions(vlanId));
+ actionList.add(new ActionBuilder().setOrder(2).setAction(outputAction(extNcId)));
+ } else {
+ actionList.add(new ActionBuilder().setOrder(0).setAction(outputAction(extNcId)));
}
+ bb.setBucketId(new BucketId(bucketId)).setAction(
+ FlowUtils.actionList(actionList));
+ ofWriter.writeBucket(nodeId, groupId, bb.build());
}
}
}
}
}
+
}
/**
* @param sourceEpgKey a key of source group
* @return all the nodes on which endpoints are either in groups that have policy with source
- * group, or are in the source group
+ * group, or are in the source group
*/
private Set<NodeId> findPeerNodesForGroup(EgKey sourceEpgKey) {
- Set<NodeId> nodes = new HashSet<NodeId>();
+ Set<NodeId> nodes = new HashSet<>();
nodes.addAll(ctx.getEndpointManager().getNodesForGroup(sourceEpgKey));
- for (EgKey dstEpgs : ctx.getCurrentPolicy().getPeers(sourceEpgKey)) {
- nodes.addAll(ctx.getEndpointManager().getNodesForGroup(dstEpgs));
+ for (EgKey dstEpGroups : ctx.getCurrentPolicy().getPeers(sourceEpgKey)) {
+ nodes.addAll(ctx.getEndpointManager().getNodesForGroup(dstEpGroups));
}
return nodes;
}
private boolean isFloodDomainOnNode(int fdId, NodeId node) throws Exception {
- for (Endpoint ep : ctx.getEndpointManager().getEndpointsForNode(node)) {
- int epFdId = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, ep).getFdId();
+ for (Endpoint endpoint : ctx.getEndpointManager().getEndpointsForNode(node)) {
+ EndpointFwdCtxOrdinals endpointFwdCtxOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, endpoint);
+ if (endpointFwdCtxOrdinals == null) {
+ continue;
+ }
+ int epFdId = endpointFwdCtxOrdinals.getFdId();
if (fdId == epFdId) {
return true;
}
}
return false;
}
+
+ private FlowCapableNode getFCNodeFromDatastore(NodeId nodeId)
+ throws ExecutionException, InterruptedException {
+ 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;
+ }
+ FlowCapableNode fcn = r.get();
+ t.close();
+ return fcn;
+ }
}
\r
package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;\r
\r
-import static org.junit.Assert.assertEquals;\r
-import static org.junit.Assert.assertTrue;\r
-import static org.mockito.Mockito.mock;\r
-import static org.mockito.Mockito.when;\r
-\r
-import org.junit.Assert;\r
+import com.google.common.base.Preconditions;\r
import org.junit.Before;\r
import org.junit.Test;\r
+import org.mockito.ArgumentCaptor;\r
+import org.mockito.Captor;\r
+import org.opendaylight.groupbasedpolicy.dto.EgKey;\r
+import org.opendaylight.groupbasedpolicy.dto.PolicyInfo;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;\r
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager;\r
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTest;\r
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.NetworkElements;\r
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;\r
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sfcutils.SfcNshHeader;\r
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sfcutils.SfcNshHeader.SfcNshHeaderBuilder;\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.IpAddress;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlanGpe;\r
\r
-public class ChainActionFlowsTest {\r
+import java.math.BigInteger;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import static org.junit.Assert.assertArrayEquals;\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertNotNull;\r
+import static org.junit.Assert.assertTrue;\r
+import static org.mockito.Mockito.any;\r
+import static org.mockito.Mockito.mock;\r
+import static org.mockito.Mockito.times;\r
+import static org.mockito.Mockito.verify;\r
+import static org.mockito.Mockito.when;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxNsiMatch;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxNspMatch;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxRegMatch;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxTunIdMatch;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.base;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.gotoTableIns;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.instructions;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadNshc1RegAction;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadNshc2RegAction;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadRegAction;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadTunIPv4Action;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadTunIdAction;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxOutputRegAction;\r
\r
- private SfcNshHeader sfcNshHeader;\r
- private NodeConnectorId tunPort;\r
- private NetworkElements netElements;\r
- private PolicyManager policyManager;\r
- private SwitchManager switchManager;\r
- private Ipv4Address ip1 = new Ipv4Address("10.1.1.1");\r
- private Ipv4Address ip2 = new Ipv4Address("10.1.1.2");\r
+public class ChainActionFlowsTest extends MapperUtilsTest {\r
+\r
+ @Captor\r
+ private final ArgumentCaptor<NodeId> nodeIdCaptor = ArgumentCaptor.forClass(NodeId.class);\r
+ private final ArgumentCaptor<Short> tableIdCaptor = ArgumentCaptor.forClass(Short.class);\r
+ private final ArgumentCaptor<Flow> flowCaptor = ArgumentCaptor.forClass(Flow.class);\r
\r
@Before\r
- public void setup() {\r
- policyManager = mock(PolicyManager.class);\r
+ public void init() {\r
+ ctx = mock(OfContext.class);\r
+ endpointManager = mock(EndpointManager.class);\r
switchManager = mock(SwitchManager.class);\r
- EndpointFwdCtxOrdinals ords = mock(EndpointFwdCtxOrdinals.class);\r
- sfcNshHeader = mock(SfcNshHeader.class);\r
- netElements = mock(NetworkElements.class);\r
- when(netElements.getSrcNodeId()).thenReturn(new NodeId("openflow:1"));\r
- when(netElements.getSrcEpOrdinals()).thenReturn(ords);\r
- when(netElements.getSrcEpOrdinals().getL3Id()).thenReturn(7);\r
- when(netElements.getDstNodeId()).thenReturn(new NodeId("openflow:1"));\r
- when(netElements.getDstEpOrdinals()).thenReturn(ords);\r
- when(netElements.getDstEpOrdinals().getL3Id()).thenReturn(7);\r
- when(netElements.getLocalNodeId()).thenReturn(new NodeId("openflow:1"));\r
- tunPort = new NodeConnectorId("openflow:1:42");\r
+ policyManager = mock(PolicyManager.class);\r
+ policyInfo = mock(PolicyInfo.class);\r
+ ofWriter = mock(OfWriter.class);\r
}\r
\r
@Test\r
- public void createExternalFlowTest() throws Exception {\r
- // Note C1 != tunDest ie ip1 and ip2 - output action\r
- sfcNshHeader = new SfcNshHeaderBuilder().setNshMetaC1(SfcNshHeader.convertIpAddressToLong(ip1))\r
- .setNshTunIpDst(ip2)\r
- .setNshMetaC2(7L)\r
- .setNshNsiToChain((short) 1)\r
- .build();\r
-\r
- Flow flow = ChainActionFlows.createExternalFlow(sfcNshHeader, tunPort, netElements, policyManager, switchManager, ip2);\r
- assertEquals(policyManager.getTABLEID_EXTERNAL_MAPPER(), flow.getTableId().shortValue());\r
- assertTrue(flow.getInstructions().getInstruction()\r
- .get(0).getInstruction().toString().contains("_outputAction=OutputAction"));\r
-\r
- // Note C1 == tunDest ie ip1\r
- sfcNshHeader = new SfcNshHeaderBuilder().setNshMetaC1(SfcNshHeader.convertIpAddressToLong(ip1))\r
- .setNshTunIpDst(ip1)\r
- .setNshMetaC2(7L)\r
- .setNshNsiToChain((short) 1)\r
- .build();\r
-\r
- flow = ChainActionFlows.createExternalFlow(sfcNshHeader, tunPort, netElements, policyManager, switchManager, ip2);\r
-\r
- assertTrue(flow.getInstructions().getInstruction()\r
- .get(0).getInstruction().toString().contains("_outputAction=OutputAction"));\r
+ public void createChainTunnelFlows_directionIn() throws Exception {\r
+ // Tenant\r
+ TenantBuilder tenantBuilder = buildTenant();\r
+ Tenant tenant = tenantBuilder.build();\r
+ // Source Endpoint\r
+ EndpointBuilder sourceEndpointBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0);\r
+ Endpoint sourceEndpoint = sourceEndpointBuilder.build();\r
+ EgKey sourceEgKey = new EgKey(tenant.getId(), ENDPOINT_GROUP_0);\r
+ // Destination Endpoint\r
+ EndpointBuilder destinationEndpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1);\r
+ Endpoint destinationEndpoint = destinationEndpointBuilder.build();\r
+ EgKey destinationEgKey = new EgKey(tenant.getId(), ENDPOINT_GROUP_1);\r
+ // Nsh header\r
+ SfcNshHeaderBuilder nshHeaderBuilder = new SfcNshHeaderBuilder();\r
+ nshHeaderBuilder.setNshNsiFromChain((short) 250);\r
+ nshHeaderBuilder.setNshNspFromChain(27L);\r
+ SfcNshHeader nshHeader = nshHeaderBuilder.build();\r
+\r
+ when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant());\r
+ when(ctx.getEndpointManager()).thenReturn(endpointManager);\r
+ when(ctx.getSwitchManager()).thenReturn(switchManager);\r
+ when(ctx.getPolicyManager()).thenReturn(policyManager);\r
+ when(ctx.getCurrentPolicy()).thenReturn(policyInfo);\r
+ when(switchManager.getTunnelPort(NODE_ID, TunnelTypeVxlanGpe.class)).thenReturn(CONNECTOR_2);\r
+ when(switchManager.getTunnelIP(NODE_ID, TunnelTypeVxlanGpe.class)).thenReturn(new IpAddress(IPV4_2));\r
+ when(policyManager.getTABLEID_PORTSECURITY()).thenReturn((short) 4);\r
+ when(policyManager.getTABLEID_SOURCE_MAPPER()).thenReturn((short) 2);\r
+\r
+ // Net elements\r
+ NetworkElements netElements = new NetworkElements(sourceEndpoint, destinationEndpoint, sourceEgKey,\r
+ destinationEgKey, NODE_ID, ctx);\r
+ assertNotNull(netElements);\r
+\r
+ ChainActionFlows.createChainTunnelFlows(nshHeader, netElements, ofWriter, ctx, HasDirection.Direction.In);\r
+\r
+ // Verify flows and capture arguments\r
+ verify(ofWriter, times(4)).writeFlow(nodeIdCaptor.capture(), tableIdCaptor.capture(), flowCaptor.capture());\r
+\r
+ // Verify nodeIds\r
+ for (NodeId capturedNodeId : nodeIdCaptor.getAllValues()) {\r
+ assertEquals(capturedNodeId, NODE_ID);\r
+ }\r
+\r
+ // Verify tableIds\r
+ List<Short> tableIds = tableIdCaptor.getAllValues();\r
+ Short expectedTableIds[] = {4, 2, 0, 2};\r
+ assertArrayEquals(expectedTableIds, tableIds.toArray());\r
+\r
+ // Verify flows\r
+ List<Flow> flows = flowCaptor.getAllValues();\r
+ assertNotNull(flows);\r
+ assertTrue(flows.size() == 4);\r
+ assertEquals(flows.get(0), allowFromChainTestFlow());\r
+ assertEquals(flows.get(1), createChainTunnelTestFlow(netElements).get(0)); // contains only 1 entry\r
+ assertEquals(flows.get(2), allowFromChainTunnelTestFlow());\r
+ assertEquals(flows.get(3), createChainBroadcastTestFlow());\r
}\r
\r
@Test\r
- public void returnOfPortFromNodeConnectorTest() {\r
- NodeConnectorId ncId = new NodeConnectorId("openflow:1:42");\r
- Integer port = ChainActionFlows.returnOfPortFromNodeConnector(ncId);\r
- assertEquals(new Integer("42"), port);\r
+ public void createChainTunnelFlows_directionOut() throws Exception {\r
+ // Tenant\r
+ TenantBuilder tenantBuilder = buildTenant();\r
+ Tenant tenant = tenantBuilder.build();\r
+ // Source Endpoint\r
+ EndpointBuilder sourceEndpointBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0);\r
+ Endpoint sourceEndpoint = sourceEndpointBuilder.build();\r
+ EgKey sourceEgKey = new EgKey(tenant.getId(), ENDPOINT_GROUP_0);\r
+ // Destination Endpoint\r
+ EndpointBuilder destinationEndpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1);\r
+ Endpoint destinationEndpoint = destinationEndpointBuilder.build();\r
+ EgKey destinationEgKey = new EgKey(tenant.getId(), ENDPOINT_GROUP_1);\r
+ // Nsh header\r
+ SfcNshHeaderBuilder nshHeaderBuilder = new SfcNshHeaderBuilder();\r
+ nshHeaderBuilder.setNshNsiToChain((short) 255);\r
+ nshHeaderBuilder.setNshNspToChain(27L);\r
+ nshHeaderBuilder.setNshTunIpDst(IPV4_2);\r
+ SfcNshHeader nshHeader = nshHeaderBuilder.build();\r
+\r
+ when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant());\r
+ when(ctx.getEndpointManager()).thenReturn(endpointManager);\r
+ when(ctx.getSwitchManager()).thenReturn(switchManager);\r
+ when(ctx.getPolicyManager()).thenReturn(policyManager);\r
+ when(ctx.getCurrentPolicy()).thenReturn(policyInfo);\r
+ when(switchManager.getTunnelPort(NODE_ID, TunnelTypeVxlanGpe.class)).thenReturn(CONNECTOR_2);\r
+ when(switchManager.getTunnelIP(NODE_ID, TunnelTypeVxlanGpe.class)).thenReturn(new IpAddress(IPV4_2));\r
+ when(policyManager.getTABLEID_EXTERNAL_MAPPER()).thenReturn((short) 6);\r
+\r
+\r
+ // Net elements\r
+ NetworkElements netElements = new NetworkElements(sourceEndpoint, destinationEndpoint, sourceEgKey,\r
+ destinationEgKey, NODE_ID, ctx);\r
+ assertNotNull(netElements);\r
+\r
+ ChainActionFlows.createChainTunnelFlows(nshHeader, netElements, ofWriter, ctx, HasDirection.Direction.Out);\r
+\r
+ // Verify flows and capture arguments\r
+ verify(ofWriter, times(1)).writeFlow(NODE_ID, (short) 6, createExternalTestFlow());\r
+ }\r
+\r
+ private Flow allowFromChainTestFlow() {\r
+ MatchBuilder matchBuilder = new MatchBuilder();\r
+ FlowUtils.addNxNshc1RegMatch(matchBuilder, 0L);\r
+ FlowUtils.addNxNsiMatch(matchBuilder, (short) 250);\r
+ FlowUtils.addNxNspMatch(matchBuilder, 27L);\r
+ Match match = matchBuilder.setInPort(CONNECTOR_2).build();\r
+\r
+ FlowId flowId = FlowIdUtils.newFlowId((short) 4, "chainport", match);\r
+ FlowBuilder flowBuilder = new FlowBuilder().setTableId((short) 4).setBarrier(false).setHardTimeout(0)\r
+ .setIdleTimeout(0).setId(flowId).setPriority(1200).setMatch(match)\r
+ .setInstructions(FlowUtils.gotoTableInstructions((short) 2));\r
+ return flowBuilder.build();\r
+ }\r
+\r
+ private List<Flow> createChainTunnelTestFlow(NetworkElements networkElements) {\r
+ Preconditions.checkNotNull(networkElements);\r
+ List<Flow> flows = new ArrayList<>();\r
+ Action segReg = nxLoadRegAction(NxmNxReg0.class, BigInteger.valueOf(1L));\r
+ Action scgReg = nxLoadRegAction(NxmNxReg1.class, BigInteger.valueOf(0xffffff));\r
+ Action bdReg = nxLoadRegAction(NxmNxReg4.class, BigInteger.valueOf(0L));\r
+ Action fdReg = nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(0L));\r
+ Action vrfReg = nxLoadRegAction(NxmNxReg6.class, BigInteger.valueOf(0L));\r
+ for (L3Address address : networkElements.getDstEp().getL3Address()) {\r
+ Layer3Match l3Match = new Ipv4MatchBuilder().setIpv4Source(new Ipv4Prefix(address.getIpAddress()\r
+ .getIpv4Address().getValue() + IP_PREFIX_32)).build();\r
+ MatchBuilder mb = new MatchBuilder().setInPort(CONNECTOR_2).setLayer3Match(l3Match)\r
+ .setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv4));\r
+ addNxTunIdMatch(mb, 2);\r
+ addNxNspMatch(mb, 27L);\r
+ addNxNsiMatch(mb, (short) 250);\r
+ Match match = mb.build();\r
+ FlowId flowId = FlowIdUtils.newFlowId((short) 2, "chaintunnel", match);\r
+ FlowBuilder flowBuilder = base((short) 2).setId(flowId).setPriority(150).setMatch(match).setInstructions(\r
+ instructions(applyActionIns(segReg, scgReg, bdReg, fdReg, vrfReg),\r
+ gotoTableIns(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));\r
+ flows.add(flowBuilder.build());\r
+ }\r
+ assertTrue(flows.size() == 1);\r
+ return flows;\r
+ }\r
+\r
+ private Flow allowFromChainTunnelTestFlow() {\r
+ MatchBuilder matchBuilder = new MatchBuilder().setInPort(CONNECTOR_2);\r
+ addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg1.class, 0xffffffL));\r
+ Match match = matchBuilder.build();\r
+ FlowId flowId = FlowIdUtils.newFlowId((short) 0, "chainport", match);\r
+ FlowBuilder flowBuilder = base((short) 0).setId(flowId).setMatch(match)\r
+ .setPriority(65000).setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));\r
+ return flowBuilder.build();\r
+ }\r
+\r
+ private Flow createChainBroadcastTestFlow() {\r
+ MatchBuilder matchBuilder = new MatchBuilder().setInPort(CONNECTOR_2);\r
+ addNxNsiMatch(matchBuilder, (short) 250);\r
+ addNxNspMatch(matchBuilder, 27L);\r
+ addNxTunIdMatch(matchBuilder, 0);\r
+ Match match = matchBuilder.build();\r
+ FlowId flowId = FlowIdUtils.newFlowId((short) 2, "chainbroadcast", match);\r
+ FlowBuilder flowBuilder = base((short) 2).setId(flowId).setPriority(150).setMatch(match)\r
+ .setInstructions(instructions(applyActionIns(nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(0))),\r
+ gotoTableIns(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));\r
+ return flowBuilder.build();\r
+ }\r
+\r
+ private Flow createExternalTestFlow() {\r
+ Action loadC1 = nxLoadNshc1RegAction(null);\r
+ Action loadC2 = nxLoadNshc2RegAction(2L);\r
+ Action loadChainTunVnId = nxLoadTunIdAction(BigInteger.valueOf(2L), false);\r
+ Action loadChainTunDest = nxLoadTunIPv4Action(IPV4_2.getValue(), false);\r
+ Action outputAction = FlowUtils.createActionResubmit(null, (short) 0);\r
+\r
+ MatchBuilder matchBuilder = new MatchBuilder();\r
+ addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, 0L));\r
+ addNxTunIdMatch(matchBuilder, 2);\r
+ addNxNspMatch(matchBuilder, 27L);\r
+ addNxNsiMatch(matchBuilder, (short) 255);\r
+\r
\r
- ncId = new NodeConnectorId("openflow:1");\r
- Assert.assertNull(ChainActionFlows.returnOfPortFromNodeConnector(ncId));\r
+ Match match = matchBuilder.build();\r
+ FlowId flowId = FlowIdUtils.newFlowId(((short) 6), "chainexternal", match);\r
+ FlowBuilder flowBuilder = base((short) 6).setId(flowId).setPriority(1000).setMatch(match)\r
+ .setInstructions(instructions(applyActionIns(loadC1, loadC2, loadChainTunDest, loadChainTunVnId,\r
+ outputAction)));\r
+ return flowBuilder.build();\r
}\r
}\r
package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
-import static org.mockito.Matchers.any;
-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.when;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
+import org.mockito.InOrder;
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.dto.EgKey;
-import org.opendaylight.groupbasedpolicy.dto.IndexedTenant;
import org.opendaylight.groupbasedpolicy.dto.PolicyInfo;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTest;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.Node;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-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.Buckets;
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.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;
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.EndpointBuilder;
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.policy.EndpointGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContextBuilder;
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.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.util.concurrent.CheckedFuture;
-
-public class GroupTableTest {
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
- private GroupTable groupTable;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
- private OfContext ofContext;
+public class GroupTableTest extends MapperUtilsTest {
+ private final GroupId GROUP_ID = new GroupId(27L);
+ private GroupTable groupTable;
+ // DataStore mocks
private DataBroker dataBroker;
private ReadOnlyTransaction readOnlyTransaction;
- private WriteTransaction writeTransaction;
- private ReadWriteTransaction readWriteTransaction;
-
- private CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> checkedFutureFCNRead;
- private CheckedFuture<Void, TransactionCommitFailedException> checkedFutureWrite;
- private Optional<FlowCapableNode> optionalFlowCapableNode;
-
+ private CheckedFuture checkedFutureFCNRead;
+ private Optional optionalFlowCapableNode;
private FlowCapableNode flowCapableNode;
- private Group group;
- private List<Group> groups;
- private Buckets buckets;
- private Bucket bucket;
- private NodeId nodeId;
- private OfWriter ofWriter;
- private Bucket bucketOther;
- private EndpointManager endpointManager;
- private Endpoint localEp;
- private EgKey egKey;
- private OfOverlayContext ofc;
- private NodeConnectorId nodeConnectorId;
-
- @SuppressWarnings("unchecked")
+
@Before
- public void initialisation() throws Exception {
- ofContext = mock(OfContext.class);
- groupTable = spy(new GroupTable(ofContext));
+ public void init() {
+ ctx = mock(OfContext.class);
+ endpointManager = mock(EndpointManager.class);
+ switchManager = mock(SwitchManager.class);
+ policyInfo = mock(PolicyInfo.class);
+ groupTable = new GroupTable(ctx);
+ ofWriter = mock(OfWriter.class);
+ OrdinalFactory.resetPolicyOrdinalValue();
+ }
- dataBroker = mock(DataBroker.class);
- when(ofContext.getDataBroker()).thenReturn(dataBroker);
+ @Test
+ public void sync_noEpNodeId() throws Exception {
+ initDataStoreMocks();
+ EndpointBuilder endpointBuilder = new EndpointBuilder();
+ Endpoint endpoint = endpointBuilder.build();
- checkedFutureFCNRead = mock(CheckedFuture.class);
- optionalFlowCapableNode = mock(Optional.class);
- flowCapableNode = mock(FlowCapableNode.class);
+ when(ctx.getEndpointManager()).thenReturn(endpointManager);
- when(checkedFutureFCNRead.get()).thenReturn(optionalFlowCapableNode);
-
- when(optionalFlowCapableNode.isPresent()).thenReturn(true);
- when(optionalFlowCapableNode.get()).thenReturn(flowCapableNode);
+ groupTable.sync(endpoint, ofWriter);
+ verifyZeroInteractions(ofWriter);
+ }
- readOnlyTransaction = mock(ReadOnlyTransaction.class);
+ @Test
+ public void sync_nodeIsNotFlowCapable() throws Exception {
+ initDataStoreMocks();
+ EndpointBuilder endpointBuilder = new EndpointBuilder();
+ OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
+ ofOverlayContextBuilder.setNodeId(NODE_ID);
+ endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
+ Endpoint endpoint = endpointBuilder.build();
+
+ when(ctx.getEndpointManager()).thenReturn(endpointManager);
+ when(ctx.getDataBroker()).thenReturn(dataBroker);
+ when(endpointManager.getEndpointNodeId(any(Endpoint.class))).thenCallRealMethod();
when(dataBroker.newReadOnlyTransaction()).thenReturn(readOnlyTransaction);
- 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);
-
- readWriteTransaction = mock(ReadWriteTransaction.class);
- when(dataBroker.newReadWriteTransaction()).thenReturn(readWriteTransaction);
+ when(readOnlyTransaction.read(eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class)))
+ .thenReturn(checkedFutureFCNRead);
+ when(checkedFutureFCNRead.get()).thenReturn(optionalFlowCapableNode);
+ when(optionalFlowCapableNode.isPresent()).thenReturn(true);
- group = mock(Group.class);
- groups = Collections.singletonList(group);
- when(flowCapableNode.getGroup()).thenReturn(groups);
+ groupTable.sync(endpoint, ofWriter);
- buckets = mock(Buckets.class);
- when(group.getBuckets()).thenReturn(buckets);
- bucket = mock(Bucket.class);
- when(bucket.getAction()).thenReturn(Collections.singletonList(mock(Action.class)));
- List<Bucket> bucketList = Collections.singletonList(bucket);
- when(buckets.getBucket()).thenReturn(bucketList);
+ verify(optionalFlowCapableNode, times(1)).isPresent();
+ verifyZeroInteractions(ofWriter);
+ }
- bucketOther = mock(Bucket.class);
- when(bucketOther.getAction()).thenReturn(Collections.singletonList(mock(Action.class)));
+ @Test
+ public void sync_nullOrdinals() throws Exception {
+ initDataStoreMocks();
+ EndpointBuilder endpointBuilder = new EndpointBuilder();
+ OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
+ ofOverlayContextBuilder.setNodeId(NODE_ID);
+ endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
+ Endpoint endpoint = endpointBuilder.build();
+
+ when(ctx.getEndpointManager()).thenReturn(endpointManager);
+ when(ctx.getDataBroker()).thenReturn(dataBroker);
+ when(endpointManager.getEndpointNodeId(any(Endpoint.class))).thenCallRealMethod();
+ when(dataBroker.newReadOnlyTransaction()).thenReturn(readOnlyTransaction);
+ when(readOnlyTransaction.read(eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class)))
+ .thenReturn(checkedFutureFCNRead);
+ when(checkedFutureFCNRead.get()).thenReturn(optionalFlowCapableNode);
+ when(optionalFlowCapableNode.isPresent()).thenReturn(true);
+ when(optionalFlowCapableNode.get()).thenReturn(flowCapableNode);
+ groupTable.sync(endpoint, ofWriter);
- nodeId = mock(NodeId.class);
- ofWriter = mock(OfWriter.class);
-
- endpointManager = mock(EndpointManager.class);
- when(ofContext.getEndpointManager()).thenReturn(endpointManager);
- localEp = mock(Endpoint.class);
- when(endpointManager.getEndpointsForNode(nodeId)).thenReturn(Collections.singletonList(
- localEp));
- IndexedTenant indexedTenant = mock(IndexedTenant.class);
- when(ofContext.getTenant(any(TenantId.class))).thenReturn(indexedTenant);
- 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<>(Collections.singletonList(egKey)));
- ofc = mock(OfOverlayContext.class);
- when(localEp.getAugmentation(OfOverlayContext.class)).thenReturn(ofc);
- nodeConnectorId = mock(NodeConnectorId.class);
- when(ofc.getNodeConnectorId()).thenReturn(nodeConnectorId);
+ verify(optionalFlowCapableNode, times(1)).isPresent();
+ verifyZeroInteractions(ofWriter);
}
- @Ignore
@Test
- public void updateTest() throws Exception {
- //doNothing().when(groupTable).sync(NODE_ID, ofWriter);
+ public void sync() throws Exception {
+ initDataStoreMocks();
+ EndpointBuilder endpointBuilder = new EndpointBuilder();
+ OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
+ ofOverlayContextBuilder.setNodeId(NODE_ID);
+ endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
+ endpointBuilder.setNetworkContainment(NET_DOMAIN_ID);
+ endpointBuilder.setTenant(buildTenant().getId());
+ Endpoint endpoint = endpointBuilder.build();
+
+ when(ctx.getEndpointManager()).thenReturn(endpointManager);
+ when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
+ when(ctx.getDataBroker()).thenReturn(dataBroker);
+ when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant());
+ when(endpointManager.getEndpointNodeId(any(Endpoint.class))).thenCallRealMethod();
+ when(dataBroker.newReadOnlyTransaction()).thenReturn(readOnlyTransaction);
+ when(readOnlyTransaction.read(eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class)))
+ .thenReturn(checkedFutureFCNRead);
+ when(checkedFutureFCNRead.get()).thenReturn(optionalFlowCapableNode);
+ when(optionalFlowCapableNode.isPresent()).thenReturn(true);
+ when(optionalFlowCapableNode.get()).thenReturn(flowCapableNode);
- //groupTable.sync(NODE_ID, ofWriter);
- //verify(groupTable).sync(any(NodeId.class), any(OfWriter.class));
- }
+ groupTable.sync(endpoint, ofWriter);
- @Ignore
- @Test
- public void updateTestNoFCN() throws Exception {
- doReturn(null).when(groupTable).getFCNodeFromDatastore(any(NodeId.class));
-
- //groupTable.sync(NODE_ID, ofWriter);
- verify(ofWriter, never()).writeBucket(any(NodeId.class), any(GroupId.class), any(Bucket.class));;
- verify(ofWriter, never()).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
- verify(ofWriter, never()).writeGroup(any(NodeId.class), any(GroupId.class), any(GroupTypes.class),
- any(String.class), any(String.class), any(Boolean.class));
+ verify(optionalFlowCapableNode, times(1)).isPresent();
+ verify(ofWriter, times(1)).writeGroup(NODE_ID, new GroupId(0L));
}
- @Ignore
@Test
- 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());
-
- //groupTable.sync(NODE_ID, ofWriter);
- verify(ofWriter).writeGroup(any(NodeId.class), any(GroupId.class));
+ public void syncGroups_groupsForNode() throws Exception {
+ // Define NodeIds
+ NodeId nodeWithoutTunnel = new NodeId("nodeIdWithoutTunnel");
+ NodeId nodeIdIpV6 = new NodeId("nodeIdIpV6");
+ NodeId nodeIdIpV4 = new NodeId("nodeIdIpV4");
+ Endpoint endpoint = buildEndpoint(IPV4_0, MAC_0, new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue())).build();
+
+ when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant());
+ when(ctx.getEndpointManager()).thenReturn(endpointManager);
+ when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
+
+ OrdinalFactory.EndpointFwdCtxOrdinals ordinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, endpoint);
+ Preconditions.checkNotNull(ordinals);
+
+ // EgKeys
+ Set<EgKey> egKeys = new HashSet<>();
+ egKeys.add(new EgKey(buildTenant().getId(), endpoint.getEndpointGroup()));
+ // Nodes
+ Set<NodeId> nodeIds = new HashSet<>();
+ nodeIds.add(NODE_ID);
+ nodeIds.add(nodeWithoutTunnel);
+ nodeIds.add(nodeIdIpV6);
+ nodeIds.add(nodeIdIpV4);
+ // Endpoints
+ Collection<Endpoint> endpoints = new HashSet<>();
+ endpoints.add(buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1).build());
+ endpoints.add(buildEndpoint(IPV4_2, MAC_2, CONNECTOR_2).build());
+
+ when(ctx.getSwitchManager()).thenReturn(switchManager);
+ when(endpointManager.getGroupsForNode(NODE_ID)).thenReturn(egKeys);
+ when(endpointManager.getNodesForGroup(any(EgKey.class))).thenReturn(nodeIds);
+ when(endpointManager.getEndpointsForNode(any(NodeId.class))).thenReturn(endpoints);
+ when(switchManager.getTunnelIP(nodeIdIpV6, TunnelTypeVxlan.class)).thenReturn(new IpAddress(IPV6_1));
+ when(switchManager.getTunnelIP(nodeIdIpV4, TunnelTypeVxlan.class)).thenReturn(new IpAddress(IPV4_1));
+ when(switchManager.getTunnelPort(NODE_ID, TunnelTypeVxlan.class)).thenReturn(CONNECTOR_1);
+ when(policyInfo.getPeers(any(EgKey.class))).thenReturn(egKeys);
+
+ groupTable.syncGroups(NODE_ID, ordinals, endpoint, GROUP_ID, ofWriter);
+
+ // Verify method order
+ InOrder order = inOrder(endpointManager, policyInfo, switchManager, ofWriter);
+ order.verify(endpointManager, times(1)).getGroupsForNode(NODE_ID);
+ order.verify(endpointManager, times(1)).getNodesForGroup(any(EgKey.class));
+ order.verify(policyInfo, times(1)).getPeers(any(EgKey.class));
+ order.verify(endpointManager, times(1)).getNodesForGroup(any(EgKey.class));
+ order.verify(switchManager, times(1)).getTunnelIP(nodeWithoutTunnel, TunnelTypeVxlan.class);
+ order.verify(switchManager, times(1)).getTunnelPort(NODE_ID, TunnelTypeVxlan.class);
+ order.verify(switchManager, times(1)).getTunnelIP(any(NodeId.class), eq(TunnelTypeVxlan.class));
+ order.verify(switchManager, times(1)).getTunnelPort(NODE_ID, TunnelTypeVxlan.class);
+ order.verify(switchManager, times(1)).getTunnelIP(any(NodeId.class), eq(TunnelTypeVxlan.class));
+ order.verify(switchManager, times(1)).getTunnelPort(NODE_ID, TunnelTypeVxlan.class);
+ order.verify(ofWriter, atLeastOnce()).writeBucket(any(NodeId.class), any(GroupId.class), any(Bucket.class));
}
- @Ignore
@Test
- 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());
+ public void syncGroups_externalEpsWithoutLocation() throws Exception {
+ EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_0, new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue()));
+ endpointBuilder.setNetworkContainment(L2FD_ID);
+ Endpoint endpoint = endpointBuilder.build();
+
+ when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant());
+ when(ctx.getEndpointManager()).thenReturn(endpointManager);
+ when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
+
+ OrdinalFactory.EndpointFwdCtxOrdinals ordinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, endpoint);
+ Preconditions.checkNotNull(ordinals);
+ // EgKeys
+ Set<EgKey> egKeys = new HashSet<>();
+ egKeys.add(new EgKey(buildTenant().getId(), endpoint.getEndpointGroup()));
+ // NodeConnectorIds
+ Set<NodeConnectorId> externalPorts = new HashSet<>();
+ externalPorts.add(new NodeConnectorId(OPENFLOW + CONNECTOR_1.getValue())); // Correct format
+ externalPorts.add(CONNECTOR_2); // NumberFormatException
+ // Endpoints
+ Collection<Endpoint> endpoints = new HashSet<>();
+ EndpointBuilder noLocEndpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1);
+ noLocEndpointBuilder.setNetworkContainment(L2FD_ID);
+ endpoints.add(noLocEndpointBuilder.build());
+
+ when(ctx.getSwitchManager()).thenReturn(switchManager);
+ when(endpointManager.getGroupsForNode(NODE_ID)).thenReturn(egKeys);
+ when(endpointManager.getExtEpsNoLocForGroup(any(EgKey.class))).thenReturn(endpoints);
+ when(switchManager.getExternalPorts(NODE_ID)).thenReturn(externalPorts);
+
+ groupTable.syncGroups(NODE_ID, ordinals, endpoint, GROUP_ID, ofWriter);
+
+ // Verify method order
+ InOrder order = inOrder(endpointManager, policyInfo, switchManager, ofWriter);
+ order.verify(endpointManager, times(1)).getGroupsForNode(NODE_ID);
+ order.verify(endpointManager, times(1)).getExtEpsNoLocForGroup(any(EgKey.class));
+ order.verify(switchManager, times(1)).getExternalPorts(any(NodeId.class));
+ order.verify(ofWriter, times(1)).writeBucket(any(NodeId.class), any(GroupId.class), any(Bucket.class));
+ }
- //groupTable.sync(NODE_ID, ofWriter);
- verify(ofWriter, never()).writeGroup(any(NodeId.class), any(GroupId.class));
+ private void initDataStoreMocks() {
+ dataBroker = mock(DataBroker.class);
+ readOnlyTransaction = mock(ReadOnlyTransaction.class);
+ checkedFutureFCNRead = mock(CheckedFuture.class);
+ optionalFlowCapableNode = mock(Optional.class);
+ flowCapableNode = mock(FlowCapableNode.class);
}
}