Skip to content

Commit 9f7a4ac

Browse files
Add the revision field for alidocstore (#68)
1 parent 2ea50f9 commit 9f7a4ac

File tree

3 files changed

+65
-16
lines changed

3 files changed

+65
-16
lines changed

docstore/docstore-ali/src/main/java/com/salesforce/multicloudj/docstore/ali/AliDocStore.java

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.alicloud.openservices.tablestore.model.RowPutChange;
2828
import com.alicloud.openservices.tablestore.model.StartLocalTransactionRequest;
2929
import com.alicloud.openservices.tablestore.model.StartLocalTransactionResponse;
30+
import com.alicloud.openservices.tablestore.model.condition.SingleColumnValueCondition;
3031
import com.alicloud.openservices.tablestore.model.sql.SQLQueryRequest;
3132
import com.google.auto.service.AutoService;
3233
import com.salesforce.multicloudj.common.exceptions.InvalidArgumentException;
@@ -305,16 +306,47 @@ protected WriteOperation newPut(Action action, Consumer<Predicate<Object>> befor
305306
);
306307
}
307308

309+
private Condition buildRevisionPrecondition(Document doc, String revField) {
310+
Object object = doc.getField(revField);
311+
if (object == null) {
312+
return null;
313+
}
314+
if (!(object instanceof String)) {
315+
throw new IllegalArgumentException(String.format("Invalid revision field %s type as %s, expect String type.", revField, object == null ? null : object.getClass().getName()));
316+
}
317+
String v = (String) doc.getField(revField);
318+
if (v == null || v.isEmpty()) {
319+
return null;
320+
}
321+
322+
Condition condition = new Condition();
323+
SingleColumnValueCondition singleColumnValueCondition = new SingleColumnValueCondition(revField,
324+
SingleColumnValueCondition.CompareOperator.EQUAL, ColumnValue.fromString(v));
325+
condition.setColumnCondition(singleColumnValueCondition);
326+
return condition;
327+
}
328+
308329
private void buildPreCondition(Action a, RowPutChange rowPutChange) {
309330
switch (a.getKind()) {
310331
case ACTION_KIND_CREATE:
311332
rowPutChange.setCondition(new Condition(RowExistenceExpectation.EXPECT_NOT_EXIST));
312333
return;
313334
case ACTION_KIND_UPDATE:
314335
case ACTION_KIND_REPLACE:
315-
rowPutChange.setCondition(new Condition(RowExistenceExpectation.EXPECT_EXIST));
336+
Condition condition = buildRevisionPrecondition(a.getDocument(), getRevisionField());
337+
rowPutChange.setCondition(Objects.requireNonNullElseGet(condition, () -> new Condition(RowExistenceExpectation.EXPECT_NOT_EXIST)));
338+
return;
339+
case ACTION_KIND_DELETE:
340+
case ACTION_KIND_PUT:
341+
// Precondition: the revision matches, if any.
342+
rowPutChange.setCondition(buildRevisionPrecondition(a.getDocument(), getRevisionField()));
343+
return;
344+
case ACTION_KIND_GET:
345+
// No preconditions on a Get.
346+
return;
347+
default:
348+
throw new IllegalArgumentException("Invalid action kind: " + a.getKind());
316349
}
317-
318350
}
319351

320352
protected void runPut(RowPutChange put, Action action, Consumer<Predicate<Object>> beforeDo) {

docstore/docstore-ali/src/test/java/com/salesforce/multicloudj/docstore/ali/AliDocStoreTest.java

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212
import com.alicloud.openservices.tablestore.model.DescribeTableResponse;
1313
import com.alicloud.openservices.tablestore.model.IndexMeta;
1414
import com.alicloud.openservices.tablestore.model.IndexType;
15-
import com.alicloud.openservices.tablestore.model.PrimaryKey;
1615
import com.alicloud.openservices.tablestore.model.PrimaryKeyBuilder;
17-
import com.alicloud.openservices.tablestore.model.PrimaryKeyColumn;
1816
import com.alicloud.openservices.tablestore.model.PrimaryKeyValue;
1917
import com.alicloud.openservices.tablestore.model.PutRowRequest;
2018
import com.alicloud.openservices.tablestore.model.PutRowResponse;
@@ -24,13 +22,10 @@
2422
import com.alicloud.openservices.tablestore.model.RowPutChange;
2523
import com.alicloud.openservices.tablestore.model.StartLocalTransactionResponse;
2624
import com.alicloud.openservices.tablestore.model.TableMeta;
27-
import com.alicloud.openservices.tablestore.model.search.ParallelScanRequest;
28-
import com.alicloud.openservices.tablestore.model.search.ParallelScanResponse;
2925
import com.alicloud.openservices.tablestore.model.sql.SQLQueryRequest;
3026
import com.alicloud.openservices.tablestore.model.sql.SQLQueryResponse;
3127
import com.google.protobuf.Timestamp;
3228
import com.salesforce.multicloudj.common.exceptions.InvalidArgumentException;
33-
import com.salesforce.multicloudj.common.exceptions.SubstrateSdkException;
3429
import com.salesforce.multicloudj.common.exceptions.UnAuthorizedException;
3530
import com.salesforce.multicloudj.docstore.client.Query;
3631
import com.salesforce.multicloudj.docstore.driver.Action;
@@ -68,7 +63,7 @@
6863
import static org.mockito.Mockito.when;
6964

7065
class AliDocStoreTest {
71-
BookWithoutNest book = new BookWithoutNest("YellowBook", "Neil", "WA", Timestamp.newBuilder().setNanos(1000).build(), 3.99f);
66+
BookWithoutNest book = new BookWithoutNest("YellowBook", "Neil", "WA", Timestamp.newBuilder().setNanos(1000).build(), 3.99f, null);
7267
TestDocStore docStore;
7368
SyncClient syncClient;
7469
IndexMeta localIndex1;
@@ -148,8 +143,9 @@ void setup() {
148143
.withInstanceId("something")
149144
.withCollectionOptions(
150145
new CollectionOptions.CollectionOptionsBuilder()
151-
.withPartitionKey("title").withSortKey("publisher").
152-
withTableName("my-table").build()
146+
.withPartitionKey("title").withSortKey("publisher")
147+
.withTableName("my-table")
148+
.withRevisionField("docRevision").build()
153149
).withCredentialsOverrider(credsOverrider).withTableStoreClient(syncClient).build();
154150

155151
localIndex1 = new IndexMeta("local_index_1");
@@ -330,7 +326,7 @@ void testRunGetsWithException() {
330326
List<String> fp3 = new ArrayList<>(List.of("title"));
331327
List<String> fp4 = new ArrayList<>(List.of("publisher"));
332328

333-
BookWithoutNest bookObj = new BookWithoutNest("YellowBook", null, "WA", Timestamp.newBuilder().setNanos(1000).build(), 0);
329+
BookWithoutNest bookObj = new BookWithoutNest("YellowBook", null, "WA", Timestamp.newBuilder().setNanos(1000).build(), 0, null);
334330
List<Action> gets = new ArrayList<>();
335331

336332
TestAction get1 = new TestAction(ActionKind.ACTION_KIND_GET, new Document(bookObj), fp1, null);
@@ -375,7 +371,7 @@ void testRunGets() {
375371
List<String> fp1 = new ArrayList<>(List.of("title", "publisher"));
376372
List<String> fp2 = new ArrayList<>(List.of("publisher", "title")); // Different order of fp1, treated as a different fp.
377373

378-
BookWithoutNest bookObj = new BookWithoutNest("YellowBook", null, "WA", Timestamp.newBuilder().setNanos(1000).build(), 0);
374+
BookWithoutNest bookObj = new BookWithoutNest("YellowBook", null, "WA", Timestamp.newBuilder().setNanos(1000).build(), 0, null);
379375
List<Action> gets = new ArrayList<>();
380376

381377
TestAction get1 = new TestAction(ActionKind.ACTION_KIND_GET, new Document(bookObj), fp1, null);
@@ -427,7 +423,7 @@ void testRunGets() {
427423

428424
@Test
429425
void testBatchGetWithMissingKeys() {
430-
BookWithoutNest bookObj = new BookWithoutNest("YellowBook", null, "WA", Timestamp.newBuilder().setNanos(1000).build(), 0);
426+
BookWithoutNest bookObj = new BookWithoutNest("YellowBook", null, "WA", Timestamp.newBuilder().setNanos(1000).build(), 0, null);
431427
List<Action> gets = new ArrayList<>();
432428
List<String> fp1 = new ArrayList<>(List.of("d"));
433429
TestAction get1 = new TestAction(ActionKind.ACTION_KIND_GET, new Document(bookObj), fp1, null);
@@ -458,7 +454,7 @@ void testBatchGetWithMissingKeys() {
458454

459455
@Test
460456
void testBatchGet() {
461-
BookWithoutNest bookObj = new BookWithoutNest("YellowBook", null, "WA", Timestamp.newBuilder().setNanos(1000).build(), 0);
457+
BookWithoutNest bookObj = new BookWithoutNest("YellowBook", null, "WA", Timestamp.newBuilder().setNanos(1000).build(), 0, null);
462458
List<Action> gets = new ArrayList<>();
463459
List<String> fp1 = new ArrayList<>(List.of("title", "publisher", "author"));
464460
TestAction get1 = new TestAction(ActionKind.ACTION_KIND_GET, new Document(bookObj), fp1, null);
@@ -510,7 +506,27 @@ void testBatchGet() {
510506
@Test
511507
void testCreate() {
512508
Document document = new Document(book);
513-
ali.getActions().create(document).run();
509+
Assertions.assertDoesNotThrow(() -> ali.getActions().create(document).run());
510+
}
511+
512+
@Test
513+
void testPut() {
514+
Document document = new Document(book);
515+
Assertions.assertDoesNotThrow(() -> ali.getActions().put(document).run());
516+
}
517+
518+
@Test
519+
void testPutWithRevision() {
520+
BookWithoutNest bookObj = new BookWithoutNest("YellowBook", null, "WA", Timestamp.newBuilder().setNanos(1000).build(), 0, "something");
521+
Document document = new Document(bookObj);
522+
Assertions.assertDoesNotThrow(() -> ali.getActions().put(document).run());
523+
}
524+
525+
@Test
526+
void testDeleteWithRevision() {
527+
BookWithoutNest bookObj = new BookWithoutNest("YellowBook", null, "WA", Timestamp.newBuilder().setNanos(1000).build(), 0, "something");
528+
Document document = new Document(bookObj);
529+
Assertions.assertDoesNotThrow(() -> ali.getActions().delete(document).run());
514530
}
515531

516532
@Test
@@ -577,7 +593,7 @@ void testRunDelete() {
577593
.withAllowScans(false)
578594
.withMaxOutstandingActionRPCs(10)
579595
.build();
580-
BookWithoutNest bookObj = new BookWithoutNest("YellowBook", null, "WA", Timestamp.newBuilder().setNanos(1000).build(), 0);
596+
BookWithoutNest bookObj = new BookWithoutNest("YellowBook", null, "WA", Timestamp.newBuilder().setNanos(1000).build(), 0, null);
581597
List<Action> deletes = new ArrayList<>();
582598

583599
TestAction delete1 = new TestAction(ActionKind.ACTION_KIND_DELETE, new Document(bookObj), null, null);

docstore/docstore-client/src/test/java/com/salesforce/multicloudj/docstore/driver/testtypes/BookWithoutNest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ public class BookWithoutNest {
1818
@JsonDeserialize(using = TimestampPbDeserializer.class)
1919
public Timestamp publishedDate;
2020
public float price;
21+
String docRevision;
2122
}

0 commit comments

Comments
 (0)