Skip to content

Commit f7daf91

Browse files
committed
Introduce ConditionalWrite.ConditionalWriteOptions & ConditionalWrite.ConditionalWriteResponse
1 parent d52cefa commit f7daf91

File tree

1 file changed

+171
-0
lines changed

1 file changed

+171
-0
lines changed
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*/
8+
9+
package org.opensearch.common.blobstore;
10+
11+
import java.time.Instant;
12+
13+
/**
14+
* Utility classes supporting conditional write operations on a {@link BlobContainer}.
15+
* The main entry points are {@link ConditionalWriteOptions} for specifying conditions, and
16+
* {@link ConditionalWriteResponse} for receiving the result of a conditional write.
17+
*/
18+
public final class ConditionalWrite {
19+
private ConditionalWrite() {}
20+
21+
/**
22+
* Encapsulates options controlling preconditions to be deployed when a blob is to be written to the remote store.
23+
* Immutable and thread-safe. Use the provided static factory methods or the {@link Builder}
24+
* to construct instances with the desired conditions. These options can be supplied to
25+
* blob store write operations to enforce preconditions
26+
*
27+
*/
28+
public static final class ConditionalWriteOptions {
29+
30+
private final boolean ifNotExists;
31+
private final boolean ifMatch;
32+
private final boolean ifUnmodifiedSince;
33+
private final String versionIdentifier;
34+
private final Instant unmodifiedSince;
35+
36+
private ConditionalWriteOptions(Builder builder) {
37+
this.ifNotExists = builder.ifNotExists;
38+
this.ifMatch = builder.ifMatch;
39+
this.ifUnmodifiedSince = builder.ifUnmodifiedSince;
40+
this.versionIdentifier = builder.versionIdentifier;
41+
this.unmodifiedSince = builder.unmodifiedSince;
42+
}
43+
44+
public static ConditionalWriteOptions none() {
45+
return new Builder().build();
46+
}
47+
48+
public static ConditionalWriteOptions ifNotExists() {
49+
return new Builder().setIfNotExists(true).build();
50+
}
51+
52+
public static ConditionalWriteOptions ifMatch(String versionIdentifier) {
53+
return new Builder().setIfMatch(true).setVersionIdentifier(versionIdentifier).build();
54+
}
55+
56+
public static ConditionalWriteOptions ifUnmodifiedSince(Instant ts) {
57+
return new Builder().setIfUnmodifiedSince(true).setUnmodifiedSince(ts).build();
58+
}
59+
60+
/**
61+
* Returns a new {@link Builder} for constructing custom conditional write options.
62+
*/
63+
public static Builder builder() {
64+
return new Builder();
65+
}
66+
67+
public boolean isIfNotExists() {
68+
return ifNotExists;
69+
}
70+
71+
public boolean isIfMatch() {
72+
return ifMatch;
73+
}
74+
75+
public boolean isIfUnmodifiedSince() {
76+
return ifUnmodifiedSince;
77+
}
78+
79+
public String getVersionIdentifier() {
80+
return versionIdentifier;
81+
}
82+
83+
public Instant getUnmodifiedSince() {
84+
return unmodifiedSince;
85+
}
86+
87+
/**
88+
* Builder for {@link ConditionalWriteOptions}.
89+
* Allows fine-grained construction of conditional write criteria.
90+
*/
91+
public static final class Builder {
92+
private boolean ifNotExists = false;
93+
private boolean ifMatch = false;
94+
private boolean ifUnmodifiedSince = false;
95+
private String versionIdentifier = null;
96+
private Instant unmodifiedSince = null;
97+
98+
private Builder() {}
99+
100+
/**
101+
* Sets the write to succeed only if the blob does not exist.
102+
* @param flag true to enable this condition
103+
* @return this builder
104+
*/
105+
public Builder setIfNotExists(boolean flag) {
106+
this.ifNotExists = flag;
107+
return this;
108+
}
109+
110+
/**
111+
* Sets the write to succeed only if the blob matches the expected version.
112+
* @param flag true to enable this condition
113+
* @return this builder
114+
*/
115+
public Builder setIfMatch(boolean flag) {
116+
this.ifMatch = flag;
117+
return this;
118+
}
119+
120+
/**
121+
* Sets the write to succeed only if the blob was not modified since a given instant.
122+
* @param flag true to enable this condition
123+
* @return this builder
124+
*/
125+
public Builder setIfUnmodifiedSince(boolean flag) {
126+
this.ifUnmodifiedSince = flag;
127+
return this;
128+
}
129+
130+
/**
131+
* Sets the timestamp before which the blob must remain unmodified.
132+
* @param ts the instant to check
133+
* @return this builder
134+
*/
135+
public Builder setUnmodifiedSince(Instant ts) {
136+
this.unmodifiedSince = ts;
137+
return this;
138+
}
139+
140+
public Builder setVersionIdentifier(String versionIdentifier) {
141+
this.versionIdentifier = versionIdentifier;
142+
return this;
143+
}
144+
145+
public ConditionalWriteOptions build() {
146+
return new ConditionalWriteOptions(this);
147+
}
148+
}
149+
}
150+
151+
/**
152+
* encapsulates the result of a conditional write operation.
153+
* Contains the new version identifier (such as an ETag or version string) retrieved from the remote store
154+
* after a successful write.
155+
*/
156+
public static final class ConditionalWriteResponse {
157+
private final String newVersionIdentifier;
158+
159+
private ConditionalWriteResponse(String versionIdentifier) {
160+
this.newVersionIdentifier = versionIdentifier;
161+
}
162+
163+
public static ConditionalWriteResponse success(String versionIdentifier) {
164+
return new ConditionalWriteResponse(versionIdentifier);
165+
}
166+
167+
public String getVersionIdentifier() {
168+
return newVersionIdentifier;
169+
}
170+
}
171+
}

0 commit comments

Comments
 (0)