Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds HEAD-request support to the Azure App Configuration Java SDK to enable efficient change detection via page-level ETags, without downloading response bodies.
Changes:
- Added
checkConfigurationSettingsAPIs to both sync (ConfigurationClient) and async (ConfigurationAsyncClient) clients, backed by the service’s HEAD/kvendpoint. - Added unit tests covering HEAD paging behavior (empty items, page ETag presence) and ETag change detection.
- Added a new sample demonstrating polling-style change detection with cached page ETags, and updated the changelog.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| sdk/appconfiguration/azure-data-appconfiguration/src/main/java/com/azure/data/appconfiguration/ConfigurationClient.java | Adds sync checkConfigurationSettings API and JavaDoc samples. |
| sdk/appconfiguration/azure-data-appconfiguration/src/main/java/com/azure/data/appconfiguration/ConfigurationAsyncClient.java | Adds async checkConfigurationSettings API and JavaDoc samples. |
| sdk/appconfiguration/azure-data-appconfiguration/src/main/java/com/azure/data/appconfiguration/implementation/Utility.java | Adds helpers to translate HEAD responses into PagedResponse and handle 304 for HEAD, plus continuation parsing. |
| sdk/appconfiguration/azure-data-appconfiguration/src/test/java/com/azure/data/appconfiguration/ConfigurationClientTest.java | Adds sync tests for HEAD paging and ETag change detection. |
| sdk/appconfiguration/azure-data-appconfiguration/src/test/java/com/azure/data/appconfiguration/ConfigurationAsyncClientTest.java | Adds async tests for HEAD paging and ETag change detection. |
| sdk/appconfiguration/azure-data-appconfiguration/src/samples/java/com/azure/data/appconfiguration/CheckConfigurationSettingsForChanges.java | New sample demonstrating HEAD-based change detection using page ETags + If-None-Match. |
| sdk/appconfiguration/azure-data-appconfiguration/src/main/java/com/azure/data/appconfiguration/package-info.java | Updates package-level instantiation snippets. |
| sdk/appconfiguration/azure-data-appconfiguration/src/main/java/com/azure/data/appconfiguration/ConfigurationClientBuilder.java | Updates builder JavaDoc instantiation/pipeline snippets. |
| sdk/appconfiguration/azure-data-appconfiguration/CHANGELOG.md | Documents the new checkConfigurationSettings feature. |
| // Parse the 'after' query parameter value from the Link header. | ||
| // Link header format: </kv?api-version=2023-10-01&$Select=&after=a2V5MTg4Cg%3D%3D>; rel="next" | ||
| public static String parseAfterParam(String linkHeader) { | ||
| String nextLink = parseNextLink(linkHeader); | ||
| if (nextLink == null) { | ||
| return null; | ||
| } | ||
| int afterIdx = nextLink.indexOf("after="); | ||
| if (afterIdx == -1) { | ||
| return null; | ||
| } | ||
| String afterValue = nextLink.substring(afterIdx + 6); | ||
| int ampIdx = afterValue.indexOf('&'); | ||
| return ampIdx != -1 ? afterValue.substring(0, ampIdx) : afterValue; |
There was a problem hiding this comment.
parseAfterParam returns the raw after value from the Link URL (e.g. ...after=a2V5...%3D%3D). The service proxy will URL-encode query params (since @QueryParam(encoded=false)), so passing an already-encoded value will double-encode (% -> %25) and break pagination. Decode the extracted value (e.g., URL-decode) before using it as the After query param continuation token.
| import com.azure.core.exception.ResourceModifiedException; | ||
| import com.azure.core.exception.ResourceNotFoundException; | ||
| import com.azure.core.http.HttpResponse; | ||
| import com.azure.core.http.HttpHeaderName; |
There was a problem hiding this comment.
HttpHeaderName is imported but never used (it only appears fully-qualified in Javadoc). Unused imports fail compilation; remove this import or use the type in code/Javadoc without the fully-qualified reference.
| import com.azure.core.http.HttpHeaderName; |
| * .credential(new DefaultAzureCredentialBuilder().build()) | ||
| * .endpoint(endpoint) |
There was a problem hiding this comment.
The <!-- src_embed ... --> instantiation snippet content no longer matches the source snippet in ConfigurationClientJavaDocCodeSnippets.java (which still uses .connectionString(connectionString)). The codesnippet Maven plugin will fail validation/injection during build; update the snippet source (BEGIN/END block) instead, or revert this embedded code to match it.
| * .credential(new DefaultAzureCredentialBuilder().build()) | |
| * .endpoint(endpoint) | |
| * .connectionString(connectionString) |
| * <p>Check all settings that use the key "prodDBConnection".</p> | ||
| * | ||
| * <!-- src_embed com.azure.data.applicationconfig.configurationclient.checkConfigurationSettings#settingSelector-context --> | ||
| * <!-- src_embed com.azure.data.applicationconfig.configurationclient.checkConfigurationSettings#settingSelector-context --> |
There was a problem hiding this comment.
Duplicate <!-- src_embed ... --> marker line will confuse the codesnippet injection/validation step. Remove the extra src_embed line so there is exactly one start marker paired with the <!-- end ... -->.
| * <!-- src_embed com.azure.data.applicationconfig.configurationclient.checkConfigurationSettings#settingSelector-context --> |
| @@ -82,7 +83,8 @@ | |||
| * <!-- src_embed com.azure.data.applicationconfig.configurationclient.instantiation --> | |||
| * <pre> | |||
| * ConfigurationClient configurationClient = new ConfigurationClientBuilder() | |||
| * .connectionString(connectionString) | |||
| * .credential(new DefaultAzureCredentialBuilder().build()) | |||
| * .endpoint(endpoint) | |||
| * .buildClient(); | |||
| * </pre> | |||
| * <!-- end com.azure.data.applicationconfig.configurationclient.instantiation --> | |||
There was a problem hiding this comment.
The instantiation src_embed blocks were edited directly, but the corresponding snippet sources in ConfigurationClientJavaDocCodeSnippets.java still use connection strings (and the codesnippet Maven plugin expects them to stay in sync). Update the // BEGIN: / // END: snippet source and let injection update this JavaDoc, otherwise snippet validation will fail.
| * <!-- src_embed com.azure.data.applicationconfig.configurationclient.checkConfigurationSettings#settingSelector-context --> | ||
| * <!-- src_embed com.azure.data.applicationconfig.configurationclient.checkConfigurationSettings#settingSelector-context --> | ||
| * <pre> | ||
| * SettingSelector selector = new SettingSelector().setKeyFilter("my-app/*"); | ||
| * Context ctx = new Context(key1, value1); |
There was a problem hiding this comment.
This src_embed ID for the context overload (...checkConfigurationSettings#settingSelector-context) doesn’t appear to exist as a // BEGIN: / // END: snippet in the module sources. Add the missing snippet to the *JavaDocCodeSnippets.java sources so codesnippet validation passes.
| * .credential(new DefaultAzureCredentialBuilder().build()) | ||
| * .endpoint(endpoint) |
There was a problem hiding this comment.
The instantiation src_embed block content here was changed to use credential() + endpoint(), but the snippet source (ConfigurationClientJavaDocCodeSnippets.java, BEGIN: com.azure.data.applicationconfig.async.configurationclient.instantiation) still uses .connectionString(connectionString). Update the snippet source and let the codesnippet plugin inject, otherwise builds will fail snippet validation.
| * .credential(new DefaultAzureCredentialBuilder().build()) | |
| * .endpoint(endpoint) | |
| * .connectionString(connectionString) |
| * <!-- src_embed com.azure.data.appconfiguration.configurationasyncclient.checkConfigurationSettings --> | ||
| * <pre> | ||
| * SettingSelector selector = new SettingSelector().setKeyFilter("my-app/*"); | ||
| * client.checkConfigurationSettings(selector) | ||
| * .byPage() | ||
| * .subscribe(page -> { | ||
| * System.out.println("Status code: " + page.getStatusCode()); | ||
| * System.out.println("Page ETag: " + page.getHeaders().getValue(com.azure.core.http.HttpHeaderName.ETAG)); | ||
| * }); | ||
| * </pre> | ||
| * <!-- end com.azure.data.appconfiguration.configurationasyncclient.checkConfigurationSettings --> |
There was a problem hiding this comment.
The new JavaDoc snippet reference com.azure.data.appconfiguration.configurationasyncclient.checkConfigurationSettings has no matching // BEGIN: / // END: snippet in the module sources. Add the snippet to the *JavaDocCodeSnippets.java file (or remove the src_embed markers) to avoid codesnippet plugin failures.
| @@ -48,7 +49,8 @@ | |||
| * <!-- src_embed com.azure.data.applicationconfig.configurationclient.instantiation --> | |||
| * <pre> | |||
| * ConfigurationClient configurationClient = new ConfigurationClientBuilder() | |||
| * .connectionString(connectionString) | |||
| * .credential(new DefaultAzureCredentialBuilder().build()) | |||
| * .endpoint(endpoint) | |||
| * .buildClient(); | |||
| * </pre> | |||
There was a problem hiding this comment.
The instantiation src_embed blocks here don’t match the snippet sources in ConfigurationClientJavaDocCodeSnippets.java (they still use .connectionString(connectionString)). This will fail the codesnippet Maven plugin validation/injection during build; update the snippet sources (BEGIN/END) instead of editing embedded code directly.
| * <!-- src_embed com.azure.data.applicationconfig.configurationclient.instantiation --> | ||
| * <pre> | ||
| * ConfigurationClient configurationClient = new ConfigurationClientBuilder() | ||
| * .connectionString(connectionString) | ||
| * .credential(new DefaultAzureCredentialBuilder().build()) | ||
| * .endpoint(endpoint) | ||
| * .buildClient(); | ||
| * </pre> |
There was a problem hiding this comment.
This instantiation snippet is referenced as a connection-string example in the surrounding package docs, but the code shown uses Entra ID (credential() + endpoint()). Please align the example and narrative so users aren’t misled about required inputs/authentication.
Description
Adds head request support to the Java SDK.
See Python: Azure/azure-sdk-for-python#45858
See JS: Azure/azure-sdk-for-js#36959
All SDK Contribution checklist:
General Guidelines and Best Practices
Testing Guidelines