GitHub Copilot ChatGPT Claude Codex CLI Cursor opencode Skill Text

azure-compute-batch-java

Azure Batch SDK for Java. Run large-scale parallel and HPC batch jobs with pools, jobs, tasks, and compute nodes. Triggers: "BatchClient java", "azure batch java", "batch pool java", "batch job java", "HPC java", "parallel computing java".

Ciza · 0 points · 20 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-compute-batch-java-e58528d.zip · 10 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-compute-batch-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 Batch SDK for Java

Client library for running large-scale parallel and high-performance computing (HPC) batch jobs in Azure.

Installation

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-compute-batch</artifactId>
    <version>1.0.0-beta.5</version>
</dependency>

Prerequisites

  • Azure Batch account
  • Pool configured with compute nodes
  • Azure subscription

Environment Variables

AZURE_BATCH_ENDPOINT=https://<account>.<region>.batch.azure.com  # Required for all auth methods
AZURE_BATCH_ACCOUNT=<account-name>  # Only required for shared key auth
AZURE_BATCH_ACCESS_KEY=<account-key>  # Only required for shared key auth
AZURE_TOKEN_CREDENTIALS=prod  # Required only if DefaultAzureCredential is used in production

Client Creation

With Microsoft Entra ID (Recommended)

import com.azure.compute.batch.BatchClient;
import com.azure.compute.batch.BatchClientBuilder;
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();

BatchClient batchClient = new BatchClientBuilder()
    .credential(credential)
    .endpoint(System.getenv("AZURE_BATCH_ENDPOINT"))
    .buildClient();

Async Client

import com.azure.compute.batch.BatchAsyncClient;

BatchAsyncClient batchAsyncClient = new BatchClientBuilder()
    .credential(credential)
    .endpoint(System.getenv("AZURE_BATCH_ENDPOINT"))
    .buildAsyncClient();

With Shared Key Credentials

import com.azure.core.credential.AzureNamedKeyCredential;

String accountName = System.getenv("AZURE_BATCH_ACCOUNT");
String accountKey = System.getenv("AZURE_BATCH_ACCESS_KEY");
AzureNamedKeyCredential sharedKeyCreds = new AzureNamedKeyCredential(accountName, accountKey);

BatchClient batchClient = new BatchClientBuilder()
    .credential(sharedKeyCreds)
    .endpoint(System.getenv("AZURE_BATCH_ENDPOINT"))
    .buildClient();

Key Concepts

Concept Description
Pool Collection of compute nodes that run tasks
Job Logical grouping of tasks
Task Unit of computation (command/script)
Node VM that executes tasks
Job Schedule Recurring job creation

Pool Operations

Create Pool

import com.azure.compute.batch.models.*;

batchClient.createPool(new BatchPoolCreateParameters("myPoolId", "STANDARD_DC2s_V2")
    .setVirtualMachineConfiguration(
        new VirtualMachineConfiguration(
            new BatchVmImageReference()
                .setPublisher("Canonical")
                .setOffer("UbuntuServer")
                .setSku("22_04-lts")
                .setVersion("latest"),
            "batch.node.ubuntu 22.04"))
    .setTargetDedicatedNodes(2)
    .setTargetLowPriorityNodes(0), null);

Get Pool

BatchPool pool = batchClient.getPool("myPoolId");
System.out.println("Pool state: " + pool.getState());
System.out.println("Current dedicated nodes: " + pool.getCurrentDedicatedNodes());

List Pools

import com.azure.core.http.rest.PagedIterable;

PagedIterable<BatchPool> pools = batchClient.listPools();
for (BatchPool pool : pools) {
    System.out.println("Pool: " + pool.getId() + ", State: " + pool.getState());
}

Resize Pool

import com.azure.core.util.polling.SyncPoller;

BatchPoolResizeParameters resizeParams = new BatchPoolResizeParameters()
    .setTargetDedicatedNodes(4)
    .setTargetLowPriorityNodes(2);

SyncPoller<BatchPool, BatchPool> poller = batchClient.beginResizePool("myPoolId", resizeParams);
poller.waitForCompletion();
BatchPool resizedPool = poller.getFinalResult();

Enable AutoScale

BatchPoolEnableAutoScaleParameters autoScaleParams = new BatchPoolEnableAutoScaleParameters()
    .setAutoScaleEvaluationInterval(Duration.ofMinutes(5))
    .setAutoScaleFormula("$TargetDedicatedNodes = min(10, $PendingTasks.GetSample(TimeInterval_Minute * 5));");

batchClient.enablePoolAutoScale("myPoolId", autoScaleParams);

Delete Pool

SyncPoller<BatchPool, Void> deletePoller = batchClient.beginDeletePool("myPoolId");
deletePoller.waitForCompletion();

Job Operations

Create Job

batchClient.createJob(
    new BatchJobCreateParameters("myJobId", new BatchPoolInfo().setPoolId("myPoolId"))
        .setPriority(100)
        .setConstraints(new BatchJobConstraints()
            .setMaxWallClockTime(Duration.ofHours(24))
            .setMaxTaskRetryCount(3)),
    null);

Get Job

BatchJob job = batchClient.getJob("myJobId", null, null);
System.out.println("Job state: " + job.getState());

List Jobs

PagedIterable<BatchJob> jobs = batchClient.listJobs(new BatchJobsListOptions());
for (BatchJob job : jobs) {
    System.out.println("Job: " + job.getId() + ", State: " + job.getState());
}

Get Task Counts

BatchTaskCountsResult counts = batchClient.getJobTaskCounts("myJobId");
System.out.println("Active: " + counts.getTaskCounts().getActive());
System.out.println("Running: " + counts.getTaskCounts().getRunning());
System.out.println("Completed: " + counts.getTaskCounts().getCompleted());

Terminate Job

BatchJobTerminateParameters terminateParams = new BatchJobTerminateParameters()
    .setTerminationReason("Manual termination");
BatchJobTerminateOptions options = new BatchJobTerminateOptions().setParameters(terminateParams);

SyncPoller<BatchJob, BatchJob> poller = batchClient.beginTerminateJob("myJobId", options, null);
poller.waitForCompletion();

Delete Job

SyncPoller<BatchJob, Void> deletePoller = batchClient.beginDeleteJob("myJobId");
deletePoller.waitForCompletion();

Task Operations

Create Single Task

BatchTaskCreateParameters task = new BatchTaskCreateParameters("task1", "echo 'Hello World'");
batchClient.createTask("myJobId", task);

Create Task with Exit Conditions

batchClient.createTask("myJobId", new BatchTaskCreateParameters("task2", "cmd /c exit 3")
    .setExitConditions(new ExitConditions()
        .setExitCodeRanges(Arrays.asList(
            new ExitCodeRangeMapping(2, 4, 
                new ExitOptions().setJobAction(BatchJobActionKind.TERMINATE)))))
    .setUserIdentity(new UserIdentity()
        .setAutoUser(new AutoUserSpecification()
            .setScope(AutoUserScope.TASK)
            .setElevationLevel(ElevationLevel.NON_ADMIN))),
    null);

Create Task Collection (up to 100)

List<BatchTaskCreateParameters> taskList = Arrays.asList(
    new BatchTaskCreateParameters("task1", "echo Task 1"),
    new BatchTaskCreateParameters("task2", "echo Task 2"),
    new BatchTaskCreateParameters("task3", "echo Task 3")
);
BatchTaskGroup taskGroup = new BatchTaskGroup(taskList);
BatchCreateTaskCollectionResult result = batchClient.createTaskCollection("myJobId", taskGroup);

Create Many Tasks (no limit)

List<BatchTaskCreateParameters> tasks = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
    tasks.add(new BatchTaskCreateParameters("task" + i, "echo Task " + i));
}
batchClient.createTasks("myJobId", tasks);

Get Task

BatchTask task = batchClient.getTask("myJobId", "task1");
System.out.println("Task state: " + task.getState());
System.out.println("Exit code: " + task.getExecutionInfo().getExitCode());

List Tasks

PagedIterable<BatchTask> tasks = batchClient.listTasks("myJobId");
for (BatchTask task : tasks) {
    System.out.println("Task: " + task.getId() + ", State: " + task.getState());
}

Get Task Output

import com.azure.core.util.BinaryData;
import java.nio.charset.StandardCharsets;

BinaryData stdout = batchClient.getTaskFile("myJobId", "task1", "stdout.txt");
System.out.println(new String(stdout.toBytes(), StandardCharsets.UTF_8));

Terminate Task

batchClient.terminateTask("myJobId", "task1", null, null);

Node Operations

List Nodes

PagedIterable<BatchNode> nodes = batchClient.listNodes("myPoolId", new BatchNodesListOptions());
for (BatchNode node : nodes) {
    System.out.println("Node: " + node.getId() + ", State: " + node.getState());
}

Reboot Node

SyncPoller<BatchNode, BatchNode> rebootPoller = batchClient.beginRebootNode("myPoolId", "nodeId");
rebootPoller.waitForCompletion();

Get Remote Login Settings

BatchNodeRemoteLoginSettings settings = batchClient.getNodeRemoteLoginSettings("myPoolId", "nodeId");
System.out.println("IP: " + settings.getRemoteLoginIpAddress());
System.out.println("Port: " + settings.getRemoteLoginPort());

Job Schedule Operations

Create Job Schedule

batchClient.createJobSchedule(new BatchJobScheduleCreateParameters("myScheduleId",
    new BatchJobScheduleConfiguration()
        .setRecurrenceInterval(Duration.ofHours(6))
        .setDoNotRunUntil(OffsetDateTime.now().plusDays(1)),
    new BatchJobSpecification(new BatchPoolInfo().setPoolId("myPoolId"))
        .setPriority(50)),
    null);

Get Job Schedule

BatchJobSchedule schedule = batchClient.getJobSchedule("myScheduleId");
System.out.println("Schedule state: " + schedule.getState());

Error Handling

import com.azure.compute.batch.models.BatchErrorException;
import com.azure.compute.batch.models.BatchError;

try {
    batchClient.getPool("nonexistent-pool");
} catch (BatchErrorException e) {
    BatchError error = e.getValue();
    System.err.println("Error code: " + error.getCode());
    System.err.println("Message: " + error.getMessage().getValue());
    
    if ("PoolNotFound".equals(error.getCode())) {
        System.err.println("The specified pool does not exist.");
    }
}

Best Practices

  1. Use Entra ID — Preferred over shared key for authentication
  2. Use management SDK for pools — azure-resourcemanager-batch supports managed identities
  3. Batch task creation — Use createTaskCollection or createTasks for multiple tasks
  4. Handle LRO properly — Pool resize, delete operations are long-running
  5. Monitor task counts — Use getJobTaskCounts to track progress
  6. Set constraints — Configure maxWallClockTime and maxTaskRetryCount
  7. Use low-priority nodes — Cost savings for fault-tolerant workloads
  8. Enable autoscale — Dynamically adjust pool size based on workload

Reference Links

Resource URL
Maven Package https://central.sonatype.com/artifact/com.azure/azure-compute-batch
GitHub https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/batch/azure-compute-batch
API Documentation https://learn.microsoft.com/java/api/com.azure.compute.batch
Product Docs https://learn.microsoft.com/azure/batch/
REST API https://learn.microsoft.com/rest/api/batchservice/
Samples https://github.com/azure/azure-batch-samples
Files (skills)
  • references
    • examples.md 28.6 KB
      # Azure Batch Java SDK - Examples
      
      Comprehensive code examples for the Azure Batch SDK for Java.
      
      ## Table of Contents
      
      - [Maven Dependency](#maven-dependency)
      - [Client Creation](#client-creation)
      - [Pool Operations](#pool-operations)
      - [Job Operations](#job-operations)
      - [Task Operations](#task-operations)
      - [Node Operations](#node-operations)
      - [Job Schedule Operations](#job-schedule-operations)
      - [Error Handling](#error-handling)
      - [Complete Application Example](#complete-application-example)
      
      ## Maven Dependency
      
      ```xml
      <dependency>
          <groupId>com.azure</groupId>
          <artifactId>azure-compute-batch</artifactId>
          <version>1.0.0-beta.5</version>
      </dependency>
      
      <!-- For DefaultAzureCredential -->
      <dependency>
          <groupId>com.azure</groupId>
          <artifactId>azure-identity</artifactId>
          <version>1.14.2</version>
      </dependency>
      ```
      
      ## Client Creation
      
      ### With Microsoft Entra ID (Recommended)
      
      ```java
      import com.azure.compute.batch.BatchClient;
      import com.azure.compute.batch.BatchClientBuilder;
      import com.azure.identity.DefaultAzureCredentialBuilder;
      
      String endpoint = System.getenv("AZURE_BATCH_ENDPOINT");
      
      BatchClient batchClient = new BatchClientBuilder()
          .credential(new DefaultAzureCredentialBuilder().build())
          .endpoint(endpoint)
          .buildClient();
      ```
      
      ### Async Client
      
      ```java
      import com.azure.compute.batch.BatchAsyncClient;
      
      BatchAsyncClient batchAsyncClient = new BatchClientBuilder()
          .credential(new DefaultAzureCredentialBuilder().build())
          .endpoint(endpoint)
          .buildAsyncClient();
      ```
      
      ### With Shared Key Credentials
      
      ```java
      import com.azure.core.credential.AzureNamedKeyCredential;
      
      String accountName = System.getenv("AZURE_BATCH_ACCOUNT");
      String accountKey = System.getenv("AZURE_BATCH_ACCESS_KEY");
      
      AzureNamedKeyCredential sharedKeyCreds = new AzureNamedKeyCredential(accountName, accountKey);
      
      BatchClient batchClient = new BatchClientBuilder()
          .credential(sharedKeyCreds)
          .endpoint(endpoint)
          .buildClient();
      ```
      
      ## Pool Operations
      
      ### Create Pool
      
      ```java
      import com.azure.compute.batch.models.*;
      
      batchClient.createPool(new BatchPoolCreateParameters("myPoolId", "STANDARD_DC2s_v2")
          .setVirtualMachineConfiguration(
              new VirtualMachineConfiguration(
                  new BatchVmImageReference()
                      .setPublisher("Canonical")
                      .setOffer("UbuntuServer")
                      .setSku("22_04-lts")
                      .setVersion("latest"),
                  "batch.node.ubuntu 22.04"))
          .setTargetDedicatedNodes(2)
          .setTargetLowPriorityNodes(0)
          .setTaskSlotsPerNode(4)
          .setTaskSchedulingPolicy(new TaskSchedulingPolicy(ComputeNodeFillType.SPREAD)), null);
      
      System.out.println("Pool created: myPoolId");
      ```
      
      ### Create Pool with Start Task
      
      ```java
      batchClient.createPool(new BatchPoolCreateParameters("myPoolWithStartTask", "STANDARD_D2s_v3")
          .setVirtualMachineConfiguration(
              new VirtualMachineConfiguration(
                  new BatchVmImageReference()
                      .setPublisher("Canonical")
                      .setOffer("0001-com-ubuntu-server-jammy")
                      .setSku("22_04-lts")
                      .setVersion("latest"),
                  "batch.node.ubuntu 22.04"))
          .setTargetDedicatedNodes(2)
          .setStartTask(new StartTask("apt-get update && apt-get install -y python3")
              .setUserIdentity(new UserIdentity()
                  .setAutoUser(new AutoUserSpecification()
                      .setScope(AutoUserScope.POOL)
                      .setElevationLevel(ElevationLevel.ADMIN)))
              .setMaxTaskRetryCount(2)
              .setWaitForSuccess(true)), null);
      ```
      
      ### Create Pool with Application Packages
      
      ```java
      import java.util.Arrays;
      
      batchClient.createPool(new BatchPoolCreateParameters("appPackagePool", "STANDARD_D2s_v3")
          .setVirtualMachineConfiguration(
              new VirtualMachineConfiguration(
                  new BatchVmImageReference()
                      .setPublisher("MicrosoftWindowsServer")
                      .setOffer("WindowsServer")
                      .setSku("2022-datacenter")
                      .setVersion("latest"),
                  "batch.node.windows amd64"))
          .setTargetDedicatedNodes(2)
          .setApplicationPackageReferences(Arrays.asList(
              new ApplicationPackageReference("myApp").setVersion("1.0"),
              new ApplicationPackageReference("myDependency").setVersion("2.0"))), null);
      ```
      
      ### Get Pool
      
      ```java
      BatchPool pool = batchClient.getPool("myPoolId");
      
      System.out.println("=== Pool Details ===");
      System.out.println("Pool ID: " + pool.getId());
      System.out.println("State: " + pool.getState());
      System.out.println("Allocation State: " + pool.getAllocationState());
      System.out.println("VM Size: " + pool.getVmSize());
      System.out.println("Current Dedicated Nodes: " + pool.getCurrentDedicatedNodes());
      System.out.println("Current Low Priority Nodes: " + pool.getCurrentLowPriorityNodes());
      System.out.println("Target Dedicated Nodes: " + pool.getTargetDedicatedNodes());
      ```
      
      ### List Pools
      
      ```java
      import com.azure.core.http.rest.PagedIterable;
      
      PagedIterable<BatchPool> pools = batchClient.listPools();
      
      System.out.println("=== Available Pools ===");
      for (BatchPool p : pools) {
          System.out.printf("Pool: %s, State: %s, Nodes: %d/%d%n",
              p.getId(),
              p.getState(),
              p.getCurrentDedicatedNodes(),
              p.getTargetDedicatedNodes());
      }
      ```
      
      ### Resize Pool
      
      ```java
      import com.azure.core.util.polling.SyncPoller;
      import java.time.Duration;
      
      BatchPoolResizeParameters resizeParams = new BatchPoolResizeParameters()
          .setTargetDedicatedNodes(4)
          .setTargetLowPriorityNodes(2)
          .setResizeTimeout(Duration.ofMinutes(15))
          .setNodeDeallocationOption(BatchNodeDeallocationOption.TASK_COMPLETION);
      
      SyncPoller<BatchPool, BatchPool> poller = batchClient.beginResizePool("myPoolId", resizeParams);
      poller.waitForCompletion();
      
      BatchPool resizedPool = poller.getFinalResult();
      System.out.println("Pool resized. New target: " + resizedPool.getTargetDedicatedNodes());
      ```
      
      ### Enable AutoScale
      
      ```java
      String autoScaleFormula = """
          // Target 1 dedicated node per 5 pending tasks
          pendingTasks = $PendingTasks.GetSample(TimeInterval_Minute * 5);
          $TargetDedicatedNodes = min(10, max(1, pendingTasks / 5));
          $TargetLowPriorityNodes = 0;
          """;
      
      BatchPoolEnableAutoScaleParameters autoScaleParams = new BatchPoolEnableAutoScaleParameters()
          .setAutoScaleEvaluationInterval(Duration.ofMinutes(5))
          .setAutoScaleFormula(autoScaleFormula);
      
      batchClient.enablePoolAutoScale("myPoolId", autoScaleParams);
      System.out.println("AutoScale enabled");
      ```
      
      ### Disable AutoScale
      
      ```java
      batchClient.disablePoolAutoScale("myPoolId");
      System.out.println("AutoScale disabled");
      ```
      
      ### Delete Pool
      
      ```java
      SyncPoller<BatchPool, Void> deletePoller = batchClient.beginDeletePool("myPoolId");
      deletePoller.waitForCompletion();
      System.out.println("Pool deleted");
      ```
      
      ## Job Operations
      
      ### Create Job
      
      ```java
      batchClient.createJob(
          new BatchJobCreateParameters("myJobId", new BatchPoolInfo().setPoolId("myPoolId"))
              .setDisplayName("My Batch Job")
              .setPriority(100)
              .setConstraints(new BatchJobConstraints()
                  .setMaxWallClockTime(Duration.ofHours(24))
                  .setMaxTaskRetryCount(3))
              .setOnAllTasksComplete(OnAllBatchTasksComplete.TERMINATE_JOB)
              .setOnTaskFailure(OnBatchTaskFailure.NO_ACTION),
          null);
      
      System.out.println("Job created: myJobId");
      ```
      
      ### Create Job with Job Manager Task
      
      ```java
      batchClient.createJob(
          new BatchJobCreateParameters("managedJobId", new BatchPoolInfo().setPoolId("myPoolId"))
              .setJobManagerTask(new BatchJobManagerTask("manager", "python3 manage_tasks.py")
                  .setDisplayName("Job Manager")
                  .setKillJobOnCompletion(true)
                  .setRunExclusive(true)),
          null);
      ```
      
      ### Get Job
      
      ```java
      BatchJob job = batchClient.getJob("myJobId", null, null);
      
      System.out.println("=== Job Details ===");
      System.out.println("Job ID: " + job.getId());
      System.out.println("State: " + job.getState());
      System.out.println("Priority: " + job.getPriority());
      System.out.println("Pool: " + job.getPoolInfo().getPoolId());
      System.out.println("Created: " + job.getCreationTime());
      ```
      
      ### List Jobs
      
      ```java
      PagedIterable<BatchJob> jobs = batchClient.listJobs(new BatchJobsListOptions());
      
      System.out.println("=== Active Jobs ===");
      for (BatchJob j : jobs) {
          System.out.printf("Job: %s, State: %s, Pool: %s%n",
              j.getId(),
              j.getState(),
              j.getPoolInfo().getPoolId());
      }
      ```
      
      ### Get Task Counts
      
      ```java
      BatchTaskCountsResult counts = batchClient.getJobTaskCounts("myJobId");
      
      System.out.println("=== Task Counts ===");
      System.out.println("Active: " + counts.getTaskCounts().getActive());
      System.out.println("Running: " + counts.getTaskCounts().getRunning());
      System.out.println("Completed: " + counts.getTaskCounts().getCompleted());
      System.out.println("Succeeded: " + counts.getTaskCounts().getSucceeded());
      System.out.println("Failed: " + counts.getTaskCounts().getFailed());
      ```
      
      ### Update Job
      
      ```java
      BatchJobUpdateParameters updateParams = new BatchJobUpdateParameters()
          .setPriority(200)
          .setConstraints(new BatchJobConstraints()
              .setMaxWallClockTime(Duration.ofHours(48)));
      
      batchClient.updateJob("myJobId", updateParams);
      System.out.println("Job updated");
      ```
      
      ### Terminate Job
      
      ```java
      BatchJobTerminateParameters terminateParams = new BatchJobTerminateParameters()
          .setTerminationReason("Manual termination - job complete");
      BatchJobTerminateOptions options = new BatchJobTerminateOptions().setParameters(terminateParams);
      
      SyncPoller<BatchJob, BatchJob> poller = batchClient.beginTerminateJob("myJobId", options, null);
      poller.waitForCompletion();
      System.out.println("Job terminated");
      ```
      
      ### Delete Job
      
      ```java
      SyncPoller<BatchJob, Void> deletePoller = batchClient.beginDeleteJob("myJobId");
      deletePoller.waitForCompletion();
      System.out.println("Job deleted");
      ```
      
      ## Task Operations
      
      ### Create Single Task
      
      ```java
      BatchTaskCreateParameters task = new BatchTaskCreateParameters("task1", "echo 'Hello World'");
      batchClient.createTask("myJobId", task);
      System.out.println("Task created: task1");
      ```
      
      ### Create Task with Resource Files
      
      ```java
      import java.util.Arrays;
      
      BatchTaskCreateParameters task = new BatchTaskCreateParameters("processDataTask", 
          "python3 process.py input.csv output.csv")
          .setResourceFiles(Arrays.asList(
              new ResourceFile()
                  .setHttpUrl("https://storage.blob.core.windows.net/container/process.py?sasToken")
                  .setFilePath("process.py"),
              new ResourceFile()
                  .setHttpUrl("https://storage.blob.core.windows.net/container/input.csv?sasToken")
                  .setFilePath("input.csv")))
          .setOutputFiles(Arrays.asList(
              new OutputFile("output.csv")
                  .setDestination(new OutputFileDestination()
                      .setContainer(new OutputFileBlobContainerDestination(
                          "https://storage.blob.core.windows.net/results?sasToken")
                          .setPath("results/output.csv")))
                  .setUploadOptions(new OutputFileUploadOptions()
                      .setUploadCondition(OutputFileUploadCondition.TASK_SUCCESS))));
      
      batchClient.createTask("myJobId", task);
      ```
      
      ### Create Task with Exit Conditions
      
      ```java
      BatchTaskCreateParameters task = new BatchTaskCreateParameters("conditionalTask", "cmd /c exit 3")
          .setExitConditions(new ExitConditions()
              .setExitCodeRanges(Arrays.asList(
                  new ExitCodeRangeMapping(0, 0,
                      new ExitOptions().setJobAction(BatchJobActionKind.NONE)),
                  new ExitCodeRangeMapping(1, 5,
                      new ExitOptions().setJobAction(BatchJobActionKind.TERMINATE)),
                  new ExitCodeRangeMapping(6, 10,
                      new ExitOptions().setDependencyAction(DependencyActionKind.BLOCK))))
              .setDefault(new ExitOptions()
                  .setJobAction(BatchJobActionKind.NONE)));
      
      batchClient.createTask("myJobId", task);
      ```
      
      ### Create Task with User Identity
      
      ```java
      BatchTaskCreateParameters task = new BatchTaskCreateParameters("adminTask", "sudo apt-get update")
          .setUserIdentity(new UserIdentity()
              .setAutoUser(new AutoUserSpecification()
                  .setScope(AutoUserScope.TASK)
                  .setElevationLevel(ElevationLevel.ADMIN)));
      
      batchClient.createTask("myJobId", task);
      ```
      
      ### Create Task Collection (up to 100)
      
      ```java
      List<BatchTaskCreateParameters> taskList = Arrays.asList(
          new BatchTaskCreateParameters("task1", "echo Task 1"),
          new BatchTaskCreateParameters("task2", "echo Task 2"),
          new BatchTaskCreateParameters("task3", "echo Task 3"),
          new BatchTaskCreateParameters("task4", "echo Task 4"),
          new BatchTaskCreateParameters("task5", "echo Task 5")
      );
      
      BatchTaskGroup taskGroup = new BatchTaskGroup(taskList);
      BatchCreateTaskCollectionResult result = batchClient.createTaskCollection("myJobId", taskGroup);
      
      System.out.printf("Created %d tasks%n", result.getValue().size());
      ```
      
      ### Create Many Tasks (no limit)
      
      ```java
      import java.util.ArrayList;
      
      List<BatchTaskCreateParameters> tasks = new ArrayList<>();
      for (int i = 0; i < 1000; i++) {
          tasks.add(new BatchTaskCreateParameters("task" + i, 
              String.format("python3 process.py --partition %d", i)));
      }
      
      batchClient.createTasks("myJobId", tasks);
      System.out.printf("Created %d tasks%n", tasks.size());
      ```
      
      ### Create Task with Dependencies
      
      ```java
      // First, create prerequisite tasks
      batchClient.createTask("myJobId", new BatchTaskCreateParameters("setup", "setup.sh"));
      batchClient.createTask("myJobId", new BatchTaskCreateParameters("download", "download.sh"));
      
      // Create dependent task
      BatchTaskCreateParameters dependentTask = new BatchTaskCreateParameters("process", "process.sh")
          .setDependsOn(new BatchTaskDependencies()
              .setTaskIds(Arrays.asList("setup", "download")));
      
      batchClient.createTask("myJobId", dependentTask);
      ```
      
      ### Get Task
      
      ```java
      BatchTask task = batchClient.getTask("myJobId", "task1");
      
      System.out.println("=== Task Details ===");
      System.out.println("Task ID: " + task.getId());
      System.out.println("State: " + task.getState());
      System.out.println("Command: " + task.getCommandLine());
      
      if (task.getExecutionInfo() != null) {
          System.out.println("Exit Code: " + task.getExecutionInfo().getExitCode());
          System.out.println("Start Time: " + task.getExecutionInfo().getStartTime());
          System.out.println("End Time: " + task.getExecutionInfo().getEndTime());
          
          if (task.getExecutionInfo().getFailureInfo() != null) {
              System.out.println("Failure: " + task.getExecutionInfo().getFailureInfo().getMessage());
          }
      }
      ```
      
      ### List Tasks
      
      ```java
      PagedIterable<BatchTask> tasks = batchClient.listTasks("myJobId");
      
      System.out.println("=== Tasks ===");
      for (BatchTask t : tasks) {
          System.out.printf("Task: %s, State: %s%n", t.getId(), t.getState());
      }
      ```
      
      ### Get Task Output
      
      ```java
      import com.azure.core.util.BinaryData;
      import java.nio.charset.StandardCharsets;
      
      // Get stdout
      BinaryData stdout = batchClient.getTaskFile("myJobId", "task1", "stdout.txt");
      System.out.println("=== stdout ===");
      System.out.println(new String(stdout.toBytes(), StandardCharsets.UTF_8));
      
      // Get stderr
      BinaryData stderr = batchClient.getTaskFile("myJobId", "task1", "stderr.txt");
      System.out.println("=== stderr ===");
      System.out.println(new String(stderr.toBytes(), StandardCharsets.UTF_8));
      ```
      
      ### List Task Files
      
      ```java
      PagedIterable<BatchNodeFile> files = batchClient.listTaskFiles("myJobId", "task1");
      
      System.out.println("=== Task Files ===");
      for (BatchNodeFile file : files) {
          System.out.printf("File: %s, Size: %d bytes%n",
              file.getName(),
              file.getProperties().getContentLength());
      }
      ```
      
      ### Terminate Task
      
      ```java
      batchClient.terminateTask("myJobId", "task1", null, null);
      System.out.println("Task terminated");
      ```
      
      ### Delete Task
      
      ```java
      batchClient.deleteTask("myJobId", "task1");
      System.out.println("Task deleted");
      ```
      
      ## Node Operations
      
      ### List Nodes
      
      ```java
      PagedIterable<BatchNode> nodes = batchClient.listNodes("myPoolId", new BatchNodesListOptions());
      
      System.out.println("=== Compute Nodes ===");
      for (BatchNode node : nodes) {
          System.out.printf("Node: %s, State: %s, IP: %s%n",
              node.getId(),
              node.getState(),
              node.getIpAddress());
      }
      ```
      
      ### Get Node
      
      ```java
      BatchNode node = batchClient.getNode("myPoolId", "nodeId");
      
      System.out.println("=== Node Details ===");
      System.out.println("Node ID: " + node.getId());
      System.out.println("State: " + node.getState());
      System.out.println("IP Address: " + node.getIpAddress());
      System.out.println("VM Size: " + node.getVmSize());
      System.out.println("Total Tasks Run: " + node.getTotalTasksRun());
      System.out.println("Running Tasks: " + node.getRunningTasksCount());
      ```
      
      ### Reboot Node
      
      ```java
      BatchNodeRebootParameters rebootParams = new BatchNodeRebootParameters()
          .setNodeRebootOption(BatchNodeRebootOption.TASK_COMPLETION);
      
      SyncPoller<BatchNode, BatchNode> rebootPoller = 
          batchClient.beginRebootNode("myPoolId", "nodeId", rebootParams);
      rebootPoller.waitForCompletion();
      System.out.println("Node rebooted");
      ```
      
      ### Get Remote Login Settings
      
      ```java
      BatchNodeRemoteLoginSettings settings = batchClient.getNodeRemoteLoginSettings("myPoolId", "nodeId");
      
      System.out.println("=== Remote Login Settings ===");
      System.out.println("IP Address: " + settings.getRemoteLoginIpAddress());
      System.out.println("Port: " + settings.getRemoteLoginPort());
      
      // SSH command
      System.out.printf("SSH: ssh -p %d user@%s%n",
          settings.getRemoteLoginPort(),
          settings.getRemoteLoginIpAddress());
      ```
      
      ### Remove Node from Pool
      
      ```java
      BatchNodeRemoveParameters removeParams = new BatchNodeRemoveParameters(
          Arrays.asList("nodeId1", "nodeId2"))
          .setNodeDeallocationOption(BatchNodeDeallocationOption.TASK_COMPLETION)
          .setResizeTimeout(Duration.ofMinutes(15));
      
      batchClient.removeNodes("myPoolId", removeParams);
      System.out.println("Nodes removal initiated");
      ```
      
      ## Job Schedule Operations
      
      ### Create Job Schedule
      
      ```java
      import java.time.OffsetDateTime;
      
      batchClient.createJobSchedule(new BatchJobScheduleCreateParameters("dailySchedule",
          new BatchJobScheduleConfiguration()
              .setRecurrenceInterval(Duration.ofHours(24))
              .setDoNotRunUntil(OffsetDateTime.now().plusHours(1))
              .setDoNotRunAfter(OffsetDateTime.now().plusDays(30)),
          new BatchJobSpecification(new BatchPoolInfo().setPoolId("myPoolId"))
              .setDisplayName("Daily Processing Job")
              .setPriority(100)
              .setConstraints(new BatchJobConstraints()
                  .setMaxTaskRetryCount(3))),
          null);
      
      System.out.println("Job schedule created: dailySchedule");
      ```
      
      ### Get Job Schedule
      
      ```java
      BatchJobSchedule schedule = batchClient.getJobSchedule("dailySchedule");
      
      System.out.println("=== Job Schedule Details ===");
      System.out.println("Schedule ID: " + schedule.getId());
      System.out.println("State: " + schedule.getState());
      System.out.println("Next Run: " + schedule.getExecutionInfo().getNextRunTime());
      System.out.println("Recent Jobs: " + schedule.getExecutionInfo().getRecentJob());
      ```
      
      ### List Job Schedules
      
      ```java
      PagedIterable<BatchJobSchedule> schedules = batchClient.listJobSchedules();
      
      System.out.println("=== Job Schedules ===");
      for (BatchJobSchedule s : schedules) {
          System.out.printf("Schedule: %s, State: %s%n", s.getId(), s.getState());
      }
      ```
      
      ### Disable Job Schedule
      
      ```java
      batchClient.disableJobSchedule("dailySchedule");
      System.out.println("Job schedule disabled");
      ```
      
      ### Enable Job Schedule
      
      ```java
      batchClient.enableJobSchedule("dailySchedule");
      System.out.println("Job schedule enabled");
      ```
      
      ### Terminate Job Schedule
      
      ```java
      batchClient.terminateJobSchedule("dailySchedule");
      System.out.println("Job schedule terminated");
      ```
      
      ### Delete Job Schedule
      
      ```java
      batchClient.deleteJobSchedule("dailySchedule");
      System.out.println("Job schedule deleted");
      ```
      
      ## Error Handling
      
      ```java
      import com.azure.compute.batch.models.BatchErrorException;
      import com.azure.compute.batch.models.BatchError;
      
      try {
          BatchPool pool = batchClient.getPool("nonexistent-pool");
      } catch (BatchErrorException e) {
          BatchError error = e.getValue();
          
          System.err.println("=== Batch Error ===");
          System.err.println("Error code: " + error.getCode());
          System.err.println("Message: " + error.getMessage().getValue());
          
          // Handle specific errors
          switch (error.getCode()) {
              case "PoolNotFound":
                  System.err.println("The specified pool does not exist.");
                  break;
              case "JobNotFound":
                  System.err.println("The specified job does not exist.");
                  break;
              case "TaskNotFound":
                  System.err.println("The specified task does not exist.");
                  break;
              case "PoolQuotaReached":
                  System.err.println("Pool quota exceeded. Delete unused pools or request quota increase.");
                  break;
              case "ActiveJobAndScheduleQuotaReached":
                  System.err.println("Job quota exceeded.");
                  break;
              default:
                  System.err.println("Unexpected error: " + error.getCode());
          }
          
          // Show additional details if available
          if (error.getValues() != null) {
              for (var detail : error.getValues()) {
                  System.err.printf("  %s: %s%n", detail.getKey(), detail.getValue());
              }
          }
      }
      ```
      
      ## Complete Application Example
      
      ```java
      import com.azure.compute.batch.BatchClient;
      import com.azure.compute.batch.BatchClientBuilder;
      import com.azure.compute.batch.models.*;
      import com.azure.core.http.rest.PagedIterable;
      import com.azure.core.util.BinaryData;
      import com.azure.identity.DefaultAzureCredentialBuilder;
      
      import java.nio.charset.StandardCharsets;
      import java.time.Duration;
      import java.util.*;
      
      public class BatchJobRunner {
          
          private final BatchClient client;
          private final String poolId;
          
          public BatchJobRunner(String poolId) {
              this.client = new BatchClientBuilder()
                  .endpoint(System.getenv("AZURE_BATCH_ENDPOINT"))
                  .credential(new DefaultAzureCredentialBuilder().build())
                  .buildClient();
              this.poolId = poolId;
          }
          
          public void ensurePoolExists() {
              try {
                  BatchPool pool = client.getPool(poolId);
                  System.out.println("Pool exists: " + pool.getId());
              } catch (BatchErrorException e) {
                  if ("PoolNotFound".equals(e.getValue().getCode())) {
                      createPool();
                  } else {
                      throw e;
                  }
              }
          }
          
          private void createPool() {
              System.out.println("Creating pool: " + poolId);
              
              client.createPool(new BatchPoolCreateParameters(poolId, "STANDARD_D2s_v3")
                  .setVirtualMachineConfiguration(
                      new VirtualMachineConfiguration(
                          new BatchVmImageReference()
                              .setPublisher("Canonical")
                              .setOffer("0001-com-ubuntu-server-jammy")
                              .setSku("22_04-lts")
                              .setVersion("latest"),
                          "batch.node.ubuntu 22.04"))
                  .setTargetDedicatedNodes(2)
                  .setTaskSlotsPerNode(4), null);
              
              // Wait for pool to be ready
              waitForPoolReady();
          }
          
          private void waitForPoolReady() {
              System.out.println("Waiting for pool to be ready...");
              while (true) {
                  BatchPool pool = client.getPool(poolId);
                  if (pool.getAllocationState() == AllocationState.STEADY 
                      && pool.getCurrentDedicatedNodes() > 0) {
                      System.out.println("Pool is ready with " + pool.getCurrentDedicatedNodes() + " nodes");
                      break;
                  }
                  try {
                      Thread.sleep(10000);
                  } catch (InterruptedException e) {
                      Thread.currentThread().interrupt();
                      throw new RuntimeException(e);
                  }
              }
          }
          
          public String runJob(String jobId, List<String> commands) {
              // Create job
              client.createJob(
                  new BatchJobCreateParameters(jobId, new BatchPoolInfo().setPoolId(poolId))
                      .setOnAllTasksComplete(OnAllBatchTasksComplete.TERMINATE_JOB),
                  null);
              
              System.out.println("Job created: " + jobId);
              
              // Create tasks
              List<BatchTaskCreateParameters> tasks = new ArrayList<>();
              for (int i = 0; i < commands.size(); i++) {
                  tasks.add(new BatchTaskCreateParameters("task" + i, commands.get(i)));
              }
              
              client.createTasks(jobId, tasks);
              System.out.println("Created " + tasks.size() + " tasks");
              
              // Wait for completion
              waitForJobComplete(jobId);
              
              return jobId;
          }
          
          private void waitForJobComplete(String jobId) {
              System.out.println("Waiting for job to complete...");
              while (true) {
                  BatchJob job = client.getJob(jobId, null, null);
                  
                  if (job.getState() == BatchJobState.COMPLETED) {
                      System.out.println("Job completed");
                      break;
                  } else if (job.getState() == BatchJobState.DISABLED 
                          || job.getState() == BatchJobState.TERMINATING) {
                      throw new RuntimeException("Job failed or was terminated");
                  }
                  
                  // Show progress
                  BatchTaskCountsResult counts = client.getJobTaskCounts(jobId);
                  System.out.printf("Progress: %d/%d tasks completed%n",
                      counts.getTaskCounts().getCompleted(),
                      counts.getTaskCounts().getActive() + counts.getTaskCounts().getRunning() 
                          + counts.getTaskCounts().getCompleted());
                  
                  try {
                      Thread.sleep(5000);
                  } catch (InterruptedException e) {
                      Thread.currentThread().interrupt();
                      throw new RuntimeException(e);
                  }
              }
          }
          
          public Map<String, String> getTaskOutputs(String jobId) {
              Map<String, String> outputs = new HashMap<>();
              
              PagedIterable<BatchTask> tasks = client.listTasks(jobId);
              for (BatchTask task : tasks) {
                  try {
                      BinaryData stdout = client.getTaskFile(jobId, task.getId(), "stdout.txt");
                      outputs.put(task.getId(), new String(stdout.toBytes(), StandardCharsets.UTF_8));
                  } catch (Exception e) {
                      outputs.put(task.getId(), "Error: " + e.getMessage());
                  }
              }
              
              return outputs;
          }
          
          public void cleanup(String jobId) {
              try {
                  client.beginDeleteJob(jobId).waitForCompletion();
                  System.out.println("Job deleted: " + jobId);
              } catch (Exception e) {
                  System.err.println("Failed to delete job: " + e.getMessage());
              }
          }
          
          public static void main(String[] args) {
              BatchJobRunner runner = new BatchJobRunner("my-batch-pool");
              
              try {
                  // Ensure pool exists
                  runner.ensurePoolExists();
                  
                  // Run job with tasks
                  List<String> commands = Arrays.asList(
                      "echo 'Processing partition 1' && sleep 5",
                      "echo 'Processing partition 2' && sleep 5",
                      "echo 'Processing partition 3' && sleep 5",
                      "echo 'Processing partition 4' && sleep 5"
                  );
                  
                  String jobId = "job-" + System.currentTimeMillis();
                  runner.runJob(jobId, commands);
                  
                  // Get outputs
                  Map<String, String> outputs = runner.getTaskOutputs(jobId);
                  
                  System.out.println("\n=== Task Outputs ===");
                  outputs.forEach((taskId, output) -> {
                      System.out.printf("%s: %s%n", taskId, output.trim());
                  });
                  
                  // Cleanup
                  runner.cleanup(jobId);
                  
              } catch (Exception e) {
                  System.err.println("Error: " + e.getMessage());
                  e.printStackTrace();
              }
          }
      }
      ```
      
      ## Environment Variables
      
      ```bash
      AZURE_BATCH_ENDPOINT=https://<account>.<region>.batch.azure.com
      AZURE_BATCH_ACCOUNT=<account-name>
      AZURE_BATCH_ACCESS_KEY=<account-key>
      
      # For DefaultAzureCredential
      AZURE_CLIENT_ID=<service-principal-client-id>
      AZURE_CLIENT_SECRET=<service-principal-secret>
      AZURE_TENANT_ID=<tenant-id>
      ```
      
      ## Best Practices
      
      1. **Use Entra ID** — Preferred over shared key for authentication
      2. **Use management SDK for pools** — `azure-resourcemanager-batch` supports managed identities
      3. **Batch task creation** — Use `createTaskCollection` or `createTasks` for multiple tasks
      4. **Handle LRO properly** — Pool resize, delete operations are long-running
      5. **Monitor task counts** — Use `getJobTaskCounts` to track progress
      6. **Set constraints** — Configure `maxWallClockTime` and `maxTaskRetryCount`
      7. **Use low-priority nodes** — Cost savings for fault-tolerant workloads
      8. **Enable autoscale** — Dynamically adjust pool size based on workload
      
  • SKILL.md 11.6 KB
    ---
    name: azure-compute-batch-java
    description: |-
      Azure Batch SDK for Java. Run large-scale parallel and HPC batch jobs with pools, jobs, tasks, and compute nodes.
      Triggers: "BatchClient java", "azure batch java", "batch pool java", "batch job java", "HPC java", "parallel computing java".
    license: MIT
    metadata:
      author: Microsoft
      version: "1.0.0"
    ---
    
    # Azure Batch SDK for Java
    
    Client library for running large-scale parallel and high-performance computing (HPC) batch jobs in Azure.
    
    ## Installation
    
    ```xml
    <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-compute-batch</artifactId>
        <version>1.0.0-beta.5</version>
    </dependency>
    ```
    
    ## Prerequisites
    
    - Azure Batch account
    - Pool configured with compute nodes
    - Azure subscription
    
    ## Environment Variables
    
    ```bash
    AZURE_BATCH_ENDPOINT=https://<account>.<region>.batch.azure.com  # Required for all auth methods
    AZURE_BATCH_ACCOUNT=<account-name>  # Only required for shared key auth
    AZURE_BATCH_ACCESS_KEY=<account-key>  # Only required for shared key auth
    AZURE_TOKEN_CREDENTIALS=prod  # Required only if DefaultAzureCredential is used in production
    ```
    
    ## Client Creation
    
    ### With Microsoft Entra ID (Recommended)
    
    ```java
    import com.azure.compute.batch.BatchClient;
    import com.azure.compute.batch.BatchClientBuilder;
    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();
    
    BatchClient batchClient = new BatchClientBuilder()
        .credential(credential)
        .endpoint(System.getenv("AZURE_BATCH_ENDPOINT"))
        .buildClient();
    ```
    
    ### Async Client
    
    ```java
    import com.azure.compute.batch.BatchAsyncClient;
    
    BatchAsyncClient batchAsyncClient = new BatchClientBuilder()
        .credential(credential)
        .endpoint(System.getenv("AZURE_BATCH_ENDPOINT"))
        .buildAsyncClient();
    ```
    
    ### With Shared Key Credentials
    
    ```java
    import com.azure.core.credential.AzureNamedKeyCredential;
    
    String accountName = System.getenv("AZURE_BATCH_ACCOUNT");
    String accountKey = System.getenv("AZURE_BATCH_ACCESS_KEY");
    AzureNamedKeyCredential sharedKeyCreds = new AzureNamedKeyCredential(accountName, accountKey);
    
    BatchClient batchClient = new BatchClientBuilder()
        .credential(sharedKeyCreds)
        .endpoint(System.getenv("AZURE_BATCH_ENDPOINT"))
        .buildClient();
    ```
    
    ## Key Concepts
    
    | Concept | Description |
    |---------|-------------|
    | Pool | Collection of compute nodes that run tasks |
    | Job | Logical grouping of tasks |
    | Task | Unit of computation (command/script) |
    | Node | VM that executes tasks |
    | Job Schedule | Recurring job creation |
    
    ## Pool Operations
    
    ### Create Pool
    
    ```java
    import com.azure.compute.batch.models.*;
    
    batchClient.createPool(new BatchPoolCreateParameters("myPoolId", "STANDARD_DC2s_V2")
        .setVirtualMachineConfiguration(
            new VirtualMachineConfiguration(
                new BatchVmImageReference()
                    .setPublisher("Canonical")
                    .setOffer("UbuntuServer")
                    .setSku("22_04-lts")
                    .setVersion("latest"),
                "batch.node.ubuntu 22.04"))
        .setTargetDedicatedNodes(2)
        .setTargetLowPriorityNodes(0), null);
    ```
    
    ### Get Pool
    
    ```java
    BatchPool pool = batchClient.getPool("myPoolId");
    System.out.println("Pool state: " + pool.getState());
    System.out.println("Current dedicated nodes: " + pool.getCurrentDedicatedNodes());
    ```
    
    ### List Pools
    
    ```java
    import com.azure.core.http.rest.PagedIterable;
    
    PagedIterable<BatchPool> pools = batchClient.listPools();
    for (BatchPool pool : pools) {
        System.out.println("Pool: " + pool.getId() + ", State: " + pool.getState());
    }
    ```
    
    ### Resize Pool
    
    ```java
    import com.azure.core.util.polling.SyncPoller;
    
    BatchPoolResizeParameters resizeParams = new BatchPoolResizeParameters()
        .setTargetDedicatedNodes(4)
        .setTargetLowPriorityNodes(2);
    
    SyncPoller<BatchPool, BatchPool> poller = batchClient.beginResizePool("myPoolId", resizeParams);
    poller.waitForCompletion();
    BatchPool resizedPool = poller.getFinalResult();
    ```
    
    ### Enable AutoScale
    
    ```java
    BatchPoolEnableAutoScaleParameters autoScaleParams = new BatchPoolEnableAutoScaleParameters()
        .setAutoScaleEvaluationInterval(Duration.ofMinutes(5))
        .setAutoScaleFormula("$TargetDedicatedNodes = min(10, $PendingTasks.GetSample(TimeInterval_Minute * 5));");
    
    batchClient.enablePoolAutoScale("myPoolId", autoScaleParams);
    ```
    
    ### Delete Pool
    
    ```java
    SyncPoller<BatchPool, Void> deletePoller = batchClient.beginDeletePool("myPoolId");
    deletePoller.waitForCompletion();
    ```
    
    ## Job Operations
    
    ### Create Job
    
    ```java
    batchClient.createJob(
        new BatchJobCreateParameters("myJobId", new BatchPoolInfo().setPoolId("myPoolId"))
            .setPriority(100)
            .setConstraints(new BatchJobConstraints()
                .setMaxWallClockTime(Duration.ofHours(24))
                .setMaxTaskRetryCount(3)),
        null);
    ```
    
    ### Get Job
    
    ```java
    BatchJob job = batchClient.getJob("myJobId", null, null);
    System.out.println("Job state: " + job.getState());
    ```
    
    ### List Jobs
    
    ```java
    PagedIterable<BatchJob> jobs = batchClient.listJobs(new BatchJobsListOptions());
    for (BatchJob job : jobs) {
        System.out.println("Job: " + job.getId() + ", State: " + job.getState());
    }
    ```
    
    ### Get Task Counts
    
    ```java
    BatchTaskCountsResult counts = batchClient.getJobTaskCounts("myJobId");
    System.out.println("Active: " + counts.getTaskCounts().getActive());
    System.out.println("Running: " + counts.getTaskCounts().getRunning());
    System.out.println("Completed: " + counts.getTaskCounts().getCompleted());
    ```
    
    ### Terminate Job
    
    ```java
    BatchJobTerminateParameters terminateParams = new BatchJobTerminateParameters()
        .setTerminationReason("Manual termination");
    BatchJobTerminateOptions options = new BatchJobTerminateOptions().setParameters(terminateParams);
    
    SyncPoller<BatchJob, BatchJob> poller = batchClient.beginTerminateJob("myJobId", options, null);
    poller.waitForCompletion();
    ```
    
    ### Delete Job
    
    ```java
    SyncPoller<BatchJob, Void> deletePoller = batchClient.beginDeleteJob("myJobId");
    deletePoller.waitForCompletion();
    ```
    
    ## Task Operations
    
    ### Create Single Task
    
    ```java
    BatchTaskCreateParameters task = new BatchTaskCreateParameters("task1", "echo 'Hello World'");
    batchClient.createTask("myJobId", task);
    ```
    
    ### Create Task with Exit Conditions
    
    ```java
    batchClient.createTask("myJobId", new BatchTaskCreateParameters("task2", "cmd /c exit 3")
        .setExitConditions(new ExitConditions()
            .setExitCodeRanges(Arrays.asList(
                new ExitCodeRangeMapping(2, 4, 
                    new ExitOptions().setJobAction(BatchJobActionKind.TERMINATE)))))
        .setUserIdentity(new UserIdentity()
            .setAutoUser(new AutoUserSpecification()
                .setScope(AutoUserScope.TASK)
                .setElevationLevel(ElevationLevel.NON_ADMIN))),
        null);
    ```
    
    ### Create Task Collection (up to 100)
    
    ```java
    List<BatchTaskCreateParameters> taskList = Arrays.asList(
        new BatchTaskCreateParameters("task1", "echo Task 1"),
        new BatchTaskCreateParameters("task2", "echo Task 2"),
        new BatchTaskCreateParameters("task3", "echo Task 3")
    );
    BatchTaskGroup taskGroup = new BatchTaskGroup(taskList);
    BatchCreateTaskCollectionResult result = batchClient.createTaskCollection("myJobId", taskGroup);
    ```
    
    ### Create Many Tasks (no limit)
    
    ```java
    List<BatchTaskCreateParameters> tasks = new ArrayList<>();
    for (int i = 0; i < 1000; i++) {
        tasks.add(new BatchTaskCreateParameters("task" + i, "echo Task " + i));
    }
    batchClient.createTasks("myJobId", tasks);
    ```
    
    ### Get Task
    
    ```java
    BatchTask task = batchClient.getTask("myJobId", "task1");
    System.out.println("Task state: " + task.getState());
    System.out.println("Exit code: " + task.getExecutionInfo().getExitCode());
    ```
    
    ### List Tasks
    
    ```java
    PagedIterable<BatchTask> tasks = batchClient.listTasks("myJobId");
    for (BatchTask task : tasks) {
        System.out.println("Task: " + task.getId() + ", State: " + task.getState());
    }
    ```
    
    ### Get Task Output
    
    ```java
    import com.azure.core.util.BinaryData;
    import java.nio.charset.StandardCharsets;
    
    BinaryData stdout = batchClient.getTaskFile("myJobId", "task1", "stdout.txt");
    System.out.println(new String(stdout.toBytes(), StandardCharsets.UTF_8));
    ```
    
    ### Terminate Task
    
    ```java
    batchClient.terminateTask("myJobId", "task1", null, null);
    ```
    
    ## Node Operations
    
    ### List Nodes
    
    ```java
    PagedIterable<BatchNode> nodes = batchClient.listNodes("myPoolId", new BatchNodesListOptions());
    for (BatchNode node : nodes) {
        System.out.println("Node: " + node.getId() + ", State: " + node.getState());
    }
    ```
    
    ### Reboot Node
    
    ```java
    SyncPoller<BatchNode, BatchNode> rebootPoller = batchClient.beginRebootNode("myPoolId", "nodeId");
    rebootPoller.waitForCompletion();
    ```
    
    ### Get Remote Login Settings
    
    ```java
    BatchNodeRemoteLoginSettings settings = batchClient.getNodeRemoteLoginSettings("myPoolId", "nodeId");
    System.out.println("IP: " + settings.getRemoteLoginIpAddress());
    System.out.println("Port: " + settings.getRemoteLoginPort());
    ```
    
    ## Job Schedule Operations
    
    ### Create Job Schedule
    
    ```java
    batchClient.createJobSchedule(new BatchJobScheduleCreateParameters("myScheduleId",
        new BatchJobScheduleConfiguration()
            .setRecurrenceInterval(Duration.ofHours(6))
            .setDoNotRunUntil(OffsetDateTime.now().plusDays(1)),
        new BatchJobSpecification(new BatchPoolInfo().setPoolId("myPoolId"))
            .setPriority(50)),
        null);
    ```
    
    ### Get Job Schedule
    
    ```java
    BatchJobSchedule schedule = batchClient.getJobSchedule("myScheduleId");
    System.out.println("Schedule state: " + schedule.getState());
    ```
    
    ## Error Handling
    
    ```java
    import com.azure.compute.batch.models.BatchErrorException;
    import com.azure.compute.batch.models.BatchError;
    
    try {
        batchClient.getPool("nonexistent-pool");
    } catch (BatchErrorException e) {
        BatchError error = e.getValue();
        System.err.println("Error code: " + error.getCode());
        System.err.println("Message: " + error.getMessage().getValue());
        
        if ("PoolNotFound".equals(error.getCode())) {
            System.err.println("The specified pool does not exist.");
        }
    }
    ```
    
    ## Best Practices
    
    1. **Use Entra ID** — Preferred over shared key for authentication
    2. **Use management SDK for pools** — `azure-resourcemanager-batch` supports managed identities
    3. **Batch task creation** — Use `createTaskCollection` or `createTasks` for multiple tasks
    4. **Handle LRO properly** — Pool resize, delete operations are long-running
    5. **Monitor task counts** — Use `getJobTaskCounts` to track progress
    6. **Set constraints** — Configure `maxWallClockTime` and `maxTaskRetryCount`
    7. **Use low-priority nodes** — Cost savings for fault-tolerant workloads
    8. **Enable autoscale** — Dynamically adjust pool size based on workload
    
    ## Reference Links
    
    | Resource | URL |
    |----------|-----|
    | Maven Package | https://central.sonatype.com/artifact/com.azure/azure-compute-batch |
    | GitHub | https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/batch/azure-compute-batch |
    | API Documentation | https://learn.microsoft.com/java/api/com.azure.compute.batch |
    | Product Docs | https://learn.microsoft.com/azure/batch/ |
    | REST API | https://learn.microsoft.com/rest/api/batchservice/ |
    | Samples | https://github.com/azure/azure-batch-samples |
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related