Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NIFI-6872: support download flow #3931

Closed
wants to merge 2 commits into from
Closed

Conversation

jsferner
Copy link
Contributor

NIFI-6872:

  • Added UI versioned flow supportsDownload functionality with download flow menu item
  • Added VersionsResource endpoint for downloading versioned flow with registry-related info removed (not currently exposed in the UI since decision was made to support any flow for download, whether versioned or not)
  • Added ProcessGroupResource endpoint for downloading current flow with registry-related info removed
  • Added StandardNifiServiceFacade functionality for downloading both current and versioned flow
  • Added XmlTransient markers on variables introduced by Instantiated model classes so they do not appear in serialized download
  • Updated NiFiRegistryFlowMapper.mapParameterContexts to handle mapping nested parameter contexts for use in producing a complete VersionedFlowSnapshot
  • Added ability for NiFiRegistryFlowMapper to map nested process groups ignoring versioning for use in producing a complete VersionedFlowSnapshot
  • Added unit tests where helpful

- Added UI versioned flow supportsDownload functionality with download flow menu item
- Added VersionsResource endpoint for downloading versioned flow with registry-related info removed
- Added ProcessGroupResource endpoint for downloading current flow with registry-related info removed
- Added StandardNifiServiceFacade functionality for downloading both current and versioned flow
- Added XmlTransient markers on variables introduced by Instantiated model classes so they do not appear in serialized download
- Updated NiFiRegistryFlowMapper.mapParameterContexts to handle mapping nested parameter contexts for use in producing a complete VersionedFlowSnapshot
- Added ability for NiFiRegistryFlowMapper to map nested process groups ignoring versioning for use in producing a complete VersionedFlowSnapshot
- Added unit tests where helpful
Copy link
Contributor

@markap14 markap14 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @jsferner thanks for the contribution! This is awesome! I made a few minor stylistic comments but those are not a really big deal. You can ignore them if you disagree. The only thing I think needs to be changed is the comment made in the StandardNiFiServiceFacade regarding mapping of the Collection to a Map, which can contain duplicate keys and cause an IllegalStateException. Thanks for an awesome contribution!

}
}
// apply registry versioning according to the lambda below
// NOTE: lambda refers to registry client and map descendant boolean which will not change during recursion
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might read more clearly if this lambda were instead created as a method: boolean isMapDescendants(ProcessGroup processGroup, VersionedProcessGroup versionedGroup) and then referenced here as return mapGroup(group, serviceProvider, this::isMapDescendants). I think this would avoid having a lengthy lambda and obviate the need for documentation explaining the point of the lambda.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to make the lambda a separate method but it actually would require taking in 2 more arguments because it's currently referencing those arguments locally where it's defined inline (registryClient and mapDescendantVersionedFlows). The values of these args don't change during recursion, they just get passed down through so it made more sense to just reference them in the lambda rather than expect them to also be passed in when it's called. Does that make sense?

final Set<VersionedParameter> parameters = context.getParameters().values().stream()
.map(this::mapParameter)
.collect(Collectors.toSet());
public Collection<VersionedParameterContext> mapParameterContexts(final ProcessGroup processGroup, final boolean mapDescendantVersionedFlows) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am thinking out loud a bit here. I don't yet fully understand the entire context around where this will be used. But it seems to me anywhere that we would want a Collection of VersionedParameterContext it would probably make sense to restrict it to a Set<VersionedParameterContext>. Because we can certainly have the case where descendant Process Groups will reference the same ParameterContext as a parent/ancestor Process Group. I don't think we would actually want the context in the Collection multiple times, would we?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, moving everything to a Map to begin with, as we discussed

final boolean includeRemoteProcessGroup, final boolean includeVersionControlInfo,
final List<ProcessGroup> childProcessGroups) {
final String processGroupId = UUID.randomUUID().toString();
final ProcessGroup processGroup = mock(ProcessGroup.class);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like there's quite a lot of mocking going on here for the ProcessGroup. There already exists a MockProcessGroup class that may simplify this quite a bit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MockProcessGroup was limited in what it was implementing already so I couldn't use it without adding a ton more implementation. Since this mapper exercises almost all the elements of a process group, it was going to take quite a bit to make the MockProcessGroup usable.

final String expectedGroupIdentifier = flowMapper.getGroupId(processGroup.getProcessGroupIdentifier());

// verify process group fields
assertEquals(versionedProcessGroup.getName(), processGroup.getName());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a big deal, but I think all of these asserts are passing the arguments backwards. The signature is assertEquals(Object expected, Object actual) but it looks like all of these assertions are made such that the actual value is passed before the expected value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, updating all

// Create a complete (include descendant flows) map of parameter contexts
final Collection<VersionedParameterContext> parameterContexts =
mapper.mapParameterContexts(processGroup, true);
final Map<String, VersionedParameterContext> parameterContextMap = parameterContexts.stream()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above, about the creation of Collection<VersionedParameterContext> with regards to changing to a Set<VersionedParameterContext>. As this is currently written, if we have Group A with Parameter Context A, and a child group, Group B, also with Parameter Context A, this will result in the Collection<VersionedParameterContext> containing two VersionedParameterContext objects with the same name. This line of code will now throw an IllegalStateException because it will result in the Map that is being formed having duplicate keys.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, moving everything to a Map as we discussed

@markap14
Copy link
Contributor

Also noticed that Travis flagged 1 checkstyle violation:
[WARNING] src/main/java/org/apache/nifi/registry/flow/mapping/NiFiRegistryFlowMapper.java:[115,83] (blocks) LeftCurly: '{' at column 83 should have line break after.

@jsferner
Copy link
Contributor Author

Fixed checkstyle failure

@mcgilman
Copy link
Contributor

Will also have a look to review the front end changes...

*
* @param processGroupId
*/
downloadFlowVersion: function (processGroupId) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not appear to be invoked. I'd recommend removing it as it would need to be updated to support a One Time Password if we wanted to leave it in place.

}

if (processGroupId !== null) {
window.open('../nifi-api/process-groups/' + encodeURIComponent(processGroupId) + '/download');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For when the user is authenticated and leveraging a token that is presented in a HTTP header, we need to update this endpoint to utilize a One Time Password which is included in a query parameter. This is necessary because the code that adds the token to the header down not execute within the new window from the window.open call.

Please check out provenance download or content download for an example.

- Updated mapParameterContext to return a Map to handle uniqueness of contexts by name since ultimately everything converted it to a map anyway. The VersionedParameterContext class from the registry model doesn't support hashcode/equals currently so returning a Set wouldn't work.
- Updated assert calls to put expected value as first parameter and actual as second parameter
- Added one time password (OTP) support for flow download endpoint to support non cert based authentication
@markap14
Copy link
Contributor

Thanks for the update @jsferner ! The code looks good from my perspective. I haven't had a chance yet to test with the update, though. Once I can test and verify behavior I'm a +1. Or if you have a chance to verify behavior, @mcgilman, feel free to merge it in if you're happy with the update as well.

@asfgit asfgit closed this in 0588830 Dec 18, 2019
@mcgilman
Copy link
Contributor

Thanks @jsferner for the PR. This has been merged to master!
Thanks @markap14 for the review help!

patricker pushed a commit to patricker/nifi that referenced this pull request Jan 22, 2020
- Added UI versioned flow supportsDownload functionality with download flow menu item
- Added VersionsResource endpoint for downloading versioned flow with registry-related info removed
- Added ProcessGroupResource endpoint for downloading current flow with registry-related info removed
- Added StandardNifiServiceFacade functionality for downloading both current and versioned flow
- Added XmlTransient markers on variables introduced by Instantiated model classes so they do not appear in serialized download
- Updated NiFiRegistryFlowMapper.mapParameterContexts to handle mapping nested parameter contexts for use in producing a complete VersionedFlowSnapshot
- Added ability for NiFiRegistryFlowMapper to map nested process groups ignoring versioning for use in producing a complete VersionedFlowSnapshot
- Added unit tests where helpful

NIFI-6872: PR response...
- Updated mapParameterContext to return a Map to handle uniqueness of contexts by name since ultimately everything converted it to a map anyway. The VersionedParameterContext class from the registry model doesn't support hashcode/equals currently so returning a Set wouldn't work.
- Updated assert calls to put expected value as first parameter and actual as second parameter
- Added one time password (OTP) support for flow download endpoint to support non cert based authentication

This closes apache#3931
natural pushed a commit to natural/nifi that referenced this pull request Feb 1, 2020
- Added UI versioned flow supportsDownload functionality with download flow menu item
- Added VersionsResource endpoint for downloading versioned flow with registry-related info removed
- Added ProcessGroupResource endpoint for downloading current flow with registry-related info removed
- Added StandardNifiServiceFacade functionality for downloading both current and versioned flow
- Added XmlTransient markers on variables introduced by Instantiated model classes so they do not appear in serialized download
- Updated NiFiRegistryFlowMapper.mapParameterContexts to handle mapping nested parameter contexts for use in producing a complete VersionedFlowSnapshot
- Added ability for NiFiRegistryFlowMapper to map nested process groups ignoring versioning for use in producing a complete VersionedFlowSnapshot
- Added unit tests where helpful

NIFI-6872: PR response...
- Updated mapParameterContext to return a Map to handle uniqueness of contexts by name since ultimately everything converted it to a map anyway. The VersionedParameterContext class from the registry model doesn't support hashcode/equals currently so returning a Set wouldn't work.
- Updated assert calls to put expected value as first parameter and actual as second parameter
- Added one time password (OTP) support for flow download endpoint to support non cert based authentication

This closes apache#3931
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants