diff --git a/cli/src/main/java/org/onosproject/cli/net/DevicePortsRemoveCommand.java b/cli/src/main/java/org/onosproject/cli/net/DevicePortsRemoveCommand.java new file mode 100644 index 0000000000..ec335b0149 --- /dev/null +++ b/cli/src/main/java/org/onosproject/cli/net/DevicePortsRemoveCommand.java @@ -0,0 +1,48 @@ +/* + * Copyright 2014-present Open Networking Foundation + * + * 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 org.onosproject.cli.net; + +import org.apache.karaf.shell.api.action.Argument; +import org.apache.karaf.shell.api.action.Command; +import org.apache.karaf.shell.api.action.Completion; +import org.apache.karaf.shell.api.action.lifecycle.Service; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.net.DeviceId; +import org.onosproject.net.device.DeviceAdminService; + +/** + * Removes an infrastructure device. + */ +@Service +@Command(scope = "onos", name = "device-ports-remove", + description = "Removes ports of an infrastructure device") +public class DevicePortsRemoveCommand extends AbstractShellCommand { + + @Argument(index = 0, name = "uri", description = "Device ID", + required = true, multiValued = false) + @Completion(DeviceIdCompleter.class) + String uri = null; + + @Override + protected void doExecute() { + try { + get(DeviceAdminService.class).removeDevicePorts(DeviceId.deviceId(uri)); + } catch (IllegalStateException e) { + print("There was some issue in removing device ports, please try again"); + } + } + +} diff --git a/core/api/src/main/java/org/onosproject/net/device/DeviceAdminService.java b/core/api/src/main/java/org/onosproject/net/device/DeviceAdminService.java index bfd467cc6c..c95e7e6999 100644 --- a/core/api/src/main/java/org/onosproject/net/device/DeviceAdminService.java +++ b/core/api/src/main/java/org/onosproject/net/device/DeviceAdminService.java @@ -40,4 +40,13 @@ public interface DeviceAdminService extends DeviceService { * @param enable true if port is to be enabled, false to disable */ void changePortState(DeviceId deviceId, PortNumber portNumber, boolean enable); + + /** + * Removes the ports of a device with the specified identifier. The device + * must be presently unavailable, i.e. offline. + * + * @param deviceId device identifier + */ + default void removeDevicePorts(DeviceId deviceId) { + } } diff --git a/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java b/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java index e274ae8d66..be24991e68 100644 --- a/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java +++ b/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java @@ -392,6 +392,24 @@ public class DeviceManager } } + @Override + public void removeDevicePorts(DeviceId deviceId) { + checkNotNull(deviceId, DEVICE_ID_NULL); + if (isAvailable(deviceId)) { + log.debug("Cannot remove ports of device {} while it is available.", deviceId); + return; + } + + List portDescriptions = ImmutableList.of(); + List events = store.updatePorts(getProvider(deviceId).id(), + deviceId, portDescriptions); + if (events != null) { + for (DeviceEvent event : events) { + post(event); + } + } + } + private void handlePortRequest(InternalPortUpDownEvent event) { DeviceId deviceId = event.deviceId(); checkNotNull(deviceId, DEVICE_ID_NULL); diff --git a/core/net/src/test/java/org/onosproject/net/device/impl/DeviceManagerTest.java b/core/net/src/test/java/org/onosproject/net/device/impl/DeviceManagerTest.java index 601e6c34c8..3e1e4d1e8f 100644 --- a/core/net/src/test/java/org/onosproject/net/device/impl/DeviceManagerTest.java +++ b/core/net/src/test/java/org/onosproject/net/device/impl/DeviceManagerTest.java @@ -246,7 +246,31 @@ public class DeviceManagerTest { assertNotNull("device should be found", service.getDevice(DID2)); assertEquals("incorrect device count", 1, service.getDeviceCount()); assertEquals("incorrect available device count", 1, service.getAvailableDeviceCount()); + } + @Test + public void removeDevicePorts() { + connectDevice(DID1, SW1); + List pds = new ArrayList<>(); + pds.add(DefaultPortDescription.builder().withPortNumber(P1).isEnabled(true).build()); + pds.add(DefaultPortDescription.builder().withPortNumber(P2).isEnabled(true).build()); + pds.add(DefaultPortDescription.builder().withPortNumber(P3).isEnabled(true).build()); + providerService.updatePorts(DID1, pds); + validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED, PORT_ADDED); + + // Try removing ports while device is available/connected; it should be a no-op. + admin.removeDevicePorts(DID1); + assertEquals("wrong port count", 3, service.getPorts(DID1).size()); + + // Disconnect device + providerService.deviceDisconnected(DID1); + assertFalse("device should not be available", service.isAvailable(DID1)); + validateEvents(DEVICE_AVAILABILITY_CHANGED); + + // Now remove ports for real + admin.removeDevicePorts(DID1); + validateEvents(PORT_REMOVED, PORT_REMOVED, PORT_REMOVED); + assertEquals("wrong port count", 0, service.getPorts(DID1).size()); } protected void validateEvents(Enum... types) {