nifi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pvill...@apache.org
Subject [14/20] nifi git commit: NIFI-4839 - Added abbreviation in simple output for name, description, and comments - Refactored so that commands produce a result which can then be written or used - Added support for back-referencing results, initially prototyp
Date Wed, 28 Feb 2018 16:25:08 GMT
http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/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
deleted file mode 100644
index 04097fc..0000000
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/JsonResultWriter.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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/b68eebd4/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ProcessGroupsResult.java
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ProcessGroupsResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ProcessGroupsResult.java
new file mode 100644
index 0000000..41cf62e
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/ProcessGroupsResult.java
@@ -0,0 +1,57 @@
+/*
+ * 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.commons.lang3.Validate;
+import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.web.api.dto.ProcessGroupDTO;
+import org.apache.nifi.web.api.entity.ProcessGroupEntity;
+
+import java.io.PrintStream;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Result for a list of ProcessGroupEntities.
+ */
+public class ProcessGroupsResult extends AbstractWritableResult<List<ProcessGroupEntity>> {
+
+    private final List<ProcessGroupEntity> processGroupEntities;
+
+    public ProcessGroupsResult(final ResultType resultType, final List<ProcessGroupEntity> processGroupEntities) {
+        super(resultType);
+        this.processGroupEntities = processGroupEntities;
+        Validate.notNull(this.processGroupEntities);
+    }
+
+    @Override
+    public List<ProcessGroupEntity> getResult() {
+        return processGroupEntities;
+    }
+
+    @Override
+    protected void writeSimpleResult(final PrintStream output) {
+        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()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/RegistryClientIDResult.java
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/RegistryClientIDResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/RegistryClientIDResult.java
new file mode 100644
index 0000000..e221318
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/RegistryClientIDResult.java
@@ -0,0 +1,44 @@
+/*
+ * 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.commons.lang3.Validate;
+import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.web.api.dto.RegistryDTO;
+
+import java.io.PrintStream;
+
+public class RegistryClientIDResult extends AbstractWritableResult<RegistryDTO> {
+
+    private final RegistryDTO registryDTO;
+
+    public RegistryClientIDResult(final ResultType resultType, final RegistryDTO registryDTO) {
+        super(resultType);
+        this.registryDTO = registryDTO;
+        Validate.notNull(this.registryDTO);
+    }
+
+    @Override
+    protected void writeSimpleResult(final PrintStream output) {
+        output.println(registryDTO.getId());
+    }
+
+    @Override
+    public RegistryDTO getResult() {
+        return registryDTO;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/RegistryClientsResult.java
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/RegistryClientsResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/RegistryClientsResult.java
new file mode 100644
index 0000000..7ca9122
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/RegistryClientsResult.java
@@ -0,0 +1,79 @@
+/*
+ * 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.commons.lang3.Validate;
+import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
+import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
+import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
+import org.apache.nifi.web.api.dto.RegistryDTO;
+import org.apache.nifi.web.api.entity.RegistryClientEntity;
+import org.apache.nifi.web.api.entity.RegistryClientsEntity;
+
+import java.io.PrintStream;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Result for a RegistryClientsEntity.
+ */
+public class RegistryClientsResult extends AbstractWritableResult<RegistryClientsEntity> {
+
+    final RegistryClientsEntity registryClients;
+
+    public RegistryClientsResult(final ResultType resultType, final RegistryClientsEntity registryClients) {
+        super(resultType);
+        this.registryClients = registryClients;
+        Validate.notNull(this.registryClients);
+    }
+
+    @Override
+    public RegistryClientsEntity getResult() {
+        return this.registryClients;
+    }
+
+    @Override
+    protected void writeSimpleResult(final PrintStream output) {
+        final Set<RegistryClientEntity> clients = registryClients.getRegistries();
+        if (clients == null || clients.isEmpty()) {
+            return;
+        }
+
+        final List<RegistryDTO> registries = clients.stream().map(RegistryClientEntity::getComponent)
+                .sorted(Comparator.comparing(RegistryDTO::getName))
+                .collect(Collectors.toList());
+
+        final Table table = new Table.Builder()
+                .column("#", 3, 3, false)
+                .column("Name", 20, 36, true)
+                .column("Id", 36, 36, false)
+                .column("Uri", 3, Integer.MAX_VALUE, false)
+                .build();
+
+        for (int i = 0; i < registries.size(); i++) {
+            RegistryDTO r = registries.get(i);
+            table.addRow("" + (i+1), r.getName(), r.getId(), r.getUri());
+        }
+
+        final TableWriter tableWriter = new DynamicTableWriter();
+        tableWriter.write(table, output);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/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
deleted file mode 100644
index ea4f551..0000000
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/SimpleResultWriter.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * 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.Optional;
-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 final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss (EEE)";
-
-    @Override
-    public void writeBuckets(List<Bucket> buckets, PrintStream output) {
-        if (buckets == null || buckets.isEmpty()) {
-            return;
-        }
-
-        buckets.sort(Comparator.comparing(Bucket::getName));
-
-        output.println();
-
-        final int nameLength = buckets.stream().mapToInt(b -> b.getName().length()).max().orElse(20);
-        final int idLength = buckets.stream().mapToInt(b -> b.getIdentifier().length()).max().orElse(36);
-        // description can be empty
-        int descLength = buckets.stream().map(b -> Optional.ofNullable(b.getDescription()))
-                                               .filter(b -> b.isPresent())
-                                               .mapToInt(b -> b.get().length())
-                                               .max()
-                                               .orElse(40);
-        descLength = descLength < 40 ? 40 : descLength;
-
-        String headerPattern = String.format("#     %%-%ds   %%-%ds   %%-%ds", nameLength, idLength, descLength);
-        final String header = String.format(headerPattern, "Name", "Id", "Description");
-        output.println(header);
-
-        // a little clunky way to dynamically create a nice header line, but at least no external dependency
-        final String headerLinePattern = String.format("---   %%-%ds   %%-%ds   %%-%ds",
-                                                       nameLength, idLength, descLength);
-        final String headerLine = String.format(headerLinePattern,
-                String.join("", Collections.nCopies(nameLength, "-")),
-                String.join("", Collections.nCopies(idLength, "-")),
-                String.join("", Collections.nCopies(descLength, "-")));
-        output.println(headerLine);
-
-        String rowPattern = String.format("%%-3d   %%-%ds   %%-%ds   %%-%ds", nameLength, idLength, descLength);
-
-        for (int i = 0; i < buckets.size(); ++i) {
-            Bucket bucket = buckets.get(i);
-            String s = String.format(rowPattern,
-                    i + 1,
-                    bucket.getName(),
-                    bucket.getIdentifier(),
-                    Optional.ofNullable(bucket.getDescription()).orElse("(empty)"));
-            output.println(s);
-
-        }
-
-        output.println();
-    }
-
-    @Override
-    public void writeBucket(Bucket bucket, PrintStream output) {
-        // this method is not used really, need context of List<Bucket>
-        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;
-        }
-
-        versionedFlows.sort(Comparator.comparing(VersionedFlow::getName));
-
-        output.println();
-
-        final int nameLength = versionedFlows.stream().mapToInt(f -> f.getName().length()).max().orElse(20);
-        final int idLength = versionedFlows.stream().mapToInt(f -> f.getIdentifier().length()).max().orElse(36);
-        // description can be empty
-        int descLength = versionedFlows.stream().map(b -> Optional.ofNullable(b.getDescription()))
-                .filter(b -> b.isPresent())
-                .mapToInt(b -> b.get().length())
-                .max()
-                .orElse(40);
-        descLength = descLength < 40 ? 40 : descLength;
-
-        String headerPattern = String.format("#     %%-%ds   %%-%ds   %%-%ds", nameLength, idLength, descLength);
-        final String header = String.format(headerPattern, "Name", "Id", "Description");
-        output.println(header);
-
-        // a little clunky way to dynamically create a nice header line, but at least no external dependency
-        final String headerLinePattern = String.format("---   %%-%ds   %%-%ds   %%-%ds",
-                nameLength, idLength, descLength);
-        final String headerLine = String.format(headerLinePattern,
-                String.join("", Collections.nCopies(nameLength, "-")),
-                String.join("", Collections.nCopies(idLength, "-")),
-                String.join("", Collections.nCopies(descLength, "-")));
-        output.println(headerLine);
-
-        String rowPattern = String.format("%%-3d   %%-%ds   %%-%ds   %%-%ds", nameLength, idLength, descLength);
-
-        for (int i = 0; i < versionedFlows.size(); ++i) {
-            VersionedFlow flow = versionedFlows.get(i);
-            String s = String.format(rowPattern,
-                    i + 1,
-                    flow.getName(),
-                    flow.getIdentifier(),
-                    Optional.ofNullable(flow.getDescription()).orElse("(empty)"));
-            output.println(s);
-
-        }
-
-        output.println();
-
-    }
-
-    @Override
-    // TODO drop as unused?
-    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;
-        }
-
-        versions.sort(Comparator.comparing(VersionedFlowSnapshotMetadata::getVersion));
-
-        output.println();
-
-        // The following section will construct a table output with dynamic column width, based on the actual data.
-        // We dynamically create a pattern with item width, as Java's formatter won't process nested declarations.
-
-        // date length, with locale specifics
-        final String datePattern = "%1$ta, %<tb %<td %<tY %<tR %<tZ";
-        final int dateLength = String.format(datePattern, new Date()).length();
-
-        // anticipating LDAP long entries
-        final int authorLength = versions.stream().mapToInt(v -> v.getAuthor().length()).max().orElse(20);
-
-        // truncate comments if too long
-        int commentsLength = versions.stream().mapToInt(v -> v.getComments().length()).max().orElse(60);
-        commentsLength = commentsLength < 40 ? 40 : commentsLength;
-
-        String headerPattern = String.format("Ver   %%-%ds   %%-%ds   %%-%ds", dateLength, authorLength, commentsLength);
-        final String header = String.format(headerPattern, "Date", "Author", "Message");
-        output.println(header);
-
-        // a little clunky way to dynamically create a nice header line, but at least no external dependency
-        final String headerLinePattern = String.format("---   %%-%ds   %%-%ds   %%-%ds", dateLength, authorLength, commentsLength);
-        final String headerLine = String.format(headerLinePattern,
-                String.join("", Collections.nCopies(dateLength, "-")),
-                String.join("", Collections.nCopies(authorLength, "-")),
-                String.join("", Collections.nCopies(commentsLength, "-")));
-        output.println(headerLine);
-
-        String rowPattern = String.format("%%3d   %%-%ds   %%-%ds   %%-%ds", dateLength, authorLength, commentsLength);
-        versions.forEach(vfs -> {
-            String row = String.format(rowPattern,
-                    vfs.getVersion(),
-                    String.format(datePattern, new Date(vfs.getTimestamp())),
-                    vfs.getAuthor(),
-                    Optional.ofNullable(vfs.getComments()).orElse("(empty)"));
-            output.println(row);
-        });
-        output.println();
-    }
-
-    @Override
-    // TODO drop as unused?
-    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;
-        }
-
-        output.println();
-
-        final List<RegistryDTO> registries = clients.stream().map(RegistryClientEntity::getComponent)
-                                                            .sorted(Comparator.comparing(RegistryDTO::getName))
-                                                            .collect(Collectors.toList());
-
-        final int nameLength = registries.stream().mapToInt(r -> r.getName().length()).max().orElse(20);
-        final int idLength = registries.stream().mapToInt(r -> r.getId().length()).max().orElse(36);
-        final int uriLength = registries.stream().mapToInt(r -> r.getUri().length()).max().orElse(36);
-
-        String headerPattern = String.format("#     %%-%ds   %%-%ds   %%-%ds", nameLength, idLength, uriLength);
-        final String header = String.format(headerPattern, "Name", "Id", "Uri");
-        output.println(header);
-
-        // a little clunky way to dynamically create a nice header line, but at least no external dependency
-        final String headerLinePattern = String.format("---   %%-%ds   %%-%ds   %%-%ds", nameLength, idLength, uriLength);
-        final String headerLine = String.format(headerLinePattern,
-                                                String.join("", Collections.nCopies(nameLength, "-")),
-                                                String.join("", Collections.nCopies(idLength, "-")),
-                                                String.join("", Collections.nCopies(uriLength, "-")));
-        output.println(headerLine);
-
-        String rowPattern = String.format("%%3d   %%-%ds   %%-%ds   %%-%ds", nameLength, idLength, uriLength);
-        for (int i = 0; i < registries.size(); i++) {
-            RegistryDTO r = registries.get(i);
-            String row = String.format(rowPattern,
-                                       i + 1,
-                                       r.getName(),
-                                       r.getId(),
-                                       r.getUri());
-            output.println(row);
-        }
-
-        output.println();
-    }
-
-    @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/b68eebd4/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/StringResult.java
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/StringResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/StringResult.java
new file mode 100644
index 0000000..1d82f65
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/StringResult.java
@@ -0,0 +1,45 @@
+/*
+ * 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.commons.lang3.Validate;
+import org.apache.nifi.toolkit.cli.api.WritableResult;
+
+import java.io.PrintStream;
+
+/**
+ * Result for a single string value.
+ */
+public class StringResult implements WritableResult<String> {
+
+    private final String value;
+
+    public StringResult(final String value) {
+        this.value = value;
+        Validate.notNull(this.value);
+    }
+
+    @Override
+    public String getResult() {
+        return value;
+    }
+
+    @Override
+    public void write(final PrintStream output) {
+        output.println(value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VariableRegistryResult.java
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VariableRegistryResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VariableRegistryResult.java
new file mode 100644
index 0000000..0791fa5
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VariableRegistryResult.java
@@ -0,0 +1,60 @@
+/*
+ * 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.commons.lang3.Validate;
+import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.web.api.dto.VariableDTO;
+import org.apache.nifi.web.api.dto.VariableRegistryDTO;
+import org.apache.nifi.web.api.entity.VariableRegistryEntity;
+
+import java.io.PrintStream;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Result for a VariableRegistryEntity.
+ */
+public class VariableRegistryResult extends AbstractWritableResult<VariableRegistryEntity> {
+
+    final VariableRegistryEntity variableRegistryEntity;
+
+    public VariableRegistryResult(final ResultType resultType, final VariableRegistryEntity variableRegistryEntity) {
+        super(resultType);
+        this.variableRegistryEntity = variableRegistryEntity;
+        Validate.notNull(this.variableRegistryEntity);
+    }
+
+    @Override
+    public VariableRegistryEntity getResult() {
+        return variableRegistryEntity;
+    }
+
+    @Override
+    protected void writeSimpleResult(final PrintStream output) {
+        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()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionControlInfoResult.java
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionControlInfoResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionControlInfoResult.java
new file mode 100644
index 0000000..ad0d17d
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionControlInfoResult.java
@@ -0,0 +1,55 @@
+/*
+ * 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.commons.lang3.Validate;
+import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.web.api.dto.VersionControlInformationDTO;
+import org.apache.nifi.web.api.entity.VersionControlInformationEntity;
+
+import java.io.PrintStream;
+
+/**
+ * Result for VersionControlInformationEntity.
+ */
+public class VersionControlInfoResult extends AbstractWritableResult<VersionControlInformationEntity> {
+
+    private final VersionControlInformationEntity versionControlInformationEntity;
+
+    public VersionControlInfoResult(final ResultType resultType,
+                                    final VersionControlInformationEntity versionControlInformationEntity) {
+        super(resultType);
+        this.versionControlInformationEntity = versionControlInformationEntity;
+        Validate.notNull(this.versionControlInformationEntity);
+    }
+
+    @Override
+    public VersionControlInformationEntity getResult() {
+        return versionControlInformationEntity;
+    }
+
+    @Override
+    protected void writeSimpleResult(final PrintStream output) {
+        final VersionControlInformationDTO dto = versionControlInformationEntity.getVersionControlInformation();
+        if (dto == null) {
+            return;
+        }
+
+        output.println(dto.getRegistryName() + " - " + dto.getBucketName() + " - " + dto.getFlowName() + " - " + dto.getVersion());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotMetadataResult.java
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotMetadataResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotMetadataResult.java
new file mode 100644
index 0000000..554097a
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotMetadataResult.java
@@ -0,0 +1,79 @@
+/*
+ * 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.commons.lang3.Validate;
+import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata;
+import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
+import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
+import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
+
+import java.io.PrintStream;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Result for a list of VersionedFlowSnapshotMetadata.
+ */
+public class VersionedFlowSnapshotMetadataResult extends AbstractWritableResult<List<VersionedFlowSnapshotMetadata>> {
+
+    private final List<VersionedFlowSnapshotMetadata> versions;
+
+    public VersionedFlowSnapshotMetadataResult(final ResultType resultType, final List<VersionedFlowSnapshotMetadata> versions) {
+        super(resultType);
+        this.versions = versions;
+        Validate.notNull(this.versions);
+        this.versions.sort(Comparator.comparing(VersionedFlowSnapshotMetadata::getVersion));
+    }
+
+    @Override
+    public List<VersionedFlowSnapshotMetadata> getResult() {
+        return this.versions;
+    }
+
+    @Override
+    protected void writeSimpleResult(final PrintStream output) {
+        if (versions == null || versions.isEmpty()) {
+            return;
+        }
+
+        // date length, with locale specifics
+        final String datePattern = "%1$ta, %<tb %<td %<tY %<tR %<tZ";
+        final int dateLength = String.format(datePattern, new Date()).length();
+
+        final Table table = new Table.Builder()
+                .column("Ver", 3, 3, false)
+                .column("Date", dateLength, dateLength, false)
+                .column("Author", 20, 200, true)
+                .column("Message", 8, 40, true)
+                .build();
+
+        versions.forEach(vfs -> {
+            table.addRow(
+                    String.valueOf(vfs.getVersion()),
+                    String.format(datePattern, new Date(vfs.getTimestamp())),
+                    vfs.getAuthor(),
+                    vfs.getComments()
+            );
+        });
+
+        final TableWriter tableWriter = new DynamicTableWriter();
+        tableWriter.write(table, output);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotMetadataSetResult.java
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotMetadataSetResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotMetadataSetResult.java
new file mode 100644
index 0000000..d8c1abc
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotMetadataSetResult.java
@@ -0,0 +1,64 @@
+/*
+ * 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.commons.lang3.Validate;
+import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata;
+import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.api.WritableResult;
+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.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Result for VersionedFlowSnapshotMetadataSetEntity.
+ */
+public class VersionedFlowSnapshotMetadataSetResult extends AbstractWritableResult<VersionedFlowSnapshotMetadataSetEntity> {
+
+    private final VersionedFlowSnapshotMetadataSetEntity versionedFlowSnapshotMetadataSetEntity;
+
+    public VersionedFlowSnapshotMetadataSetResult(final ResultType resultType,
+                                                  final VersionedFlowSnapshotMetadataSetEntity versionedFlowSnapshotMetadataSetEntity) {
+        super(resultType);
+        this.versionedFlowSnapshotMetadataSetEntity = versionedFlowSnapshotMetadataSetEntity;
+        Validate.notNull(this.versionedFlowSnapshotMetadataSetEntity);
+    }
+
+    @Override
+    public VersionedFlowSnapshotMetadataSetEntity getResult() {
+        return versionedFlowSnapshotMetadataSetEntity;
+    }
+
+    @Override
+    protected void writeSimpleResult(final PrintStream output) throws IOException {
+        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());
+
+        final WritableResult<List<VersionedFlowSnapshotMetadata>> result = new VersionedFlowSnapshotMetadataResult(resultType, snapshots);
+        result.write(output);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotResult.java
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotResult.java
new file mode 100644
index 0000000..f8c7453
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowSnapshotResult.java
@@ -0,0 +1,65 @@
+/*
+ * 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.commons.lang3.Validate;
+import org.apache.nifi.registry.flow.VersionedFlowSnapshot;
+import org.apache.nifi.toolkit.cli.api.WritableResult;
+import org.apache.nifi.toolkit.cli.impl.util.JacksonUtils;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+/**
+ * Result for a VersionedFlowSnapshot.
+ *
+ * If this result was created with a non-null exportFileName, then the write method will ignore
+ * the passed in PrintStream, and will write the serialized snapshot to the give file.
+ *
+ * If this result was created with a null exportFileName, then the write method will write the
+ * serialized snapshot to the given PrintStream.
+ */
+public class VersionedFlowSnapshotResult implements WritableResult<VersionedFlowSnapshot> {
+
+    private final VersionedFlowSnapshot versionedFlowSnapshot;
+
+    private final String exportFileName;
+
+    public VersionedFlowSnapshotResult(final VersionedFlowSnapshot versionedFlowSnapshot, final String exportFileName) {
+        this.versionedFlowSnapshot = versionedFlowSnapshot;
+        this.exportFileName = exportFileName;
+        Validate.notNull(this.versionedFlowSnapshot);
+    }
+
+    @Override
+    public VersionedFlowSnapshot getResult() {
+        return versionedFlowSnapshot;
+    }
+
+    @Override
+    public void write(final PrintStream output) throws IOException {
+        if (exportFileName != null) {
+            try (final OutputStream resultOut = new FileOutputStream(exportFileName)) {
+                JacksonUtils.write(versionedFlowSnapshot, resultOut);
+            }
+        } else {
+            JacksonUtils.write(versionedFlowSnapshot, output);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowsResult.java
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowsResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowsResult.java
new file mode 100644
index 0000000..5f6cc18
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VersionedFlowsResult.java
@@ -0,0 +1,107 @@
+/*
+ * 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.commons.lang3.Validate;
+import org.apache.nifi.registry.flow.VersionedFlow;
+import org.apache.nifi.toolkit.cli.api.Context;
+import org.apache.nifi.toolkit.cli.api.ReferenceResolver;
+import org.apache.nifi.toolkit.cli.api.Referenceable;
+import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter;
+import org.apache.nifi.toolkit.cli.impl.result.writer.Table;
+import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter;
+
+import java.io.PrintStream;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Result for a list of VersionedFlows.
+ */
+public class VersionedFlowsResult extends AbstractWritableResult<List<VersionedFlow>> implements Referenceable {
+
+    private final List<VersionedFlow> versionedFlows;
+
+    public VersionedFlowsResult(final ResultType resultType, final List<VersionedFlow> flows) {
+        super(resultType);
+        this.versionedFlows = flows;
+        Validate.notNull(this.versionedFlows);
+
+        // NOTE: it is important that the order the flows are printed is the same order for the ReferenceResolver
+        this.versionedFlows.sort(Comparator.comparing(VersionedFlow::getName));
+    }
+
+    @Override
+    public List<VersionedFlow> getResult() {
+        return versionedFlows;
+    }
+
+    @Override
+    protected void writeSimpleResult(PrintStream output) {
+        if (versionedFlows.isEmpty()) {
+            return;
+        }
+
+        final Table table = new Table.Builder()
+                .column("#", 3, 3, false)
+                .column("Name", 20, 36, true)
+                .column("Id", 36, 36, false)
+                .column("Description", 11, 40, true)
+                .build();
+
+        for (int i = 0; i < versionedFlows.size(); ++i) {
+            final VersionedFlow flow = versionedFlows.get(i);
+            table.addRow(String.valueOf(i + 1), flow.getName(), flow.getIdentifier(), flow.getDescription());
+        }
+
+        final TableWriter tableWriter = new DynamicTableWriter();
+        tableWriter.write(table, output);
+    }
+
+    @Override
+    public ReferenceResolver createReferenceResolver(final Context context) {
+        final Map<Integer,VersionedFlow> backRefs = new HashMap<>();
+        final AtomicInteger position = new AtomicInteger(0);
+        versionedFlows.forEach(f -> backRefs.put(position.incrementAndGet(), f));
+
+        return new ReferenceResolver() {
+            @Override
+            public String resolve(final Integer position) {
+                final VersionedFlow versionedFlow = backRefs.get(position);
+                if (versionedFlow != null) {
+                    if (context.isInteractive()) {
+                        context.getOutput().printf("Using a positional backreference for '%s'%n", versionedFlow.getName());
+                    }
+                    return versionedFlow.getIdentifier();
+                } else {
+                    return null;
+                }
+            }
+
+            @Override
+            public boolean isEmpty() {
+                return backRefs.isEmpty();
+            }
+        };
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/Void.java
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/Void.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/Void.java
new file mode 100644
index 0000000..03b5726
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/Void.java
@@ -0,0 +1,20 @@
+/*
+ * 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;
+
+public final class Void {
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VoidResult.java
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VoidResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VoidResult.java
new file mode 100644
index 0000000..9653dd6
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/VoidResult.java
@@ -0,0 +1,39 @@
+/*
+ * 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.toolkit.cli.api.Result;
+
+/**
+ * Represents a result that has no real results.
+ */
+public class VoidResult implements Result<Void> {
+
+    private static final Void VOID = new Void();
+
+    private static final VoidResult INSTANCE = new VoidResult();
+
+    public static VoidResult getInstance() {
+        return INSTANCE;
+    }
+
+    @Override
+    public Void getResult() {
+        return VOID;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/writer/DynamicTableWriter.java
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/writer/DynamicTableWriter.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/writer/DynamicTableWriter.java
new file mode 100644
index 0000000..6b1aadd
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/writer/DynamicTableWriter.java
@@ -0,0 +1,123 @@
+/*
+ * 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.writer;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.PrintStream;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class DynamicTableWriter implements TableWriter {
+
+    @Override
+    public void write(final Table table, final PrintStream output) {
+        if (table == null) {
+            throw new IllegalArgumentException("Table cannot be null");
+        }
+
+        if (output == null) {
+            throw new IllegalArgumentException("Output cannot be null");
+        }
+
+        if (table.getColumns().isEmpty()) {
+            throw new IllegalArgumentException("Table has no columns to write");
+        }
+
+        output.println();
+
+        final List<TableColumn> columns = table.getColumns();
+        final List<String[]> rows = table.getRows();
+
+        final int numColumns = columns.size();
+        final Integer[] columnLengths = determineColumnLengths(columns, rows);
+        final List<String> columnNames = columns.stream().map(c -> c.getName()).collect(Collectors.toList());
+
+        final Object[] columnLengthsObj = Arrays.copyOf(columnLengths, numColumns, Object[].class);
+        final Object[] columnNamesObj = columnNames.toArray(new Object[numColumns]);
+
+        final String columnsPatternFormat = String.join("", Collections.nCopies(numColumns, "%%-%ds   "));
+        final String columnsPattern = String.format(columnsPatternFormat, columnLengthsObj);
+
+        // format the header line which will include the column names
+        final String header = String.format(columnsPattern, columnNamesObj);
+        output.println(header);
+
+        // a little clunky way to dynamically create a nice header line, but at least no external dependency
+        final Object[] headerLineValues = new Object[numColumns];
+        for (int i=0; i < numColumns; i++) {
+            int length = columnLengths[i];
+            headerLineValues[i] =  String.join("", Collections.nCopies(length, "-"));
+        }
+
+        final String headerLine = String.format(columnsPattern, headerLineValues);
+        output.println(headerLine);
+
+        // format the rows and print them
+        for (String[] row : rows) {
+            // convert the row to an Object[] for the String.format and also abbreviate any values
+            final Object[] rowValues = new Object[row.length];
+            for (int i=0; i < row.length; i++) {
+                final TableColumn column = columns.get(i);
+                if (column.isAbbreviated()) {
+                    rowValues[i] = StringUtils.abbreviate(row[i], columnLengths[i]);
+                } else {
+                    rowValues[i] = row[i];
+                }
+            }
+
+            final String rowString = String.format(columnsPattern, rowValues);
+            output.println(rowString);
+        }
+
+        output.println();
+        output.flush();
+    }
+
+    private Integer[] determineColumnLengths(final List<TableColumn> columns, final List<String[]> rows) {
+        final Integer[] columnLengths = new Integer[columns.size()];
+
+        for (int i=0; i < columns.size(); i++) {
+            final TableColumn column = columns.get(i);
+
+            int maxLengthInColumn = -1;
+
+            // find the max length of the values in the column
+            for (String[] row : rows) {
+                final String colVal = row[i];
+                if (colVal != null && colVal.length() > maxLengthInColumn) {
+                    maxLengthInColumn = colVal.length();
+                }
+            }
+
+            // if there were values for the column, then start with the min length of the column
+            if (maxLengthInColumn < 0) {
+                maxLengthInColumn = column.getMinLength();
+            }
+
+            // make sure the column length is at least as long as the column name
+            maxLengthInColumn = Math.max(maxLengthInColumn, column.getName().length());
+
+            // make sure the column length is not longer than the max length
+            columnLengths[i] = Math.min(maxLengthInColumn, column.getMaxLength());
+        }
+
+        return columnLengths;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/writer/Table.java
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/writer/Table.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/writer/Table.java
new file mode 100644
index 0000000..b4941ec
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/writer/Table.java
@@ -0,0 +1,92 @@
+/*
+ * 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.writer;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class Table {
+
+    public static String EMPTY_VALUE = "(empty)";
+
+    private final List<TableColumn> columns;
+    private final List<String[]> rows = new ArrayList<>();
+
+    private Table(final Builder builder) {
+        this.columns = Collections.unmodifiableList(
+                builder.columns == null ? Collections.emptyList() : new ArrayList<>(builder.columns));
+
+        if (this.columns.isEmpty()) {
+            throw new IllegalStateException("Cannot create a table with no columns");
+        }
+    }
+
+    public void addRow(String ... values) {
+        if (values == null) {
+            throw new IllegalArgumentException("Values cannot be null");
+        }
+
+        if (values.length != columns.size()) {
+            throw new IllegalArgumentException("Row has " + values.length
+                    + " columns, but table has " + columns.size() + " columns");
+        }
+
+        // fill in any null values in the row with the empty value
+        for (int i=0; i < values.length; i++) {
+            if (values[i] == null) {
+                values[i] = EMPTY_VALUE;
+            }
+        }
+
+        this.rows.add(values);
+    }
+
+    public List<TableColumn> getColumns() {
+        return columns;
+    }
+
+    public List<String[]> getRows() {
+        return rows;
+    }
+
+    /**
+     * Builder for a Table.
+     */
+    public static class Builder {
+
+        private final List<TableColumn> columns = new ArrayList<>();
+
+        public Builder column(final TableColumn column) {
+            if (column == null) {
+                throw new IllegalArgumentException("TableColumn cannot be null");
+            }
+            this.columns.add(column);
+            return this;
+        }
+
+        public Builder column(final String name, int minLength, int maxLength, boolean abbreviate) {
+            final TableColumn column = new TableColumn(name, minLength, maxLength, abbreviate);
+            return column(column);
+        }
+
+        public Table build() {
+            return new Table(this);
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/writer/TableColumn.java
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/writer/TableColumn.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/writer/TableColumn.java
new file mode 100644
index 0000000..e686aef
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/writer/TableColumn.java
@@ -0,0 +1,59 @@
+/*
+ * 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.writer;
+
+import org.apache.commons.lang3.Validate;
+
+public class TableColumn {
+
+    private final String name;
+    private final int minLength;
+    private final int maxLength;
+    private final boolean abbreviate;
+
+    public TableColumn(final String name, final int minLength, final int maxLength) {
+        this(name, minLength, maxLength, false);
+    }
+
+    public TableColumn(final String name, final int minLength, final int maxLength, final boolean abbreviate) {
+        this.name = name;
+        this.minLength = minLength;
+        this.maxLength = maxLength;
+        this.abbreviate = abbreviate;
+        Validate.notBlank(this.name);
+        Validate.isTrue(this.minLength > 0);
+        Validate.isTrue(this.maxLength > 0);
+        Validate.isTrue(this.maxLength >= this.minLength);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public int getMinLength() {
+        return minLength;
+    }
+
+    public int getMaxLength() {
+        return maxLength;
+    }
+
+    public boolean isAbbreviated() {
+        return abbreviate;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/writer/TableWriter.java
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/writer/TableWriter.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/writer/TableWriter.java
new file mode 100644
index 0000000..7ca90ff
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/writer/TableWriter.java
@@ -0,0 +1,34 @@
+/*
+ * 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.writer;
+
+import java.io.PrintStream;
+
+/**
+ * A writer capable of printing a table to a stream.
+ */
+public interface TableWriter {
+
+    /**
+     * Writes the given table to the given PrintStream.
+     *
+     * @param table a table to write
+     * @param output the stream to write to
+     */
+    void write(Table table, PrintStream output);
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/session/SessionVariable.java
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/session/SessionVariable.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/session/SessionVariable.java
new file mode 100644
index 0000000..4c293b0
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/session/SessionVariable.java
@@ -0,0 +1,58 @@
+/*
+ * 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.session;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Possible variables that can be set in the session.
+ */
+public enum SessionVariable {
+
+    NIFI_CLIENT_PROPS("nifi.props"),
+    NIFI_REGISTRY_CLIENT_PROPS("nifi.reg.props");
+
+    private final String variableName;
+
+    SessionVariable(final String variableName) {
+        this.variableName = variableName;
+    }
+
+    public String getVariableName() {
+        return this.variableName;
+    }
+
+    public static SessionVariable fromVariableName(final String variableName) {
+        for (final SessionVariable variable : values()) {
+            if (variable.getVariableName().equals(variableName)) {
+                return variable;
+            }
+        }
+
+        return null;
+    }
+
+    public static List<String> getAllVariableNames() {
+        final List<String> names = new ArrayList<>();
+        for (SessionVariable variable : values()) {
+            names.add(variable.getVariableName());
+        }
+        return names;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/session/SessionVariables.java
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/session/SessionVariables.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/session/SessionVariables.java
deleted file mode 100644
index 747588f..0000000
--- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/session/SessionVariables.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.session;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Possible variables that can be set in the session.
- */
-public enum SessionVariables {
-
-    NIFI_CLIENT_PROPS("nifi.props"),
-    NIFI_REGISTRY_CLIENT_PROPS("nifi.reg.props");
-
-    private final String variableName;
-
-    SessionVariables(final String variableName) {
-        this.variableName = variableName;
-    }
-
-    public String getVariableName() {
-        return this.variableName;
-    }
-
-    public static SessionVariables fromVariableName(final String variableName) {
-        for (final SessionVariables variable : values()) {
-            if (variable.getVariableName().equals(variableName)) {
-                return variable;
-            }
-        }
-
-        return null;
-    }
-
-    public static List<String> getAllVariableNames() {
-        final List<String> names = new ArrayList<>();
-        for (SessionVariables variable : values()) {
-            names.add(variable.getVariableName());
-        }
-        return names;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/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 9a78588..500207f 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
@@ -21,7 +21,6 @@ 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.client.NiFiClientFactory;
 import org.apache.nifi.toolkit.cli.impl.client.NiFiRegistryClientFactory;
@@ -29,8 +28,6 @@ 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.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;
@@ -38,7 +35,7 @@ import java.util.Map;
 public class NiFiCLIMainRunner {
 
     public static void main(String[] args) {
-        final String[] cmdArgs = ("nifi-reg create-bucket -bn FOO -p src/test/resources/test.properties " +
+        final String[] cmdArgs = ("registry list-buckets help " +
                 "").split("[ ]");
 
         final Session session = new InMemorySession();
@@ -50,8 +47,6 @@ 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/b68eebd4/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 10c2db0..3e2e2a3 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
@@ -21,7 +21,6 @@ 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.client.NiFiClientFactory;
 import org.apache.nifi.toolkit.cli.impl.client.NiFiRegistryClientFactory;
@@ -29,10 +28,8 @@ 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.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.apache.nifi.toolkit.cli.impl.session.SessionVariable;
 import org.jline.reader.Candidate;
 import org.jline.reader.LineReader;
 import org.jline.reader.impl.DefaultParser;
@@ -65,8 +62,6 @@ 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);
@@ -195,7 +190,7 @@ public class TestCLICompleter {
         final List<Candidate> candidates = new ArrayList<>();
         completer.complete(lineReader, parsedLine, candidates);
         assertTrue(candidates.size() > 0);
-        assertEquals(SessionVariables.values().length, candidates.size());
+        assertEquals(SessionVariable.values().length, candidates.size());
     }
 
     @Test
@@ -207,7 +202,7 @@ public class TestCLICompleter {
                 Arrays.asList(
                         topCommand,
                         subCommand,
-                        SessionVariables.NIFI_CLIENT_PROPS.getVariableName(),
+                        SessionVariable.NIFI_CLIENT_PROPS.getVariableName(),
                         "src/test/resources/"),
                 3, -1, -1);
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/b68eebd4/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestBucketsResult.java
----------------------------------------------------------------------
diff --git a/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestBucketsResult.java b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestBucketsResult.java
new file mode 100644
index 0000000..1bb9582
--- /dev/null
+++ b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/result/TestBucketsResult.java
@@ -0,0 +1,76 @@
+/*
+ * 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.bucket.Bucket;
+import org.apache.nifi.toolkit.cli.api.ResultType;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+public class TestBucketsResult {
+
+    private ByteArrayOutputStream outputStream;
+    private PrintStream printStream;
+
+    @Before
+    public void setup() {
+        this.outputStream = new ByteArrayOutputStream();
+        this.printStream = new PrintStream(outputStream, true);
+    }
+
+    @Test
+    public void testWritingSimpleBucketsResult() throws IOException {
+        final Bucket b1 = new Bucket();
+        b1.setName("Bucket 1");
+        b1.setDescription("This is bucket 1");
+        b1.setIdentifier(UUID.fromString("ea752054-22c6-4fc0-b851-967d9a3837cb").toString());
+
+        final Bucket b2 = new Bucket();
+        b2.setName("Bucket 2");
+        b2.setDescription(null);
+        b2.setIdentifier(UUID.fromString("ddf5f289-7502-46df-9798-4b0457c1816b").toString());
+
+        final List<Bucket> buckets = new ArrayList<>();
+        buckets.add(b1);
+        buckets.add(b2);
+
+        final BucketsResult result = new BucketsResult(ResultType.SIMPLE, buckets);
+        result.write(printStream);
+
+        final String resultOut = new String(outputStream.toByteArray(), StandardCharsets.UTF_8);
+        //System.out.println(resultOut);
+
+        final String expected = "\n" +
+                "#   Name       Id                                     Description        \n" +
+                "-   --------   ------------------------------------   ----------------   \n" +
+                "1   Bucket 1   ea752054-22c6-4fc0-b851-967d9a3837cb   This is bucket 1   \n" +
+                "2   Bucket 2   ddf5f289-7502-46df-9798-4b0457c1816b   (empty)            \n" +
+                "\n";
+
+        Assert.assertEquals(expected, resultOut);
+    }
+
+}


Mime
View raw message