Yuta HIGUCHI

Disconnect switch when Device was admin removed.

Change-Id: I8d55eda686d29b43540f5467739983564afde5af
......@@ -28,6 +28,10 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.core.CoreService;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceEvent.Type;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.driver.DefaultDriverProviderService;
import org.onosproject.net.driver.DriverService;
import org.onosproject.openflow.controller.DefaultOpenFlowPacketContext;
......@@ -72,6 +76,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
......@@ -82,6 +87,7 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.openflow.controller.Dpid.dpid;
@Component(immediate = true)
@Service
......@@ -106,6 +112,10 @@ public class OpenFlowControllerImpl implements OpenFlowController {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ComponentConfigService cfgService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
@Property(name = "openflowPorts", value = DEFAULT_OFPORT,
label = "Port numbers (comma separated) used by OpenFlow protocol; default is 6633,6653")
private String openflowPorts = DEFAULT_OFPORT;
......@@ -161,11 +171,13 @@ public class OpenFlowControllerImpl implements OpenFlowController {
ArrayListMultimap.create();
private final Controller ctrl = new Controller();
private InternalDeviceListener listener = new InternalDeviceListener();
@Activate
public void activate(ComponentContext context) {
coreService.registerApplication(APP_ID, this::cleanup);
cfgService.registerProperties(getClass());
deviceService.addListener(listener);
ctrl.setConfigParams(context.getProperties());
ctrl.start(agent, driverService);
}
......@@ -182,6 +194,7 @@ public class OpenFlowControllerImpl implements OpenFlowController {
@Deactivate
public void deactivate() {
deviceService.removeListener(listener);
cleanup();
cfgService.unregisterProperties(getClass(), false);
}
......@@ -521,6 +534,46 @@ public class OpenFlowControllerImpl implements OpenFlowController {
sw.setRole(role);
}
class InternalDeviceListener implements DeviceListener {
@Override
public boolean isRelevant(DeviceEvent event) {
return event.type() == Type.DEVICE_REMOVED;
}
@Override
public void event(DeviceEvent event) {
switch (event.type()) {
case DEVICE_ADDED:
break;
case DEVICE_AVAILABILITY_CHANGED:
break;
case DEVICE_REMOVED:
// Device administratively removed, disconnect
Optional.ofNullable(getSwitch(dpid(event.subject().id().uri())))
.ifPresent(OpenFlowSwitch::disconnectSwitch);
break;
case DEVICE_SUSPENDED:
break;
case DEVICE_UPDATED:
break;
case PORT_ADDED:
break;
case PORT_REMOVED:
break;
case PORT_STATS_UPDATED:
break;
case PORT_UPDATED:
break;
default:
break;
}
}
}
/**
* Implementation of an OpenFlow Agent which is responsible for
* keeping track of connected switches and the state in which
......
......@@ -33,6 +33,7 @@ import org.junit.Test;
import org.onlab.junit.TestTools;
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.core.CoreService;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.openflow.OpenflowSwitchDriverAdapter;
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.controller.OpenFlowSwitch;
......@@ -143,6 +144,8 @@ public class OpenFlowControllerImplTest {
controller.cfgService = mockConfigService;
replay(mockConfigService);
controller.deviceService = new DeviceServiceAdapter();
ComponentContext mockContext = EasyMock.createMock(ComponentContext.class);
Dictionary<String, Object> properties = new Hashtable<>();
properties.put("openflowPorts",
......