Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Assess and upgrade Azure workloads between plans, tiers, or SKUs with automated migration steps
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/languages/java/package-specific/com.microsoft.azure.management.md
1# com.microsoft.azure.management.**23## Code Checklist45- Keep Azure resources, operations, and property values identical. The goal is functional equivalence, not feature expansion.6- Do not change the method sequence when creating or updating an Azure resource unless the new SDK requires it.7- Preserve the existing async pattern. For example, a delayed provisioning pattern that uses `Creatable<Resource>` should not be replaced by a direct `.create()` call. Similarly, when provisioning a resource, do not swap `.withNewDependencyResource` for `.withExistingDependencyResource` unless mandated by the new API surface.8- Keep the text emitted by logging and stdout/stderr unchanged to avoid breaking downstream consumers of those streams.9- Do not replace `resource.region()` with `resource.regionName()`; doing so changes the type from `Region` to `String` and can introduce subtle regressions.1011## Code Samples1213### Authentication with File1415File-based authentication (e.g., `Azure.configure().authenticate(credentialFile)`) is **discouraged** under Azure's security-by-default posture: it relies on long-lived secrets stored on disk, which conflicts with the modern guidance to prefer managed identities, workload identity, or other credential types exposed by `DefaultAzureCredential`.1617#### Detect: legacy file-based authentication patterns1819Treat **any** of the following shapes in the legacy code as file-based authentication that must be replaced (not migrated). Triggers include `AZURE_AUTH_LOCATION`, `.authenticate(File)`, `ApplicationTokenCredentials.fromFile`, or any code path that reads `clientId` / `clientSecret` / `tenant` from disk and feeds them into a credential builder.2021```java22// Shape A: direct File overload23Azure azure = Azure.authenticate(new File(System.getenv("AZURE_AUTH_LOCATION")))24.withDefaultSubscription();2526// Shape B: configure() chain with a File27File credFile = new File(authFilePath);28Azure azure = Azure.configure()29.withLogLevel(LogLevel.BASIC)30.authenticate(credFile)31.withDefaultSubscription();3233// Shape C: ApplicationTokenCredentials.fromFile(...)34ApplicationTokenCredentials creds =35ApplicationTokenCredentials.fromFile(new File(authFile));36Azure azure = Azure.authenticate(creds).withSubscription(subscriptionId);37```3839Do **not** emit a code sample that reproduces any of the above during the upgrade — including a "modernized" variant that parses the same file with Jackson and feeds it into `ClientSecretCredentialBuilder`. Instead, replace the authentication block in the migrated code with a `DefaultAzureCredential` (or another appropriate `TokenCredential`) and prepend a `TODO` comment that explains the change. For example:4041```java42// TODO: The original code authenticated using a credential file (AZURE_AUTH_LOCATION),43// which is discouraged because it relies on long-lived secrets on disk and conflicts44// with Azure's security-by-default guidance. It has been replaced with45// DefaultAzureCredential. This change alters the authentication mechanism, so the46// resulting code path requires extra testing (local dev, CI, and target runtime47// identities) before it is considered production-ready.48TokenCredential credential = new DefaultAzureCredentialBuilder().build();49AzureProfile profile = new AzureProfile(AzureEnvironment.AZURE);50AzureResourceManager azure = AzureResourceManager.configure()51.authenticate(credential, profile)52.withDefaultSubscription();53```5455Keep the `TODO` comment in the migrated source so reviewers and downstream maintainers are aware that the authentication mechanism changed and that the new code path has not been exercised by the original tests.5657### OKHttp Interceptors5859Legacy OKHttp `Interceptor` implementation classes should be migrated to `HttpPipelinePolicy` implementation classes. This is a two-step migration — both steps are required:6061**Step 1: Convert each `Interceptor` subclass to an `HttpPipelinePolicy` subclass.** Rename the class from `XxxInterceptor` to `XxxPolicy` and reimplement its logic against the `HttpPipelinePolicy` interface (i.e. `process(HttpPipelineCallContext, HttpPipelineNextPolicy)`) instead of the OKHttp `Interceptor.intercept(Chain)` API.6263**Step 2: Register every converted policy on the new manager builder via `.withPolicy(new XxxPolicy())`.** Each `withNetworkInterceptor(new XxxInterceptor())` call on the legacy `RestClient.Builder` must have a corresponding `.withPolicy(new XxxPolicy())` call on `AzureResourceManager.configure()` (or the equivalent `XxxManager.configure()`). Preserve the original ordering of the interceptors when registering the policies.6465Do not skip Step 2: converting the class without wiring it into the manager builder silently drops the behavior.66671. Legacy code:68```java69RestClient.Builder builder = new RestClient.Builder()70...71.withNetworkInterceptor(new ResourceGroupTaggingInterceptor())72...;7374Azure.Authenticated azureAuthed = Azure.authenticate(builder.build(), subscriptionId, credentials.domain());75Azure azure = azureAuthed.withSubscription(subscriptionId);76```77782. Migrated code (note: `ResourceGroupTaggingPolicy` is the Step 1 conversion of `ResourceGroupTaggingInterceptor`, and it must be registered via `.withPolicy(...)` in Step 2):79```java80AzureResourceManager azureResourceManager = AzureResourceManager.configure()81.withPolicy(new ResourceGroupTaggingPolicy())82.authenticate(credential, profile)83.withDefaultSubscription();84```8586### ProviderRegistrationInterceptor8788If legacy client(XXManager) initializes with `ProviderRegistrationInterceptor`, check whether this client is one of the premium ones:89- Azure90- AuthorizationManager91- CdnManager92- ComputeManager93- ContainerInstanceManager94- ContainerRegistryManager95- ContainerServiceManager96- CosmosDBManager97- DnsZoneManager98- EventHubManager99- KeyVaultManager100- MonitorManager101- MSIManager102- NetworkManager103- RedisManager104- ResourceManager105- SearchServiceManager106- ServiceBusManager107- SqlServerManager108- StorageManager109- TrafficManager110111If not, add `ProviderRegistrationPolicy` when initializing the client. Otherwise, don't.112113For each legacy client, add along with whether to initialize with `ProviderRegistrationPolicy`, to the generated plan guideline, and migrate accordingly.1141151. Legacy client(not premium client):116```java117BatchManager batchManager = BatchManager.configure()118.withLogLevel(LogLevel.BASIC)119.withInterceptor(new ProviderRegistrationInterceptor(credentials))120.authenticate(credentials, subscriptionId);121```122should be migrated to:123```java124BatchManager batchManager = BatchManager.configure()125.withPolicy(new ProviderRegistrationPolicy())126.withLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BASIC))127.authenticate(credential, profile);128```1291302. Legacy client(premium clients):131```java132Azure azure = Azure.configure()133.withInterceptor(new ProviderRegistrationInterceptor(credentials))134.withLogLevel(LogLevel.BASIC)135.authenticate(credentials)136.withSubscription(subscriptionId);137```138should be migrated to:139```java140AzureResourceManager.configure()141.withLogLevel(HttpLogDetailLevel.BASIC)142.authenticate(credential, profile);143```144145### BatchAccount146147azure-resourcemanager-batch is no longer a premium/handwritten library. In BatchAccount, `withNewStorageAccount` should be replaced by `.withAutoStorage(new AutoStorageBaseProperties().withStorageAccountId(storageAccount.id()))`, while the `storageAccount` needs to be created separately.148149Legacy code:150```java151BatchAccount batchAccount = azure.batchAccounts().define(batchAccountName)152.withRegion(region)153.withNewResourceGroup(rgName)154.defineNewApplication(applicationName)155.defineNewApplicationPackage(applicationPackageName)156.withAllowUpdates(true)157.withDisplayName(applicationDisplayName)158.attach()159.withNewStorageAccount(storageAccountName)160.create();161```162163Migrated:164```java165StorageAccount storageAccount = storageManager.storageAccounts()166.define(storageAccountName)167.withRegion(REGION)168.withExistingResourceGroup(resourceGroup)169.create();170BatchAccount account = batchManager.batchAccounts()171.define(batchAccountName)172.withRegion(REGION)173.withExistingResourceGroup(resourceGroup)174.withAutoStorage(new AutoStorageBaseProperties().withStorageAccountId(storageAccount.id()))175.create();176// create application with batch account177application = batchManager.applications()178.define(applicationName)179.withExistingBatchAccount(resourceGroup, account.name())180.withDisplayName(applicationDisplayName)181.withAllowUpdates(true)182.create();183applicationPackage = batchManager.applicationPackages()184.define(applicationPackageName)185.withExistingApplication(resourceGroup, batchAccountName, applicationName)186.create();187```188