Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions tools/azure-rest-api-specs-examples-automation/java/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,10 @@ def process_java_example(filepath: str) -> List[JavaExample]:
lines = f.readlines()

class_name = filename.split(".")[0]
return process_java_example_content(lines, class_name)
return process_java_example_content(lines, class_name, filepath)


def process_java_example_content(lines: List[str], class_name: str) -> List[JavaExample]:
def process_java_example_content(lines: List[str], class_name: str, filepath: str = None) -> List[JavaExample]:
java_examples = []
if is_aggregated_java_example(lines):
aggregated_java_example = break_down_aggregated_java_example(lines)
Expand All @@ -199,8 +199,20 @@ def process_java_example_content(lines: List[str], class_name: str) -> List[Java
example_dir, example_filename = path.split(example_filepath)

try:
sdk_package_path_updated = sdk_package_path
if filepath and sdk_package_path.endswith("/resourcemanager/azure-resourcemanager"):
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filepath should be validated before extracting the package name. If the filepath is None or doesn't contain enough path segments, this will fail with an unclear IndexError. Consider adding a check to ensure the filepath matches the expected structure.

Copilot uses AI. Check for mistakes.
# special handling for libs included in azure-resourcemanager, as samples in it are copied
# from other packages.
# this behavior can change, if in automation we no longer do such copy.
Comment on lines +204 to +206
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment describes the behavior but doesn't explain when or why this special handling might change. Consider adding more context about the conditions under which this workaround would no longer be needed, or reference a tracking issue/ticket for the automation change.

Suggested change
# special handling for libs included in azure-resourcemanager, as samples in it are copied
# from other packages.
# this behavior can change, if in automation we no longer do such copy.
# Special handling for libs included in azure-resourcemanager, as samples in it are currently
# copied from other resource-manager packages. We remap sdk_package_path to the original
# per-service package so that example lookup works correctly.
# If the automation is updated so that samples are no longer copied into
# azure-resourcemanager (for example, they are generated and validated in-place for each
# azure-resourcemanager-* package), this remapping will no longer be necessary and
# sdk_package_path can be used directly here.

Copilot uses AI. Check for mistakes.
sdk_package_name = filepath.replace("\\", "/").split("/")[-3]
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The path split logic assumes a specific directory structure depth. Using split("/")[-3] is fragile and may fail if the filepath structure changes or has a different depth. Consider using a more robust approach to extract the package name, such as parsing the package declaration from the Java file or using a regex pattern to extract the service name from a known base path.

Copilot uses AI. Check for mistakes.
sdk_package_path_updated = path.join(
sdk_package_path.rstrip("/resourcemanager/azure-resourcemanager"),
Comment on lines +208 to +209
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rstrip operation with a path string is incorrect. The rstrip method removes characters from a set, not a substring. For example, if sdk_package_path is "/path/to/resourcemanager/azure-resourcemanager", this will remove any trailing 'r', 'e', 'g', 'a', 'n', 'a', 'm', 'e', 'c', 'u', 'o', 's', 'e', 'r', '-', 'e', 'r', 'u', 'z', 'a', or '/' characters, not the exact substring. Use removesuffix (Python 3.9+) or string slicing instead.

Suggested change
sdk_package_path_updated = path.join(
sdk_package_path.rstrip("/resourcemanager/azure-resourcemanager"),
suffix = "/resourcemanager/azure-resourcemanager"
base_sdk_package_path = sdk_package_path[: -len(suffix)]
sdk_package_path_updated = path.join(
base_sdk_package_path,

Copilot uses AI. Check for mistakes.
sdk_package_name,
"azure-resourcemanager-" + sdk_package_name,
)

example_dir = examples_dir.try_find_resource_manager_example(
specs_path, sdk_package_path, example_dir, example_filename
specs_path, sdk_package_path_updated, example_dir, example_filename
)
except NameError:
pass
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import sys
import tempfile
import unittest
from os import path
from os import path, makedirs

from main import process_java_example_content
from main import _set_paths
Expand Down Expand Up @@ -329,3 +330,142 @@ def test_process_java_example_original_file_typespec(self):
"specification/mongocluster/resource-manager/Microsoft.DocumentDB/preview/2024-03-01-preview/examples-java",
java_examples[0].target_dir,
)

def test_process_java_example_original_file_typespec_resourcemanager(self):
java_code = """
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) TypeSpec Code Generator.

package com.azure.resourcemanager.keyvault.generated;

/**
* Samples for Secrets List.
*/
public final class SecretsListSamples {
/*
* x-ms-original-file: 2025-05-01/listSecrets.json
*/
/**
* Sample code: List secrets in the vault.
*
* @param azure The entry point for accessing resource management APIs in Azure.
*/
public static void listSecretsInTheVault(com.azure.resourcemanager.AzureResourceManager azure) {
azure.vaults()
.manager()
.serviceClient()
.getSecrets()
.list("sample-group", "sample-vault", null, com.azure.core.util.Context.NONE);
}
}
"""

with create_mock_test_folder_resourcemanager() as tmp_dir_name:
_set_paths(
path.join(tmp_dir_name, "azure-rest-api-specs"),
path.join(tmp_dir_name, "azure-sdk-for-java/sdk/resourcemanager/azure-resourcemanager"),
)
java_examples = process_java_example_content(
java_code.splitlines(keepends=True),
"SecretsListSamples",
path.join(
tmp_dir_name,
"azure-sdk-for-java/sdk/resourcemanager/azure-resourcemanager/src/samples/java/com/azure/resourcemanager/keyvault/generated/SecretsListSamples.java",
),
)

self.assertEqual(1, len(java_examples))

self.assertEqual(
"specification/keyvault/resource-manager/Microsoft.KeyVault/stable/2025-05-01/examples-java",
java_examples[0].target_dir,
)


def create_mock_test_folder_resourcemanager() -> tempfile.TemporaryDirectory:
tmp_path = path.abspath(".")
tmp_dir = tempfile.TemporaryDirectory(dir=tmp_path)
try:
sdk_path = path.join(tmp_dir.name, "azure-sdk-for-java/sdk/keyvault/azure-resourcemanager-keyvault")
makedirs(sdk_path)
with open(path.join(sdk_path, "tsp-location.yaml"), "w+", encoding="utf-8") as file:
file.write(
"""directory: specification/keyvault/KeyVault.Management
commit: 7eb7eaf5d0ebb12a9f0ade8e4433cfb0f6c32840
repo: Azure/azure-rest-api-specs
additionalDirectories:
"""
)

keyvault_json_example_file_content = """{
"parameters": {
"api-version": "2025-05-01",
"resourceGroupName": "sample-group",
"subscriptionId": "00000000-0000-0000-0000-000000000000",
"vaultName": "sample-vault"
},
"responses": {
"200": {
"body": {
"value": [
{
"name": "secret-name",
"type": "Microsoft.KeyVault/vaults/secrets",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/sample-group/providers/Microsoft.KeyVault/vaults/sample-vault/secrets/secret-name",
"location": "westus",
"properties": {
"attributes": {
"created": 1514941476,
"enabled": true,
"updated": 1514941476
},
"secretUri": "https://sample-vault.vault.azure.net/secrets/secret-name",
"secretUriWithVersion": "https://sample-vault.vault.azure.net/secrets/secret-name/40af42fbc10047f8a756a73211492f56"
}
},
{
"name": "secret-name2",
"type": "Microsoft.KeyVault/vaults/secrets",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/sample-group/providers/Microsoft.KeyVault/vaults/sample-vault/secrets/secret-name2",
"location": "westus",
"properties": {
"attributes": {
"created": 1514941476,
"enabled": true,
"updated": 1514941476
},
"secretUri": "https://sample-vault.vault.azure.net/secrets/secret-name2",
"secretUriWithVersion": "https://sample-vault.vault.azure.net/secrets/secret-name2/cd7264a6f56c44d1b594423c80609aae"
}
}
]
}
}
},
"operationId": "Secrets_List",
"title": "List secrets in the vault"
}
"""

# api-version 2025-05-01
specs_path = path.join(
tmp_dir.name,
"azure-rest-api-specs/specification/keyvault/KeyVault.Management/examples/2025-05-01",
)
makedirs(specs_path)
with open(path.join(specs_path, "listSecrets.json"), "w+", encoding="utf-8") as file:
file.write(keyvault_json_example_file_content)

specs_path = path.join(
tmp_dir.name,
"azure-rest-api-specs/specification/keyvault/resource-manager/Microsoft.KeyVault/stable/2025-05-01/examples",
)
makedirs(specs_path)
with open(path.join(specs_path, "listSecrets.json"), "w+", encoding="utf-8") as file:
file.write(keyvault_json_example_file_content)
except Exception as error:
tmp_dir.cleanup()
raise error

return tmp_dir