Merge pull request #551 from apache/dependabot/maven/version.spring-boot-3.2.4
Bump version.spring-boot from 3.2.3 to 3.2.4
diff --git a/pom.xml b/pom.xml
index 75b6d08..39964bb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -249,7 +249,7 @@
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
- <version>1.4.8</version>
+ <version>1.4.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
@@ -616,7 +616,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
- <version>0.8.11</version>
+ <version>0.8.12</version>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
@@ -796,7 +796,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
- <version>3.2.1</version>
+ <version>3.2.3</version>
<executions>
<execution>
<id>sign-artifacts</id>
diff --git a/scim-core/src/main/java/org/apache/directory/scim/core/repository/ETag.java b/scim-core/src/main/java/org/apache/directory/scim/core/repository/ETag.java
new file mode 100644
index 0000000..1410060
--- /dev/null
+++ b/scim-core/src/main/java/org/apache/directory/scim/core/repository/ETag.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.directory.scim.core.repository;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * Bean representing an ETag, as defined by RFC 7232 section 2.3.
+ * <p>
+ * From RFC 7644 - SCIM Protocol
+ * <p>
+ * When supported by a SCIM Server, SCIM ETags MUST be specified
+ * as an HTTP header and SHOULD be specified within the 'version'
+ * attribute contained in the resource's 'meta' attribute.
+ * <p>
+ * From RFC 7232 - HTTP Conditional Requests
+ * <p>
+ * The "ETag" header field in a response provides the current entity-tag
+ * for the selected representation, as determined at the conclusion of
+ * handling the request. An entity-tag is an opaque validator for
+ * differentiating between multiple representations of the same
+ * resource, regardless of whether those multiple representations are
+ * due to resource state changes over time, content negotiation
+ * resulting in multiple representations being valid at the same time,
+ * or both. An entity-tag consists of an opaque quoted string, possibly
+ * prefixed by a weakness indicator ({@code W/}).
+ * <p>
+ * Examples:<ul>
+ * <li>ETag: "xyzzy"</li>
+ * <li>ETag: W/"xyzzy"</li>
+ * <li>ETag: ""</li>
+ * </ul>
+ * @see <a href="https://datatracker.ietf.org/doc/html/rfc7232#section-2.3">Conditional Requests - RFC 7232</a>
+ * @see <a href="https://datatracker.ietf.org/doc/html/rfc7644#section-3.14">SCIM Protocol - RFC 7644</a>
+ */
+@Data
+@EqualsAndHashCode
+@RequiredArgsConstructor
+public class ETag {
+ private final String value;
+ private final boolean weak;
+}
diff --git a/scim-core/src/main/java/org/apache/directory/scim/core/repository/Repository.java b/scim-core/src/main/java/org/apache/directory/scim/core/repository/Repository.java
index 3cbbc42..d398bb4 100644
--- a/scim-core/src/main/java/org/apache/directory/scim/core/repository/Repository.java
+++ b/scim-core/src/main/java/org/apache/directory/scim/core/repository/Repository.java
@@ -19,6 +19,7 @@
package org.apache.directory.scim.core.repository;
+import jakarta.annotation.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -69,14 +70,14 @@
*
*
* @param id the identifier of the ScimResource to update and persist.
- * @param version an optional version (usually used as an ETag) that can be used to optimize update requests, may be compared against, the current {@code ScimResource.meta.version}.
+ * @param etags optional ETag(s) in 'If-Match' header. If not null, to avoid dirty writing, {@code ScimResource.meta.version} must match one of this set (the set should contain only one element).
* @param resource an updated resource to persist
* @param includedAttributes optional set of attributes to include from ScimResource, may be used to optimize queries.
* @param excludedAttributes optional set of attributes to exclude from ScimResource, may be used to optimize queries.
* @return The newly updated ScimResource.
* @throws ResourceException When the ScimResource cannot be updated.
*/
- T update(String id, String version, T resource, Set<AttributeReference> includedAttributes, Set<AttributeReference> excludedAttributes) throws ResourceException;
+ T update(String id, @Nullable Set<ETag> etags, T resource, Set<AttributeReference> includedAttributes, Set<AttributeReference> excludedAttributes) throws ResourceException;
/**
* Allows the SCIM server's REST implementation to update and existing
@@ -86,14 +87,14 @@
* it can be used as a mechanism for caching and to ensure clients do not inadvertently overwrite other changes.
*
* @param id the identifier of the ScimResource to update and persist.
- * @param version an optional version (usually used as an ETag) that can be used to optimize update requests, may be compared against, the current {@code ScimResource.meta.version}.
+ * @param etags optional ETag(s) in 'If-Match' header. If not null, to avoid dirty writing, {@code ScimResource.meta.version} must match one of this set (the set should contain only one element).
* @param patchOperations a list of patch operations to apply to an existing resource.
* @param includedAttributes optional set of attributes to include from ScimResource, may be used to optimize queries.
* @param excludedAttributes optional set of attributes to exclude from ScimResource, may be used to optimize queries.
* @return The newly updated ScimResource.
* @throws ResourceException When the ScimResource cannot be updated.
*/
- T patch(String id, String version, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributes, Set<AttributeReference> excludedAttributes) throws ResourceException;
+ T patch(String id, @Nullable Set<ETag> etags, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributes, Set<AttributeReference> excludedAttributes) throws ResourceException;
/**
* Retrieves the ScimResource associated with the provided identifier.
diff --git a/scim-server-examples/scim-server-jersey/src/main/java/org/apache/directory/scim/example/jersey/service/InMemoryGroupService.java b/scim-server-examples/scim-server-jersey/src/main/java/org/apache/directory/scim/example/jersey/service/InMemoryGroupService.java
index 42b09e3..6d248ab 100644
--- a/scim-server-examples/scim-server-jersey/src/main/java/org/apache/directory/scim/example/jersey/service/InMemoryGroupService.java
+++ b/scim-server-examples/scim-server-jersey/src/main/java/org/apache/directory/scim/example/jersey/service/InMemoryGroupService.java
@@ -23,6 +23,7 @@
import jakarta.inject.Inject;
import jakarta.ws.rs.core.Response;
import org.apache.commons.lang3.StringUtils;
+import org.apache.directory.scim.core.repository.ETag;
import org.apache.directory.scim.core.repository.PatchHandler;
import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
import org.apache.directory.scim.core.repository.Repository;
@@ -104,13 +105,13 @@
}
@Override
- public ScimGroup update(String id, String version, ScimGroup resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimGroup update(String id, Set<ETag> etags, ScimGroup resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
groups.put(id, resource);
return resource;
}
@Override
- public ScimGroup patch(String id, String version, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimGroup patch(String id, Set<ETag> etags, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
ScimGroup resource = patchHandler.apply(get(id), patchOperations);
groups.put(id, resource);
return resource;
diff --git a/scim-server-examples/scim-server-jersey/src/main/java/org/apache/directory/scim/example/jersey/service/InMemoryUserService.java b/scim-server-examples/scim-server-jersey/src/main/java/org/apache/directory/scim/example/jersey/service/InMemoryUserService.java
index 2f00013..cbbe1b0 100644
--- a/scim-server-examples/scim-server-jersey/src/main/java/org/apache/directory/scim/example/jersey/service/InMemoryUserService.java
+++ b/scim-server-examples/scim-server-jersey/src/main/java/org/apache/directory/scim/example/jersey/service/InMemoryUserService.java
@@ -32,6 +32,7 @@
import jakarta.inject.Named;
import jakarta.ws.rs.core.Response;
+import org.apache.directory.scim.core.repository.ETag;
import org.apache.directory.scim.core.repository.PatchHandler;
import org.apache.directory.scim.example.jersey.extensions.LuckyNumberExtension;
import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
@@ -137,13 +138,13 @@
}
@Override
- public ScimUser update(String id, String version, ScimUser resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimUser update(String id, Set<ETag> etags, ScimUser resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
users.put(id, resource);
return resource;
}
@Override
- public ScimUser patch(String id, String version, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimUser patch(String id, Set<ETag> etags, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
ScimUser resource = patchHandler.apply(get(id), patchOperations);
users.put(id, resource);
return resource;
diff --git a/scim-server-examples/scim-server-memory/src/main/java/org/apache/directory/scim/example/memory/service/InMemoryGroupService.java b/scim-server-examples/scim-server-memory/src/main/java/org/apache/directory/scim/example/memory/service/InMemoryGroupService.java
index f5de84a..2d9ad1e 100644
--- a/scim-server-examples/scim-server-memory/src/main/java/org/apache/directory/scim/example/memory/service/InMemoryGroupService.java
+++ b/scim-server-examples/scim-server-memory/src/main/java/org/apache/directory/scim/example/memory/service/InMemoryGroupService.java
@@ -23,6 +23,7 @@
import jakarta.inject.Inject;
import jakarta.ws.rs.core.Response;
import org.apache.commons.lang3.StringUtils;
+import org.apache.directory.scim.core.repository.ETag;
import org.apache.directory.scim.core.repository.PatchHandler;
import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
import org.apache.directory.scim.core.repository.Repository;
@@ -104,13 +105,13 @@
}
@Override
- public ScimGroup update(String id, String version, ScimGroup resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimGroup update(String id, Set<ETag> etags, ScimGroup resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
groups.put(id, resource);
return resource;
}
@Override
- public ScimGroup patch(String id, String version, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimGroup patch(String id, Set<ETag> etags, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
ScimGroup resource = patchHandler.apply(get(id), patchOperations);
groups.put(id, resource);
return resource;
diff --git a/scim-server-examples/scim-server-memory/src/main/java/org/apache/directory/scim/example/memory/service/InMemoryUserService.java b/scim-server-examples/scim-server-memory/src/main/java/org/apache/directory/scim/example/memory/service/InMemoryUserService.java
index 562cc66..f465f0a 100644
--- a/scim-server-examples/scim-server-memory/src/main/java/org/apache/directory/scim/example/memory/service/InMemoryUserService.java
+++ b/scim-server-examples/scim-server-memory/src/main/java/org/apache/directory/scim/example/memory/service/InMemoryUserService.java
@@ -32,6 +32,7 @@
import jakarta.inject.Named;
import jakarta.ws.rs.core.Response;
+import org.apache.directory.scim.core.repository.ETag;
import org.apache.directory.scim.core.repository.PatchHandler;
import org.apache.directory.scim.example.memory.extensions.LuckyNumberExtension;
import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
@@ -137,13 +138,13 @@
}
@Override
- public ScimUser update(String id, String version, ScimUser resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimUser update(String id, Set<ETag> etags, ScimUser resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
users.put(id, resource);
return resource;
}
@Override
- public ScimUser patch(String id, String version, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimUser patch(String id, Set<ETag> etags, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
ScimUser resource = patchHandler.apply(get(id), patchOperations);
users.put(id, resource);
return resource;
diff --git a/scim-server-examples/scim-server-quarkus/pom.xml b/scim-server-examples/scim-server-quarkus/pom.xml
index 1113750..df40aeb 100644
--- a/scim-server-examples/scim-server-quarkus/pom.xml
+++ b/scim-server-examples/scim-server-quarkus/pom.xml
@@ -29,7 +29,7 @@
<properties>
<module.name>org.apache.directory.scim.example.quarkus</module.name>
- <version.quarkus>3.8.2</version.quarkus>
+ <version.quarkus>3.9.1</version.quarkus>
<max.jdk.version>17</max.jdk.version>
<!-- disable discovery of tests in other jars, tests are wrapped directly in this project to run with Quarkus -->
<dependenciesToScan />
diff --git a/scim-server-examples/scim-server-quarkus/src/main/java/org/apache/directory/scim/example/quarkus/service/InMemoryGroupService.java b/scim-server-examples/scim-server-quarkus/src/main/java/org/apache/directory/scim/example/quarkus/service/InMemoryGroupService.java
index af28ae7..f17bde1 100644
--- a/scim-server-examples/scim-server-quarkus/src/main/java/org/apache/directory/scim/example/quarkus/service/InMemoryGroupService.java
+++ b/scim-server-examples/scim-server-quarkus/src/main/java/org/apache/directory/scim/example/quarkus/service/InMemoryGroupService.java
@@ -23,6 +23,7 @@
import jakarta.inject.Inject;
import jakarta.ws.rs.core.Response;
import org.apache.commons.lang3.StringUtils;
+import org.apache.directory.scim.core.repository.ETag;
import org.apache.directory.scim.core.repository.PatchHandler;
import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
import org.apache.directory.scim.core.repository.Repository;
@@ -104,13 +105,13 @@
}
@Override
- public ScimGroup update(String id, String version, ScimGroup resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimGroup update(String id, Set<ETag> etags, ScimGroup resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
groups.put(id, resource);
return resource;
}
@Override
- public ScimGroup patch(String id, String version, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimGroup patch(String id, Set<ETag> etags, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
ScimGroup resource = patchHandler.apply(get(id), patchOperations);
groups.put(id, resource);
return resource;
diff --git a/scim-server-examples/scim-server-quarkus/src/main/java/org/apache/directory/scim/example/quarkus/service/InMemoryUserService.java b/scim-server-examples/scim-server-quarkus/src/main/java/org/apache/directory/scim/example/quarkus/service/InMemoryUserService.java
index b849846..8aa6784 100644
--- a/scim-server-examples/scim-server-quarkus/src/main/java/org/apache/directory/scim/example/quarkus/service/InMemoryUserService.java
+++ b/scim-server-examples/scim-server-quarkus/src/main/java/org/apache/directory/scim/example/quarkus/service/InMemoryUserService.java
@@ -28,6 +28,7 @@
import jakarta.inject.Named;
import jakarta.ws.rs.core.Response;
+import org.apache.directory.scim.core.repository.ETag;
import org.apache.directory.scim.core.repository.PatchHandler;
import org.apache.directory.scim.example.quarkus.extensions.LuckyNumberExtension;
import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
@@ -133,13 +134,13 @@
}
@Override
- public ScimUser update(String id, String version, ScimUser resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimUser update(String id, Set<ETag> etags, ScimUser resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
users.put(id, resource);
return resource;
}
@Override
- public ScimUser patch(String id, String version, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimUser patch(String id, Set<ETag> etags, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
ScimUser resource = patchHandler.apply(get(id), patchOperations);
users.put(id, resource);
return resource;
diff --git a/scim-server-examples/scim-server-spring-boot/src/main/java/org/apache/directory/scim/example/spring/service/InMemoryGroupService.java b/scim-server-examples/scim-server-spring-boot/src/main/java/org/apache/directory/scim/example/spring/service/InMemoryGroupService.java
index 0df2da7..df4b827 100644
--- a/scim-server-examples/scim-server-spring-boot/src/main/java/org/apache/directory/scim/example/spring/service/InMemoryGroupService.java
+++ b/scim-server-examples/scim-server-spring-boot/src/main/java/org/apache/directory/scim/example/spring/service/InMemoryGroupService.java
@@ -21,6 +21,7 @@
import jakarta.annotation.PostConstruct;
import jakarta.ws.rs.core.Response;
+import org.apache.directory.scim.core.repository.ETag;
import org.apache.directory.scim.core.repository.PatchHandler;
import org.apache.directory.scim.core.repository.Repository;
import org.apache.directory.scim.core.schema.SchemaRegistry;
@@ -94,13 +95,13 @@
}
@Override
- public ScimGroup update(String id, String version, ScimGroup resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimGroup update(String id, Set<ETag> etags, ScimGroup resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
groups.put(id, resource);
return resource;
}
@Override
- public ScimGroup patch(String id, String version, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimGroup patch(String id, Set<ETag> etags, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
ScimGroup resource = patchHandler.apply(get(id), patchOperations);
groups.put(id, resource);
return resource;
diff --git a/scim-server-examples/scim-server-spring-boot/src/main/java/org/apache/directory/scim/example/spring/service/InMemoryUserService.java b/scim-server-examples/scim-server-spring-boot/src/main/java/org/apache/directory/scim/example/spring/service/InMemoryUserService.java
index 36ba0cc..39c2eef 100644
--- a/scim-server-examples/scim-server-spring-boot/src/main/java/org/apache/directory/scim/example/spring/service/InMemoryUserService.java
+++ b/scim-server-examples/scim-server-spring-boot/src/main/java/org/apache/directory/scim/example/spring/service/InMemoryUserService.java
@@ -29,6 +29,7 @@
import jakarta.annotation.PostConstruct;
import jakarta.ws.rs.core.Response;
+import org.apache.directory.scim.core.repository.ETag;
import org.apache.directory.scim.core.repository.PatchHandler;
import org.apache.directory.scim.core.repository.Repository;
import org.apache.directory.scim.core.schema.SchemaRegistry;
@@ -127,13 +128,13 @@
}
@Override
- public ScimUser update(String id, String version, ScimUser resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimUser update(String id, Set<ETag> etags, ScimUser resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
users.put(id, resource);
return resource;
}
@Override
- public ScimUser patch(String id, String version, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimUser patch(String id, Set<ETag> etags, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
ScimUser resource = patchHandler.apply(get(id), patchOperations);
users.put(id, resource);
return resource;
diff --git a/scim-server/src/main/java/org/apache/directory/scim/server/rest/BaseResourceTypeResourceImpl.java b/scim-server/src/main/java/org/apache/directory/scim/server/rest/BaseResourceTypeResourceImpl.java
index b378c1b..f8a1fc6 100644
--- a/scim-server/src/main/java/org/apache/directory/scim/server/rest/BaseResourceTypeResourceImpl.java
+++ b/scim-server/src/main/java/org/apache/directory/scim/server/rest/BaseResourceTypeResourceImpl.java
@@ -33,6 +33,7 @@
import jakarta.ws.rs.core.Response.Status;
import jakarta.ws.rs.core.Response.Status.Family;
+import org.apache.directory.scim.core.repository.ETag;
import org.apache.directory.scim.protocol.exception.ScimException;
import org.apache.directory.scim.server.exception.*;
import org.apache.directory.scim.core.repository.RepositoryRegistry;
@@ -70,7 +71,7 @@
private final RepositoryRegistry repositoryRegistry;
- private final AttributeUtil attributeUtil;
+ private final AttributeUtil attributeUtil;
private final Class<T> resourceClass;
@@ -254,14 +255,14 @@
@Override
public Response update(T resource, String id, AttributeReferenceListWrapper attributes, AttributeReferenceListWrapper excludedAttributes) throws ScimException, ResourceException {
- return update(attributes, excludedAttributes, (etag, includeAttributes, excludeAttributes, repository)
- -> repository.update(id, etag,resource, includeAttributes, excludeAttributes));
+ return update(attributes, excludedAttributes, (etags, includeAttributes, excludeAttributes, repository)
+ -> repository.update(id, etags, resource, includeAttributes, excludeAttributes));
}
@Override
public Response patch(PatchRequest patchRequest, String id, AttributeReferenceListWrapper attributes, AttributeReferenceListWrapper excludedAttributes) throws ScimException, ResourceException {
- return update(attributes, excludedAttributes, (etag, includeAttributes, excludeAttributes, repository)
- -> repository.patch(id, etag, patchRequest.getPatchOperationList(), includeAttributes, excludeAttributes));
+ return update(attributes, excludedAttributes, (etags, includeAttributes, excludeAttributes, repository)
+ -> repository.patch(id, etags, patchRequest.getPatchOperationList(), includeAttributes, excludeAttributes));
}
@Override
@@ -279,8 +280,10 @@
Set<AttributeReference> excludedAttributeReferences = AttributeReferenceListWrapper.getAttributeReferences(excludedAttributes);
validateAttributes(attributeReferences, excludedAttributeReferences);
- String requestEtag = headers.getHeaderString("ETag");
- T updated = updateFunction.update(requestEtag, attributeReferences, excludedAttributeReferences, repository);
+ String requestEtag = headers.getHeaderString("If-Match");
+ Set<ETag> etags = EtagParser.parseETag(requestEtag);
+
+ T updated = updateFunction.update(etags, attributeReferences, excludedAttributeReferences, repository);
// Process Attributes
updated = processFilterAttributeExtensions(repository, updated, attributeReferences, excludedAttributeReferences);
@@ -371,6 +374,6 @@
@FunctionalInterface
private interface UpdateFunction<T extends ScimResource> {
- T update(String etag, Set<AttributeReference> includeAttributes, Set<AttributeReference> excludeAttributes, Repository<T> repository) throws ResourceException;
+ T update(Set<ETag> etags, Set<AttributeReference> includeAttributes, Set<AttributeReference> excludeAttributes, Repository<T> repository) throws ResourceException;
}
}
diff --git a/scim-server/src/main/java/org/apache/directory/scim/server/rest/EtagParser.java b/scim-server/src/main/java/org/apache/directory/scim/server/rest/EtagParser.java
new file mode 100644
index 0000000..ffe6711
--- /dev/null
+++ b/scim-server/src/main/java/org/apache/directory/scim/server/rest/EtagParser.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.directory.scim.server.rest;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.directory.scim.core.repository.ETag;
+
+public final class EtagParser {
+
+ private EtagParser() {
+ }
+
+ /**
+ * Parse comma-separated entity tags
+ *
+ * @param value
+ * @return
+ * @throws IllegalArgumentException
+ */
+ public static Set<ETag> parseETag(String value) throws IllegalArgumentException {
+ if (StringUtils.isNotBlank(value)) {
+ Set<ETag> result = new HashSet<>();
+
+ for (String etag : value.split(",")) {
+ etag = etag.trim();
+ boolean weakTag = false;
+
+ if (etag.startsWith("W/")) {
+ weakTag = true;
+ etag = etag.substring(2);
+ }
+
+ if (etag.startsWith("\"")) {
+ etag = etag.substring(1);
+ }
+
+ if (etag.endsWith("\"")) {
+ etag = etag.substring(0, etag.length() - 1);
+ }
+
+ result.add(new ETag(etag, weakTag));
+ }
+ return result;
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/scim-server/src/test/java/org/apache/directory/scim/server/it/testapp/InMemoryGroupService.java b/scim-server/src/test/java/org/apache/directory/scim/server/it/testapp/InMemoryGroupService.java
index 2dac3ea..9af8eeb 100644
--- a/scim-server/src/test/java/org/apache/directory/scim/server/it/testapp/InMemoryGroupService.java
+++ b/scim-server/src/test/java/org/apache/directory/scim/server/it/testapp/InMemoryGroupService.java
@@ -25,6 +25,7 @@
import jakarta.inject.Named;
import jakarta.ws.rs.core.Response;
import org.apache.commons.lang3.StringUtils;
+import org.apache.directory.scim.core.repository.ETag;
import org.apache.directory.scim.core.repository.PatchHandler;
import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
import org.apache.directory.scim.core.repository.Repository;
@@ -98,13 +99,13 @@
}
@Override
- public ScimGroup update(String id, String version, ScimGroup resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimGroup update(String id, Set<ETag> etags, ScimGroup resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
groups.put(id, resource);
return resource;
}
@Override
- public ScimGroup patch(String id, String version, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimGroup patch(String id, Set<ETag> etags, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
ScimGroup resource = patchHandler.apply(get(id), patchOperations);
groups.put(id, resource);
return resource;
diff --git a/scim-server/src/test/java/org/apache/directory/scim/server/it/testapp/InMemoryUserService.java b/scim-server/src/test/java/org/apache/directory/scim/server/it/testapp/InMemoryUserService.java
index 909df75..a870610 100644
--- a/scim-server/src/test/java/org/apache/directory/scim/server/it/testapp/InMemoryUserService.java
+++ b/scim-server/src/test/java/org/apache/directory/scim/server/it/testapp/InMemoryUserService.java
@@ -24,6 +24,7 @@
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.ws.rs.core.Response;
+import org.apache.directory.scim.core.repository.ETag;
import org.apache.directory.scim.core.repository.PatchHandler;
import org.apache.directory.scim.server.exception.UnableToCreateResourceException;
import org.apache.directory.scim.core.repository.Repository;
@@ -130,13 +131,13 @@
}
@Override
- public ScimUser update(String id, String version, ScimUser resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimUser update(String id, Set<ETag> etags, ScimUser resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
users.put(id, resource);
return resource;
}
@Override
- public ScimUser patch(String id, String version, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimUser patch(String id, Set<ETag> etags, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
ScimUser resource = patchHandler.apply(get(id), patchOperations);
users.put(id, resource);
return resource;
diff --git a/scim-server/src/test/java/org/apache/directory/scim/server/rest/EtagParserTest.java b/scim-server/src/test/java/org/apache/directory/scim/server/rest/EtagParserTest.java
new file mode 100644
index 0000000..6ca513f
--- /dev/null
+++ b/scim-server/src/test/java/org/apache/directory/scim/server/rest/EtagParserTest.java
@@ -0,0 +1,68 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+
+* http://www.apache.org/licenses/LICENSE-2.0
+
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.directory.scim.server.rest;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Set;
+import org.apache.directory.scim.core.repository.ETag;
+import org.junit.jupiter.api.Test;
+
+public class EtagParserTest {
+
+ @Test
+ public void testParse() {
+ Set<ETag> etags = EtagParser.parseETag("\"67ab43\", \"54ed21\", W/\"7892dd\"");
+
+ assertThat(etags)
+ .isNotNull()
+ .hasSize(3)
+ .containsOnly(
+ new ETag("67ab43", false),
+ new ETag("54ed21", false),
+ new ETag("7892dd", true));
+ }
+
+ @Test
+ public void testParseWildcard() {
+ Set<ETag> etags = EtagParser.parseETag("*");
+
+ assertThat(etags)
+ .isNotNull()
+ .hasSize(1)
+ .containsOnly(
+ new ETag("*", false));
+ }
+
+ @Test
+ public void testParseEmpty() {
+ Set<ETag> etags = EtagParser.parseETag("");
+ assertThat(etags).isNull();
+ }
+
+ @Test
+ public void testParseNull() {
+ assertThat(EtagParser.parseETag(null))
+ .isNull();
+ }
+}
diff --git a/scim-spec/scim-spec-protocol/pom.xml b/scim-spec/scim-spec-protocol/pom.xml
index 85c32dc..c07ff42 100644
--- a/scim-spec/scim-spec-protocol/pom.xml
+++ b/scim-spec/scim-spec-protocol/pom.xml
@@ -41,7 +41,7 @@
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
- <version>2.2.20</version>
+ <version>2.2.21</version>
</dependency>
<dependency>
<groupId>org.apache.directory.scimple</groupId>
diff --git a/support/spring-boot/src/test/java/org/apache/directory/scim/spring/it/app/InMemoryGroupService.java b/support/spring-boot/src/test/java/org/apache/directory/scim/spring/it/app/InMemoryGroupService.java
index 07a79d0..d849b72 100644
--- a/support/spring-boot/src/test/java/org/apache/directory/scim/spring/it/app/InMemoryGroupService.java
+++ b/support/spring-boot/src/test/java/org/apache/directory/scim/spring/it/app/InMemoryGroupService.java
@@ -22,6 +22,7 @@
import jakarta.annotation.PostConstruct;
import jakarta.ws.rs.core.Response;
import org.apache.commons.lang3.StringUtils;
+import org.apache.directory.scim.core.repository.ETag;
import org.apache.directory.scim.core.repository.PatchHandler;
import org.apache.directory.scim.core.repository.Repository;
import org.apache.directory.scim.core.schema.SchemaRegistry;
@@ -93,13 +94,13 @@
}
@Override
- public ScimGroup update(String id, String version, ScimGroup resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimGroup update(String id, Set<ETag> etags, ScimGroup resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
groups.put(id, resource);
return resource;
}
@Override
- public ScimGroup patch(String id, String version, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimGroup patch(String id, Set<ETag> etags, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
ScimGroup resource = patchHandler.apply(get(id), patchOperations);
groups.put(id, resource);
return resource;
diff --git a/support/spring-boot/src/test/java/org/apache/directory/scim/spring/it/app/InMemoryUserService.java b/support/spring-boot/src/test/java/org/apache/directory/scim/spring/it/app/InMemoryUserService.java
index 430d837..9ec72a8 100644
--- a/support/spring-boot/src/test/java/org/apache/directory/scim/spring/it/app/InMemoryUserService.java
+++ b/support/spring-boot/src/test/java/org/apache/directory/scim/spring/it/app/InMemoryUserService.java
@@ -21,6 +21,7 @@
import jakarta.annotation.PostConstruct;
import jakarta.ws.rs.core.Response;
+import org.apache.directory.scim.core.repository.ETag;
import org.apache.directory.scim.core.repository.PatchHandler;
import org.apache.directory.scim.core.repository.Repository;
import org.apache.directory.scim.core.schema.SchemaRegistry;
@@ -124,13 +125,13 @@
}
@Override
- public ScimUser update(String id, String version, ScimUser resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimUser update(String id, Set<ETag> etags, ScimUser resource, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
users.put(id, resource);
return resource;
}
@Override
- public ScimUser patch(String id, String version, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
+ public ScimUser patch(String id, Set<ETag> etags, List<PatchOperation> patchOperations, Set<AttributeReference> includedAttributeReferences, Set<AttributeReference> excludedAttributeReferences) throws ResourceException {
ScimUser resource = patchHandler.apply(get(id), patchOperations);
users.put(id, resource);
return resource;