Make 'mappings' CLI output user friendly 66/54766/4
authorLorand Jakab <lojakab@cisco.com>
Thu, 22 Dec 2016 16:54:38 +0000 (18:54 +0200)
committerLorand Jakab <lojakab@cisco.com>
Fri, 21 Apr 2017 20:44:58 +0000 (23:44 +0300)
Before this patch, the mappings CLI command would print out the full
Java objects contained in a map-cache. That's great for in-depth
debugging, but for a quick look it very hard to read. This patch
implements a user friendly CLI output for mappings, to improve
readability.

The old full output is still available in Karaf, but is by adding the
'-d' or '--debug' switch to the CLI command.

Example output:

---8<--------------------------------------------------------------------
opendaylight-user@root>mappings
Policy map-cache
----------------
Instance ID 1
  [1] 192.0.2.1/32|192.0.2.2/32, TTL: 1440
    -> Locator                                         State     Pri/Wgt
       10.10.10.10                                     no-route  1/1

Southbound map-cache
--------------------
Instance ID 0
  192.0.2.1/32, TTL: 1440
    -> Locator                                         State     Pri/Wgt
       192.168.16.21                                   up        1/1
       fdab:cc19:b80e::21                              up        1/1
       -----------------------------------------------------------------
    -> Subscriber RLOC                                 Subscriber EID
       192.168.16.21                                   No Address Present
       127.0.0.2                                       No Address Present
-------------------------------------------------------------------->8---

Change-Id: Id3c304ac9eda77a0cc36bff1cdeb18d61608a796
Signed-off-by: Lorand Jakab <lojakab@cisco.com>
17 files changed:
mappingservice/api/src/main/java/org/opendaylight/lispflowmapping/interfaces/dao/Subscriber.java
mappingservice/api/src/main/java/org/opendaylight/lispflowmapping/interfaces/mapcache/IMapCache.java
mappingservice/api/src/main/java/org/opendaylight/lispflowmapping/interfaces/mapcache/IMappingSystem.java
mappingservice/api/src/main/java/org/opendaylight/lispflowmapping/interfaces/mappingservice/IMappingService.java
mappingservice/api/src/main/java/org/opendaylight/lispflowmapping/interfaces/mappingservice/IMappingServiceShell.java
mappingservice/implementation/src/main/java/org/opendaylight/lispflowmapping/implementation/MappingService.java
mappingservice/implementation/src/main/java/org/opendaylight/lispflowmapping/implementation/MappingServiceShell.java
mappingservice/implementation/src/main/java/org/opendaylight/lispflowmapping/implementation/MappingSystem.java
mappingservice/lisp-proto/src/main/java/org/opendaylight/lispflowmapping/lisp/type/MappingData.java
mappingservice/lisp-proto/src/main/java/org/opendaylight/lispflowmapping/lisp/util/Constants.java [new file with mode: 0644]
mappingservice/lisp-proto/src/main/java/org/opendaylight/lispflowmapping/lisp/util/Stringifier.java [new file with mode: 0644]
mappingservice/mapcache/src/main/java/org/opendaylight/lispflowmapping/mapcache/AuthKeyDb.java
mappingservice/mapcache/src/main/java/org/opendaylight/lispflowmapping/mapcache/FlatMapCache.java
mappingservice/mapcache/src/main/java/org/opendaylight/lispflowmapping/mapcache/MultiTableMapCache.java
mappingservice/mapcache/src/main/java/org/opendaylight/lispflowmapping/mapcache/SimpleMapCache.java
mappingservice/mapcache/src/main/java/org/opendaylight/lispflowmapping/mapcache/lisp/LispMapCacheStringifier.java [new file with mode: 0644]
mappingservice/shell/src/main/java/org/opendaylight/lispflowmapping/shell/LispMappings.java

index b740bdc4c153ebf635f477bccd582466553103f7..538498af56d918bf0dadeed3ea7fade9a83eff9b 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.lispflowmapping.interfaces.dao;
 
 import java.util.Date;
 import java.util.concurrent.TimeUnit;
+import org.opendaylight.lispflowmapping.lisp.util.LispAddressStringifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.rloc.container.Rloc;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.subscriber.data.grouping.SubscriberData;
@@ -140,4 +141,9 @@ public class Subscriber {
         return "_rloc=" + data.getRloc().toString() + ", _eid=" + data.getEid().toString()
                 + ", _ttl=" + data.getTtl().toString() + ", last request @ " + lastRequestDate.toString();
     }
+
+    public String getString() {
+        return "[" + LispAddressStringifier.getString(data.getRloc())
+                + ", " + LispAddressStringifier.getString(data.getEid()) + "]";
+    }
 }
index 91cee91d0a7a3cce3f686262a81795e27a147234..597ab4c8e3af44b10925e8f4c68a8780b133e78f 100644 (file)
@@ -95,4 +95,11 @@ public interface IMapCache {
      * @return a String consisting of all the mappings in the cache
      */
     String printMappings();
+
+    /**
+     * Print mappings in cache in a human friendly format.
+     *
+     * @return a String consisting of all the mappings in the cache
+     */
+    String prettyPrintMappings();
 }
index c2181a41a9a5618550f9fae0dbd495b7ef5a0a6f..32ada32c624862c94edada6a35ff7906f70a2a42 100644 (file)
@@ -220,6 +220,13 @@ public interface IMappingSystem {
      */
     String printMappings();
 
+    /**
+     * Print mappings in cache in a human friendly format.
+     *
+     * @return a String consisting of all the mappings in the cache
+     */
+    String prettyPrintMappings();
+
     /**
      * Print all authentication keys. Used for testing, debugging and the karaf shell.
      *
index 8e2b1bf43884de5b0c31b3dfef2fa3ca8d34a793..5f08aa619083ddec68e583fde79fe422de95c90a 100644 (file)
@@ -213,6 +213,13 @@ public interface IMappingService {
      */
     String printMappings();
 
+    /**
+     * Print mappings in cache in a human friendly format.
+     *
+     * @return a String consisting of all the mappings in the cache
+     */
+    String prettyPrintMappings();
+
     /**
      * Print all authentication keys. Used for testing, debugging and the karaf shell.
      *
index 474b3b8e78b64d72292c1ed4c9a395d534010249..3e9be6bd222a1bedd4434fc6d6b1400d83e7417c 100644 (file)
@@ -22,6 +22,13 @@ public interface IMappingServiceShell {
      */
     String printMappings();
 
+    /**
+     * Print the full mapping database in human readable form.
+     *
+     * @return the text to be printed on the Karaf console.
+     */
+    String prettyPrintMappings();
+
     /**
      * Print the full authentication key database.
      *
index 6bce0e86663d8340f38a663682acc04b868b1548..0cd50e7632c4a801699b24acffe3ccd490fdbef1 100644 (file)
@@ -481,6 +481,11 @@ public class MappingService implements OdlMappingserviceService, IMappingService
         return mappingSystem.printMappings();
     }
 
+    @Override
+    public String prettyPrintMappings() {
+        return mappingSystem.prettyPrintMappings();
+    }
+
     @Override
     public String printKeys() {
         return mappingSystem.printKeys();
index a214f26bc89205a28c774bb8940f15293710af75..0242910a2d068d6ee2f35f77e6b4f29deeec80f2 100644 (file)
@@ -37,6 +37,11 @@ public class MappingServiceShell implements IMappingServiceShell {
         return mappingService.printMappings();
     }
 
+    @Override
+    public String prettyPrintMappings() {
+        return mappingService.prettyPrintMappings();
+    }
+
     @Override
     public String printKeys() {
         return mappingService.printKeys();
index b21afa6cc18b3f57fdc4acfae7534ac57f40dae4..0661c5f49fdfc9b36a0a10cd94f649f685035ce4 100644 (file)
@@ -651,13 +651,23 @@ public class MappingSystem implements IMappingSystem {
     @Override
     public String printMappings() {
         final StringBuffer sb = new StringBuffer();
-        sb.append("PolicyMapCache\n--------------\n");
+        sb.append("Policy map-cache\n----------------\n");
         sb.append(pmc.printMappings());
-        sb.append("SbMapCache\n----------\n");
+        sb.append("\nSouthbound map-cache\n--------------------\n");
         sb.append(smc.printMappings());
         return sb.toString();
     }
 
+    @Override
+    public String prettyPrintMappings() {
+        final StringBuffer sb = new StringBuffer();
+        sb.append("Policy map-cache\n----------------\n");
+        sb.append(pmc.prettyPrintMappings());
+        sb.append("\nSouthbound map-cache\n--------------------\n");
+        sb.append(smc.prettyPrintMappings());
+        return sb.toString();
+    }
+
     @Override
     public String printKeys() {
         return akdb.printKeys();
index f56b885e28e9f9a14ded204b567df46e4ed85c65..e953177dd01683513030220f19cdb40fe6bcabc4 100644 (file)
@@ -10,7 +10,9 @@ package org.opendaylight.lispflowmapping.lisp.type;
 
 import com.google.common.base.Optional;
 import java.util.Date;
+import org.opendaylight.lispflowmapping.lisp.util.LispAddressStringifier;
 import org.opendaylight.lispflowmapping.lisp.util.MappingRecordUtil;
+import org.opendaylight.lispflowmapping.lisp.util.Stringifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord;
 
@@ -111,4 +113,29 @@ public class MappingData {
 
         return sb.append(']').toString();
     }
+
+    public String getString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append("Merge: ");
+        sb.append(mergeEnabled ? "on" : "off");
+
+        if (xtrId != null) {
+            sb.append(", xTR-ID: ");
+            sb.append(LispAddressStringifier.getString(xtrId));
+        }
+
+        if (timestamp != null) {
+            sb.append(", timestamp: ");
+            sb.append(timestamp.toString());
+        }
+
+        if (record != null) {
+            sb.append("\n");
+            sb.append(Stringifier.getString(record));
+            sb.append("\n");
+        }
+
+        return sb.append(']').toString();
+    }
 }
diff --git a/mappingservice/lisp-proto/src/main/java/org/opendaylight/lispflowmapping/lisp/util/Constants.java b/mappingservice/lisp-proto/src/main/java/org/opendaylight/lispflowmapping/lisp/util/Constants.java
new file mode 100644 (file)
index 0000000..0ade1a3
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017 Cisco Systems, Inc.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.lispflowmapping.lisp.util;
+
+/**
+ * Constants that we can/need to use in several places throughout the project.
+ *
+ * @author Lorand Jakab
+ *
+ */
+public final class Constants {
+    public static final int INET6_ADDRSTRLEN = 46;
+
+    // TODO Move constants from other files that don't clearly belong there into this file.
+}
diff --git a/mappingservice/lisp-proto/src/main/java/org/opendaylight/lispflowmapping/lisp/util/Stringifier.java b/mappingservice/lisp-proto/src/main/java/org/opendaylight/lispflowmapping/lisp/util/Stringifier.java
new file mode 100644 (file)
index 0000000..1dad461
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.lispflowmapping.lisp.util;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecord;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord;
+
+/**
+ * Utility class with static methods returning user friendly string
+ * representations of certain model based auto-generated classes.
+ *
+ * @author Lorand Jakab
+ *
+ */
+public class Stringifier {
+    private static final String NEW_LINE = System.lineSeparator();
+
+    public static String getString(MappingRecord mapping) {
+        return getString(mapping, 0);
+    }
+
+    public static String getString(MappingRecord mapping, int indentation) {
+        final String indent = new String(new char[indentation]).replace("\0", " ");
+
+        StringBuilder mrsb = new StringBuilder(indent);
+
+        // Main information, EID prefix and TTL (for now)
+        mrsb.append(LispAddressStringifier.getString(mapping.getEid()));
+        mrsb.append(", TTL: ");
+        mrsb.append(mapping.getRecordTtl().toString());
+        mrsb.append(NEW_LINE);
+
+        // Locator records
+        // Regular indentation for the mapping record
+        mrsb.append(indent);
+        // Extra indentation for locator records
+        mrsb.append(indent);
+        if (mapping.getLocatorRecord() == null || mapping.getLocatorRecord().isEmpty()) {
+            // We only print the action for negative mappings (0 locator records)
+            mrsb.append("-> Negative entry, action: ");
+            mrsb.append(mapping.getAction().getName());
+        } else {
+            mrsb.append("-> Locator                                         State     Pri/Wgt");
+            mrsb.append(NEW_LINE);
+            mrsb.append(indent);
+            boolean first = true;
+            for (LocatorRecord record : mapping.getLocatorRecord()) {
+                if (first) {
+                    first = false;
+                } else {
+                    mrsb.append(NEW_LINE);
+                    mrsb.append(indent);
+                }
+                mrsb.append(getString(record, indentation + 3));
+            }
+        }
+
+        return mrsb.toString();
+    }
+
+    public static String getString(LocatorRecord locator) {
+        return getString(locator, 0);
+    }
+
+    public static String getString(LocatorRecord locator, int indentation) {
+        final String indent = new String(new char[indentation]).replace("\0", " ");
+
+        StringBuilder lrsb = new StringBuilder(indent);
+
+        String rloc = LispAddressStringifier.getString(locator.getRloc());
+        int padLen = Constants.INET6_ADDRSTRLEN + 2 - rloc.length();
+        lrsb.append(rloc);
+        lrsb.append(new String(new char[padLen]).replace("\0", " "));
+        lrsb.append(locator.isRouted() ? "up        " : "no-route  ");
+        lrsb.append(locator.getPriority().toString());
+        lrsb.append('/');
+        lrsb.append(locator.getWeight().toString());
+
+        return lrsb.toString();
+    }
+}
index f66366e096f428ad199ec6a199cae891c710df33..634f6e1000a2654e10e748fe8c10b95a6094a1fe 100644 (file)
@@ -9,11 +9,11 @@
 package org.opendaylight.lispflowmapping.mapcache;
 
 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
-import org.opendaylight.lispflowmapping.interfaces.dao.IRowVisitor;
 import org.opendaylight.lispflowmapping.interfaces.dao.MappingEntry;
 import org.opendaylight.lispflowmapping.interfaces.dao.SubKeys;
 import org.opendaylight.lispflowmapping.interfaces.mapcache.IAuthKeyDb;
 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
+import org.opendaylight.lispflowmapping.mapcache.lisp.LispMapCacheStringifier;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.SourceDestKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkey;
@@ -115,41 +115,6 @@ public class AuthKeyDb implements IAuthKeyDb {
 
     @Override
     public String printKeys() {
-        final StringBuffer sb = new StringBuffer();
-        sb.append("Keys\tValues\n");
-
-        final IRowVisitor innerVisitor = (new IRowVisitor() {
-            String lastKey = "";
-
-            public void visitRow(Object keyId, String valueKey, Object value) {
-                String key = keyId.getClass().getSimpleName() + "#" + keyId;
-                if (!lastKey.equals(key)) {
-                    sb.append("\n" + key + "\t");
-                }
-                sb.append(valueKey + "=" + value + "\t");
-                lastKey = key;
-            }
-        });
-
-        dao.getAll(new IRowVisitor() {
-            String lastKey = "";
-
-            public void visitRow(Object keyId, String valueKey, Object value) {
-                String key = keyId.getClass().getSimpleName() + "#" + keyId;
-                if (!lastKey.equals(key)) {
-                    sb.append("\n" + key + "\t");
-                }
-                if (valueKey.equals(SubKeys.VNI)) {
-                    sb.append(valueKey + "= { ");
-                    ((ILispDAO)value).getAll(innerVisitor);
-                    sb.append("}\t");
-                } else {
-                    sb.append(valueKey + "=" + value + "\t");
-                }
-                lastKey = key;
-            }
-        });
-        sb.append("\n");
-        return sb.toString();
+        return LispMapCacheStringifier.printKeys(dao);
     }
 }
index 2764766984cbaf0beabe500b634c2161cd7c765d..32ab47f4e48be360ee69a9603842c4fe14d7f3f2 100644 (file)
@@ -9,11 +9,11 @@
 package org.opendaylight.lispflowmapping.mapcache;
 
 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
-import org.opendaylight.lispflowmapping.interfaces.dao.IRowVisitor;
 import org.opendaylight.lispflowmapping.interfaces.dao.MappingEntry;
 import org.opendaylight.lispflowmapping.interfaces.dao.SubKeys;
 import org.opendaylight.lispflowmapping.interfaces.mapcache.IMapCache;
 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
+import org.opendaylight.lispflowmapping.mapcache.lisp.LispMapCacheStringifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
 
 /**
@@ -77,21 +77,11 @@ public class FlatMapCache implements IMapCache {
 
     @Override
     public String printMappings() {
-        final StringBuffer sb = new StringBuffer();
-        sb.append("Keys\tValues\n");
-        dao.getAll(new IRowVisitor() {
-            String lastKey = "";
+        return LispMapCacheStringifier.printFMCMappings(dao);
+    }
 
-            public void visitRow(Object keyId, String valueKey, Object value) {
-                String key = keyId.getClass().getSimpleName() + "#" + keyId;
-                if (!lastKey.equals(key)) {
-                    sb.append("\n" + key + "\t");
-                }
-                sb.append(valueKey + "=" + value + "\t");
-                lastKey = key;
-            }
-        });
-        sb.append("\n");
-        return sb.toString();
+    @Override
+    public String prettyPrintMappings() {
+        return LispMapCacheStringifier.prettyPrintFMCMappings(dao);
     }
 }
index 960927fb1674711bd1ca8ff5ad1e2b442a5dc74c..59b4621d2abf18c49840d86d55d4ef626ea5226e 100644 (file)
@@ -9,13 +9,13 @@ package org.opendaylight.lispflowmapping.mapcache;
 
 import java.util.Map;
 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
-import org.opendaylight.lispflowmapping.interfaces.dao.IRowVisitor;
 import org.opendaylight.lispflowmapping.interfaces.dao.MappingEntry;
 import org.opendaylight.lispflowmapping.interfaces.dao.SubKeys;
 import org.opendaylight.lispflowmapping.interfaces.mapcache.IMapCache;
 import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
 import org.opendaylight.lispflowmapping.lisp.util.SourceDestKeyHelper;
+import org.opendaylight.lispflowmapping.mapcache.lisp.LispMapCacheStringifier;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.SourceDestKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
 
@@ -170,61 +170,6 @@ public class MultiTableMapCache implements IMapCache {
         return (ILispDAO) mappingsDb.getSpecific(SourceDestKeyHelper.getDstBinary(address), SubKeys.LCAF_SRCDST);
     }
 
-    public String printMappings() {
-        final StringBuffer sb = new StringBuffer();
-        sb.append("Keys\tValues\n");
-        final IRowVisitor innerVisitor = (new IRowVisitor() {
-            String lastKey = "";
-
-            public void visitRow(Object keyId, String valueKey, Object value) {
-                String key = keyId.getClass().getSimpleName() + "#" + keyId;
-                if (!lastKey.equals(key)) {
-                    sb.append("\n" + key + "\t");
-                }
-                sb.append(valueKey + "=" + value + "\t");
-                lastKey = key;
-            }
-        });
-        final IRowVisitor vniVisitor = (new IRowVisitor() {
-            String lastKey = "";
-
-            public void visitRow(Object keyId, String valueKey, Object value) {
-                String key = keyId.getClass().getSimpleName() + "#" + keyId;
-                if (!lastKey.equals(key)) {
-                    sb.append(key + "\t");
-                }
-                if ((valueKey.equals(SubKeys.LCAF_SRCDST))) {
-                    sb.append(valueKey + "= { ");
-                    ((ILispDAO)value).getAll(innerVisitor);
-                    sb.append("}\t");
-                } else {
-                    sb.append(valueKey + "=" + value + "\t");
-                }
-                lastKey = key;
-            }
-        });
-        dao.getAll(new IRowVisitor() {
-            String lastKey = "";
-
-            public void visitRow(Object keyId, String valueKey, Object value) {
-                String key = keyId.getClass().getSimpleName() + "#" + keyId;
-                if (!lastKey.equals(key)) {
-                    sb.append("\n" + key + "\t");
-                }
-                if (valueKey.equals(SubKeys.VNI)) {
-                    sb.append(valueKey + "= { ");
-                    ((ILispDAO)value).getAll(vniVisitor);
-                    sb.append("}\t");
-                } else {
-                    sb.append(valueKey + "=" + value + "\t");
-                }
-                lastKey = key;
-            }
-        });
-        sb.append("\n");
-        return sb.toString();
-    }
-
     @Override
     public void addData(Eid eid, String subKey, Object data) {
         Eid key = MaskUtil.normalize(eid);
@@ -270,4 +215,14 @@ public class MultiTableMapCache implements IMapCache {
             table.removeSpecific(key, subKey);
         }
     }
+
+    @Override
+    public String printMappings() {
+        return LispMapCacheStringifier.printMTMCMappings(dao);
+    }
+
+    @Override
+    public String prettyPrintMappings() {
+        return LispMapCacheStringifier.prettyPrintMTMCMappings(dao);
+    }
 }
index fb994a65df8125c64550c3c1f5cae49cffaca04d..93a80966d277c54c9288ca3312babd733ed1b169 100644 (file)
@@ -19,6 +19,7 @@ import org.opendaylight.lispflowmapping.interfaces.dao.MappingEntry;
 import org.opendaylight.lispflowmapping.interfaces.dao.SubKeys;
 import org.opendaylight.lispflowmapping.interfaces.mapcache.ILispMapCache;
 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
+import org.opendaylight.lispflowmapping.mapcache.lisp.LispMapCacheStringifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.inet.binary.types.rev160303.IpAddressBinary;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
@@ -266,41 +267,11 @@ public class SimpleMapCache implements ILispMapCache {
 
     @Override
     public String printMappings() {
-        final StringBuffer sb = new StringBuffer();
-        sb.append("Keys\tValues\n");
-
-        final IRowVisitor innerVisitor = (new IRowVisitor() {
-            String lastKey = "";
-
-            public void visitRow(Object keyId, String valueKey, Object value) {
-                String key = keyId.getClass().getSimpleName() + "#" + keyId;
-                if (!lastKey.equals(key)) {
-                    sb.append("\n" + key + "\t");
-                }
-                sb.append(valueKey + "=" + value + "\t");
-                lastKey = key;
-            }
-        });
-
-        dao.getAll(new IRowVisitor() {
-            String lastKey = "";
+        return LispMapCacheStringifier.printSMCMappings(dao);
+    }
 
-            public void visitRow(Object keyId, String valueKey, Object value) {
-                String key = keyId.getClass().getSimpleName() + "#" + keyId;
-                if (!lastKey.equals(key)) {
-                    sb.append("\n" + key + "\t");
-                }
-                if (valueKey.equals(SubKeys.VNI)) {
-                    sb.append(valueKey + "= { ");
-                    ((ILispDAO)value).getAll(innerVisitor);
-                    sb.append("}\t");
-                } else {
-                    sb.append(valueKey + "=" + value + "\t");
-                }
-                lastKey = key;
-            }
-        });
-        sb.append("\n");
-        return sb.toString();
+    @Override
+    public String prettyPrintMappings() {
+        return LispMapCacheStringifier.prettyPrintSMCMappings(dao);
     }
 }
diff --git a/mappingservice/mapcache/src/main/java/org/opendaylight/lispflowmapping/mapcache/lisp/LispMapCacheStringifier.java b/mappingservice/mapcache/src/main/java/org/opendaylight/lispflowmapping/mapcache/lisp/LispMapCacheStringifier.java
new file mode 100644 (file)
index 0000000..c2b14e2
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2017 Cisco Systems, Inc.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.lispflowmapping.mapcache.lisp;
+
+import java.util.Set;
+import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
+import org.opendaylight.lispflowmapping.interfaces.dao.IRowVisitor;
+import org.opendaylight.lispflowmapping.interfaces.dao.SubKeys;
+import org.opendaylight.lispflowmapping.interfaces.dao.Subscriber;
+import org.opendaylight.lispflowmapping.lisp.type.MappingData;
+import org.opendaylight.lispflowmapping.lisp.util.Constants;
+import org.opendaylight.lispflowmapping.lisp.util.LispAddressStringifier;
+import org.opendaylight.lispflowmapping.lisp.util.Stringifier;
+
+public class LispMapCacheStringifier {
+    public static String printKeys(ILispDAO dao) {
+        final StringBuffer sb = new StringBuffer();
+        sb.append("Keys\tValues\n");
+
+        final IRowVisitor innerVisitor = (new IRowVisitor() {
+            String lastKey = "";
+
+            public void visitRow(Object keyId, String valueKey, Object value) {
+                String key = keyId.getClass().getSimpleName() + "#" + keyId;
+                if (!lastKey.equals(key)) {
+                    sb.append("\n" + key + "\t");
+                }
+                sb.append(valueKey + "=" + value + "\t");
+                lastKey = key;
+            }
+        });
+
+        dao.getAll(new IRowVisitor() {
+            String lastKey = "";
+
+            public void visitRow(Object keyId, String valueKey, Object value) {
+                String key = keyId.getClass().getSimpleName() + "#" + keyId;
+                if (!lastKey.equals(key)) {
+                    sb.append("\n" + key + "\t");
+                }
+                if (valueKey.equals(SubKeys.VNI)) {
+                    sb.append(valueKey + "= { ");
+                    ((ILispDAO)value).getAll(innerVisitor);
+                    sb.append("}\t");
+                } else {
+                    sb.append(valueKey + "=" + value + "\t");
+                }
+                lastKey = key;
+            }
+        });
+        sb.append("\n");
+        return sb.toString();
+    }
+
+    public static String printFMCMappings(ILispDAO dao) {
+        final StringBuffer sb = new StringBuffer();
+        sb.append("Keys\tValues\n");
+        dao.getAll(new IRowVisitor() {
+            String lastKey = "";
+
+            public void visitRow(Object keyId, String valueKey, Object value) {
+                String key = keyId.getClass().getSimpleName() + "#" + keyId;
+                if (!lastKey.equals(key)) {
+                    sb.append("\n" + key + "\t");
+                }
+                sb.append(valueKey + "=" + value + "\t");
+                lastKey = key;
+            }
+        });
+        sb.append("\n");
+        return sb.toString();
+    }
+
+    public static String prettyPrintFMCMappings(ILispDAO dao) {
+        final StringBuffer sb = new StringBuffer();
+        dao.getAll(new IRowVisitor() {
+            public void visitRow(Object keyId, String valueKey, Object value) {
+                switch (valueKey) {
+                    case SubKeys.RECORD:
+                        MappingData md = (MappingData) value;
+                        sb.append(Stringifier.getString(md.getRecord(), 2));
+                        sb.append("\n");
+                        break;
+                    default:
+                        break;
+                }
+            }
+        });
+        sb.append("\n");
+        return sb.toString();
+    }
+
+    public static String printMTMCMappings(ILispDAO dao) {
+        final StringBuffer sb = new StringBuffer();
+        sb.append("Keys\tValues\n");
+        final IRowVisitor innerVisitor = (new IRowVisitor() {
+            String lastKey = "";
+
+            public void visitRow(Object keyId, String valueKey, Object value) {
+                String key = keyId.getClass().getSimpleName() + "#" + keyId;
+                if (!lastKey.equals(key)) {
+                    sb.append("\n" + key + "\t");
+                }
+                sb.append(valueKey + "=" + value + "\t");
+                lastKey = key;
+            }
+        });
+        final IRowVisitor vniVisitor = (new IRowVisitor() {
+            String lastKey = "";
+
+            public void visitRow(Object keyId, String valueKey, Object value) {
+                String key = keyId.getClass().getSimpleName() + "#" + keyId;
+                if (!lastKey.equals(key)) {
+                    sb.append(key + "\t");
+                }
+                if ((valueKey.equals(SubKeys.LCAF_SRCDST))) {
+                    sb.append(valueKey + "= { ");
+                    ((ILispDAO)value).getAll(innerVisitor);
+                    sb.append("}\t");
+                } else {
+                    sb.append(valueKey + "=" + value + "\t");
+                }
+                lastKey = key;
+            }
+        });
+        dao.getAll(new IRowVisitor() {
+            String lastKey = "";
+
+            public void visitRow(Object keyId, String valueKey, Object value) {
+                String key = keyId.getClass().getSimpleName() + "#" + keyId;
+                if (!lastKey.equals(key)) {
+                    sb.append("\n" + key + "\t");
+                }
+                if (valueKey.equals(SubKeys.VNI)) {
+                    sb.append(valueKey + "= { ");
+                    ((ILispDAO)value).getAll(vniVisitor);
+                    sb.append("}\t");
+                } else {
+                    sb.append(valueKey + "=" + value + "\t");
+                }
+                lastKey = key;
+            }
+        });
+        sb.append("\n");
+        return sb.toString();
+    }
+
+    @SuppressWarnings("unchecked")
+    public static String prettyPrintMTMCMappings(ILispDAO dao) {
+        final StringBuffer sb = new StringBuffer();
+
+        final IRowVisitor mappingVisitor = (new IRowVisitor() {
+            public void visitRow(Object keyId, String valueKey, Object value) {
+                switch (valueKey) {
+                    case SubKeys.RECORD:
+                        MappingData md = (MappingData) value;
+                        sb.append(Stringifier.getString(md.getRecord(), 2));
+                        sb.append("\n");
+                        break;
+                    case SubKeys.SUBSCRIBERS:
+                        Set<Subscriber> subscribers = (Set<Subscriber>) value;
+                        sb.append(prettyPrintSubscriberSet(subscribers, 4));
+                        sb.append("\n");
+                        break;
+                    case SubKeys.LCAF_SRCDST:
+                        ((ILispDAO)value).getAll(this);
+                        break;
+                    default:
+                        break;
+                }
+            }
+        });
+
+        dao.getAll(new IRowVisitor() {
+            String lastKey = "";
+
+            public void visitRow(Object keyId, String valueKey, Object value) {
+                String key = keyId.getClass().getSimpleName() + "#" + keyId;
+                if (!lastKey.equals(key)) {
+                    sb.append("Instance ID " + keyId + "\n");
+                }
+                if (valueKey.equals(SubKeys.VNI)) {
+                    ((ILispDAO)value).getAll(mappingVisitor);
+                }
+                lastKey = key;
+            }
+        });
+        return sb.toString();
+    }
+
+    public static String printSMCMappings(ILispDAO dao) {
+        final StringBuffer sb = new StringBuffer();
+        sb.append("Keys\tValues\n");
+
+        final IRowVisitor innerVisitor = (new IRowVisitor() {
+            String lastKey = "";
+
+            public void visitRow(Object keyId, String valueKey, Object value) {
+                String key = keyId.getClass().getSimpleName() + "#" + keyId;
+                if (!lastKey.equals(key)) {
+                    sb.append("\n" + key + "\t");
+                }
+                sb.append(valueKey + "=" + value + "\t");
+                lastKey = key;
+            }
+        });
+
+        dao.getAll(new IRowVisitor() {
+            String lastKey = "";
+
+            public void visitRow(Object keyId, String valueKey, Object value) {
+                String key = keyId.getClass().getSimpleName() + "#" + keyId;
+                if (!lastKey.equals(key)) {
+                    sb.append("\n" + key + "\t");
+                }
+                if (valueKey.equals(SubKeys.VNI)) {
+                    sb.append(valueKey + "= { ");
+                    ((ILispDAO)value).getAll(innerVisitor);
+                    sb.append("}\t");
+                } else {
+                    sb.append(valueKey + "=" + value + "\t");
+                }
+                lastKey = key;
+            }
+        });
+        sb.append("\n");
+        return sb.toString();
+    }
+
+    @SuppressWarnings("unchecked")
+    public static String prettyPrintSMCMappings(ILispDAO dao) {
+        final StringBuffer sb = new StringBuffer();
+
+        final IRowVisitor mappingVisitor = (new IRowVisitor() {
+            public void visitRow(Object keyId, String valueKey, Object value) {
+                switch (valueKey) {
+                    case SubKeys.RECORD:
+                        MappingData md = (MappingData) value;
+                        sb.append(Stringifier.getString(md.getRecord(), 2));
+                        sb.append("\n");
+                        break;
+                    case SubKeys.SUBSCRIBERS:
+                        Set<Subscriber> subscribers = (Set<Subscriber>) value;
+                        sb.append(prettyPrintSubscriberSet(subscribers, 4));
+                        sb.append("\n");
+                        break;
+                    default:
+                        break;
+                }
+            }
+        });
+
+        dao.getAll(new IRowVisitor() {
+            String lastKey = "";
+
+            public void visitRow(Object keyId, String valueKey, Object value) {
+                String key = keyId.getClass().getSimpleName() + "#" + keyId;
+                if (!lastKey.equals(key)) {
+                    sb.append("Instance ID " + keyId + "\n");
+                }
+                if (valueKey.equals(SubKeys.VNI)) {
+                    ((ILispDAO)value).getAll(mappingVisitor);
+                }
+                lastKey = key;
+            }
+        });
+        return sb.toString();
+    }
+
+    /**
+     * Given a Set of Subscriber objects, and the level of indentation, create a nicely formatted String to be added
+     * to a map-cache print-out in a tabular form.
+     *
+     * @param subscribers the Set of Subscriber objects to be printed
+     * @param indentation indentation level
+     * @return the formatted String
+     */
+    public static String prettyPrintSubscriberSet(Set<Subscriber> subscribers, int indentation) {
+        final String indent = new String(new char[indentation]).replace("\0", " ");
+
+        StringBuilder sb = new StringBuilder(indent);
+        sb.append("   -----------------------------------------------------------------\n");
+        sb.append(indent);
+        sb.append("-> Subscriber RLOC                                 Subscriber EID\n   ");
+        sb.append(indent);
+        boolean first = true;
+        for (Subscriber subscriber : subscribers) {
+            if (first) {
+                first = false;
+            } else {
+                sb.append("\n   ");
+                sb.append(indent);
+            }
+            String srcRloc = LispAddressStringifier.getString(subscriber.getSrcRloc());
+            int padLen = Constants.INET6_ADDRSTRLEN + 2 - srcRloc.length();
+            sb.append(srcRloc);
+            sb.append(new String(new char[padLen]).replace("\0", " "));
+            sb.append(LispAddressStringifier.getString(subscriber.getSrcEid()));
+        }
+        return sb.toString();
+    }
+}
index ecb36a2531a8683cafe4e5eb277537b53dc6223f..01a8de054aca2e240258d03af8a1c908d217a690 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Cisco Systems, Inc.  All rights reserved.
+ * Copyright (c) 2015, 2017 Cisco Systems, Inc.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -9,6 +9,7 @@
 package org.opendaylight.lispflowmapping.shell;
 
 import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
 import org.apache.karaf.shell.console.OsgiCommandSupport;
 import org.opendaylight.lispflowmapping.interfaces.mappingservice.IMappingServiceShell;
 
@@ -20,12 +21,19 @@ import org.opendaylight.lispflowmapping.interfaces.mappingservice.IMappingServic
  */
 @Command(scope = "mappingservice", name = "mappings", description = "Print mapping database")
 public class LispMappings  extends OsgiCommandSupport {
+    @Option(name = "-d", aliases = "--debug", description = "Debug output", required = false, multiValued = false)
+    private boolean debug;
+
     private IMappingServiceShell mappingServiceShell;
 
     @Override
     @SuppressWarnings("checkstyle:RegexpSinglelineJava")
     protected Object doExecute() throws Exception {
-        System.out.print(mappingServiceShell.printMappings());
+        if (debug) {
+            System.out.print(mappingServiceShell.printMappings());
+        } else {
+            System.out.print(mappingServiceShell.prettyPrintMappings());
+        }
         return null;
     }