future.addCallback(new JaxRsRestconfCallback<>(ar) {
@Override
Response transform(final DataPutResult result) {
- return switch (result) {
- // Note: no Location header, as it matches the request path
- case CREATED -> Response.status(Status.CREATED).build();
- case REPLACED -> Response.noContent().build();
- };
+ // Note: no Location header, as it matches the request path
+ final var builder = result.created() ? Response.status(Status.CREATED) : Response.noContent();
+ fillConfigurationMetadata(builder, result);
+ return builder.build();
}
});
}
}
private static final Logger LOG = LoggerFactory.getLogger(RestconfStrategy.class);
+ private static final @NonNull DataPutResult PUT_CREATED = new DataPutResult(true);
+ private static final @NonNull DataPutResult PUT_REPLACED = new DataPutResult(false);
private final @NonNull ImmutableMap<QName, RpcImplementation> localRpcs;
private final @NonNull ApiPathNormalizer pathNormalizer;
Futures.addCallback(commitFuture, new FutureCallback<CommitInfo>() {
@Override
public void onSuccess(final CommitInfo result) {
- ret.set(exists ? DataPutResult.REPLACED : DataPutResult.CREATED);
+ ret.set(exists ? PUT_REPLACED : PUT_CREATED);
}
@Override
*/
package org.opendaylight.restconf.server.api;
+import java.time.Instant;
+import org.eclipse.jdt.annotation.Nullable;
+
/**
* Result of a {@code PUT} request as defined in
* <a href="https://www.rfc-editor.org/rfc/rfc8040#section-4.5">RFC8040 section 4.5</a>. The definition makes it
* clear that the logical operation is {@code create-or-replace}.
+ *
+ * @param created {@code true} if the resource was created, {@code false} if it was replaced
+ * @param entityTag response {@code ETag} header, or {@code null} if not applicable
+ * @param lastModified response {@code Last-Modified} header, or {@code null} if not applicable
*/
-public enum DataPutResult {
- /**
- * A new resource has been created.
- */
- CREATED,
- /*
- * An existing resources has been replaced.
- */
- REPLACED;
+public record DataPutResult(
+ boolean created,
+ @Nullable EntityTag entityTag,
+ @Nullable Instant lastModified) implements ConfigurationMetadata {
+ public DataPutResult(final boolean created) {
+ this(created, null, null);
+ }
}
\ No newline at end of file
* An implementation of a RESTCONF server, implementing the
* <a href="https://www.rfc-editor.org/rfc/rfc8040#section-3.3">RESTCONF API Resource</a>.
*/
-// FIXME: NETCONF-1207: configuration datastore should maintain ETag and Last-Modified headers, so that these can be
-// returned when PATCH/PUT modify the data.
@NonNullByDefault
public interface RestconfServer {
/**
* @param body data node for put to config DS
* @return A {@link RestconfFuture} of the operation
*/
+ // FIXME: NETCONF-1207: result should carry ConfigurationMetadata
RestconfFuture<Empty> dataPATCH(ResourceBody body);
/**
* @param body data node for put to config DS
* @return A {@link RestconfFuture} of the operation
*/
+ // FIXME: NETCONF-1207: result should carry ConfigurationMetadata
RestconfFuture<Empty> dataPATCH(ApiPath identifier, ResourceBody body);
/**
* @param body YANG Patch body
* @return A {@link RestconfFuture} of the {@link PatchStatusContext} content
*/
+ // FIXME: NETCONF-1207: result should carry ConfigurationMetadata
RestconfFuture<PatchStatusContext> dataPATCH(PatchBody body);
/**
* @param body YANG Patch body
* @return A {@link RestconfFuture} of the {@link PatchStatusContext} content
*/
+ // FIXME: NETCONF-1207: result should carry ConfigurationMetadata
RestconfFuture<PatchStatusContext> dataPATCH(ApiPath identifier, PatchBody body);
RestconfFuture<DataPostResult.CreateResource> dataPOST(ChildBody body, Map<String, String> queryParameters);