use of org.apache.nifi.web.api.entity.ProcessGroupEntity in project nifi by apache.
the class FlowResource method populateRemainingFlowStructure.
/**
* Populates the remaining content of the specified snippet.
*/
private FlowDTO populateRemainingFlowStructure(FlowDTO flowStructure) {
processorResource.populateRemainingProcessorEntitiesContent(flowStructure.getProcessors());
connectionResource.populateRemainingConnectionEntitiesContent(flowStructure.getConnections());
inputPortResource.populateRemainingInputPortEntitiesContent(flowStructure.getInputPorts());
outputPortResource.populateRemainingOutputPortEntitiesContent(flowStructure.getOutputPorts());
remoteProcessGroupResource.populateRemainingRemoteProcessGroupEntitiesContent(flowStructure.getRemoteProcessGroups());
funnelResource.populateRemainingFunnelEntitiesContent(flowStructure.getFunnels());
labelResource.populateRemainingLabelEntitiesContent(flowStructure.getLabels());
processGroupResource.populateRemainingProcessGroupEntitiesContent(flowStructure.getProcessGroups());
// go through each process group child and populate its uri
for (final ProcessGroupEntity processGroupEntity : flowStructure.getProcessGroups()) {
final ProcessGroupDTO processGroup = processGroupEntity.getComponent();
if (processGroup != null) {
processGroup.setContents(null);
}
}
return flowStructure;
}
use of org.apache.nifi.web.api.entity.ProcessGroupEntity in project nifi by apache.
the class ProcessGroupResource method instantiateTemplate.
/**
* Instantiates the specified template within this ProcessGroup. The template instance that is instantiated cannot be referenced at a later time, therefore there is no
* corresponding URI. Instead the request URI is returned.
* <p>
* Alternatively, we could have performed a PUT request. However, PUT requests are supposed to be idempotent and this endpoint is certainly not.
*
* @param httpServletRequest request
* @param groupId The group id
* @param requestInstantiateTemplateRequestEntity The instantiate template request
* @return A flowEntity.
*/
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("{id}/template-instance")
@ApiOperation(value = "Instantiates a template", response = FlowEntity.class, authorizations = { @Authorization(value = "Write - /process-groups/{uuid}"), @Authorization(value = "Read - /templates/{uuid}"), @Authorization(value = "Write - if the template contains any restricted components - /restricted-components") })
@ApiResponses(value = { @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), @ApiResponse(code = 401, message = "Client could not be authenticated."), @ApiResponse(code = 403, message = "Client is not authorized to make this request."), @ApiResponse(code = 404, message = "The specified resource could not be found."), @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 instantiateTemplate(@Context HttpServletRequest httpServletRequest, @ApiParam(value = "The process group id.", required = true) @PathParam("id") String groupId, @ApiParam(value = "The instantiate template request.", required = true) InstantiateTemplateRequestEntity requestInstantiateTemplateRequestEntity) {
// ensure the position has been specified
if (requestInstantiateTemplateRequestEntity == null || requestInstantiateTemplateRequestEntity.getOriginX() == null || requestInstantiateTemplateRequestEntity.getOriginY() == null) {
throw new IllegalArgumentException("The origin position (x, y) must be specified.");
}
// ensure the template id was provided
if (requestInstantiateTemplateRequestEntity.getTemplateId() == null) {
throw new IllegalArgumentException("The template id must be specified.");
}
// ensure the template encoding version is valid
if (requestInstantiateTemplateRequestEntity.getEncodingVersion() != null) {
try {
FlowEncodingVersion.parse(requestInstantiateTemplateRequestEntity.getEncodingVersion());
} catch (final IllegalArgumentException e) {
throw new IllegalArgumentException("The template encoding version is not valid. The expected format is <number>.<number>");
}
}
// populate the encoding version if necessary
if (requestInstantiateTemplateRequestEntity.getEncodingVersion() == null) {
// if the encoding version is not specified, use the latest encoding version as these options were
// not available pre 1.x, will be overridden if populating from the underlying template below
requestInstantiateTemplateRequestEntity.setEncodingVersion(TemplateDTO.MAX_ENCODING_VERSION);
}
// populate the component bundles if necessary
if (requestInstantiateTemplateRequestEntity.getSnippet() == null) {
// get the desired template in order to determine the supported bundles
final TemplateDTO requestedTemplate = serviceFacade.exportTemplate(requestInstantiateTemplateRequestEntity.getTemplateId());
final FlowSnippetDTO requestTemplateContents = requestedTemplate.getSnippet();
// determine the compatible bundles to use for each component in this template, this ensures the nodes in the cluster
// instantiate the components from the same bundles
discoverCompatibleBundles(requestTemplateContents);
// update the requested template as necessary - use the encoding version from the underlying template
requestInstantiateTemplateRequestEntity.setEncodingVersion(requestedTemplate.getEncodingVersion());
requestInstantiateTemplateRequestEntity.setSnippet(requestTemplateContents);
}
if (isReplicateRequest()) {
return replicate(HttpMethod.POST, requestInstantiateTemplateRequestEntity);
}
return withWriteLock(serviceFacade, requestInstantiateTemplateRequestEntity, lookup -> {
final NiFiUser user = NiFiUserUtils.getNiFiUser();
// ensure write on the group
final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.WRITE, user);
final Authorizable template = lookup.getTemplate(requestInstantiateTemplateRequestEntity.getTemplateId());
template.authorize(authorizer, RequestAction.READ, user);
// ensure read on the template
final TemplateContentsAuthorizable templateContents = lookup.getTemplateContents(requestInstantiateTemplateRequestEntity.getSnippet());
final Consumer<ComponentAuthorizable> authorizeRestricted = authorizable -> {
if (authorizable.isRestricted()) {
authorizeRestrictions(authorizer, authorizable);
}
};
// ensure restricted access if necessary
templateContents.getEncapsulatedProcessors().forEach(authorizeRestricted);
templateContents.getEncapsulatedControllerServices().forEach(authorizeRestricted);
}, () -> serviceFacade.verifyComponentTypes(requestInstantiateTemplateRequestEntity.getSnippet()), instantiateTemplateRequestEntity -> {
// create the template and generate the json
final FlowEntity entity = serviceFacade.createTemplateInstance(groupId, instantiateTemplateRequestEntity.getOriginX(), instantiateTemplateRequestEntity.getOriginY(), instantiateTemplateRequestEntity.getEncodingVersion(), instantiateTemplateRequestEntity.getSnippet(), getIdGenerationSeed().orElse(null));
final FlowDTO flowSnippet = entity.getFlow();
// prune response as necessary
for (ProcessGroupEntity childGroupEntity : flowSnippet.getProcessGroups()) {
childGroupEntity.getComponent().setContents(null);
}
// create the response entity
populateRemainingSnippetContent(flowSnippet);
// generate the response
return generateCreatedResponse(getAbsolutePath(), entity).build();
});
}
use of org.apache.nifi.web.api.entity.ProcessGroupEntity in project nifi by apache.
the class ProcessGroupResource method getProcessGroup.
/**
* Retrieves the contents of the specified group.
*
* @param groupId The id of the process group.
* @return A processGroupEntity.
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("{id}")
@ApiOperation(value = "Gets a process group", response = ProcessGroupEntity.class, authorizations = { @Authorization(value = "Read - /process-groups/{uuid}") })
@ApiResponses(value = { @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), @ApiResponse(code = 401, message = "Client could not be authenticated."), @ApiResponse(code = 403, message = "Client is not authorized to make this request."), @ApiResponse(code = 404, message = "The specified resource could not be found."), @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 getProcessGroup(@ApiParam(value = "The process group id.", required = false) @PathParam("id") final String groupId) {
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
}
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
});
// get this process group contents
final ProcessGroupEntity entity = serviceFacade.getProcessGroup(groupId);
populateRemainingProcessGroupEntityContent(entity);
if (entity.getComponent() != null) {
entity.getComponent().setContents(null);
}
return generateOkResponse(entity).build();
}
use of org.apache.nifi.web.api.entity.ProcessGroupEntity in project nifi by apache.
the class ProcessGroupResource method createProcessGroup.
/**
* Adds the specified process group.
*
* @param httpServletRequest request
* @param groupId The group id
* @param requestProcessGroupEntity A processGroupEntity
* @return A processGroupEntity
* @throws IOException if the request indicates that the Process Group should be imported from a Flow Registry and NiFi is unable to communicate with the Flow Registry
*/
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("{id}/process-groups")
@ApiOperation(value = "Creates a process group", response = ProcessGroupEntity.class, authorizations = { @Authorization(value = "Write - /process-groups/{uuid}") })
@ApiResponses(value = { @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), @ApiResponse(code = 401, message = "Client could not be authenticated."), @ApiResponse(code = 403, message = "Client is not authorized to make this request."), @ApiResponse(code = 404, message = "The specified resource could not be found."), @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 createProcessGroup(@Context final HttpServletRequest httpServletRequest, @ApiParam(value = "The process group id.", required = true) @PathParam("id") final String groupId, @ApiParam(value = "The process group configuration details.", required = true) final ProcessGroupEntity requestProcessGroupEntity) throws IOException {
if (requestProcessGroupEntity == null || requestProcessGroupEntity.getComponent() == null) {
throw new IllegalArgumentException("Process group details must be specified.");
}
if (requestProcessGroupEntity.getRevision() == null || (requestProcessGroupEntity.getRevision().getVersion() == null || requestProcessGroupEntity.getRevision().getVersion() != 0)) {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Process group.");
}
if (requestProcessGroupEntity.getComponent().getId() != null) {
throw new IllegalArgumentException("Process group ID cannot be specified.");
}
final PositionDTO proposedPosition = requestProcessGroupEntity.getComponent().getPosition();
if (proposedPosition != null) {
if (proposedPosition.getX() == null || proposedPosition.getY() == null) {
throw new IllegalArgumentException("The x and y coordinate of the proposed position must be specified.");
}
}
// if the group name isn't specified, ensure the group is being imported from version control
if (StringUtils.isBlank(requestProcessGroupEntity.getComponent().getName()) && requestProcessGroupEntity.getComponent().getVersionControlInformation() == null) {
throw new IllegalArgumentException("The group name is required when the group is not imported from version control.");
}
if (requestProcessGroupEntity.getComponent().getParentGroupId() != null && !groupId.equals(requestProcessGroupEntity.getComponent().getParentGroupId())) {
throw new IllegalArgumentException(String.format("If specified, the parent process group id %s must be the same as specified in the URI %s", requestProcessGroupEntity.getComponent().getParentGroupId(), groupId));
}
requestProcessGroupEntity.getComponent().setParentGroupId(groupId);
// Step 1: Ensure that user has write permissions to the Process Group. If not, then immediately fail.
// Step 2: Retrieve flow from Flow Registry
// Step 3: Resolve Bundle info
// Step 4: Update contents of the ProcessGroupDTO passed in to include the components that need to be added.
// Step 5: If any of the components is a Restricted Component, then we must authorize the user
// for write access to the RestrictedComponents resource
// Step 6: Replicate the request or call serviceFacade.updateProcessGroup
final VersionControlInformationDTO versionControlInfo = requestProcessGroupEntity.getComponent().getVersionControlInformation();
if (versionControlInfo != null && requestProcessGroupEntity.getVersionedFlowSnapshot() == null) {
// Step 1: Ensure that user has write permissions to the Process Group. If not, then immediately fail.
// Step 2: Retrieve flow from Flow Registry
final VersionedFlowSnapshot flowSnapshot = serviceFacade.getVersionedFlowSnapshot(versionControlInfo, true);
final Bucket bucket = flowSnapshot.getBucket();
final VersionedFlow flow = flowSnapshot.getFlow();
versionControlInfo.setBucketName(bucket.getName());
versionControlInfo.setFlowName(flow.getName());
versionControlInfo.setFlowDescription(flow.getDescription());
versionControlInfo.setRegistryName(serviceFacade.getFlowRegistryName(versionControlInfo.getRegistryId()));
final VersionedFlowState flowState = flowSnapshot.isLatest() ? VersionedFlowState.UP_TO_DATE : VersionedFlowState.STALE;
versionControlInfo.setState(flowState.name());
// Step 3: Resolve Bundle info
BundleUtils.discoverCompatibleBundles(flowSnapshot.getFlowContents());
// Step 4: Update contents of the ProcessGroupDTO passed in to include the components that need to be added.
requestProcessGroupEntity.setVersionedFlowSnapshot(flowSnapshot);
}
if (versionControlInfo != null) {
final VersionedFlowSnapshot flowSnapshot = requestProcessGroupEntity.getVersionedFlowSnapshot();
serviceFacade.verifyImportProcessGroup(versionControlInfo, flowSnapshot.getFlowContents(), groupId);
}
// Step 6: Replicate the request or call serviceFacade.updateProcessGroup
if (isReplicateRequest()) {
return replicate(HttpMethod.POST, requestProcessGroupEntity);
}
return withWriteLock(serviceFacade, requestProcessGroupEntity, lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
// Step 5: If any of the components is a Restricted Component, then we must authorize the user
// for write access to the RestrictedComponents resource
final VersionedFlowSnapshot versionedFlowSnapshot = requestProcessGroupEntity.getVersionedFlowSnapshot();
if (versionedFlowSnapshot != null) {
final Set<ConfigurableComponent> restrictedComponents = FlowRegistryUtils.getRestrictedComponents(versionedFlowSnapshot.getFlowContents());
restrictedComponents.forEach(restrictedComponent -> {
final ComponentAuthorizable restrictedComponentAuthorizable = lookup.getConfigurableComponent(restrictedComponent);
authorizeRestrictions(authorizer, restrictedComponentAuthorizable);
});
}
}, () -> {
final VersionedFlowSnapshot versionedFlowSnapshot = requestProcessGroupEntity.getVersionedFlowSnapshot();
if (versionedFlowSnapshot != null) {
serviceFacade.verifyComponentTypes(versionedFlowSnapshot.getFlowContents());
}
}, processGroupEntity -> {
final ProcessGroupDTO processGroup = processGroupEntity.getComponent();
// set the processor id as appropriate
processGroup.setId(generateUuid());
// ensure the group name comes from the versioned flow
final VersionedFlowSnapshot flowSnapshot = processGroupEntity.getVersionedFlowSnapshot();
if (flowSnapshot != null && StringUtils.isNotBlank(flowSnapshot.getFlowContents().getName()) && StringUtils.isBlank(processGroup.getName())) {
processGroup.setName(flowSnapshot.getFlowContents().getName());
}
// create the process group contents
final Revision revision = getRevision(processGroupEntity, processGroup.getId());
ProcessGroupEntity entity = serviceFacade.createProcessGroup(revision, groupId, processGroup);
if (flowSnapshot != null) {
final RevisionDTO revisionDto = entity.getRevision();
final String newGroupId = entity.getComponent().getId();
final Revision newGroupRevision = new Revision(revisionDto.getVersion(), revisionDto.getClientId(), newGroupId);
// We don't want the Process Group's position to be updated because we want to keep the position where the user
// placed the Process Group. However, we do want to use the name of the Process Group that is in the Flow Contents.
// To accomplish this, we call updateProcessGroupContents() passing 'true' for the updateSettings flag but null out the position.
flowSnapshot.getFlowContents().setPosition(null);
entity = serviceFacade.updateProcessGroupContents(NiFiUserUtils.getNiFiUser(), newGroupRevision, newGroupId, versionControlInfo, flowSnapshot, getIdGenerationSeed().orElse(null), false, true, true);
}
populateRemainingProcessGroupEntityContent(entity);
// generate a 201 created response
String uri = entity.getUri();
return generateCreatedResponse(URI.create(uri), entity).build();
});
}
use of org.apache.nifi.web.api.entity.ProcessGroupEntity in project nifi by apache.
the class PGImport method doExecute.
@Override
public StringResult doExecute(final NiFiClient client, final Properties properties) throws NiFiClientException, IOException, MissingOptionException {
final String bucketId = getRequiredArg(properties, CommandOption.BUCKET_ID);
final String flowId = getRequiredArg(properties, CommandOption.FLOW_ID);
final Integer flowVersion = getRequiredIntArg(properties, CommandOption.FLOW_VERSION);
// if a registry client is specified use it, otherwise see if there is only one available and use that,
// if more than one is available then throw an exception because we don't know which one to use
String registryId = getArg(properties, CommandOption.REGISTRY_CLIENT_ID);
if (StringUtils.isBlank(registryId)) {
final RegistryClientsEntity registries = client.getControllerClient().getRegistryClients();
final Set<RegistryClientEntity> entities = registries.getRegistries();
if (entities == null || entities.isEmpty()) {
throw new NiFiClientException("No registry clients available");
}
if (entities.size() == 1) {
registryId = entities.stream().findFirst().get().getId();
} else {
throw new MissingOptionException(CommandOption.REGISTRY_CLIENT_ID.getLongName() + " must be provided when there is more than one available");
}
}
// get the optional id of the parent PG, otherwise fallback to the root group
String parentPgId = getArg(properties, CommandOption.PG_ID);
if (StringUtils.isBlank(parentPgId)) {
final FlowClient flowClient = client.getFlowClient();
parentPgId = flowClient.getRootGroupId();
}
final VersionControlInformationDTO versionControlInfo = new VersionControlInformationDTO();
versionControlInfo.setRegistryId(registryId);
versionControlInfo.setBucketId(bucketId);
versionControlInfo.setFlowId(flowId);
versionControlInfo.setVersion(flowVersion);
final ProcessGroupBox pgBox = client.getFlowClient().getSuggestedProcessGroupCoordinates(parentPgId);
final PositionDTO posDto = new PositionDTO();
posDto.setX(Integer.valueOf(pgBox.getX()).doubleValue());
posDto.setY(Integer.valueOf(pgBox.getY()).doubleValue());
final ProcessGroupDTO pgDto = new ProcessGroupDTO();
pgDto.setVersionControlInformation(versionControlInfo);
pgDto.setPosition(posDto);
final ProcessGroupEntity pgEntity = new ProcessGroupEntity();
pgEntity.setComponent(pgDto);
pgEntity.setRevision(getInitialRevisionDTO());
final ProcessGroupClient pgClient = client.getProcessGroupClient();
final ProcessGroupEntity createdEntity = pgClient.createProcessGroup(parentPgId, pgEntity);
return new StringResult(createdEntity.getId(), getContext().isInteractive());
}
Aggregations