diff --git a/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java b/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java index ba898d2d852d7d256e330f0592978498fec7527c..ab1df5e24a2e5b59792d249aa69f1ffc7476b8c6 100644 --- a/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java +++ b/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java @@ -87,6 +87,13 @@ public interface IFloodlightProviderService extends IFloodlightService { */ public Role getRole(); + /** + * Get the current mapping of controller IDs to their IP addresses + * Returns a copy of the current mapping. + * @see IHAListener + */ + public Map<String,String> getControllerNodeIPs(); + /** * Gets the ID of the controller */ diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java index 3cf597e4258118674d8f4161996aaece5e0039be..0f9f77bf15bde0bde303a72477aee2438cfaaefb 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java +++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java @@ -712,8 +712,8 @@ public class Controller implements IFloodlightProviderService, // configured on the switch. This is the serial failover // mechanism from OpenFlow spec v1.0. log.error("Disconnecting switch from SLAVE controller." + - " Switch {} doesn't support role request messages", - sw.getId()); + " Switch {} doesn't support role request messages", + sw.getId()); sw.setConnected(false); connectedSwitches.remove(sw.getId()); sw.getChannel().close(); @@ -772,7 +772,7 @@ public class Controller implements IFloodlightProviderService, } log.info("Received NX role reply message; setting role of " + - "controller to {}", role.name()); + "controller to {}", role.name()); sw.setRole(role); @@ -1932,7 +1932,7 @@ public class Controller implements IFloodlightProviderService, CONTROLLER_INTERFACE_TYPE, CONTROLLER_INTERFACE_NUMBER, CONTROLLER_INTERFACE_DISCOVERED_IP }; - synchronized(curControllerNodeIPs) { + synchronized(controllerNodeIPsCache) { // We currently assume that interface Ethernet0 is the relevant // controller interface. Might change. // We could (should?) implement this using @@ -1981,6 +1981,18 @@ public class Controller implements IFloodlightProviderService, } } } + + @Override + public Map<String, String> getControllerNodeIPs() { + // We return a copy of the mapping so we can guarantee that + // the mapping return is the same as one that will be (or was) + // dispatched to IHAListeners + HashMap<String,String> retval = new HashMap<String,String>(); + synchronized(controllerNodeIPsCache) { + retval.putAll(controllerNodeIPsCache); + } + return retval; + } @Override public void rowsModified(String tableName, Set<Object> rowKeys) { @@ -1996,4 +2008,5 @@ public class Controller implements IFloodlightProviderService, handleControllerNodeIPChanges(); } } + } diff --git a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java index 314dbdb46159c7ffd8d7f7a0e7958446851679ad..3eeb0681f57a9c3f444703b9b99c6f1c1b3b73af 100644 --- a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java +++ b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java @@ -621,7 +621,7 @@ public class ControllerTest extends FloodlightTestCase { expectedAddedMap.put("c1", "1.1.1.1"); listener.wait(waitTimeout); listener.do_assert(1, expectedCurMap, expectedAddedMap, expectedRemovedMap); - + // Add an interface that we want to ignore. controller.storageSource.insertRow(Controller.CONTROLLER_INTERFACE_TABLE_NAME, getFakeControllerIPRow("row2", "c1", "Ethernet", 1, "1.1.1.2")); @@ -668,6 +668,22 @@ public class ControllerTest extends FloodlightTestCase { } } + @Test + public void testGetControllerNodeIPs() { + HashMap<String,String> expectedCurMap = new HashMap<String, String>(); + + controller.storageSource.insertRow(Controller.CONTROLLER_INTERFACE_TABLE_NAME, + getFakeControllerIPRow("row1", "c1", "Ethernet", 0, "1.1.1.1")); + controller.storageSource.insertRow(Controller.CONTROLLER_INTERFACE_TABLE_NAME, + getFakeControllerIPRow("row2", "c1", "Ethernet", 1, "1.1.1.2")); + controller.storageSource.insertRow(Controller.CONTROLLER_INTERFACE_TABLE_NAME, + getFakeControllerIPRow("row3", "c2", "Ethernet", 0, "2.2.2.2")); + expectedCurMap.put("c1", "1.1.1.1"); + expectedCurMap.put("c2", "2.2.2.2"); + assertEquals("expectedControllerNodeIPs is not as expected", + expectedCurMap, controller.getControllerNodeIPs()); + } + @Test public void testRoleChangeForSerialFailoverSwitch() throws Exception { IOFSwitch newsw = createMock(IOFSwitch.class); diff --git a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java index 8edd5a034c7a5f45a23307b197759aa36d9ab08c..e471eeb8565b1a0357ff3c19a37b6c6c9ead361f 100644 --- a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java +++ b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java @@ -285,4 +285,10 @@ public class MockFloodlightProvider implements IFloodlightModule, IFloodlightPro public String getControllerId() { return "localhost"; } + + @Override + public Map<String, String> getControllerNodeIPs() { + // TODO Auto-generated method stub + return null; + } }