Skip to content

Commit 7c0fb7b

Browse files
SK-3026 added tokens support
1 parent 78fb577 commit 7c0fb7b

9 files changed

Lines changed: 240 additions & 1 deletion

File tree

‎flowvault/src/main/java/com/skyflow/utils/Utils.java‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ public static V1InsertRequest getInsertRequestBody(InsertRequest request, VaultC
148148
if (hasText(record.getTableName())) {
149149
data.tableName(record.getTableName());
150150
}
151+
if (record.getTokens() != null && !record.getTokens().isEmpty()) {
152+
data.tokens(record.getTokens());
153+
}
151154
UpsertOptions recordUpsert = record.getUpsert();
152155
if (recordUpsert != null && recordUpsert.getUniqueColumns() != null
153156
&& !recordUpsert.getUniqueColumns().isEmpty()) {

‎flowvault/src/main/java/com/skyflow/utils/validations/Validations.java‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,37 @@ public static void validateInsertRequest(InsertRequest insertRequest) throws Sky
205205
}
206206
}
207207
}
208+
validateInsertRecordTokens(record.getTokens());
209+
}
210+
}
211+
212+
// Tokens are optional on an insert record, but when supplied the map must not be empty and
213+
// every entry must have a non-blank key and value — mirroring the checks on data above.
214+
private static void validateInsertRecordTokens(Map<String, Object> tokens) throws SkyflowException {
215+
if (tokens == null) {
216+
return;
217+
}
218+
if (tokens.isEmpty()) {
219+
LogUtil.printErrorLog(Utils.parameterizedString(
220+
ErrorLogs.EMPTY_TOKENS.getLog(), InterfaceName.INSERT.getName()
221+
));
222+
throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyTokens.getMessage());
223+
}
224+
for (String key : tokens.keySet()) {
225+
if (key == null || key.trim().isEmpty()) {
226+
LogUtil.printErrorLog(Utils.parameterizedString(
227+
ErrorLogs.EMPTY_OR_NULL_KEY_IN_TOKENS.getLog(), InterfaceName.INSERT.getName()
228+
));
229+
throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyKeyInTokens.getMessage());
230+
}
231+
Object value = tokens.get(key);
232+
if (value == null || value.toString().trim().isEmpty()) {
233+
LogUtil.printErrorLog(Utils.parameterizedString(
234+
ErrorLogs.EMPTY_OR_NULL_VALUE_IN_TOKENS.getLog(),
235+
InterfaceName.INSERT.getName(), key
236+
));
237+
throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyValueInTokens.getMessage());
238+
}
208239
}
209240
}
210241

‎flowvault/src/main/java/com/skyflow/vault/data/BulkInsertRequestRecord.java‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ public BulkInsertRequestRecordBuilder data(Map<String, Object> data) {
3131
return this;
3232
}
3333

34+
@Override
35+
public BulkInsertRequestRecordBuilder tokens(Map<String, Object> tokens) {
36+
super.tokens(tokens);
37+
return this;
38+
}
39+
3440
@Override
3541
public BulkInsertRequestRecordBuilder upsert(UpsertOptions upsert) {
3642
super.upsert(upsert);

‎flowvault/src/main/java/com/skyflow/vault/data/InsertRequestRecord.java‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ public Map<String, Object> getData() {
1818
return this.builder.data;
1919
}
2020

21+
public Map<String, Object> getTokens() {
22+
return this.builder.tokens;
23+
}
24+
2125
public UpsertOptions getUpsert() {
2226
return this.builder.upsert;
2327
}
@@ -26,6 +30,7 @@ public UpsertOptions getUpsert() {
2630
public static class InsertRequestRecordBuilder {
2731
private String tableName;
2832
private Map<String, Object> data;
33+
private Map<String, Object> tokens;
2934
private UpsertOptions upsert;
3035

3136
public InsertRequestRecordBuilder tableName(String tableName) {
@@ -38,6 +43,11 @@ public InsertRequestRecordBuilder data(Map<String, Object> data) {
3843
return this;
3944
}
4045

46+
public InsertRequestRecordBuilder tokens(Map<String, Object> tokens) {
47+
this.tokens = tokens;
48+
return this;
49+
}
50+
4151
public InsertRequestRecordBuilder upsert(UpsertOptions upsert) {
4252
this.upsert = upsert;
4353
return this;

‎flowvault/src/test/java/com/skyflow/utils/RequestFidelityTests.java‎

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ private static ArrayList<InsertRequestRecord> recordList(InsertRequestRecord...
7474
public void testBulkInsert_everyRecordFieldReachesWire() {
7575
Map<String, Object> data = new LinkedHashMap<>();
7676
data.put("name", "john");
77+
Map<String, Object> tokens = new LinkedHashMap<>();
78+
tokens.put("name", "tok-abc");
7779
UpsertOptions upsert = UpsertOptions.builder()
7880
.updateType("UPDATE")
7981
.uniqueColumns(Arrays.asList("email", "phone"))
@@ -82,6 +84,7 @@ public void testBulkInsert_everyRecordFieldReachesWire() {
8284
BulkInsertRequestRecord record = BulkInsertRequestRecord.builder()
8385
.tableName("cards")
8486
.data(data)
87+
.tokens(tokens)
8588
.upsert(upsert)
8689
.build();
8790
BulkInsertRequest request = BulkInsertRequest.builder()
@@ -97,6 +100,7 @@ public void testBulkInsert_everyRecordFieldReachesWire() {
97100
Assert.assertEquals("cards", wire.getTableName().get());
98101
// The user's own map instances must be handed to the wire object untouched.
99102
Assert.assertSame(data, wire.getData().get());
103+
Assert.assertSame(tokens, wire.getTokens().get());
100104
Assert.assertEquals(FlowEnumUpdateType.UPDATE, wire.getUpsert().get().getUpdateType().get());
101105
Assert.assertEquals(Arrays.asList("email", "phone"), wire.getUpsert().get().getUniqueColumns().get());
102106
}
@@ -106,10 +110,13 @@ public void testBulkInsert_nonAsciiAndSpacedValues_userValueReachesWire() {
106110
Map<String, Object> data = new LinkedHashMap<>();
107111
data.put("name", NON_ASCII_NAME);
108112
data.put("street address", "12 東京都 千代田区");
113+
Map<String, Object> tokens = new LinkedHashMap<>();
114+
tokens.put("name", "tök-ábc 123");
109115

110116
BulkInsertRequestRecord record = BulkInsertRequestRecord.builder()
111117
.tableName(NON_ASCII_TABLE)
112118
.data(data)
119+
.tokens(tokens)
113120
.build();
114121
BulkInsertRequest request = BulkInsertRequest.builder()
115122
.tableName(SPACED_TABLE)
@@ -123,6 +130,7 @@ public void testBulkInsert_nonAsciiAndSpacedValues_userValueReachesWire() {
123130
Assert.assertEquals(NON_ASCII_TABLE, wire.getTableName().get());
124131
Assert.assertEquals(NON_ASCII_NAME, wire.getData().get().get("name"));
125132
Assert.assertEquals("12 東京都 千代田区", wire.getData().get().get("street address"));
133+
Assert.assertEquals("tök-ábc 123", wire.getTokens().get().get("name"));
126134
}
127135

128136
@Test
@@ -517,6 +525,65 @@ private static com.skyflow.generated.rest.types.V1Upsert upsertWire(String updat
517525
.getRecords().get().get(0).getUpsert().get();
518526
}
519527

528+
// ── insert: tokens map ───────────────────────────────────────────────────
529+
530+
@Test
531+
public void testBulkInsert_emptyTokensMapIsOmittedFromWire() {
532+
// Validations.validateInsertRequest rejects an explicitly-set-but-empty tokens map before
533+
// the body builder runs; this pins the builder's own behavior when called directly.
534+
Map<String, Object> data = new HashMap<>();
535+
data.put("name", "john");
536+
BulkInsertRequestRecord record = BulkInsertRequestRecord.builder()
537+
.tableName("cards")
538+
.data(data)
539+
.tokens(new HashMap<>())
540+
.build();
541+
BulkInsertRequest request = BulkInsertRequest.builder().records(recordList(record)).build();
542+
543+
V1InsertRequest body = Utils.getBulkInsertRequestBody(request, vaultConfig());
544+
545+
Assert.assertFalse(body.getRecords().get().get(0).getTokens().isPresent());
546+
}
547+
548+
@Test
549+
public void testBulkInsert_nullTokensMapIsOmittedFromWire() {
550+
Map<String, Object> data = new HashMap<>();
551+
data.put("name", "john");
552+
BulkInsertRequestRecord record = BulkInsertRequestRecord.builder()
553+
.tableName("cards")
554+
.data(data)
555+
.build();
556+
BulkInsertRequest request = BulkInsertRequest.builder().records(recordList(record)).build();
557+
558+
V1InsertRequest body = Utils.getBulkInsertRequestBody(request, vaultConfig());
559+
560+
Assert.assertFalse(body.getRecords().get().get(0).getTokens().isPresent());
561+
}
562+
563+
@Test
564+
public void testBulkInsert_multiValueTokensMapReachesWireVerbatim() {
565+
Map<String, Object> data = new HashMap<>();
566+
data.put("name", "john");
567+
Map<String, Object> tokens = new LinkedHashMap<>();
568+
tokens.put("name", "tok-1");
569+
tokens.put("ssn", "tok-2");
570+
tokens.put("nested", Collections.singletonMap("group", "tok-3"));
571+
BulkInsertRequestRecord record = BulkInsertRequestRecord.builder()
572+
.tableName("cards")
573+
.data(data)
574+
.tokens(tokens)
575+
.build();
576+
BulkInsertRequest request = BulkInsertRequest.builder().records(recordList(record)).build();
577+
578+
V1InsertRequest body = Utils.getBulkInsertRequestBody(request, vaultConfig());
579+
580+
Map<String, Object> wireTokens = body.getRecords().get().get(0).getTokens().get();
581+
Assert.assertSame(tokens, wireTokens);
582+
Assert.assertEquals("tok-1", wireTokens.get("name"));
583+
Assert.assertEquals("tok-2", wireTokens.get("ssn"));
584+
Assert.assertEquals(Collections.singletonMap("group", "tok-3"), wireTokens.get("nested"));
585+
}
586+
520587
// ─────────────────────────────────────────────────────────────────────────
521588
// Bulk detokenize
522589
// ─────────────────────────────────────────────────────────────────────────

‎flowvault/src/test/java/com/skyflow/utils/UtilsTests.java‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,24 @@ public void testGetInsertRequestBody_keepsRequestLevelTableNameOnEnvelopeOnly()
258258
Assert.assertFalse(body.getRecords().get().get(0).getTableName().isPresent());
259259
}
260260

261+
@Test
262+
public void testGetInsertRequestBody_withTokens() {
263+
Map<String, Object> data = new HashMap<>();
264+
data.put("name", "john");
265+
Map<String, Object> tokens = new HashMap<>();
266+
tokens.put("name", "tok-abc");
267+
InsertRequestRecord record = InsertRequestRecord.builder().tableName("table1").data(data).tokens(tokens).build();
268+
ArrayList<InsertRequestRecord> records = new ArrayList<>();
269+
records.add(record);
270+
InsertRequest request = InsertRequest.builder().records(records).build();
271+
VaultConfig config = new VaultConfig();
272+
config.setVaultId("vault123");
273+
274+
V1InsertRequest body = Utils.getInsertRequestBody(request, config);
275+
276+
Assert.assertEquals(tokens, body.getRecords().get().get(0).getTokens().get());
277+
}
278+
261279
@Test
262280
public void testGetInsertRequestBody_withUpsertAtRequestLevel() {
263281
Map<String, Object> data = new HashMap<>();

‎flowvault/src/test/java/com/skyflow/utils/validations/ValidationsTests.java‎

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,93 @@ public void testValidateInsertRequest_validRequestWithUpsertAtRecordLevel() {
554554
}
555555
}
556556

557+
@Test
558+
public void testValidateInsertRequest_validRequestWithTokens() {
559+
Map<String, Object> tokens = new HashMap<>();
560+
tokens.put("name", "tok-abc");
561+
ArrayList<InsertRequestRecord> records = new ArrayList<>();
562+
records.add(InsertRequestRecord.builder().tableName("table1").tokens(tokens).build());
563+
InsertRequest request = InsertRequest.builder().records(records).build();
564+
try {
565+
Validations.validateInsertRequest(request);
566+
} catch (SkyflowException e) {
567+
Assert.fail(INVALID_EXCEPTION_THROWN);
568+
}
569+
}
570+
571+
@Test
572+
public void testValidateInsertRequest_emptyTokensMapThrows() {
573+
ArrayList<InsertRequestRecord> records = new ArrayList<>();
574+
records.add(InsertRequestRecord.builder().tableName("table1").tokens(new HashMap<>()).build());
575+
InsertRequest request = InsertRequest.builder().records(records).build();
576+
try {
577+
Validations.validateInsertRequest(request);
578+
Assert.fail(EXCEPTION_NOT_THROWN);
579+
} catch (SkyflowException e) {
580+
Assert.assertEquals(ErrorMessage.EmptyTokens.getMessage(), e.getMessage());
581+
}
582+
}
583+
584+
@Test
585+
public void testValidateInsertRequest_nullKeyInTokensThrows() {
586+
Map<String, Object> tokens = new HashMap<>();
587+
tokens.put(null, "tok-abc");
588+
ArrayList<InsertRequestRecord> records = new ArrayList<>();
589+
records.add(InsertRequestRecord.builder().tableName("table1").tokens(tokens).build());
590+
InsertRequest request = InsertRequest.builder().records(records).build();
591+
try {
592+
Validations.validateInsertRequest(request);
593+
Assert.fail(EXCEPTION_NOT_THROWN);
594+
} catch (SkyflowException e) {
595+
Assert.assertEquals(ErrorMessage.EmptyKeyInTokens.getMessage(), e.getMessage());
596+
}
597+
}
598+
599+
@Test
600+
public void testValidateInsertRequest_blankKeyInTokensThrows() {
601+
Map<String, Object> tokens = new HashMap<>();
602+
tokens.put(" ", "tok-abc");
603+
ArrayList<InsertRequestRecord> records = new ArrayList<>();
604+
records.add(InsertRequestRecord.builder().tableName("table1").tokens(tokens).build());
605+
InsertRequest request = InsertRequest.builder().records(records).build();
606+
try {
607+
Validations.validateInsertRequest(request);
608+
Assert.fail(EXCEPTION_NOT_THROWN);
609+
} catch (SkyflowException e) {
610+
Assert.assertEquals(ErrorMessage.EmptyKeyInTokens.getMessage(), e.getMessage());
611+
}
612+
}
613+
614+
@Test
615+
public void testValidateInsertRequest_nullValueInTokensThrows() {
616+
Map<String, Object> tokens = new HashMap<>();
617+
tokens.put("name", null);
618+
ArrayList<InsertRequestRecord> records = new ArrayList<>();
619+
records.add(InsertRequestRecord.builder().tableName("table1").tokens(tokens).build());
620+
InsertRequest request = InsertRequest.builder().records(records).build();
621+
try {
622+
Validations.validateInsertRequest(request);
623+
Assert.fail(EXCEPTION_NOT_THROWN);
624+
} catch (SkyflowException e) {
625+
Assert.assertEquals(ErrorMessage.EmptyValueInTokens.getMessage(), e.getMessage());
626+
}
627+
}
628+
629+
@Test
630+
public void testValidateInsertRequest_blankValueInTokensThrows() {
631+
Map<String, Object> tokens = new HashMap<>();
632+
tokens.put("name", " ");
633+
ArrayList<InsertRequestRecord> records = new ArrayList<>();
634+
records.add(InsertRequestRecord.builder().tableName("table1").tokens(tokens).build());
635+
InsertRequest request = InsertRequest.builder().records(records).build();
636+
try {
637+
Validations.validateInsertRequest(request);
638+
Assert.fail(EXCEPTION_NOT_THROWN);
639+
} catch (SkyflowException e) {
640+
Assert.assertEquals(ErrorMessage.EmptyValueInTokens.getMessage(), e.getMessage());
641+
}
642+
}
643+
557644
// ── validateDetokenizeRequest ─────────────────────────────────────────────
558645

559646
@Test
@@ -872,13 +959,16 @@ public void testValidateBulkInsertRequest_validRequest() {
872959
}
873960

874961
@Test
875-
public void testValidateBulkInsertRequest_validRequestWithUpsert() {
962+
public void testValidateBulkInsertRequest_validRequestWithUpsertAndTokens() {
876963
Map<String, Object> data = new HashMap<>();
877964
data.put("name", "john");
965+
Map<String, Object> tokens = new HashMap<>();
966+
tokens.put("name", "tok-abc");
878967
ArrayList<InsertRequestRecord> records = new ArrayList<>();
879968
records.add(BulkInsertRequestRecord.builder()
880969
.tableName("table1")
881970
.data(data)
971+
.tokens(tokens)
882972
.upsert(UpsertOptions.builder()
883973
.updateType("REPLACE")
884974
.uniqueColumns(Collections.singletonList("email"))

0 commit comments

Comments
 (0)