NIFI-5027 Adding commands pg-get-services, pg-enable-services, and pg-disable-services

- Improving response when service is stuck enabling, and improving response when some services couldn't be enabled
- Throwing exception when a service is stuck enabling or can't be enabled so that standalone mode gets a non-zero status code, also allowing use of -verbose so stand-alone can decide if output is desired
- Improving information provided by pg-disable-services

Signed-off-by: Pierre Villard <pierre.villard.fr@gmail.com>

This closes #2604.
This commit is contained in:
Bryan Bende 2018-04-03 09:30:30 -04:00 committed by Pierre Villard
parent 1913b1e2a8
commit 7abb02fff0
11 changed files with 765 additions and 0 deletions

View File

@ -16,6 +16,8 @@
*/
package org.apache.nifi.toolkit.cli.impl.client.nifi;
import org.apache.nifi.web.api.entity.ActivateControllerServicesEntity;
import org.apache.nifi.web.api.entity.ControllerServicesEntity;
import org.apache.nifi.web.api.entity.CurrentUserEntity;
import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity;
import org.apache.nifi.web.api.entity.ScheduleComponentsEntity;
@ -78,4 +80,21 @@ public interface FlowClient {
VersionedFlowSnapshotMetadataSetEntity getVersions(String registryId, String bucketId, String flowId)
throws NiFiClientException, IOException;
/**
* Retrieves the controller services for the given group.
*
* @param groupId the process group id
* @return tje controller services entity
*/
ControllerServicesEntity getControllerServices(String groupId) throws NiFiClientException, IOException;
/**
* Enable or disable controller services in the given process group.
*
* @param activateControllerServicesEntity the entity indicating the process group to enable/disable services for
* @return the activate response
*/
ActivateControllerServicesEntity activateControllerServices(ActivateControllerServicesEntity activateControllerServicesEntity) throws NiFiClientException, IOException;
}

View File

@ -23,7 +23,9 @@ import org.apache.nifi.toolkit.cli.impl.client.nifi.ProcessGroupBox;
import org.apache.nifi.web.api.dto.PositionDTO;
import org.apache.nifi.web.api.dto.flow.FlowDTO;
import org.apache.nifi.web.api.dto.flow.ProcessGroupFlowDTO;
import org.apache.nifi.web.api.entity.ActivateControllerServicesEntity;
import org.apache.nifi.web.api.entity.ComponentEntity;
import org.apache.nifi.web.api.entity.ControllerServicesEntity;
import org.apache.nifi.web.api.entity.CurrentUserEntity;
import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity;
import org.apache.nifi.web.api.entity.ScheduleComponentsEntity;
@ -177,4 +179,42 @@ public class JerseyFlowClient extends AbstractJerseyClient implements FlowClient
return getRequestBuilder(target).get(VersionedFlowSnapshotMetadataSetEntity.class);
});
}
@Override
public ControllerServicesEntity getControllerServices(final String groupId) throws NiFiClientException, IOException {
if (StringUtils.isBlank(groupId)) {
throw new IllegalArgumentException("Group Id cannot be null or blank");
}
return executeAction("Error retrieving controller services", () -> {
final WebTarget target = flowTarget
.path("process-groups/{id}/controller-services")
.resolveTemplate("id", groupId);
return getRequestBuilder(target).get(ControllerServicesEntity.class);
});
}
@Override
public ActivateControllerServicesEntity activateControllerServices(final ActivateControllerServicesEntity activateControllerServicesEntity)
throws NiFiClientException, IOException {
if (activateControllerServicesEntity == null) {
throw new IllegalArgumentException("Entity cannot be null");
}
if (StringUtils.isBlank(activateControllerServicesEntity.getId())) {
throw new IllegalArgumentException("Entity must contain a process group id");
}
return executeAction("Error enabling or disabling controlling services", () -> {
final WebTarget target = flowTarget
.path("process-groups/{id}/controller-services")
.resolveTemplate("id", activateControllerServicesEntity.getId());
return getRequestBuilder(target).put(
Entity.entity(activateControllerServicesEntity, MediaType.APPLICATION_JSON_TYPE),
ActivateControllerServicesEntity.class);
});
}
}

View File

@ -205,4 +205,12 @@ public abstract class AbstractCommand<R extends Result> implements Command<R> {
}
}
protected boolean isVerbose(final Properties properties) {
return properties.containsKey(CommandOption.VERBOSE.getLongName());
}
protected boolean isInteractive() {
return getContext().isInteractive();
}
}

View File

@ -21,7 +21,10 @@ import org.apache.nifi.toolkit.cli.impl.command.AbstractCommandGroup;
import org.apache.nifi.toolkit.cli.impl.command.nifi.flow.CurrentUser;
import org.apache.nifi.toolkit.cli.impl.command.nifi.flow.GetRootId;
import org.apache.nifi.toolkit.cli.impl.command.nifi.pg.PGChangeVersion;
import org.apache.nifi.toolkit.cli.impl.command.nifi.pg.PGDisableControllerServices;
import org.apache.nifi.toolkit.cli.impl.command.nifi.pg.PGEnableControllerServices;
import org.apache.nifi.toolkit.cli.impl.command.nifi.pg.PGGetAllVersions;
import org.apache.nifi.toolkit.cli.impl.command.nifi.pg.PGGetControllerServices;
import org.apache.nifi.toolkit.cli.impl.command.nifi.pg.PGGetVars;
import org.apache.nifi.toolkit.cli.impl.command.nifi.pg.PGGetVersion;
import org.apache.nifi.toolkit.cli.impl.command.nifi.pg.PGImport;
@ -68,6 +71,9 @@ public class NiFiCommandGroup extends AbstractCommandGroup {
commands.add(new PGGetAllVersions());
commands.add(new PGList());
commands.add(new PGStatus());
commands.add(new PGGetControllerServices());
commands.add(new PGEnableControllerServices());
commands.add(new PGDisableControllerServices());
return new ArrayList<>(commands);
}
}

View File

@ -0,0 +1,176 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.toolkit.cli.impl.command.nifi.pg;
import org.apache.commons.cli.MissingOptionException;
import org.apache.nifi.toolkit.cli.api.CommandException;
import org.apache.nifi.toolkit.cli.api.Context;
import org.apache.nifi.toolkit.cli.impl.client.nifi.FlowClient;
import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
import org.apache.nifi.toolkit.cli.impl.command.nifi.pg.cs.ControllerServiceStateCounts;
import org.apache.nifi.toolkit.cli.impl.command.nifi.pg.cs.ControllerServiceStates;
import org.apache.nifi.toolkit.cli.impl.command.nifi.pg.cs.ControllerServiceUtil;
import org.apache.nifi.toolkit.cli.impl.result.VoidResult;
import org.apache.nifi.web.api.entity.ActivateControllerServicesEntity;
import org.apache.nifi.web.api.entity.BulletinEntity;
import org.apache.nifi.web.api.entity.ControllerServiceEntity;
import org.apache.nifi.web.api.entity.ControllerServicesEntity;
import java.io.IOException;
import java.util.Properties;
public class PGDisableControllerServices extends AbstractNiFiCommand<VoidResult> {
public static final int MAX_DISABLING_ITERATIONS = 20;
public static final long DELAY_MS = 2000;
public PGDisableControllerServices() {
super("pg-disable-services", VoidResult.class);
}
@Override
public String getDescription() {
return "Disables the controller services in the given process group. Any services that are in use by a running component " +
"will fail to be disabled and will need to be stopped first using pg-stop.";
}
@Override
protected void doInitialize(final Context context) {
addOption(CommandOption.PG_ID.createOption());
}
@Override
public VoidResult doExecute(NiFiClient client, Properties properties)
throws NiFiClientException, IOException, MissingOptionException, CommandException {
final FlowClient flowClient = client.getFlowClient();
final String pgId = getRequiredArg(properties, CommandOption.PG_ID);
final ControllerServiceStateCounts initialServiceStates = getControllerServiceStates(flowClient, pgId);
// if we have no enabled or enabling services then there is nothing to do so return
if (initialServiceStates.getEnabled() == 0 && initialServiceStates.getEnabling() == 0) {
if (shouldPrint(properties)) {
println();
println("No services are currently enabled/enabling, nothing to do...");
println();
}
return VoidResult.getInstance();
}
if (shouldPrint(properties)) {
println();
println("Starting states:");
printControllerServiceStates(initialServiceStates);
println();
println("Attempting to disable services...");
}
// send the request to disable services and wait a second
final ActivateControllerServicesEntity disableEntity = new ActivateControllerServicesEntity();
disableEntity.setId(pgId);
disableEntity.setState(ActivateControllerServicesEntity.STATE_DISABLED);
flowClient.activateControllerServices(disableEntity);
sleep(1000);
// wait for disabling services to become disabled, or until we've waited up to max number of waits
int disablingWaitCount = 1;
ControllerServiceStateCounts serviceStates = getControllerServiceStates(flowClient, pgId);
while (serviceStates.getDisabling() > 0 && disablingWaitCount < MAX_DISABLING_ITERATIONS) {
if (shouldPrint(properties)) {
println("Currently " + serviceStates.getDisabling() + " services are disabling, waiting to finish before proceeding ("
+ disablingWaitCount + " of " + MAX_DISABLING_ITERATIONS + ")...");
}
sleep(DELAY_MS);
disablingWaitCount++;
serviceStates = getControllerServiceStates(flowClient, pgId);
}
// if we have still have disabling services then we may have a stuck service so throw an exception
if (serviceStates.getDisabling() > 0) {
if (shouldPrint(properties)) {
printServicesStillDisabling(flowClient, pgId);
}
throw new CommandException("One or more services may be stuck disabling, run command with -verbose to obtain more details");
}
// otherwise the command was successful so print the final states and return
if (shouldPrint(properties)) {
println();
println("Finished States:");
printControllerServiceStates(serviceStates);
println();
}
return VoidResult.getInstance();
}
private void printControllerServiceStates(final ControllerServiceStateCounts serviceStates) {
println(" - " + serviceStates.getEnabled() + " enabled");
println(" - " + serviceStates.getEnabling() + " enabling");
println(" - " + serviceStates.getDisabled() + " disabled");
println(" - " + serviceStates.getDisabling() + " disabling");
}
private void printServicesStillDisabling(final FlowClient flowClient, final String pgId)
throws NiFiClientException, IOException {
final ControllerServicesEntity servicesEntity = flowClient.getControllerServices(pgId);
if (servicesEntity == null || servicesEntity.getControllerServices() == null) {
return;
}
println();
println("One or more services appear to be stuck disabling: ");
for (final ControllerServiceEntity serviceEntity : servicesEntity.getControllerServices()) {
if (ControllerServiceStates.STATE_DISABLING.equals(serviceEntity.getComponent().getState())) {
println();
println("Service: " + serviceEntity.getId() + " - " + serviceEntity.getComponent().getName());
if (serviceEntity.getBulletins() != null) {
println();
println("Reasons: ");
for (final BulletinEntity bulletinEntity : serviceEntity.getBulletins()) {
println("- " + bulletinEntity.getBulletin().getMessage());
}
}
}
}
}
private void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
private boolean shouldPrint(final Properties properties) {
return isInteractive() || isVerbose(properties);
}
private ControllerServiceStateCounts getControllerServiceStates(final FlowClient flowClient, final String pgId)
throws NiFiClientException, IOException {
return ControllerServiceUtil.getControllerServiceStates(flowClient, pgId);
}
}

View File

@ -0,0 +1,221 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.toolkit.cli.impl.command.nifi.pg;
import org.apache.commons.cli.MissingOptionException;
import org.apache.nifi.toolkit.cli.api.CommandException;
import org.apache.nifi.toolkit.cli.api.Context;
import org.apache.nifi.toolkit.cli.impl.client.nifi.FlowClient;
import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
import org.apache.nifi.toolkit.cli.impl.command.nifi.pg.cs.ControllerServiceStateCounts;
import org.apache.nifi.toolkit.cli.impl.command.nifi.pg.cs.ControllerServiceStates;
import org.apache.nifi.toolkit.cli.impl.command.nifi.pg.cs.ControllerServiceUtil;
import org.apache.nifi.toolkit.cli.impl.result.VoidResult;
import org.apache.nifi.web.api.dto.ControllerServiceDTO;
import org.apache.nifi.web.api.entity.ActivateControllerServicesEntity;
import org.apache.nifi.web.api.entity.BulletinEntity;
import org.apache.nifi.web.api.entity.ControllerServiceEntity;
import org.apache.nifi.web.api.entity.ControllerServicesEntity;
import java.io.IOException;
import java.util.Properties;
public class PGEnableControllerServices extends AbstractNiFiCommand<VoidResult> {
public static final int MAX_ATTEMPTS = 180;
public static final int MAX_ENABLING_ITERATIONS = 20;
public static final long ENABLING_DELAY_MS = 2000;
public PGEnableControllerServices() {
super("pg-enable-services", VoidResult.class);
}
@Override
public String getDescription() {
return "Attempts to enable all controller services in the given PG. In stand-alone mode this command will not " +
"produce all of the output seen in interactive mode unless the --verbose argument is specified.";
}
@Override
protected void doInitialize(final Context context) {
addOption(CommandOption.PG_ID.createOption());
}
@Override
public VoidResult doExecute(final NiFiClient client, final Properties properties)
throws NiFiClientException, IOException, MissingOptionException, CommandException {
final String pgId = getRequiredArg(properties, CommandOption.PG_ID);
final FlowClient flowClient = client.getFlowClient();
if (shouldPrint(properties)) {
println();
}
int count = 0;
int prevNumEnabled = -1;
int enablingIterations = 1;
// request to enable services until the number of enabled services is no longer changing, which means either all
// services have been enabled, or the rest of the services are invalid and can't be enabled
while (count < MAX_ATTEMPTS) {
// retrieve the current states of the services in the given pg
final ControllerServiceStateCounts states = getControllerServiceStates(flowClient, pgId);
// if any services are currently enabling then sleep and loop again
if (states.getEnabling() > 0) {
if (enablingIterations < MAX_ENABLING_ITERATIONS) {
if (shouldPrint(properties)) {
println("Currently " + states.getEnabling() + " services are enabling, waiting to finish before " +
"proceeding (" + enablingIterations + " of " + MAX_ENABLING_ITERATIONS + ")");
}
try {
Thread.sleep(ENABLING_DELAY_MS);
} catch (InterruptedException e) {
Thread.interrupted();
}
enablingIterations++;
continue;
} else {
if (shouldPrint(properties)) {
printServicesStillEnabling(flowClient, pgId);
}
// throw an exception so stand-alone mode will exit with a non-zero status code
throw new CommandException("One or more services are stuck enabling, run command with -verbose to obtain more details");
}
}
// reset the enabling iteration count since we got past the above block without breaking
enablingIterations = 1;
// if no services are enabling and the number of enabled services equals the number of enabled services from
// last iteration, then we know there are no more that we can enable so break
if (states.getEnabled() == prevNumEnabled && states.getEnabling() == 0) {
if (shouldPrint(properties)) {
println();
println("Finished with " + states.getEnabled() + " enabled services and " + states.getDisabled() + " disabled services");
}
if (states.getDisabled() > 0 || states.getDisabling() > 0) {
if (shouldPrint(properties)) {
printServicesNotEnabled(flowClient, pgId);
println();
}
// throw an exception so stand-alone mode will exit with a non-zero status code
throw new CommandException("One or more services could not be enabled, run command with -verbose to obtain more details");
} else {
if (shouldPrint(properties)) {
println();
}
// just break here to proceed with normal completion (i.e. will have a zero status code)
break;
}
}
// if we didn't break then store the number that were enabled to compare with next time
prevNumEnabled = states.getEnabled();
if (shouldPrint(properties)) {
println("Currently " + states.getEnabled() + " enabled services and " + states.getDisabled()
+ " disabled services, attempting to enable services...");
}
// send the request to enable services
final ActivateControllerServicesEntity enableEntity = new ActivateControllerServicesEntity();
enableEntity.setId(pgId);
enableEntity.setState(ActivateControllerServicesEntity.STATE_ENABLED);
flowClient.activateControllerServices(enableEntity);
count++;
}
return VoidResult.getInstance();
}
private boolean shouldPrint(final Properties properties) {
return isInteractive() || isVerbose(properties);
}
private ControllerServiceStateCounts getControllerServiceStates(final FlowClient flowClient, final String pgId)
throws NiFiClientException, IOException {
return ControllerServiceUtil.getControllerServiceStates(flowClient, pgId);
}
private void printServicesStillEnabling(final FlowClient flowClient, final String pgId)
throws NiFiClientException, IOException {
final ControllerServicesEntity servicesEntity = flowClient.getControllerServices(pgId);
if (servicesEntity == null || servicesEntity.getControllerServices() == null) {
return;
}
println();
println("One or more services appear to be stuck enabling: ");
for (final ControllerServiceEntity serviceEntity : servicesEntity.getControllerServices()) {
if (ControllerServiceStates.STATE_ENABLING.equals(serviceEntity.getComponent().getState())) {
println();
println("Service: " + serviceEntity.getId() + " - " + serviceEntity.getComponent().getName());
if (serviceEntity.getBulletins() != null) {
println();
println("Reasons: ");
for (final BulletinEntity bulletinEntity : serviceEntity.getBulletins()) {
println("- " + bulletinEntity.getBulletin().getMessage());
}
}
}
}
}
private void printServicesNotEnabled(final FlowClient flowClient, final String pgId)
throws NiFiClientException, IOException {
final ControllerServicesEntity servicesEntity = flowClient.getControllerServices(pgId);
if (servicesEntity == null || servicesEntity.getControllerServices() == null) {
return;
}
println();
println("The following services could not be enabled: ");
for (final ControllerServiceEntity serviceEntity : servicesEntity.getControllerServices()) {
if (!ControllerServiceStates.STATE_ENABLED.equals(serviceEntity.getComponent().getState())) {
println();
println("Service: " + serviceEntity.getId() + " - " + serviceEntity.getComponent().getName());
final ControllerServiceDTO serviceDTO = serviceEntity.getComponent();
if (serviceDTO.getValidationErrors() != null) {
println();
println("Validation Errors: ");
for (final String validationError : serviceDTO.getValidationErrors()) {
println("- " + validationError);
}
}
}
}
}
}

View File

@ -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.command.nifi.pg;
import org.apache.commons.cli.MissingOptionException;
import org.apache.nifi.toolkit.cli.api.CommandException;
import org.apache.nifi.toolkit.cli.api.Context;
import org.apache.nifi.toolkit.cli.impl.client.nifi.FlowClient;
import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
import org.apache.nifi.toolkit.cli.impl.result.ControllerServicesResult;
import org.apache.nifi.web.api.entity.ControllerServicesEntity;
import java.io.IOException;
import java.util.Properties;
/**
* Command to get the list of controller services for a given process group.
*/
public class PGGetControllerServices extends AbstractNiFiCommand<ControllerServicesResult> {
public PGGetControllerServices() {
super("pg-get-services", ControllerServicesResult.class);
}
@Override
public String getDescription() {
return "Retrieves the list of controller services for the given process group.";
}
@Override
protected void doInitialize(final Context context) {
addOption(CommandOption.PG_ID.createOption());
}
@Override
public ControllerServicesResult doExecute(NiFiClient client, Properties properties)
throws NiFiClientException, IOException, MissingOptionException, CommandException {
final String pgId = getRequiredArg(properties, CommandOption.PG_ID);
final FlowClient flowClient = client.getFlowClient();
final ControllerServicesEntity servicesEntity = flowClient.getControllerServices(pgId);
return new ControllerServicesResult(getResultType(properties), servicesEntity);
}
}

View File

@ -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.command.nifi.pg.cs;
public class ControllerServiceStateCounts {
private int enabled;
private int enabling;
private int disabled;
private int disabling;
public int getEnabled() {
return enabled;
}
public void incrementEnabled() {
enabled++;
}
public int getEnabling() {
return enabling;
}
public void incrementEnabling() {
enabling++;
}
public int getDisabled() {
return disabled;
}
public void incrementDisabled() {
disabled++;
}
public int getDisabling() {
return disabling;
}
public void incrementDisabling() {
disabling++;
}
}

View File

@ -0,0 +1,28 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.toolkit.cli.impl.command.nifi.pg.cs;
/**
* Possible states for a controller service.
*/
public interface ControllerServiceStates {
String STATE_ENABLED = "ENABLED";
String STATE_ENABLING = "ENABLING";
String STATE_DISABLED = "DISABLED";
String STATE_DISABLING = "DISABLING";
}

View File

@ -0,0 +1,68 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.toolkit.cli.impl.command.nifi.pg.cs;
import org.apache.nifi.toolkit.cli.impl.client.nifi.FlowClient;
import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
import org.apache.nifi.web.api.entity.ControllerServiceEntity;
import org.apache.nifi.web.api.entity.ControllerServicesEntity;
import java.io.IOException;
/**
* Utility methods for controller service commands.
*/
public class ControllerServiceUtil {
public static ControllerServiceStateCounts getControllerServiceStates(final FlowClient flowClient, final String pgId)
throws NiFiClientException, IOException {
final ControllerServicesEntity servicesEntity = flowClient.getControllerServices(pgId);
return getControllerServiceStates(servicesEntity);
}
public static ControllerServiceStateCounts getControllerServiceStates(final ControllerServicesEntity servicesEntity)
throws NiFiClientException {
final ControllerServiceStateCounts states = new ControllerServiceStateCounts();
if (servicesEntity == null || servicesEntity.getControllerServices() == null || servicesEntity.getControllerServices().isEmpty()) {
return states;
}
for (final ControllerServiceEntity serviceEntity : servicesEntity.getControllerServices()) {
final String state = serviceEntity.getComponent().getState();
switch(state) {
case ControllerServiceStates.STATE_ENABLED:
states.incrementEnabled();
break;
case ControllerServiceStates.STATE_ENABLING:
states.incrementEnabling();
break;
case ControllerServiceStates.STATE_DISABLED:
states.incrementDisabled();
break;
case ControllerServiceStates.STATE_DISABLING:
states.incrementDisabling();
break;
default:
throw new NiFiClientException("Unexpected controller service state: " + state);
}
}
return states;
}
}

View File

@ -0,0 +1,81 @@
/*
* 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.ControllerServiceDTO;
import org.apache.nifi.web.api.entity.ControllerServiceEntity;
import org.apache.nifi.web.api.entity.ControllerServicesEntity;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Result for ControllerServicesEntity.
*/
public class ControllerServicesResult extends AbstractWritableResult<ControllerServicesEntity> {
private final ControllerServicesEntity controllerServicesEntity;
public ControllerServicesResult(final ResultType resultType, final ControllerServicesEntity controllerServicesEntity) {
super(resultType);
this.controllerServicesEntity = controllerServicesEntity;
Validate.notNull(this.controllerServicesEntity);
}
@Override
protected void writeSimpleResult(final PrintStream output) throws IOException {
final Set<ControllerServiceEntity> serviceEntities = controllerServicesEntity.getControllerServices();
if (serviceEntities == null) {
return;
}
final List<ControllerServiceDTO> serviceDTOS = serviceEntities.stream()
.map(s -> s.getComponent())
.collect(Collectors.toList());
Collections.sort(serviceDTOS, Comparator.comparing(ControllerServiceDTO::getName));
final Table table = new Table.Builder()
.column("#", 3, 3, false)
.column("Name", 5, 40, false)
.column("State", 5, 40, false)
.build();
for (int i=0; i < serviceDTOS.size(); i++) {
final ControllerServiceDTO serviceDTO = serviceDTOS.get(i);
table.addRow(String.valueOf(i+1), serviceDTO.getName(), serviceDTO.getState());
}
final TableWriter tableWriter = new DynamicTableWriter();
tableWriter.write(table, output);
}
@Override
public ControllerServicesEntity getResult() {
return controllerServicesEntity;
}
}