@Override void enterState() { if (OFSwitchManager.clearTablesOnEachTransitionToMaster) { log.info("Clearing flow tables of {} on upcoming transition to MASTER.", sw.getId().toString()); clearAllTables(); } else if (OFSwitchManager.clearTablesOnInitialConnectAsMaster && initialRole == null) { /* don't do it if we were slave first */ initialRole = OFControllerRole.ROLE_MASTER; log.info("Clearing flow tables of {} on upcoming initial role as MASTER.", sw.getId().toString()); clearAllTables(); } sendBarrier(); /* Need to make sure the tables are clear before adding default flows */ addDefaultFlows(); /* * We also need a barrier between adding flows and notifying modules of the * transition to master. Some modules might modify the flow tables and expect * the clear/default flow operations above to have completed. */ sendBarrier(); setSwitchStatus(SwitchStatus.MASTER); }
/** IOFConnectionListener */ @Override public void connectionClosed(IOFConnectionBackend connection) { // Disconnect handler's remaining connections cleanup(); // Only remove the switch handler when the main connection is // closed if (connection == this.mainConnection) { switchManager.handshakeDisconnected(connection.getDatapathId()); if(sw != null) { log.debug("[{}] - main connection {} closed - disconnecting switch", connection); setSwitchStatus(SwitchStatus.DISCONNECTED); switchManager.switchDisconnected(sw); } } }
public void setSwitchStatus(SwitchStatus status) { if(sw != null) { SwitchStatus oldStatus = sw.getStatus(); if(oldStatus != status) { log.debug("[{}] SwitchStatus change to {} requested, switch is in status " + oldStatus, mainConnection.getDatapathId(), status); sw.setStatus(status); switchManager.switchStatusChanged(sw, oldStatus, status); } else { log.warn("[{}] SwitchStatus change to {} requested, switch is already in status", mainConnection.getDatapathId(), status); } } else { log.warn("[{}] SwitchStatus change to {} requested, but switch is not allocated yet", mainConnection.getDatapathId(), status); } }
/** * Test switchActivated for a new switch while in slave: disconnect the switch */ @Test public void testNewSwitchActivatedWhileSlave() throws Exception { doSetUp(HARole.STANDBY); IOFSwitchBackend sw = createMock(IOFSwitchBackend.class); IOFSwitchListener listener = createMock(IOFSwitchListener.class); switchManager.addOFSwitchListener(listener); expect(sw.getId()).andReturn(DATAPATH_ID_0).anyTimes(); expect(sw.getStatus()).andReturn(SwitchStatus.MASTER).anyTimes(); sw.disconnect(); expectLastCall().once(); expect(sw.getOFFactory()).andReturn(factory).once(); replay(sw, listener); // nothing recorded switchManager.switchAdded(sw); switchManager.switchStatusChanged(sw, SwitchStatus.HANDSHAKE, SwitchStatus.MASTER); verify(sw); controller.processUpdateQueueForTesting(); verify(listener); }
/** * Create and activate a switch, either completely new or reconnected * The mocked switch instance will be returned. It will be reset. */ private IOFSwitchBackend doActivateSwitchInt(DatapathId datapathId, SwitchDescription description, OFFeaturesReply featuresReply, boolean clearFlows) throws Exception { IOFSwitchBackend sw = createMock(IOFSwitchBackend.class); if (featuresReply == null) { featuresReply = createOFFeaturesReply(datapathId); } if (description == null) { description = createSwitchDescription(); } setupSwitchForAddSwitch(sw, datapathId, description, featuresReply); replay(sw); switchManager.switchAdded(sw); switchManager.switchStatusChanged(sw, SwitchStatus.HANDSHAKE, SwitchStatus.MASTER); verify(sw); assertEquals(sw, switchManager.getSwitch(datapathId)); // drain updates and ignore controller.processUpdateQueueForTesting(); reset(sw); return sw; }
/** * Try to remove a switch that's different from what's in the active * switch map. Should be ignored */ @Test public void testSwitchDisconnectedOther() throws Exception { IOFSwitch origSw = doActivateNewSwitch(DATAPATH_ID_1, null, null); // create a new mock switch IOFSwitchBackend sw = createMock(IOFSwitchBackend.class); expect(sw.getId()).andReturn(DATAPATH_ID_1).anyTimes(); IOFSwitchListener listener = createMock(IOFSwitchListener.class); switchManager.addOFSwitchListener(listener); replay(sw, listener); switchManager.switchDisconnected(sw); controller.processUpdateQueueForTesting(); verify(sw, listener); expect(origSw.getStatus()).andReturn(SwitchStatus.MASTER).anyTimes(); replay(origSw); assertSame(origSw, switchManager.getSwitch(DATAPATH_ID_1)); }
/** * Tests that you can't remove a switch from the map returned by * getSwitches() (because getSwitches should return an unmodifiable * map) */ @Test public void testRemoveActiveSwitch() { IOFSwitchBackend sw = createNiceMock(IOFSwitchBackend.class); setupSwitchForAddSwitch(sw, DATAPATH_ID_1, null, null); replay(sw); switchManager.switchAdded(sw); switchManager.switchStatusChanged(sw, SwitchStatus.HANDSHAKE, SwitchStatus.MASTER); assertEquals(sw, switchManager.getSwitch(DATAPATH_ID_1)); try { switchManager.getAllSwitchMap().remove(DATAPATH_ID_1); fail("Expected: UnsupportedOperationException"); } catch(UnsupportedOperationException e) { // expected } // we don't care for updates. drain queue. controller.processUpdateQueueForTesting(); }
/** * Tests that the switch manager should only return a switch to a getActiveSwitch * call when the switch is visible/active. */ @Test public void testGetActiveSwitch() { MockOFConnection connection = new MockOFConnection(DATAPATH_ID_1, OFAuxId.MAIN); IOFSwitchBackend sw = new MockOFSwitchImpl(connection); sw.setStatus(SwitchStatus.HANDSHAKE); assertNull(switchManager.getActiveSwitch(DATAPATH_ID_1)); switchManager.switchAdded(sw); assertNull(switchManager.getActiveSwitch(DATAPATH_ID_1)); sw.setStatus(SwitchStatus.MASTER); assertEquals(sw, switchManager.getActiveSwitch(DATAPATH_ID_1)); sw.setStatus(SwitchStatus.QUARANTINED); assertNull(switchManager.getActiveSwitch(DATAPATH_ID_1)); sw.setStatus(SwitchStatus.SLAVE); assertEquals(sw, switchManager.getActiveSwitch(DATAPATH_ID_1)); sw.setStatus(SwitchStatus.DISCONNECTED); assertNull(switchManager.getActiveSwitch(DATAPATH_ID_1)); // we don't care for updates. drain queue. controller.processUpdateQueueForTesting(); }
/** * Tests the connection closed functionality after the switch handshake is complete. * Essentially when the switch handshake is aware of an IOFSwitch. * @throws Exception */ @Test public void testConnectionClosedAfterHandshakeComplete() throws Exception { testInitialMoveToMasterWithRole(); // Test connection closed prior to being finished reset(switchManager); switchManager.handshakeDisconnected(dpid); expectLastCall().once(); switchManager.switchDisconnected(sw); expectLastCall().once(); replay(switchManager); reset(sw); expect(sw.getStatus()).andReturn(SwitchStatus.DISCONNECTED).anyTimes(); replay(sw); switchHandler.connectionClosed(connection); verify(switchManager); verify(sw); }
/** * Test switchActivated for a new switch while in slave: disconnect the switch */ @Test public void testNewSwitchActivatedWhileSlave() throws Exception { doSetUp(HARole.STANDBY); IOFSwitchBackend sw = createMock(IOFSwitchBackend.class); IOFSwitchListener listener = createMock(IOFSwitchListener.class); switchManager.addOFSwitchListener(listener); expect(sw.getId()).andReturn(DATAPATH_ID_0).anyTimes(); expect(sw.getStatus()).andReturn(SwitchStatus.MASTER).anyTimes(); sw.disconnect(); expectLastCall().once(); replay(sw, listener); // nothing recorded switchManager.switchAdded(sw); switchManager.switchStatusChanged(sw, SwitchStatus.HANDSHAKE, SwitchStatus.MASTER); verify(sw); controller.processUpdateQueueForTesting(); verify(listener); }