1.0.0-M1 to 1.0.0This guide covers the breaking changes to the org.apache.directory.scim.core.repository.Repository interface and how to update your implementations.
[!CAUTION] The
Repositoryinterface has breaking changes that require updates to all implementations.
The Repository interface has been refactored to use ScimRequestContext instead of passing individual parameters. This consolidates request metadata (included/excluded attributes, pagination, sorting, and ETags) into a single context object.
ScimRequestContext moved from org.apache.directory.scim.spec to org.apache.directory.scim.core.repositoryScimRequestContext.getETag() instead of being a separate method parameterScimRequestContext to consolidate request metadata| Method | Old Signature (1.0.0-M1) | New Signature (1.0.0) |
|---|---|---|
create | create(T) | create(T, ScimRequestContext) |
get | get(String) | get(String, ScimRequestContext) |
find | find(Filter, PageRequest, SortRequest) | find(Filter, ScimRequestContext) |
update | update(String, String, T, Set<AttributeReference>, Set<AttributeReference>) | update(String, T, ScimRequestContext) |
patch | patch(String, String, List<PatchOperation>, Set<AttributeReference>, Set<AttributeReference>) | patch(String, List<PatchOperation>, ScimRequestContext) |
org.apache.directory.scim.core.repository.ETagA new ETag class has been added to represent HTTP ETags for optimistic concurrency control:
import org.apache.directory.scim.core.repository.ETag; // ETag is used for versioning and optimistic concurrency // The constructor takes a value and a boolean indicating if it's a weak ETag ETag etag = new ETag("abc123", false); // Strong ETag ETag weakEtag = new ETag("abc123", true); // Weak ETag // Useful methods etag.getValue(); // Returns the ETag value etag.isWeak(); // Returns true if this is a weak ETag
Update the import for ScimRequestContext - the package has changed:
Before (1.0.0-M1):
import org.apache.directory.scim.spec.ScimRequestContext;
After (1.0.0):
import org.apache.directory.scim.core.repository.ScimRequestContext;
Also, the ETag import is no longer needed as a separate parameter (ETags are accessed via ScimRequestContext):
// No longer needed as a method parameter, but still available via ScimRequestContext import org.apache.directory.scim.core.repository.ETag;
create MethodBefore (1.0.0-M1):
@Override public ScimUser create(ScimUser resource) throws ResourceException { // implementation }
After (1.0.0):
@Override public ScimUser create(ScimUser resource, ScimRequestContext requestContext) throws ResourceException { // implementation - requestContext available if needed for attribute filtering }
get MethodBefore (1.0.0-M1):
@Override public ScimUser get(String id) throws ResourceException { // implementation }
After (1.0.0):
@Override public ScimUser get(String id, ScimRequestContext requestContext) throws ResourceException { // implementation - requestContext available if needed for attribute filtering }
find MethodBefore (1.0.0-M1):
@Override public FilterResponse<ScimUser> find(Filter filter, PageRequest pageRequest, SortRequest sortRequest) throws ResourceException { long count = pageRequest != null ? pageRequest.getCount() : users.size(); long startIndex = pageRequest != null ? pageRequest.getStartIndex() - 1 : 0; // ... }
After (1.0.0):
@Override public FilterResponse<ScimUser> find(Filter filter, ScimRequestContext requestContext) throws ResourceException { long count = requestContext.getPageRequest().map(PageRequest::getCount).orElse(users.size()); long startIndex = requestContext.getPageRequest().map(PageRequest::getStartIndex).map(it -> it - 1).orElse(0); // ... }
update MethodBefore (1.0.0-M1):
@Override public ScimUser update(String id, String version, ScimUser resource, Set<AttributeReference> includedAttributes, Set<AttributeReference> excludedAttributes) throws ResourceException { // version was a String for ETag // implementation }
After (1.0.0):
@Override public ScimUser update(String id, ScimUser resource, ScimRequestContext requestContext) throws ResourceException { // ETag is now accessed via requestContext.getETag() // includedAttributes/excludedAttributes are also in requestContext // implementation }
patch MethodBefore (1.0.0-M1):
@Override public ScimUser patch(String id, String version, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributes, Set<AttributeReference> excludedAttributes) throws ResourceException { // version was a String for ETag // implementation }
After (1.0.0):
@Override public ScimUser patch(String id, List<PatchOperation> patchOperations, ScimRequestContext requestContext) throws ResourceException { // ETag is now accessed via requestContext.getETag() // includedAttributes/excludedAttributes are also in requestContext // implementation }
The minimum JDK version has changed from JDK 11 to JDK 17.
The ScimRequestContext provides access to all request metadata:
| Method | Description |
|---|---|
getIncludedAttributes() | Attributes that should be included in the response |
getExcludedAttributes() | Attributes that should be excluded from the response |
getPageRequest() | Pagination information (returns Optional<PageRequest>) |
getSortRequest() | Sorting information |
getETag() | ETag(s) from the If-Match header for optimistic concurrency |
ETags are now accessed via ScimRequestContext.getETag() instead of being a separate method parameter. This returns a Set<ETag> which aligns with the HTTP If-Match header semantics (which can contain multiple ETags).
If you need to implement optimistic locking with ETags:
@Override public ScimUser update(String id, ScimUser resource, ScimRequestContext requestContext) throws ResourceException { ScimUser existing = store.get(id); if (existing == null) { throw new ResourceNotFoundException(id); } // Optional: Check ETag for optimistic concurrency Set<ETag> etags = requestContext.getETag(); if (etags != null && !etags.isEmpty()) { String currentVersion = existing.getMeta().getVersion(); boolean matches = etags.stream() .anyMatch(etag -> etag.getValue().equals(currentVersion)); if (!matches) { throw new PreconditionFailedException("ETag mismatch"); } } store.save(resource); return resource; }
If you encounter issues during migration, please: