Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion flowvault/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -767,7 +767,7 @@ Every bulk response exposes `getSummary()` and `getRecords()`. The records list
| `getError()` | failures only | Error message for this item. `null` means this item succeeded. |
| `getRequestId()` | failures only | The `x-request-id` of the batch this item was in — quote it in support escalations. Items from the same batch share one id. |

The success payload sits alongside those fields on the same object: `getSkyflowId()`/`getTokens()`/`getData()` for insert (`getFields()` is a deprecated alias for `getTokens()`), `getValue()`/`getTokenGroupName()`/`getMetadata()` for detokenize, `getTokens()` for tokenize, `getToken()` for delete.
The success payload sits alongside those fields on the same object: `getSkyflowId()`/`getTokens()`/`getData()` for insert (`getFields()` is deprecated — it returns the same data in its original, pre-typed `Map<String, Object>` shape, not `getTokens()`'s `Token` objects), `getValue()`/`getTokenGroupName()`/`getMetadata()` for detokenize, `getTokens()` for tokenize, `getToken()` for delete.

Summaries per operation:

Expand Down
Binary file modifiedflowvault/api-report/skyflow-flowvault-java.baseline.jar
Binary file not shown.
Original file line numberDiff line numberDiff line change
Expand Up@@ -55,12 +55,15 @@ public Map<String, List<Token>> getTokens() {
}

/**
* @deprecated Response key 'fields' is deprecated. Use {@link #getTokens()} instead.
* @deprecated Response key 'fields' is deprecated. Use {@link #getTokens()} instead. This
* still returns {@code Map<String, Object>}, matching its original (pre-typed) contract —
* see {@link Token#toRawTokens(Map)} for how {@link #getTokens()}'s typed data is rendered
* back into that generic shape.
*/
@Deprecated(since = "1.0.2", forRemoval = true)
public Map<String, List<Token>> getFields() {
public Map<String, Object> getFields() {
LogUtil.printWarningLog(InfoLogs.DEPRECATED_INSERT_FIELDS_GETTER.getLog());
return getTokens();
return Token.toRawTokens(getTokens());
}

public Map<String, Object> getData() {
Expand Down
31 changes: 31 additions & 0 deletions flowvault/src/main/java/com/skyflow/vault/data/Token.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -100,4 +100,35 @@ private static Token toToken(Object entry) {
}
return null;
}

/**
* The inverse of {@link #parseTokens(Map)}: renders parsed {@link Token} objects back into
* the generic {@code Map<String, Object>} shape {@code getFields()} returned before it was
* deprecated, for callers who haven't migrated to {@link InsertResponseRecord#getTokens()}
* yet. Each column's value becomes a {@code List<Map<String, Object>>}, one map per
* {@code Token} with {@code "token"}/{@code "tokenGroupName"} keys — this doesn't reproduce
* the exact original wire shape (a single-group column may originally have been a bare
* value or an unwrapped map rather than a one-element list), since that distinction is lost
* once parsed, but it's a consistent, self-describing shape every caller can read the same
* way regardless of how many groups a column has.
*
* <p>Returns {@code null} when {@code tokens} is {@code null}.
*/
static Map<String, Object> toRawTokens(Map<String, List<Token>> tokens) {
if (tokens == null) {
return null;
}
Map<String, Object> raw = new LinkedHashMap<>();
for (Map.Entry<String, List<Token>> entry : tokens.entrySet()) {
List<Map<String, Object>> rawEntries = new ArrayList<>();
for (Token token : entry.getValue()) {
Map<String, Object> rawEntry = new LinkedHashMap<>();
rawEntry.put("token", token.getToken());
rawEntry.put("tokenGroupName", token.getTokenGroupName());
rawEntries.add(rawEntry);
}
raw.put(entry.getKey(), rawEntries);
}
return raw;
}
}
10 changes: 8 additions & 2 deletions flowvault/src/test/java/com/skyflow/utils/UtilsTests.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -1704,8 +1704,14 @@ public void testFormatBulkInsertResponse_success() {
// The wire type's raw tokens map is parsed into typed Token objects before reaching the
// caller - see ResponseComponentTests's Token.parseTokens() tests for the parsing logic.
Assert.assertEquals("tok-abc", inserted.getTokens().get("name").get(0).getToken());
// getFields() is deprecated but still delegates to getTokens() for backward compatibility.
Assert.assertEquals("tok-abc", inserted.getFields().get("name").get(0).getToken());
// getFields() is deprecated, and now renders that typed data back into its original
// Map<String, Object> shape rather than returning getTokens()'s value directly - a bare
// string column comes back as a one-element List<Map> instead of the original bare value,
// since that distinction is lost once the raw data is parsed into Token objects.
Object nameField = inserted.getFields().get("name");
Map<?, ?> nameToken = (Map<?, ?>) ((List<?>) nameField).get(0);
Assert.assertEquals("tok-abc", nameToken.get("token"));
Assert.assertNull(nameToken.get("tokenGroupName"));
Assert.assertEquals(data, inserted.getData());
Assert.assertEquals(0, inserted.getIndex());
Assert.assertEquals(200, inserted.getHttpCode());
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -706,8 +706,10 @@ public void testBulkInsert_successWithListOfMapsTokenShape() throws Exception {

BulkInsertResponseRecord inserted = response.getRecords().get(0);
Assert.assertNotNull(inserted.getTokens());
// getFields() is deprecated but still delegates to getTokens() for backward compatibility.
Assert.assertEquals(inserted.getTokens(), inserted.getFields());
// getFields() is deprecated and now renders getTokens()'s typed data back into its
// original raw shape - a lossless round trip for this input, so it equals the raw map
// the mock returned in the first place.
Assert.assertEquals(tokens, inserted.getFields());
// The wire type's List<Map> token shape is parsed into typed Token objects - no casting.
List<Token> field1Tokens = inserted.getTokens().get("field1");
Assert.assertEquals(1, field1Tokens.size());
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,8 +73,14 @@ public void testBulkInsertResponse_recordsPreserveIndexAndInheritedFields() {
Assert.assertEquals("table1", actual.getTableName());
Assert.assertEquals("id-1", actual.getSkyflowId());
Assert.assertEquals(tokens, actual.getTokens());
// getFields() is deprecated but still delegates to getTokens() for backward compatibility.
Assert.assertEquals(tokens, actual.getFields());
// getFields() is deprecated, and now returns its original (pre-typed) shape - a Map<String,
// Object> rendered back from the typed getTokens() data, not getTokens()'s value itself.
Map<String, Object> rawToken = new HashMap<>();
rawToken.put("token", "token-name");
rawToken.put("tokenGroupName", "group1");
Map<String, Object> expectedFields = new HashMap<>();
expectedFields.put("name", Collections.singletonList(rawToken));
Assert.assertEquals(expectedFields, actual.getFields());
Assert.assertEquals(data, actual.getData());
Assert.assertEquals(hashedData, actual.getHashedData());
Assert.assertEquals(200, actual.getHttpCode());
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,6 +19,18 @@
*/
public class ResponseComponentTests {

// getFields()'s deprecated, pre-typed shape for a single column with one token group -
// {"name": [{"token": "tok-1", "tokenGroupName": "group1"}]} - matching
// tokens.put("name", Collections.singletonList(new Token("tok-1", "group1"))).
private static Map<String, Object> singleColumnRawFields() {
Map<String, Object> rawToken = new HashMap<>();
rawToken.put("token", "tok-1");
rawToken.put("tokenGroupName", "group1");
Map<String, Object> rawFields = new HashMap<>();
rawFields.put("name", Collections.singletonList(rawToken));
return rawFields;
}

// Tests for Success and Summary were removed: the bulk insert response contract replaced
// those classes with BulkInsertResponseRecord / BulkSummary, covered below. Token was removed
// in the same rework, then reintroduced (with the same shape it had before) as the type
Expand All@@ -42,8 +54,9 @@ public void testBulkInsertResponseRecord_gettersReturnConstructorValues() {
Assert.assertEquals("persons", record.getTableName());
Assert.assertEquals("skyflow-id-1", record.getSkyflowId());
Assert.assertEquals(tokens, record.getTokens());
// getFields() is deprecated but still delegates to getTokens() for backward compatibility.
Assert.assertEquals(tokens, record.getFields());
// getFields() is deprecated, and now returns its original (pre-typed) shape - a Map<String,
// Object> rendered back from the typed getTokens() data, not getTokens()'s value itself.
Assert.assertEquals(singleColumnRawFields(), record.getFields());
Assert.assertEquals(data, record.getData());
Assert.assertEquals(hashedData, record.getHashedData());
Assert.assertEquals(200, record.getHttpCode());
Expand All@@ -67,7 +80,7 @@ public void testBulkInsertResponseRecord_deprecatedConstructorAndGetFieldsStillW
2, "persons", "skyflow-id-1", tokens, hashedData, 200, null, null);

Assert.assertEquals(tokens, record.getTokens());
Assert.assertEquals(tokens, record.getFields());
Assert.assertEquals(singleColumnRawFields(), record.getFields());
Assert.assertNull(record.getData());
Assert.assertEquals(hashedData, record.getHashedData());
}
Expand All@@ -89,7 +102,7 @@ public void testInsertResponseRecord_deprecatedConstructorDefaultsDataToNull() {
Assert.assertEquals("persons", record.getTableName());
Assert.assertEquals("skyflow-id-1", record.getSkyflowId());
Assert.assertEquals(tokens, record.getTokens());
Assert.assertEquals(tokens, record.getFields());
Assert.assertEquals(singleColumnRawFields(), record.getFields());
Assert.assertNull(record.getData());
Assert.assertEquals(hashedData, record.getHashedData());
Assert.assertEquals(200, record.getHttpCode());
Expand DownExpand Up@@ -254,6 +267,53 @@ public void testParseTokens_skipsNullEntriesWithinAList() {
Assert.assertEquals("tok-a", col1.get(0).getToken());
}

@Test
public void testToRawTokens_returnsNullWhenTokensIsNull() {
Assert.assertNull(Token.toRawTokens(null));
}

@Test
public void testToRawTokens_rendersEachTokenAsAMapWithBothKeys() {
Map<String, List<Token>> tokens = new HashMap<>();
tokens.put("col1", Collections.singletonList(new Token("tok-a", "tg1")));

Map<String, Object> raw = Token.toRawTokens(tokens);

List<?> col1 = (List<?>) raw.get("col1");
Assert.assertEquals(1, col1.size());
Map<?, ?> entry = (Map<?, ?>) col1.get(0);
Assert.assertEquals("tok-a", entry.get("token"));
Assert.assertEquals("tg1", entry.get("tokenGroupName"));
}

@Test
public void testToRawTokens_rendersMultipleTokenGroupsAsSeparateMapEntries() {
Map<String, List<Token>> tokens = new HashMap<>();
tokens.put("col1", Arrays.asList(new Token("tok-a", "tg1"), new Token("tok-b", "tg2")));

List<?> col1 = (List<?>) Token.toRawTokens(tokens).get("col1");

Assert.assertEquals(2, col1.size());
Assert.assertEquals("tok-a", ((Map<?, ?>) col1.get(0)).get("token"));
Assert.assertEquals("tok-b", ((Map<?, ?>) col1.get(1)).get("token"));
}

@Test
public void testToRawTokens_isTheInverseOfParseTokensForMapShapedInput() {
// parseTokens() followed by toRawTokens() round-trips losslessly when every column's raw
// value was already a {token, tokenGroupName} map (or list of them) - the shape toRawTokens
// always produces. Only the bare-value case (see UtilsTests) loses information on the way.
Map<String, Object> entry = new HashMap<>();
entry.put("token", "tok-a");
entry.put("tokenGroupName", "tg1");
Map<String, Object> rawTokens = new HashMap<>();
rawTokens.put("col1", Collections.singletonList(entry));

Map<String, Object> roundTripped = Token.toRawTokens(Token.parseTokens(rawTokens));

Assert.assertEquals(rawTokens, roundTripped);
}

// ── BulkSummary ──────────────────────────────────────────────────────────

@Test
Expand Down
Loading