Skip to content

Conversation

@erant10
Copy link
Contributor

@erant10 erant10 commented Dec 31, 2022

No description provided.

Eran Toledano and others added 4 commits December 29, 2022 13:18
These tests were disabled, so they have been reworked with a new PatchOperationAssert
@bdemers bdemers changed the title Patch Draft Draft: Applying Patches to resources Jan 3, 2023
@bdemers
Copy link
Member

bdemers commented Jan 3, 2023

Related PR for cleaning up/enabling patch related tests: #217

Copy link
Member

@bdemers bdemers left a comment

Choose a reason for hiding this comment

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

Awesome!
@erant10, any objection to me merging #217 into your branch?
(I can hack on the ObjectMapper Factory bits from my comment too)

import com.fasterxml.jackson.module.jakarta.xmlbind.JakartaXmlBindAnnotationIntrospector;
import com.fasterxml.jackson.module.jakarta.xmlbind.JakartaXmlBindAnnotationModule;

public class ObjectMapperProvider {
Copy link
Member

Choose a reason for hiding this comment

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

I recently refactored some of the JSON/ObjectMapper bits.
I'm not 100% that will help with this usage, but it is something we can investigate.

https://github.com/apache/directory-scimple/blob/develop/scim-core/src/main/java/org/apache/directory/scim/core/json/ObjectMapperFactory.java

This may come into play when dealing with patches that contain values from SCIM Extensions.
That said, with your approach using objectAsMap it may not make a difference.
(Mostly a note to myself, to go back and look at the ObjectMapper-related bits 😄)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

of course, feel free to merge :)

Yeah I got the map conversion idea from this pr - #29
which might not be the most efficient but it seems simple enough...

@bdemers
Copy link
Member

bdemers commented Jan 3, 2023

I almost forgot, but if you haven't already, can you fill out an Apache ICLA (or CCLA in needed)
https://www.apache.org/licenses/contributor-agreements.html

@erant10
Copy link
Contributor Author

erant10 commented Jan 3, 2023

@bdemers My main concern with this implementation is that PatchHandler is coupled with InMemoryFilterExpression, which is only meant to be used with the in-memory implementation... I wonder if there is a way to abstract-ify this FilterExpression so that it can be easily modified for non-demo purposes...

@bdemers
Copy link
Member

bdemers commented Jan 4, 2023

@erant10 good call out on the InMemoryScimFilterMatcher, I noticed that but forgot to mention it.

I think it's use is appropriate as the patch only affects a single resource (or possibly a small subset), so there shouldn't be any major perf issues. (which was mostly my original concern, e.g. return a large collection from a datastore and then filter it down in memory)

I like your idea of somehow abstracting the useful bits out, but I'll throw out some related ideas too:

  • Add comments/doc stating that the usage of InMemoryScimFilterMatcher should only be used on small sets of data.
  • Go a different direction, create some sort of "mapper/visitor" interface that will convert a FilterExpression into something else. This something else could be a JDBC query, or in this case, a Predicate.

Mostly thinking out loud, I'm not 100% sure that the last bit adds much value, as its very implementation-specific, and anyone who creates a Repository<ScimResource> has could choose to not use it 🤷

Thoughts?

# Conflicts:
#	scim-core/src/main/java/org/apache/directory/scim/core/repository/UpdateRequest.java
@bdemers
Copy link
Member

bdemers commented Jan 4, 2023

I merged in #217 and resolved a couple of minor conflicts

  • added a couple of missing license headers.
  • updated ObjectMapper creation per comment above

@bdemers bdemers marked this pull request as draft January 4, 2023 16:31
@bdemers
Copy link
Member

bdemers commented Jan 4, 2023

Note: if needed, we can clean up the history before merging, but there is probably more value in hacking on all the patch-related bits in one branch 💥

@bdemers
Copy link
Member

bdemers commented Jan 6, 2023

@erant10 I just used this branch to do a quick test with Okta's group membership patch requests and it worked great!

Awesome work!

@erant10
Copy link
Contributor Author

erant10 commented Jan 18, 2023

@bdemers Sorry for the delay, just got back from vacation :)
I will take a look at your commits and add my latests changes to the branch. I'll keep you posted!
and yes I agree we can definitely squash commits before merging (assuming we still want to go down this route :)

@bdemers
Copy link
Member

bdemers commented Jan 18, 2023

Related I created #233, (only the last commit is relevant)
But it tries to abstract out some of the common filter logic to help folks map filters into other objects

@erant10
Copy link
Contributor Author

erant10 commented Jan 19, 2023

Related I created #233, (only the last commit is relevant) But it tries to abstract out some of the common filter logic to help folks map filters into other objects

I like that change. do you think it makes sense to merge it as a separate PR, or rather include it in this one?

@bdemers
Copy link
Member

bdemers commented Jan 19, 2023

@erant10 if we can split it up that would be ideal... but, it's all related to getting the patch bits working, so I personally wouldn't loose any sleep over getting everything in a single branch.

We could clean up the history a little before merging (but IMHO, that not required unless it makes the change set more readable)

Comment on lines 162 to 166
if (actual instanceof ScimResource) {
// actual is the top level scim resource - need to extract the top attribute.
// otherwise we can move on directly to the sub-attribute
actual = schemaAttribute.getAccessor().get(actual);
}
Copy link
Member

Choose a reason for hiding this comment

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

@erant10
🤔 This bit has me confused.
Locally, I reverted this back the previous try/catch/todo, and all the tests pass.

But I haven't been able to figure out what condition causes this error. Any ideas?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

actually this is a bug I just fixed in my latest commit. My original thought was that we should only "drill down" into the object if actual is a ScimResource (i.e. User/Group) but not if its an Attribute (e.g. Email). But I was wrong, and thats what was breaking the test lol. Anyway I added a method to the Schema interface which will check if a field is accessible. I think this fixes it, let me know if it makes more sense now

@erant10 erant10 marked this pull request as ready for review January 24, 2023 01:02
@erant10 erant10 changed the title Draft: Applying Patches to resources Applying Patches to resources Jan 24, 2023
}
else {
Attribute attribute = baseSchema.getAttribute(attributeReference.getAttributeName());
checkMutability(attribute);
Copy link
Member

Choose a reason for hiding this comment

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

Awesome!

bdemers and others added 6 commits January 24, 2023 18:55
Add test cases for patch replace/remove with filter
Create Patch Operation handlers for each type of OP
…esource

This allows for some complexity reduction and has a side benefit of traversing the object graph once per request vs once per patch op

The `checkMutabilty` logic was also tweaked to allow setting of an immutable attribute if there is no existing value per rfc7644 sec 3.5.2
> a client MUST NOT modify an attribute that has mutability "readOnly" or "immutable".  However, a client MAY "add" a value to an "immutable" attribute if the attribute had no previous value.
}
}

private static void checkMutability(Attribute attribute, Object currentValue) throws IllegalArgumentException {
Copy link
Member

Choose a reason for hiding this comment

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

My last change litters the code with a few more checkMutability calls, to account for rfc7644 sec 3.5.2

a client MUST NOT modify an attribute that has mutability "readOnly" or "immutable". However, a client MAY "add" a value to an "immutable" attribute if the attribute had no previous value.

I'm not really a fan of spreading of how I spread this logic around, but needing the object's current value makes it tricky.
I went down the rabbit hole of creating a Collection/Map/Iterator/etc that could wrap a delegate and then make a mutability check if/when the attribute was mutated in the map. It was a neat bit of code, but it was ugly and required special handling for extensions so I threw it away. There is probably something more elegant that could be done, but I'm out of ideas 😆

It's not critical to get this in, but if you have any thoughts let me know!

@bdemers
Copy link
Member

bdemers commented Feb 1, 2023

@erant10 are we ready to merge this?

@erant10
Copy link
Contributor Author

erant10 commented Feb 1, 2023

@bdemers Yes I believe so!
I may have some fixes to address later on but I can always open a new PR right?

@bdemers
Copy link
Member

bdemers commented Feb 1, 2023

@erant10 perfect! I'll merge it!

@bdemers bdemers merged commit 934b2ba into apache:develop Feb 1, 2023
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.

2 participants