Skip to content

feat(sdk): add EntityIdentifier convenience constructors#346

Merged
marythought merged 2 commits intomainfrom
feat/DSPX-2793-entity-identifier-helpers
Apr 9, 2026
Merged

feat(sdk): add EntityIdentifier convenience constructors#346
marythought merged 2 commits intomainfrom
feat/DSPX-2793-entity-identifier-helpers

Conversation

@marythought
Copy link
Copy Markdown
Contributor

@marythought marythought commented Apr 9, 2026

Summary

  • Add EntityIdentifiers utility class with static helpers mirroring the Go SDK's ForEmail, ForClientID, ForUserName, and ForToken constructors
  • Reduces EntityIdentifier construction from ~10 lines of nested builders to a single call

Before:

GetDecisionRequest request = GetDecisionRequest.newBuilder()
    .setEntityIdentifier(
        EntityIdentifier.newBuilder()
            .setEntityChain(
                EntityChain.newBuilder()
                    .addEntities(
                        Entity.newBuilder()
                            .setEmailAddress("jen@example.com")
                            .setCategory(Entity.Category.CATEGORY_SUBJECT))))
    .setAction(Action.newBuilder().setName("read"))
    .setResource(
        Resource.newBuilder()
            .setAttributeValues(
                Resource.AttributeValues.newBuilder()
                    .addFqns("https://example.com/attr/department/value/finance")))
    .build();

After:

GetDecisionRequest request = GetDecisionRequest.newBuilder()
    .setEntityIdentifier(EntityIdentifiers.forEmail("jen@example.com"))
    .setAction(Action.newBuilder().setName("read"))
    .setResource(
        Resource.newBuilder()
            .setAttributeValues(
                Resource.AttributeValues.newBuilder()
                    .addFqns("https://example.com/attr/department/value/finance")))
    .build();

Test plan

  • EntityIdentifiersTest — 8 tests covering all 4 helpers with valid and empty string inputs

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added convenient factory methods to create entity identifiers from email addresses, client IDs, usernames, or JWT tokens, returning ready-to-use identifier objects.
  • Tests

    • Added comprehensive parameterized tests for these factory methods, covering empty-string inputs and null-argument error handling, and verifying the produced identifier structures and token contents.

Add EntityIdentifiers utility class with static helpers that mirror
the Go SDK's ForEmail, ForClientID, ForUserName, and ForToken
constructors. Reduces EntityIdentifier construction from ~10 lines
of nested builders to a single method call.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Mary Dickson <mary.dickson@virtru.com>
@marythought marythought requested review from a team as code owners April 9, 2026 14:35
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 9, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a2bc57d2-a718-472f-baff-6d632429f18b

📥 Commits

Reviewing files that changed from the base of the PR and between 9125b74 and 9b8b01f.

📒 Files selected for processing (2)
  • sdk/src/main/java/io/opentdf/platform/sdk/EntityIdentifiers.java
  • sdk/src/test/java/io/opentdf/platform/sdk/EntityIdentifiersTest.java
🚧 Files skipped from review as they are similar to previous changes (2)
  • sdk/src/main/java/io/opentdf/platform/sdk/EntityIdentifiers.java
  • sdk/src/test/java/io/opentdf/platform/sdk/EntityIdentifiersTest.java

📝 Walkthrough

Walkthrough

Added a new non-instantiable utility class EntityIdentifiers with static factory methods to build EntityIdentifier instances for email, client ID, username, and JWT token. Added unit tests exercising each factory method and null-input behavior.

Changes

Cohort / File(s) Summary
EntityIdentifiers Utility & Tests
sdk/src/main/java/io/opentdf/platform/sdk/EntityIdentifiers.java, sdk/src/test/java/io/opentdf/platform/sdk/EntityIdentifiersTest.java
New final utility class providing forEmail, forClientId, forUserName, and forToken static factory methods. Methods validate non-null inputs, construct Entity/EntityChain wrappers or Token-based identifiers. Companion parameterized tests verify identifier cases, entity content, category, token contents, and null-input exceptions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I stitch identifiers, one by one,
Email, client, username—hop, they're done.
A token tucked in, secure and neat,
Tests nibble through each little beat.
Hooray for factories, compact and sweet!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: introducing convenience constructor methods (static factory methods) for EntityIdentifier that simplify object construction.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/DSPX-2793-entity-identifier-helpers

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
sdk/src/test/java/io/opentdf/platform/sdk/EntityIdentifiersTest.java (1)

73-77: Add null-input contract tests once constructor behavior is finalized.

If you keep/introduce explicit null preconditions, add assertThrows tests for forEmail, forClientId, forUserName, and forToken so the SDK contract stays enforced.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk/src/test/java/io/opentdf/platform/sdk/EntityIdentifiersTest.java` around
lines 73 - 77, Add null-input contract tests in EntityIdentifiersTest: write
assertThrows assertions for EntityIdentifier factory methods forEmail,
forClientId, forUserName, and forToken to validate they throw on null input once
the constructor/null-precondition behavior is finalized; update or add test
methods that call EntityIdentifiers.forEmail(null),
EntityIdentifiers.forClientId(null), EntityIdentifiers.forUserName(null), and
EntityIdentifiers.forToken(null) and assertThrows the expected exception type
(e.g., NullPointerException or IllegalArgumentException) to keep the SDK
contract enforced.
sdk/src/main/java/io/opentdf/platform/sdk/EntityIdentifiers.java (1)

35-69: Define explicit null-input behavior for public constructors.

These helpers are part of the SDK surface; adding explicit null preconditions would make failures predictable and error messages clearer.

Proposed refactor
 package io.opentdf.platform.sdk;
 
 import io.opentdf.platform.authorization.v2.EntityIdentifier;
 import io.opentdf.platform.entity.Entity;
 import io.opentdf.platform.entity.EntityChain;
 import io.opentdf.platform.entity.Token;
+import java.util.Objects;
@@
     public static EntityIdentifier forEmail(String email) {
+        email = Objects.requireNonNull(email, "email must not be null");
         return fromEntity(Entity.newBuilder()
                 .setEmailAddress(email)
                 .setCategory(Entity.Category.CATEGORY_SUBJECT)
                 .build());
     }
@@
     public static EntityIdentifier forClientId(String clientId) {
+        clientId = Objects.requireNonNull(clientId, "clientId must not be null");
         return fromEntity(Entity.newBuilder()
                 .setClientId(clientId)
                 .setCategory(Entity.Category.CATEGORY_SUBJECT)
                 .build());
     }
@@
     public static EntityIdentifier forUserName(String userName) {
+        userName = Objects.requireNonNull(userName, "userName must not be null");
         return fromEntity(Entity.newBuilder()
                 .setUserName(userName)
                 .setCategory(Entity.Category.CATEGORY_SUBJECT)
                 .build());
     }
@@
     public static EntityIdentifier forToken(String jwt) {
+        jwt = Objects.requireNonNull(jwt, "jwt must not be null");
         return EntityIdentifier.newBuilder()
                 .setToken(Token.newBuilder().setJwt(jwt).build())
                 .build();
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk/src/main/java/io/opentdf/platform/sdk/EntityIdentifiers.java` around
lines 35 - 69, The public factory methods forEmail, forClientId, forUserName,
and forToken should validate their inputs and fail fast with a clear exception;
update each method (forEmail, forClientId, forUserName, forToken) to explicitly
check for null (e.g., using Objects.requireNonNull or throwing an
IllegalArgumentException/NullPointerException with a descriptive message) before
building the Entity/Token, so callers receive a predictable error when a null
argument is passed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@sdk/src/main/java/io/opentdf/platform/sdk/EntityIdentifiers.java`:
- Around line 35-69: The public factory methods forEmail, forClientId,
forUserName, and forToken should validate their inputs and fail fast with a
clear exception; update each method (forEmail, forClientId, forUserName,
forToken) to explicitly check for null (e.g., using Objects.requireNonNull or
throwing an IllegalArgumentException/NullPointerException with a descriptive
message) before building the Entity/Token, so callers receive a predictable
error when a null argument is passed.

In `@sdk/src/test/java/io/opentdf/platform/sdk/EntityIdentifiersTest.java`:
- Around line 73-77: Add null-input contract tests in EntityIdentifiersTest:
write assertThrows assertions for EntityIdentifier factory methods forEmail,
forClientId, forUserName, and forToken to validate they throw on null input once
the constructor/null-precondition behavior is finalized; update or add test
methods that call EntityIdentifiers.forEmail(null),
EntityIdentifiers.forClientId(null), EntityIdentifiers.forUserName(null), and
EntityIdentifiers.forToken(null) and assertThrows the expected exception type
(e.g., NullPointerException or IllegalArgumentException) to keep the SDK
contract enforced.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4e4a4d08-577a-4f51-85f1-8baa0f2d7e7c

📥 Commits

Reviewing files that changed from the base of the PR and between 982b287 and 9125b74.

📒 Files selected for processing (2)
  • sdk/src/main/java/io/opentdf/platform/sdk/EntityIdentifiers.java
  • sdk/src/test/java/io/opentdf/platform/sdk/EntityIdentifiersTest.java

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the EntityIdentifiers utility class to the Java SDK, providing static factory methods for creating EntityIdentifier objects from emails, client IDs, usernames, and JWT tokens. Accompanying unit tests were also added. Review feedback recommends implementing explicit null checks for input parameters in the factory methods to prevent NullPointerException and suggests refactoring the token tests into a single parameterized test for improved consistency and maintainability.

Address CodeRabbit review:
- Add Objects.requireNonNull to all four factory methods
- Consolidate forToken tests into a parameterized test
- Add null-input contract test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Mary Dickson <mary.dickson@virtru.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

X-Test Failure Report

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 9, 2026

@marythought
Copy link
Copy Markdown
Contributor Author

Both nitpicks addressed in 9b8b01f:

  • Added Objects.requireNonNull to all four factory methods
  • Added nullInputsThrow test covering all four methods

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

@marythought marythought merged commit eeb8805 into main Apr 9, 2026
19 checks passed
@marythought marythought deleted the feat/DSPX-2793-entity-identifier-helpers branch April 9, 2026 15:22
marythought pushed a commit that referenced this pull request Apr 9, 2026
🤖 I have created a release *beep* *boop*
---


<details><summary>0.13.0</summary>

##
[0.13.0](v0.12.0...v0.13.0)
(2026-04-09)


### Features

* **sdk:** add EntityIdentifier convenience constructors
([#346](#346))
([eeb8805](eeb8805))
* **sdk:** DSPX-2418 add discovery convenience methods
([#339](#339))
([8de6068](8de6068))
* **sdk:** expose SRT signer
([#329](#329))
([f93d332](f93d332))


### Bug Fixes

* add a default assertion id if one is not specified
([#341](#341))
([69d6a53](69d6a53))
* **docs:** DSPX-2409 replace SDK README code example with working code
([#336](#336))
([0f224a6](0f224a6))
* **sdk:** Support kas keys with extended EC methods
([#344](#344))
([982b287](982b287))
* **sdk:** Support RSA4096 Kas keys
([#343](#343))
([dba9bbf](dba9bbf))
* **sdk:** Updates to proto version v0.16.0
([#308](#308))
([4660e27](4660e27))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: opentdf-automation[bot] <149537512+opentdf-automation[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants