NIFI-4839 - Updating README and cleaning up descriptions and comments

- Making registryClientId optional and auto selecting when only one is available
- Added delete-bucket command
- Added delete-flow command for registry
This commit is contained in:
Bryan Bende 2018-02-11 11:13:18 -05:00 committed by Pierre Villard
parent fe71c18ec5
commit 69367ff0bf
8 changed files with 204 additions and 6 deletions

View File

@ -123,3 +123,32 @@ Example of json output for list-buckets:
"href" : "buckets/3c7b7467-0012-4d8f-a918-6aa42b6b9d39" "href" : "buckets/3c7b7467-0012-4d8f-a918-6aa42b6b9d39"
} }
} ] } ]
## Adding Commands
To add a NiFi command, create a new class that extends AbstractNiFiCommand:
public class MyCommand extends AbstractNiFiCommand {
public MyCommand() {
super("my-command");
}
@Override
protected void doExecute(NiFiClient client, Properties properties)
throws NiFiClientException, IOException, MissingOptionException, CommandException {
// TODO implement
}
@Override
public String getDescription() {
return "This is my new command";
}
}
Add the new command to NiFiCommandGroup:
commands.add(new MyCommand());
To add a NiFi Registry command, perform the same steps, but extend from
AbstractNiFiRegistryCommand, and add the command to NiFiRegistryCommandGroup.

View File

@ -20,7 +20,7 @@ import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options; import org.apache.commons.cli.Options;
/** /**
* Represents a command to execute against NiFi registry. * Represents a command to execute.
*/ */
public interface Command { public interface Command {
@ -32,7 +32,7 @@ public interface Command {
void initialize(Context context); void initialize(Context context);
/** /**
* @return the name of the command that will be specified as the first argument to the tool * @return the name of the command
*/ */
String getName(); String getName();

View File

@ -65,6 +65,7 @@ public enum CommandOption {
PROTOCOL("pro", "protocol", "The security protocol to use, such as TLSv.1.2", true), PROTOCOL("pro", "protocol", "The security protocol to use, such as TLSv.1.2", true),
// Miscellaneous // Miscellaneous
FORCE("force", "force", "Indicates to force a delete operation", false),
OUTPUT_TYPE("ot", "outputType", "The type of output to produce (json or simple)", true), OUTPUT_TYPE("ot", "outputType", "The type of output to produce (json or simple)", true),
VERBOSE("verbose", "verbose", "Indicates that verbose output should be provided", false), VERBOSE("verbose", "verbose", "Indicates that verbose output should be provided", false),
HELP("h", "help", "Help", false) HELP("h", "help", "Help", false)

View File

@ -30,9 +30,12 @@ import org.apache.nifi.web.api.dto.PositionDTO;
import org.apache.nifi.web.api.dto.ProcessGroupDTO; import org.apache.nifi.web.api.dto.ProcessGroupDTO;
import org.apache.nifi.web.api.dto.VersionControlInformationDTO; import org.apache.nifi.web.api.dto.VersionControlInformationDTO;
import org.apache.nifi.web.api.entity.ProcessGroupEntity; 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 java.io.IOException; import java.io.IOException;
import java.util.Properties; import java.util.Properties;
import java.util.Set;
/** /**
* Command for importing a flow to NiFi from NiFi Registry. * Command for importing a flow to NiFi from NiFi Registry.
@ -46,7 +49,8 @@ public class PGImport extends AbstractNiFiCommand {
@Override @Override
public String getDescription() { public String getDescription() {
return "Creates a new process group by importing a versioned flow from a registry. If no process group id is " + return "Creates a new process group by importing a versioned flow from a registry. If no process group id is " +
"specified, then the created process group will be placed in the root group."; "specified, then the created process group will be placed in the root group. If only one registry client " +
"exists in NiFi, then it does not need to be specified and will be automatically selected.";
} }
@Override @Override
@ -62,11 +66,29 @@ public class PGImport extends AbstractNiFiCommand {
protected void doExecute(final NiFiClient client, final Properties properties) protected void doExecute(final NiFiClient client, final Properties properties)
throws NiFiClientException, IOException, MissingOptionException { throws NiFiClientException, IOException, MissingOptionException {
final String registryId = getRequiredArg(properties, CommandOption.REGISTRY_CLIENT_ID);
final String bucketId = getRequiredArg(properties, CommandOption.BUCKET_ID); final String bucketId = getRequiredArg(properties, CommandOption.BUCKET_ID);
final String flowId = getRequiredArg(properties, CommandOption.FLOW_ID); final String flowId = getRequiredArg(properties, CommandOption.FLOW_ID);
final Integer flowVersion = getRequiredIntArg(properties, CommandOption.FLOW_VERSION); final Integer flowVersion = getRequiredIntArg(properties, CommandOption.FLOW_VERSION);
// if a registry client is specified use it, otherwise see if there is only one available and use that,
// if more than one is available then throw an exception because we don't know which one to use
String registryId = getArg(properties, CommandOption.REGISTRY_CLIENT_ID);
if (StringUtils.isBlank(registryId)) {
final RegistryClientsEntity registries = client.getControllerClient().getRegistryClients();
final Set<RegistryClientEntity> entities = registries.getRegistries();
if (entities == null || entities.isEmpty()) {
throw new NiFiClientException("No registry clients available");
}
if (entities.size() == 1) {
registryId = entities.stream().findFirst().get().getId();
} else {
throw new MissingOptionException(CommandOption.REGISTRY_CLIENT_ID.getLongName()
+ " must be provided when there is more than one available");
}
}
// get the optional id of the parent PG, otherwise fallback to the root group // get the optional id of the parent PG, otherwise fallback to the root group
String parentPgId = getArg(properties, CommandOption.PG_ID); String parentPgId = getArg(properties, CommandOption.PG_ID);
if (StringUtils.isBlank(parentPgId)) { if (StringUtils.isBlank(parentPgId)) {

View File

@ -19,8 +19,10 @@ package org.apache.nifi.toolkit.cli.impl.command.registry;
import org.apache.nifi.toolkit.cli.api.Command; import org.apache.nifi.toolkit.cli.api.Command;
import org.apache.nifi.toolkit.cli.impl.command.AbstractCommandGroup; import org.apache.nifi.toolkit.cli.impl.command.AbstractCommandGroup;
import org.apache.nifi.toolkit.cli.impl.command.registry.bucket.CreateBucket; import org.apache.nifi.toolkit.cli.impl.command.registry.bucket.CreateBucket;
import org.apache.nifi.toolkit.cli.impl.command.registry.bucket.DeleteBucket;
import org.apache.nifi.toolkit.cli.impl.command.registry.bucket.ListBuckets; import org.apache.nifi.toolkit.cli.impl.command.registry.bucket.ListBuckets;
import org.apache.nifi.toolkit.cli.impl.command.registry.flow.CreateFlow; import org.apache.nifi.toolkit.cli.impl.command.registry.flow.CreateFlow;
import org.apache.nifi.toolkit.cli.impl.command.registry.flow.DeleteFlow;
import org.apache.nifi.toolkit.cli.impl.command.registry.flow.ExportFlowVersion; import org.apache.nifi.toolkit.cli.impl.command.registry.flow.ExportFlowVersion;
import org.apache.nifi.toolkit.cli.impl.command.registry.flow.ImportFlowVersion; import org.apache.nifi.toolkit.cli.impl.command.registry.flow.ImportFlowVersion;
import org.apache.nifi.toolkit.cli.impl.command.registry.flow.ListFlowVersions; import org.apache.nifi.toolkit.cli.impl.command.registry.flow.ListFlowVersions;
@ -47,8 +49,10 @@ public class NiFiRegistryCommandGroup extends AbstractCommandGroup {
commandList.add(new CurrentUser()); commandList.add(new CurrentUser());
commandList.add(new ListBuckets()); commandList.add(new ListBuckets());
commandList.add(new CreateBucket()); commandList.add(new CreateBucket());
commandList.add(new DeleteBucket());
commandList.add(new ListFlows()); commandList.add(new ListFlows());
commandList.add(new CreateFlow()); commandList.add(new CreateFlow());
commandList.add(new DeleteFlow());
commandList.add(new ListFlowVersions()); commandList.add(new ListFlowVersions());
commandList.add(new ExportFlowVersion()); commandList.add(new ExportFlowVersion());
commandList.add(new ImportFlowVersion()); commandList.add(new ImportFlowVersion());

View File

@ -0,0 +1,70 @@
/*
* 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.registry.bucket;
import org.apache.commons.cli.ParseException;
import org.apache.nifi.registry.client.BucketClient;
import org.apache.nifi.registry.client.FlowClient;
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.impl.command.CommandOption;
import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
/**
* Deletes a bucket from the given registry.
*/
public class DeleteBucket extends AbstractNiFiRegistryCommand {
public DeleteBucket() {
super("delete-bucket");
}
@Override
public String getDescription() {
return "Deletes the bucket with the given id. If the bucket contains any items then the force option must be used.";
}
@Override
protected void doInitialize(Context context) {
addOption(CommandOption.BUCKET_ID.createOption());
addOption(CommandOption.FORCE.createOption());
}
@Override
protected void doExecute(final NiFiRegistryClient client, final Properties properties)
throws IOException, NiFiRegistryException, ParseException {
final String bucketId = getRequiredArg(properties, CommandOption.BUCKET_ID);
final boolean forceDelete = properties.containsKey(CommandOption.FORCE.getLongName());
final FlowClient flowClient = client.getFlowClient();
final List<VersionedFlow> flowsInBucket = flowClient.getByBucket(bucketId);
if (flowsInBucket != null && flowsInBucket.size() > 0 && !forceDelete) {
throw new NiFiRegistryException("Bucket is not empty, use --" + CommandOption.FORCE.getLongName() + " to delete");
} else {
final BucketClient bucketClient = client.getBucketClient();
bucketClient.delete(bucketId);
}
}
}

View File

@ -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.command.registry.flow;
import org.apache.commons.cli.ParseException;
import org.apache.nifi.registry.client.FlowClient;
import org.apache.nifi.registry.client.FlowSnapshotClient;
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.impl.command.CommandOption;
import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
/**
* Deletes a flow from the given registry.
*/
public class DeleteFlow extends AbstractNiFiRegistryCommand {
public DeleteFlow() {
super("delete-flow");
}
@Override
public String getDescription() {
return "Deletes a flow from the registry. If the flow has one or more versions then the force option must be used.";
}
@Override
protected void doInitialize(Context context) {
addOption(CommandOption.FLOW_ID.createOption());
addOption(CommandOption.FORCE.createOption());
}
@Override
protected void doExecute(final NiFiRegistryClient client, final Properties properties)
throws IOException, NiFiRegistryException, ParseException {
final String flowId = getRequiredArg(properties, CommandOption.FLOW_ID);
final boolean forceDelete = properties.containsKey(CommandOption.FORCE.getLongName());
final String bucketId = getBucketId(client, flowId);
final FlowSnapshotClient flowSnapshotClient = client.getFlowSnapshotClient();
final List<VersionedFlowSnapshotMetadata> snapshotMetadata = flowSnapshotClient.getSnapshotMetadata(bucketId, flowId);
if (snapshotMetadata != null && snapshotMetadata.size() > 0 && !forceDelete) {
throw new NiFiRegistryException("Flow has versions, use --" + CommandOption.FORCE.getLongName() + " to delete");
} else {
final FlowClient flowClient = client.getFlowClient();
flowClient.delete(bucketId, flowId);
}
}
}

View File

@ -48,7 +48,7 @@ public class ImportFlowVersion extends AbstractNiFiRegistryCommand {
@Override @Override
public String getDescription() { public String getDescription() {
return "Imports a version of a flow that was previously exported. The imported version automatically becomes " + return "Imports a version of a flow from a local file, or a URL. The imported version automatically becomes " +
"the next version of the given flow."; "the next version of the given flow.";
} }