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