intent-details command
- Intended to be used by ONOS-5221, ONOS-5827
Change-Id: I33ab29946907e1963cc66c451d5f1aa77760f4fe
diff --git a/cli/src/main/java/org/onosproject/cli/net/IntentDetailsCommand.java b/cli/src/main/java/org/onosproject/cli/net/IntentDetailsCommand.java
new file mode 100644
index 0000000..1cd0a1b
--- /dev/null
+++ b/cli/src/main/java/org/onosproject/cli/net/IntentDetailsCommand.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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 java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.onlab.util.Tools;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.Link;
+import org.onosproject.net.LinkKey;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentId;
+import org.onosproject.net.intent.IntentService;
+
+/**
+ * Displays details about an Intent in the system.
+ */
+@Command(scope = "onos", name = "intent-details",
+ description = "Displays intent details")
+public class IntentDetailsCommand extends AbstractShellCommand {
+
+ @Option(name = "--id",
+ description = "Filter intent by specific Id", multiValued = true)
+ private List<String> idsStr;
+
+ private Set<IntentId> ids = null;
+
+
+ @Override
+ protected void execute() {
+ if (idsStr != null) {
+ ids = idsStr.stream()
+ .map(IntentId::valueOf)
+ .collect(Collectors.toSet());
+ }
+
+ IntentService service = get(IntentService.class);
+
+ Tools.stream(service.getIntentData())
+ .filter(this::filter)
+ .forEach(this::printIntentData);
+ }
+
+ private boolean filter(IntentData data) {
+ if (ids != null && !ids.contains(data.intent().id())) {
+ return false;
+ }
+
+ return true;
+ }
+
+ private void printIntentData(IntentData data) {
+ print("Key: %s ID: %s", data.key(), data.intent().id());
+
+ print(" Request: %s Current: %s", data.request(), data.state());
+
+ print(" intent: %s", s(data.intent()));
+
+ data.installables().stream()
+ .forEach(this::printInstallable);
+
+ // empty line
+ print("");
+ }
+
+ private void printInstallable(Intent installable) {
+ print(" installable: %s %s", installable.getClass().getSimpleName(),
+ installable.id());
+
+ print(" resources: %s", installable.resources().stream()
+ .filter(r -> !(r instanceof Link))
+ .map(this::s)
+ .collect(Collectors.joining(", ")));
+
+ print(" links: %s", installable.resources().stream()
+ .filter(Link.class::isInstance)
+ .map(Link.class::cast)
+ .map(LinkKey::linkKey)
+ .map(l -> String.format("%s -> %s", l.src(), l.dst()))
+ .collect(Collectors.joining(", ")));
+ }
+
+ protected String s(Object o) {
+ return simplify(String.valueOf(o));
+ }
+
+ /**
+ * Simplify toString result for CLI.
+ *
+ * @param input String
+ * @return simplified String
+ */
+ public static String simplify(String input) {
+ String after = input
+ // omit redundant info
+ .replaceAll("treatment=DefaultTrafficTreatment", "treatment=")
+ .replaceAll("selector=DefaultTrafficSelector", "selector=")
+ // shorten AppId
+ .replaceAll("DefaultApplicationId\\{id=(\\d+), name=([.\\w]+)\\}", "$2($1)")
+ // omit empty list/array attribute
+ .replaceAll("(, )?\\w+=\\[\\]", "")
+ // omit empty map attribute
+ .replaceAll("(, )?\\w+=\\{\\}", "")
+ // omit Object which became empty
+ .replaceAll("(, )?\\w+\\{\\}", "\\{\\}")
+ // shorten FilteredConnectPoint
+ .replaceAll("FilteredConnectPoint", "")
+ // trim prefix Default
+ .replaceAll("Default(\\w+)\\{", "$1\\{")
+ .replaceAll(", , ", ", ");
+
+ return after.equals(input) ? input : simplify(after);
+ }
+
+}
diff --git a/cli/src/main/java/org/onosproject/cli/net/IntentsListCommand.java b/cli/src/main/java/org/onosproject/cli/net/IntentsListCommand.java
index 0953291..59b3e47 100644
--- a/cli/src/main/java/org/onosproject/cli/net/IntentsListCommand.java
+++ b/cli/src/main/java/org/onosproject/cli/net/IntentsListCommand.java
@@ -65,7 +65,7 @@
private boolean pending = false;
@Option(name = "-f", aliases = "--filter",
- description = "Filter intents by specific key",
+ description = "Filter intents by specific keyword",
required = false, multiValued = true)
private List<String> filter = new ArrayList<>();
diff --git a/cli/src/main/java/org/onosproject/cli/net/completer/IntentIdCompleter.java b/cli/src/main/java/org/onosproject/cli/net/completer/IntentIdCompleter.java
new file mode 100644
index 0000000..2d4662e
--- /dev/null
+++ b/cli/src/main/java/org/onosproject/cli/net/completer/IntentIdCompleter.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.completer;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.onlab.util.Tools;
+import org.onosproject.cli.AbstractChoicesCompleter;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentId;
+import org.onosproject.net.intent.IntentService;
+
+/**
+ * IntentId Completer.
+ */
+public class IntentIdCompleter extends AbstractChoicesCompleter {
+
+ @Override
+ protected List<String> choices() {
+ IntentService service = AbstractShellCommand.get(IntentService.class);
+
+ return Tools.stream(service.getIntents())
+ .map(Intent::id)
+ .map(IntentId::toString)
+ .collect(Collectors.toList());
+ }
+
+}
diff --git a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index 8b60699..92271f2 100644
--- a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -729,6 +729,14 @@
<command>
<action class="org.onosproject.cli.net.DpisListCommand"/>
</command>
+
+ <command>
+ <action class="org.onosproject.cli.net.IntentDetailsCommand"/>
+ <optional-completers>
+ <entry key="--id" value-ref="intentIdCompleter"/>
+ </optional-completers>
+ </command>
+
</command-bundle>
<bean id="reviewAppNameCompleter" class="org.onosproject.cli.security.ReviewApplicationNameCompleter"/>
@@ -747,6 +755,7 @@
<bean id="roleCompleter" class="org.onosproject.cli.net.RoleCompleter"/>
<bean id="hostIdCompleter" class="org.onosproject.cli.net.HostIdCompleter"/>
<bean id="intentKeyCompleter" class="org.onosproject.cli.net.IntentKeyCompleter"/>
+ <bean id="intentIdCompleter" class="org.onosproject.cli.net.completer.IntentIdCompleter"/>
<bean id="flowRuleStatusCompleter" class="org.onosproject.cli.net.FlowRuleStatusCompleter"/>
<bean id="groupStatusCompleter" class="org.onosproject.cli.net.GroupStatusCompleter" />
<bean id="connectPointCompleter" class="org.onosproject.cli.net.ConnectPointCompleter"/>
diff --git a/core/api/src/main/java/org/onosproject/net/intent/IntentId.java b/core/api/src/main/java/org/onosproject/net/intent/IntentId.java
index c86471d..9799b78 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/IntentId.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/IntentId.java
@@ -16,6 +16,9 @@
package org.onosproject.net.intent;
import com.google.common.annotations.Beta;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
import org.onlab.util.Identifier;
import org.onosproject.net.resource.ResourceConsumer;
import org.onosproject.net.resource.ResourceConsumerId;
@@ -27,6 +30,8 @@
@Beta
public final class IntentId extends Identifier<Long> implements ResourceConsumer {
+ private static final String HEX_PREFIX = "0x";
+
/**
* Creates an intent identifier from the specified long representation.
*
@@ -38,6 +43,17 @@
}
/**
+ * Creates an intent identifier from the specified String representation.
+ *
+ * @param id hexadecimal String prefixed with 0x
+ * @return intent identifier
+ */
+ public static IntentId valueOf(String id) {
+ checkArgument(id.startsWith(HEX_PREFIX), "Invalid id: %s", id);
+ return valueOf(Long.parseUnsignedLong(id.substring(2), 16));
+ }
+
+ /**
* Constructor for serializer.
*/
IntentId() {
@@ -64,7 +80,7 @@
@Override
public String toString() {
- return "0x" + Long.toHexString(identifier);
+ return HEX_PREFIX + Long.toHexString(identifier);
}
@Override