Skip to content

OAK-11640 : removed usage of ImmutableSet.builder#2212

Merged
rishabhdaim merged 3 commits intotrunkfrom
OAK-11640
Apr 9, 2025
Merged

OAK-11640 : removed usage of ImmutableSet.builder#2212
rishabhdaim merged 3 commits intotrunkfrom
OAK-11640

Conversation

@rishabhdaim
Copy link
Contributor

No description provided.

@github-actions
Copy link

github-actions bot commented Apr 7, 2025

Commit-Check ✔️

Copy link
Member

@thomasmueller thomasmueller left a comment

Choose a reason for hiding this comment

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

It looks OK as far as I see, but I'm not sure about the security part.

Possibly memory usage could be much higher than with the current ImmutableSet.

Set<Object> creds = ImmutableSet.builder()
.addAll(subject.getPublicCredentials(Credentials.class))
.addAll(subject.getPublicCredentials(AuthInfo.class)).build();
Set<Object> creds = Stream.concat(subject.getPublicCredentials(Credentials.class).stream(), subject.getPublicCredentials(AuthInfo.class).stream())
Copy link
Contributor

Choose a reason for hiding this comment

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

Did you check that it's ok not to make this immutable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it is only iterated in the same class to destroy these credentials, but I would say that we should play safe here as well. let me update the ticket to use Collections.unmodifiableSet

Copy link
Contributor Author

Choose a reason for hiding this comment

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

addressed in 1c2d8a0

Copy link
Contributor

@reschke reschke left a comment

Choose a reason for hiding this comment

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

...but see comments.

@reschke
Copy link
Contributor

reschke commented Apr 7, 2025

Possibly memory usage could be much higher than with the current ImmutableSet.

...because?

@rishabhdaim
Copy link
Contributor Author

It looks OK as far as I see, but I'm not sure about the security part.

Possibly memory usage could be much higher than with the current ImmutableSet.

We have already done the micro benchmarks for SetUtils.toLinkedSet vs ImmutableSet and the results are here: #2178 (comment)

it seems that using Java's LinkedHashSet uses lesser memory because it doesn't uses another data structure (i.e. ArrayList in case of ImmutableSet) to store insertion order.

@mbaedke
Copy link
Contributor

mbaedke commented Apr 7, 2025

It looks OK as far as I see, but I'm not sure about the security part.

Possibly memory usage could be much higher than with the current ImmutableSet.

AFAICT all the sets in question are pretty small (also I don't quite understand how the memory usage would increase). Could you elaborate on your security concerns?

@rishabhdaim rishabhdaim requested a review from mbaedke April 7, 2025 08:51
@thomasmueller
Copy link
Member

Possibly memory usage could be much higher than with the current ImmutableSet.

...because?

Because the hash table implementation is very different. Guava seems to use an open-addressing hash table (power of 2 sized) with linear probing, where entries are very small. Java internally (inside of LinkedHashSet) uses a HashMap that uses separate chaining....

Did someone test memory usage?

Copy link
Member

@thomasmueller thomasmueller left a comment

Choose a reason for hiding this comment

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

More investigation is needed:

  • Verify memory usage
  • Verify behavior of null entries
  • Verify with someone that knows the security part

@sonarqubecloud
Copy link

sonarqubecloud bot commented Apr 7, 2025

addAll(getAutoMembership()).build();
return Collections.unmodifiableSet((Set<String>)
Stream.concat(autoMembershipConfig.getAutoMembership(authorizable).stream(), getAutoMembership().stream())
.collect(Collectors.toCollection(LinkedHashSet::new)));
Copy link
Contributor Author

@rishabhdaim rishabhdaim Apr 8, 2025

Choose a reason for hiding this comment

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

getAutoMembership has been annotated with @NotNull

Set<Privilege> privs = new LinkedHashSet<>();
for (AccessControlManager acMgr : acMgrs) {
privs.add(acMgr.getSupportedPrivileges(absPath));
privs.addAll(Arrays.asList(acMgr.getSupportedPrivileges(absPath)));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Null not possible here as well since getSupportedPrivileges has been annotated as @NotNull

private Role(@NotNull Role base, long permissions, String... privilegeNames) {
this.permissions = base.permissions|permissions;
this.privilegeNames = ImmutableSet.<String>builder().addAll(base.privilegeNames).add(privilegeNames).build();
this.privilegeNames = Collections.unmodifiableSet(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

private constructor called from within the class, privilegeNames can't be null here.

Set<Object> creds = ImmutableSet.builder()
.addAll(subject.getPublicCredentials(Credentials.class))
.addAll(subject.getPublicCredentials(AuthInfo.class)).build();
Set<Object> builder = new LinkedHashSet<>(subject.getPublicCredentials(Credentials.class));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

same case as above, getPublicCredentials can't return null.

builder.addAll(declaredAggregateNames);
}
this.declaredAggregateNames = builder.build();
this.declaredAggregateNames = declaredAggregateNames != null ? Collections.unmodifiableSet(SetUtils.toLinkedSet(declaredAggregateNames)) : Set.of();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Null case already handled.

@NotNull
private Set<String> resolveBuiltInAggregation(@NotNull String privilegeName) {
ImmutableSet.Builder<String> builder = ImmutableSet.builder();
Set<String> builder = new LinkedHashSet<>();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Only called when AGGREGATE_PRIVILEGES already has privilegeName, so null value not possible here as well.

ImmutableSet.Builder<MountedNodeStore> b = ImmutableSet.builder();
Set<MountedNodeStore> b = new LinkedHashSet<>();
b.add(this.globalStore);
b.addAll(this.nonDefaultStores);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Both values globalStore & nonDefaultStores can't be null else the code would have already failed in the higher tier.

NodeStateCopier.builder()
.include(includes)
.exclude(excludes.build())
.exclude(Collections.unmodifiableSet(excludes))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

excludes can't be null.

@rishabhdaim
Copy link
Contributor Author

rishabhdaim commented Apr 8, 2025

More investigation is needed:

* Verify memory usage

* Verify behavior of null entries

* Verify with someone that knows the security part

@thomasmueller please find reply as below:

  1. Memory usage had already been tested along with performance and both Java's LinkedHashSet & ImmutableSet provides similar performance and memory usage.
  2. ImmutableSet also throws NPE in case we put null values for addAll method, which is again same behaviour of LinkedHashSet.addAll. Also, I have added comments for each method explaining whether null value is possible or not.
  3. @anchela @Amoratinos could you please review from security point of view.

Copy link
Contributor

@Amoratinos Amoratinos left a comment

Choose a reason for hiding this comment

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

to me looks good, there are a couple of trivial things like removing imports but nothing blocker

Copy link
Member

@thomasmueller thomasmueller left a comment

Choose a reason for hiding this comment

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

It seems my concerns are addressed then! Thanks a lot!

@thomasmueller thomasmueller self-requested a review April 8, 2025 12:20
@rishabhdaim rishabhdaim merged commit 3216a1d into trunk Apr 9, 2025
5 checks passed
@rishabhdaim rishabhdaim deleted the OAK-11640 branch April 9, 2025 01:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants