mirror of https://github.com/apache/nifi.git
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:
parent
1913b1e2a8
commit
7abb02fff0
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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++;
|
||||
}
|
||||
|
||||
}
|
|
@ -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";
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue