NIFI-12186 Add ability to export a versioned reporting task snapshot (#7853)

* NIFI-12186 Add ability to export a versioned reporting task snapshot
- Add CLI commands and optional query param to specify specific reporting task
This commit is contained in:
Bryan Bende 2023-10-09 10:50:36 -04:00 committed by GitHub
parent 457973d133
commit ae61ebb5ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 538 additions and 33 deletions

View File

@ -0,0 +1,48 @@
/*
* 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.flow;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.List;
@ApiModel
public class VersionedReportingTaskSnapshot {
private List<VersionedReportingTask> reportingTasks;
private List<VersionedControllerService> controllerServices;
@ApiModelProperty(value = "The controller services")
public List<VersionedControllerService> getControllerServices() {
return controllerServices;
}
public void setControllerServices(List<VersionedControllerService> controllerServices) {
this.controllerServices = controllerServices;
}
@ApiModelProperty(value = "The reporting tasks")
public List<VersionedReportingTask> getReportingTasks() {
return reportingTasks;
}
public void setReportingTasks(List<VersionedReportingTask> reportingTasks) {
this.reportingTasks = reportingTasks;
}
}

View File

@ -615,8 +615,9 @@ public class NiFiRegistryFlowMapper {
continue;
}
// if mapping a reporting task, serviceGroupId will be null and we don't want to produce external service references
final String serviceGroupId = serviceNode.getProcessGroupIdentifier();
if (!includedGroupIds.contains(serviceGroupId)) {
if (serviceGroupId != null && !includedGroupIds.contains(serviceGroupId)) {
final String serviceId = getId(serviceNode.getVersionedComponentId(), serviceNode.getIdentifier());
final ExternalControllerServiceReference controllerServiceReference = new ExternalControllerServiceReference();

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.controller.serialization;
import org.apache.nifi.controller.ReportingTaskNode;
import org.apache.nifi.controller.service.ControllerServiceNode;
import org.apache.nifi.controller.service.ControllerServiceProvider;
import org.apache.nifi.flow.VersionedControllerService;
import org.apache.nifi.flow.VersionedReportingTask;
import org.apache.nifi.flow.VersionedReportingTaskSnapshot;
import org.apache.nifi.nar.ExtensionManager;
import org.apache.nifi.registry.flow.mapping.NiFiRegistryFlowMapper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
public class VersionedReportingTaskSnapshotMapper {
private final NiFiRegistryFlowMapper flowMapper;
private final ControllerServiceProvider controllerServiceProvider;
public VersionedReportingTaskSnapshotMapper(final ExtensionManager extensionManager, final ControllerServiceProvider controllerServiceProvider) {
this.flowMapper = new NiFiRegistryFlowMapper(extensionManager);
this.controllerServiceProvider = controllerServiceProvider;
}
public VersionedReportingTaskSnapshot createMapping(final Set<ReportingTaskNode> reportingTaskNodes, final Set<ControllerServiceNode> controllerServiceNodes) {
final VersionedReportingTaskSnapshot versionedReportingTaskSnapshot = new VersionedReportingTaskSnapshot();
versionedReportingTaskSnapshot.setReportingTasks(mapReportingTasks(reportingTaskNodes));
versionedReportingTaskSnapshot.setControllerServices(mapControllerServices(controllerServiceNodes));
return versionedReportingTaskSnapshot;
}
private List<VersionedReportingTask> mapReportingTasks(final Set<ReportingTaskNode> reportingTaskNodes) {
final List<VersionedReportingTask> reportingTasks = new ArrayList<>();
for (final ReportingTaskNode taskNode : reportingTaskNodes) {
final VersionedReportingTask versionedReportingTask = flowMapper.mapReportingTask(taskNode, controllerServiceProvider);
reportingTasks.add(versionedReportingTask);
}
return reportingTasks;
}
private List<VersionedControllerService> mapControllerServices(final Set<ControllerServiceNode> controllerServiceNodes) {
final List<VersionedControllerService> controllerServices = new ArrayList<>();
for (final ControllerServiceNode serviceNode : controllerServiceNodes) {
final VersionedControllerService versionedControllerService = flowMapper.mapControllerService(
serviceNode, controllerServiceProvider, Collections.emptySet(), Collections.emptyMap());
controllerServices.add(versionedControllerService);
}
return controllerServices;
}
}

View File

@ -29,6 +29,7 @@ import org.apache.nifi.controller.service.ControllerServiceState;
import org.apache.nifi.diagnostics.DiagnosticLevel;
import org.apache.nifi.flow.ExternalControllerServiceReference;
import org.apache.nifi.flow.ParameterProviderReference;
import org.apache.nifi.flow.VersionedReportingTaskSnapshot;
import org.apache.nifi.flow.VersionedParameterContext;
import org.apache.nifi.flow.VersionedProcessGroup;
import org.apache.nifi.groups.ProcessGroup;
@ -317,6 +318,21 @@ public interface NiFiServiceFacade {
*/
ControllerConfigurationEntity getControllerConfiguration();
/**
* Gets the snapshot for the given reporting task.
*
* @param reportingTaskId the id of the reporting task to get the snapshot for
* @return the reporting task snapshot
*/
VersionedReportingTaskSnapshot getVersionedReportingTaskSnapshot(String reportingTaskId);
/**
* Gets the snapshot of all reporting tasks.
*
* @return the reporting task snapshot
*/
VersionedReportingTaskSnapshot getVersionedReportingTaskSnapshot();
/**
* Gets the controller level bulletins.
*

View File

@ -91,7 +91,9 @@ import org.apache.nifi.controller.leader.election.LeaderElectionManager;
import org.apache.nifi.controller.repository.FlowFileEvent;
import org.apache.nifi.controller.repository.FlowFileEventRepository;
import org.apache.nifi.controller.repository.claim.ContentDirection;
import org.apache.nifi.controller.serialization.VersionedReportingTaskSnapshotMapper;
import org.apache.nifi.controller.service.ControllerServiceNode;
import org.apache.nifi.controller.service.ControllerServiceProvider;
import org.apache.nifi.controller.service.ControllerServiceReference;
import org.apache.nifi.controller.service.ControllerServiceState;
import org.apache.nifi.controller.status.ProcessGroupStatus;
@ -113,6 +115,7 @@ import org.apache.nifi.flow.VersionedExternalFlowMetadata;
import org.apache.nifi.flow.VersionedFlowCoordinates;
import org.apache.nifi.flow.VersionedParameterContext;
import org.apache.nifi.flow.VersionedProcessGroup;
import org.apache.nifi.flow.VersionedReportingTaskSnapshot;
import org.apache.nifi.groups.ProcessGroup;
import org.apache.nifi.groups.ProcessGroupCounts;
import org.apache.nifi.groups.RemoteProcessGroup;
@ -4150,6 +4153,52 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
return entityFactory.createControllerConfigurationEntity(dto, revision, permissions);
}
@Override
public VersionedReportingTaskSnapshot getVersionedReportingTaskSnapshot(final String reportingTaskId) {
final NiFiUser user = NiFiUserUtils.getNiFiUser();
final ReportingTaskNode reportingTaskNode = reportingTaskDAO.getReportingTask(reportingTaskId);
return getVersionedReportingTaskSnapshot(Collections.singleton(reportingTaskNode), user);
}
@Override
public VersionedReportingTaskSnapshot getVersionedReportingTaskSnapshot() {
final NiFiUser user = NiFiUserUtils.getNiFiUser();
final Set<ReportingTaskNode> reportingTaskNodes = reportingTaskDAO.getReportingTasks();
return getVersionedReportingTaskSnapshot(reportingTaskNodes, user);
}
private VersionedReportingTaskSnapshot getVersionedReportingTaskSnapshot(final Set<ReportingTaskNode> reportingTaskNodes, final NiFiUser user) {
final Set<ControllerServiceNode> serviceNodes = new HashSet<>();
reportingTaskNodes.forEach(reportingTaskNode -> {
reportingTaskNode.authorize(authorizer, RequestAction.READ, user);
findReferencedControllerServices(reportingTaskNode, serviceNodes, user);
});
final ExtensionManager extensionManager = controllerFacade.getExtensionManager();
final ControllerServiceProvider serviceProvider = controllerFacade.getControllerServiceProvider();
final VersionedReportingTaskSnapshotMapper snapshotMapper = new VersionedReportingTaskSnapshotMapper(extensionManager, serviceProvider);
return snapshotMapper.createMapping(reportingTaskNodes, serviceNodes);
}
private void findReferencedControllerServices(final ComponentNode componentNode, final Set<ControllerServiceNode> serviceNodes, final NiFiUser user) {
componentNode.getPropertyDescriptors().forEach(descriptor -> {
if (descriptor.getControllerServiceDefinition() != null) {
final String serviceId = componentNode.getEffectivePropertyValue(descriptor);
if (serviceId != null) {
try {
final ControllerServiceNode serviceNode = controllerServiceDAO.getControllerService(serviceId);
serviceNode.authorize(authorizer, RequestAction.READ, user);
if (serviceNodes.add(serviceNode)) {
findReferencedControllerServices(serviceNode, serviceNodes, user);
}
} catch (ResourceNotFoundException e) {
// ignore if the resource is not found, if the referenced service was previously deleted, it should not stop this action
}
}
}
});
}
@Override
public ControllerBulletinsEntity getControllerBulletins() {
final NiFiUser user = NiFiUserUtils.getNiFiUser();

View File

@ -26,38 +26,6 @@ import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.Authorization;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authorization.Authorizer;
import org.apache.nifi.authorization.RequestAction;
@ -77,6 +45,7 @@ import org.apache.nifi.controller.ScheduledState;
import org.apache.nifi.controller.service.ControllerServiceNode;
import org.apache.nifi.controller.service.ControllerServiceState;
import org.apache.nifi.flow.ExecutionEngine;
import org.apache.nifi.flow.VersionedReportingTaskSnapshot;
import org.apache.nifi.groups.ProcessGroup;
import org.apache.nifi.nar.NarClassLoadersHolder;
import org.apache.nifi.registry.client.NiFiRegistryException;
@ -159,6 +128,41 @@ import org.apache.nifi.web.api.request.FlowMetricsRegistry;
import org.apache.nifi.web.api.request.IntegerParameter;
import org.apache.nifi.web.api.request.LongParameter;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import java.text.Collator;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.apache.nifi.web.api.entity.ScheduleComponentsEntity.STATE_DISABLED;
import static org.apache.nifi.web.api.entity.ScheduleComponentsEntity.STATE_ENABLED;
@ -178,6 +182,9 @@ public class FlowResource extends ApplicationResource {
private static final String NIFI_REGISTRY_TYPE = "org.apache.nifi.registry.flow.NifiRegistryFlowRegistryClient";
private static final String RECURSIVE = "false";
private static final String VERSIONED_REPORTING_TASK_SNAPSHOT_FILENAME_PATTERN = "VersionedReportingTaskSnapshot-%s.json";
private static final String VERSIONED_REPORTING_TASK_SNAPSHOT_DATE_FORMAT = "yyyyMMddHHmmss";
private NiFiServiceFacade serviceFacade;
private Authorizer authorizer;
@ -680,6 +687,86 @@ public class FlowResource extends ApplicationResource {
return generateOkResponse(entity).build();
}
/**
* Gets a snapshot of reporting tasks.
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("reporting-tasks/snapshot")
@ApiOperation(
value = "Get a snapshot of the given reporting tasks and any controller services they use",
response = VersionedReportingTaskSnapshot.class,
authorizations = {
@Authorization(value = "Read - /flow")
}
)
@ApiResponses(
value = {
@ApiResponse(code = 401, message = "Client could not be authenticated."),
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
}
)
public Response getReportingTaskSnapshot(
@ApiParam(value = "Specifies a reporting task id to export. If not specified, all reporting tasks will be exported.")
@QueryParam("reportingTaskId") final String reportingTaskId
) {
authorizeFlow();
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
}
final VersionedReportingTaskSnapshot snapshot = reportingTaskId == null
? serviceFacade.getVersionedReportingTaskSnapshot() :
serviceFacade.getVersionedReportingTaskSnapshot(reportingTaskId);
return generateOkResponse(snapshot).build();
}
/**
* Downloads a snapshot of reporting tasks.
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("reporting-tasks/download")
@ApiOperation(
value = "Download a snapshot of the given reporting tasks and any controller services they use",
response = byte[].class,
authorizations = {
@Authorization(value = "Read - /flow")
}
)
@ApiResponses(
value = {
@ApiResponse(code = 401, message = "Client could not be authenticated."),
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
}
)
public Response downloadReportingTaskSnapshot(
@ApiParam(value = "Specifies a reporting task id to export. If not specified, all reporting tasks will be exported.")
@QueryParam("reportingTaskId") final String reportingTaskId
) {
authorizeFlow();
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
}
final VersionedReportingTaskSnapshot snapshot = reportingTaskId == null
? serviceFacade.getVersionedReportingTaskSnapshot() :
serviceFacade.getVersionedReportingTaskSnapshot(reportingTaskId);
final SimpleDateFormat dateFormat = new SimpleDateFormat(VERSIONED_REPORTING_TASK_SNAPSHOT_DATE_FORMAT);
final String filename = VERSIONED_REPORTING_TASK_SNAPSHOT_FILENAME_PATTERN.formatted(dateFormat.format(new Date()));
return generateOkResponse(snapshot).header(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment; filename=\"%s\"", filename)).build();
}
/**
* Updates the specified process group.
*

View File

@ -16,6 +16,7 @@
*/
package org.apache.nifi.toolkit.cli.impl.client.nifi;
import org.apache.nifi.flow.VersionedReportingTaskSnapshot;
import org.apache.nifi.web.api.entity.ActivateControllerServicesEntity;
import org.apache.nifi.web.api.entity.ClusteSummaryEntity;
import org.apache.nifi.web.api.entity.ConnectionStatusEntity;
@ -122,6 +123,20 @@ public interface FlowClient {
*/
ReportingTasksEntity getReportingTasks() throws NiFiClientException, IOException;
/**
* Retrieves the snapshot of all reporting tasks and their respective controller services.
*
* @return the snapshot
*/
VersionedReportingTaskSnapshot getReportingTaskSnapshot() throws NiFiClientException, IOException;
/**
* Retrieves the snapshot of the given reporting task and it's respective controller services.
*
* @return the snapshot
*/
VersionedReportingTaskSnapshot getReportingTaskSnapshot(String reportingTaskId) throws NiFiClientException, IOException;
/**
* Retrieves the parameter providers.
*

View File

@ -17,6 +17,7 @@
package org.apache.nifi.toolkit.cli.impl.client.nifi.impl;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.flow.VersionedReportingTaskSnapshot;
import org.apache.nifi.toolkit.cli.impl.client.nifi.FlowClient;
import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
import org.apache.nifi.toolkit.cli.impl.client.nifi.ProcessGroupBox;
@ -246,6 +247,23 @@ public class JerseyFlowClient extends AbstractJerseyClient implements FlowClient
});
}
@Override
public VersionedReportingTaskSnapshot getReportingTaskSnapshot() throws NiFiClientException, IOException {
return executeAction("Error retrieving reporting tasks", () -> {
final WebTarget target = flowTarget.path("reporting-tasks/snapshot");
return getRequestBuilder(target).get(VersionedReportingTaskSnapshot.class);
});
}
@Override
public VersionedReportingTaskSnapshot getReportingTaskSnapshot(final String reportingTaskId) throws NiFiClientException, IOException {
return executeAction("Error retrieving reporting task", () -> {
final WebTarget target = flowTarget.path("reporting-tasks/snapshot")
.queryParam("reportingTaskId", reportingTaskId);
return getRequestBuilder(target).get(VersionedReportingTaskSnapshot.class);
});
}
@Override
public ParameterProvidersEntity getParamProviders() throws NiFiClientException, IOException {
return executeAction("Error retrieving parameter providers", () -> {

View File

@ -29,6 +29,8 @@ import org.apache.nifi.toolkit.cli.impl.command.nifi.cs.GetControllerServices;
import org.apache.nifi.toolkit.cli.impl.command.nifi.flow.ClusterSummary;
import org.apache.nifi.toolkit.cli.impl.command.nifi.flow.CreateReportingTask;
import org.apache.nifi.toolkit.cli.impl.command.nifi.flow.CurrentUser;
import org.apache.nifi.toolkit.cli.impl.command.nifi.flow.ExportReportingTask;
import org.apache.nifi.toolkit.cli.impl.command.nifi.flow.ExportReportingTasks;
import org.apache.nifi.toolkit.cli.impl.command.nifi.flow.GetControllerConfiguration;
import org.apache.nifi.toolkit.cli.impl.command.nifi.flow.GetReportingTask;
import org.apache.nifi.toolkit.cli.impl.command.nifi.flow.GetReportingTasks;
@ -150,6 +152,8 @@ public class NiFiCommandGroup extends AbstractCommandGroup {
commands.add(new DeleteReportingTask());
commands.add(new StartReportingTasks());
commands.add(new StopReportingTasks());
commands.add(new ExportReportingTasks());
commands.add(new ExportReportingTask());
commands.add(new ListUsers());
commands.add(new CreateUser());
commands.add(new ListUserGroups());

View File

@ -0,0 +1,67 @@
/*
* 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.flow;
import org.apache.commons.cli.MissingOptionException;
import org.apache.nifi.flow.VersionedReportingTaskSnapshot;
import org.apache.nifi.toolkit.cli.api.CommandException;
import org.apache.nifi.toolkit.cli.api.Context;
import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
import org.apache.nifi.toolkit.cli.impl.result.nifi.VersionedReportingTaskSnapshotResult;
import java.io.IOException;
import java.util.Properties;
public class ExportReportingTask extends AbstractNiFiCommand<VersionedReportingTaskSnapshotResult> {
public ExportReportingTask() {
super("export-reporting-task", VersionedReportingTaskSnapshotResult.class);
}
@Override
public void doInitialize(final Context context) {
addOption(CommandOption.RT_ID.createOption());
addOption(CommandOption.OUTPUT_FILE.createOption());
}
@Override
public String getDescription() {
return "Exports a snapshot of the specified reporting task and any management controller services used by the reporting task. " +
" The --" + CommandOption.OUTPUT_FILE.getLongName() + " can be used to export to a file, " +
"otherwise the content will be written to terminal or standard out.";
}
@Override
public VersionedReportingTaskSnapshotResult doExecute(final NiFiClient client, final Properties properties) throws NiFiClientException, IOException, MissingOptionException, CommandException {
final String reportingTaskId = getRequiredArg(properties, CommandOption.RT_ID);
final VersionedReportingTaskSnapshot snapshot = client.getFlowClient().getReportingTaskSnapshot(reportingTaskId);
// currently export doesn't use the ResultWriter concept, it always writes JSON
// destination will be a file if outputFile is specified, otherwise it will be the output stream of the CLI
final String outputFile;
if (properties.containsKey(CommandOption.OUTPUT_FILE.getLongName())) {
outputFile = properties.getProperty(CommandOption.OUTPUT_FILE.getLongName());
} else {
outputFile = null;
}
return new VersionedReportingTaskSnapshotResult(snapshot, outputFile);
}
}

View File

@ -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.command.nifi.flow;
import org.apache.commons.cli.MissingOptionException;
import org.apache.nifi.flow.VersionedReportingTaskSnapshot;
import org.apache.nifi.toolkit.cli.api.CommandException;
import org.apache.nifi.toolkit.cli.api.Context;
import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClient;
import org.apache.nifi.toolkit.cli.impl.client.nifi.NiFiClientException;
import org.apache.nifi.toolkit.cli.impl.command.CommandOption;
import org.apache.nifi.toolkit.cli.impl.command.nifi.AbstractNiFiCommand;
import org.apache.nifi.toolkit.cli.impl.result.nifi.VersionedReportingTaskSnapshotResult;
import java.io.IOException;
import java.util.Properties;
public class ExportReportingTasks extends AbstractNiFiCommand<VersionedReportingTaskSnapshotResult> {
public ExportReportingTasks() {
super("export-reporting-tasks", VersionedReportingTaskSnapshotResult.class);
}
@Override
public void doInitialize(final Context context) {
addOption(CommandOption.OUTPUT_FILE.createOption());
}
@Override
public String getDescription() {
return "Exports a snapshot of all reporting tasks and any management controller services used by the reporting tasks. " +
" The --" + CommandOption.OUTPUT_FILE.getLongName() + " can be used to export to a file, " +
"otherwise the content will be written to terminal or standard out.";
}
@Override
public VersionedReportingTaskSnapshotResult doExecute(final NiFiClient client, final Properties properties) throws NiFiClientException, IOException, MissingOptionException, CommandException {
final VersionedReportingTaskSnapshot snapshot = client.getFlowClient().getReportingTaskSnapshot();
// currently export doesn't use the ResultWriter concept, it always writes JSON
// destination will be a file if outputFile is specified, otherwise it will be the output stream of the CLI
final String outputFile;
if (properties.containsKey(CommandOption.OUTPUT_FILE.getLongName())) {
outputFile = properties.getProperty(CommandOption.OUTPUT_FILE.getLongName());
} else {
outputFile = null;
}
return new VersionedReportingTaskSnapshotResult(snapshot, outputFile);
}
}

View File

@ -0,0 +1,63 @@
/*
* 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.nifi;
import org.apache.nifi.flow.VersionedReportingTaskSnapshot;
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;
import java.util.Objects;
/**
* Result for a VersionedReportingTaskSnapshot.
*
* 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 VersionedReportingTaskSnapshotResult implements WritableResult<VersionedReportingTaskSnapshot> {
private final VersionedReportingTaskSnapshot versionedReportingTaskSnapshot;
private final String exportFileName;
public VersionedReportingTaskSnapshotResult(final VersionedReportingTaskSnapshot versionedReportingTaskSnapshot, final String exportFileName) {
this.versionedReportingTaskSnapshot = Objects.requireNonNull(versionedReportingTaskSnapshot);
this.exportFileName = exportFileName;
}
@Override
public VersionedReportingTaskSnapshot getResult() {
return versionedReportingTaskSnapshot;
}
@Override
public void write(final PrintStream output) throws IOException {
if (exportFileName != null) {
try (final OutputStream resultOut = new FileOutputStream(exportFileName)) {
JacksonUtils.write(versionedReportingTaskSnapshot, resultOut);
}
} else {
JacksonUtils.write(versionedReportingTaskSnapshot, output);
}
}
}