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

HDDS-4117. Normalize Keypath for listKeys. #1451

Merged
merged 5 commits into from Oct 28, 2020

Conversation

bharatviswa504
Copy link
Contributor

What changes were proposed in this pull request?

Normalize Keypath for listKeys.
When ozone.om.enable.filesystem.paths, OM normalizes path, and stores the Keyname in the OM DB KeyTable.

When listKeys uses given keyName(not normalized key path) as prefix and Starkey the list-keys will return an empty results.

Similar to HDDS-4102, we should normalize Starkey and keyPrefix.

What is the link to the Apache JIRA

https://issues.apache.org/jira/browse/HDDS-4117

How was this patch tested?

Added a test.

@bharatviswa504 bharatviswa504 changed the title Hdds 4117 HDDS-4117. Normalize Keypath for listKeys. Sep 29, 2020
@bharatviswa504
Copy link
Contributor Author

Rebased and fixed test.

Copy link
Member

@elek elek left a comment

Choose a reason for hiding this comment

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

Thanks @bharatviswa504

Overall it looks good to me. It turns out the key normalization only of enableFileSystemPaths is turned on.

I have a few questions inline about the implementation (seems to be possible to make it more simple)

Comment on lines 924 to 925
startKey = normalizeListKeyPath(startKey);
keyPrefix = normalizeListKeyPath(keyPrefix);
Copy link
Member

Choose a reason for hiding this comment

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

NIT:

I think it's easier to follow to move the condition to here:

     if (enableFileSystemPaths) {
       startKey = normalizeListKeyPath(startKey);
       keyPrefix = normalizeListKeyPath(keyPrefix);
    }

Despite the name, the startKey and keyPrefix are not normalized if enableFileSystemPaths is false

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As anyway this condition needs to be checked inside normalizeListKeyPath, so not performed check again here.

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, I don't get it. Why do we need to check it inside normalizeListKeyPath.

As I wrote it's a very minor thing, but it seems to be better to move out the check from the method because it improves the readability (IMHO!).

When somebody read the listKeys method it suggest the the keys are normalized. but in fact it's normalized only if enableFileSystemPaths. This can be confusing as the method name is normalizeListKeyPath and not something like normalizeListKeyPathIfNormalizationIsEnabled.

I suggested moving out this condition from this method to improve the readibility, but if you think it's a bad idea, it can be ignored.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks to explain it. I understood your point. Updated the code.

String normalizeKeyPath = keyPath;
if (enableFileSystemPaths) {
// For empty strings do nothing.
if (StringUtils.isBlank(keyPath)) {
Copy link
Member

Choose a reason for hiding this comment

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

Is there any reason to keep these two features (return empty string for empty string + keep closing /) in here intead of moving to OmUtils.normalizeKey(keyPath)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For key ending with "/" after normalizing it will return the key without trailing "/". As here the key intended to be searched is, I have added it back here. In my view removing "/" at the end when the user explicitly asked to search for keys end with "/", it might return results differently, as I don't want to change current semantics.

Example:
the prefix is "/a/b/c/d/" -> after Normalize "/a/b/c/d"
So if we don't add "/" back, it will return keys with prefix "/a/b/c/d", but user intention here is to get keys in "/a/b/c/d/" so not to change semantics for this case handled in this method instead of common method used by all classes.

And also for null not calling OmUtils.normalizeKey(keyPath), the Paths method will fail with NPE, so this is also considered a special case and handled it in this method.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks to explain it.

the Paths method will fail with NPE, so this is also

Not a big deal, but if we move the empty check, to normalizeKey, the method will be safe forever, and we don't need to do the empty check all the time when we need to call it.

Copy link
Member

Choose a reason for hiding this comment

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

BTW (just a discussion not a code review comment): it can be useful to differentiate between normalization (removing/resolving .., //) and handling closing /. My impression is that we need different rules for them.

This is a good example here: you need the first ("normalization") but not the second. (Maybe two different method?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for clear explanation, I have updated to move null check to normalizeKey method.

BTW (just a discussion not a code review comment): it can be useful to differentiate between normalization
(removing/resolving .., //) and handling closing /. My impression is that we need different rules for them.

Updated OmUtils.normalizeKey to take the boolean flag to preseverTralingSlash if true will preserve it. In this way, this method can be used in listKey case with true, rest all code with false. Have a look in to it, and share ur suggestions on the approach.

@bharatviswa504
Copy link
Contributor Author

Thank You @elek for the review.
I have addressed the review comments.

@rakeshadr
Copy link
Contributor

+1 LGTM
Thanks @bharatviswa504 for the contribution.

@bharatviswa504 bharatviswa504 merged commit 3861e77 into apache:master Oct 28, 2020
@bharatviswa504
Copy link
Contributor Author

Thank You @rakeshadr and @elek for the review.
@elek if you have any more comments, happy to address them in a new Jira.

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