http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/GetRegistryClientId.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/GetRegistryClientId.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/GetRegistryClientId.java
new file mode 100644
index 0000000..f2f0685
--- /dev/null
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/GetRegistryClientId.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.nifi.toolkit.cli.impl.command.nifi.registry;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.toolkit.cli.api.CommandException;
+import org.apache.nifi.toolkit.cli.api.Context;
+import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
+import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
+import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
+import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
+import org.apache.nifi.web.api.dto.RegistryDTO;
+import org.apache.nifi.web.api.entity.RegistryClientsEntity;
+
+import java.io.IOException;
+import java.util.Properties;
+
+/**
+ * Command to get the id of a registry client by name or url.
+ */
+public class GetRegistryClientId extends AbstractNiFiCommand {
+
+    public GetRegistryClientId() {
+        super("get-reg-client-id");
+    }
+
+    @Override
+    public String getDescription() {
+        return "Returns the id of the first registry client found with the 
given name or url. " +
+                "Only one of name or url can be specified.";
+    }
+
+    @Override
+    protected void doInitialize(final Context context) {
+        addOption(CommandOption.REGISTRY_CLIENT_NAME.createOption());
+        addOption(CommandOption.REGISTRY_CLIENT_URL.createOption());
+    }
+
+    @Override
+    protected void doExecute(final NiFiClient client, final Properties 
properties)
+            throws NiFiClientException, IOException, CommandException {
+        final String regClientName = getArg(properties, 
CommandOption.REGISTRY_CLIENT_NAME);
+        final String regClientUrl = getArg(properties, 
CommandOption.REGISTRY_CLIENT_URL);
+
+        if (!StringUtils.isBlank(regClientName) && 
!StringUtils.isBlank(regClientUrl)) {
+            throw new CommandException("Name and URL cannot be specified at 
the same time");
+        }
+
+        if (StringUtils.isBlank(regClientName) && 
StringUtils.isBlank(regClientUrl)) {
+            throw new CommandException("Name or URL must be specified");
+        }
+
+        final RegistryClientsEntity registries = 
client.getControllerClient().getRegistryClients();
+
+        RegistryDTO registry;
+
+        if (!StringUtils.isBlank(regClientName)) {
+            registry = registries.getRegistries().stream()
+                    .map(r -> r.getComponent())
+                    .filter(r -> 
r.getName().equalsIgnoreCase(regClientName.trim()))
+                    .findFirst()
+                    .orElse(null);
+        } else {
+            registry = registries.getRegistries().stream()
+                    .map(r -> r.getComponent())
+                    .filter(r -> 
r.getUri().equalsIgnoreCase(regClientUrl.trim()))
+                    .findFirst()
+                    .orElse(null);
+        }
+
+        if (registry == null) {
+            throw new NiFiClientException("No registry client exists with the 
name '" + regClientName + "'");
+        } else {
+            println(registry.getId());
+        }
+    }
+
+    private RegistryDTO getByName(final RegistryClientsEntity registries, 
final String regClientName) {
+        return registries.getRegistries().stream()
+                .map(r -> r.getComponent())
+                .filter(r -> r.getName().equalsIgnoreCase(regClientName))
+                .findFirst()
+                .orElse(null);
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/ListRegistryClients.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/ListRegistryClients.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/ListRegistryClients.java
index 396bb01..4cf498f 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/ListRegistryClients.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/ListRegistryClients.java
@@ -16,6 +16,7 @@
  */
 package org.apache.nifi.toolkit.cli.impl.command.nifi.registry;
 
+import org.apache.nifi.toolkit.cli.api.ResultWriter;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
 import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
@@ -34,9 +35,16 @@ public class ListRegistryClients extends AbstractNiFiCommand 
{
     }
 
     @Override
+    public String getDescription() {
+        return "Returns the registry clients defined in the given NiFi 
instance.";
+    }
+
+    @Override
     protected void doExecute(final NiFiClient client, final Properties 
properties) throws NiFiClientException, IOException {
         final RegistryClientsEntity registries = 
client.getControllerClient().getRegistryClients();
-        writeResult(properties, registries);
+
+        final ResultWriter resultWriter = getResultWriter(properties);
+        resultWriter.writeRegistryClients(registries, 
getContext().getOutput());
     }
 
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/UpdateRegistryClient.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/UpdateRegistryClient.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/UpdateRegistryClient.java
index b7a2f60..94825b4 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/UpdateRegistryClient.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/nifi/registry/UpdateRegistryClient.java
@@ -40,6 +40,11 @@ public class UpdateRegistryClient extends 
AbstractNiFiCommand {
     }
 
     @Override
+    public String getDescription() {
+        return "Updates the given registry client with a new name, url, or 
description.";
+    }
+
+    @Override
     public void doInitialize(final Context context) {
         addOption(CommandOption.REGISTRY_CLIENT_ID.createOption());
         addOption(CommandOption.REGISTRY_CLIENT_NAME.createOption());

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/AbstractNiFiRegistryCommand.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/AbstractNiFiRegistryCommand.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/AbstractNiFiRegistryCommand.java
index 70fb40a..9753d8d 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/AbstractNiFiRegistryCommand.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/AbstractNiFiRegistryCommand.java
@@ -17,6 +17,7 @@
 package org.apache.nifi.toolkit.cli.impl.command.registry;
 
 import org.apache.commons.cli.ParseException;
+import org.apache.nifi.registry.bucket.BucketItem;
 import org.apache.nifi.registry.client.NiFiRegistryClient;
 import org.apache.nifi.registry.client.NiFiRegistryException;
 import org.apache.nifi.toolkit.cli.api.ClientFactory;
@@ -25,6 +26,8 @@ import 
org.apache.nifi.toolkit.cli.impl.command.AbstractPropertyCommand;
 import org.apache.nifi.toolkit.cli.impl.session.SessionVariables;
 
 import java.io.IOException;
+import java.util.List;
+import java.util.Optional;
 import java.util.Properties;
 
 /**
@@ -60,4 +63,22 @@ public abstract class AbstractNiFiRegistryCommand extends 
AbstractPropertyComman
     protected abstract void doExecute(final NiFiRegistryClient client, final 
Properties properties)
             throws IOException, NiFiRegistryException, ParseException;
 
+    /*
+     * NOTE: This will bring back every item in the registry. We should create 
an end-point on the registry side
+     * to retrieve a flow by id and remove this later.
+     */
+    protected String getBucketId(final NiFiRegistryClient client, final String 
flowId) throws IOException, NiFiRegistryException {
+        final List<BucketItem> items = client.getItemsClient().getAll();
+
+        final Optional<BucketItem> matchingItem = items.stream()
+                .filter(i ->  i.getIdentifier().equals(flowId))
+                .findFirst();
+
+        if (!matchingItem.isPresent()) {
+            throw new NiFiRegistryException("Versioned flow does not exist 
with id " + flowId);
+        }
+
+        return matchingItem.get().getBucketIdentifier();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/bucket/CreateBucket.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/bucket/CreateBucket.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/bucket/CreateBucket.java
index d92fe6d..6f71c2f 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/bucket/CreateBucket.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/bucket/CreateBucket.java
@@ -38,6 +38,11 @@ public class CreateBucket extends 
AbstractNiFiRegistryCommand {
     }
 
     @Override
+    public String getDescription() {
+        return "Creates a bucket using the given name and description.";
+    }
+
+    @Override
     public void doInitialize(final Context context) {
         addOption(CommandOption.BUCKET_NAME.createOption());
         addOption(CommandOption.BUCKET_DESC.createOption());

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/bucket/ListBuckets.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/bucket/ListBuckets.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/bucket/ListBuckets.java
index c20db63..e833d39 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/bucket/ListBuckets.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/bucket/ListBuckets.java
@@ -20,6 +20,7 @@ import org.apache.commons.cli.MissingOptionException;
 import org.apache.nifi.registry.bucket.Bucket;
 import org.apache.nifi.registry.client.NiFiRegistryClient;
 import org.apache.nifi.registry.client.NiFiRegistryException;
+import org.apache.nifi.toolkit.cli.api.ResultWriter;
 import 
org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
 
 import java.io.IOException;
@@ -36,9 +37,15 @@ public class ListBuckets extends AbstractNiFiRegistryCommand 
{
     }
 
     @Override
+    public String getDescription() {
+        return "Lists the buckets that the current user has access to.";
+    }
+
+    @Override
     protected void doExecute(final NiFiRegistryClient client, final Properties 
properties)
             throws IOException, NiFiRegistryException, MissingOptionException {
         final List<Bucket> buckets = client.getBucketClient().getAll();
-        writeResult(properties, buckets);
+        final ResultWriter resultWriter = getResultWriter(properties);
+        resultWriter.writeBuckets(buckets, getContext().getOutput());
     }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/CreateFlow.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/CreateFlow.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/CreateFlow.java
index f5100f5..d62af16 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/CreateFlow.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/CreateFlow.java
@@ -38,6 +38,11 @@ public class CreateFlow extends AbstractNiFiRegistryCommand {
     }
 
     @Override
+    public String getDescription() {
+        return "Creates a flow in the given bucket with the given name and 
description.";
+    }
+
+    @Override
     public void doInitialize(final Context context) {
         addOption(CommandOption.BUCKET_ID.createOption());
         addOption(CommandOption.FLOW_NAME.createOption());

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ExportFlowVersion.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ExportFlowVersion.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ExportFlowVersion.java
index 6a07ba0..cb0e187 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ExportFlowVersion.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ExportFlowVersion.java
@@ -17,17 +17,17 @@
 package org.apache.nifi.toolkit.cli.impl.command.registry.flow;
 
 import org.apache.commons.cli.ParseException;
-import org.apache.nifi.registry.bucket.BucketItem;
 import org.apache.nifi.registry.client.NiFiRegistryClient;
 import org.apache.nifi.registry.client.NiFiRegistryException;
 import org.apache.nifi.registry.flow.VersionedFlowSnapshot;
 import org.apache.nifi.toolkit.cli.api.Context;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import 
org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
+import org.apache.nifi.toolkit.cli.impl.util.JacksonUtils;
 
+import java.io.FileOutputStream;
 import java.io.IOException;
-import java.util.List;
-import java.util.Optional;
+import java.io.OutputStream;
 import java.util.Properties;
 
 public class ExportFlowVersion extends AbstractNiFiRegistryCommand {
@@ -44,6 +44,12 @@ public class ExportFlowVersion extends 
AbstractNiFiRegistryCommand {
     }
 
     @Override
+    public String getDescription() {
+        return "Exports a specific version of a flow. The --" + 
CommandOption.OUTPUT_FILE.getLongName()
+                + " can be used to export to a file, otherwise the content 
will be written to terminal or standard out.";
+    }
+
+    @Override
     public void doExecute(final NiFiRegistryClient client, final Properties 
properties)
             throws ParseException, IOException, NiFiRegistryException {
         final String flowId = getRequiredArg(properties, 
CommandOption.FLOW_ID);
@@ -66,25 +72,17 @@ public class ExportFlowVersion extends 
AbstractNiFiRegistryCommand {
         versionedFlowSnapshot.getSnapshotMetadata().setFlowIdentifier(null);
         versionedFlowSnapshot.getSnapshotMetadata().setLink(null);
 
-        writeResult(properties, versionedFlowSnapshot);
-    }
-
-    /*
-     * NOTE: This will bring back every item in the registry. We should create 
an end-point on the registry side
-     * to retrieve a flow by id and remove this later.
-     */
-    private String getBucketId(final NiFiRegistryClient client, final String 
flowId) throws IOException, NiFiRegistryException {
-        final List<BucketItem> items = client.getItemsClient().getAll();
-
-        final Optional<BucketItem> matchingItem = items.stream()
-                .filter(i ->  i.getIdentifier().equals(flowId))
-                .findFirst();
-
-        if (!matchingItem.isPresent()) {
-            throw new NiFiRegistryException("Versioned flow does not exist 
with id " + flowId);
+        // currently export doesn't use the ResultWriter concept, it always 
writes JSON
+        // destination will be a file if outputFile is specified, otherwise it 
will be the output stream of the CLI
+        if (properties.containsKey(CommandOption.OUTPUT_FILE.getLongName())) {
+            final String outputFile = 
properties.getProperty(CommandOption.OUTPUT_FILE.getLongName());
+            try (final OutputStream resultOut = new 
FileOutputStream(outputFile)) {
+                JacksonUtils.write(versionedFlowSnapshot, resultOut);
+            }
+        } else {
+            final OutputStream output = getContext().getOutput();
+            JacksonUtils.write(versionedFlowSnapshot, output);
         }
-
-        return matchingItem.get().getBucketIdentifier();
     }
 
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ImportFlowVersion.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ImportFlowVersion.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ImportFlowVersion.java
index 3aab6e9..3e739de 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ImportFlowVersion.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ImportFlowVersion.java
@@ -16,8 +16,8 @@
  */
 package org.apache.nifi.toolkit.cli.impl.command.registry.flow;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.commons.cli.ParseException;
-import org.apache.nifi.registry.bucket.BucketItem;
 import org.apache.nifi.registry.client.FlowSnapshotClient;
 import org.apache.nifi.registry.client.NiFiRegistryClient;
 import org.apache.nifi.registry.client.NiFiRegistryException;
@@ -26,11 +26,10 @@ import 
org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata;
 import org.apache.nifi.toolkit.cli.api.Context;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import 
org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
+import org.apache.nifi.toolkit.cli.impl.util.JacksonUtils;
 
 import java.io.FileInputStream;
 import java.io.IOException;
-import java.util.List;
-import java.util.Optional;
 import java.util.Properties;
 
 /**
@@ -43,6 +42,12 @@ public class ImportFlowVersion extends 
AbstractNiFiRegistryCommand {
     }
 
     @Override
+    public String getDescription() {
+        return "Imports a version of a flow that was previously exported. The 
imported version automatically becomes " +
+                "the next version of the given flow.";
+    }
+
+    @Override
     public void doInitialize(final Context context) {
         addOption(CommandOption.FLOW_ID.createOption());
         addOption(CommandOption.INPUT_FILE.createOption());
@@ -57,7 +62,8 @@ public class ImportFlowVersion extends 
AbstractNiFiRegistryCommand {
         try (final FileInputStream in = new FileInputStream(inputFile)) {
             final FlowSnapshotClient snapshotClient = 
client.getFlowSnapshotClient();
 
-            final VersionedFlowSnapshot deserializedSnapshot = 
MAPPER.readValue(in, VersionedFlowSnapshot.class);
+            final ObjectMapper objectMapper = JacksonUtils.getObjectMapper();
+            final VersionedFlowSnapshot deserializedSnapshot = 
objectMapper.readValue(in, VersionedFlowSnapshot.class);
             if (deserializedSnapshot == null) {
                 throw new IOException("Unable to deserialize flow version from 
" + inputFile);
             }
@@ -95,21 +101,4 @@ public class ImportFlowVersion extends 
AbstractNiFiRegistryCommand {
         }
     }
 
-    /*
-     * NOTE: This will bring back every item in the registry. We should create 
an end-point on the registry side
-     * to retrieve a flow by id and remove this later.
-     */
-    private String getBucketId(final NiFiRegistryClient client, final String 
flowId) throws IOException, NiFiRegistryException {
-        final List<BucketItem> items = client.getItemsClient().getAll();
-
-        final Optional<BucketItem> matchingItem = items.stream()
-                .filter(i ->  i.getIdentifier().equals(flowId))
-                .findFirst();
-
-        if (!matchingItem.isPresent()) {
-            throw new NiFiRegistryException("Versioned flow does not exist 
with id " + flowId);
-        }
-
-        return matchingItem.get().getBucketIdentifier();
-    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlowVersions.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlowVersions.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlowVersions.java
index bce08cb..7968d9c 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlowVersions.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlowVersions.java
@@ -22,6 +22,7 @@ import org.apache.nifi.registry.client.NiFiRegistryClient;
 import org.apache.nifi.registry.client.NiFiRegistryException;
 import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata;
 import org.apache.nifi.toolkit.cli.api.Context;
+import org.apache.nifi.toolkit.cli.api.ResultWriter;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import 
org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
 
@@ -39,19 +40,25 @@ public class ListFlowVersions extends 
AbstractNiFiRegistryCommand {
     }
 
     @Override
+    public String getDescription() {
+        return "Lists all of the flows for the given bucket.";
+    }
+
+    @Override
     public void doInitialize(final Context context) {
-        addOption(CommandOption.BUCKET_ID.createOption());
         addOption(CommandOption.FLOW_ID.createOption());
     }
 
     @Override
     protected void doExecute(final NiFiRegistryClient client, final Properties 
properties)
             throws ParseException, IOException, NiFiRegistryException {
-        final String bucket = getRequiredArg(properties, 
CommandOption.BUCKET_ID);
         final String flow = getRequiredArg(properties, CommandOption.FLOW_ID);
+        final String bucket = getBucketId(client, flow);
 
         final FlowSnapshotClient snapshotClient = 
client.getFlowSnapshotClient();
         final List<VersionedFlowSnapshotMetadata> snapshotMetadata = 
snapshotClient.getSnapshotMetadata(bucket, flow);
-        writeResult(properties, snapshotMetadata);
+
+        final ResultWriter resultWriter = getResultWriter(properties);
+        resultWriter.writeSnapshotMetadata(snapshotMetadata, 
getContext().getOutput());
     }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlows.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlows.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlows.java
index 99813ce..c8156cd 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlows.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/flow/ListFlows.java
@@ -22,6 +22,7 @@ import org.apache.nifi.registry.client.NiFiRegistryClient;
 import org.apache.nifi.registry.client.NiFiRegistryException;
 import org.apache.nifi.registry.flow.VersionedFlow;
 import org.apache.nifi.toolkit.cli.api.Context;
+import org.apache.nifi.toolkit.cli.api.ResultWriter;
 import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
 import 
org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
 
@@ -39,6 +40,11 @@ public class ListFlows extends AbstractNiFiRegistryCommand {
     }
 
     @Override
+    public String getDescription() {
+        return "Lists all of the flows in the given bucket.";
+    }
+
+    @Override
     public void doInitialize(final Context context) {
         addOption(CommandOption.BUCKET_ID.createOption());
     }
@@ -50,6 +56,9 @@ public class ListFlows extends AbstractNiFiRegistryCommand {
 
         final FlowClient flowClient = client.getFlowClient();
         final List<VersionedFlow> flows = flowClient.getByBucket(bucketId);
-        writeResult(properties, flows);
+
+        final ResultWriter resultWriter = getResultWriter(properties);
+        resultWriter.writeFlows(flows, getContext().getOutput());
     }
+
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/user/CurrentUser.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/user/CurrentUser.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/user/CurrentUser.java
index ad42d9e..0c1ef23 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/user/CurrentUser.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/user/CurrentUser.java
@@ -20,6 +20,7 @@ import org.apache.commons.cli.ParseException;
 import org.apache.nifi.registry.client.NiFiRegistryClient;
 import org.apache.nifi.registry.client.NiFiRegistryException;
 import org.apache.nifi.registry.client.UserClient;
+import org.apache.nifi.toolkit.cli.api.ResultWriter;
 import 
org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
 
 import java.io.IOException;
@@ -35,9 +36,16 @@ public class CurrentUser extends AbstractNiFiRegistryCommand 
{
     }
 
     @Override
+    public String getDescription() {
+        return "Returns information about the user accessing NiFi Registry. " +
+                "This provides a way to test if the CLI is accessing NiFi 
Registry as the expected user.";
+    }
+
+    @Override
     protected void doExecute(final NiFiRegistryClient client, final Properties 
properties)
             throws IOException, NiFiRegistryException, ParseException {
         final UserClient userClient = client.getUserClient();
-        writeResult(properties, userClient.getAccessStatus());
+        final ResultWriter resultWriter = getResultWriter(properties);
+        resultWriter.writeCurrentUser(userClient.getAccessStatus(), 
getContext().getOutput());
     }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/ClearSession.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/ClearSession.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/ClearSession.java
index 6fb0554..89fc592 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/ClearSession.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/ClearSession.java
@@ -28,6 +28,11 @@ public class ClearSession extends AbstractCommand {
     }
 
     @Override
+    public String getDescription() {
+        return "Clears all values in the session.";
+    }
+
+    @Override
     public void execute(final CommandLine cli) throws CommandException {
         try {
             getContext().getSession().clear();

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/GetVariable.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/GetVariable.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/GetVariable.java
index b663962..c7b2311 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/GetVariable.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/GetVariable.java
@@ -33,6 +33,11 @@ public class GetVariable extends AbstractCommand {
     }
 
     @Override
+    public String getDescription() {
+        return "Returns the value of the given variable in the session.";
+    }
+
+    @Override
     public void execute(final CommandLine commandLine) throws CommandException 
{
         final String[] args = commandLine.getArgs();
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/RemoveVariable.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/RemoveVariable.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/RemoveVariable.java
index 77d480a..ae37eea 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/RemoveVariable.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/RemoveVariable.java
@@ -32,6 +32,11 @@ public class RemoveVariable extends AbstractCommand {
     }
 
     @Override
+    public String getDescription() {
+        return "Removes the given variable from the session.";
+    }
+
+    @Override
     public void execute(final CommandLine commandLine) throws CommandException 
{
         final String[] args = commandLine.getArgs();
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/SetVariable.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/SetVariable.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/SetVariable.java
index 6302d83..f98ee05 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/SetVariable.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/SetVariable.java
@@ -34,6 +34,12 @@ public class SetVariable extends AbstractCommand {
     }
 
     @Override
+    public String getDescription() {
+        return "Sets the given variable in the session. " +
+                "Use the 'keys' command to show the variable names that are 
supported.";
+    }
+
+    @Override
     public void execute(final CommandLine commandLine) throws CommandException 
{
         final String[] args = commandLine.getArgs();
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/ShowKeys.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/ShowKeys.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/ShowKeys.java
index d64ffce..8825e83 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/ShowKeys.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/ShowKeys.java
@@ -31,6 +31,11 @@ public class ShowKeys extends AbstractCommand {
     }
 
     @Override
+    public String getDescription() {
+        return "Returns the available variable names that can be set in the 
session.";
+    }
+
+    @Override
     public void execute(CommandLine cli) throws CommandException {
         println();
         for (final SessionVariables variable : SessionVariables.values()) {

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/ShowSession.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/ShowSession.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/ShowSession.java
index 1c12ffb..49c5060 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/ShowSession.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/session/ShowSession.java
@@ -34,6 +34,11 @@ public class ShowSession extends AbstractCommand {
     }
 
     @Override
+    public String getDescription() {
+        return "Returns all of the variables and values in the session.";
+    }
+
+    @Override
     public void execute(final CommandLine cli) throws CommandException {
         try {
             final Session session = getContext().getSession();

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/context/StandardContext.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/context/StandardContext.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/context/StandardContext.java
index e2b1364..ef4d6ae 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/context/StandardContext.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/context/StandardContext.java
@@ -20,10 +20,15 @@ import org.apache.commons.lang3.Validate;
 import org.apache.nifi.registry.client.NiFiRegistryClient;
 import org.apache.nifi.toolkit.cli.api.ClientFactory;
 import org.apache.nifi.toolkit.cli.api.Context;
+import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.api.ResultWriter;
 import org.apache.nifi.toolkit.cli.api.Session;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 
 import java.io.PrintStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Context for the CLI which will be passed to each command.
@@ -35,6 +40,7 @@ public class StandardContext implements Context {
     private final Session session;
     private final PrintStream output;
     private final boolean isInteractive;
+    private final Map<ResultType,ResultWriter> resultWriters;
 
     private StandardContext(final Builder builder) {
         this.niFiClientFactory = builder.niFiClientFactory;
@@ -42,11 +48,21 @@ public class StandardContext implements Context {
         this.session = builder.session;
         this.output = builder.output;
         this.isInteractive = builder.isInteractive;
+        this.resultWriters = Collections.unmodifiableMap(
+                builder.resultWriters == null ? Collections.emptyMap() : new 
HashMap<>(builder.resultWriters));
 
         Validate.notNull(this.niFiClientFactory);
         Validate.notNull(this.niFiRegistryClientFactory);
         Validate.notNull(this.session);
         Validate.notNull(this.output);
+        Validate.notNull(this.resultWriters);
+
+        // ensure every ResultType has a provided writer
+        for (final ResultType resultType : ResultType.values()) {
+            if (!resultWriters.containsKey(resultType)) {
+                throw new IllegalStateException("ResultWriter not found for " 
+ resultType.name());
+            }
+        }
     }
 
     @Override
@@ -74,12 +90,26 @@ public class StandardContext implements Context {
         return isInteractive;
     }
 
+    @Override
+    public ResultWriter getResultWriter(final ResultType resultType) {
+        if (resultType == null) {
+            if (isInteractive()) {
+                return resultWriters.get(ResultType.SIMPLE);
+            } else {
+                return resultWriters.get(ResultType.JSON);
+            }
+        } else {
+            return resultWriters.get(resultType);
+        }
+    }
+
     public static class Builder {
         private ClientFactory<NiFiClient> niFiClientFactory;
         private ClientFactory<NiFiRegistryClient> niFiRegistryClientFactory;
         private Session session;
         private PrintStream output;
         private boolean isInteractive;
+        private Map<ResultType,ResultWriter> resultWriters = new HashMap<>();
 
         public Builder nifiClientFactory(final ClientFactory<NiFiClient> 
niFiClientFactory) {
             this.niFiClientFactory = niFiClientFactory;
@@ -106,6 +136,11 @@ public class StandardContext implements Context {
             return this;
         }
 
+        public Builder resultWriter(final ResultType resultType, final 
ResultWriter writer) {
+            resultWriters.put(resultType, writer);
+            return this;
+        }
+
         public StandardContext build() {
             return new StandardContext(this);
         }

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/JsonResultWriter.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/JsonResultWriter.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/JsonResultWriter.java
new file mode 100644
index 0000000..04097fc
--- /dev/null
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/JsonResultWriter.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.nifi.toolkit.cli.impl.result;
+
+import org.apache.nifi.registry.authorization.CurrentUser;
+import org.apache.nifi.registry.bucket.Bucket;
+import org.apache.nifi.registry.flow.VersionedFlow;
+import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata;
+import org.apache.nifi.toolkit.cli.api.ResultWriter;
+import org.apache.nifi.toolkit.cli.impl.util.JacksonUtils;
+import org.apache.nifi.web.api.entity.CurrentUserEntity;
+import org.apache.nifi.web.api.entity.ProcessGroupEntity;
+import org.apache.nifi.web.api.entity.RegistryClientsEntity;
+import org.apache.nifi.web.api.entity.VariableRegistryEntity;
+import org.apache.nifi.web.api.entity.VersionControlInformationEntity;
+import org.apache.nifi.web.api.entity.VersionedFlowSnapshotMetadataSetEntity;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.List;
+
+/**
+ * ResultWriter implementation that uses Jackson to serialize to JSON.
+ */
+public class JsonResultWriter implements ResultWriter {
+
+    @Override
+    public void writeBuckets(List<Bucket> buckets, PrintStream output) throws 
IOException {
+        write(buckets, output);
+    }
+
+    @Override
+    public void writeBucket(Bucket bucket, PrintStream output) throws 
IOException {
+        write(bucket, output);
+    }
+
+    @Override
+    public void writeFlows(List<VersionedFlow> versionedFlows, PrintStream 
output) throws IOException {
+        write(versionedFlows, output);
+    }
+
+    @Override
+    public void writeFlow(VersionedFlow versionedFlow, PrintStream output) 
throws IOException {
+        write(versionedFlow, output);
+    }
+
+    @Override
+    public void writeSnapshotMetadata(List<VersionedFlowSnapshotMetadata> 
versions, PrintStream output) throws IOException {
+        write(versions, output);
+    }
+
+    @Override
+    public void writeSnapshotMetadata(VersionedFlowSnapshotMetadata version, 
PrintStream output) throws IOException {
+        write(version, output);
+    }
+
+    @Override
+    public void writeRegistryClients(RegistryClientsEntity clientsEntity, 
PrintStream output) throws IOException {
+        write(clientsEntity, output);
+    }
+
+    @Override
+    public void writeVariables(VariableRegistryEntity variableRegistryEntity, 
PrintStream output) throws IOException {
+        write(variableRegistryEntity, output);
+    }
+
+    @Override
+    public void writeSnapshotMetadata(VersionedFlowSnapshotMetadataSetEntity 
versionedFlowSnapshotMetadataSetEntity, PrintStream output) throws IOException {
+        write(versionedFlowSnapshotMetadataSetEntity, output);
+    }
+
+    @Override
+    public void writeVersionControlInfo(VersionControlInformationEntity 
versionControlInformationEntity, PrintStream output) throws IOException {
+        write(versionControlInformationEntity, output);
+    }
+
+    @Override
+    public void writeProcessGroups(List<ProcessGroupEntity> 
processGroupEntities, PrintStream output) throws IOException {
+        write(processGroupEntities, output);
+    }
+
+    @Override
+    public void writeCurrentUser(CurrentUserEntity currentUserEntity, 
PrintStream output) throws IOException {
+        write(currentUserEntity, output);
+    }
+
+    @Override
+    public void writeCurrentUser(CurrentUser currentUser, PrintStream output) 
throws IOException {
+        write(currentUser, output);
+    }
+
+    private void write(final Object result, final OutputStream output) throws 
IOException {
+        JacksonUtils.write(result, output);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/SimpleResultWriter.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/SimpleResultWriter.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/SimpleResultWriter.java
new file mode 100644
index 0000000..5835636
--- /dev/null
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/SimpleResultWriter.java
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.nifi.toolkit.cli.impl.result;
+
+import org.apache.nifi.registry.authorization.CurrentUser;
+import org.apache.nifi.registry.bucket.Bucket;
+import org.apache.nifi.registry.flow.VersionedFlow;
+import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata;
+import org.apache.nifi.toolkit.cli.api.ResultWriter;
+import org.apache.nifi.web.api.dto.ProcessGroupDTO;
+import org.apache.nifi.web.api.dto.RegistryDTO;
+import org.apache.nifi.web.api.dto.VariableDTO;
+import org.apache.nifi.web.api.dto.VariableRegistryDTO;
+import org.apache.nifi.web.api.dto.VersionControlInformationDTO;
+import org.apache.nifi.web.api.entity.CurrentUserEntity;
+import org.apache.nifi.web.api.entity.ProcessGroupEntity;
+import org.apache.nifi.web.api.entity.RegistryClientEntity;
+import org.apache.nifi.web.api.entity.RegistryClientsEntity;
+import org.apache.nifi.web.api.entity.VariableRegistryEntity;
+import org.apache.nifi.web.api.entity.VersionControlInformationEntity;
+import org.apache.nifi.web.api.entity.VersionedFlowSnapshotMetadataEntity;
+import org.apache.nifi.web.api.entity.VersionedFlowSnapshotMetadataSetEntity;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.text.SimpleDateFormat;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * ResultWriter implementation that writes simple human-readable output, 
primarily for use in the interactive CLI.
+ */
+public class SimpleResultWriter implements ResultWriter {
+
+    public static String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
+
+    @Override
+    public void writeBuckets(List<Bucket> buckets, PrintStream output) {
+        if (buckets == null || buckets.isEmpty()) {
+            return;
+        }
+
+        Collections.sort(buckets, Comparator.comparing(Bucket::getName));
+
+        output.println();
+        buckets.stream().forEach(b -> writeBucket(b, output));
+        output.println();
+    }
+
+    @Override
+    public void writeBucket(Bucket bucket, PrintStream output) {
+        if (bucket == null) {
+            return;
+        }
+        output.println(bucket.getName() + " - " + bucket.getIdentifier());
+    }
+
+    @Override
+    public void writeFlows(List<VersionedFlow> versionedFlows, PrintStream 
output) {
+        if (versionedFlows == null || versionedFlows.isEmpty()) {
+            return;
+        }
+
+        Collections.sort(versionedFlows, 
Comparator.comparing(VersionedFlow::getName));
+
+        output.println();
+        versionedFlows.stream().forEach(vf -> writeFlow(vf, output));
+        output.println();
+    }
+
+    @Override
+    public void writeFlow(VersionedFlow versionedFlow, PrintStream output) {
+        if (versionedFlow == null) {
+            return;
+        }
+        output.println(versionedFlow.getName() + " - " + 
versionedFlow.getIdentifier());
+    }
+
+    @Override
+    public void writeSnapshotMetadata(List<VersionedFlowSnapshotMetadata> 
versions, PrintStream output) {
+        if (versions == null || versions.isEmpty()) {
+            return;
+        }
+
+        Collections.sort(versions, 
Comparator.comparing(VersionedFlowSnapshotMetadata::getVersion));
+
+        output.println();
+        versions.stream().forEach(vfs -> writeSnapshotMetadata(vfs, output));
+        output.println();
+    }
+
+    @Override
+    public void writeSnapshotMetadata(VersionedFlowSnapshotMetadata version, 
PrintStream output) {
+        if (version == null) {
+            return;
+        }
+
+        final Date date = new Date(version.getTimestamp());
+        final SimpleDateFormat dateFormatter = new 
SimpleDateFormat(DATE_FORMAT);
+        output.println(version.getVersion() + " - " + 
dateFormatter.format(date) + " - " + version.getAuthor());
+    }
+
+    @Override
+    public void writeRegistryClients(RegistryClientsEntity clientsEntity, 
PrintStream output) {
+        if (clientsEntity == null) {
+            return;
+        }
+
+        final Set<RegistryClientEntity> clients = 
clientsEntity.getRegistries();
+        if (clients == null || clients.isEmpty()) {
+            return;
+        }
+
+        final List<RegistryDTO> registies = clients.stream().map(c -> 
c.getComponent()).collect(Collectors.toList());
+        Collections.sort(registies, 
Comparator.comparing(RegistryDTO::getName));
+        registies.stream().forEach(r -> output.println(r.getName() + " - " + 
r.getId() + " - " + r.getUri()));
+    }
+
+    @Override
+    public void writeVariables(VariableRegistryEntity variableRegistryEntity, 
PrintStream output) {
+        if (variableRegistryEntity == null) {
+            return;
+        }
+
+        final VariableRegistryDTO variableRegistryDTO = 
variableRegistryEntity.getVariableRegistry();
+        if (variableRegistryDTO == null || variableRegistryDTO.getVariables() 
== null) {
+            return;
+        }
+
+        final List<VariableDTO> variables = 
variableRegistryDTO.getVariables().stream().map(v -> 
v.getVariable()).collect(Collectors.toList());
+        Collections.sort(variables, 
Comparator.comparing(VariableDTO::getName));
+        variables.stream().forEach(v -> output.println(v.getName() + " - " + 
v.getValue()));
+    }
+
+    @Override
+    public void writeSnapshotMetadata(VersionedFlowSnapshotMetadataSetEntity 
versionedFlowSnapshotMetadataSetEntity, PrintStream output) {
+        if (versionedFlowSnapshotMetadataSetEntity == null) {
+            return;
+        }
+
+        final Set<VersionedFlowSnapshotMetadataEntity> entities = 
versionedFlowSnapshotMetadataSetEntity.getVersionedFlowSnapshotMetadataSet();
+        if (entities == null || entities.isEmpty()) {
+            return;
+        }
+
+        final List<VersionedFlowSnapshotMetadata> snapshots = 
entities.stream().map(v -> 
v.getVersionedFlowSnapshotMetadata()).collect(Collectors.toList());
+        writeSnapshotMetadata(snapshots, output);
+    }
+
+    @Override
+    public void writeVersionControlInfo(VersionControlInformationEntity 
versionControlInformationEntity, PrintStream output) {
+        if (versionControlInformationEntity == null) {
+            return;
+        }
+
+        final VersionControlInformationDTO dto = 
versionControlInformationEntity.getVersionControlInformation();
+        if (dto == null) {
+            return;
+        }
+
+        output.println(dto.getRegistryName() + " - " + dto.getBucketName() + " 
- " + dto.getFlowName() + " - " + dto.getVersion());
+    }
+
+    @Override
+    public void writeProcessGroups(List<ProcessGroupEntity> 
processGroupEntities, PrintStream output) throws IOException {
+        if (processGroupEntities == null) {
+            return;
+        }
+
+        final List<ProcessGroupDTO> dtos = processGroupEntities.stream().map(e 
-> e.getComponent()).collect(Collectors.toList());
+        Collections.sort(dtos, Comparator.comparing(ProcessGroupDTO::getName));
+
+        dtos.stream().forEach(dto -> output.println(dto.getName() + " - " + 
dto.getId()));
+    }
+
+    @Override
+    public void writeCurrentUser(CurrentUserEntity currentUserEntity, 
PrintStream output) {
+        if (currentUserEntity == null) {
+            return;
+        }
+
+        output.println(currentUserEntity.getIdentity());
+    }
+
+    @Override
+    public void writeCurrentUser(CurrentUser currentUser, PrintStream output) {
+        if (currentUser == null) {
+            return;
+        }
+
+        output.println(currentUser.getIdentity());
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/util/JacksonUtils.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/util/JacksonUtils.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/util/JacksonUtils.java
new file mode 100644
index 0000000..31bf755
--- /dev/null
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/util/JacksonUtils.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.nifi.toolkit.cli.impl.util;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectWriter;
+import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class JacksonUtils {
+
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+    static {
+        MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+        
MAPPER.setDefaultPropertyInclusion(JsonInclude.Value.construct(JsonInclude.Include.NON_NULL,
 JsonInclude.Include.NON_NULL));
+        MAPPER.setAnnotationIntrospector(new 
JaxbAnnotationIntrospector(MAPPER.getTypeFactory()));
+        MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, 
false);
+    }
+
+    private static final ObjectWriter OBJECT_WRITER = 
MAPPER.writerWithDefaultPrettyPrinter();
+
+    public static ObjectMapper getObjectMapper() {
+        return MAPPER;
+    }
+
+    public static ObjectWriter getObjectWriter() {
+        return OBJECT_WRITER;
+    }
+
+    public static void write(final Object result, final OutputStream output) 
throws IOException {
+        OBJECT_WRITER.writeValue(new OutputStream() {
+            @Override
+            public void write(byte[] b) throws IOException {
+                output.write(b);
+            }
+
+            @Override
+            public void write(byte[] b, int off, int len) throws IOException {
+                output.write(b, off, len);
+            }
+
+            @Override
+            public void write(int b) throws IOException {
+                output.write(b);
+            }
+
+            @Override
+            public void close() throws IOException {
+                // DON'T close the output stream here
+                output.flush();
+            }
+        }, result);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/NiFiCLIMainRunner.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/NiFiCLIMainRunner.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/NiFiCLIMainRunner.java
index fb7d94f..9a78588 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/NiFiCLIMainRunner.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/NiFiCLIMainRunner.java
@@ -19,16 +19,19 @@ package org.apache.nifi.toolkit.cli;
 import org.apache.nifi.registry.client.NiFiRegistryClient;
 import org.apache.nifi.toolkit.cli.api.ClientFactory;
 import org.apache.nifi.toolkit.cli.api.Command;
+import org.apache.nifi.toolkit.cli.api.CommandGroup;
 import org.apache.nifi.toolkit.cli.api.Context;
+import org.apache.nifi.toolkit.cli.api.ResultType;
 import org.apache.nifi.toolkit.cli.api.Session;
-import org.apache.nifi.toolkit.cli.impl.context.StandardContext;
-import org.apache.nifi.toolkit.cli.impl.session.InMemorySession;
 import org.apache.nifi.toolkit.cli.impl.client.NiFiClientFactory;
 import org.apache.nifi.toolkit.cli.impl.client.NiFiRegistryClientFactory;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.command.CommandFactory;
-import org.apache.nifi.toolkit.cli.api.CommandGroup;
 import org.apache.nifi.toolkit.cli.impl.command.CommandProcessor;
+import org.apache.nifi.toolkit.cli.impl.context.StandardContext;
+import org.apache.nifi.toolkit.cli.impl.result.JsonResultWriter;
+import org.apache.nifi.toolkit.cli.impl.result.SimpleResultWriter;
+import org.apache.nifi.toolkit.cli.impl.session.InMemorySession;
 
 import java.util.Map;
 
@@ -47,6 +50,8 @@ public class NiFiCLIMainRunner {
                 .session(session)
                 .nifiClientFactory(niFiClientFactory)
                 .nifiRegistryClientFactory(nifiRegClientFactory)
+                .resultWriter(ResultType.SIMPLE, new SimpleResultWriter())
+                .resultWriter(ResultType.JSON, new JsonResultWriter())
                 .build();
 
         final Map<String,Command> commands = 
CommandFactory.createTopLevelCommands(context);

http://git-wip-us.apache.org/repos/asf/nifi/blob/c1c80800/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/TestCLICompleter.java
----------------------------------------------------------------------
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/TestCLICompleter.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/TestCLICompleter.java
index e4763f0..10c2db0 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/TestCLICompleter.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/TestCLICompleter.java
@@ -19,17 +19,20 @@ package org.apache.nifi.toolkit.cli;
 import org.apache.nifi.registry.client.NiFiRegistryClient;
 import org.apache.nifi.toolkit.cli.api.ClientFactory;
 import org.apache.nifi.toolkit.cli.api.Command;
+import org.apache.nifi.toolkit.cli.api.CommandGroup;
 import org.apache.nifi.toolkit.cli.api.Context;
+import org.apache.nifi.toolkit.cli.api.ResultType;
 import org.apache.nifi.toolkit.cli.api.Session;
-import 
org.apache.nifi.toolkit.cli.impl.command.registry.NiFiRegistryCommandGroup;
-import org.apache.nifi.toolkit.cli.impl.context.StandardContext;
-import org.apache.nifi.toolkit.cli.impl.session.InMemorySession;
-import org.apache.nifi.toolkit.cli.impl.session.SessionVariables;
 import org.apache.nifi.toolkit.cli.impl.client.NiFiClientFactory;
 import org.apache.nifi.toolkit.cli.impl.client.NiFiRegistryClientFactory;
 import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
 import org.apache.nifi.toolkit.cli.impl.command.CommandFactory;
-import org.apache.nifi.toolkit.cli.api.CommandGroup;
+import 
org.apache.nifi.toolkit.cli.impl.command.registry.NiFiRegistryCommandGroup;
+import org.apache.nifi.toolkit.cli.impl.context.StandardContext;
+import org.apache.nifi.toolkit.cli.impl.result.JsonResultWriter;
+import org.apache.nifi.toolkit.cli.impl.result.SimpleResultWriter;
+import org.apache.nifi.toolkit.cli.impl.session.InMemorySession;
+import org.apache.nifi.toolkit.cli.impl.session.SessionVariables;
 import org.jline.reader.Candidate;
 import org.jline.reader.LineReader;
 import org.jline.reader.impl.DefaultParser;
@@ -62,6 +65,8 @@ public class TestCLICompleter {
                 .session(session)
                 .nifiClientFactory(niFiClientFactory)
                 .nifiRegistryClientFactory(nifiRegClientFactory)
+                .resultWriter(ResultType.SIMPLE, new SimpleResultWriter())
+                .resultWriter(ResultType.JSON, new JsonResultWriter())
                 .build();
 
         final Map<String,Command> commands = 
CommandFactory.createTopLevelCommands(context);

Reply via email to