GitHub Copilot ChatGPT Claude Codex CLI Cursor opencode Skill Text

azure-appconfiguration-java

Azure App Configuration SDK for Java. Centralized application configuration management with key-value settings, feature flags, and snapshots. Triggers: "ConfigurationClient java", "app configuration java", "feature flag java", "configuration setting java", "azure config java".

Ciza · 0 points · 15 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download microsoft-skills-.github_plugins_azure-sdk-java_skills_azure-appconfiguration-java-e58528d.zip · 9 KB
Part of microsoft/skills — 195 skills

Install

skills CLI npx skills add https://github.com/microsoft/skills/tree/main/.github/plugins/azure-sdk-java/skills/azure-appconfiguration-java
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install microsoft-skills@llmmart
Git git clone https://github.com/microsoft/skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole microsoft/skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Azure App Configuration SDK for Java

Client library for Azure App Configuration, a managed service for centralizing application configurations.

Installation

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-data-appconfiguration</artifactId>
    <version>1.8.0</version>
</dependency>

Or use Azure SDK BOM:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-sdk-bom</artifactId>
            <version>{bom_version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-data-appconfiguration</artifactId>
    </dependency>
</dependencies>

Prerequisites

  • Azure App Configuration store
  • Connection string or Entra ID credentials

Environment Variables

AZURE_APPCONFIG_CONNECTION_STRING=Endpoint=https://<store>.azconfig.io;Id=<id>;Secret=<secret>  # Alternative to Entra ID auth
AZURE_APPCONFIG_ENDPOINT=https://<store>.azconfig.io  # Required for all auth methods
AZURE_TOKEN_CREDENTIALS=prod  # Required only if DefaultAzureCredential is used in production

Client Creation

With Connection String

import com.azure.data.appconfiguration.ConfigurationClient;
import com.azure.data.appconfiguration.ConfigurationClientBuilder;

ConfigurationClient configClient = new ConfigurationClientBuilder()
    .connectionString(System.getenv("AZURE_APPCONFIG_CONNECTION_STRING"))
    .buildClient();

Async Client

import com.azure.data.appconfiguration.ConfigurationAsyncClient;

ConfigurationAsyncClient asyncClient = new ConfigurationClientBuilder()
    .connectionString(connectionString)
    .buildAsyncClient();

With Entra ID (Recommended)

import com.azure.core.credential.TokenCredential;
import com.azure.identity.AzureIdentityEnvVars;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.ManagedIdentityCredentialBuilder;

// Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>
TokenCredential credential = new DefaultAzureCredentialBuilder()
    .requireEnvVars(AzureIdentityEnvVars.AZURE_TOKEN_CREDENTIALS)
    .build();
// Or use a specific credential directly in production:
// See https://learn.microsoft.com/java/api/overview/azure/identity-readme?view=azure-java-stable#credential-classes
// TokenCredential credential = new ManagedIdentityCredentialBuilder().build();

ConfigurationClient configClient = new ConfigurationClientBuilder()
    .credential(credential)
    .endpoint(System.getenv("AZURE_APPCONFIG_ENDPOINT"))
    .buildClient();

Key Concepts

Concept Description
Configuration Setting Key-value pair with optional label
Label Dimension for separating settings (e.g., environments)
Feature Flag Special setting for feature management
Secret Reference Setting pointing to Key Vault secret
Snapshot Point-in-time immutable view of settings

Configuration Setting Operations

Create Setting (Add)

Creates only if setting doesn't exist:

import com.azure.data.appconfiguration.models.ConfigurationSetting;

ConfigurationSetting setting = configClient.addConfigurationSetting(
    "app/database/connection", 
    "Production", 
    "Server=prod.db.com;Database=myapp"
);

Create or Update Setting (Set)

Creates or overwrites:

ConfigurationSetting setting = configClient.setConfigurationSetting(
    "app/cache/enabled", 
    "Production", 
    "true"
);

Get Setting

ConfigurationSetting setting = configClient.getConfigurationSetting(
    "app/database/connection", 
    "Production"
);
System.out.println("Value: " + setting.getValue());
System.out.println("Content-Type: " + setting.getContentType());
System.out.println("Last Modified: " + setting.getLastModified());

Conditional Get (If Changed)

import com.azure.core.http.rest.Response;
import com.azure.core.util.Context;

Response<ConfigurationSetting> response = configClient.getConfigurationSettingWithResponse(
    setting,      // Setting with ETag
    null,         // Accept datetime
    true,         // ifChanged - only fetch if modified
    Context.NONE
);

if (response.getStatusCode() == 304) {
    System.out.println("Setting not modified");
} else {
    ConfigurationSetting updated = response.getValue();
}

Update Setting

ConfigurationSetting updated = configClient.setConfigurationSetting(
    "app/cache/enabled", 
    "Production", 
    "false"
);

Conditional Update (If Unchanged)

// Only update if ETag matches (no concurrent modifications)
Response<ConfigurationSetting> response = configClient.setConfigurationSettingWithResponse(
    setting,     // Setting with current ETag
    true,        // ifUnchanged
    Context.NONE
);

Delete Setting

ConfigurationSetting deleted = configClient.deleteConfigurationSetting(
    "app/cache/enabled", 
    "Production"
);

Conditional Delete

Response<ConfigurationSetting> response = configClient.deleteConfigurationSettingWithResponse(
    setting,     // Setting with ETag
    true,        // ifUnchanged
    Context.NONE
);

List and Filter Settings

List by Key Pattern

import com.azure.data.appconfiguration.models.SettingSelector;
import com.azure.core.http.rest.PagedIterable;

SettingSelector selector = new SettingSelector()
    .setKeyFilter("app/*");

PagedIterable<ConfigurationSetting> settings = configClient.listConfigurationSettings(selector);
for (ConfigurationSetting s : settings) {
    System.out.println(s.getKey() + " = " + s.getValue());
}

List by Label

SettingSelector selector = new SettingSelector()
    .setKeyFilter("*")
    .setLabelFilter("Production");

PagedIterable<ConfigurationSetting> settings = configClient.listConfigurationSettings(selector);

List by Multiple Keys

SettingSelector selector = new SettingSelector()
    .setKeyFilter("app/database/*,app/cache/*");

PagedIterable<ConfigurationSetting> settings = configClient.listConfigurationSettings(selector);

List Revisions

SettingSelector selector = new SettingSelector()
    .setKeyFilter("app/database/connection");

PagedIterable<ConfigurationSetting> revisions = configClient.listRevisions(selector);
for (ConfigurationSetting revision : revisions) {
    System.out.println("Value: " + revision.getValue() + ", Modified: " + revision.getLastModified());
}

Feature Flags

Create Feature Flag

import com.azure.data.appconfiguration.models.FeatureFlagConfigurationSetting;
import com.azure.data.appconfiguration.models.FeatureFlagFilter;
import java.util.Arrays;

FeatureFlagFilter percentageFilter = new FeatureFlagFilter("Microsoft.Percentage")
    .addParameter("Value", 50);

FeatureFlagConfigurationSetting featureFlag = new FeatureFlagConfigurationSetting("beta-feature", true)
    .setDescription("Beta feature rollout")
    .setClientFilters(Arrays.asList(percentageFilter));

FeatureFlagConfigurationSetting created = (FeatureFlagConfigurationSetting)
    configClient.addConfigurationSetting(featureFlag);

Get Feature Flag

FeatureFlagConfigurationSetting flag = (FeatureFlagConfigurationSetting)
    configClient.getConfigurationSetting(featureFlag);

System.out.println("Feature: " + flag.getFeatureId());
System.out.println("Enabled: " + flag.isEnabled());
System.out.println("Filters: " + flag.getClientFilters());

Update Feature Flag

featureFlag.setEnabled(false);
FeatureFlagConfigurationSetting updated = (FeatureFlagConfigurationSetting)
    configClient.setConfigurationSetting(featureFlag);

Secret References

Create Secret Reference

import com.azure.data.appconfiguration.models.SecretReferenceConfigurationSetting;

SecretReferenceConfigurationSetting secretRef = new SecretReferenceConfigurationSetting(
    "app/secrets/api-key",
    "https://myvault.vault.azure.net/secrets/api-key"
);

SecretReferenceConfigurationSetting created = (SecretReferenceConfigurationSetting)
    configClient.addConfigurationSetting(secretRef);

Get Secret Reference

SecretReferenceConfigurationSetting ref = (SecretReferenceConfigurationSetting)
    configClient.getConfigurationSetting(secretRef);

System.out.println("Secret URI: " + ref.getSecretId());

Read-Only Settings

Set Read-Only

ConfigurationSetting readOnly = configClient.setReadOnly(
    "app/critical/setting", 
    "Production", 
    true
);

Clear Read-Only

ConfigurationSetting writable = configClient.setReadOnly(
    "app/critical/setting", 
    "Production", 
    false
);

Snapshots

Create Snapshot

import com.azure.data.appconfiguration.models.ConfigurationSnapshot;
import com.azure.data.appconfiguration.models.ConfigurationSettingsFilter;
import com.azure.core.util.polling.SyncPoller;
import com.azure.core.util.polling.PollOperationDetails;

List<ConfigurationSettingsFilter> filters = new ArrayList<>();
filters.add(new ConfigurationSettingsFilter("app/*"));

SyncPoller<PollOperationDetails, ConfigurationSnapshot> poller = configClient.beginCreateSnapshot(
    "release-v1.0",
    new ConfigurationSnapshot(filters),
    Context.NONE
);
poller.setPollInterval(Duration.ofSeconds(10));
poller.waitForCompletion();

ConfigurationSnapshot snapshot = poller.getFinalResult();
System.out.println("Snapshot: " + snapshot.getName() + ", Status: " + snapshot.getStatus());

Get Snapshot

ConfigurationSnapshot snapshot = configClient.getSnapshot("release-v1.0");
System.out.println("Created: " + snapshot.getCreatedAt());
System.out.println("Items: " + snapshot.getItemCount());

List Settings in Snapshot

PagedIterable<ConfigurationSetting> settings = 
    configClient.listConfigurationSettingsForSnapshot("release-v1.0");

for (ConfigurationSetting setting : settings) {
    System.out.println(setting.getKey() + " = " + setting.getValue());
}

Archive Snapshot

ConfigurationSnapshot archived = configClient.archiveSnapshot("release-v1.0");
System.out.println("Status: " + archived.getStatus()); // archived

Recover Snapshot

ConfigurationSnapshot recovered = configClient.recoverSnapshot("release-v1.0");
System.out.println("Status: " + recovered.getStatus()); // ready

List All Snapshots

import com.azure.data.appconfiguration.models.SnapshotSelector;

SnapshotSelector selector = new SnapshotSelector().setNameFilter("release-*");
PagedIterable<ConfigurationSnapshot> snapshots = configClient.listSnapshots(selector);

for (ConfigurationSnapshot snap : snapshots) {
    System.out.println(snap.getName() + " - " + snap.getStatus());
}

Labels

List Labels

import com.azure.data.appconfiguration.models.SettingLabelSelector;

configClient.listLabels(new SettingLabelSelector().setNameFilter("*"))
    .forEach(label -> System.out.println("Label: " + label.getName()));

Async Operations

ConfigurationAsyncClient asyncClient = new ConfigurationClientBuilder()
    .connectionString(connectionString)
    .buildAsyncClient();

// Async list with reactive streams
asyncClient.listConfigurationSettings(new SettingSelector().setLabelFilter("Production"))
    .subscribe(
        setting -> System.out.println(setting.getKey() + " = " + setting.getValue()),
        error -> System.err.println("Error: " + error.getMessage()),
        () -> System.out.println("Completed")
    );

Error Handling

import com.azure.core.exception.HttpResponseException;

try {
    configClient.getConfigurationSetting("nonexistent", null);
} catch (HttpResponseException e) {
    if (e.getResponse().getStatusCode() == 404) {
        System.err.println("Setting not found");
    } else {
        System.err.println("Error: " + e.getMessage());
    }
}

Best Practices

  1. Use labels — Separate configurations by environment (Dev, Staging, Production)
  2. Use snapshots — Create immutable snapshots for releases
  3. Feature flags — Use for gradual rollouts and A/B testing
  4. Secret references — Store sensitive values in Key Vault
  5. Conditional requests — Use ETags for optimistic concurrency
  6. Read-only protection — Lock critical production settings
  7. Use Entra ID — Preferred over connection strings
  8. Async client — Use for high-throughput scenarios

Reference Links

Resource URL
Maven Package https://central.sonatype.com/artifact/com.azure/azure-data-appconfiguration
GitHub https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/appconfiguration/azure-data-appconfiguration
API Documentation https://aka.ms/java-docs
Product Docs https://learn.microsoft.com/azure/azure-app-configuration
Samples https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/appconfiguration/azure-data-appconfiguration/src/samples
Troubleshooting https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/appconfiguration/azure-data-appconfiguration/TROUBLESHOOTING.md
Files (skills)
  • references
    • examples.md 25.2 KB
      # Azure App Configuration Java SDK - Examples
      
      Comprehensive code examples for the Azure App Configuration SDK for Java.
      
      ## Table of Contents
      
      - [Maven Dependency](#maven-dependency)
      - [Client Creation](#client-creation)
      - [Configuration Settings CRUD](#configuration-settings-crud)
      - [List and Filter Settings](#list-and-filter-settings)
      - [Feature Flags](#feature-flags)
      - [Secret References](#secret-references)
      - [Read-Only Settings](#read-only-settings)
      - [Snapshots](#snapshots)
      - [Labels](#labels)
      - [Async Operations](#async-operations)
      - [Error Handling](#error-handling)
      - [Complete Application Example](#complete-application-example)
      
      ## Maven Dependency
      
      ```xml
      <dependency>
          <groupId>com.azure</groupId>
          <artifactId>azure-data-appconfiguration</artifactId>
          <version>1.8.0</version>
      </dependency>
      
      <!-- For DefaultAzureCredential -->
      <dependency>
          <groupId>com.azure</groupId>
          <artifactId>azure-identity</artifactId>
          <version>1.14.2</version>
      </dependency>
      ```
      
      Or use Azure SDK BOM:
      
      ```xml
      <dependencyManagement>
          <dependencies>
              <dependency>
                  <groupId>com.azure</groupId>
                  <artifactId>azure-sdk-bom</artifactId>
                  <version>1.2.28</version>
                  <type>pom</type>
                  <scope>import</scope>
              </dependency>
          </dependencies>
      </dependencyManagement>
      
      <dependencies>
          <dependency>
              <groupId>com.azure</groupId>
              <artifactId>azure-data-appconfiguration</artifactId>
          </dependency>
      </dependencies>
      ```
      
      ## Client Creation
      
      ### With Connection String
      
      ```java
      import com.azure.data.appconfiguration.ConfigurationClient;
      import com.azure.data.appconfiguration.ConfigurationClientBuilder;
      
      String connectionString = System.getenv("AZURE_APPCONFIG_CONNECTION_STRING");
      
      ConfigurationClient client = new ConfigurationClientBuilder()
          .connectionString(connectionString)
          .buildClient();
      ```
      
      ### With Entra ID (Recommended)
      
      ```java
      import com.azure.identity.DefaultAzureCredentialBuilder;
      
      String endpoint = System.getenv("AZURE_APPCONFIG_ENDPOINT");
      
      ConfigurationClient client = new ConfigurationClientBuilder()
          .credential(new DefaultAzureCredentialBuilder().build())
          .endpoint(endpoint)
          .buildClient();
      ```
      
      ### Async Client
      
      ```java
      import com.azure.data.appconfiguration.ConfigurationAsyncClient;
      
      ConfigurationAsyncClient asyncClient = new ConfigurationClientBuilder()
          .credential(new DefaultAzureCredentialBuilder().build())
          .endpoint(endpoint)
          .buildAsyncClient();
      ```
      
      ## Configuration Settings CRUD
      
      ### Create Setting (Add)
      
      Creates only if setting doesn't exist:
      
      ```java
      import com.azure.data.appconfiguration.models.ConfigurationSetting;
      
      // Add with key, label, and value
      ConfigurationSetting setting = client.addConfigurationSetting(
          "app/database/connection",    // key
          "Production",                  // label (can be null)
          "Server=prod.db.com;Database=myapp"  // value
      );
      
      System.out.println("Setting created:");
      System.out.println("  Key: " + setting.getKey());
      System.out.println("  Label: " + setting.getLabel());
      System.out.println("  Value: " + setting.getValue());
      System.out.println("  ETag: " + setting.getETag());
      ```
      
      ### Create or Update Setting (Set)
      
      Creates or overwrites:
      
      ```java
      ConfigurationSetting setting = client.setConfigurationSetting(
          "app/cache/enabled",
          "Production",
          "true"
      );
      
      System.out.println("Setting set: " + setting.getKey() + " = " + setting.getValue());
      ```
      
      ### Create with ConfigurationSetting Object
      
      ```java
      ConfigurationSetting newSetting = new ConfigurationSetting()
          .setKey("app/feature/timeout")
          .setLabel("Production")
          .setValue("30000")
          .setContentType("application/json");
      
      ConfigurationSetting created = client.addConfigurationSetting(newSetting);
      ```
      
      ### Get Setting
      
      ```java
      ConfigurationSetting setting = client.getConfigurationSetting(
          "app/database/connection",
          "Production"
      );
      
      System.out.println("=== Setting Details ===");
      System.out.println("Key: " + setting.getKey());
      System.out.println("Label: " + setting.getLabel());
      System.out.println("Value: " + setting.getValue());
      System.out.println("Content-Type: " + setting.getContentType());
      System.out.println("Last Modified: " + setting.getLastModified());
      System.out.println("ETag: " + setting.getETag());
      System.out.println("Read-Only: " + setting.isReadOnly());
      ```
      
      ### Conditional Get (If Changed)
      
      Only fetch if modified since last retrieval:
      
      ```java
      import com.azure.core.http.rest.Response;
      import com.azure.core.util.Context;
      
      // First, get the setting with its ETag
      ConfigurationSetting setting = client.getConfigurationSetting("app/cache/enabled", "Production");
      
      // Later, check if it changed
      Response<ConfigurationSetting> response = client.getConfigurationSettingWithResponse(
          setting,      // Setting with ETag
          null,         // Accept datetime
          true,         // ifChanged - only fetch if modified
          Context.NONE
      );
      
      if (response.getStatusCode() == 304) {
          System.out.println("Setting not modified since last fetch");
      } else {
          ConfigurationSetting updated = response.getValue();
          System.out.println("Setting was modified: " + updated.getValue());
      }
      ```
      
      ### Update Setting
      
      ```java
      // Simple update
      ConfigurationSetting updated = client.setConfigurationSetting(
          "app/cache/enabled",
          "Production",
          "false"
      );
      
      System.out.println("Updated value: " + updated.getValue());
      ```
      
      ### Conditional Update (If Unchanged)
      
      Only update if no concurrent modifications:
      
      ```java
      // Get current setting with ETag
      ConfigurationSetting current = client.getConfigurationSetting("app/timeout", "Production");
      
      // Modify the value
      current.setValue("60000");
      
      // Update only if ETag matches (optimistic concurrency)
      Response<ConfigurationSetting> response = client.setConfigurationSettingWithResponse(
          current,     // Setting with current ETag
          true,        // ifUnchanged - only update if ETag matches
          Context.NONE
      );
      
      if (response.getStatusCode() == 200) {
          System.out.println("Update successful");
      } else {
          System.out.println("Conflict - setting was modified by another process");
      }
      ```
      
      ### Delete Setting
      
      ```java
      ConfigurationSetting deleted = client.deleteConfigurationSetting(
          "app/cache/enabled",
          "Production"
      );
      
      if (deleted != null) {
          System.out.println("Deleted setting: " + deleted.getKey());
      }
      ```
      
      ### Conditional Delete
      
      ```java
      Response<ConfigurationSetting> response = client.deleteConfigurationSettingWithResponse(
          setting,     // Setting with ETag
          true,        // ifUnchanged
          Context.NONE
      );
      
      if (response.getStatusCode() == 200) {
          System.out.println("Setting deleted");
      }
      ```
      
      ## List and Filter Settings
      
      ### List All Settings
      
      ```java
      import com.azure.data.appconfiguration.models.SettingSelector;
      import com.azure.core.http.rest.PagedIterable;
      
      PagedIterable<ConfigurationSetting> settings = client.listConfigurationSettings(
          new SettingSelector()
      );
      
      System.out.println("=== All Settings ===");
      for (ConfigurationSetting s : settings) {
          System.out.printf("%s [%s] = %s%n", s.getKey(), s.getLabel(), s.getValue());
      }
      ```
      
      ### List by Key Pattern
      
      ```java
      SettingSelector selector = new SettingSelector()
          .setKeyFilter("app/*");  // Wildcard pattern
      
      PagedIterable<ConfigurationSetting> settings = client.listConfigurationSettings(selector);
      
      for (ConfigurationSetting s : settings) {
          System.out.println(s.getKey() + " = " + s.getValue());
      }
      ```
      
      ### List by Label
      
      ```java
      SettingSelector selector = new SettingSelector()
          .setKeyFilter("*")
          .setLabelFilter("Production");
      
      PagedIterable<ConfigurationSetting> settings = client.listConfigurationSettings(selector);
      ```
      
      ### List by Multiple Keys
      
      ```java
      SettingSelector selector = new SettingSelector()
          .setKeyFilter("app/database/*,app/cache/*");  // Comma-separated patterns
      
      PagedIterable<ConfigurationSetting> settings = client.listConfigurationSettings(selector);
      ```
      
      ### List Null Labels Only
      
      ```java
      SettingSelector selector = new SettingSelector()
          .setKeyFilter("*")
          .setLabelFilter("\0");  // Null label filter
      
      PagedIterable<ConfigurationSetting> settings = client.listConfigurationSettings(selector);
      ```
      
      ### Select Specific Fields
      
      ```java
      import com.azure.data.appconfiguration.models.SettingFields;
      import java.util.EnumSet;
      
      SettingSelector selector = new SettingSelector()
          .setKeyFilter("*")
          .setFields(EnumSet.of(SettingFields.KEY, SettingFields.VALUE, SettingFields.LAST_MODIFIED));
      
      PagedIterable<ConfigurationSetting> settings = client.listConfigurationSettings(selector);
      ```
      
      ### List Revisions
      
      View history of changes:
      
      ```java
      SettingSelector selector = new SettingSelector()
          .setKeyFilter("app/database/connection");
      
      PagedIterable<ConfigurationSetting> revisions = client.listRevisions(selector);
      
      System.out.println("=== Setting Revisions ===");
      for (ConfigurationSetting revision : revisions) {
          System.out.printf("Value: %s, Modified: %s%n",
              revision.getValue(),
              revision.getLastModified());
      }
      ```
      
      ## Feature Flags
      
      ### Create Feature Flag
      
      ```java
      import com.azure.data.appconfiguration.models.FeatureFlagConfigurationSetting;
      import com.azure.data.appconfiguration.models.FeatureFlagFilter;
      import java.util.Arrays;
      
      // Simple feature flag
      FeatureFlagConfigurationSetting simpleFlag = new FeatureFlagConfigurationSetting("dark-mode", true)
          .setDescription("Enable dark mode theme");
      
      client.addConfigurationSetting(simpleFlag);
      
      // Feature flag with percentage filter
      FeatureFlagFilter percentageFilter = new FeatureFlagFilter("Microsoft.Percentage")
          .addParameter("Value", 50);  // 50% rollout
      
      FeatureFlagConfigurationSetting betaFlag = new FeatureFlagConfigurationSetting("beta-feature", true)
          .setDescription("Beta feature with gradual rollout")
          .setClientFilters(Arrays.asList(percentageFilter));
      
      FeatureFlagConfigurationSetting created = (FeatureFlagConfigurationSetting)
          client.addConfigurationSetting(betaFlag);
      
      System.out.println("Feature flag created: " + created.getFeatureId());
      ```
      
      ### Create Feature Flag with Targeting Filter
      
      ```java
      import java.util.HashMap;
      import java.util.Map;
      
      Map<String, Object> targetingParams = new HashMap<>();
      targetingParams.put("Audience", Map.of(
          "Users", Arrays.asList("user1@example.com", "user2@example.com"),
          "Groups", Arrays.asList(
              Map.of("Name", "beta-testers", "RolloutPercentage", 100),
              Map.of("Name", "employees", "RolloutPercentage", 50)
          ),
          "DefaultRolloutPercentage", 10
      ));
      
      FeatureFlagFilter targetingFilter = new FeatureFlagFilter("Microsoft.Targeting")
          .setParameters(targetingParams);
      
      FeatureFlagConfigurationSetting targetedFlag = new FeatureFlagConfigurationSetting("new-dashboard", true)
          .setDescription("New dashboard with targeted rollout")
          .setClientFilters(Arrays.asList(targetingFilter));
      
      client.addConfigurationSetting(targetedFlag);
      ```
      
      ### Get Feature Flag
      
      ```java
      FeatureFlagConfigurationSetting flag = (FeatureFlagConfigurationSetting)
          client.getConfigurationSetting(
              ".appconfig.featureflag/beta-feature",  // Key format for feature flags
              null
          );
      
      System.out.println("=== Feature Flag ===");
      System.out.println("Feature ID: " + flag.getFeatureId());
      System.out.println("Enabled: " + flag.isEnabled());
      System.out.println("Description: " + flag.getDescription());
      System.out.println("Filters: " + flag.getClientFilters());
      ```
      
      ### Update Feature Flag
      
      ```java
      FeatureFlagConfigurationSetting flag = (FeatureFlagConfigurationSetting)
          client.getConfigurationSetting(".appconfig.featureflag/beta-feature", null);
      
      // Disable the feature
      flag.setEnabled(false);
      
      FeatureFlagConfigurationSetting updated = (FeatureFlagConfigurationSetting)
          client.setConfigurationSetting(flag);
      
      System.out.println("Feature flag updated. Enabled: " + updated.isEnabled());
      ```
      
      ### List Feature Flags
      
      ```java
      SettingSelector selector = new SettingSelector()
          .setKeyFilter(".appconfig.featureflag/*");
      
      PagedIterable<ConfigurationSetting> flags = client.listConfigurationSettings(selector);
      
      System.out.println("=== Feature Flags ===");
      for (ConfigurationSetting setting : flags) {
          if (setting instanceof FeatureFlagConfigurationSetting) {
              FeatureFlagConfigurationSetting flag = (FeatureFlagConfigurationSetting) setting;
              System.out.printf("%s: %s%n", flag.getFeatureId(), flag.isEnabled() ? "ON" : "OFF");
          }
      }
      ```
      
      ## Secret References
      
      ### Create Secret Reference
      
      ```java
      import com.azure.data.appconfiguration.models.SecretReferenceConfigurationSetting;
      
      SecretReferenceConfigurationSetting secretRef = new SecretReferenceConfigurationSetting(
          "app/secrets/api-key",                                    // Key
          "https://myvault.vault.azure.net/secrets/api-key"        // Key Vault secret URI
      );
      
      SecretReferenceConfigurationSetting created = (SecretReferenceConfigurationSetting)
          client.addConfigurationSetting(secretRef);
      
      System.out.println("Secret reference created: " + created.getKey());
      System.out.println("Points to: " + created.getSecretId());
      ```
      
      ### Get Secret Reference
      
      ```java
      SecretReferenceConfigurationSetting ref = (SecretReferenceConfigurationSetting)
          client.getConfigurationSetting("app/secrets/api-key", null);
      
      System.out.println("Secret URI: " + ref.getSecretId());
      
      // To get the actual secret value, use Key Vault SDK
      // SecretClient kvClient = new SecretClientBuilder()...
      // KeyVaultSecret secret = kvClient.getSecret("api-key");
      ```
      
      ### Update Secret Reference
      
      ```java
      SecretReferenceConfigurationSetting ref = (SecretReferenceConfigurationSetting)
          client.getConfigurationSetting("app/secrets/api-key", null);
      
      // Point to a different secret version
      ref.setSecretId("https://myvault.vault.azure.net/secrets/api-key/abc123");
      
      client.setConfigurationSetting(ref);
      ```
      
      ## Read-Only Settings
      
      ### Set Read-Only
      
      ```java
      ConfigurationSetting readOnly = client.setReadOnly(
          "app/critical/setting",
          "Production",
          true  // isReadOnly
      );
      
      System.out.println("Setting is now read-only: " + readOnly.isReadOnly());
      ```
      
      ### Clear Read-Only
      
      ```java
      ConfigurationSetting writable = client.setReadOnly(
          "app/critical/setting",
          "Production",
          false  // make writable
      );
      
      System.out.println("Setting is writable: " + !writable.isReadOnly());
      ```
      
      ## Snapshots
      
      ### Create Snapshot
      
      ```java
      import com.azure.data.appconfiguration.models.ConfigurationSnapshot;
      import com.azure.data.appconfiguration.models.ConfigurationSettingsFilter;
      import com.azure.core.util.polling.SyncPoller;
      import com.azure.core.util.polling.PollOperationDetails;
      import java.time.Duration;
      import java.util.ArrayList;
      import java.util.List;
      
      List<ConfigurationSettingsFilter> filters = new ArrayList<>();
      filters.add(new ConfigurationSettingsFilter("app/*"));  // Include all app/* keys
      
      SyncPoller<PollOperationDetails, ConfigurationSnapshot> poller = client.beginCreateSnapshot(
          "release-v1.0",
          new ConfigurationSnapshot(filters),
          Context.NONE
      );
      
      poller.setPollInterval(Duration.ofSeconds(10));
      poller.waitForCompletion();
      
      ConfigurationSnapshot snapshot = poller.getFinalResult();
      
      System.out.println("=== Snapshot Created ===");
      System.out.println("Name: " + snapshot.getName());
      System.out.println("Status: " + snapshot.getStatus());
      System.out.println("Item Count: " + snapshot.getItemCount());
      System.out.println("Size: " + snapshot.getSizeInBytes() + " bytes");
      System.out.println("Created: " + snapshot.getCreatedAt());
      ```
      
      ### Get Snapshot
      
      ```java
      ConfigurationSnapshot snapshot = client.getSnapshot("release-v1.0");
      
      System.out.println("Snapshot: " + snapshot.getName());
      System.out.println("Status: " + snapshot.getStatus());
      System.out.println("Items: " + snapshot.getItemCount());
      System.out.println("Retention: " + snapshot.getRetentionPeriod());
      ```
      
      ### List Settings in Snapshot
      
      ```java
      PagedIterable<ConfigurationSetting> settings = 
          client.listConfigurationSettingsForSnapshot("release-v1.0");
      
      System.out.println("=== Settings in Snapshot ===");
      for (ConfigurationSetting setting : settings) {
          System.out.printf("%s = %s%n", setting.getKey(), setting.getValue());
      }
      ```
      
      ### Archive Snapshot
      
      ```java
      ConfigurationSnapshot archived = client.archiveSnapshot("release-v1.0");
      System.out.println("Status: " + archived.getStatus());  // archived
      ```
      
      ### Recover Snapshot
      
      ```java
      ConfigurationSnapshot recovered = client.recoverSnapshot("release-v1.0");
      System.out.println("Status: " + recovered.getStatus());  // ready
      ```
      
      ### List All Snapshots
      
      ```java
      import com.azure.data.appconfiguration.models.SnapshotSelector;
      
      SnapshotSelector selector = new SnapshotSelector()
          .setNameFilter("release-*");
      
      PagedIterable<ConfigurationSnapshot> snapshots = client.listSnapshots(selector);
      
      System.out.println("=== Snapshots ===");
      for (ConfigurationSnapshot snap : snapshots) {
          System.out.printf("%s - %s (%d items)%n",
              snap.getName(),
              snap.getStatus(),
              snap.getItemCount());
      }
      ```
      
      ## Labels
      
      ### List Labels
      
      ```java
      import com.azure.data.appconfiguration.models.SettingLabelSelector;
      
      PagedIterable<SettingLabel> labels = client.listLabels(
          new SettingLabelSelector().setNameFilter("*")
      );
      
      System.out.println("=== Labels ===");
      for (SettingLabel label : labels) {
          System.out.println("Label: " + (label.getName() == null ? "(null)" : label.getName()));
      }
      ```
      
      ## Async Operations
      
      ### Async List with Reactive Streams
      
      ```java
      ConfigurationAsyncClient asyncClient = new ConfigurationClientBuilder()
          .credential(new DefaultAzureCredentialBuilder().build())
          .endpoint(endpoint)
          .buildAsyncClient();
      
      asyncClient.listConfigurationSettings(new SettingSelector().setLabelFilter("Production"))
          .subscribe(
              setting -> System.out.println(setting.getKey() + " = " + setting.getValue()),
              error -> System.err.println("Error: " + error.getMessage()),
              () -> System.out.println("Completed listing")
          );
      
      // Keep application running for async operations
      Thread.sleep(5000);
      ```
      
      ### Async Get and Set
      
      ```java
      asyncClient.getConfigurationSetting("app/timeout", "Production")
          .flatMap(setting -> {
              setting.setValue("45000");
              return asyncClient.setConfigurationSetting(setting);
          })
          .subscribe(
              updated -> System.out.println("Updated: " + updated.getValue()),
              error -> System.err.println("Error: " + error.getMessage())
          );
      ```
      
      ## Error Handling
      
      ```java
      import com.azure.core.exception.HttpResponseException;
      import com.azure.core.exception.ResourceNotFoundException;
      
      try {
          ConfigurationSetting setting = client.getConfigurationSetting("nonexistent", null);
      } catch (ResourceNotFoundException e) {
          System.err.println("Setting not found");
      } catch (HttpResponseException e) {
          int statusCode = e.getResponse().getStatusCode();
          
          switch (statusCode) {
              case 401:
                  System.err.println("Unauthorized - check credentials");
                  break;
              case 403:
                  System.err.println("Forbidden - check permissions");
                  break;
              case 409:
                  System.err.println("Conflict - setting already exists or ETag mismatch");
                  break;
              case 412:
                  System.err.println("Precondition failed - setting was modified");
                  break;
              case 429:
                  System.err.println("Rate limited - retry with backoff");
                  break;
              default:
                  System.err.println("Error: " + e.getMessage());
          }
      }
      ```
      
      ## Complete Application Example
      
      ```java
      import com.azure.data.appconfiguration.ConfigurationClient;
      import com.azure.data.appconfiguration.ConfigurationClientBuilder;
      import com.azure.data.appconfiguration.models.*;
      import com.azure.core.http.rest.PagedIterable;
      import com.azure.identity.DefaultAzureCredentialBuilder;
      
      import java.util.*;
      
      public class AppConfigurationManager {
          
          private final ConfigurationClient client;
          private final String environment;
          
          public AppConfigurationManager(String environment) {
              this.client = new ConfigurationClientBuilder()
                  .endpoint(System.getenv("AZURE_APPCONFIG_ENDPOINT"))
                  .credential(new DefaultAzureCredentialBuilder().build())
                  .buildClient();
              this.environment = environment;
          }
          
          public String getSetting(String key) {
              try {
                  ConfigurationSetting setting = client.getConfigurationSetting(key, environment);
                  return setting.getValue();
              } catch (Exception e) {
                  // Try without label
                  try {
                      ConfigurationSetting setting = client.getConfigurationSetting(key, null);
                      return setting.getValue();
                  } catch (Exception ex) {
                      return null;
                  }
              }
          }
          
          public void setSetting(String key, String value) {
              client.setConfigurationSetting(key, environment, value);
          }
          
          public boolean isFeatureEnabled(String featureId) {
              try {
                  String key = ".appconfig.featureflag/" + featureId;
                  ConfigurationSetting setting = client.getConfigurationSetting(key, environment);
                  
                  if (setting instanceof FeatureFlagConfigurationSetting) {
                      return ((FeatureFlagConfigurationSetting) setting).isEnabled();
                  }
                  
                  // Try without label
                  setting = client.getConfigurationSetting(key, null);
                  if (setting instanceof FeatureFlagConfigurationSetting) {
                      return ((FeatureFlagConfigurationSetting) setting).isEnabled();
                  }
              } catch (Exception e) {
                  // Feature flag doesn't exist - default to disabled
              }
              return false;
          }
          
          public void setFeatureEnabled(String featureId, boolean enabled) {
              String key = ".appconfig.featureflag/" + featureId;
              
              try {
                  FeatureFlagConfigurationSetting flag = (FeatureFlagConfigurationSetting)
                      client.getConfigurationSetting(key, environment);
                  flag.setEnabled(enabled);
                  client.setConfigurationSetting(flag);
              } catch (Exception e) {
                  // Create new feature flag
                  FeatureFlagConfigurationSetting newFlag = new FeatureFlagConfigurationSetting(featureId, enabled);
                  newFlag.setLabel(environment);
                  client.addConfigurationSetting(newFlag);
              }
          }
          
          public Map<String, String> getAllSettings(String prefix) {
              Map<String, String> result = new HashMap<>();
              
              SettingSelector selector = new SettingSelector()
                  .setKeyFilter(prefix + "*")
                  .setLabelFilter(environment);
              
              PagedIterable<ConfigurationSetting> settings = client.listConfigurationSettings(selector);
              
              for (ConfigurationSetting setting : settings) {
                  if (!(setting instanceof FeatureFlagConfigurationSetting) 
                      && !(setting instanceof SecretReferenceConfigurationSetting)) {
                      result.put(setting.getKey(), setting.getValue());
                  }
              }
              
              return result;
          }
          
          public void createSnapshot(String snapshotName, String keyPrefix) {
              List<ConfigurationSettingsFilter> filters = new ArrayList<>();
              filters.add(new ConfigurationSettingsFilter(keyPrefix + "*")
                  .setLabel(environment));
              
              var poller = client.beginCreateSnapshot(snapshotName, new ConfigurationSnapshot(filters), null);
              poller.waitForCompletion();
              
              ConfigurationSnapshot snapshot = poller.getFinalResult();
              System.out.printf("Snapshot '%s' created with %d items%n", 
                  snapshot.getName(), snapshot.getItemCount());
          }
          
          public static void main(String[] args) {
              AppConfigurationManager config = new AppConfigurationManager("Production");
              
              // Set some configuration
              config.setSetting("app/database/timeout", "30000");
              config.setSetting("app/cache/ttl", "3600");
              
              // Get configuration
              String timeout = config.getSetting("app/database/timeout");
              System.out.println("Database timeout: " + timeout);
              
              // Feature flags
              config.setFeatureEnabled("dark-mode", true);
              
              if (config.isFeatureEnabled("dark-mode")) {
                  System.out.println("Dark mode is enabled");
              }
              
              // Get all app settings
              Map<String, String> appSettings = config.getAllSettings("app/");
              System.out.println("\n=== All App Settings ===");
              appSettings.forEach((key, value) -> 
                  System.out.printf("%s = %s%n", key, value));
              
              // Create a snapshot for release
              config.createSnapshot("release-" + System.currentTimeMillis(), "app/");
          }
      }
      ```
      
      ## Environment Variables
      
      ```bash
      AZURE_APPCONFIG_CONNECTION_STRING=Endpoint=https://<store>.azconfig.io;Id=<id>;Secret=<secret>
      AZURE_APPCONFIG_ENDPOINT=https://<store>.azconfig.io
      
      # For DefaultAzureCredential
      AZURE_CLIENT_ID=<service-principal-client-id>
      AZURE_CLIENT_SECRET=<service-principal-secret>
      AZURE_TENANT_ID=<tenant-id>
      ```
      
      ## Best Practices
      
      1. **Use labels** — Separate configurations by environment (Dev, Staging, Production)
      2. **Use snapshots** — Create immutable snapshots for releases
      3. **Feature flags** — Use for gradual rollouts and A/B testing
      4. **Secret references** — Store sensitive values in Key Vault, not App Configuration
      5. **Conditional requests** — Use ETags for optimistic concurrency
      6. **Read-only protection** — Lock critical production settings
      7. **Use Entra ID** — Preferred over connection strings for security
      8. **Async client** — Use for high-throughput scenarios
      
  • SKILL.md 13.6 KB
    ---
    name: azure-appconfiguration-java
    description: |
      Azure App Configuration SDK for Java. Centralized application configuration management with key-value settings, feature flags, and snapshots.
      Triggers: "ConfigurationClient java", "app configuration java", "feature flag java", "configuration setting java", "azure config java".
    license: MIT
    metadata:
      author: Microsoft
      version: "1.0.0"
      package: com.azure:azure-data-appconfiguration
    ---
    
    # Azure App Configuration SDK for Java
    
    Client library for Azure App Configuration, a managed service for centralizing application configurations.
    
    ## Installation
    
    ```xml
    <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-data-appconfiguration</artifactId>
        <version>1.8.0</version>
    </dependency>
    ```
    
    Or use Azure SDK BOM:
    
    ```xml
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.azure</groupId>
                <artifactId>azure-sdk-bom</artifactId>
                <version>{bom_version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
    <dependencies>
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-data-appconfiguration</artifactId>
        </dependency>
    </dependencies>
    ```
    
    ## Prerequisites
    
    - Azure App Configuration store
    - Connection string or Entra ID credentials
    
    ## Environment Variables
    
    ```bash
    AZURE_APPCONFIG_CONNECTION_STRING=Endpoint=https://<store>.azconfig.io;Id=<id>;Secret=<secret>  # Alternative to Entra ID auth
    AZURE_APPCONFIG_ENDPOINT=https://<store>.azconfig.io  # Required for all auth methods
    AZURE_TOKEN_CREDENTIALS=prod  # Required only if DefaultAzureCredential is used in production
    ```
    
    ## Client Creation
    
    ### With Connection String
    
    ```java
    import com.azure.data.appconfiguration.ConfigurationClient;
    import com.azure.data.appconfiguration.ConfigurationClientBuilder;
    
    ConfigurationClient configClient = new ConfigurationClientBuilder()
        .connectionString(System.getenv("AZURE_APPCONFIG_CONNECTION_STRING"))
        .buildClient();
    ```
    
    ### Async Client
    
    ```java
    import com.azure.data.appconfiguration.ConfigurationAsyncClient;
    
    ConfigurationAsyncClient asyncClient = new ConfigurationClientBuilder()
        .connectionString(connectionString)
        .buildAsyncClient();
    ```
    
    ### With Entra ID (Recommended)
    
    ```java
    import com.azure.core.credential.TokenCredential;
    import com.azure.identity.AzureIdentityEnvVars;
    import com.azure.identity.DefaultAzureCredentialBuilder;
    import com.azure.identity.ManagedIdentityCredentialBuilder;
    
    // Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>
    TokenCredential credential = new DefaultAzureCredentialBuilder()
        .requireEnvVars(AzureIdentityEnvVars.AZURE_TOKEN_CREDENTIALS)
        .build();
    // Or use a specific credential directly in production:
    // See https://learn.microsoft.com/java/api/overview/azure/identity-readme?view=azure-java-stable#credential-classes
    // TokenCredential credential = new ManagedIdentityCredentialBuilder().build();
    
    ConfigurationClient configClient = new ConfigurationClientBuilder()
        .credential(credential)
        .endpoint(System.getenv("AZURE_APPCONFIG_ENDPOINT"))
        .buildClient();
    ```
    
    ## Key Concepts
    
    | Concept | Description |
    |---------|-------------|
    | Configuration Setting | Key-value pair with optional label |
    | Label | Dimension for separating settings (e.g., environments) |
    | Feature Flag | Special setting for feature management |
    | Secret Reference | Setting pointing to Key Vault secret |
    | Snapshot | Point-in-time immutable view of settings |
    
    ## Configuration Setting Operations
    
    ### Create Setting (Add)
    
    Creates only if setting doesn't exist:
    
    ```java
    import com.azure.data.appconfiguration.models.ConfigurationSetting;
    
    ConfigurationSetting setting = configClient.addConfigurationSetting(
        "app/database/connection", 
        "Production", 
        "Server=prod.db.com;Database=myapp"
    );
    ```
    
    ### Create or Update Setting (Set)
    
    Creates or overwrites:
    
    ```java
    ConfigurationSetting setting = configClient.setConfigurationSetting(
        "app/cache/enabled", 
        "Production", 
        "true"
    );
    ```
    
    ### Get Setting
    
    ```java
    ConfigurationSetting setting = configClient.getConfigurationSetting(
        "app/database/connection", 
        "Production"
    );
    System.out.println("Value: " + setting.getValue());
    System.out.println("Content-Type: " + setting.getContentType());
    System.out.println("Last Modified: " + setting.getLastModified());
    ```
    
    ### Conditional Get (If Changed)
    
    ```java
    import com.azure.core.http.rest.Response;
    import com.azure.core.util.Context;
    
    Response<ConfigurationSetting> response = configClient.getConfigurationSettingWithResponse(
        setting,      // Setting with ETag
        null,         // Accept datetime
        true,         // ifChanged - only fetch if modified
        Context.NONE
    );
    
    if (response.getStatusCode() == 304) {
        System.out.println("Setting not modified");
    } else {
        ConfigurationSetting updated = response.getValue();
    }
    ```
    
    ### Update Setting
    
    ```java
    ConfigurationSetting updated = configClient.setConfigurationSetting(
        "app/cache/enabled", 
        "Production", 
        "false"
    );
    ```
    
    ### Conditional Update (If Unchanged)
    
    ```java
    // Only update if ETag matches (no concurrent modifications)
    Response<ConfigurationSetting> response = configClient.setConfigurationSettingWithResponse(
        setting,     // Setting with current ETag
        true,        // ifUnchanged
        Context.NONE
    );
    ```
    
    ### Delete Setting
    
    ```java
    ConfigurationSetting deleted = configClient.deleteConfigurationSetting(
        "app/cache/enabled", 
        "Production"
    );
    ```
    
    ### Conditional Delete
    
    ```java
    Response<ConfigurationSetting> response = configClient.deleteConfigurationSettingWithResponse(
        setting,     // Setting with ETag
        true,        // ifUnchanged
        Context.NONE
    );
    ```
    
    ## List and Filter Settings
    
    ### List by Key Pattern
    
    ```java
    import com.azure.data.appconfiguration.models.SettingSelector;
    import com.azure.core.http.rest.PagedIterable;
    
    SettingSelector selector = new SettingSelector()
        .setKeyFilter("app/*");
    
    PagedIterable<ConfigurationSetting> settings = configClient.listConfigurationSettings(selector);
    for (ConfigurationSetting s : settings) {
        System.out.println(s.getKey() + " = " + s.getValue());
    }
    ```
    
    ### List by Label
    
    ```java
    SettingSelector selector = new SettingSelector()
        .setKeyFilter("*")
        .setLabelFilter("Production");
    
    PagedIterable<ConfigurationSetting> settings = configClient.listConfigurationSettings(selector);
    ```
    
    ### List by Multiple Keys
    
    ```java
    SettingSelector selector = new SettingSelector()
        .setKeyFilter("app/database/*,app/cache/*");
    
    PagedIterable<ConfigurationSetting> settings = configClient.listConfigurationSettings(selector);
    ```
    
    ### List Revisions
    
    ```java
    SettingSelector selector = new SettingSelector()
        .setKeyFilter("app/database/connection");
    
    PagedIterable<ConfigurationSetting> revisions = configClient.listRevisions(selector);
    for (ConfigurationSetting revision : revisions) {
        System.out.println("Value: " + revision.getValue() + ", Modified: " + revision.getLastModified());
    }
    ```
    
    ## Feature Flags
    
    ### Create Feature Flag
    
    ```java
    import com.azure.data.appconfiguration.models.FeatureFlagConfigurationSetting;
    import com.azure.data.appconfiguration.models.FeatureFlagFilter;
    import java.util.Arrays;
    
    FeatureFlagFilter percentageFilter = new FeatureFlagFilter("Microsoft.Percentage")
        .addParameter("Value", 50);
    
    FeatureFlagConfigurationSetting featureFlag = new FeatureFlagConfigurationSetting("beta-feature", true)
        .setDescription("Beta feature rollout")
        .setClientFilters(Arrays.asList(percentageFilter));
    
    FeatureFlagConfigurationSetting created = (FeatureFlagConfigurationSetting)
        configClient.addConfigurationSetting(featureFlag);
    ```
    
    ### Get Feature Flag
    
    ```java
    FeatureFlagConfigurationSetting flag = (FeatureFlagConfigurationSetting)
        configClient.getConfigurationSetting(featureFlag);
    
    System.out.println("Feature: " + flag.getFeatureId());
    System.out.println("Enabled: " + flag.isEnabled());
    System.out.println("Filters: " + flag.getClientFilters());
    ```
    
    ### Update Feature Flag
    
    ```java
    featureFlag.setEnabled(false);
    FeatureFlagConfigurationSetting updated = (FeatureFlagConfigurationSetting)
        configClient.setConfigurationSetting(featureFlag);
    ```
    
    ## Secret References
    
    ### Create Secret Reference
    
    ```java
    import com.azure.data.appconfiguration.models.SecretReferenceConfigurationSetting;
    
    SecretReferenceConfigurationSetting secretRef = new SecretReferenceConfigurationSetting(
        "app/secrets/api-key",
        "https://myvault.vault.azure.net/secrets/api-key"
    );
    
    SecretReferenceConfigurationSetting created = (SecretReferenceConfigurationSetting)
        configClient.addConfigurationSetting(secretRef);
    ```
    
    ### Get Secret Reference
    
    ```java
    SecretReferenceConfigurationSetting ref = (SecretReferenceConfigurationSetting)
        configClient.getConfigurationSetting(secretRef);
    
    System.out.println("Secret URI: " + ref.getSecretId());
    ```
    
    ## Read-Only Settings
    
    ### Set Read-Only
    
    ```java
    ConfigurationSetting readOnly = configClient.setReadOnly(
        "app/critical/setting", 
        "Production", 
        true
    );
    ```
    
    ### Clear Read-Only
    
    ```java
    ConfigurationSetting writable = configClient.setReadOnly(
        "app/critical/setting", 
        "Production", 
        false
    );
    ```
    
    ## Snapshots
    
    ### Create Snapshot
    
    ```java
    import com.azure.data.appconfiguration.models.ConfigurationSnapshot;
    import com.azure.data.appconfiguration.models.ConfigurationSettingsFilter;
    import com.azure.core.util.polling.SyncPoller;
    import com.azure.core.util.polling.PollOperationDetails;
    
    List<ConfigurationSettingsFilter> filters = new ArrayList<>();
    filters.add(new ConfigurationSettingsFilter("app/*"));
    
    SyncPoller<PollOperationDetails, ConfigurationSnapshot> poller = configClient.beginCreateSnapshot(
        "release-v1.0",
        new ConfigurationSnapshot(filters),
        Context.NONE
    );
    poller.setPollInterval(Duration.ofSeconds(10));
    poller.waitForCompletion();
    
    ConfigurationSnapshot snapshot = poller.getFinalResult();
    System.out.println("Snapshot: " + snapshot.getName() + ", Status: " + snapshot.getStatus());
    ```
    
    ### Get Snapshot
    
    ```java
    ConfigurationSnapshot snapshot = configClient.getSnapshot("release-v1.0");
    System.out.println("Created: " + snapshot.getCreatedAt());
    System.out.println("Items: " + snapshot.getItemCount());
    ```
    
    ### List Settings in Snapshot
    
    ```java
    PagedIterable<ConfigurationSetting> settings = 
        configClient.listConfigurationSettingsForSnapshot("release-v1.0");
    
    for (ConfigurationSetting setting : settings) {
        System.out.println(setting.getKey() + " = " + setting.getValue());
    }
    ```
    
    ### Archive Snapshot
    
    ```java
    ConfigurationSnapshot archived = configClient.archiveSnapshot("release-v1.0");
    System.out.println("Status: " + archived.getStatus()); // archived
    ```
    
    ### Recover Snapshot
    
    ```java
    ConfigurationSnapshot recovered = configClient.recoverSnapshot("release-v1.0");
    System.out.println("Status: " + recovered.getStatus()); // ready
    ```
    
    ### List All Snapshots
    
    ```java
    import com.azure.data.appconfiguration.models.SnapshotSelector;
    
    SnapshotSelector selector = new SnapshotSelector().setNameFilter("release-*");
    PagedIterable<ConfigurationSnapshot> snapshots = configClient.listSnapshots(selector);
    
    for (ConfigurationSnapshot snap : snapshots) {
        System.out.println(snap.getName() + " - " + snap.getStatus());
    }
    ```
    
    ## Labels
    
    ### List Labels
    
    ```java
    import com.azure.data.appconfiguration.models.SettingLabelSelector;
    
    configClient.listLabels(new SettingLabelSelector().setNameFilter("*"))
        .forEach(label -> System.out.println("Label: " + label.getName()));
    ```
    
    ## Async Operations
    
    ```java
    ConfigurationAsyncClient asyncClient = new ConfigurationClientBuilder()
        .connectionString(connectionString)
        .buildAsyncClient();
    
    // Async list with reactive streams
    asyncClient.listConfigurationSettings(new SettingSelector().setLabelFilter("Production"))
        .subscribe(
            setting -> System.out.println(setting.getKey() + " = " + setting.getValue()),
            error -> System.err.println("Error: " + error.getMessage()),
            () -> System.out.println("Completed")
        );
    ```
    
    ## Error Handling
    
    ```java
    import com.azure.core.exception.HttpResponseException;
    
    try {
        configClient.getConfigurationSetting("nonexistent", null);
    } catch (HttpResponseException e) {
        if (e.getResponse().getStatusCode() == 404) {
            System.err.println("Setting not found");
        } else {
            System.err.println("Error: " + e.getMessage());
        }
    }
    ```
    
    ## Best Practices
    
    1. **Use labels** — Separate configurations by environment (Dev, Staging, Production)
    2. **Use snapshots** — Create immutable snapshots for releases
    3. **Feature flags** — Use for gradual rollouts and A/B testing
    4. **Secret references** — Store sensitive values in Key Vault
    5. **Conditional requests** — Use ETags for optimistic concurrency
    6. **Read-only protection** — Lock critical production settings
    7. **Use Entra ID** — Preferred over connection strings
    8. **Async client** — Use for high-throughput scenarios
    
    ## Reference Links
    
    | Resource | URL |
    |----------|-----|
    | Maven Package | https://central.sonatype.com/artifact/com.azure/azure-data-appconfiguration |
    | GitHub | https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/appconfiguration/azure-data-appconfiguration |
    | API Documentation | https://aka.ms/java-docs |
    | Product Docs | https://learn.microsoft.com/azure/azure-app-configuration |
    | Samples | https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/appconfiguration/azure-data-appconfiguration/src/samples |
    | Troubleshooting | https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/appconfiguration/azure-data-appconfiguration/TROUBLESHOOTING.md |
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related