Committed by
Gerrit Code Review
[Emu] ONOS-3512 CLI for new resource subsystem
- "resources" command to print available resources on new resource service. - "allocations" command to dump current allocations - "test-allocate-resource" command to allocate a resource Change-Id: I89e531c71ef288b8c06dcd355a3a819d667c8225
Showing
5 changed files
with
399 additions
and
0 deletions
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.cli.net; | ||
| 17 | + | ||
| 18 | +import static org.onosproject.net.DeviceId.deviceId; | ||
| 19 | + | ||
| 20 | +import java.util.Collection; | ||
| 21 | +import java.util.stream.StreamSupport; | ||
| 22 | + | ||
| 23 | +import org.apache.karaf.shell.commands.Argument; | ||
| 24 | +import org.apache.karaf.shell.commands.Command; | ||
| 25 | +import org.apache.karaf.shell.commands.Option; | ||
| 26 | +import org.onosproject.cli.AbstractShellCommand; | ||
| 27 | +import org.onosproject.net.Device; | ||
| 28 | +import org.onosproject.net.DeviceId; | ||
| 29 | +import org.onosproject.net.OchSignal; | ||
| 30 | +import org.onosproject.net.Port; | ||
| 31 | +import org.onosproject.net.PortNumber; | ||
| 32 | +import org.onosproject.net.device.DeviceService; | ||
| 33 | +import org.onosproject.net.newresource.ResourceAllocation; | ||
| 34 | +import org.onosproject.net.newresource.ResourcePath; | ||
| 35 | +import org.onosproject.net.newresource.ResourceService; | ||
| 36 | + | ||
| 37 | +import com.google.common.base.Strings; | ||
| 38 | + | ||
| 39 | +/** | ||
| 40 | + * Lists allocated resources. | ||
| 41 | + */ | ||
| 42 | +@Command(scope = "onos", name = "allocations", | ||
| 43 | + description = "Lists allocated resources") | ||
| 44 | +public class AllocationsCommand extends AbstractShellCommand { | ||
| 45 | + | ||
| 46 | + // TODO add other resource types | ||
| 47 | + @Option(name = "-l", aliases = "--lambda", description = "Lambda Resource", | ||
| 48 | + required = false, multiValued = false) | ||
| 49 | + private boolean lambda = true; | ||
| 50 | + | ||
| 51 | + @Argument(index = 0, name = "deviceIdString", description = "Device ID", | ||
| 52 | + required = false, multiValued = false) | ||
| 53 | + String deviceIdStr = null; | ||
| 54 | + | ||
| 55 | + @Argument(index = 1, name = "portNumberString", description = "PortNumber", | ||
| 56 | + required = false, multiValued = false) | ||
| 57 | + String portNumberStr = null; | ||
| 58 | + | ||
| 59 | + | ||
| 60 | + | ||
| 61 | + private DeviceService deviceService; | ||
| 62 | + private ResourceService resourceService; | ||
| 63 | + | ||
| 64 | + @Override | ||
| 65 | + protected void execute() { | ||
| 66 | + deviceService = get(DeviceService.class); | ||
| 67 | + resourceService = get(ResourceService.class); | ||
| 68 | + | ||
| 69 | + | ||
| 70 | + if (deviceIdStr != null && portNumberStr != null) { | ||
| 71 | + DeviceId deviceId = deviceId(deviceIdStr); | ||
| 72 | + PortNumber portNumber = PortNumber.fromString(portNumberStr); | ||
| 73 | + | ||
| 74 | + printAllocation(deviceId, portNumber, 0); | ||
| 75 | + } else if (deviceIdStr != null) { | ||
| 76 | + DeviceId deviceId = deviceId(deviceIdStr); | ||
| 77 | + | ||
| 78 | + printAllocation(deviceId, 0); | ||
| 79 | + } else { | ||
| 80 | + printAllocation(); | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + private void printAllocation() { | ||
| 86 | + print("ROOT"); | ||
| 87 | + StreamSupport.stream(deviceService.getAvailableDevices().spliterator(), false) | ||
| 88 | + .map(Device::id) | ||
| 89 | + .forEach(did -> printAllocation(did, 1)); | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + private void printAllocation(DeviceId did, int level) { | ||
| 93 | + print("%s%s", Strings.repeat(" ", level), did); | ||
| 94 | + StreamSupport.stream(deviceService.getPorts(did).spliterator(), false) | ||
| 95 | + .map(Port::number) | ||
| 96 | + .forEach(num -> printAllocation(did, num, level + 1)); | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + private void printAllocation(DeviceId did, PortNumber num, int level) { | ||
| 100 | + if (level == 0) { | ||
| 101 | + // print DeviceId when Port was directly specified. | ||
| 102 | + print("%s", did); | ||
| 103 | + } | ||
| 104 | + print("%s%s", Strings.repeat(" ", level), asVerboseString(num)); | ||
| 105 | + | ||
| 106 | + // TODO: Current design cannot deal with sub-resources | ||
| 107 | + // (e.g., TX/RX under Port) | ||
| 108 | + | ||
| 109 | + ResourcePath path = ResourcePath.discrete(did, num); | ||
| 110 | + if (lambda) { | ||
| 111 | + //print("Lambda resources:"); | ||
| 112 | + Collection<ResourceAllocation> allocations | ||
| 113 | + = resourceService.getResourceAllocations(path, OchSignal.class); | ||
| 114 | + | ||
| 115 | + for (ResourceAllocation a : allocations) { | ||
| 116 | + print("%s%s allocated by %s", Strings.repeat(" ", level + 1), | ||
| 117 | + a.resource().last(), asVerboseString(a.consumer())); | ||
| 118 | + } | ||
| 119 | + } | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + /** | ||
| 123 | + * Add type name if the toString does not start with them. | ||
| 124 | + * | ||
| 125 | + * e.g., IntentId#toString result in "42" | ||
| 126 | + * asVerboseString(id) will result in "IntentId:42" | ||
| 127 | + * | ||
| 128 | + * @param obj non-null Object to print. | ||
| 129 | + * @return verbose String representation | ||
| 130 | + */ | ||
| 131 | + private static String asVerboseString(Object obj) { | ||
| 132 | + String name = obj.getClass().getSimpleName(); | ||
| 133 | + String toString = String.valueOf(obj); | ||
| 134 | + if (toString.startsWith(name)) { | ||
| 135 | + return toString; | ||
| 136 | + } else { | ||
| 137 | + return String.format("%s:%s", name, toString); | ||
| 138 | + } | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.cli.net; | ||
| 17 | + | ||
| 18 | +import static com.google.common.base.Preconditions.checkArgument; | ||
| 19 | +import static org.onlab.osgi.DefaultServiceDirectory.getService; | ||
| 20 | + | ||
| 21 | +import java.util.List; | ||
| 22 | +import java.util.stream.Collectors; | ||
| 23 | +import java.util.stream.StreamSupport; | ||
| 24 | + | ||
| 25 | +import org.apache.karaf.shell.console.completer.ArgumentCompleter.ArgumentList; | ||
| 26 | +import org.onosproject.cli.AbstractChoicesCompleter; | ||
| 27 | +import org.onosproject.net.DeviceId; | ||
| 28 | +import org.onosproject.net.device.DeviceService; | ||
| 29 | + | ||
| 30 | +/** | ||
| 31 | + * PortNumber completer. | ||
| 32 | + * | ||
| 33 | + * Assumes argument right before the one being completed is DeviceId. | ||
| 34 | + */ | ||
| 35 | +public class PortNumberCompleter extends AbstractChoicesCompleter { | ||
| 36 | + | ||
| 37 | + @Override | ||
| 38 | + protected List<String> choices() { | ||
| 39 | + ArgumentList args = getArgumentList(); | ||
| 40 | + checkArgument(args.getCursorArgumentIndex() >= 1, | ||
| 41 | + "Expects DeviceId as previous argument"); | ||
| 42 | + | ||
| 43 | + String deviceIdStr = args.getArguments()[args.getCursorArgumentIndex() - 1]; | ||
| 44 | + DeviceId deviceId = DeviceId.deviceId(deviceIdStr); | ||
| 45 | + | ||
| 46 | + DeviceService deviceService = getService(DeviceService.class); | ||
| 47 | + return StreamSupport.stream(deviceService.getPorts(deviceId).spliterator(), false) | ||
| 48 | + .map(port -> port.number().toString()) | ||
| 49 | + .collect(Collectors.toList()); | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.cli.net; | ||
| 17 | + | ||
| 18 | +import static org.onosproject.net.DeviceId.deviceId; | ||
| 19 | + | ||
| 20 | +import java.util.Collection; | ||
| 21 | +import org.apache.karaf.shell.commands.Argument; | ||
| 22 | +import org.apache.karaf.shell.commands.Command; | ||
| 23 | +import org.onosproject.cli.AbstractShellCommand; | ||
| 24 | +import org.onosproject.net.DeviceId; | ||
| 25 | +import org.onosproject.net.PortNumber; | ||
| 26 | +import org.onosproject.net.newresource.ResourcePath; | ||
| 27 | +import org.onosproject.net.newresource.ResourceService; | ||
| 28 | + | ||
| 29 | +import com.google.common.base.Strings; | ||
| 30 | + | ||
| 31 | +/** | ||
| 32 | + * Lists available resources. | ||
| 33 | + */ | ||
| 34 | +@Command(scope = "onos", name = "resources", | ||
| 35 | + description = "Lists available resources") | ||
| 36 | +public class ResourcesCommand extends AbstractShellCommand { | ||
| 37 | + | ||
| 38 | + @Argument(index = 0, name = "deviceIdString", description = "Device ID", | ||
| 39 | + required = false, multiValued = false) | ||
| 40 | + String deviceIdStr = null; | ||
| 41 | + | ||
| 42 | + @Argument(index = 1, name = "portNumberString", description = "PortNumber", | ||
| 43 | + required = false, multiValued = false) | ||
| 44 | + String portNumberStr = null; | ||
| 45 | + | ||
| 46 | + | ||
| 47 | + private ResourceService resourceService; | ||
| 48 | + | ||
| 49 | + @Override | ||
| 50 | + protected void execute() { | ||
| 51 | + resourceService = get(ResourceService.class); | ||
| 52 | + | ||
| 53 | + if (deviceIdStr != null && portNumberStr != null) { | ||
| 54 | + DeviceId deviceId = deviceId(deviceIdStr); | ||
| 55 | + PortNumber portNumber = PortNumber.fromString(portNumberStr); | ||
| 56 | + | ||
| 57 | + printResource(ResourcePath.discrete(deviceId, portNumber), 0); | ||
| 58 | + } else if (deviceIdStr != null) { | ||
| 59 | + DeviceId deviceId = deviceId(deviceIdStr); | ||
| 60 | + | ||
| 61 | + printResource(ResourcePath.discrete(deviceId), 0); | ||
| 62 | + } else { | ||
| 63 | + printResource(ResourcePath.ROOT, 0); | ||
| 64 | + } | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + private void printResource(ResourcePath resource, int level) { | ||
| 68 | + if (resource.equals(ResourcePath.ROOT)) { | ||
| 69 | + print("ROOT"); | ||
| 70 | + } else { | ||
| 71 | + String name = resource.last().getClass().getSimpleName(); | ||
| 72 | + String toString = String.valueOf(resource.last()); | ||
| 73 | + if (toString.startsWith(name)) { | ||
| 74 | + print("%s%s", Strings.repeat(" ", level), | ||
| 75 | + toString); | ||
| 76 | + | ||
| 77 | + } else { | ||
| 78 | + print("%s%s:%s", Strings.repeat(" ", level), | ||
| 79 | + name, | ||
| 80 | + toString); | ||
| 81 | + } | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + Collection<ResourcePath> resources = resourceService.getAvailableResources(resource); | ||
| 85 | + // TODO: Should consider better output for leaf nodes | ||
| 86 | + resources.forEach(r -> printResource(r, level + 1)); | ||
| 87 | + } | ||
| 88 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.cli.net; | ||
| 17 | + | ||
| 18 | +import static org.onosproject.net.newresource.ResourcePath.discrete; | ||
| 19 | + | ||
| 20 | +import java.util.Optional; | ||
| 21 | + | ||
| 22 | +import org.apache.karaf.shell.commands.Argument; | ||
| 23 | +import org.apache.karaf.shell.commands.Command; | ||
| 24 | +import org.apache.karaf.shell.commands.Option; | ||
| 25 | +import org.onosproject.cli.AbstractShellCommand; | ||
| 26 | +import org.onosproject.net.ChannelSpacing; | ||
| 27 | +import org.onosproject.net.DeviceId; | ||
| 28 | +import org.onosproject.net.GridType; | ||
| 29 | +import org.onosproject.net.OchSignal; | ||
| 30 | +import org.onosproject.net.PortNumber; | ||
| 31 | +import org.onosproject.net.intent.IntentId; | ||
| 32 | +import org.onosproject.net.newresource.ResourceAllocation; | ||
| 33 | +import org.onosproject.net.newresource.ResourceConsumer; | ||
| 34 | +import org.onosproject.net.newresource.ResourcePath; | ||
| 35 | +import org.onosproject.net.newresource.ResourceService; | ||
| 36 | + | ||
| 37 | +/** | ||
| 38 | + * Test tool to allocate resources. | ||
| 39 | + */ | ||
| 40 | +@Command(scope = "onos", name = "test-allocate-resources", | ||
| 41 | + description = "Test tool to allocate resources") | ||
| 42 | +public class TestAllocateResource extends AbstractShellCommand { | ||
| 43 | + | ||
| 44 | + // TODO add support for other resource types | ||
| 45 | + | ||
| 46 | + // FIXME provide a proper way to specify a lambda and lambda ranges | ||
| 47 | + @Option(name = "-l", aliases = "--lambda", | ||
| 48 | + description = "Lambda Resource to allocate", | ||
| 49 | + required = false, multiValued = false) | ||
| 50 | + private String lambda = "1"; | ||
| 51 | + | ||
| 52 | + @Option(name = "-i", aliases = "--intentId", | ||
| 53 | + description = "IntentId to use for allocation", | ||
| 54 | + required = false, multiValued = false) | ||
| 55 | + private int nIntendId = 42; | ||
| 56 | + | ||
| 57 | + | ||
| 58 | + @Argument(index = 0, name = "deviceIdString", description = "Device ID", | ||
| 59 | + required = true, multiValued = false) | ||
| 60 | + String deviceIdStr = null; | ||
| 61 | + | ||
| 62 | + @Argument(index = 1, name = "portNumberString", description = "PortNumber", | ||
| 63 | + required = true, multiValued = false) | ||
| 64 | + String portNumberStr = null; | ||
| 65 | + | ||
| 66 | + private ResourceService resourceService; | ||
| 67 | + | ||
| 68 | + @Override | ||
| 69 | + protected void execute() { | ||
| 70 | + resourceService = get(ResourceService.class); | ||
| 71 | + DeviceId did = DeviceId.deviceId(deviceIdStr); | ||
| 72 | + PortNumber portNum = PortNumber.fromString(portNumberStr); | ||
| 73 | + | ||
| 74 | + ResourceConsumer consumer = IntentId.valueOf(nIntendId); | ||
| 75 | + | ||
| 76 | + ResourcePath resource = discrete(did, portNum, | ||
| 77 | + createLambda(Integer.parseInt(lambda))); | ||
| 78 | + | ||
| 79 | + Optional<ResourceAllocation> allocate = resourceService.allocate(consumer, resource); | ||
| 80 | + if (allocate.isPresent()) { | ||
| 81 | + print("Allocated: %s", allocate.get()); | ||
| 82 | + } else { | ||
| 83 | + print("Failed to allocate %s for %s", resource, consumer); | ||
| 84 | + } | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + private OchSignal createLambda(int i) { | ||
| 88 | + return new OchSignal(GridType.FLEX, | ||
| 89 | + ChannelSpacing.CHL_12P5GHZ, | ||
| 90 | + i, | ||
| 91 | + 1); | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | +} |
| ... | @@ -295,6 +295,29 @@ | ... | @@ -295,6 +295,29 @@ |
| 295 | </completers> | 295 | </completers> |
| 296 | </command> | 296 | </command> |
| 297 | <command> | 297 | <command> |
| 298 | + <action class="org.onosproject.cli.net.ResourcesCommand"/> | ||
| 299 | + <completers> | ||
| 300 | + <ref component-id="deviceIdCompleter"/> | ||
| 301 | + <ref component-id="portNumberCompleter"/> | ||
| 302 | + </completers> | ||
| 303 | + </command> | ||
| 304 | + <command> | ||
| 305 | + <action class="org.onosproject.cli.net.AllocationsCommand"/> | ||
| 306 | + <completers> | ||
| 307 | + <ref component-id="deviceIdCompleter"/> | ||
| 308 | + <ref component-id="portNumberCompleter"/> | ||
| 309 | + </completers> | ||
| 310 | + </command> | ||
| 311 | + <command> | ||
| 312 | + <action class="org.onosproject.cli.net.TestAllocateResource"/> | ||
| 313 | + <completers> | ||
| 314 | + <ref component-id="deviceIdCompleter"/> | ||
| 315 | + <ref component-id="portNumberCompleter"/> | ||
| 316 | + </completers> | ||
| 317 | + </command> | ||
| 318 | + | ||
| 319 | + <!-- Should deprecate following 3 commands soon. --> | ||
| 320 | + <command> | ||
| 298 | <action class="org.onosproject.cli.net.ResourceAllocationsCommand"/> | 321 | <action class="org.onosproject.cli.net.ResourceAllocationsCommand"/> |
| 299 | <completers> | 322 | <completers> |
| 300 | <ref component-id="connectPointCompleter"/> | 323 | <ref component-id="connectPointCompleter"/> |
| ... | @@ -487,6 +510,7 @@ | ... | @@ -487,6 +510,7 @@ |
| 487 | <bean id="componentPropertyNameCompleter" class="org.onosproject.cli.cfg.ComponentPropertyNameCompleter"/> | 510 | <bean id="componentPropertyNameCompleter" class="org.onosproject.cli.cfg.ComponentPropertyNameCompleter"/> |
| 488 | <bean id="nodeIdCompleter" class="org.onosproject.cli.NodeIdCompleter"/> | 511 | <bean id="nodeIdCompleter" class="org.onosproject.cli.NodeIdCompleter"/> |
| 489 | <bean id="deviceIdCompleter" class="org.onosproject.cli.net.DeviceIdCompleter"/> | 512 | <bean id="deviceIdCompleter" class="org.onosproject.cli.net.DeviceIdCompleter"/> |
| 513 | + <bean id="portNumberCompleter" class="org.onosproject.cli.net.PortNumberCompleter"/> | ||
| 490 | <bean id="clusterIdCompleter" class="org.onosproject.cli.net.ClusterIdCompleter"/> | 514 | <bean id="clusterIdCompleter" class="org.onosproject.cli.net.ClusterIdCompleter"/> |
| 491 | <bean id="roleCompleter" class="org.onosproject.cli.net.RoleCompleter"/> | 515 | <bean id="roleCompleter" class="org.onosproject.cli.net.RoleCompleter"/> |
| 492 | <bean id="hostIdCompleter" class="org.onosproject.cli.net.HostIdCompleter"/> | 516 | <bean id="hostIdCompleter" class="org.onosproject.cli.net.HostIdCompleter"/> | ... | ... |
-
Please register or login to post a comment