Merge branch 'master' into netgraphrefactor
Conflicts:
src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
index 6628bcc..2eaf535 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
@@ -200,7 +200,23 @@
// TODO: Fix me
@Override
public List<Link> getLinks(Long dpid, short port) {
- List<Link> links = null;
+ List<Link> links = new ArrayList<Link>();
+
+ IPortObject srcPort = dbop.searchPort(HexString.toHexString(dpid), port);
+ ISwitchObject srcSw = srcPort.getSwitch();
+
+ if(srcSw != null) {
+ for(IPortObject dstPort : srcPort.getLinkedPorts()) {
+ ISwitchObject dstSw = dstPort.getSwitch();
+ Link link = new Link(HexString.toLong(srcSw.getDPID()),
+ srcPort.getNumber(),
+ HexString.toLong(dstSw.getDPID()),
+ dstPort.getNumber());
+
+ links.add(link);
+ }
+ }
+
return links;
}
@@ -222,14 +238,11 @@
// TODO: Fix me
@Override
public void deleteLinksOnPort(Long dpid, short port) {
- // BEGIN: Trial code
- // author: Naoki Shiota
List<Link> linksToDelete = getLinks(dpid,port);
for(Link l : linksToDelete) {
deleteLink(l);
}
- // END: Trial code
}
/**
@@ -242,6 +255,23 @@
public List<Link> getLinks(String dpid) {
List<Link> links = new ArrayList<Link>();
+ ISwitchObject srcSw = dbop.searchSwitch(dpid);
+
+ if(srcSw != null) {
+ for(IPortObject srcPort : srcSw.getPorts()) {
+ for(IPortObject dstPort : srcPort.getLinkedPorts()) {
+ ISwitchObject dstSw = dstPort.getSwitch();
+ if(dstSw != null) {
+ Link link = new Link(HexString.toLong(srcSw.getDPID()),
+ srcPort.getNumber(),
+ HexString.toLong(dstSw.getDPID()),
+ dstPort.getNumber());
+ links.add(link);
+ }
+ }
+ }
+ }
+
return links;
}
@@ -253,20 +283,22 @@
Iterable<ISwitchObject> switches = dbop.getActiveSwitches();
List<Link> links = new ArrayList<Link>();
- for (ISwitchObject sw : switches) {
- GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
- ExtractLink extractor = new ExtractLink();
-
- pipe.start(sw.asVertex());
- pipe.enablePath(true);
- pipe.out("on").out("link").in("on").path().step(extractor);
+
+ for (ISwitchObject srcSw : switches) {
+ for(IPortObject srcPort : srcSw.getPorts()) {
+ for(IPortObject dstPort : srcPort.getLinkedPorts()) {
+ ISwitchObject dstSw = dstPort.getSwitch();
- while (pipe.hasNext() ) {
- Link l = pipe.next();
- links.add(l);
+ if(dstSw != null && dstSw.getState().equals("ACTIVE")) {
+ links.add(new Link(HexString.toLong(srcSw.getDPID()),
+ srcPort.getNumber(),
+ HexString.toLong(dstSw.getDPID()),
+ dstPort.getNumber()));
+ }
+ }
}
-
}
+
return links;
}
diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
new file mode 100644
index 0000000..0bf9ba0
--- /dev/null
+++ b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
@@ -0,0 +1,440 @@
+/**
+* Copyright 2011, Big Switch Networks, Inc.
+* Originally created by David Erickson, Stanford University
+*
+* Licensed under the Apache License, Version 2.0 (the "License"); you may
+* not use this file except in compliance with the License. You may obtain
+* a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+* License for the specific language governing permissions and limitations
+* under the License.
+**/
+
+package net.floodlightcontroller.linkdiscovery.internal;
+
+import static org.easymock.EasyMock.*;
+
+import java.util.Collections;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IFloodlightProviderService.Role;
+import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.test.MockThreadPoolService;
+import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryListener;
+import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryService;
+import net.floodlightcontroller.linkdiscovery.LinkInfo;
+import net.floodlightcontroller.linkdiscovery.internal.LinkDiscoveryManager;
+import net.floodlightcontroller.restserver.IRestApiService;
+import net.floodlightcontroller.restserver.RestApiServer;
+import net.floodlightcontroller.routing.IRoutingService;
+import net.floodlightcontroller.routing.Link;
+import net.floodlightcontroller.storage.IStorageSourceService;
+import net.floodlightcontroller.storage.memory.MemoryStorageSource;
+import net.floodlightcontroller.test.FloodlightTestCase;
+import net.floodlightcontroller.threadpool.IThreadPoolService;
+import net.floodlightcontroller.topology.ITopologyService;
+import net.floodlightcontroller.topology.NodePortTuple;
+import net.floodlightcontroller.topology.TopologyManager;
+import net.onrc.onos.registry.controller.IControllerRegistryService;
+import net.onrc.onos.registry.controller.StandaloneRegistry;
+
+/**
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class LinkDiscoveryManagerTest extends FloodlightTestCase {
+
+ private TestLinkDiscoveryManager ldm;
+ private StandaloneRegistry srs;
+ protected static Logger log = LoggerFactory.getLogger(LinkDiscoveryManagerTest.class);
+
+ public class TestLinkDiscoveryManager extends LinkDiscoveryManager {
+ public boolean isSendLLDPsCalled = false;
+ public boolean isClearLinksCalled = false;
+
+ @Override
+ protected void discoverOnAllPorts() {
+ isSendLLDPsCalled = true;
+ super.discoverOnAllPorts();
+ }
+
+ public void reset() {
+ isSendLLDPsCalled = false;
+ isClearLinksCalled = false;
+ }
+
+ @Override
+ protected void clearAllLinks() {
+ isClearLinksCalled = true;
+ super.clearAllLinks();
+ }
+ }
+
+ public LinkDiscoveryManager getTopology() {
+ return ldm;
+ }
+
+ public IOFSwitch createMockSwitch(Long id) {
+ IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
+ expect(mockSwitch.getId()).andReturn(id).anyTimes();
+ return mockSwitch;
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ FloodlightModuleContext cntx = new FloodlightModuleContext();
+ ldm = new TestLinkDiscoveryManager();
+ TopologyManager routingEngine = new TopologyManager();
+ ldm.linkDiscoveryAware = new ArrayList<ILinkDiscoveryListener>();
+ srs = new StandaloneRegistry();
+ MockThreadPoolService tp = new MockThreadPoolService();
+ RestApiServer restApi = new RestApiServer();
+ cntx.addService(IRestApiService.class, restApi);
+ cntx.addService(IThreadPoolService.class, tp);
+ cntx.addService(IRoutingService.class, routingEngine);
+ cntx.addService(ILinkDiscoveryService.class, ldm);
+ cntx.addService(ITopologyService.class, ldm);
+ cntx.addService(IStorageSourceService.class, new MemoryStorageSource());
+ cntx.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
+ cntx.addService(IControllerRegistryService.class, srs);
+
+ restApi.init(cntx);
+ tp.init(cntx);
+ routingEngine.init(cntx);
+ srs.init(cntx);
+ ldm.init(cntx);
+ restApi.startUp(cntx);
+ tp.startUp(cntx);
+ routingEngine.startUp(cntx);
+ srs.startUp(cntx);
+ ldm.startUp(cntx);
+
+ IOFSwitch sw1 = createMockSwitch(1L);
+ IOFSwitch sw2 = createMockSwitch(2L);
+ Map<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
+ switches.put(1L, sw1);
+ switches.put(2L, sw2);
+ getMockFloodlightProvider().setSwitches(switches);
+ replay(sw1, sw2);
+ }
+
+ @Test
+ public void testAddOrUpdateLink() throws Exception {
+ LinkDiscoveryManager topology = getTopology();
+
+ Link lt = new Link(1L, 2, 2L, 1);
+ LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+ System.currentTimeMillis(), null,
+ 0, 0);
+ topology.addOrUpdateLink(lt, info);
+
+
+ NodePortTuple srcNpt = new NodePortTuple(1L, 2);
+ NodePortTuple dstNpt = new NodePortTuple(2L, 1);
+
+ // check invariants hold
+ assertNotNull(topology.switchLinks.get(lt.getSrc()));
+ assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
+ assertNotNull(topology.portLinks.get(srcNpt));
+ assertTrue(topology.portLinks.get(srcNpt).contains(lt));
+ assertNotNull(topology.portLinks.get(dstNpt));
+ assertTrue(topology.portLinks.get(dstNpt).contains(lt));
+ assertTrue(topology.links.containsKey(lt));
+ }
+
+ @Test
+ public void testDeleteLink() throws Exception {
+ LinkDiscoveryManager topology = getTopology();
+
+ Link lt = new Link(1L, 2, 2L, 1);
+ LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+ System.currentTimeMillis(), null,
+ 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ topology.deleteLinks(Collections.singletonList(lt), "Test");
+
+ // check invariants hold
+ assertNull(topology.switchLinks.get(lt.getSrc()));
+ assertNull(topology.switchLinks.get(lt.getDst()));
+ assertNull(topology.portLinks.get(lt.getSrc()));
+ assertNull(topology.portLinks.get(lt.getDst()));
+ assertTrue(topology.links.isEmpty());
+ }
+
+ @Test
+ public void testAddOrUpdateLinkToSelf() throws Exception {
+ LinkDiscoveryManager topology = getTopology();
+
+ Link lt = new Link(1L, 2, 2L, 3);
+ NodePortTuple srcNpt = new NodePortTuple(1L, 2);
+ NodePortTuple dstNpt = new NodePortTuple(2L, 3);
+
+ LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+ System.currentTimeMillis(), null,
+ 0, 0);
+ topology.addOrUpdateLink(lt, info);
+
+ // check invariants hold
+ assertNotNull(topology.switchLinks.get(lt.getSrc()));
+ assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
+ assertNotNull(topology.portLinks.get(srcNpt));
+ assertTrue(topology.portLinks.get(srcNpt).contains(lt));
+ assertNotNull(topology.portLinks.get(dstNpt));
+ assertTrue(topology.portLinks.get(dstNpt).contains(lt));
+ assertTrue(topology.links.containsKey(lt));
+ }
+
+ @Test
+ public void testDeleteLinkToSelf() throws Exception {
+ LinkDiscoveryManager topology = getTopology();
+
+ Link lt = new Link(1L, 2, 1L, 3);
+ NodePortTuple srcNpt = new NodePortTuple(1L, 2);
+ NodePortTuple dstNpt = new NodePortTuple(2L, 3);
+
+ LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+ System.currentTimeMillis(), null,
+ 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ topology.deleteLinks(Collections.singletonList(lt), "Test to self");
+
+ // check invariants hold
+ assertNull(topology.switchLinks.get(lt.getSrc()));
+ assertNull(topology.switchLinks.get(lt.getDst()));
+ assertNull(topology.portLinks.get(srcNpt));
+ assertNull(topology.portLinks.get(dstNpt));
+ assertTrue(topology.links.isEmpty());
+ }
+
+ @Test
+ public void testRemovedSwitch() {
+ LinkDiscoveryManager topology = getTopology();
+
+ Link lt = new Link(1L, 2, 2L, 1);
+ NodePortTuple srcNpt = new NodePortTuple(1L, 2);
+ NodePortTuple dstNpt = new NodePortTuple(2L, 1);
+ LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+ System.currentTimeMillis(), null,
+ 0, 0);
+ topology.addOrUpdateLink(lt, info);
+
+ IOFSwitch sw1 = getMockFloodlightProvider().getSwitches().get(1L);
+ IOFSwitch sw2 = getMockFloodlightProvider().getSwitches().get(2L);
+ // Mock up our expected behavior
+ topology.removedSwitch(sw1);
+ verify(sw1, sw2);
+
+ // check invariants hold
+ assertNull(topology.switchLinks.get(lt.getSrc()));
+ assertNull(topology.switchLinks.get(lt.getDst()));
+ assertNull(topology.portLinks.get(srcNpt));
+ assertNull(topology.portLinks.get(dstNpt));
+ assertTrue(topology.links.isEmpty());
+ }
+
+ @Test
+ public void testRemovedSwitchSelf() {
+ LinkDiscoveryManager topology = getTopology();
+ IOFSwitch sw1 = createMockSwitch(1L);
+ replay(sw1);
+ Link lt = new Link(1L, 2, 1L, 3);
+ LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+ System.currentTimeMillis(), null,
+ 0, 0);
+ topology.addOrUpdateLink(lt, info);
+
+ // Mock up our expected behavior
+ topology.removedSwitch(sw1);
+
+ verify(sw1);
+ // check invariants hold
+ assertNull(topology.switchLinks.get(lt.getSrc()));
+ assertNull(topology.portLinks.get(lt.getSrc()));
+ assertNull(topology.portLinks.get(lt.getDst()));
+ assertTrue(topology.links.isEmpty());
+ }
+
+ @Test
+ public void testAddUpdateLinks() throws Exception {
+ LinkDiscoveryManager topology = getTopology();
+
+ Link lt = new Link(1L, 1, 2L, 1);
+ NodePortTuple srcNpt = new NodePortTuple(1L, 1);
+ NodePortTuple dstNpt = new NodePortTuple(2L, 1);
+
+ LinkInfo info;
+
+ info = new LinkInfo(System.currentTimeMillis() - 40000,
+ System.currentTimeMillis() - 40000, null,
+ 0, 0);
+ topology.addOrUpdateLink(lt, info);
+
+ // check invariants hold
+ assertNotNull(topology.switchLinks.get(lt.getSrc()));
+ assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
+ assertNotNull(topology.portLinks.get(srcNpt));
+ assertTrue(topology.portLinks.get(srcNpt).contains(lt));
+ assertNotNull(topology.portLinks.get(dstNpt));
+ assertTrue(topology.portLinks.get(dstNpt).contains(lt));
+ assertTrue(topology.links.containsKey(lt));
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
+ topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
+ topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
+
+ topology.timeoutLinks();
+
+
+ info = new LinkInfo(System.currentTimeMillis(),/* firstseen */
+ null,/* unicast */
+ System.currentTimeMillis(), 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
+ assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+
+
+ // Add a link info based on info that woudld be obtained from unicast LLDP
+ // Setting the unicast LLDP reception time to be 40 seconds old, so we can use
+ // this to test timeout after this test. Although the info is initialized
+ // with LT_OPENFLOW_LINK, the link property should be changed to LT_NON_OPENFLOW
+ // by the addOrUpdateLink method.
+ info = new LinkInfo(System.currentTimeMillis() - 40000,
+ System.currentTimeMillis() - 40000, null, 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
+ topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
+ topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
+
+ // Expect to timeout the unicast Valid Time, but not the multicast Valid time
+ // So the link type should go back to non-openflow link.
+ topology.timeoutLinks();
+ assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
+ assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+
+ // Set the multicastValidTime to be old and see if that also times out.
+ info = new LinkInfo(System.currentTimeMillis() - 40000,
+ null, System.currentTimeMillis() - 40000, 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ topology.timeoutLinks();
+ assertTrue(topology.links.get(lt) == null);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
+ topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
+ topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
+
+
+ // Test again only with multicast LLDP
+ info = new LinkInfo(System.currentTimeMillis() - 40000,
+ null, System.currentTimeMillis() - 40000, 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
+ assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+
+ // Call timeout and check if link is no longer present.
+ topology.timeoutLinks();
+ assertTrue(topology.links.get(lt) == null);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
+ topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
+ topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
+
+ // Start clean and see if loops are also added.
+ lt = new Link(1L, 1, 1L, 2);
+ srcNpt = new NodePortTuple(1L, 1);
+ dstNpt = new NodePortTuple(1L, 2);
+ info = new LinkInfo(System.currentTimeMillis() - 40000,
+ null, System.currentTimeMillis() - 40000, 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+
+
+ // Start clean and see if loops are also added.
+ lt = new Link(1L, 1, 1L, 3);
+ srcNpt = new NodePortTuple(1L, 1);
+ dstNpt = new NodePortTuple(1L, 3);
+ info = new LinkInfo(System.currentTimeMillis() - 40000,
+ null, System.currentTimeMillis() - 40000, 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+
+
+ // Start clean and see if loops are also added.
+ lt = new Link(1L, 4, 1L, 5);
+ srcNpt = new NodePortTuple(1L, 4);
+ dstNpt = new NodePortTuple(1L, 5);
+ info = new LinkInfo(System.currentTimeMillis() - 40000,
+ null, System.currentTimeMillis() - 40000, 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+
+
+ // Start clean and see if loops are also added.
+ lt = new Link(1L, 3, 1L, 5);
+ srcNpt = new NodePortTuple(1L, 3);
+ dstNpt = new NodePortTuple(1L, 5);
+ info = new LinkInfo(System.currentTimeMillis() - 40000,
+ null, System.currentTimeMillis() - 40000, 0, 0);
+ topology.addOrUpdateLink(lt, info);
+ assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+ assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+ }
+
+ @Test
+ public void testHARoleChange() throws Exception {
+ LinkDiscoveryManager topology = getTopology();
+ IOFSwitch sw1 = createMockSwitch(1L);
+ IOFSwitch sw2 = createMockSwitch(2L);
+ replay(sw1, sw2);
+ Link lt = new Link(1L, 2, 2L, 1);
+ NodePortTuple srcNpt = new NodePortTuple(1L, 2);
+ NodePortTuple dstNpt = new NodePortTuple(2L, 1);
+ LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+ System.currentTimeMillis(), null,
+ 0, 0);
+ topology.addOrUpdateLink(lt, info);
+
+ // check invariants hold
+ assertNotNull(topology.switchLinks.get(lt.getSrc()));
+ assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
+ assertNotNull(topology.portLinks.get(srcNpt));
+ assertTrue(topology.portLinks.get(srcNpt).contains(lt));
+ assertNotNull(topology.portLinks.get(dstNpt));
+ assertTrue(topology.portLinks.get(dstNpt).contains(lt));
+ assertTrue(topology.links.containsKey(lt));
+
+ // check that it clears from memory
+ getMockFloodlightProvider().dispatchRoleChanged(null, Role.SLAVE);
+ assertTrue(topology.switchLinks.isEmpty());
+ getMockFloodlightProvider().dispatchRoleChanged(Role.SLAVE, Role.MASTER);
+ // check that lldps were sent
+ assertTrue(ldm.isSendLLDPsCalled);
+ assertTrue(ldm.isClearLinksCalled);
+ ldm.reset();
+ }
+}
diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java
new file mode 100644
index 0000000..09319bf
--- /dev/null
+++ b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java
@@ -0,0 +1,536 @@
+package net.floodlightcontroller.linkdiscovery.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.floodlightcontroller.linkdiscovery.LinkInfo;
+import net.floodlightcontroller.linkdiscovery.internal.TestableGraphDBOperation.TestPortObject;
+import net.floodlightcontroller.routing.Link;
+import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkStorage;
+import net.onrc.onos.util.GraphDBConnection;
+import net.onrc.onos.util.GraphDBOperation;
+
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openflow.protocol.OFPhysicalPort;
+import org.openflow.util.HexString;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({LinkStorageImpl.class, GraphDBConnection.class, GraphDBOperation.class})
+public class LinkStorageImplTest {
+ protected static Logger log = LoggerFactory.getLogger(LinkStorageImplTest.class);
+
+ private static ILinkStorage linkStorage;
+
+ // Mock GraphDBConnection (do nothing)
+ private static GraphDBConnection conn;
+
+ // Mock GraphDBOperation (mocks port-related methods only)
+ private static TestableGraphDBOperation ope;
+
+ /**
+ * Setup code called before each tests.
+ * Read test graph data and replace DB access by test graph data.
+ * @throws Exception
+ */
+ @Before
+ public void setUp() throws Exception{
+ PowerMock.mockStatic(GraphDBConnection.class);
+ PowerMock.suppress(PowerMock.constructor(GraphDBConnection.class));
+ conn = PowerMock.createNiceMock(GraphDBConnection.class);
+ EasyMock.expect(GraphDBConnection.getInstance((String)EasyMock.anyObject())).andReturn(conn).anyTimes();
+ PowerMock.replay(GraphDBConnection.class);
+
+ ope = new TestableGraphDBOperation();
+ PowerMock.expectNew(GraphDBOperation.class, (GraphDBConnection)EasyMock.anyObject()).andReturn(ope).anyTimes();
+ PowerMock.replay(GraphDBOperation.class);
+
+ linkStorage = new LinkStorageImpl();
+ linkStorage.init("/dummy/path/to/conf");
+
+ initLinks();
+ }
+
+ /**
+ * Closing code called after each tests.
+ * Discard test graph data.
+ * @throws Exception
+ */
+ @After
+ public void tearDown() throws Exception {
+ // finish code
+ linkStorage.close();
+ ope.close();
+ }
+
+ // TODO: remove @Ignore after UPDATE method is implemented
+ /**
+ * Test if update() can correctly updates LinkInfo for a Link.
+ */
+ @Ignore @Test
+ public void testUpdate_UpdateSingleLink() {
+ Link linkToUpdate= createExistingLink();
+ long currentTime = System.currentTimeMillis();
+ LinkInfo infoToUpdate = createFeasibleLinkInfo(currentTime);
+ LinkInfo infoToVerify = createFeasibleLinkInfo(currentTime);
+
+ linkStorage.update(linkToUpdate, infoToUpdate, ILinkStorage.DM_OPERATION.UPDATE);
+
+ doTestLinkHasStateOf(linkToUpdate, infoToVerify);
+ }
+
+ /**
+ * Test if update() can correctly creates a Link.
+ */
+ @Test
+ public void testUpdate_CreateSingleLink() {
+ Link linkToCreate = createFeasibleLink();
+ Link linkToVerify = createFeasibleLink();
+
+ //Use the link storage API to add the link
+ linkStorage.update(linkToCreate, ILinkStorage.DM_OPERATION.CREATE);
+ doTestLinkExist(linkToVerify);
+ }
+
+ /**
+ * Test if update() can correctly inserts a Link.
+ */
+ @Test
+ public void testUpdate_InsertSingleLink(){
+ Link linkToInsert = createFeasibleLink();
+ Link linkToVerify = createFeasibleLink();
+
+ //Use the link storage API to add the link
+ linkStorage.update(linkToInsert, ILinkStorage.DM_OPERATION.INSERT);
+ doTestLinkExist(linkToVerify);
+ }
+
+ /**
+ * Test if update() can correctly deletes a Link.
+ */
+ @Test
+ public void testUpdate_DeleteSingleLink(){
+ Link linkToDelete = createExistingLink();
+ Link linkToVerify = createExistingLink();
+
+ // Test deletion of existing link
+ linkStorage.update(linkToDelete, DM_OPERATION.DELETE);
+ doTestLinkNotExist(linkToVerify);
+ }
+
+ /**
+ * Test if update() can correctly creates multiple Links.
+ */
+ @Test
+ public void testUpdate_CreateLinks(){
+ List<Link> linksToCreate = createFeasibleLinks();
+ List<Link> linksToVerify = createFeasibleLinks();
+
+ // Test creation of new links
+ linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
+ for(Link l : linksToVerify) {
+ doTestLinkExist(l);
+ }
+ }
+
+ /**
+ * Test if update() can handle mixture of normal/abnormal input for creation of Links.
+ * Deprecated: DBOperation is responsible.
+ */
+ @Ignore @Test
+ public void testUpdate_CreateLinks_Mixuture(){
+ List<Link> linksToCreate = new ArrayList<Link>();
+ linksToCreate.add(createFeasibleLink());
+ linksToCreate.add(createExistingLink());
+
+ // Test creation of mixture of new/existing links
+ linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
+ doTestLinkExist(createFeasibleLink());
+ doTestLinkExist(createExistingLink());
+ }
+
+ /**
+ * Test if update() can correctly inserts multiple Links.
+ */
+ @Test
+ public void testUpdate_InsertLinks(){
+ List<Link> linksToInsert = createFeasibleLinks();
+ List<Link> linksToVerify = createFeasibleLinks();
+
+ // Test insertion of new links
+ linkStorage.update(linksToInsert, ILinkStorage.DM_OPERATION.INSERT);
+ for(Link l : linksToVerify) {
+ doTestLinkExist(l);
+ }
+ }
+
+ /**
+ * Test if update() can handle mixture of normal/abnormal input for creation of Links.
+ */
+ @Ignore @Test
+ public void testUpdate_InsertLinks_Mixuture(){
+ List<Link> linksToInsert = new ArrayList<Link>();
+ linksToInsert.add(createFeasibleLink());
+ linksToInsert.add(createExistingLink());
+
+ // Test insertion of mixture of new/existing links
+ linkStorage.update(linksToInsert, ILinkStorage.DM_OPERATION.INSERT);
+ doTestLinkExist(createFeasibleLink());
+ doTestLinkExist(createExistingLink());
+ }
+
+ /**
+ * Test if update() can correctly deletes multiple Links.
+ */
+ @Test
+ public void testUpdate_DeleteLinks(){
+ List<Link> linksToDelete = createExistingLinks();
+ List<Link> linksToVerify = createExistingLinks();
+
+ // Test deletion of existing links
+ linkStorage.update(linksToDelete, ILinkStorage.DM_OPERATION.DELETE);
+ for(Link l : linksToVerify) {
+ doTestLinkNotExist(l);
+ }
+ }
+
+ /**
+ * Test if update() can handle mixture of normal/abnormal input for deletion of Links.
+ */
+ @Ignore @Test
+ public void testUpdate_DeleteLinks_Mixuture(){
+ List<Link> linksToDelete = new ArrayList<Link>();
+ linksToDelete.add(createFeasibleLink());
+ linksToDelete.add(createExistingLink());
+
+ // Test deletion of mixture of new/existing links
+ linkStorage.update(linksToDelete, ILinkStorage.DM_OPERATION.DELETE);
+ doTestLinkNotExist(createFeasibleLink());
+ doTestLinkNotExist(createExistingLink());
+ }
+
+ // TODO: remove @Ignore after UPDATE method is implemented
+ /**
+ * Test if updateLink() can correctly updates LinkInfo for a Link.
+ */
+ @Ignore @Test
+ public void testUpdateLink_Update() {
+ Link linkToUpdate= createExistingLink();
+ long currentTime = System.currentTimeMillis();
+ LinkInfo infoToUpdate = createFeasibleLinkInfo(currentTime);
+ LinkInfo infoToVerify = createFeasibleLinkInfo(currentTime);
+
+ linkStorage.updateLink(linkToUpdate, infoToUpdate, ILinkStorage.DM_OPERATION.UPDATE);
+
+ doTestLinkHasStateOf(linkToUpdate, infoToVerify);
+ }
+
+ /**
+ * Test if updateLink() can correctly creates a Link.
+ */
+ @Test
+ public void testUpdateLink_Create() {
+ Link linkToCreate = createFeasibleLink();
+ Link linkToVerify = createFeasibleLink();
+
+ //Use the link storage API to add the link
+ linkStorage.updateLink(linkToCreate, null, ILinkStorage.DM_OPERATION.CREATE);
+ doTestLinkExist(linkToVerify);
+ }
+
+ /**
+ * Test if updateLink() can correctly inserts a Link.
+ */
+ @Test
+ public void testUpdateLink_Insert() {
+ Link linkToInsert = createFeasibleLink();
+ Link linkToVerify = createFeasibleLink();
+
+ //Use the link storage API to add the link
+ linkStorage.updateLink(linkToInsert, null, ILinkStorage.DM_OPERATION.INSERT);
+
+ doTestLinkExist(linkToVerify);
+ }
+
+ // TODO: Check if addOrUpdateLink() should accept DELETE operation. If not, remove this test.
+ /**
+ * Test if updateLink() can correctly deletes a Link.
+ */
+ @Ignore @Test
+ public void testUpdateLink_Delete() {
+ Link linkToDelete = createExistingLink();
+ Link linkToVerify = createExistingLink();
+
+ // Test deletion of existing link
+ linkStorage.updateLink(linkToDelete, null, DM_OPERATION.DELETE);
+ doTestLinkNotExist(linkToVerify);
+
+ linkToDelete = createFeasibleLink();
+ linkToVerify = createFeasibleLink();
+
+ // Test deletion of not-existing link
+ linkStorage.updateLink(linkToDelete, null, DM_OPERATION.DELETE);
+ doTestLinkNotExist(linkToVerify);
+ }
+
+ /**
+ * Test if getLinks() can correctly return Links connected to specific DPID and port.
+ */
+ @Test
+ public void testGetLinks_ByDpidPort(){
+ Link linkToVerify = createExistingLink();
+ Long dpid = linkToVerify.getSrc();
+ short port = (short)linkToVerify.getSrcPort();
+
+ List<Link> list = linkStorage.getLinks(dpid, port);
+
+ assertEquals(list.size(), 1);
+
+ Link l = list.get(0);
+ assertEquals(l.getSrc(), linkToVerify.getSrc());
+ assertEquals(l.getSrcPort(), linkToVerify.getSrcPort());
+ assertEquals(l.getDst(), linkToVerify.getDst());
+ assertEquals(l.getDstPort(), linkToVerify.getDstPort());
+
+ Link linkToVerifyNot = createFeasibleLink();
+
+ List<Link> list2 = linkStorage.getLinks(linkToVerifyNot.getSrc(), (short)linkToVerifyNot.getSrcPort());
+
+ assertEquals(list2.size(), 0);
+ }
+
+ /**
+ * Test if getLinks() can correctly return Links connected to specific MAC address.
+ */
+ @Test
+ public void testGetLinks_ByString() {
+ Link linkToVeryfy = createExistingLink();
+ String dpid = HexString.toHexString(linkToVeryfy.getSrc());
+
+ List<Link> links = linkStorage.getLinks(dpid);
+ assertTrue(links.contains(linkToVeryfy));
+
+ Link linkToVerifyNot = createFeasibleLink();
+ assertFalse(links.contains(linkToVerifyNot));
+ }
+
+ /**
+ * Test if deleteLink() can correctly delete a Link.
+ */
+ @Test
+ public void testDeleteLink() {
+ // Deletion of existing link
+ Link linkToDelete = createExistingLink();
+ Link linkToVerify = createExistingLink();
+
+ linkStorage.deleteLink(linkToDelete);
+ doTestLinkNotExist(linkToVerify);
+ }
+
+ /**
+ * Test if deleteLinks() can correctly delete Links.
+ */
+ @Test
+ public void testDeleteLinks(){
+ List<Link> linksToDelete = createExistingLinks();
+ List<Link> linksToVerify = createExistingLinks();
+
+ linkStorage.deleteLinks(linksToDelete);
+ for(Link l : linksToVerify) {
+ doTestLinkNotExist(l);
+ }
+ }
+
+ /**
+ * Test if deleteLinks() can handle mixture of normal/abnormal input.
+ */
+ @Ignore @Test
+ public void testDeleteLinks_Mixture(){
+ List<Link> linksToDelete = new ArrayList<Link>();
+ linksToDelete.add(createFeasibleLink());
+ linksToDelete.add(createExistingLink());
+
+ // Test deletion of mixture of new/existing links
+ linkStorage.deleteLinks(linksToDelete);
+ doTestLinkNotExist(createFeasibleLink());
+ doTestLinkNotExist(createExistingLink());
+ }
+
+ /**
+ * Test if getActiveLinks() can correctly return active Links.
+ */
+ @Test
+ public void testGetActiveLinks() {
+ Link existingLink = createExistingLink();
+ Link notExistingLink = createFeasibleLink();
+
+ List<Link> links = linkStorage.getActiveLinks();
+
+ assertTrue(links.contains(existingLink));
+ assertFalse(links.contains(notExistingLink));
+ }
+
+ /**
+ * Test if deleteLinksOnPort() can delete Links.
+ */
+ @Test
+ public void testDeleteLinksOnPort() {
+ Link linkToDelete = createExistingLink();
+ Link linkToVerify = createExistingLink();
+
+ linkStorage.deleteLinksOnPort(linkToDelete.getSrc(), linkToDelete.getSrcPort());
+
+ doTestLinkNotExist(linkToVerify);
+ }
+
+ /**
+ * Test if specific link is existing
+ * @param link
+ */
+ private void doTestLinkExist(Link link) {
+ assertTrue(ope.hasLinkBetween(HexString.toHexString(link.getSrc()),
+ link.getSrcPort(),
+ HexString.toHexString(link.getDst()),
+ link.getDstPort()));
+ }
+
+ /**
+ * Test if titanGraph doesn't have specific link
+ * @param link
+ */
+ private void doTestLinkNotExist(Link link) {
+ assertFalse(ope.hasLinkBetween(HexString.toHexString(link.getSrc()),
+ link.getSrcPort(),
+ HexString.toHexString(link.getDst()),
+ link.getDstPort()));
+ }
+
+ /**
+ * Test if titanGraph has specific Link with specific LinkInfo
+ * @param link
+ */
+ private void doTestLinkHasStateOf(Link link, LinkInfo info) {
+ }
+
+ //----------------- Creation of test data -----------------------
+ // Assume a network shown below.
+ //
+ // [dpid1]--+--[port:1]----[port:1]--+--[dpid2]
+ // | |
+ // +--[port:2] [port:2]--+
+ // |
+ // +--[port:3] [port:1]--+--[dpid3]
+ // | |
+ // +--[port:4]----[port:2]--+
+ //
+ // dpid1 : 00:00:00:00:0a:01
+ // dpid2 : 00:00:00:00:0a:02
+ // dpid3 : 00:00:00:00:0a:03
+
+ private void initLinks() {
+ final String dpid1 = "00:00:00:00:0a:01";
+ final String dpid2 = "00:00:00:00:0a:02";
+ final String dpid3 = "00:00:00:00:0a:03";
+
+ ope.createNewSwitchForTest(dpid1).setStateForTest("ACTIVE");
+ ope.createNewSwitchForTest(dpid2).setStateForTest("ACTIVE");
+ ope.createNewSwitchForTest(dpid3).setStateForTest("ACTIVE");
+
+ TestPortObject ports1 [] = {
+ ope.createNewPortForTest(dpid1, (short)1),
+ ope.createNewPortForTest(dpid1, (short)2),
+ ope.createNewPortForTest(dpid1, (short)3),
+ ope.createNewPortForTest(dpid1, (short)4),
+ };
+
+ TestPortObject ports2 [] = {
+ ope.createNewPortForTest(dpid2, (short)1),
+ ope.createNewPortForTest(dpid2, (short)2),
+ };
+
+ TestPortObject ports3 [] = {
+ ope.createNewPortForTest(dpid3, (short)1),
+ ope.createNewPortForTest(dpid3, (short)2),
+ };
+
+ ope.setLinkBetweenPortsForTest(ports1[0], ports2[0]);
+ ope.setLinkBetweenPortsForTest(ports1[3], ports3[1]);
+ }
+
+ /**
+ * Returns new Link object of existing link
+ * @return new Link object
+ */
+ private Link createExistingLink() {
+ return new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1);
+ }
+
+ /**
+ * Returns new Link object of not-existing but feasible link
+ * @return new Link object
+ */
+ private Link createFeasibleLink() {
+ return new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a03"), 1);
+ }
+
+ // make NO sense while test-network data doesn't define physical network (i.e. any link is feasible)
+ @SuppressWarnings("unused")
+ private Link createInfeasibleLink() {
+ return new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a03"), 3);
+ }
+
+ /**
+ * Returns list of Link objects which all has information of existing link in titanGraph
+ * @return ArrayList of new Link objects
+ */
+ private List<Link> createExistingLinks() {
+ List<Link> links = new ArrayList<Link>();
+ links.add(new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1));
+ links.add(new Link(Long.decode("0x0000000000000a01"), 4, Long.decode("0x0000000000000a03"), 2));
+ return links;
+ }
+
+ /**
+ * Returns list of Link objects which all has information of not-existing but feasible link
+ * @return ArrayList of new Link objects
+ */
+ private List<Link> createFeasibleLinks() {
+ List<Link> links = new ArrayList<Link>();
+ links.add(new Link(Long.decode("0x0000000000000a01"), 2, Long.decode("0x0000000000000a02"), 2));
+ links.add(new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a03"), 1));
+ return links;
+ }
+
+ /**
+ * Returns new LinkInfo object with convenient values.
+ * @return LinkInfo object
+ */
+ private LinkInfo createFeasibleLinkInfo(long time) {
+ long time_first = time;
+ long time_last_lldp = time + 50;
+ long time_last_bddp = time + 100;
+ int state_src = OFPhysicalPort.OFPortState.OFPPS_STP_FORWARD.getValue();
+ int state_dst = OFPhysicalPort.OFPortState.OFPPS_STP_LISTEN.getValue();
+
+ return new LinkInfo(time_first,
+ time_last_lldp,
+ time_last_bddp,
+ state_src,
+ state_dst);
+ }
+ //---------------------------------------------------------------
+}
diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestableGraphDBOperation.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestableGraphDBOperation.java
new file mode 100644
index 0000000..e3ad879
--- /dev/null
+++ b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestableGraphDBOperation.java
@@ -0,0 +1,1500 @@
+package net.floodlightcontroller.linkdiscovery.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.easymock.EasyMock;
+import org.openflow.util.HexString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.tinkerpop.blueprints.Direction;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.frames.Adjacency;
+import com.tinkerpop.frames.Incidence;
+import com.tinkerpop.frames.Property;
+import com.tinkerpop.frames.annotations.gremlin.GremlinGroovy;
+import com.tinkerpop.frames.annotations.gremlin.GremlinParam;
+
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.flowcache.web.DatapathSummarySerializer;
+import net.onrc.onos.ofcontroller.util.FlowEntryId;
+import net.onrc.onos.ofcontroller.util.FlowId;
+import net.onrc.onos.util.GraphDBConnection;
+import net.onrc.onos.util.GraphDBOperation;
+import net.onrc.onos.util.IDBConnection;
+
+/**
+ * Mock class of GraphDBOperation which provides additional setter to construct a graph for test.
+ * This object simply caches parameters set up by override interfaces and reflect them when commit().
+ * *ForTest() methods are exempt from cache, parameters through those methods are reflected soon.
+ * @author Naoki Shiota
+ *
+ */
+public class TestableGraphDBOperation extends GraphDBOperation {
+ protected static Logger log = LoggerFactory.getLogger(TestableGraphDBOperation.class);
+
+ protected List<TestSwitchObject> switches;
+ protected List<TestPortObject> ports;
+ protected List<TestDeviceObject> devices;
+ protected List<TestFlowPath> paths;
+ protected List<TestFlowEntry> entries;
+
+ protected List<TestSwitchObject> switchesToAdd;
+ protected List<TestPortObject> portsToAdd;
+ protected List<TestDeviceObject> devicesToAdd;
+ protected List<TestFlowPath> pathsToAdd;
+ protected List<TestFlowEntry> entriesToAdd;
+
+ protected List<TestSwitchObject> switchesToRemove;
+ protected List<TestPortObject> portsToRemove;
+ protected List<TestDeviceObject> devicesToRemove;
+ protected List<TestFlowPath> pathsToRemove;
+ protected List<TestFlowEntry> entriesToRemove;
+
+ // Testable implementations of INetMapTopologyObject interfaces
+
+ public static class TestSwitchObject implements ISwitchObject {
+ private String state,type,dpid;
+ private List<IPortObject> ports;
+ private List<IDeviceObject> devices;
+ private List<IFlowEntry> entries;
+
+ private String stateToUpdate, typeToUpdate, dpidToUpdate;
+ private List<IPortObject> portsToAdd;
+ private List<IPortObject> portsToRemove;
+
+ public TestSwitchObject() {
+ type = "switch";
+
+ ports = new ArrayList<IPortObject>();
+ portsToAdd = new ArrayList<IPortObject>();
+ portsToRemove = new ArrayList<IPortObject>();
+ devices = new ArrayList<IDeviceObject>();
+ entries = new ArrayList<IFlowEntry>();
+
+ clearUncommitedData();
+ }
+
+ public void commit() {
+ for(IPortObject port : portsToAdd) {
+ ports.add(port);
+ }
+ for(IPortObject port : portsToRemove) {
+ ports.remove(port);
+ }
+ if(stateToUpdate != null) { state = stateToUpdate; }
+ if(typeToUpdate != null) { type = typeToUpdate; }
+ if(dpidToUpdate != null) { dpid = dpidToUpdate; }
+
+ clearUncommitedData();
+ }
+
+ public void rollback() {
+ clearUncommitedData();
+ }
+
+ public void clearUncommitedData() {
+ portsToAdd.clear();
+ portsToRemove.clear();
+ stateToUpdate = typeToUpdate = dpidToUpdate = null;
+ }
+
+ public void setStateForTest(String state) { this.state = state; }
+ public void setTypeForTest(String type) { this.type = type; }
+ public void setDpidForTest(String dpid) { this.dpid = dpid; }
+ public void addPortForTest(TestPortObject port) { ports.add(port); }
+ public void addDeviceForTest(TestDeviceObject dev) { devices.add(dev); }
+ public void addEntryForTest(TestFlowEntry entry) { entries.add(entry); }
+
+ @Override
+ @JsonProperty("state")
+ @Property("state")
+ public String getState() { return state; }
+
+ @Override
+ @Property("state")
+ public void setState(String state) { this.stateToUpdate = state; }
+
+ @Override
+ @JsonIgnore
+ @Property("type")
+ public String getType() { return type ; }
+
+ @Override
+ @Property("type")
+ public void setType(String type) { this.typeToUpdate = type; }
+
+ // Not support for test
+ @Override
+ public Vertex asVertex() { return null; }
+
+ @Override
+ @JsonProperty("dpid")
+ @Property("dpid")
+ public String getDPID() { return dpid; }
+
+ @Override
+ @Property("dpid")
+ public void setDPID(String dpid) { this.dpidToUpdate = dpid; }
+
+ @Override
+ @JsonProperty("ports")
+ @Adjacency(label = "on")
+ public Iterable<IPortObject> getPorts() { return ports; }
+
+ @Override
+ @JsonIgnore
+ @GremlinGroovy("_().out('on').has('number',port_num)")
+ public IPortObject getPort(@GremlinParam("port_num") short port_num) {
+ for(IPortObject port : ports) {
+ if(port.getNumber() == port_num) {
+ return port;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ @Adjacency(label = "on")
+ public void addPort(IPortObject port) { portsToAdd.add(port); }
+
+ @Override
+ @Adjacency(label = "on")
+ public void removePort(IPortObject port) { portsToRemove.add(port); }
+
+ @Override
+ @JsonIgnore
+ @GremlinGroovy("_().out('on').out('host')")
+ public Iterable<IDeviceObject> getDevices() { return devices; }
+
+ @Override
+ @JsonIgnore
+ @Incidence(label = "switch", direction = Direction.IN)
+ public Iterable<IFlowEntry> getFlowEntries() { return entries; }
+ }
+
+ public static class TestPortObject implements IPortObject {
+ private String state,type,desc;
+ private Short number;
+ private Integer port_state;
+ private ISwitchObject sw;
+
+ private List<IPortObject> linkedPorts;
+ private List<IDeviceObject> devices;
+ private List<IFlowEntry> inflows,outflows;
+
+ private String stateToUpdate,typeToUpdate,descToUpdate;
+ private Short numberToUpdate;
+ private Integer port_stateToUpdate;
+
+ private List<IPortObject> linkedPortsToAdd;
+ private List<IPortObject> linkedPortsToRemove;
+ private List<IDeviceObject> devicesToAdd;
+ private List<IDeviceObject> devicesToRemove;
+
+
+ public TestPortObject() {
+ type = "port";
+
+ linkedPorts = new ArrayList<IPortObject>();
+ linkedPortsToAdd = new ArrayList<IPortObject>();
+ linkedPortsToRemove = new ArrayList<IPortObject>();
+ devices = new ArrayList<IDeviceObject>();
+ devicesToAdd = new ArrayList<IDeviceObject>();
+ devicesToRemove = new ArrayList<IDeviceObject>();
+ inflows = new ArrayList<IFlowEntry>();
+ outflows = new ArrayList<IFlowEntry>();
+
+ clearUncommitedData();
+ }
+
+ public void commit() {
+ for(IPortObject port : linkedPortsToAdd) { linkedPorts.add(port); }
+ for(IPortObject port : linkedPortsToRemove) { linkedPorts.remove(port); }
+ for(IDeviceObject dev : devicesToAdd) { devices.add(dev); }
+ for(IDeviceObject dev : devicesToRemove) { devices.remove(dev); }
+
+ if(stateToUpdate != null) { state = stateToUpdate; }
+ if(typeToUpdate != null) { type = typeToUpdate; }
+ if(descToUpdate != null) { desc = descToUpdate; }
+ if(numberToUpdate != null) { number = numberToUpdate; }
+ if(port_stateToUpdate != null) { port_state = port_stateToUpdate; }
+
+ clearUncommitedData();
+ }
+
+ public void rollback() {
+ clearUncommitedData();
+ }
+
+ public void clearUncommitedData() {
+ linkedPortsToAdd.clear();
+ linkedPortsToRemove.clear();
+ devicesToAdd.clear();
+ devicesToRemove.clear();
+ stateToUpdate = typeToUpdate = descToUpdate = null;
+ port_stateToUpdate = null;
+ numberToUpdate = null;
+ }
+
+ // Setter methods for test
+ public void setStateForTest(String state) { this.state = state; }
+ public void setTypeForTest(String type) { this.type = type; }
+ public void setDescForTest(String desc) { this.desc = desc; }
+ public void setNumberForTest(Short number) { this.number = number; }
+ public void setPortStateForTest(Integer state) { this.port_state = state; }
+ public void setSwitchForTest(ISwitchObject sw) { this.sw = sw; }
+ public void addLinkedPortForTest(TestPortObject port) { this.linkedPorts.add(port); }
+ public void addInflowForTest(TestFlowEntry entry) { inflows.add(entry); }
+ public void addOutflowForTest(TestFlowEntry entry) { outflows.add(entry); }
+
+ // Override methods for mock IPortObject
+ @Override
+ @JsonProperty("state")
+ @Property("state")
+ public String getState() { return state; }
+
+ @Override
+ @Property("state")
+ public void setState(String state) { this.stateToUpdate = state; }
+
+ @Override
+ @JsonIgnore
+ @Property("type")
+ public String getType() { return type; }
+
+ @Override
+ @Property("type")
+ public void setType(String type) { this.typeToUpdate = type; }
+
+ // not support for test
+ @Override
+ public Vertex asVertex() {
+ return null;
+ }
+
+ @Override
+ @JsonProperty("number")
+ @Property("number")
+ public Short getNumber() { return number; }
+
+ @Override
+ @Property("number")
+ public void setNumber(Short n) { this.numberToUpdate = n; }
+
+ @Override
+ @JsonProperty("desc")
+ @Property("desc")
+ public String getDesc() { return desc; }
+
+ @Override
+ @Property("desc")
+ public void setDesc(String s) { this.descToUpdate = s; }
+
+ @Override
+ @JsonIgnore
+ @Property("port_state")
+ public Integer getPortState() { return port_state; }
+
+ @Override
+ @Property("port_state")
+ public void setPortState(Integer s) { this.port_stateToUpdate = s; }
+
+ @Override
+ @JsonIgnore
+ @Incidence(label = "on", direction = Direction.IN)
+ public ISwitchObject getSwitch() { return sw; }
+
+ @Override
+ @JsonProperty("devices")
+ @Adjacency(label = "host")
+ public Iterable<IDeviceObject> getDevices() { return devices; }
+
+ @Override
+ @Adjacency(label = "host")
+ public void setDevice(IDeviceObject device) { devicesToAdd.add(device); }
+
+ @Override
+ @Adjacency(label = "host")
+ public void removeDevice(IDeviceObject device) { devicesToRemove.add(device); }
+
+ @Override
+ @JsonIgnore
+ @Incidence(label = "inport", direction = Direction.IN)
+ public Iterable<IFlowEntry> getInFlowEntries() { return inflows; }
+
+ @Override
+ @JsonIgnore
+ @Incidence(label = "outport", direction = Direction.IN)
+ public Iterable<IFlowEntry> getOutFlowEntries() { return outflows; }
+
+ @Override
+ @JsonIgnore
+ @Adjacency(label = "link")
+ public Iterable<IPortObject> getLinkedPorts() { return linkedPorts; }
+
+ @Override
+ @Adjacency(label = "link")
+ public void removeLink(IPortObject dest_port) { linkedPortsToRemove.add(dest_port); }
+
+ @Override
+ @Adjacency(label = "link")
+ public void setLinkPort(IPortObject dest_port) { linkedPortsToAdd.add(dest_port); }
+ }
+
+ public static class TestDeviceObject implements IDeviceObject {
+ private String state,type,mac,ipaddr;
+ private List<IPortObject> ports;
+ private List<ISwitchObject> switches;
+
+ private String stateToUpdate,typeToUpdate,macToUpdate,ipaddrToUpdate;
+ private List<IPortObject> portsToAdd;
+ private List<IPortObject> portsToRemove;
+
+ public TestDeviceObject() {
+ type = "device";
+
+ ports = new ArrayList<IPortObject>();
+ portsToAdd = new ArrayList<IPortObject>();
+ portsToRemove = new ArrayList<IPortObject>();
+ switches = new ArrayList<ISwitchObject>();
+
+ clearUncommitedData();
+ }
+
+ public void commit() {
+ for(IPortObject port : portsToAdd) {
+ ports.add(port);
+ }
+ for(IPortObject port : portsToRemove) {
+ ports.remove(port);
+ }
+
+ if(stateToUpdate != null) { state = stateToUpdate; }
+ if(typeToUpdate != null) { type = typeToUpdate; }
+ if(macToUpdate != null) { mac = macToUpdate; }
+ if(ipaddrToUpdate != null) { ipaddr = ipaddrToUpdate; }
+
+ clearUncommitedData();
+ }
+
+ public void rollback() {
+ clearUncommitedData();
+ }
+
+ public void clearUncommitedData() {
+ ports.clear();
+ portsToAdd.clear();
+ portsToRemove.clear();
+
+ stateToUpdate = typeToUpdate = macToUpdate = ipaddrToUpdate = null;
+ }
+
+ // Setter methods for test
+ public void setStateForTest(String state) { this.state = state; }
+ public void setTypeForTest(String type) { this.type = type; }
+ public void setMacForTest(String mac) { this.mac = mac; }
+ public void setIpaddrForTest(String ipaddr) { this.ipaddr = ipaddr; }
+ public void addSwitchForTest(ISwitchObject sw) { switches.add(sw); }
+ public void addPortForTest(IPortObject port) { ports.add(port); }
+
+
+ // Override methods
+ @Override
+ @JsonProperty("state")
+ @Property("state")
+ public String getState() { return state; }
+
+ @Override
+ @Property("state")
+ public void setState(String state) { stateToUpdate = state; }
+
+ @Override
+ @JsonIgnore
+ @Property("type")
+ public String getType() { return type; }
+
+ @Override
+ @Property("type")
+ public void setType(String type) { typeToUpdate = type; }
+
+ @Override
+ public Vertex asVertex() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ @JsonProperty("mac")
+ @Property("dl_addr")
+ public String getMACAddress() { return mac; }
+
+ @Override
+ @Property("dl_addr")
+ public void setMACAddress(String macaddr) { macToUpdate = macaddr; }
+
+ @Override
+ @JsonProperty("ipv4")
+ @Property("nw_addr")
+ public String getIPAddress() { return ipaddr; }
+
+ @Override
+ @Property("dl_addr")
+ public void setIPAddress(String ipaddr) { ipaddrToUpdate = ipaddr; }
+
+ @Override
+ @JsonIgnore
+ @Incidence(label = "host", direction = Direction.IN)
+ public Iterable<IPortObject> getAttachedPorts() {
+ return ports; }
+
+ @Override
+ @JsonIgnore
+ @Incidence(label = "host", direction = Direction.IN)
+ public void setHostPort(IPortObject port) { portsToAdd.add(port); }
+
+ @Override
+ @JsonIgnore
+ @Incidence(label = "host", direction = Direction.IN)
+ public void removeHostPort(IPortObject port) { portsToRemove.add(port); }
+
+ @Override
+ @JsonIgnore
+ @GremlinGroovy("_().in('host').in('on')")
+ public Iterable<ISwitchObject> getSwitch() { return switches; }
+ }
+
+ public static class TestFlowPath implements IFlowPath {
+ private String state,type,flowId,installerId,srcSw,dstSw;
+ private String dataPathSummary,userState;
+ private String matchSrcMac,matchDstMac,matchSrcIpaddr,matchDstIpaddr;
+ private Short srcPort,dstPort,matchEthernetFrameType;
+
+ private List<IFlowEntry> entries;
+ private List<ISwitchObject> switches;
+
+ private String stateToUpdate,typeToUpdate,flowIdToUpdate,installerIdToUpdate,srcSwToUpdate,dstSwToUpdate;
+ private String dataPathSummaryToUpdate,userStateToUpdate;
+ private String matchSrcMacToUpdate,matchDstMacToUpdate,matchSrcIpaddrToUpdate,matchDstIpaddrToUpdate;
+ private Short srcPortToUpdate,dstPortToUpdate,matchEthernetFrameTypeToUpdate;
+
+ private List<IFlowEntry> flowsToAdd;
+ private List<IFlowEntry> flowsToRemove;
+
+ public TestFlowPath() {
+ type = "flow";
+
+ entries = new ArrayList<IFlowEntry>();
+ flowsToAdd = new ArrayList<IFlowEntry>();
+ flowsToRemove = new ArrayList<IFlowEntry>();
+
+ switches = new ArrayList<ISwitchObject>();
+
+ clear();
+ }
+
+ public void commit() {
+ for(IFlowEntry flow : flowsToAdd) {
+ entries.add(flow);
+ }
+ for(IFlowEntry flow : flowsToRemove) {
+ entries.remove(flow);
+ }
+ if(stateToUpdate != null) { state = stateToUpdate; }
+ if(typeToUpdate != null) { type = typeToUpdate; }
+ if(flowIdToUpdate != null) { flowId = flowIdToUpdate; }
+ if(installerIdToUpdate != null) { installerId = installerIdToUpdate; }
+ if(srcSwToUpdate != null) { srcSw = srcSwToUpdate; }
+ if(dstSwToUpdate != null) { dstSw = dstSwToUpdate; }
+ if(dataPathSummaryToUpdate != null) { dataPathSummary = dataPathSummaryToUpdate; }
+ if(userStateToUpdate != null) { userState = userStateToUpdate; }
+ if(matchSrcMacToUpdate != null) { matchSrcMac = matchSrcMacToUpdate; }
+ if(matchDstMacToUpdate != null) { matchDstMac = matchDstMacToUpdate; }
+ if(matchSrcIpaddrToUpdate != null) { matchSrcIpaddr = matchSrcIpaddrToUpdate; }
+ if(matchDstIpaddrToUpdate != null) { matchDstIpaddr = matchDstIpaddrToUpdate; }
+ if(srcPortToUpdate != null) { srcPort = srcPortToUpdate; }
+ if(dstPortToUpdate != null) { dstPort = dstPortToUpdate; }
+ if(matchEthernetFrameTypeToUpdate != null) { matchEthernetFrameType = matchEthernetFrameTypeToUpdate; }
+ }
+
+ public void rollback() {
+ clear();
+ }
+
+ public void clear() {
+ flowsToAdd.clear();
+ flowsToRemove.clear();
+
+ stateToUpdate = typeToUpdate = flowIdToUpdate = installerIdToUpdate = null;
+ srcSwToUpdate = dstSwToUpdate = dataPathSummaryToUpdate = userStateToUpdate = null;
+ matchSrcMacToUpdate = matchDstMacToUpdate = matchSrcIpaddrToUpdate = matchDstIpaddrToUpdate = null;
+ srcPortToUpdate = dstPortToUpdate = matchEthernetFrameTypeToUpdate = null;
+ }
+
+ // Setter methods for test
+ public void setStateForTest(String state) { this.state = state; }
+ public void setTypeForTest(String type) { this.type = type; }
+ public void setFlowIdForTest(String flowId) { this.flowId = flowId; }
+ public void setInstallerIdForTest(String installerId) { this.installerId = installerId; }
+ public void setSrcSwForTest(String srcSw) { this.srcSw = srcSw; }
+ public void setDstSwForTest(String dstSw) { this.dstSw = dstSw; }
+ public void setDataPathSummaryForTest(String dataPathSummary) { this.dataPathSummary = dataPathSummary; }
+ public void setUserStateForTest(String userState) { this.userState = userState; }
+ public void setMatchSrcMacForTest(String matchSrcMac) { this.matchSrcMac = matchSrcMac; }
+ public void setMatchDstMacForTest(String matchDstMac) { this.matchDstMac = matchDstMac; }
+ public void setMatchSrcIpaddrForTest(String matchSrcIpaddr) { this.matchSrcIpaddr = matchSrcIpaddr; }
+ public void setMatchDstIpaddrForTest(String matchDstIpaddr) { this.matchDstIpaddr = matchDstIpaddr; }
+ public void setSrcPortForTest(Short srcPort) { this.srcPort = srcPort; }
+ public void setDstPortForTest(Short dstPort) { this.dstPort = dstPort; }
+ public void setMatchEthernetFrameTypeForTest(Short matchEthernetFrameType) { this.matchEthernetFrameType = matchEthernetFrameType; }
+ public void addFlowEntryForTest(IFlowEntry entry) { entries.add(entry); }
+ public void addSwitchForTest(ISwitchObject sw) { switches.add(sw); }
+
+ @Override
+ @JsonProperty("state")
+ @Property("state")
+ public String getState() { return state; }
+
+ @Override
+ @Property("state")
+ public void setState(String state) { stateToUpdate = state; }
+
+ @Override
+ @JsonIgnore
+ @Property("type")
+ public String getType() { return type; }
+
+ @Override
+ @Property("type")
+ public void setType(String type) { typeToUpdate = type; }
+
+ @Override
+ public Vertex asVertex() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ @JsonProperty("flowId")
+ @Property("flow_id")
+ public String getFlowId() { return flowId; }
+
+ @Override
+ @Property("flow_id")
+ public void setFlowId(String flowId) { flowIdToUpdate = flowId; }
+
+ @Override
+ @JsonProperty("installerId")
+ @Property("installer_id")
+ public String getInstallerId() { return installerId; }
+
+ @Override
+ @Property("installer_id")
+ public void setInstallerId(String installerId) { installerIdToUpdate = installerId; }
+
+ @Override
+ @JsonProperty("srcDpid")
+ @Property("src_switch")
+ public String getSrcSwitch() { return srcSw; }
+
+ @Override
+ @Property("src_switch")
+ public void setSrcSwitch(String srcSwitch) { srcSwToUpdate = srcSwitch; }
+
+ @Override
+ @JsonProperty("srcPort")
+ @Property("src_port")
+ public Short getSrcPort() { return srcPort; }
+
+ @Override
+ @Property("src_port")
+ public void setSrcPort(Short srcPort) { srcPortToUpdate = srcPort; }
+
+ @Override
+ @JsonProperty("dstDpid")
+ @Property("dst_switch")
+ public String getDstSwitch() { return dstSw; }
+
+ @Override
+ @Property("dst_switch")
+ public void setDstSwitch(String dstSwitch) { dstSwToUpdate = dstSwitch; }
+
+ @Override
+ @JsonProperty("dstPort")
+ @Property("dst_port")
+ public Short getDstPort() { return dstPort; }
+
+ @Override
+ @Property("dst_port")
+ public void setDstPort(Short dstPort) { dstPortToUpdate = dstPort; }
+
+ @Override
+ @JsonProperty("dataPath")
+ @JsonSerialize(using = DatapathSummarySerializer.class)
+ @Property("data_path_summary")
+ public String getDataPathSummary() { return dataPathSummary; }
+
+ @Override
+ @Property("data_path_summary")
+ public void setDataPathSummary(String dataPathSummary) { dataPathSummaryToUpdate = dataPathSummary; }
+
+ @Override
+ @JsonIgnore
+ @Adjacency(label = "flow", direction = Direction.IN)
+ public Iterable<IFlowEntry> getFlowEntries() { return entries; }
+
+ @Override
+ @Adjacency(label = "flow", direction = Direction.IN)
+ public void addFlowEntry(IFlowEntry flowEntry) {
+ if(! entries.contains(flowEntry)) {
+ flowsToAdd.add(flowEntry);
+ }
+ }
+
+ @Override
+ @Adjacency(label = "flow", direction = Direction.IN)
+ public void removeFlowEntry(IFlowEntry flowEntry) {
+ if(entries.contains(flowEntry)) {
+ flowsToAdd.add(flowEntry);
+ }
+ }
+
+ @Override
+ @JsonIgnore
+ @Property("matchEthernetFrameType")
+ public Short getMatchEthernetFrameType() { return matchEthernetFrameType; }
+
+ @Override
+ @Property("matchEthernetFrameType")
+ public void setMatchEthernetFrameType(Short matchEthernetFrameType) {
+ matchEthernetFrameTypeToUpdate = matchEthernetFrameType; }
+
+ @Override
+ @JsonIgnore
+ @Property("matchSrcMac")
+ public String getMatchSrcMac() { return matchSrcMac; }
+
+ @Override
+ @Property("matchSrcMac")
+ public void setMatchSrcMac(String matchSrcMac) { matchSrcMacToUpdate = matchSrcMac; }
+
+ @Override
+ @JsonIgnore
+ @Property("matchDstMac")
+ public String getMatchDstMac() { return matchDstMac; }
+
+ @Override
+ @Property("matchDstMac")
+ public void setMatchDstMac(String matchDstMac) { matchDstMacToUpdate = matchDstMac; }
+
+ @Override
+ @JsonIgnore
+ @Property("matchSrcIPv4Net")
+ public String getMatchSrcIPv4Net() { return matchSrcIpaddr; }
+
+ @Override
+ @Property("matchSrcIPv4Net")
+ public void setMatchSrcIPv4Net(String matchSrcIPv4Net) {
+ matchSrcIpaddrToUpdate = matchSrcIPv4Net; }
+
+ @Override
+ @JsonIgnore
+ @Property("matchDstIPv4Net")
+ public String getMatchDstIPv4Net() { return matchDstIpaddr; }
+
+ @Override
+ @Property("matchDstIPv4Net")
+ public void setMatchDstIPv4Net(String matchDstIPv4Net) {
+ matchDstIpaddrToUpdate = matchDstIPv4Net; }
+
+ @Override
+ @JsonIgnore
+ @GremlinGroovy("_().in('flow').out('switch')")
+ public Iterable<ISwitchObject> getSwitches() { return switches; }
+
+ @Override
+ @JsonIgnore
+ @Property("user_state")
+ public String getUserState() { return userState; }
+
+ @Override
+ @Property("user_state")
+ public void setUserState(String userState) { userStateToUpdate = userState; }
+ }
+
+ public static class TestFlowEntry implements IFlowEntry {
+ private String state,type,entryId,dpid,userState,switchState,errorStateType,errorStateCode;
+ private String matchSrcMac,matchDstMac,matchSrcIpaddr,matchDstIpaddr;
+ private Short matchInPort,matchEtherFrameType,actionOutput;
+
+ private IFlowPath flowPath;
+ private ISwitchObject sw;
+ private IPortObject inport,outport;
+
+ private String stateToUpdate,typeToUpdate,entryIdToUpdate,dpidToUpdate,
+ userStateToUpdate,switchStateToUpdate,errorStateTypeToUpdate,errorStateCodeToUpdate;
+ private String matchSrcMacToUpdate,matchDstMacToUpdate,matchSrcIpaddrToUpdate,matchDstIpaddrToUpdate;
+
+ private Short matchInPortToUpdate,matchEtherFrameTypeToUpdate,actionOutputToUpdate;
+
+ private IFlowPath flowPathToUpdate;
+ private ISwitchObject swToUpdate;
+ private IPortObject inportToUpdate,outportToUpdate;
+
+ public TestFlowEntry() {
+ type = "flow_entry";
+
+ clearUncommitedData();
+ }
+
+ public void commit() {
+ if(stateToUpdate != null) { state = stateToUpdate; }
+ if(typeToUpdate != null) { type = typeToUpdate; }
+ if(entryIdToUpdate != null) { entryId = entryIdToUpdate; }
+ if(dpidToUpdate != null) { dpid = dpidToUpdate; }
+ if(userStateToUpdate != null) { userState = userStateToUpdate; }
+ if(switchStateToUpdate != null) { switchState = switchStateToUpdate; }
+ if(errorStateTypeToUpdate != null) { errorStateType = errorStateTypeToUpdate; }
+ if(errorStateCodeToUpdate != null) { errorStateCode = errorStateCodeToUpdate; }
+ if(matchSrcMacToUpdate != null) { matchSrcMac = matchSrcMacToUpdate; }
+ if(matchDstMacToUpdate != null) { matchDstMac = matchDstMacToUpdate; }
+ if(matchSrcIpaddrToUpdate != null) { matchSrcIpaddr = matchSrcIpaddrToUpdate; }
+ if(matchDstIpaddrToUpdate != null) { matchDstIpaddr = matchDstIpaddrToUpdate; }
+ if(matchInPortToUpdate != null) { matchInPort = matchInPortToUpdate; }
+ if(matchEtherFrameTypeToUpdate != null) { matchEtherFrameType = matchEtherFrameTypeToUpdate; }
+ if(actionOutputToUpdate != null) { actionOutput = actionOutputToUpdate; }
+
+ if(flowPathToUpdate != null) { flowPath = flowPathToUpdate; }
+ if(swToUpdate != null) { sw = swToUpdate; }
+ if(inportToUpdate != null) { inport = inportToUpdate; }
+ if(outportToUpdate != null) { outport = outportToUpdate; }
+
+ clearUncommitedData();
+ }
+
+ public void rollback() {
+ clearUncommitedData();
+ }
+
+ public void clearUncommitedData() {
+ stateToUpdate = typeToUpdate = entryIdToUpdate = dpidToUpdate = null;
+ userStateToUpdate = switchStateToUpdate = errorStateTypeToUpdate = errorStateCodeToUpdate = null;
+ matchSrcMacToUpdate = matchDstMacToUpdate = matchSrcIpaddrToUpdate = matchDstIpaddrToUpdate = null;
+ matchInPortToUpdate = matchEtherFrameTypeToUpdate = actionOutputToUpdate = null;
+ flowPathToUpdate = null;
+ swToUpdate = null;
+ inportToUpdate = outportToUpdate = null;
+ }
+
+ // Setter methods for test
+ public void setStateForTest(String state) { this.state = state; }
+ public void setTypeForTest(String type) { this.type = type; }
+ public void setEntryIdForTest(String entryId) { this.entryId = entryId; }
+ public void setDpidForTest(String dpid) { this.dpid = dpid; }
+ public void setUserStateForTest(String userState) { this.userState = userState; }
+ public void setSwitchStateForTest(String switchState) { this.switchState = switchState; }
+ public void setErrorStateTypeForTest(String errorStateType) { this.errorStateType = errorStateType; }
+ public void setErrorStateCodeForTest(String errorStateCode) { this.errorStateCode = errorStateCode; }
+ public void setMatchSrcMacForTest(String matchSrcMac) { this.matchSrcMac = matchSrcMac; }
+ public void setMatchDstMacForTest(String matchDstMac) { this.matchDstMac = matchDstMac; }
+ public void setMatchSrcIpaddrForTest(String matchSrcIpaddr) { this.matchSrcIpaddr = matchSrcIpaddr; }
+ public void setMatchDstIpaddrForTest(String matchDstIpaddr) { this.matchDstIpaddr = matchDstIpaddr; }
+ public void setMatchInPortForTest(Short matchInPort) { this.matchInPort = matchInPort; }
+ public void setMatchEtherFrameTypeForTest(Short matchEtherFrameType) { this.matchEtherFrameType = matchEtherFrameType; }
+ public void setActionOutputForTest(Short actionOutput) { this.actionOutput = actionOutput; }
+ public void setFlowPathForTest(IFlowPath flowPath) { this.flowPath = flowPath; }
+ public void setSwitchForTest(ISwitchObject sw) { this.sw = sw; }
+ public void setInportForTest(IPortObject inport) { this.inport = inport; }
+ public void setOutportForTest(IPortObject outport) { this.outport = outport; }
+
+ @Override
+ @JsonProperty("state")
+ @Property("state")
+ public String getState() { return state; }
+
+ @Override
+ @Property("state")
+ public void setState(String state) { stateToUpdate = state; }
+
+ @Override
+ @JsonIgnore
+ @Property("type")
+ public String getType() { return type; }
+
+ @Override
+ @Property("type")
+ public void setType(String type) { typeToUpdate = type; }
+
+ @Override
+ public Vertex asVertex() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ @Property("flow_entry_id")
+ public String getFlowEntryId() { return entryId; }
+
+ @Override
+ @Property("flow_entry_id")
+ public void setFlowEntryId(String flowEntryId) { entryIdToUpdate = flowEntryId; }
+
+ @Override
+ @Property("switch_dpid")
+ public String getSwitchDpid() { return dpid; }
+
+ @Override
+ @Property("switch_dpid")
+ public void setSwitchDpid(String switchDpid) { dpidToUpdate = switchDpid; }
+
+ @Override
+ @Property("user_state")
+ public String getUserState() { return userState; }
+
+ @Override
+ @Property("user_state")
+ public void setUserState(String userState) { userStateToUpdate = userState; }
+
+ @Override
+ @Property("switch_state")
+ public String getSwitchState() { return switchState; }
+
+ @Override
+ @Property("switch_state")
+ public void setSwitchState(String switchState) { switchStateToUpdate = switchState; }
+
+ @Override
+ @Property("error_state_type")
+ public String getErrorStateType() { return errorStateType; }
+
+ @Override
+ @Property("error_state_type")
+ public void setErrorStateType(String errorStateType) { errorStateTypeToUpdate = errorStateType; }
+
+ @Override
+ @Property("error_state_code")
+ public String getErrorStateCode() { return errorStateCode; }
+
+ @Override
+ @Property("error_state_code")
+ public void setErrorStateCode(String errorStateCode) { errorStateCodeToUpdate = errorStateCode; }
+
+ @Override
+ @Property("matchInPort")
+ public Short getMatchInPort() { return matchInPort; }
+
+ @Override
+ @Property("matchInPort")
+ public void setMatchInPort(Short matchInPort) { matchInPortToUpdate = matchInPort; }
+
+ @Override
+ @Property("matchEthernetFrameType")
+ public Short getMatchEthernetFrameType() {return matchEtherFrameType; }
+
+ @Override
+ @Property("matchEthernetFrameType")
+ public void setMatchEthernetFrameType(Short matchEthernetFrameType) { matchEtherFrameTypeToUpdate = matchEthernetFrameType; }
+
+ @Override
+ @Property("matchSrcMac")
+ public String getMatchSrcMac() { return matchSrcMac; }
+
+ @Override
+ @Property("matchSrcMac")
+ public void setMatchSrcMac(String matchSrcMac) { matchSrcMacToUpdate = matchSrcMac; }
+
+ @Override
+ @Property("matchDstMac")
+ public String getMatchDstMac() { return matchDstMac; }
+
+ @Override
+ @Property("matchDstMac")
+ public void setMatchDstMac(String matchDstMac) { matchDstMacToUpdate = matchDstMac; }
+
+ @Override
+ @Property("matchSrcIPv4Net")
+ public String getMatchSrcIPv4Net() { return matchSrcIpaddr; }
+
+ @Override
+ @Property("matchSrcIPv4Net")
+ public void setMatchSrcIPv4Net(String matchSrcIPv4Net) { matchSrcIpaddrToUpdate = matchSrcIPv4Net; }
+
+ @Override
+ @Property("matchDstIPv4Net")
+ public String getMatchDstIPv4Net() { return matchDstIpaddr; }
+
+ @Override
+ @Property("matchDstIPv4Net")
+ public void setMatchDstIPv4Net(String matchDstIPv4Net) { matchDstIpaddrToUpdate = matchDstIPv4Net; }
+
+ @Override
+ @Property("actionOutput")
+ public Short getActionOutput() { return actionOutput; }
+
+ @Override
+ @Property("actionOutput")
+ public void setActionOutput(Short actionOutput) { actionOutputToUpdate = actionOutput; }
+
+ @Override
+ @Adjacency(label = "flow")
+ public IFlowPath getFlow() { return flowPath; }
+
+ @Override
+ @Adjacency(label = "flow")
+ public void setFlow(IFlowPath flow) { flowPathToUpdate = flow; }
+
+ @Override
+ @Adjacency(label = "switch")
+ public ISwitchObject getSwitch() { return sw; }
+
+ @Override
+ @Adjacency(label = "switch")
+ public void setSwitch(ISwitchObject sw) { swToUpdate = sw; }
+
+ @Override
+ @Adjacency(label = "inport")
+ public IPortObject getInPort() { return inport; }
+
+ @Override
+ @Adjacency(label = "inport")
+ public void setInPort(IPortObject port) { inportToUpdate = port; }
+
+ @Override
+ @Adjacency(label = "outport")
+ public IPortObject getOutPort() { return outport; }
+
+ @Override
+ @Adjacency(label = "outport")
+ public void setOutPort(IPortObject port) { outportToUpdate = port; }
+ }
+
+
+ public TestableGraphDBOperation() {
+ super(EasyMock.createNiceMock(GraphDBConnection.class));
+
+ switches = new ArrayList<TestSwitchObject>();
+ ports = new ArrayList<TestPortObject>();
+ devices = new ArrayList<TestDeviceObject>();
+ paths = new ArrayList<TestFlowPath>();
+ entries = new ArrayList<TestFlowEntry>();
+
+ switchesToAdd = new ArrayList<TestSwitchObject>();
+ portsToAdd = new ArrayList<TestPortObject>();
+ devicesToAdd = new ArrayList<TestDeviceObject>();
+ pathsToAdd = new ArrayList<TestFlowPath>();
+ entriesToAdd = new ArrayList<TestFlowEntry>();
+
+ switchesToRemove = new ArrayList<TestSwitchObject>();
+ portsToRemove = new ArrayList<TestPortObject>();
+ devicesToRemove = new ArrayList<TestDeviceObject>();
+ pathsToRemove = new ArrayList<TestFlowPath>();
+ entriesToRemove = new ArrayList<TestFlowEntry>();
+
+ clearUncommitedData();
+ }
+
+ private void clearUncommitedData() {
+ for(TestFlowEntry flow : entries) {
+ flow.clearUncommitedData();
+ }
+ for(TestFlowEntry flow : entriesToAdd) {
+ flow.clearUncommitedData();
+ }
+
+ for(TestDeviceObject dev : devices) {
+ dev.clearUncommitedData();
+ }
+ for(TestDeviceObject dev : devicesToAdd) {
+ dev.clearUncommitedData();
+ }
+
+ for(TestSwitchObject sw : switches) {
+ sw.clearUncommitedData();
+ }
+ for(TestSwitchObject sw : switchesToAdd) {
+ sw.clearUncommitedData();
+ }
+
+ for(TestPortObject port : ports) {
+ port.clearUncommitedData();
+ }
+ for(TestPortObject port : portsToAdd) {
+ port.clearUncommitedData();
+ }
+
+ entriesToAdd.clear();
+ entriesToRemove.clear();
+ devicesToAdd.clear();
+ devicesToRemove.clear();
+ switchesToAdd.clear();
+ switchesToRemove.clear();
+ portsToAdd.clear();
+ portsToRemove.clear();
+ }
+
+
+ // this.*ForTest() methods below are supposed to be used for creation of test topology.
+ /**
+ * Create new empty TestSwitchObject.
+ * @return New TestSwitchObject
+ */
+ public TestSwitchObject createNewSwitchForTest() {
+ TestSwitchObject sw = new TestSwitchObject();
+ switches.add(sw);
+ return sw;
+ }
+
+ /**
+ * Create new TestSwitchObject with specific DPID.
+ * @param dpid DPID to be set
+ * @return New TestSwitchObject
+ */
+ public TestSwitchObject createNewSwitchForTest(String dpid) {
+ for(TestSwitchObject sw_loop : switches) {
+ if(sw_loop.getDPID().equals(dpid)) {
+ // Already created
+ log.error("switch already exists : " + dpid);
+ return sw_loop;
+ }
+ }
+
+ TestSwitchObject sw = new TestSwitchObject();
+
+ sw.setDpidForTest(dpid);
+ switches.add(sw);
+
+ return sw;
+ }
+
+ /**
+ * Create new empty TestPortObject.
+ * @return New TestPortObject
+ */
+ public TestPortObject createNewPortForTest() {
+ TestPortObject port = new TestPortObject();
+ ports.add(port);
+ return port;
+ }
+
+ /**
+ * Create new TestPortObject with specific DPID and port number.
+ * @param dpid DPID to be set
+ * @param number Port number to be set
+ * @return New TestPortObject
+ */
+ public TestPortObject createNewPortForTest(String dpid, Short number) {
+ TestSwitchObject sw = null;
+
+ for(TestSwitchObject sw_loop : switches) {
+ if(sw_loop.getDPID().equals(dpid)) {
+ sw = sw_loop;
+ }
+ }
+
+ if(sw != null) {
+ TestPortObject port = new TestPortObject();
+ port.setNumberForTest(number);
+ port.setSwitchForTest(sw);
+ sw.addPortForTest(port);
+
+ ports.add(port);
+
+ return port;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Link a TestPortObject to other TestPortObject.
+ * @param src TestPortObjecgt of source port.
+ * @param dst TestPortObjecgt of destination port.
+ */
+ public void setLinkBetweenPortsForTest(TestPortObject src, TestPortObject dst) {
+ src.addLinkedPortForTest(dst);
+ }
+
+ /**
+ * Create new empty TestDeviceObject.
+ * @return New TestDeviceObject
+ */
+ public TestDeviceObject createNewDeviceForTest() {
+ TestDeviceObject dev = new TestDeviceObject();
+
+ return dev;
+ }
+
+ /**
+ * Create new empty TestFlowPathObject.
+ * @return New TestFlowPathObject
+ */
+ public TestFlowPath createNewFlowPathForTest() {
+ TestFlowPath path = new TestFlowPath();
+ paths.add(path);
+ return path;
+ }
+
+ /**
+ * Create new empty TestFlowEntryObject.
+ * @return New TestFlowEntryObject
+ */
+ public TestFlowEntry createNewFlowEntryForTest() {
+ TestFlowEntry entry = new TestFlowEntry();
+ entries.add(entry);
+ return entry;
+ }
+
+
+ public boolean hasLinkBetween(String srcSw_str, Short srcNumber, String dstSw_str, Short dstNumber) {
+ IPortObject srcPort = null, dstPort = null;
+ long srcSw = HexString.toLong(srcSw_str);
+ long dstSw = HexString.toLong(dstSw_str);
+
+ for(TestSwitchObject sw : switches) {
+ long swLong = HexString.toLong(sw.getDPID());
+ if(swLong == srcSw) {
+ for(IPortObject port : sw.getPorts()) {
+ if(port.getNumber().equals(srcNumber)) {
+ srcPort = port;
+ }
+ }
+ } else if(swLong == dstSw) {
+ for(IPortObject port : sw.getPorts()) {
+ if(port.getNumber().equals(dstNumber)) {
+ dstPort = port;
+ }
+ }
+ }
+ }
+
+ if(srcPort != null && dstPort != null) {
+ for(IPortObject port : srcPort.getLinkedPorts()) {
+ if(port.equals(dstPort)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ // Overriding methods below are to mock GraphDBOperation class.
+ @Override
+ public ISwitchObject newSwitch(String dpid) {
+ TestSwitchObject sw = new TestSwitchObject();
+ sw.setDPID(dpid);
+ switchesToAdd.add(sw);
+
+ return sw;
+ }
+
+ @Override
+ public ISwitchObject searchSwitch(String dpid_str) {
+ Long dpid = HexString.toLong(dpid_str);
+
+ for(ISwitchObject sw : switches) {
+ if(HexString.toLong(sw.getDPID()) == dpid) {
+ return sw;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public ISwitchObject searchActiveSwitch(String dpid_str) {
+ Long dpid = HexString.toLong(dpid_str);
+
+ for(ISwitchObject sw : switches) {
+ if(HexString.toLong(sw.getDPID()) == dpid && sw.getState().equals("ACTIVE")) {
+ return sw;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Iterable<ISwitchObject> getActiveSwitches() {
+ List<ISwitchObject> list = new ArrayList<ISwitchObject>();
+
+ for(ISwitchObject sw : switches) {
+ if(sw.getState() != null && sw.getState().equals("ACTIVE")) {
+ list.add(sw);
+ }
+ }
+ return list.isEmpty() ? null : list;
+ }
+
+ @Override
+ public Iterable<ISwitchObject> getAllSwitches() {
+ List<ISwitchObject> list = new ArrayList<ISwitchObject>();
+
+ for(ISwitchObject sw : switches) {
+ list.add(sw);
+ }
+
+ return list.isEmpty() ? null : list;
+ }
+
+ @Override
+ public Iterable<ISwitchObject> getInactiveSwitches() {
+ List<ISwitchObject> list = new ArrayList<ISwitchObject>();
+
+ for(ISwitchObject sw : switches) {
+ if(! sw.getState().equals("ACTIVE")) {
+ list.add(sw);
+ }
+ }
+ return list.isEmpty() ? null : list;
+ }
+
+ @Override
+ public Iterable<IFlowEntry> getAllSwitchNotUpdatedFlowEntries() {
+ List<IFlowEntry> list = new ArrayList<IFlowEntry>();
+
+ for(TestFlowEntry entry : entries) {
+ if(entry.getSwitchState().equals("FE_SWITCH_NOT_UPDATED")) {
+ list.add(entry);
+ }
+ }
+ return list;
+ }
+
+ @Override
+ public void removeSwitch(ISwitchObject sw) {
+ if(switches.contains(sw)) {
+ switchesToRemove.add((TestSwitchObject)sw);
+ }
+ }
+
+ @Override
+ public IPortObject newPort(Short portNumber) {
+ TestPortObject port = new TestPortObject();
+ port.setNumber(portNumber);
+
+ return port;
+ }
+
+ public IPortObject newPort(Long dpid, Short portNumber) {
+ TestPortObject port = null;
+ TestSwitchObject sw = (TestSwitchObject)searchSwitch(HexString.toHexString(dpid));
+
+ if(sw != null) {
+ port = (TestPortObject)newPort(portNumber);
+ portsToAdd.add(port);
+ sw.addPort(port);
+ }
+
+ return port;
+ }
+
+ @Override
+ public IPortObject searchPort(String dpid_str, short number) {
+ long dpid = HexString.toLong(dpid_str);
+
+ for(TestSwitchObject sw : switches) {
+ if(HexString.toLong(sw.getDPID()) == dpid) {
+ for(IPortObject port : sw.getPorts()) {
+ if(port.getNumber().equals(number)) {
+ return port;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void removePort(IPortObject port) {
+ for(TestSwitchObject sw : switches) {
+ for(IPortObject pt : sw.getPorts()) {
+ if(pt.equals(port)) {
+ sw.removePort(port);
+ }
+ }
+ }
+ portsToRemove.add((TestPortObject)port);
+ }
+
+ @Override
+ public IDeviceObject newDevice() {
+ TestDeviceObject dev = new TestDeviceObject();
+ devicesToAdd.add(dev);
+
+ return dev;
+ }
+
+ @Override
+ public IDeviceObject searchDevice(String macAddr) {
+ for(IDeviceObject dev : devices) {
+ if(dev.getMACAddress().equals(macAddr)) {
+ return dev;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Iterable<IDeviceObject> getDevices() {
+ List<IDeviceObject> list = new ArrayList<IDeviceObject>();
+
+ for(TestDeviceObject dev : devices) {
+ list.add(dev);
+ }
+
+ return list;
+ }
+
+ @Override
+ public void removeDevice(IDeviceObject dev) {
+ if(devices.contains((TestDeviceObject)dev)) {
+ devicesToRemove.add((TestDeviceObject)dev);
+ }
+ }
+
+ @Override
+ public IFlowPath newFlowPath() {
+ TestFlowPath path = new TestFlowPath();
+ pathsToAdd.add(path);
+
+ return path;
+ }
+
+ @Override
+ public IFlowPath searchFlowPath(FlowId flowId) {
+ for(IFlowPath path : paths) {
+ if(path.getFlowId().equals(flowId)) {
+ return path;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public IFlowPath getFlowPathByFlowEntry(IFlowEntry flowEntry) {
+ for(IFlowPath path : paths) {
+ for(IFlowEntry entry : path.getFlowEntries()) {
+ if(entry.equals(flowEntry)) {
+ return path;
+ }
+ }
+
+ }
+ return null;
+ }
+
+ @Override
+ public Iterable<IFlowPath> getAllFlowPaths() {
+ List<IFlowPath> list = new ArrayList<IFlowPath>();
+
+ for(IFlowPath path : paths) {
+ list.add(path);
+ }
+
+ return list;
+ }
+
+ @Override
+ public void removeFlowPath(IFlowPath flowPath) {
+ if(paths.contains((TestFlowPath)flowPath)) {
+ pathsToRemove.add((TestFlowPath)flowPath);
+ }
+ }
+
+ @Override
+ public IFlowEntry newFlowEntry() {
+ TestFlowEntry entry = new TestFlowEntry();
+ entriesToAdd.add(entry);
+ return entry;
+ }
+
+ @Override
+ public IFlowEntry searchFlowEntry(FlowEntryId flowEntryId) {
+ for(TestFlowEntry entry : entries) {
+ // TODO check if this matching works
+ if(entry.getFlowEntryId().equals(flowEntryId)) {
+ return entry;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Iterable<IFlowEntry> getAllFlowEntries() {
+ List<IFlowEntry> list = new ArrayList<IFlowEntry>();
+
+ for(TestFlowEntry entry : entries) {
+ list.add(entry);
+ }
+
+ return list;
+ }
+
+ @Override
+ public void removeFlowEntry(IFlowEntry flowEntry) {
+ if(entries.contains((TestFlowEntry)flowEntry)) {
+ entriesToRemove.add((TestFlowEntry)flowEntry);
+ }
+ }
+
+ @Override
+ public IDBConnection getDBConnection() {
+ return super.getDBConnection();
+ }
+
+ @Override
+ public void commit() {
+ for(TestSwitchObject sw : switchesToAdd) {
+ switches.add(sw);
+ }
+ for(TestSwitchObject sw : switchesToRemove) {
+ sw.commit();
+ switches.remove(sw);
+ }
+ for(TestSwitchObject sw : switches) {
+ sw.commit();
+ }
+
+ for(TestPortObject port : portsToAdd) {
+ ports.add(port);
+ }
+ for(TestPortObject port : portsToRemove) {
+ port.commit();
+ ports.remove(port);
+ }
+ for(TestPortObject port : ports) {
+ port.commit();
+ }
+
+ for(TestDeviceObject dev : devicesToAdd) {
+ devices.add(dev);
+ }
+ for(TestDeviceObject dev : devicesToRemove) {
+ dev.commit();
+ devices.remove(dev);
+ }
+ for(TestDeviceObject dev : devices) {
+ dev.commit();
+ }
+
+ clearUncommitedData();
+ }
+
+ @Override
+ public void rollback() {
+ clearUncommitedData();
+ }
+
+ @Override
+ public void close() {
+ // TODO Auto-generated method stub
+
+ }
+}
diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestableLinkStorageImpl.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestableLinkStorageImpl.java
new file mode 100644
index 0000000..5709f03
--- /dev/null
+++ b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestableLinkStorageImpl.java
@@ -0,0 +1,39 @@
+package net.floodlightcontroller.linkdiscovery.internal;
+
+import java.util.Set;
+
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
+import com.tinkerpop.blueprints.Vertex;
+
+/**
+ * Seam that allows me to set up a testable instance of LinkStorageImpl that
+ * writes to a file database rather than a Cassandra cluster.
+ * It seems the init() API on LinkStorageImpl might change so I won't rely
+ * on it yet.
+ *
+ * @author jono
+ *
+ */
+
+public class TestableLinkStorageImpl extends LinkStorageImpl {
+ protected TitanGraph graph;
+
+ public TestableLinkStorageImpl(TitanGraph graph){
+ this.graph = graph;
+ }
+
+ @Override
+ public void init(String conf){
+ Set<String> s = graph.getIndexedKeys(Vertex.class);
+ if (!s.contains("dpid")) {
+ graph.createKeyIndex("dpid", Vertex.class);
+ graph.stopTransaction(Conclusion.SUCCESS);
+ }
+ if (!s.contains("type")) {
+ graph.createKeyIndex("type", Vertex.class);
+ graph.stopTransaction(Conclusion.SUCCESS);
+ }
+
+ }
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
index 29151c3..7bf2b1a 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
@@ -5,12 +5,14 @@
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
import net.floodlightcontroller.routing.Link;
import net.onrc.onos.ofcontroller.core.ILinkStorage;
import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
+import net.onrc.onos.ofcontroller.core.internal.TestableGraphDBOperation.TestPortObject;
+import net.onrc.onos.util.GraphDBConnection;
+import net.onrc.onos.util.GraphDBOperation;
import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
import org.easymock.EasyMock;
@@ -24,23 +26,21 @@
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.thinkaurelius.titan.core.TitanFactory;
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.tinkerpop.blueprints.Direction;
-import com.tinkerpop.blueprints.Edge;
-import com.tinkerpop.blueprints.Vertex;
-import com.tinkerpop.gremlin.java.GremlinPipeline;
-import com.tinkerpop.pipes.PipeFunction;
-import com.tinkerpop.pipes.transform.PathPipe;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
@RunWith(PowerMockRunner.class)
-@PrepareForTest({TitanFactory.class})
+@PrepareForTest({LinkStorageImpl.class, GraphDBConnection.class, GraphDBOperation.class})
public class LinkStorageImplTest {
+ protected static Logger log = LoggerFactory.getLogger(LinkStorageImplTest.class);
+
private static ILinkStorage linkStorage;
- private static TitanGraph titanGraph;
- //private static IController
+ // Mock GraphDBConnection (do nothing)
+ private static GraphDBConnection conn;
+
+ // Mock GraphDBOperation (mocks port-related methods only)
+ private static TestableGraphDBOperation ope;
/**
* Setup code called before each tests.
@@ -49,20 +49,20 @@
*/
@Before
public void setUp() throws Exception{
- TestDatabaseManager.deleteTestDatabase();
-
- titanGraph = TestDatabaseManager.getTestDatabase();
- TestDatabaseManager.populateTestData(titanGraph);
-
- // replace return value of TitanFactory.open() to dummy DB created above
- PowerMock.mockStatic(TitanFactory.class);
- EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
- PowerMock.replay(TitanFactory.class);
+ PowerMock.mockStatic(GraphDBConnection.class);
+ PowerMock.suppress(PowerMock.constructor(GraphDBConnection.class));
+ conn = PowerMock.createNiceMock(GraphDBConnection.class);
+ EasyMock.expect(GraphDBConnection.getInstance((String)EasyMock.anyObject())).andReturn(conn).anyTimes();
+ PowerMock.replay(GraphDBConnection.class);
+ ope = new TestableGraphDBOperation();
+ PowerMock.expectNew(GraphDBOperation.class, (GraphDBConnection)EasyMock.anyObject()).andReturn(ope).anyTimes();
+ PowerMock.replay(GraphDBOperation.class);
+
linkStorage = new LinkStorageImpl();
+ linkStorage.init("/dummy/path/to/conf");
- // initialize with dummy string
- linkStorage.init("/dummy/path/to/db");
+ initLinks();
}
/**
@@ -74,9 +74,7 @@
public void tearDown() throws Exception {
// finish code
linkStorage.close();
-
- titanGraph.shutdown();
- TestDatabaseManager.deleteTestDatabase();
+ ope.close();
}
// TODO: remove @Ignore after UPDATE method is implemented
@@ -105,14 +103,7 @@
//Use the link storage API to add the link
linkStorage.update(linkToCreate, ILinkStorage.DM_OPERATION.CREATE);
- doTestLinkIsInGraph(linkToVerify);
-
- // Add same link
- Link linkToCreateTwice = createFeasibleLink();
- linkStorage.update(linkToCreateTwice, ILinkStorage.DM_OPERATION.CREATE);
-
- // this occurs assertion failure if there are two links in titanGraph
- doTestLinkIsInGraph(linkToVerify);
+ doTestLinkExist(linkToVerify);
}
/**
@@ -125,15 +116,7 @@
//Use the link storage API to add the link
linkStorage.update(linkToInsert, ILinkStorage.DM_OPERATION.INSERT);
-
- doTestLinkIsInGraph(linkToVerify);
-
- // Add same link
- Link linkToInsertTwice = createFeasibleLink();
- linkStorage.update(linkToInsertTwice, ILinkStorage.DM_OPERATION.INSERT);
-
- // this occurs assertion failure if there are two links in titanGraph
- doTestLinkIsInGraph(linkToVerify);
+ doTestLinkExist(linkToVerify);
}
/**
@@ -146,14 +129,7 @@
// Test deletion of existing link
linkStorage.update(linkToDelete, DM_OPERATION.DELETE);
- doTestLinkIsNotInGraph(linkToVerify);
-
- linkToDelete = createFeasibleLink();
- linkToVerify = createFeasibleLink();
-
- // Test deletion of not-existing link
- linkStorage.update(linkToDelete, DM_OPERATION.DELETE);
- doTestLinkIsNotInGraph(linkToVerify);
+ doTestLinkNotExist(linkToVerify);
}
/**
@@ -167,21 +143,15 @@
// Test creation of new links
linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
for(Link l : linksToVerify) {
- doTestLinkIsInGraph(l);
- }
-
- // Test creation of existing links
- linksToCreate = createFeasibleLinks();
- linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
- for(Link l : linksToVerify) {
- doTestLinkIsInGraph(l);
+ doTestLinkExist(l);
}
}
/**
* Test if update() can handle mixture of normal/abnormal input for creation of Links.
+ * Deprecated: DBOperation is responsible.
*/
- @Test
+ @Ignore @Test
public void testUpdate_CreateLinks_Mixuture(){
List<Link> linksToCreate = new ArrayList<Link>();
linksToCreate.add(createFeasibleLink());
@@ -189,8 +159,8 @@
// Test creation of mixture of new/existing links
linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
- doTestLinkIsInGraph(createFeasibleLink());
- doTestLinkIsInGraph(createExistingLink());
+ doTestLinkExist(createFeasibleLink());
+ doTestLinkExist(createExistingLink());
}
/**
@@ -204,21 +174,14 @@
// Test insertion of new links
linkStorage.update(linksToInsert, ILinkStorage.DM_OPERATION.INSERT);
for(Link l : linksToVerify) {
- doTestLinkIsInGraph(l);
- }
-
- // Test insertion of existing links
- linksToInsert = createFeasibleLinks();
- linkStorage.update(linksToInsert, ILinkStorage.DM_OPERATION.INSERT);
- for(Link l : linksToVerify) {
- doTestLinkIsInGraph(l);
+ doTestLinkExist(l);
}
}
/**
* Test if update() can handle mixture of normal/abnormal input for creation of Links.
*/
- @Test
+ @Ignore @Test
public void testUpdate_InsertLinks_Mixuture(){
List<Link> linksToInsert = new ArrayList<Link>();
linksToInsert.add(createFeasibleLink());
@@ -226,8 +189,8 @@
// Test insertion of mixture of new/existing links
linkStorage.update(linksToInsert, ILinkStorage.DM_OPERATION.INSERT);
- doTestLinkIsInGraph(createFeasibleLink());
- doTestLinkIsInGraph(createExistingLink());
+ doTestLinkExist(createFeasibleLink());
+ doTestLinkExist(createExistingLink());
}
/**
@@ -241,21 +204,14 @@
// Test deletion of existing links
linkStorage.update(linksToDelete, ILinkStorage.DM_OPERATION.DELETE);
for(Link l : linksToVerify) {
- doTestLinkIsNotInGraph(l);
- }
-
- // Test deletion of not-existing links
- linksToDelete = createExistingLinks();
- linkStorage.update(linksToDelete, ILinkStorage.DM_OPERATION.DELETE);
- for(Link l : linksToVerify) {
- doTestLinkIsNotInGraph(l);
+ doTestLinkNotExist(l);
}
}
/**
* Test if update() can handle mixture of normal/abnormal input for deletion of Links.
*/
- @Test
+ @Ignore @Test
public void testUpdate_DeleteLinks_Mixuture(){
List<Link> linksToDelete = new ArrayList<Link>();
linksToDelete.add(createFeasibleLink());
@@ -263,8 +219,8 @@
// Test deletion of mixture of new/existing links
linkStorage.update(linksToDelete, ILinkStorage.DM_OPERATION.DELETE);
- doTestLinkIsNotInGraph(createFeasibleLink());
- doTestLinkIsNotInGraph(createExistingLink());
+ doTestLinkNotExist(createFeasibleLink());
+ doTestLinkNotExist(createExistingLink());
}
// TODO: remove @Ignore after UPDATE method is implemented
@@ -293,14 +249,7 @@
//Use the link storage API to add the link
linkStorage.updateLink(linkToCreate, null, ILinkStorage.DM_OPERATION.CREATE);
- doTestLinkIsInGraph(linkToVerify);
-
- // Add same link
- Link linkToCreateTwice = createFeasibleLink();
- linkStorage.updateLink(linkToCreateTwice, null, ILinkStorage.DM_OPERATION.CREATE);
-
- // this occurs assertion failure if there are two links in titanGraph
- doTestLinkIsInGraph(linkToVerify);
+ doTestLinkExist(linkToVerify);
}
/**
@@ -314,14 +263,7 @@
//Use the link storage API to add the link
linkStorage.updateLink(linkToInsert, null, ILinkStorage.DM_OPERATION.INSERT);
- doTestLinkIsInGraph(linkToVerify);
-
- // Add same link
- Link linkToInsertTwice = createFeasibleLink();
- linkStorage.updateLink(linkToInsertTwice, null, ILinkStorage.DM_OPERATION.INSERT);
-
- // this occurs assertion failure if there are two links in titanGraph
- doTestLinkIsInGraph(linkToVerify);
+ doTestLinkExist(linkToVerify);
}
// TODO: Check if addOrUpdateLink() should accept DELETE operation. If not, remove this test.
@@ -335,14 +277,14 @@
// Test deletion of existing link
linkStorage.updateLink(linkToDelete, null, DM_OPERATION.DELETE);
- doTestLinkIsNotInGraph(linkToVerify);
+ doTestLinkNotExist(linkToVerify);
linkToDelete = createFeasibleLink();
linkToVerify = createFeasibleLink();
// Test deletion of not-existing link
linkStorage.updateLink(linkToDelete, null, DM_OPERATION.DELETE);
- doTestLinkIsNotInGraph(linkToVerify);
+ doTestLinkNotExist(linkToVerify);
}
/**
@@ -396,14 +338,7 @@
Link linkToVerify = createExistingLink();
linkStorage.deleteLink(linkToDelete);
- doTestLinkIsNotInGraph(linkToVerify);
-
- // Deletion of not existing link
- linkToDelete = createFeasibleLink();
- linkToVerify = createFeasibleLink();
-
- linkStorage.deleteLink(linkToDelete);
- doTestLinkIsNotInGraph(linkToVerify);
+ doTestLinkNotExist(linkToVerify);
}
/**
@@ -416,14 +351,14 @@
linkStorage.deleteLinks(linksToDelete);
for(Link l : linksToVerify) {
- doTestLinkIsNotInGraph(l);
+ doTestLinkNotExist(l);
}
}
/**
* Test if deleteLinks() can handle mixture of normal/abnormal input.
*/
- @Test
+ @Ignore @Test
public void testDeleteLinks_Mixture(){
List<Link> linksToDelete = new ArrayList<Link>();
linksToDelete.add(createFeasibleLink());
@@ -431,8 +366,8 @@
// Test deletion of mixture of new/existing links
linkStorage.deleteLinks(linksToDelete);
- doTestLinkIsNotInGraph(createFeasibleLink());
- doTestLinkIsNotInGraph(createExistingLink());
+ doTestLinkNotExist(createFeasibleLink());
+ doTestLinkNotExist(createExistingLink());
}
/**
@@ -459,57 +394,29 @@
linkStorage.deleteLinksOnPort(linkToDelete.getSrc(), linkToDelete.getSrcPort());
- doTestLinkIsNotInGraph(linkToVerify);
+ doTestLinkNotExist(linkToVerify);
}
/**
- * Test if titanGraph has specific link
+ * Test if specific link is existing
* @param link
*/
- private void doTestLinkIsInGraph(Link link) {
- String src_dpid = HexString.toHexString(link.getSrc());
- String dst_dpid = HexString.toHexString(link.getDst());
- short src_port = link.getSrcPort();
- short dst_port = link.getDstPort();
-
- Iterator<Vertex> it = titanGraph.getVertices("dpid", src_dpid).iterator();
-
- // Test if just one switch is found in the graph
- assertTrue(it.hasNext());
- Vertex sw = it.next();
- assertFalse(it.hasNext());
-
- GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
- pipe.start(sw).out("on").has("number", src_port).out("link").has("number", dst_port).in("on").has("dpid", dst_dpid);
-
- // Test if just one link is found in the graph
- assertTrue(pipe.hasNext());
- pipe.next();
- assertFalse(pipe.hasNext());
+ private void doTestLinkExist(Link link) {
+ assertTrue(ope.hasLinkBetween(HexString.toHexString(link.getSrc()),
+ link.getSrcPort(),
+ HexString.toHexString(link.getDst()),
+ link.getDstPort()));
}
/**
* Test if titanGraph doesn't have specific link
* @param link
*/
- private void doTestLinkIsNotInGraph(Link link) {
- String src_dpid = HexString.toHexString(link.getSrc());
- String dst_dpid = HexString.toHexString(link.getDst());
- short src_port = link.getSrcPort();
- short dst_port = link.getDstPort();
-
- Iterator<Vertex> it = titanGraph.getVertices("dpid", src_dpid).iterator();
-
- // Test if just one switch is found in the graph
- assertTrue(it.hasNext());
- Vertex sw = it.next();
- assertFalse(it.hasNext());
-
- GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
- pipe.start(sw).out("on").has("number", src_port).out("link").has("number", dst_port).in("on").has("dpid", dst_dpid);
-
- // Test if no link is found in the graph
- assertFalse(pipe.hasNext());
+ private void doTestLinkNotExist(Link link) {
+ assertFalse(ope.hasLinkBetween(HexString.toHexString(link.getSrc()),
+ link.getSrcPort(),
+ HexString.toHexString(link.getDst()),
+ link.getDstPort()));
}
/**
@@ -517,74 +424,73 @@
* @param link
*/
private void doTestLinkHasStateOf(Link link, LinkInfo info) {
- String src_dpid = HexString.toHexString(link.getSrc());
- String dst_dpid = HexString.toHexString(link.getDst());
- short src_port = link.getSrcPort();
- short dst_port = link.getDstPort();
-
- Iterator<Vertex> it = titanGraph.getVertices("dpid", src_dpid).iterator();
-
- // Test if just one switch is found in the graph
- assertTrue(it.hasNext());
- Vertex sw = it.next();
- assertFalse(it.hasNext());
-
- GremlinPipeline<Vertex, Edge> pipe = new GremlinPipeline<Vertex, Edge>();
- pipe.start(sw);
- pipe.enablePath();
- pipe.out("on").has("number", src_port).out("link").has("number", dst_port).in("on").has("dpid", dst_dpid)
- .path().step(new PipeFunction<PathPipe<Vertex>, Edge>() {
- @Override
- public Edge compute(PathPipe<Vertex> pipepath) {
- List<Vertex> V = pipepath.next();
-
- Vertex port_src = V.get(1);
- Vertex port_dst = V.get(2);
-
- for(Edge e : port_src.getEdges(Direction.OUT)) {
- if(e.getVertex(Direction.IN).equals(port_dst)) {
- return e;
- }
- }
-
- return null;
- }
- });
-
- // Test if just one link is found in the graph
- assertTrue(pipe.hasNext());
- Edge edge = pipe.next();
- assertTrue(edge != null);
- assertFalse(pipe.hasNext());
-
- // TODO: implement test code to check if update is correctly done.
- assertTrue(false);
}
-
-
+
//----------------- Creation of test data -----------------------
- /**
- * Returns new Link object which has information of existing link in titanGraph
- * @return new Link object
- */
- private Link createExistingLink() {
- // Link from SEA switch port 2 to CHI switch port 1
- return new Link(Long.decode("0x0000000000000a01"), 2, Long.decode("0x0000000000000a03"), 1);
+ // Assume a network shown below.
+ //
+ // [dpid1]--+--[port:1]----[port:1]--+--[dpid2]
+ // | |
+ // +--[port:2] [port:2]--+
+ // |
+ // +--[port:3] [port:1]--+--[dpid3]
+ // | |
+ // +--[port:4]----[port:2]--+
+ //
+ // dpid1 : 00:00:00:00:0a:01
+ // dpid2 : 00:00:00:00:0a:02
+ // dpid3 : 00:00:00:00:0a:03
+
+ private void initLinks() {
+ final String dpid1 = "00:00:00:00:0a:01";
+ final String dpid2 = "00:00:00:00:0a:02";
+ final String dpid3 = "00:00:00:00:0a:03";
+
+ ope.createNewSwitchForTest(dpid1).setStateForTest("ACTIVE");
+ ope.createNewSwitchForTest(dpid2).setStateForTest("ACTIVE");
+ ope.createNewSwitchForTest(dpid3).setStateForTest("ACTIVE");
+
+ TestPortObject ports1 [] = {
+ ope.createNewPortForTest(dpid1, (short)1),
+ ope.createNewPortForTest(dpid1, (short)2),
+ ope.createNewPortForTest(dpid1, (short)3),
+ ope.createNewPortForTest(dpid1, (short)4),
+ };
+
+ TestPortObject ports2 [] = {
+ ope.createNewPortForTest(dpid2, (short)1),
+ ope.createNewPortForTest(dpid2, (short)2),
+ };
+
+ TestPortObject ports3 [] = {
+ ope.createNewPortForTest(dpid3, (short)1),
+ ope.createNewPortForTest(dpid3, (short)2),
+ };
+
+ ope.setLinkBetweenPortsForTest(ports1[0], ports2[0]);
+ ope.setLinkBetweenPortsForTest(ports1[3], ports3[1]);
}
/**
- * Returns new Link object which has information of not-existing but feasible link in titanGraph
+ * Returns new Link object of existing link
+ * @return new Link object
+ */
+ private Link createExistingLink() {
+ return new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1);
+ }
+
+ /**
+ * Returns new Link object of not-existing but feasible link
* @return new Link object
*/
private Link createFeasibleLink() {
- // Link from SEA switch port 1 to LAX switch port 1
- return new Link(Long.decode("0x0000000000000a01"), 4, Long.decode("0x0000000000000a02"), 1);
+ return new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a03"), 1);
}
// make NO sense while test-network data doesn't define physical network (i.e. any link is feasible)
@SuppressWarnings("unused")
private Link createInfeasibleLink() {
- return new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1);
+ return new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a03"), 3);
}
/**
@@ -593,10 +499,8 @@
*/
private List<Link> createExistingLinks() {
List<Link> links = new ArrayList<Link>();
- // Link from SEA switch port 2 to CHI switch port 1
- links.add(new Link(Long.decode("0x0000000000000a01"), 2, Long.decode("0x0000000000000a03"), 1));
- // Link from LAX switch port 1 to SEA switch port 3
- links.add(new Link(Long.decode("0x0000000000000a02"), 1, Long.decode("0x0000000000000a01"), 3));
+ links.add(new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1));
+ links.add(new Link(Long.decode("0x0000000000000a01"), 4, Long.decode("0x0000000000000a03"), 2));
return links;
}
@@ -606,10 +510,8 @@
*/
private List<Link> createFeasibleLinks() {
List<Link> links = new ArrayList<Link>();
- // Link from CHI switch port 4 to NYC switch port 3
- links.add(new Link(Long.decode("0x0000000000000a03"), 4, Long.decode("0x0000000000000a05"), 3));
- // Link from SEA switch port 4 to LAX switch port 1
- links.add(new Link(Long.decode("0x0000000000000a01"), 4, Long.decode("0x0000000000000a02"), 1));
+ links.add(new Link(Long.decode("0x0000000000000a01"), 2, Long.decode("0x0000000000000a02"), 2));
+ links.add(new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a03"), 1));
return links;
}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java
new file mode 100644
index 0000000..31a4bb0
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java
@@ -0,0 +1,1331 @@
+package net.onrc.onos.ofcontroller.core.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.easymock.EasyMock;
+import org.openflow.util.HexString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.frames.annotations.gremlin.GremlinParam;
+
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.util.FlowEntryId;
+import net.onrc.onos.ofcontroller.util.FlowId;
+import net.onrc.onos.util.GraphDBConnection;
+import net.onrc.onos.util.GraphDBOperation;
+import net.onrc.onos.util.IDBConnection;
+
+/**
+ * Mock class of GraphDBOperation which provides additional setter to construct a graph for test.
+ * This object simply caches parameters set up by override interfaces and reflect them when commit().
+ * *ForTest() methods are exempt from cache, parameters through those methods are reflected soon.
+ * @author Naoki Shiota
+ *
+ */
+public class TestableGraphDBOperation extends GraphDBOperation {
+ protected static Logger log = LoggerFactory.getLogger(TestableGraphDBOperation.class);
+
+ protected List<TestSwitchObject> switches;
+ protected List<TestPortObject> ports;
+ protected List<TestDeviceObject> devices;
+ protected List<TestFlowPath> paths;
+ protected List<TestFlowEntry> entries;
+
+ protected List<TestSwitchObject> switchesToAdd;
+ protected List<TestPortObject> portsToAdd;
+ protected List<TestDeviceObject> devicesToAdd;
+ protected List<TestFlowPath> pathsToAdd;
+ protected List<TestFlowEntry> entriesToAdd;
+
+ protected List<TestSwitchObject> switchesToRemove;
+ protected List<TestPortObject> portsToRemove;
+ protected List<TestDeviceObject> devicesToRemove;
+ protected List<TestFlowPath> pathsToRemove;
+ protected List<TestFlowEntry> entriesToRemove;
+
+ // Testable implementations of INetMapTopologyObject interfaces
+
+ public static class TestSwitchObject implements ISwitchObject {
+ private String state,type,dpid;
+ private List<IPortObject> ports;
+ private List<IDeviceObject> devices;
+ private List<IFlowEntry> entries;
+
+ private String stateToUpdate, typeToUpdate, dpidToUpdate;
+ private List<IPortObject> portsToAdd;
+ private List<IPortObject> portsToRemove;
+
+ public TestSwitchObject() {
+ type = "switch";
+
+ ports = new ArrayList<IPortObject>();
+ portsToAdd = new ArrayList<IPortObject>();
+ portsToRemove = new ArrayList<IPortObject>();
+ devices = new ArrayList<IDeviceObject>();
+ entries = new ArrayList<IFlowEntry>();
+
+ clearUncommitedData();
+ }
+
+ public void commit() {
+ for(IPortObject port : portsToAdd) {
+ ports.add(port);
+ }
+ for(IPortObject port : portsToRemove) {
+ ports.remove(port);
+ }
+ if(stateToUpdate != null) { state = stateToUpdate; }
+ if(typeToUpdate != null) { type = typeToUpdate; }
+ if(dpidToUpdate != null) { dpid = dpidToUpdate; }
+
+ clearUncommitedData();
+ }
+
+ public void rollback() {
+ clearUncommitedData();
+ }
+
+ public void clearUncommitedData() {
+ portsToAdd.clear();
+ portsToRemove.clear();
+ stateToUpdate = typeToUpdate = dpidToUpdate = null;
+ }
+
+ public void setStateForTest(String state) { this.state = state; }
+ public void setTypeForTest(String type) { this.type = type; }
+ public void setDpidForTest(String dpid) { this.dpid = dpid; }
+ public void addPortForTest(TestPortObject port) { ports.add(port); }
+ public void addDeviceForTest(TestDeviceObject dev) { devices.add(dev); }
+ public void addEntryForTest(TestFlowEntry entry) { entries.add(entry); }
+
+ @Override
+ public String getState() { return state; }
+
+ @Override
+ public void setState(String state) { this.stateToUpdate = state; }
+
+ @Override
+ public String getType() { return type ; }
+
+ @Override
+ public void setType(String type) { this.typeToUpdate = type; }
+
+ // Not support for test
+ @Override
+ public Vertex asVertex() { return null; }
+
+ @Override
+ public String getDPID() { return dpid; }
+
+ @Override
+ public void setDPID(String dpid) { this.dpidToUpdate = dpid; }
+
+ @Override
+ public Iterable<IPortObject> getPorts() { return ports; }
+
+ @Override
+ public IPortObject getPort(@GremlinParam("port_num") short port_num) {
+ for(IPortObject port : ports) {
+ if(port.getNumber() == port_num) {
+ return port;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void addPort(IPortObject port) { portsToAdd.add(port); }
+
+ @Override
+ public void removePort(IPortObject port) { portsToRemove.add(port); }
+
+ @Override
+ public Iterable<IDeviceObject> getDevices() { return devices; }
+
+ @Override
+ public Iterable<IFlowEntry> getFlowEntries() { return entries; }
+ }
+
+ public static class TestPortObject implements IPortObject {
+ private String state,type,desc;
+ private Short number;
+ private Integer port_state;
+ private ISwitchObject sw;
+
+ private List<IPortObject> linkedPorts;
+ private List<IDeviceObject> devices;
+ private List<IFlowEntry> inflows,outflows;
+
+ private String stateToUpdate,typeToUpdate,descToUpdate;
+ private Short numberToUpdate;
+ private Integer port_stateToUpdate;
+
+ private List<IPortObject> linkedPortsToAdd;
+ private List<IPortObject> linkedPortsToRemove;
+ private List<IDeviceObject> devicesToAdd;
+ private List<IDeviceObject> devicesToRemove;
+
+
+ public TestPortObject() {
+ type = "port";
+
+ linkedPorts = new ArrayList<IPortObject>();
+ linkedPortsToAdd = new ArrayList<IPortObject>();
+ linkedPortsToRemove = new ArrayList<IPortObject>();
+ devices = new ArrayList<IDeviceObject>();
+ devicesToAdd = new ArrayList<IDeviceObject>();
+ devicesToRemove = new ArrayList<IDeviceObject>();
+ inflows = new ArrayList<IFlowEntry>();
+ outflows = new ArrayList<IFlowEntry>();
+
+ clearUncommitedData();
+ }
+
+ public void commit() {
+ for(IPortObject port : linkedPortsToAdd) { linkedPorts.add(port); }
+ for(IPortObject port : linkedPortsToRemove) { linkedPorts.remove(port); }
+ for(IDeviceObject dev : devicesToAdd) { devices.add(dev); }
+ for(IDeviceObject dev : devicesToRemove) { devices.remove(dev); }
+
+ if(stateToUpdate != null) { state = stateToUpdate; }
+ if(typeToUpdate != null) { type = typeToUpdate; }
+ if(descToUpdate != null) { desc = descToUpdate; }
+ if(numberToUpdate != null) { number = numberToUpdate; }
+ if(port_stateToUpdate != null) { port_state = port_stateToUpdate; }
+
+ clearUncommitedData();
+ }
+
+ public void rollback() {
+ clearUncommitedData();
+ }
+
+ public void clearUncommitedData() {
+ linkedPortsToAdd.clear();
+ linkedPortsToRemove.clear();
+ devicesToAdd.clear();
+ devicesToRemove.clear();
+ stateToUpdate = typeToUpdate = descToUpdate = null;
+ port_stateToUpdate = null;
+ numberToUpdate = null;
+ }
+
+ // Setter methods for test
+ public void setStateForTest(String state) { this.state = state; }
+ public void setTypeForTest(String type) { this.type = type; }
+ public void setDescForTest(String desc) { this.desc = desc; }
+ public void setNumberForTest(Short number) { this.number = number; }
+ public void setPortStateForTest(Integer state) { this.port_state = state; }
+ public void setSwitchForTest(ISwitchObject sw) { this.sw = sw; }
+ public void addLinkedPortForTest(TestPortObject port) { this.linkedPorts.add(port); }
+ public void addInflowForTest(TestFlowEntry entry) { inflows.add(entry); }
+ public void addOutflowForTest(TestFlowEntry entry) { outflows.add(entry); }
+
+ // Override methods for mock IPortObject
+ @Override
+ public String getState() { return state; }
+
+ @Override
+ public void setState(String state) { this.stateToUpdate = state; }
+
+ @Override
+ public String getType() { return type; }
+
+ @Override
+ public void setType(String type) { this.typeToUpdate = type; }
+
+ // not support for test
+ @Override
+ public Vertex asVertex() {
+ return null;
+ }
+
+ @Override
+ public Short getNumber() { return number; }
+
+ @Override
+ public void setNumber(Short n) { this.numberToUpdate = n; }
+
+ @Override
+ public String getDesc() { return desc; }
+
+ @Override
+ public void setDesc(String s) { this.descToUpdate = s; }
+
+ @Override
+ public Integer getPortState() { return port_state; }
+
+ @Override
+ public void setPortState(Integer s) { this.port_stateToUpdate = s; }
+
+ @Override
+ public ISwitchObject getSwitch() { return sw; }
+
+ @Override
+ public Iterable<IDeviceObject> getDevices() { return devices; }
+
+ @Override
+ public void setDevice(IDeviceObject device) { devicesToAdd.add(device); }
+
+ @Override
+ public void removeDevice(IDeviceObject device) { devicesToRemove.add(device); }
+
+ @Override
+ public Iterable<IFlowEntry> getInFlowEntries() { return inflows; }
+
+ @Override
+ public Iterable<IFlowEntry> getOutFlowEntries() { return outflows; }
+
+ @Override
+ public Iterable<IPortObject> getLinkedPorts() { return linkedPorts; }
+
+ @Override
+ public void removeLink(IPortObject dest_port) { linkedPortsToRemove.add(dest_port); }
+
+ @Override
+ public void setLinkPort(IPortObject dest_port) { linkedPortsToAdd.add(dest_port); }
+ }
+
+ public static class TestDeviceObject implements IDeviceObject {
+ private String state,type,mac,ipaddr;
+ private List<IPortObject> ports;
+ private List<ISwitchObject> switches;
+
+ private String stateToUpdate,typeToUpdate,macToUpdate,ipaddrToUpdate;
+ private List<IPortObject> portsToAdd;
+ private List<IPortObject> portsToRemove;
+
+ public TestDeviceObject() {
+ type = "device";
+
+ ports = new ArrayList<IPortObject>();
+ portsToAdd = new ArrayList<IPortObject>();
+ portsToRemove = new ArrayList<IPortObject>();
+ switches = new ArrayList<ISwitchObject>();
+
+ clearUncommitedData();
+ }
+
+ public void commit() {
+ for(IPortObject port : portsToAdd) {
+ ports.add(port);
+ }
+ for(IPortObject port : portsToRemove) {
+ ports.remove(port);
+ }
+
+ if(stateToUpdate != null) { state = stateToUpdate; }
+ if(typeToUpdate != null) { type = typeToUpdate; }
+ if(macToUpdate != null) { mac = macToUpdate; }
+ if(ipaddrToUpdate != null) { ipaddr = ipaddrToUpdate; }
+
+ clearUncommitedData();
+ }
+
+ public void rollback() {
+ clearUncommitedData();
+ }
+
+ public void clearUncommitedData() {
+ ports.clear();
+ portsToAdd.clear();
+ portsToRemove.clear();
+
+ stateToUpdate = typeToUpdate = macToUpdate = ipaddrToUpdate = null;
+ }
+
+ // Setter methods for test
+ public void setStateForTest(String state) { this.state = state; }
+ public void setTypeForTest(String type) { this.type = type; }
+ public void setMacForTest(String mac) { this.mac = mac; }
+ public void setIpaddrForTest(String ipaddr) { this.ipaddr = ipaddr; }
+ public void addSwitchForTest(ISwitchObject sw) { switches.add(sw); }
+ public void addPortForTest(IPortObject port) { ports.add(port); }
+
+
+ // Override methods
+ @Override
+ public String getState() { return state; }
+
+ @Override
+ public void setState(String state) { stateToUpdate = state; }
+
+ @Override
+ public String getType() { return type; }
+
+ @Override
+ public void setType(String type) { typeToUpdate = type; }
+
+ @Override
+ public Vertex asVertex() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getMACAddress() { return mac; }
+
+ @Override
+ public void setMACAddress(String macaddr) { macToUpdate = macaddr; }
+
+ @Override
+ public String getIPAddress() { return ipaddr; }
+
+ @Override
+ public void setIPAddress(String ipaddr) { ipaddrToUpdate = ipaddr; }
+
+ @Override
+ public Iterable<IPortObject> getAttachedPorts() {
+ return ports; }
+
+ @Override
+ public void setHostPort(IPortObject port) { portsToAdd.add(port); }
+
+ @Override
+ public void removeHostPort(IPortObject port) { portsToRemove.add(port); }
+
+ @Override
+ public Iterable<ISwitchObject> getSwitch() { return switches; }
+ }
+
+ public static class TestFlowPath implements IFlowPath {
+ private String state,type,flowId,installerId,srcSw,dstSw;
+ private String dataPathSummary,userState;
+ private String matchSrcMac,matchDstMac,matchSrcIpaddr,matchDstIpaddr;
+ private Short srcPort,dstPort,matchEthernetFrameType;
+
+ private List<IFlowEntry> entries;
+ private List<ISwitchObject> switches;
+
+ private String stateToUpdate,typeToUpdate,flowIdToUpdate,installerIdToUpdate,srcSwToUpdate,dstSwToUpdate;
+ private String dataPathSummaryToUpdate,userStateToUpdate;
+ private String matchSrcMacToUpdate,matchDstMacToUpdate,matchSrcIpaddrToUpdate,matchDstIpaddrToUpdate;
+ private Short srcPortToUpdate,dstPortToUpdate,matchEthernetFrameTypeToUpdate;
+
+ private List<IFlowEntry> flowsToAdd;
+ private List<IFlowEntry> flowsToRemove;
+
+ public TestFlowPath() {
+ type = "flow";
+
+ entries = new ArrayList<IFlowEntry>();
+ flowsToAdd = new ArrayList<IFlowEntry>();
+ flowsToRemove = new ArrayList<IFlowEntry>();
+
+ switches = new ArrayList<ISwitchObject>();
+
+ clear();
+ }
+
+ public void commit() {
+ for(IFlowEntry flow : flowsToAdd) {
+ entries.add(flow);
+ }
+ for(IFlowEntry flow : flowsToRemove) {
+ entries.remove(flow);
+ }
+ if(stateToUpdate != null) { state = stateToUpdate; }
+ if(typeToUpdate != null) { type = typeToUpdate; }
+ if(flowIdToUpdate != null) { flowId = flowIdToUpdate; }
+ if(installerIdToUpdate != null) { installerId = installerIdToUpdate; }
+ if(srcSwToUpdate != null) { srcSw = srcSwToUpdate; }
+ if(dstSwToUpdate != null) { dstSw = dstSwToUpdate; }
+ if(dataPathSummaryToUpdate != null) { dataPathSummary = dataPathSummaryToUpdate; }
+ if(userStateToUpdate != null) { userState = userStateToUpdate; }
+ if(matchSrcMacToUpdate != null) { matchSrcMac = matchSrcMacToUpdate; }
+ if(matchDstMacToUpdate != null) { matchDstMac = matchDstMacToUpdate; }
+ if(matchSrcIpaddrToUpdate != null) { matchSrcIpaddr = matchSrcIpaddrToUpdate; }
+ if(matchDstIpaddrToUpdate != null) { matchDstIpaddr = matchDstIpaddrToUpdate; }
+ if(srcPortToUpdate != null) { srcPort = srcPortToUpdate; }
+ if(dstPortToUpdate != null) { dstPort = dstPortToUpdate; }
+ if(matchEthernetFrameTypeToUpdate != null) { matchEthernetFrameType = matchEthernetFrameTypeToUpdate; }
+ }
+
+ public void rollback() {
+ clear();
+ }
+
+ public void clear() {
+ flowsToAdd.clear();
+ flowsToRemove.clear();
+
+ stateToUpdate = typeToUpdate = flowIdToUpdate = installerIdToUpdate = null;
+ srcSwToUpdate = dstSwToUpdate = dataPathSummaryToUpdate = userStateToUpdate = null;
+ matchSrcMacToUpdate = matchDstMacToUpdate = matchSrcIpaddrToUpdate = matchDstIpaddrToUpdate = null;
+ srcPortToUpdate = dstPortToUpdate = matchEthernetFrameTypeToUpdate = null;
+ }
+
+ // Setter methods for test
+ public void setStateForTest(String state) { this.state = state; }
+ public void setTypeForTest(String type) { this.type = type; }
+ public void setFlowIdForTest(String flowId) { this.flowId = flowId; }
+ public void setInstallerIdForTest(String installerId) { this.installerId = installerId; }
+ public void setSrcSwForTest(String srcSw) { this.srcSw = srcSw; }
+ public void setDstSwForTest(String dstSw) { this.dstSw = dstSw; }
+ public void setDataPathSummaryForTest(String dataPathSummary) { this.dataPathSummary = dataPathSummary; }
+ public void setUserStateForTest(String userState) { this.userState = userState; }
+ public void setMatchSrcMacForTest(String matchSrcMac) { this.matchSrcMac = matchSrcMac; }
+ public void setMatchDstMacForTest(String matchDstMac) { this.matchDstMac = matchDstMac; }
+ public void setMatchSrcIpaddrForTest(String matchSrcIpaddr) { this.matchSrcIpaddr = matchSrcIpaddr; }
+ public void setMatchDstIpaddrForTest(String matchDstIpaddr) { this.matchDstIpaddr = matchDstIpaddr; }
+ public void setSrcPortForTest(Short srcPort) { this.srcPort = srcPort; }
+ public void setDstPortForTest(Short dstPort) { this.dstPort = dstPort; }
+ public void setMatchEthernetFrameTypeForTest(Short matchEthernetFrameType) { this.matchEthernetFrameType = matchEthernetFrameType; }
+ public void addFlowEntryForTest(IFlowEntry entry) { entries.add(entry); }
+ public void addSwitchForTest(ISwitchObject sw) { switches.add(sw); }
+
+ @Override
+ public String getState() { return state; }
+
+ @Override
+ public void setState(String state) { stateToUpdate = state; }
+
+ @Override
+ public String getType() { return type; }
+
+ @Override
+ public void setType(String type) { typeToUpdate = type; }
+
+ @Override
+ public Vertex asVertex() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getFlowId() { return flowId; }
+
+ @Override
+ public void setFlowId(String flowId) { flowIdToUpdate = flowId; }
+
+ @Override
+ public String getInstallerId() { return installerId; }
+
+ @Override
+ public void setInstallerId(String installerId) { installerIdToUpdate = installerId; }
+
+ @Override
+ public String getSrcSwitch() { return srcSw; }
+
+ @Override
+ public void setSrcSwitch(String srcSwitch) { srcSwToUpdate = srcSwitch; }
+
+ @Override
+ public Short getSrcPort() { return srcPort; }
+
+ @Override
+ public void setSrcPort(Short srcPort) { srcPortToUpdate = srcPort; }
+
+ @Override
+ public String getDstSwitch() { return dstSw; }
+
+ @Override
+ public void setDstSwitch(String dstSwitch) { dstSwToUpdate = dstSwitch; }
+
+ @Override
+ public Short getDstPort() { return dstPort; }
+
+ @Override
+ public void setDstPort(Short dstPort) { dstPortToUpdate = dstPort; }
+
+ @Override
+ public String getDataPathSummary() { return dataPathSummary; }
+
+ @Override
+ public void setDataPathSummary(String dataPathSummary) { dataPathSummaryToUpdate = dataPathSummary; }
+
+ @Override
+ public Iterable<IFlowEntry> getFlowEntries() { return entries; }
+
+ @Override
+ public void addFlowEntry(IFlowEntry flowEntry) {
+ if(! entries.contains(flowEntry)) {
+ flowsToAdd.add(flowEntry);
+ }
+ }
+
+ @Override
+ public void removeFlowEntry(IFlowEntry flowEntry) {
+ if(entries.contains(flowEntry)) {
+ flowsToAdd.add(flowEntry);
+ }
+ }
+
+ @Override
+ public Short getMatchEthernetFrameType() { return matchEthernetFrameType; }
+
+ @Override
+ public void setMatchEthernetFrameType(Short matchEthernetFrameType) {
+ matchEthernetFrameTypeToUpdate = matchEthernetFrameType; }
+
+ @Override
+ public String getMatchSrcMac() { return matchSrcMac; }
+
+ @Override
+ public void setMatchSrcMac(String matchSrcMac) { matchSrcMacToUpdate = matchSrcMac; }
+
+ @Override
+ public String getMatchDstMac() { return matchDstMac; }
+
+ @Override
+ public void setMatchDstMac(String matchDstMac) { matchDstMacToUpdate = matchDstMac; }
+
+ @Override
+ public String getMatchSrcIPv4Net() { return matchSrcIpaddr; }
+
+ @Override
+ public void setMatchSrcIPv4Net(String matchSrcIPv4Net) {
+ matchSrcIpaddrToUpdate = matchSrcIPv4Net; }
+
+ @Override
+ public String getMatchDstIPv4Net() { return matchDstIpaddr; }
+
+ @Override
+ public void setMatchDstIPv4Net(String matchDstIPv4Net) {
+ matchDstIpaddrToUpdate = matchDstIPv4Net; }
+
+ @Override
+ public Iterable<ISwitchObject> getSwitches() { return switches; }
+
+ @Override
+ public String getUserState() { return userState; }
+
+ @Override
+ public void setUserState(String userState) { userStateToUpdate = userState; }
+ }
+
+ public static class TestFlowEntry implements IFlowEntry {
+ private String state,type,entryId,dpid,userState,switchState,errorStateType,errorStateCode;
+ private String matchSrcMac,matchDstMac,matchSrcIpaddr,matchDstIpaddr;
+ private Short matchInPort,matchEtherFrameType,actionOutput;
+
+ private IFlowPath flowPath;
+ private ISwitchObject sw;
+ private IPortObject inport,outport;
+
+ private String stateToUpdate,typeToUpdate,entryIdToUpdate,dpidToUpdate,
+ userStateToUpdate,switchStateToUpdate,errorStateTypeToUpdate,errorStateCodeToUpdate;
+ private String matchSrcMacToUpdate,matchDstMacToUpdate,matchSrcIpaddrToUpdate,matchDstIpaddrToUpdate;
+
+ private Short matchInPortToUpdate,matchEtherFrameTypeToUpdate,actionOutputToUpdate;
+
+ private IFlowPath flowPathToUpdate;
+ private ISwitchObject swToUpdate;
+ private IPortObject inportToUpdate,outportToUpdate;
+
+ public TestFlowEntry() {
+ type = "flow_entry";
+
+ clearUncommitedData();
+ }
+
+ public void commit() {
+ if(stateToUpdate != null) { state = stateToUpdate; }
+ if(typeToUpdate != null) { type = typeToUpdate; }
+ if(entryIdToUpdate != null) { entryId = entryIdToUpdate; }
+ if(dpidToUpdate != null) { dpid = dpidToUpdate; }
+ if(userStateToUpdate != null) { userState = userStateToUpdate; }
+ if(switchStateToUpdate != null) { switchState = switchStateToUpdate; }
+ if(errorStateTypeToUpdate != null) { errorStateType = errorStateTypeToUpdate; }
+ if(errorStateCodeToUpdate != null) { errorStateCode = errorStateCodeToUpdate; }
+ if(matchSrcMacToUpdate != null) { matchSrcMac = matchSrcMacToUpdate; }
+ if(matchDstMacToUpdate != null) { matchDstMac = matchDstMacToUpdate; }
+ if(matchSrcIpaddrToUpdate != null) { matchSrcIpaddr = matchSrcIpaddrToUpdate; }
+ if(matchDstIpaddrToUpdate != null) { matchDstIpaddr = matchDstIpaddrToUpdate; }
+ if(matchInPortToUpdate != null) { matchInPort = matchInPortToUpdate; }
+ if(matchEtherFrameTypeToUpdate != null) { matchEtherFrameType = matchEtherFrameTypeToUpdate; }
+ if(actionOutputToUpdate != null) { actionOutput = actionOutputToUpdate; }
+
+ if(flowPathToUpdate != null) { flowPath = flowPathToUpdate; }
+ if(swToUpdate != null) { sw = swToUpdate; }
+ if(inportToUpdate != null) { inport = inportToUpdate; }
+ if(outportToUpdate != null) { outport = outportToUpdate; }
+
+ clearUncommitedData();
+ }
+
+ public void rollback() {
+ clearUncommitedData();
+ }
+
+ public void clearUncommitedData() {
+ stateToUpdate = typeToUpdate = entryIdToUpdate = dpidToUpdate = null;
+ userStateToUpdate = switchStateToUpdate = errorStateTypeToUpdate = errorStateCodeToUpdate = null;
+ matchSrcMacToUpdate = matchDstMacToUpdate = matchSrcIpaddrToUpdate = matchDstIpaddrToUpdate = null;
+ matchInPortToUpdate = matchEtherFrameTypeToUpdate = actionOutputToUpdate = null;
+ flowPathToUpdate = null;
+ swToUpdate = null;
+ inportToUpdate = outportToUpdate = null;
+ }
+
+ // Setter methods for test
+ public void setStateForTest(String state) { this.state = state; }
+ public void setTypeForTest(String type) { this.type = type; }
+ public void setEntryIdForTest(String entryId) { this.entryId = entryId; }
+ public void setDpidForTest(String dpid) { this.dpid = dpid; }
+ public void setUserStateForTest(String userState) { this.userState = userState; }
+ public void setSwitchStateForTest(String switchState) { this.switchState = switchState; }
+ public void setErrorStateTypeForTest(String errorStateType) { this.errorStateType = errorStateType; }
+ public void setErrorStateCodeForTest(String errorStateCode) { this.errorStateCode = errorStateCode; }
+ public void setMatchSrcMacForTest(String matchSrcMac) { this.matchSrcMac = matchSrcMac; }
+ public void setMatchDstMacForTest(String matchDstMac) { this.matchDstMac = matchDstMac; }
+ public void setMatchSrcIpaddrForTest(String matchSrcIpaddr) { this.matchSrcIpaddr = matchSrcIpaddr; }
+ public void setMatchDstIpaddrForTest(String matchDstIpaddr) { this.matchDstIpaddr = matchDstIpaddr; }
+ public void setMatchInPortForTest(Short matchInPort) { this.matchInPort = matchInPort; }
+ public void setMatchEtherFrameTypeForTest(Short matchEtherFrameType) { this.matchEtherFrameType = matchEtherFrameType; }
+ public void setActionOutputForTest(Short actionOutput) { this.actionOutput = actionOutput; }
+ public void setFlowPathForTest(IFlowPath flowPath) { this.flowPath = flowPath; }
+ public void setSwitchForTest(ISwitchObject sw) { this.sw = sw; }
+ public void setInportForTest(IPortObject inport) { this.inport = inport; }
+ public void setOutportForTest(IPortObject outport) { this.outport = outport; }
+
+ @Override
+ public String getState() { return state; }
+
+ @Override
+ public void setState(String state) { stateToUpdate = state; }
+
+ @Override
+ public String getType() { return type; }
+
+ @Override
+ public void setType(String type) { typeToUpdate = type; }
+
+ @Override
+ public Vertex asVertex() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getFlowEntryId() { return entryId; }
+
+ @Override
+ public void setFlowEntryId(String flowEntryId) { entryIdToUpdate = flowEntryId; }
+
+ @Override
+ public String getSwitchDpid() { return dpid; }
+
+ @Override
+ public void setSwitchDpid(String switchDpid) { dpidToUpdate = switchDpid; }
+
+ @Override
+ public String getUserState() { return userState; }
+
+ @Override
+ public void setUserState(String userState) { userStateToUpdate = userState; }
+
+ @Override
+ public String getSwitchState() { return switchState; }
+
+ @Override
+ public void setSwitchState(String switchState) { switchStateToUpdate = switchState; }
+
+ @Override
+ public String getErrorStateType() { return errorStateType; }
+
+ @Override
+ public void setErrorStateType(String errorStateType) { errorStateTypeToUpdate = errorStateType; }
+
+ @Override
+ public String getErrorStateCode() { return errorStateCode; }
+
+ @Override
+ public void setErrorStateCode(String errorStateCode) { errorStateCodeToUpdate = errorStateCode; }
+
+ @Override
+ public Short getMatchInPort() { return matchInPort; }
+
+ @Override
+ public void setMatchInPort(Short matchInPort) { matchInPortToUpdate = matchInPort; }
+
+ @Override
+ public Short getMatchEthernetFrameType() {return matchEtherFrameType; }
+
+ @Override
+ public void setMatchEthernetFrameType(Short matchEthernetFrameType) { matchEtherFrameTypeToUpdate = matchEthernetFrameType; }
+
+ @Override
+ public String getMatchSrcMac() { return matchSrcMac; }
+
+ @Override
+ public void setMatchSrcMac(String matchSrcMac) { matchSrcMacToUpdate = matchSrcMac; }
+
+ @Override
+ public String getMatchDstMac() { return matchDstMac; }
+
+ @Override
+ public void setMatchDstMac(String matchDstMac) { matchDstMacToUpdate = matchDstMac; }
+
+ @Override
+ public String getMatchSrcIPv4Net() { return matchSrcIpaddr; }
+
+ @Override
+ public void setMatchSrcIPv4Net(String matchSrcIPv4Net) { matchSrcIpaddrToUpdate = matchSrcIPv4Net; }
+
+ @Override
+ public String getMatchDstIPv4Net() { return matchDstIpaddr; }
+
+ @Override
+ public void setMatchDstIPv4Net(String matchDstIPv4Net) { matchDstIpaddrToUpdate = matchDstIPv4Net; }
+
+ @Override
+ public Short getActionOutput() { return actionOutput; }
+
+ @Override
+ public void setActionOutput(Short actionOutput) { actionOutputToUpdate = actionOutput; }
+
+ @Override
+ public IFlowPath getFlow() { return flowPath; }
+
+ @Override
+ public void setFlow(IFlowPath flow) { flowPathToUpdate = flow; }
+
+ @Override
+ public ISwitchObject getSwitch() { return sw; }
+
+ @Override
+ public void setSwitch(ISwitchObject sw) { swToUpdate = sw; }
+
+ @Override
+ public IPortObject getInPort() { return inport; }
+
+ @Override
+ public void setInPort(IPortObject port) { inportToUpdate = port; }
+
+ @Override
+ public IPortObject getOutPort() { return outport; }
+
+ @Override
+ public void setOutPort(IPortObject port) { outportToUpdate = port; }
+ }
+
+
+ public TestableGraphDBOperation() {
+ super(EasyMock.createNiceMock(GraphDBConnection.class));
+
+ switches = new ArrayList<TestSwitchObject>();
+ ports = new ArrayList<TestPortObject>();
+ devices = new ArrayList<TestDeviceObject>();
+ paths = new ArrayList<TestFlowPath>();
+ entries = new ArrayList<TestFlowEntry>();
+
+ switchesToAdd = new ArrayList<TestSwitchObject>();
+ portsToAdd = new ArrayList<TestPortObject>();
+ devicesToAdd = new ArrayList<TestDeviceObject>();
+ pathsToAdd = new ArrayList<TestFlowPath>();
+ entriesToAdd = new ArrayList<TestFlowEntry>();
+
+ switchesToRemove = new ArrayList<TestSwitchObject>();
+ portsToRemove = new ArrayList<TestPortObject>();
+ devicesToRemove = new ArrayList<TestDeviceObject>();
+ pathsToRemove = new ArrayList<TestFlowPath>();
+ entriesToRemove = new ArrayList<TestFlowEntry>();
+
+ clearUncommitedData();
+ }
+
+ private void clearUncommitedData() {
+ for(TestFlowEntry flow : entries) {
+ flow.clearUncommitedData();
+ }
+ for(TestFlowEntry flow : entriesToAdd) {
+ flow.clearUncommitedData();
+ }
+
+ for(TestDeviceObject dev : devices) {
+ dev.clearUncommitedData();
+ }
+ for(TestDeviceObject dev : devicesToAdd) {
+ dev.clearUncommitedData();
+ }
+
+ for(TestSwitchObject sw : switches) {
+ sw.clearUncommitedData();
+ }
+ for(TestSwitchObject sw : switchesToAdd) {
+ sw.clearUncommitedData();
+ }
+
+ for(TestPortObject port : ports) {
+ port.clearUncommitedData();
+ }
+ for(TestPortObject port : portsToAdd) {
+ port.clearUncommitedData();
+ }
+
+ entriesToAdd.clear();
+ entriesToRemove.clear();
+ devicesToAdd.clear();
+ devicesToRemove.clear();
+ switchesToAdd.clear();
+ switchesToRemove.clear();
+ portsToAdd.clear();
+ portsToRemove.clear();
+ }
+
+
+ // this.*ForTest() methods below are supposed to be used for creation of test topology.
+ /**
+ * Create new empty TestSwitchObject.
+ * @return New TestSwitchObject
+ */
+ public TestSwitchObject createNewSwitchForTest() {
+ TestSwitchObject sw = new TestSwitchObject();
+ switches.add(sw);
+ return sw;
+ }
+
+ /**
+ * Create new TestSwitchObject with specific DPID.
+ * @param dpid DPID to be set
+ * @return New TestSwitchObject
+ */
+ public TestSwitchObject createNewSwitchForTest(String dpid) {
+ for(TestSwitchObject sw_loop : switches) {
+ if(sw_loop.getDPID().equals(dpid)) {
+ // Already created
+ log.error("switch already exists : " + dpid);
+ return sw_loop;
+ }
+ }
+
+ TestSwitchObject sw = new TestSwitchObject();
+
+ sw.setDpidForTest(dpid);
+ switches.add(sw);
+
+ return sw;
+ }
+
+ /**
+ * Create new empty TestPortObject.
+ * @return New TestPortObject
+ */
+ public TestPortObject createNewPortForTest() {
+ TestPortObject port = new TestPortObject();
+ ports.add(port);
+ return port;
+ }
+
+ /**
+ * Create new TestPortObject with specific DPID and port number.
+ * @param dpid DPID to be set
+ * @param number Port number to be set
+ * @return New TestPortObject
+ */
+ public TestPortObject createNewPortForTest(String dpid, Short number) {
+ TestSwitchObject sw = null;
+
+ for(TestSwitchObject sw_loop : switches) {
+ if(sw_loop.getDPID().equals(dpid)) {
+ sw = sw_loop;
+ }
+ }
+
+ if(sw != null) {
+ TestPortObject port = new TestPortObject();
+ port.setNumberForTest(number);
+ port.setSwitchForTest(sw);
+ sw.addPortForTest(port);
+
+ ports.add(port);
+
+ return port;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Link a TestPortObject to other TestPortObject.
+ * @param src TestPortObjecgt of source port.
+ * @param dst TestPortObjecgt of destination port.
+ */
+ public void setLinkBetweenPortsForTest(TestPortObject src, TestPortObject dst) {
+ src.addLinkedPortForTest(dst);
+ }
+
+ /**
+ * Create new empty TestDeviceObject.
+ * @return New TestDeviceObject
+ */
+ public TestDeviceObject createNewDeviceForTest() {
+ TestDeviceObject dev = new TestDeviceObject();
+
+ return dev;
+ }
+
+ /**
+ * Create new empty TestFlowPathObject.
+ * @return New TestFlowPathObject
+ */
+ public TestFlowPath createNewFlowPathForTest() {
+ TestFlowPath path = new TestFlowPath();
+ paths.add(path);
+ return path;
+ }
+
+ /**
+ * Create new empty TestFlowEntryObject.
+ * @return New TestFlowEntryObject
+ */
+ public TestFlowEntry createNewFlowEntryForTest() {
+ TestFlowEntry entry = new TestFlowEntry();
+ entries.add(entry);
+ return entry;
+ }
+
+
+ public boolean hasLinkBetween(String srcSw_str, Short srcNumber, String dstSw_str, Short dstNumber) {
+ IPortObject srcPort = null, dstPort = null;
+ long srcSw = HexString.toLong(srcSw_str);
+ long dstSw = HexString.toLong(dstSw_str);
+
+ for(TestSwitchObject sw : switches) {
+ long swLong = HexString.toLong(sw.getDPID());
+ if(swLong == srcSw) {
+ for(IPortObject port : sw.getPorts()) {
+ if(port.getNumber().equals(srcNumber)) {
+ srcPort = port;
+ }
+ }
+ } else if(swLong == dstSw) {
+ for(IPortObject port : sw.getPorts()) {
+ if(port.getNumber().equals(dstNumber)) {
+ dstPort = port;
+ }
+ }
+ }
+ }
+
+ if(srcPort != null && dstPort != null) {
+ for(IPortObject port : srcPort.getLinkedPorts()) {
+ if(port.equals(dstPort)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ // Overriding methods below are to mock GraphDBOperation class.
+ @Override
+ public ISwitchObject newSwitch(String dpid) {
+ TestSwitchObject sw = new TestSwitchObject();
+ sw.setDPID(dpid);
+ switchesToAdd.add(sw);
+
+ return sw;
+ }
+
+ @Override
+ public ISwitchObject searchSwitch(String dpid_str) {
+ Long dpid = HexString.toLong(dpid_str);
+
+ for(ISwitchObject sw : switches) {
+ if(HexString.toLong(sw.getDPID()) == dpid) {
+ return sw;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public ISwitchObject searchActiveSwitch(String dpid_str) {
+ Long dpid = HexString.toLong(dpid_str);
+
+ for(ISwitchObject sw : switches) {
+ if(HexString.toLong(sw.getDPID()) == dpid && sw.getState().equals("ACTIVE")) {
+ return sw;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Iterable<ISwitchObject> getActiveSwitches() {
+ List<ISwitchObject> list = new ArrayList<ISwitchObject>();
+
+ for(ISwitchObject sw : switches) {
+ if(sw.getState() != null && sw.getState().equals("ACTIVE")) {
+ list.add(sw);
+ }
+ }
+ return list.isEmpty() ? null : list;
+ }
+
+ @Override
+ public Iterable<ISwitchObject> getAllSwitches() {
+ List<ISwitchObject> list = new ArrayList<ISwitchObject>();
+
+ for(ISwitchObject sw : switches) {
+ list.add(sw);
+ }
+
+ return list.isEmpty() ? null : list;
+ }
+
+ @Override
+ public Iterable<ISwitchObject> getInactiveSwitches() {
+ List<ISwitchObject> list = new ArrayList<ISwitchObject>();
+
+ for(ISwitchObject sw : switches) {
+ if(! sw.getState().equals("ACTIVE")) {
+ list.add(sw);
+ }
+ }
+ return list.isEmpty() ? null : list;
+ }
+
+ @Override
+ public Iterable<IFlowEntry> getAllSwitchNotUpdatedFlowEntries() {
+ List<IFlowEntry> list = new ArrayList<IFlowEntry>();
+
+ for(TestFlowEntry entry : entries) {
+ if(entry.getSwitchState().equals("FE_SWITCH_NOT_UPDATED")) {
+ list.add(entry);
+ }
+ }
+ return list;
+ }
+
+ @Override
+ public void removeSwitch(ISwitchObject sw) {
+ if(switches.contains(sw)) {
+ switchesToRemove.add((TestSwitchObject)sw);
+ }
+ }
+
+ @Override
+ public IPortObject newPort(Short portNumber) {
+ TestPortObject port = new TestPortObject();
+ port.setNumber(portNumber);
+
+ return port;
+ }
+
+ public IPortObject newPort(Long dpid, Short portNumber) {
+ TestPortObject port = null;
+ TestSwitchObject sw = (TestSwitchObject)searchSwitch(HexString.toHexString(dpid));
+
+ if(sw != null) {
+ port = (TestPortObject)newPort(portNumber);
+ portsToAdd.add(port);
+ sw.addPort(port);
+ }
+
+ return port;
+ }
+
+ @Override
+ public IPortObject searchPort(String dpid_str, short number) {
+ long dpid = HexString.toLong(dpid_str);
+
+ for(TestSwitchObject sw : switches) {
+ if(HexString.toLong(sw.getDPID()) == dpid) {
+ for(IPortObject port : sw.getPorts()) {
+ if(port.getNumber().equals(number)) {
+ return port;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void removePort(IPortObject port) {
+ for(TestSwitchObject sw : switches) {
+ for(IPortObject pt : sw.getPorts()) {
+ if(pt.equals(port)) {
+ sw.removePort(port);
+ }
+ }
+ }
+ portsToRemove.add((TestPortObject)port);
+ }
+
+ @Override
+ public IDeviceObject newDevice() {
+ TestDeviceObject dev = new TestDeviceObject();
+ devicesToAdd.add(dev);
+
+ return dev;
+ }
+
+ @Override
+ public IDeviceObject searchDevice(String macAddr) {
+ for(IDeviceObject dev : devices) {
+ if(dev.getMACAddress().equals(macAddr)) {
+ return dev;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Iterable<IDeviceObject> getDevices() {
+ List<IDeviceObject> list = new ArrayList<IDeviceObject>();
+
+ for(TestDeviceObject dev : devices) {
+ list.add(dev);
+ }
+
+ return list;
+ }
+
+ @Override
+ public void removeDevice(IDeviceObject dev) {
+ if(devices.contains((TestDeviceObject)dev)) {
+ devicesToRemove.add((TestDeviceObject)dev);
+ }
+ }
+
+ @Override
+ public IFlowPath newFlowPath() {
+ TestFlowPath path = new TestFlowPath();
+ pathsToAdd.add(path);
+
+ return path;
+ }
+
+ @Override
+ public IFlowPath searchFlowPath(FlowId flowId) {
+ for(IFlowPath path : paths) {
+ if(path.getFlowId().equals(flowId)) {
+ return path;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public IFlowPath getFlowPathByFlowEntry(IFlowEntry flowEntry) {
+ for(IFlowPath path : paths) {
+ for(IFlowEntry entry : path.getFlowEntries()) {
+ if(entry.equals(flowEntry)) {
+ return path;
+ }
+ }
+
+ }
+ return null;
+ }
+
+ @Override
+ public Iterable<IFlowPath> getAllFlowPaths() {
+ List<IFlowPath> list = new ArrayList<IFlowPath>();
+
+ for(IFlowPath path : paths) {
+ list.add(path);
+ }
+
+ return list;
+ }
+
+ @Override
+ public void removeFlowPath(IFlowPath flowPath) {
+ if(paths.contains((TestFlowPath)flowPath)) {
+ pathsToRemove.add((TestFlowPath)flowPath);
+ }
+ }
+
+ @Override
+ public IFlowEntry newFlowEntry() {
+ TestFlowEntry entry = new TestFlowEntry();
+ entriesToAdd.add(entry);
+ return entry;
+ }
+
+ @Override
+ public IFlowEntry searchFlowEntry(FlowEntryId flowEntryId) {
+ for(TestFlowEntry entry : entries) {
+ // TODO check if this matching works
+ if(entry.getFlowEntryId().equals(flowEntryId)) {
+ return entry;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Iterable<IFlowEntry> getAllFlowEntries() {
+ List<IFlowEntry> list = new ArrayList<IFlowEntry>();
+
+ for(TestFlowEntry entry : entries) {
+ list.add(entry);
+ }
+
+ return list;
+ }
+
+ @Override
+ public void removeFlowEntry(IFlowEntry flowEntry) {
+ if(entries.contains((TestFlowEntry)flowEntry)) {
+ entriesToRemove.add((TestFlowEntry)flowEntry);
+ }
+ }
+
+ @Override
+ public IDBConnection getDBConnection() {
+ return super.getDBConnection();
+ }
+
+ @Override
+ public void commit() {
+ for(TestSwitchObject sw : switchesToAdd) {
+ switches.add(sw);
+ }
+ for(TestSwitchObject sw : switchesToRemove) {
+ sw.commit();
+ switches.remove(sw);
+ }
+ for(TestSwitchObject sw : switches) {
+ sw.commit();
+ }
+
+ for(TestPortObject port : portsToAdd) {
+ ports.add(port);
+ }
+ for(TestPortObject port : portsToRemove) {
+ port.commit();
+ ports.remove(port);
+ }
+ for(TestPortObject port : ports) {
+ port.commit();
+ }
+
+ for(TestDeviceObject dev : devicesToAdd) {
+ devices.add(dev);
+ }
+ for(TestDeviceObject dev : devicesToRemove) {
+ dev.commit();
+ devices.remove(dev);
+ }
+ for(TestDeviceObject dev : devices) {
+ dev.commit();
+ }
+
+ clearUncommitedData();
+ }
+
+ @Override
+ public void rollback() {
+ clearUncommitedData();
+ }
+
+ @Override
+ public void close() {
+ // TODO Auto-generated method stub
+
+ }
+}