Skip to content

Commit

Permalink
azure-core, add new AzureCloud expandable enum (#43099)
Browse files Browse the repository at this point in the history
* azure cloud

* remove getAzureCloud

* licence header

* add  in test

* changelog for core-management

* suppress test warnings

* spotless

* move AzureProfile to com.azure.core.models

* fix changelog

* remove deprecation

* nit, javadoc
  • Loading branch information
XiaofeiCao authored Jan 10, 2025
1 parent c9f9b83 commit dbd675b
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 0 deletions.
2 changes: 2 additions & 0 deletions sdk/core/azure-core-management/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

### Features Added

- Added `AzureProfile(AzureCloud azureCloud)` constructor overload.

### Breaking Changes

### Bugs Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,68 @@
package com.azure.core.management.profile;

import com.azure.core.management.AzureEnvironment;
import com.azure.core.models.AzureCloud;
import com.azure.core.util.Configuration;
import com.azure.core.util.logging.ClientLogger;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
* Azure profile for client.
*/
public final class AzureProfile {
private static final ClientLogger LOGGER = new ClientLogger(AzureProfile.class);

private final String tenantId;
private final String subscriptionId;
private final AzureEnvironment environment;
private static final Map<AzureCloud, AzureEnvironment> ENDPOINT_MAP = new HashMap<>();

static {
ENDPOINT_MAP.put(AzureCloud.AZURE_PUBLIC_CLOUD, AzureEnvironment.AZURE);
ENDPOINT_MAP.put(AzureCloud.AZURE_CHINA_CLOUD, AzureEnvironment.AZURE_CHINA);
ENDPOINT_MAP.put(AzureCloud.AZURE_US_GOVERNMENT, AzureEnvironment.AZURE_US_GOVERNMENT);
}

/**
* Creates AzureProfile instance with specific Azure cloud. The global cloud is {@link AzureCloud#AZURE_PUBLIC_CLOUD}.
* The tenant ID and subscription ID can be set via environment variables. The environment variables are expected
* as below:
* <ul>
* <li>{@link Configuration#PROPERTY_AZURE_TENANT_ID AZURE_TENANT_ID}</li>
* <li>{@link Configuration#PROPERTY_AZURE_SUBSCRIPTION_ID AZURE_SUBSCRIPTION_ID}</li>
* </ul>
*
* @param azureCloud the Azure cloud
*/
public AzureProfile(AzureCloud azureCloud) {
Objects.requireNonNull(azureCloud);
this.environment = fromAzureCloud(azureCloud);
Configuration configuration = Configuration.getGlobalConfiguration();
this.tenantId = configuration.get(Configuration.PROPERTY_AZURE_TENANT_ID);
this.subscriptionId = configuration.get(Configuration.PROPERTY_AZURE_SUBSCRIPTION_ID);
}

/**
* Creates AzureProfile instance with tenant ID, subscription ID and specific Azure cloud.
* The global cloud is {@link AzureCloud#AZURE_PUBLIC_CLOUD}.
*
* @param tenantId the tenant ID required for Graph Rbac
* @param subscriptionId the subscription ID required for resource management
* @param azureCloud the Azure cloud
*/
public AzureProfile(String tenantId, String subscriptionId, AzureCloud azureCloud) {
Objects.requireNonNull(azureCloud);
this.environment = fromAzureCloud(azureCloud);
this.tenantId = tenantId;
this.subscriptionId = subscriptionId;
}

/**
* <p>Note: Only use this constructor for custom Azure cloud/endpoints.
* Use {@link AzureProfile#AzureProfile(String, String, AzureCloud)} for global environment.</p>
* Creates AzureProfile instance with Azure environment. The global environment is {@link AzureEnvironment#AZURE}.
* The tenant ID and subscription ID can be set via environment variables. The environment variables are expected
* as below:
Expand All @@ -26,6 +74,7 @@ public final class AzureProfile {
* </ul>
*
* @param environment the Azure environment
* @see AzureProfile#AzureProfile(AzureCloud)
*/
public AzureProfile(AzureEnvironment environment) {
Objects.requireNonNull(environment);
Expand All @@ -36,12 +85,15 @@ public AzureProfile(AzureEnvironment environment) {
}

/**
* <p>Note: Only use this constructor for custom Azure cloud/endpoints.
* Use {@link AzureProfile#AzureProfile(String, String, AzureCloud)} for global environment.</p>
* Creates AzureProfile instance with tenant ID, subscription ID and Azure environment.
* The global environment is {@link AzureEnvironment#AZURE}.
*
* @param tenantId the tenant ID required for Graph Rbac
* @param subscriptionId the subscription ID required for resource management
* @param environment the Azure environment
* @see AzureProfile#AzureProfile(String, String, AzureCloud)
*/
public AzureProfile(String tenantId, String subscriptionId, AzureEnvironment environment) {
Objects.requireNonNull(environment);
Expand Down Expand Up @@ -76,4 +128,13 @@ public String getSubscriptionId() {
public AzureEnvironment getEnvironment() {
return environment;
}

private AzureEnvironment fromAzureCloud(AzureCloud azureCloud) {
AzureEnvironment azureEnvironment = ENDPOINT_MAP.get(azureCloud);
if (azureEnvironment == null) {
throw LOGGER.logExceptionAsError(new IllegalArgumentException(
String.format("No endpoint mapping defined for AzureCloud: [%s].", azureCloud)));
}
return azureEnvironment;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.core.management;

import com.azure.core.management.profile.AzureProfile;
import com.azure.core.models.AzureCloud;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.HashMap;

public class AzureProfileTests {
@Test
public void testFromAzureCloud() {
// normal case
AzureProfile azurePublicCloud = new AzureProfile(AzureCloud.AZURE_PUBLIC_CLOUD);
Assertions.assertEquals(AzureEnvironment.AZURE, azurePublicCloud.getEnvironment());

AzureProfile azureChinaCloud = new AzureProfile(AzureCloud.AZURE_CHINA_CLOUD);
Assertions.assertEquals(AzureEnvironment.AZURE_CHINA, azureChinaCloud.getEnvironment());

AzureProfile azureUSGovernment = new AzureProfile(AzureCloud.AZURE_US_GOVERNMENT);
Assertions.assertEquals(AzureEnvironment.AZURE_US_GOVERNMENT, azureUSGovernment.getEnvironment());

// exception case
// exception when initializing using custom AzureCloud
AzureCloud azureCloud = AzureCloud.fromString("Custom");
Assertions.assertNotNull(azureCloud);
Assertions.assertThrows(IllegalArgumentException.class, () -> new AzureProfile(azureCloud));

AzureProfile customEnvironment = new AzureProfile(new AzureEnvironment(new HashMap<>()));
}
}
4 changes: 4 additions & 0 deletions sdk/core/azure-core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## 1.55.0-beta.1 (Unreleased)

### Features Added

- Added `azure.core.models.AzureCloud` expandable enum to represent different Azure clouds.

### Other Changes

- Removed length restriction on application id in `ClientOptions`. ([#42937](/~https://github.com/Azure/azure-sdk-for-java/pull/42937))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.core.models;

import com.azure.core.util.ExpandableStringEnum;

/**
* An expandable enum that describes Azure cloud environment.
*/
public final class AzureCloud extends ExpandableStringEnum<AzureCloud> {
/**
* Azure public cloud.
*/
public static final AzureCloud AZURE_PUBLIC_CLOUD = fromString("AZURE_PUBLIC_CLOUD");
/**
* Azure China cloud.
*/
public static final AzureCloud AZURE_CHINA_CLOUD = fromString("AZURE_CHINA_CLOUD");
/**
* Azure US government cloud.
*/
public static final AzureCloud AZURE_US_GOVERNMENT = fromString("AZURE_US_GOVERNMENT");

/**
* Creates or finds an AzureCloud from its string representation.
*
* @param cloudName cloud name to look for
* @return the corresponding AzureCloud
*/
public static AzureCloud fromString(String cloudName) {
return fromString(cloudName, AzureCloud.class);
}

/**
* Creates a new instance of {@link AzureCloud} without a {@link #toString()} value.
* <p>
* This constructor shouldn't be called as it will produce a {@link AzureCloud} which doesn't have a
* String enum value.
*
* @deprecated Use one of the constants or the {@link #fromString(String)} factory method.
*/
@Deprecated
public AzureCloud() {
}
}

0 comments on commit dbd675b

Please sign in to comment.