From f3842a9250b3e55161f32cb2972c89609a474e13 Mon Sep 17 00:00:00 2001 From: tanya732 Date: Tue, 14 Jul 2026 11:17:30 +0530 Subject: [PATCH 1/3] feat: add MIGRATION_GUIDE --- MIGRATION_GUIDE.md | 380 +++++++-------------------------------------- 1 file changed, 60 insertions(+), 320 deletions(-) diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index 9d98602c3..1617592a6 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -1,369 +1,109 @@ -# V3 Migration Guide +# Migrating from v3 to v4 -A guide to migrating the Auth0 Java SDK from `v2` to `v3`. +`v4` is a compatible evolution of `v3`. The Authentication API is unchanged, and the Management API keeps the same client structure, builder patterns, and pagination introduced in `v3`. The breaking changes are narrow and limited to a few generated Management API types where field types were tightened for correctness or split for type-safety. -- [Overall changes](#overall-changes) - - [Java versions](#java-versions) - - [Authentication API](#authentication-api) - - [Management API](#management-api) -- [Specific changes to the Management API](#specific-changes-to-the-management-api) - - [Client initialization](#client-initialization) - - [Sub-client organization](#sub-client-organization) - - [Request and response patterns](#request-and-response-patterns) - - [Pagination](#pagination) - - [Exception handling](#exception-handling) - - [Accessing raw HTTP responses](#accessing-raw-http-responses) - - [Request-level configuration](#request-level-configuration) - - [Type changes](#type-changes) +- [Overview](#overview) +- [Breaking changes](#breaking-changes) + - [1. Role pagination fields are now non-optional primitives](#1-role-pagination-fields-are-now-non-optional-primitives) + - [2. Connection attribute `identifier` is split by attribute type](#2-connection-attribute-identifier-is-split-by-attribute-type) + - [3. Phone provider protection backoff strategy enum value changed](#3-phone-provider-protection-backoff-strategy-enum-value-changed) +- [Migration steps](#migration-steps) -## Overall changes +## Overview -### Java versions +Most `v3` code compiles and runs unchanged on `v4`. You only need to act if your code touches one of the following: -Both v2 and v3 require Java 8 or above. +| Area | What changed | Impact | +|------|--------------|--------| +| `ListRolesOffsetPaginatedResponseContent` | `start` / `limit` / `total` changed from `Optional` to primitive `double`, and are now required builder stages | Callers reading these getters or constructing the type | +| Connection attributes | The shared `ConnectionAttributeIdentifier` type is removed and replaced by dedicated `EmailAttributeIdentifier`, `PhoneAttributeIdentifier`, and `UsernameAttributeIdentifier` types | Callers reading/setting `identifier` on `EmailAttribute`, `PhoneAttribute`, `UsernameAttribute` | +| `PhoneProviderProtectionBackoffStrategyEnum` | `NONE` (`"none"`) removed, replaced by `DEFAULT` (`"default"`) | Callers referencing the `NONE` constant or visitor | -### Authentication API +Everything else in `v4` is additive. -This major version change does not affect the Authentication API. The `AuthAPI` class has been ported directly from v2 to v3. Any code written for the Authentication API in the v2 version should work in the v3 version. +## Breaking changes -```java -// Works in both v2 and v3 -AuthAPI auth = AuthAPI.newBuilder("{YOUR_DOMAIN}", "{YOUR_CLIENT_ID}", "{YOUR_CLIENT_SECRET}").build(); -``` - -### Management API - -V3 introduces significant improvements to the Management API SDK by migrating to [Fern](https://github.com/fern-api/fern) as the code generation tool. This provides: - -- Better resource grouping with sub-client organization -- Type-safe request and response objects using builder patterns -- Automatic pagination with `SyncPagingIterable` -- Simplified access to HTTP response metadata via `withRawResponse()` -- Consistent method naming (`list`, `create`, `get`, `update`, `delete`) - -## Specific changes to the Management API - -### Client initialization - -The Management API client initialization has changed from `ManagementAPI` to `ManagementApi`, and uses a different builder pattern. - -**v2:** -```java -import com.auth0.client.mgmt.ManagementAPI; +### 1. Role pagination fields are now non-optional primitives -// Using domain and token -ManagementAPI mgmt = ManagementAPI.newBuilder("{YOUR_DOMAIN}", "{YOUR_API_TOKEN}").build(); - -// Using TokenProvider -TokenProvider tokenProvider = SimpleTokenProvider.create("{YOUR_API_TOKEN}"); -ManagementAPI mgmt = ManagementAPI.newBuilder("{YOUR_DOMAIN}", tokenProvider).build(); -``` +In `ListRolesOffsetPaginatedResponseContent`, the `start`, `limit`, and `total` fields change from `Optional` to primitive `double`, and the builder now requires them as mandatory, staged arguments. **v3:** -1st Approach : Standard Token-Based ```java -import com.auth0.client.mgmt.ManagementApi; - -ManagementApi client = ManagementApi - .builder() - .url("https://{YOUR_DOMAIN}/api/v2") - .token("{YOUR_API_TOKEN}") - .build(); +private final Optional start; +public Optional getStart() { ... } ``` -or - -2nd Approach : OAuth client credentials flow - +**v4:** ```java -OAuthTokenSupplier tokenSupplier = new OAuthTokenSupplier( -"{CLIENT_ID}", -"{CLIENT_SECRET}", -"https://{YOUR_DOMAIN}", -"{YOUR_AUDIENCE}" -); - -ClientOptions clientOptions = ClientOptions.builder() -.environment(Environment.custom("https://{YOUR_AUDIENCE}")) -.addHeader("Authorization", () -> "Bearer " + tokenSupplier.get()) -.build(); - -ManagementApi client = new ManagementApi(clientOptions); - +private final double start; +public double getStart() { ... } ``` -#### Builder options comparison - -| Option | v2 | v3 | -|--------|----|----| -| Domain/URL | `newBuilder(domain, token)` | `.url("https://domain/api/v2")` | -| Token | Constructor parameter | `.token(token)` | -| Timeout | Via `HttpOptions` | `.timeout(seconds)` | -| Max retries | Via `HttpOptions` | `.maxRetries(count)` | -| Custom HTTP client | `.withHttpClient(Auth0HttpClient)` | `.httpClient(OkHttpClient)` | -| Custom headers | Not directly supported | `.addHeader(name, value)` | +If you read these getters, drop the `Optional` handling: -### Sub-client organization - -V3 introduces a hierarchical sub-client structure. Operations on related resources are now accessed through nested clients instead of methods on a flat entity class. - -**v2:** ```java -// All user operations on UsersEntity -Request userRequest = mgmt.users().get("user_id", new UserFilter()); -Request> permissionsRequest = mgmt.users().getPermissions("user_id", new PermissionsFilter()); -Request> rolesRequest = mgmt.users().getRoles("user_id", new RolesFilter()); -Request logsRequest = mgmt.users().getLogEvents("user_id", new LogEventFilter()); -``` +// v3 +double start = response.getStart().orElse(0d); -**v3:** -```java -// Operations organized into sub-clients -GetUserResponseContent user = client.users().get("user_id"); -SyncPagingIterable permissions = client.users().permissions().list("user_id"); -SyncPagingIterable roles = client.users().roles().list("user_id"); -SyncPagingIterable logs = client.users().logs().list("user_id"); +// v4 +double start = response.getStart(); ``` -#### Common sub-client mappings +If you construct the type, the builder is now staged and requires `start`, `limit`, and `total` in order: -| v2 Method | v3 Sub-client | -|-----------|---------------| -| `mgmt.users().getPermissions()` | `client.users().permissions().list()` | -| `mgmt.users().getRoles()` | `client.users().roles().list()` | -| `mgmt.users().getLogEvents()` | `client.users().logs().list()` | -| `mgmt.users().getOrganizations()` | `client.users().organizations().list()` | -| `mgmt.users().link()` | `client.users().identities().link()` | -| `mgmt.users().unlink()` | `client.users().identities().delete()` | -| `mgmt.users().deleteMultifactorProvider()` | `client.users().multifactor().deleteProvider()` | -| `mgmt.organizations().getMembers()` | `client.organizations().members().list()` | -| `mgmt.organizations().getInvitations()` | `client.organizations().invitations().list()` | -| `mgmt.organizations().getEnabledConnections()` | `client.organizations().enabledConnections().list()` | -| `mgmt.actions().getVersions()` | `client.actions().versions().list()` | -| `mgmt.actions().getTriggerBindings()` | `client.actions().triggers().bindings().list()` | -| `mgmt.guardian().getFactors()` | `client.guardian().factors().list()` | -| `mgmt.branding().getUniversalLoginTemplate()` | `client.branding().templates().getUniversalLogin()` | -| `mgmt.connections().getScimConfiguration()` | `client.connections().scimConfiguration().get()` | - -### Request and response patterns - -V3 uses type-safe request content objects with builders instead of domain objects or filter parameters. - -**v2:** ```java -import com.auth0.json.mgmt.users.User; -import com.auth0.net.Request; - -// Creating a user -User user = new User("Username-Password-Authentication"); -user.setEmail("test@example.com"); -user.setPassword("password123".toCharArray()); - -Request request = mgmt.users().create(user); -User createdUser = request.execute().getBody(); -``` - -**v3:** -```java -import com.auth0.client.mgmt.types.CreateUserRequestContent; -import com.auth0.client.mgmt.types.CreateUserResponseContent; - -// Creating a user -CreateUserResponseContent user = client.users().create( - CreateUserRequestContent - .builder() - .connection("Username-Password-Authentication") - .email("test@example.com") - .password("password123") - .build() -); +// v4 +ListRolesOffsetPaginatedResponseContent content = ListRolesOffsetPaginatedResponseContent.builder() + .start(0) + .limit(50) + .total(200) + .roles(roles) + .build(); ``` -#### Key differences - -| Aspect | v2 | v3 | -|--------|----|----| -| Request building | Domain objects with setters | Builder pattern with `*RequestContent` types | -| Response type | `Request` requiring `.execute().getBody()` | Direct return of response object | -| Filtering | Filter classes (e.g., `UserFilter`) | `*RequestParameters` builder classes | -| Execution | Explicit `.execute()` call | Implicit execution on method call | +### 2. Connection attribute `identifier` is split by attribute type -### Pagination +The shared `ConnectionAttributeIdentifier` type is removed and replaced with dedicated types per attribute. The `identifier` field on `EmailAttribute`, `PhoneAttribute`, and `UsernameAttribute` now uses the matching type, so their `getIdentifier()` and builder `identifier(...)` signatures change. -V3 introduces `SyncPagingIterable` for automatic pagination, replacing the manual `Request` pattern. - -**v2:** -```java -import com.auth0.json.mgmt.users.UsersPage; -import com.auth0.client.mgmt.filter.UserFilter; - -Request request = mgmt.users().list(new UserFilter().withPage(0, 50)); -UsersPage page = request.execute().getBody(); - -for (User user : page.getItems()) { - System.out.println(user.getEmail()); -} - -// Manual pagination -while (page.getNext() != null) { - request = mgmt.users().list(new UserFilter().withPage(page.getNext(), 50)); - page = request.execute().getBody(); - for (User user : page.getItems()) { - System.out.println(user.getEmail()); - } -} -``` +| Attribute | v3 identifier type | v4 identifier type | +|-----------|--------------------|--------------------| +| `EmailAttribute` | `ConnectionAttributeIdentifier` | `EmailAttributeIdentifier` | +| `PhoneAttribute` | `ConnectionAttributeIdentifier` | `PhoneAttributeIdentifier` | +| `UsernameAttribute` | `ConnectionAttributeIdentifier` | `UsernameAttributeIdentifier` | **v3:** ```java -import com.auth0.client.mgmt.core.SyncPagingIterable; -import com.auth0.client.mgmt.types.UserResponseSchema; -import com.auth0.client.mgmt.types.ListUsersRequestParameters; - -// Automatic iteration through all pages -SyncPagingIterable users = client.users().list( - ListUsersRequestParameters - .builder() - .perPage(50) - .build() -); - -for (UserResponseSchema user : users) { - System.out.println(user.getEmail()); -} - -// Or manual page control -List pageItems = users.getItems(); -while (users.hasNext()) { - pageItems = users.nextPage().getItems(); - // process page -} +public Optional getIdentifier() { ... } ``` -### Exception handling - -V3 uses a unified `ManagementApiException` class instead of the v2 exception hierarchy. - -**v2:** +**v4 (`EmailAttribute`):** ```java -import com.auth0.exception.Auth0Exception; -import com.auth0.exception.APIException; -import com.auth0.exception.RateLimitException; - -try { - User user = mgmt.users().get("user_id", null).execute().getBody(); -} catch (RateLimitException e) { - // Rate limited - long retryAfter = e.getLimit(); -} catch (APIException e) { - int statusCode = e.getStatusCode(); - String error = e.getError(); - String description = e.getDescription(); -} catch (Auth0Exception e) { - // Network or other errors -} +public Optional getIdentifier() { ... } ``` -**v3:** -```java -import com.auth0.client.mgmt.core.ManagementApiException; - -try { - GetUserResponseContent user = client.users().get("user_id"); -} catch (ManagementApiException e) { - int statusCode = e.statusCode(); - Object body = e.body(); - Map> headers = e.headers(); - String message = e.getMessage(); -} -``` - -### Accessing raw HTTP responses - -V3 provides access to full HTTP response metadata via `withRawResponse()`. - -**v2:** -```java -// Response wrapper provided status code -Response response = mgmt.users().get("user_id", null).execute(); -int statusCode = response.getStatusCode(); -User user = response.getBody(); -``` +Update your imports and any variables holding the identifier. The new types expose `active` (`Optional`); `EmailAttributeIdentifier` and `PhoneAttributeIdentifier` additionally expose a `defaultMethod` (`DefaultMethodEmailIdentifierEnum` / `DefaultMethodPhoneNumberIdentifierEnum`). -**v3:** ```java -import com.auth0.client.mgmt.core.ManagementApiHttpResponse; - -// Use withRawResponse() to access headers and metadata -ManagementApiHttpResponse response = client.users() - .withRawResponse() - .get("user_id"); - -GetUserResponseContent user = response.body(); -Map> headers = response.headers(); +// v4 +EmailAttribute email = EmailAttribute.builder() + .identifier(EmailAttributeIdentifier.builder() + .active(true) + .build()) + .build(); ``` -### Request-level configuration - -V3 allows per-request configuration through `RequestOptions`. +### 3. Phone provider protection backoff strategy enum value changed -**v2:** -```java -// Most configuration was at client level only -// Request-level headers required creating a new request manually -Request request = mgmt.users().get("user_id", null); -request.addHeader("X-Custom-Header", "value"); -User user = request.execute().getBody(); -``` +`PhoneProviderProtectionBackoffStrategyEnum.NONE` (`"none"`, `visitNone()`) is removed and replaced by `PhoneProviderProtectionBackoffStrategyEnum.DEFAULT` (`"default"`, `visitDefault()`). **v3:** ```java -import com.auth0.client.mgmt.core.RequestOptions; - -GetUserResponseContent user = client.users().get( - "user_id", - GetUserRequestParameters.builder().build(), - RequestOptions.builder() - .timeout(10) - .maxRetries(1) - .addHeader("X-Custom-Header", "value") - .build() -); +PhoneProviderProtectionBackoffStrategyEnum strategy = PhoneProviderProtectionBackoffStrategyEnum.NONE; ``` -### Type changes - -V3 uses generated type classes located in `com.auth0.client.mgmt.types` instead of the hand-written POJOs in `com.auth0.json.mgmt`. - -**v2:** +**v4:** ```java -import com.auth0.json.mgmt.users.User; -import com.auth0.json.mgmt.roles.Role; -import com.auth0.json.mgmt.organizations.Organization; +PhoneProviderProtectionBackoffStrategyEnum strategy = PhoneProviderProtectionBackoffStrategyEnum.DEFAULT; ``` -**v3:** -```java -import com.auth0.client.mgmt.types.UserResponseSchema; -import com.auth0.client.mgmt.types.CreateUserRequestContent; -import com.auth0.client.mgmt.types.CreateUserResponseContent; -import com.auth0.client.mgmt.types.Role; -import com.auth0.client.mgmt.types.Organization; -``` - -Type naming conventions in v3: -- Request body types: `*RequestContent` (e.g., `CreateUserRequestContent`) -- Response types: `*ResponseContent` or `*ResponseSchema` (e.g., `GetUserResponseContent`, `UserResponseSchema`) -- Query parameters: `*RequestParameters` (e.g., `ListUsersRequestParameters`) - -All types use immutable builders: - -```java -// v3 type construction -CreateUserRequestContent request = CreateUserRequestContent - .builder() - .connection("Username-Password-Authentication") - .email("test@example.com") - .password("secure-password") - .build(); -``` +If you implement the visitor interface, rename `visitNone()` to `visitDefault()`. From 870c26aeed72f6f45e663166d375c4843df6cae2 Mon Sep 17 00:00:00 2001 From: tanya732 Date: Wed, 15 Jul 2026 13:37:19 +0530 Subject: [PATCH 2/3] Added new v3 to v4 migration guide --- .fernignore | 2 +- CHANGELOG.md | 4 +- README.md | 2 +- v3_MIGRATION_GUIDE.md | 369 ++++++++++++++++++++ MIGRATION_GUIDE.md => v4_MIGRATION_GUIDE.md | 60 +++- 5 files changed, 431 insertions(+), 6 deletions(-) create mode 100644 v3_MIGRATION_GUIDE.md rename MIGRATION_GUIDE.md => v4_MIGRATION_GUIDE.md (60%) diff --git a/.fernignore b/.fernignore index 819c62a7e..da1783c73 100644 --- a/.fernignore +++ b/.fernignore @@ -6,7 +6,7 @@ README.md # Examples and Migration Guide from auth0-real EXAMPLES.md v3_MIGRATION_GUIDE.md -MIGRATION_GUIDE.md +v4_MIGRATION_GUIDE.md LICENSE CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c058de91..b549e4f9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -143,7 +143,7 @@ ManagementApi client = ManagementApi ``` **Note**: The Authentication API remains supported, with deprecated APIs removed. -A complete migration guide is available at [MIGRATION_GUIDE](MIGRATION_GUIDE.md). +A complete migration guide is available at [MIGRATION_GUIDE](v3_MIGRATION_GUIDE). ## [3.0.0-beta.0](https://github.com/auth0/auth0-java/tree/3.0.0-beta.0) (2025-12-18) [Full Changelog](https://github.com/auth0/auth0-java/compare/2.27.0...3.0.0-beta.0) @@ -157,7 +157,7 @@ A complete migration guide is available at [MIGRATION_GUIDE](MIGRATION_GUIDE.md) - Nullability annotations to POJO classes - Fully compatible **Authentication API client** — no breaking changes -- [Migration guide](MIGRATION_GUIDE) available for upgrading from v2.x +- [Migration guide](v3_MIGRATION_GUIDE) available for upgrading from v2.x ## [2.27.0](https://github.com/auth0/auth0-java/tree/2.27.0) (2025-12-18) diff --git a/README.md b/README.md index 8f24453eb..34923e781 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ ## Documentation - [Reference](./reference.md) - code samples for Management APIs. - [Examples](./EXAMPLES.md) - code samples for common auth0-java scenarios. -- [Migration Guide](./MIGRATION_GUIDE.md) - guidance for updating your application to use version 3 of auth0-java. +- [Migration Guide](./v3_MIGRATION_GUIDE) - guidance for updating your application to use version 3 of auth0-java. - [Docs site](https://www.auth0.com/docs) - explore our docs site and learn more about Auth0. ## Getting Started diff --git a/v3_MIGRATION_GUIDE.md b/v3_MIGRATION_GUIDE.md new file mode 100644 index 000000000..9d98602c3 --- /dev/null +++ b/v3_MIGRATION_GUIDE.md @@ -0,0 +1,369 @@ +# V3 Migration Guide + +A guide to migrating the Auth0 Java SDK from `v2` to `v3`. + +- [Overall changes](#overall-changes) + - [Java versions](#java-versions) + - [Authentication API](#authentication-api) + - [Management API](#management-api) +- [Specific changes to the Management API](#specific-changes-to-the-management-api) + - [Client initialization](#client-initialization) + - [Sub-client organization](#sub-client-organization) + - [Request and response patterns](#request-and-response-patterns) + - [Pagination](#pagination) + - [Exception handling](#exception-handling) + - [Accessing raw HTTP responses](#accessing-raw-http-responses) + - [Request-level configuration](#request-level-configuration) + - [Type changes](#type-changes) + +## Overall changes + +### Java versions + +Both v2 and v3 require Java 8 or above. + +### Authentication API + +This major version change does not affect the Authentication API. The `AuthAPI` class has been ported directly from v2 to v3. Any code written for the Authentication API in the v2 version should work in the v3 version. + +```java +// Works in both v2 and v3 +AuthAPI auth = AuthAPI.newBuilder("{YOUR_DOMAIN}", "{YOUR_CLIENT_ID}", "{YOUR_CLIENT_SECRET}").build(); +``` + +### Management API + +V3 introduces significant improvements to the Management API SDK by migrating to [Fern](https://github.com/fern-api/fern) as the code generation tool. This provides: + +- Better resource grouping with sub-client organization +- Type-safe request and response objects using builder patterns +- Automatic pagination with `SyncPagingIterable` +- Simplified access to HTTP response metadata via `withRawResponse()` +- Consistent method naming (`list`, `create`, `get`, `update`, `delete`) + +## Specific changes to the Management API + +### Client initialization + +The Management API client initialization has changed from `ManagementAPI` to `ManagementApi`, and uses a different builder pattern. + +**v2:** +```java +import com.auth0.client.mgmt.ManagementAPI; + +// Using domain and token +ManagementAPI mgmt = ManagementAPI.newBuilder("{YOUR_DOMAIN}", "{YOUR_API_TOKEN}").build(); + +// Using TokenProvider +TokenProvider tokenProvider = SimpleTokenProvider.create("{YOUR_API_TOKEN}"); +ManagementAPI mgmt = ManagementAPI.newBuilder("{YOUR_DOMAIN}", tokenProvider).build(); +``` + +**v3:** +1st Approach : Standard Token-Based +```java +import com.auth0.client.mgmt.ManagementApi; + +ManagementApi client = ManagementApi + .builder() + .url("https://{YOUR_DOMAIN}/api/v2") + .token("{YOUR_API_TOKEN}") + .build(); +``` + +or + +2nd Approach : OAuth client credentials flow + +```java +OAuthTokenSupplier tokenSupplier = new OAuthTokenSupplier( +"{CLIENT_ID}", +"{CLIENT_SECRET}", +"https://{YOUR_DOMAIN}", +"{YOUR_AUDIENCE}" +); + +ClientOptions clientOptions = ClientOptions.builder() +.environment(Environment.custom("https://{YOUR_AUDIENCE}")) +.addHeader("Authorization", () -> "Bearer " + tokenSupplier.get()) +.build(); + +ManagementApi client = new ManagementApi(clientOptions); + +``` + +#### Builder options comparison + +| Option | v2 | v3 | +|--------|----|----| +| Domain/URL | `newBuilder(domain, token)` | `.url("https://domain/api/v2")` | +| Token | Constructor parameter | `.token(token)` | +| Timeout | Via `HttpOptions` | `.timeout(seconds)` | +| Max retries | Via `HttpOptions` | `.maxRetries(count)` | +| Custom HTTP client | `.withHttpClient(Auth0HttpClient)` | `.httpClient(OkHttpClient)` | +| Custom headers | Not directly supported | `.addHeader(name, value)` | + +### Sub-client organization + +V3 introduces a hierarchical sub-client structure. Operations on related resources are now accessed through nested clients instead of methods on a flat entity class. + +**v2:** +```java +// All user operations on UsersEntity +Request userRequest = mgmt.users().get("user_id", new UserFilter()); +Request> permissionsRequest = mgmt.users().getPermissions("user_id", new PermissionsFilter()); +Request> rolesRequest = mgmt.users().getRoles("user_id", new RolesFilter()); +Request logsRequest = mgmt.users().getLogEvents("user_id", new LogEventFilter()); +``` + +**v3:** +```java +// Operations organized into sub-clients +GetUserResponseContent user = client.users().get("user_id"); +SyncPagingIterable permissions = client.users().permissions().list("user_id"); +SyncPagingIterable roles = client.users().roles().list("user_id"); +SyncPagingIterable logs = client.users().logs().list("user_id"); +``` + +#### Common sub-client mappings + +| v2 Method | v3 Sub-client | +|-----------|---------------| +| `mgmt.users().getPermissions()` | `client.users().permissions().list()` | +| `mgmt.users().getRoles()` | `client.users().roles().list()` | +| `mgmt.users().getLogEvents()` | `client.users().logs().list()` | +| `mgmt.users().getOrganizations()` | `client.users().organizations().list()` | +| `mgmt.users().link()` | `client.users().identities().link()` | +| `mgmt.users().unlink()` | `client.users().identities().delete()` | +| `mgmt.users().deleteMultifactorProvider()` | `client.users().multifactor().deleteProvider()` | +| `mgmt.organizations().getMembers()` | `client.organizations().members().list()` | +| `mgmt.organizations().getInvitations()` | `client.organizations().invitations().list()` | +| `mgmt.organizations().getEnabledConnections()` | `client.organizations().enabledConnections().list()` | +| `mgmt.actions().getVersions()` | `client.actions().versions().list()` | +| `mgmt.actions().getTriggerBindings()` | `client.actions().triggers().bindings().list()` | +| `mgmt.guardian().getFactors()` | `client.guardian().factors().list()` | +| `mgmt.branding().getUniversalLoginTemplate()` | `client.branding().templates().getUniversalLogin()` | +| `mgmt.connections().getScimConfiguration()` | `client.connections().scimConfiguration().get()` | + +### Request and response patterns + +V3 uses type-safe request content objects with builders instead of domain objects or filter parameters. + +**v2:** +```java +import com.auth0.json.mgmt.users.User; +import com.auth0.net.Request; + +// Creating a user +User user = new User("Username-Password-Authentication"); +user.setEmail("test@example.com"); +user.setPassword("password123".toCharArray()); + +Request request = mgmt.users().create(user); +User createdUser = request.execute().getBody(); +``` + +**v3:** +```java +import com.auth0.client.mgmt.types.CreateUserRequestContent; +import com.auth0.client.mgmt.types.CreateUserResponseContent; + +// Creating a user +CreateUserResponseContent user = client.users().create( + CreateUserRequestContent + .builder() + .connection("Username-Password-Authentication") + .email("test@example.com") + .password("password123") + .build() +); +``` + +#### Key differences + +| Aspect | v2 | v3 | +|--------|----|----| +| Request building | Domain objects with setters | Builder pattern with `*RequestContent` types | +| Response type | `Request` requiring `.execute().getBody()` | Direct return of response object | +| Filtering | Filter classes (e.g., `UserFilter`) | `*RequestParameters` builder classes | +| Execution | Explicit `.execute()` call | Implicit execution on method call | + +### Pagination + +V3 introduces `SyncPagingIterable` for automatic pagination, replacing the manual `Request` pattern. + +**v2:** +```java +import com.auth0.json.mgmt.users.UsersPage; +import com.auth0.client.mgmt.filter.UserFilter; + +Request request = mgmt.users().list(new UserFilter().withPage(0, 50)); +UsersPage page = request.execute().getBody(); + +for (User user : page.getItems()) { + System.out.println(user.getEmail()); +} + +// Manual pagination +while (page.getNext() != null) { + request = mgmt.users().list(new UserFilter().withPage(page.getNext(), 50)); + page = request.execute().getBody(); + for (User user : page.getItems()) { + System.out.println(user.getEmail()); + } +} +``` + +**v3:** +```java +import com.auth0.client.mgmt.core.SyncPagingIterable; +import com.auth0.client.mgmt.types.UserResponseSchema; +import com.auth0.client.mgmt.types.ListUsersRequestParameters; + +// Automatic iteration through all pages +SyncPagingIterable users = client.users().list( + ListUsersRequestParameters + .builder() + .perPage(50) + .build() +); + +for (UserResponseSchema user : users) { + System.out.println(user.getEmail()); +} + +// Or manual page control +List pageItems = users.getItems(); +while (users.hasNext()) { + pageItems = users.nextPage().getItems(); + // process page +} +``` + +### Exception handling + +V3 uses a unified `ManagementApiException` class instead of the v2 exception hierarchy. + +**v2:** +```java +import com.auth0.exception.Auth0Exception; +import com.auth0.exception.APIException; +import com.auth0.exception.RateLimitException; + +try { + User user = mgmt.users().get("user_id", null).execute().getBody(); +} catch (RateLimitException e) { + // Rate limited + long retryAfter = e.getLimit(); +} catch (APIException e) { + int statusCode = e.getStatusCode(); + String error = e.getError(); + String description = e.getDescription(); +} catch (Auth0Exception e) { + // Network or other errors +} +``` + +**v3:** +```java +import com.auth0.client.mgmt.core.ManagementApiException; + +try { + GetUserResponseContent user = client.users().get("user_id"); +} catch (ManagementApiException e) { + int statusCode = e.statusCode(); + Object body = e.body(); + Map> headers = e.headers(); + String message = e.getMessage(); +} +``` + +### Accessing raw HTTP responses + +V3 provides access to full HTTP response metadata via `withRawResponse()`. + +**v2:** +```java +// Response wrapper provided status code +Response response = mgmt.users().get("user_id", null).execute(); +int statusCode = response.getStatusCode(); +User user = response.getBody(); +``` + +**v3:** +```java +import com.auth0.client.mgmt.core.ManagementApiHttpResponse; + +// Use withRawResponse() to access headers and metadata +ManagementApiHttpResponse response = client.users() + .withRawResponse() + .get("user_id"); + +GetUserResponseContent user = response.body(); +Map> headers = response.headers(); +``` + +### Request-level configuration + +V3 allows per-request configuration through `RequestOptions`. + +**v2:** +```java +// Most configuration was at client level only +// Request-level headers required creating a new request manually +Request request = mgmt.users().get("user_id", null); +request.addHeader("X-Custom-Header", "value"); +User user = request.execute().getBody(); +``` + +**v3:** +```java +import com.auth0.client.mgmt.core.RequestOptions; + +GetUserResponseContent user = client.users().get( + "user_id", + GetUserRequestParameters.builder().build(), + RequestOptions.builder() + .timeout(10) + .maxRetries(1) + .addHeader("X-Custom-Header", "value") + .build() +); +``` + +### Type changes + +V3 uses generated type classes located in `com.auth0.client.mgmt.types` instead of the hand-written POJOs in `com.auth0.json.mgmt`. + +**v2:** +```java +import com.auth0.json.mgmt.users.User; +import com.auth0.json.mgmt.roles.Role; +import com.auth0.json.mgmt.organizations.Organization; +``` + +**v3:** +```java +import com.auth0.client.mgmt.types.UserResponseSchema; +import com.auth0.client.mgmt.types.CreateUserRequestContent; +import com.auth0.client.mgmt.types.CreateUserResponseContent; +import com.auth0.client.mgmt.types.Role; +import com.auth0.client.mgmt.types.Organization; +``` + +Type naming conventions in v3: +- Request body types: `*RequestContent` (e.g., `CreateUserRequestContent`) +- Response types: `*ResponseContent` or `*ResponseSchema` (e.g., `GetUserResponseContent`, `UserResponseSchema`) +- Query parameters: `*RequestParameters` (e.g., `ListUsersRequestParameters`) + +All types use immutable builders: + +```java +// v3 type construction +CreateUserRequestContent request = CreateUserRequestContent + .builder() + .connection("Username-Password-Authentication") + .email("test@example.com") + .password("secure-password") + .build(); +``` diff --git a/MIGRATION_GUIDE.md b/v4_MIGRATION_GUIDE.md similarity index 60% rename from MIGRATION_GUIDE.md rename to v4_MIGRATION_GUIDE.md index 1617592a6..084b0a784 100644 --- a/MIGRATION_GUIDE.md +++ b/v4_MIGRATION_GUIDE.md @@ -1,12 +1,16 @@ # Migrating from v3 to v4 -`v4` is a compatible evolution of `v3`. The Authentication API is unchanged, and the Management API keeps the same client structure, builder patterns, and pagination introduced in `v3`. The breaking changes are narrow and limited to a few generated Management API types where field types were tightened for correctness or split for type-safety. +`v4` is a compatible evolution of `v3`. The Authentication API is unchanged, and the Management API keeps the same client structure, builder patterns, and pagination introduced in `v3`. The breaking changes are narrow: a few generated Management API types where field types were tightened or split for type-safety, and the removal of the Federated Connections Tokensets API. - [Overview](#overview) - [Breaking changes](#breaking-changes) - [1. Role pagination fields are now non-optional primitives](#1-role-pagination-fields-are-now-non-optional-primitives) - [2. Connection attribute `identifier` is split by attribute type](#2-connection-attribute-identifier-is-split-by-attribute-type) - [3. Phone provider protection backoff strategy enum value changed](#3-phone-provider-protection-backoff-strategy-enum-value-changed) + - [4. Federated Connections Tokensets API removed](#4-federated-connections-tokensets-api-removed) +- [Other changes](#other-changes) + - [Per-request retry configuration](#per-request-retry-configuration) + - [Query parameter serialization](#query-parameter-serialization) - [Migration steps](#migration-steps) ## Overview @@ -18,8 +22,9 @@ Most `v3` code compiles and runs unchanged on `v4`. You only need to act if your | `ListRolesOffsetPaginatedResponseContent` | `start` / `limit` / `total` changed from `Optional` to primitive `double`, and are now required builder stages | Callers reading these getters or constructing the type | | Connection attributes | The shared `ConnectionAttributeIdentifier` type is removed and replaced by dedicated `EmailAttributeIdentifier`, `PhoneAttributeIdentifier`, and `UsernameAttributeIdentifier` types | Callers reading/setting `identifier` on `EmailAttribute`, `PhoneAttribute`, `UsernameAttribute` | | `PhoneProviderProtectionBackoffStrategyEnum` | `NONE` (`"none"`) removed, replaced by `DEFAULT` (`"default"`) | Callers referencing the `NONE` constant or visitor | +| Federated Connections Tokensets | `client.users().federatedConnectionsTokensets()` and its types removed | Callers of that API | -Everything else in `v4` is additive. +Everything else in `v4` is additive or internal. ## Breaking changes @@ -107,3 +112,54 @@ PhoneProviderProtectionBackoffStrategyEnum strategy = PhoneProviderProtectionBac ``` If you implement the visitor interface, rename `visitNone()` to `visitDefault()`. + +### 4. Federated Connections Tokensets API removed + +The Federated Connections Tokensets API is removed. The following are no longer available: + +- Client accessor: `client.users().federatedConnectionsTokensets()` (and its async/raw variants) +- Types: `FederatedConnectionTokenSet`, `ConnectionFederatedConnectionsAccessTokens` + +**v3:** +```java +List tokensets = + client.users().federatedConnectionsTokensets().list("user_id"); + +client.users().federatedConnectionsTokensets().delete("user_id", "tokenset_id"); +``` + +**v4:** + +No replacement is generated in the SDK. Remove these calls; if you still need this functionality, call the corresponding Management API endpoint directly. + +## Other changes + +These are backward-compatible but worth noting. + +### Per-request retry configuration + +Requests now honor a per-request `maxRetries` value via `RequestOptions`, alongside the existing `timeout`: + +```java +GetUserResponseContent user = client.users().get( + "user_id", + GetUserRequestParameters.builder().build(), + RequestOptions.builder() + .timeout(10) + .maxRetries(2) + .build() +); +``` + +### Query parameter serialization + +List/query parameter types (e.g. `ListUsersRequestParameters`, `ListClientsRequestParameters`, `ListLogsRequestParameters`, `ListConnectionsQueryParameters`) now serialize their optional/nullable query parameters through a nullable-nonempty filter instead of being marked `@JsonIgnore`. Builder usage is unchanged; this only affects how parameters are emitted on the wire. + +## Migration steps + +1. Update the dependency to the `v4` release. +2. Replace any `ConnectionAttributeIdentifier` imports/usages with the matching `EmailAttributeIdentifier`, `PhoneAttributeIdentifier`, or `UsernameAttributeIdentifier`. +3. Remove `Optional` handling around `ListRolesOffsetPaginatedResponseContent#getStart/getLimit/getTotal`, and update any builder usage to the staged `start` → `limit` → `total` form. +4. Replace `PhoneProviderProtectionBackoffStrategyEnum.NONE` with `DEFAULT` (and `visitNone()` with `visitDefault()` in any visitor implementations). +5. Remove any usage of `client.users().federatedConnectionsTokensets()` and the `FederatedConnectionTokenSet` / `ConnectionFederatedConnectionsAccessTokens` types. +6. Run `mvn verify` (or your build) and fix any remaining compilation errors surfaced by the above. From 9015720145c02052ce1724a8a2bca2493c44c4ed Mon Sep 17 00:00:00 2001 From: tanya732 Date: Wed, 15 Jul 2026 13:50:55 +0530 Subject: [PATCH 3/3] Update Readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 34923e781..5b217127b 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,8 @@ ## Documentation - [Reference](./reference.md) - code samples for Management APIs. - [Examples](./EXAMPLES.md) - code samples for common auth0-java scenarios. -- [Migration Guide](./v3_MIGRATION_GUIDE) - guidance for updating your application to use version 3 of auth0-java. +- [v4 Migration Guide](./v4_MIGRATION_GUIDE.md) - guidance for updating your application from version 3 to version 4 of auth0-java. +- [v3 Migration Guide](./v3_MIGRATION_GUIDE.md) - guidance for updating your application from version 2 to version 3 of auth0-java. - [Docs site](https://www.auth0.com/docs) - explore our docs site and learn more about Auth0. ## Getting Started