Committed by
Gerrit Code Review
resources command enchancement
- Aggregate output of some Discrete resources Currently supports: VlanID, MPLS label, Tributary slots - Add support for Continuous resource Change-Id: I5d002ba7f43f8b8d06228507b7463c29296aec90
Showing
1 changed file
with
88 additions
and
11 deletions
| ... | @@ -19,6 +19,8 @@ import static org.onosproject.net.DeviceId.deviceId; | ... | @@ -19,6 +19,8 @@ import static org.onosproject.net.DeviceId.deviceId; |
| 19 | 19 | ||
| 20 | import java.util.Set; | 20 | import java.util.Set; |
| 21 | import java.util.HashSet; | 21 | import java.util.HashSet; |
| 22 | +import java.util.List; | ||
| 23 | +import java.util.ArrayList; | ||
| 22 | import java.util.Arrays; | 24 | import java.util.Arrays; |
| 23 | import java.util.Collection; | 25 | import java.util.Collection; |
| 24 | import java.util.Collections; | 26 | import java.util.Collections; |
| ... | @@ -26,13 +28,23 @@ import java.util.Collections; | ... | @@ -26,13 +28,23 @@ import java.util.Collections; |
| 26 | import org.apache.karaf.shell.commands.Argument; | 28 | import org.apache.karaf.shell.commands.Argument; |
| 27 | import org.apache.karaf.shell.commands.Command; | 29 | import org.apache.karaf.shell.commands.Command; |
| 28 | import org.apache.karaf.shell.commands.Option; | 30 | import org.apache.karaf.shell.commands.Option; |
| 31 | +import org.onlab.packet.MplsLabel; | ||
| 32 | +import org.onlab.packet.VlanId; | ||
| 29 | import org.onosproject.cli.AbstractShellCommand; | 33 | import org.onosproject.cli.AbstractShellCommand; |
| 30 | import org.onosproject.net.DeviceId; | 34 | import org.onosproject.net.DeviceId; |
| 31 | import org.onosproject.net.PortNumber; | 35 | import org.onosproject.net.PortNumber; |
| 36 | +import org.onosproject.net.TributarySlot; | ||
| 32 | import org.onosproject.net.newresource.Resource; | 37 | import org.onosproject.net.newresource.Resource; |
| 33 | import org.onosproject.net.newresource.ResourceService; | 38 | import org.onosproject.net.newresource.ResourceService; |
| 34 | 39 | ||
| 35 | import com.google.common.base.Strings; | 40 | import com.google.common.base.Strings; |
| 41 | +import com.google.common.collect.ArrayListMultimap; | ||
| 42 | +import com.google.common.collect.DiscreteDomain; | ||
| 43 | +import com.google.common.collect.ImmutableSet; | ||
| 44 | +import com.google.common.collect.Multimap; | ||
| 45 | +import com.google.common.collect.Range; | ||
| 46 | +import com.google.common.collect.RangeSet; | ||
| 47 | +import com.google.common.collect.TreeRangeSet; | ||
| 36 | 48 | ||
| 37 | /** | 49 | /** |
| 38 | * Lists available resources. | 50 | * Lists available resources. |
| ... | @@ -87,7 +99,8 @@ public class ResourcesCommand extends AbstractShellCommand { | ... | @@ -87,7 +99,8 @@ public class ResourcesCommand extends AbstractShellCommand { |
| 87 | } | 99 | } |
| 88 | 100 | ||
| 89 | private void printResource(Resource resource, int level) { | 101 | private void printResource(Resource resource, int level) { |
| 90 | - Collection<Resource> children = resourceService.getAvailableResources(resource); | 102 | + // TODO add an option to show only available resource |
| 103 | + Collection<Resource> children = resourceService.getRegisteredResources(resource); | ||
| 91 | 104 | ||
| 92 | if (resource.equals(Resource.ROOT)) { | 105 | if (resource.equals(Resource.ROOT)) { |
| 93 | print("ROOT"); | 106 | print("ROOT"); |
| ... | @@ -99,24 +112,88 @@ public class ResourcesCommand extends AbstractShellCommand { | ... | @@ -99,24 +112,88 @@ public class ResourcesCommand extends AbstractShellCommand { |
| 99 | return; | 112 | return; |
| 100 | } | 113 | } |
| 101 | 114 | ||
| 102 | - String toString = String.valueOf(resource.last()); | 115 | + if (resource instanceof Resource.Continuous) { |
| 103 | - if (toString.startsWith(resourceName)) { | 116 | + print("%s%s: %f", Strings.repeat(" ", level), |
| 104 | - print("%s%s", Strings.repeat(" ", level), | 117 | + resource.last(), |
| 105 | - toString); | 118 | + ((Resource.Continuous) resource).value()); |
| 119 | + // Continuous resource is terminal node, stop here | ||
| 120 | + return; | ||
| 121 | + } else { | ||
| 122 | + | ||
| 123 | + String toString = String.valueOf(resource.last()); | ||
| 124 | + if (toString.startsWith(resourceName)) { | ||
| 125 | + print("%s%s", Strings.repeat(" ", level), | ||
| 126 | + toString); | ||
| 127 | + } else { | ||
| 128 | + print("%s%s: %s", Strings.repeat(" ", level), | ||
| 129 | + resourceName, | ||
| 130 | + toString); | ||
| 131 | + } | ||
| 132 | + } | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + | ||
| 136 | + // Classify children into aggregatable terminal resources and everything else | ||
| 137 | + | ||
| 138 | + Set<Class<?>> aggregatableTypes = ImmutableSet.<Class<?>>builder() | ||
| 139 | + .add(VlanId.class) | ||
| 140 | + .add(MplsLabel.class) | ||
| 141 | + .build(); | ||
| 142 | + // (last() resource name) -> { Resource } | ||
| 143 | + Multimap<String, Resource> aggregatables = ArrayListMultimap.create(); | ||
| 144 | + List<Resource> nonAggregatable = new ArrayList<>(); | ||
| 145 | + | ||
| 146 | + for (Resource r : children) { | ||
| 147 | + if (r instanceof Resource.Continuous) { | ||
| 148 | + // non-aggregatable terminal node | ||
| 149 | + nonAggregatable.add(r); | ||
| 150 | + } else if (aggregatableTypes.contains(r.last().getClass())) { | ||
| 151 | + // aggregatable & terminal node | ||
| 152 | + aggregatables.put(r.last().getClass().getSimpleName(), r); | ||
| 106 | } else { | 153 | } else { |
| 107 | - print("%s%s: %s", Strings.repeat(" ", level), | 154 | + nonAggregatable.add(r); |
| 108 | - resourceName, | ||
| 109 | - toString); | ||
| 110 | } | 155 | } |
| 111 | } | 156 | } |
| 112 | 157 | ||
| 158 | + // print aggregated (terminal) | ||
| 159 | + aggregatables.asMap().entrySet() | ||
| 160 | + .forEach(e -> { | ||
| 161 | + // for each type... | ||
| 162 | + String resourceName = e.getKey(); | ||
| 163 | + | ||
| 164 | + RangeSet<Long> rangeSet = TreeRangeSet.create(); | ||
| 165 | + | ||
| 166 | + // aggregate into RangeSet | ||
| 167 | + e.getValue().stream() | ||
| 168 | + .map(Resource::last) | ||
| 169 | + .map(res -> { | ||
| 170 | + if (res instanceof VlanId) { | ||
| 171 | + return (long) ((VlanId) res).toShort(); | ||
| 172 | + } else if (res instanceof MplsLabel) { | ||
| 173 | + return (long) ((MplsLabel) res).toInt(); | ||
| 174 | + } else if (res instanceof TributarySlot) { | ||
| 175 | + return ((TributarySlot) res).index(); | ||
| 176 | + } | ||
| 177 | + // TODO support Lambda (OchSignal types) | ||
| 178 | + return 0L; | ||
| 179 | + }) | ||
| 180 | + .map(Range::singleton) | ||
| 181 | + .map(range -> range.canonical(DiscreteDomain.longs())) | ||
| 182 | + .forEach(rangeSet::add); | ||
| 183 | + | ||
| 184 | + print("%s%s: %s", Strings.repeat(" ", level + 1), | ||
| 185 | + resourceName, | ||
| 186 | + rangeSet); | ||
| 187 | + }); | ||
| 188 | + | ||
| 189 | + | ||
| 190 | + // print non-aggregatables (recurse) | ||
| 113 | if (sort) { | 191 | if (sort) { |
| 114 | - children.stream() | 192 | + nonAggregatable.stream() |
| 115 | .sorted((o1, o2) -> String.valueOf(o1.id()).compareTo(String.valueOf(o2.id()))) | 193 | .sorted((o1, o2) -> String.valueOf(o1.id()).compareTo(String.valueOf(o2.id()))) |
| 116 | .forEach(r -> printResource(r, level + 1)); | 194 | .forEach(r -> printResource(r, level + 1)); |
| 117 | } else { | 195 | } else { |
| 118 | - // TODO: Should consider better output for leaf nodes | 196 | + nonAggregatable.forEach(r -> printResource(r, level + 1)); |
| 119 | - children.forEach(r -> printResource(r, level + 1)); | ||
| 120 | } | 197 | } |
| 121 | } | 198 | } |
| 122 | } | 199 | } | ... | ... |
-
Please register or login to post a comment