Azure SDK for Java Reference Documentation

Current version is 1.0.0-beta.2, click here for the index

Azure Load Testing client library for Java

Azure Load Testing provides client library in Java to the user by which they can interact natively with Azure Load Testing service. Azure Load Testing is a fully managed load-testing service that enables you to generate high-scale load. The service simulates traffic for your applications, regardless of where they're hosted. Developers, testers, and quality assurance (QA) engineers can use it to optimize application performance, scalability, or capacity

This package contains Microsoft Azure Developer LoadTesting client library.

Documentation

Various documentation is available to help you get started

Getting started

Prerequisites

Adding the package to your product

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-developer-loadtesting</artifactId>
    <version>1.0.0-beta.2</version>
</dependency>

Authentication

Azure Identity package provides the default implementation for authenticating the client.

By default, Azure Active Directory token authentication depends on correct configure of following environment variables.

  • AZURE_CLIENT_ID for Azure client ID.
  • AZURE_TENANT_ID for Azure tenant ID.
  • AZURE_CLIENT_SECRET or AZURE_CLIENT_CERTIFICATE_PATH for client secret or client certificate.

In addition, Azure subscription ID can be configured via environment variable AZURE_SUBSCRIPTION_ID.

With above configuration, azure client can be authenticated by following code:

// ensure the user, service principal or managed identity used has Loadtesting Contributor role for the resource
TokenCredential credential = new DefaultAzureCredentialBuilder()
    .build();
// create client using DefaultAzureCredential
LoadTestingClientBuilder builder = new LoadTestingClientBuilder()
    .credential(credential)
    .endpoint("<Enter Azure Load Testing Data-Plane URL>");
LoadTestAdministrationClient adminClient = builder.buildLoadTestAdministrationClient();
LoadTestRunClient testRunClient = builder.buildLoadTestRunClient();

RequestOptions reqOpts = new RequestOptions()
    .addQueryParam("orderBy", "lastModifiedDateTime")
    .addQueryParam("maxPageSize", "10");
adminClient.listTests(reqOpts);

reqOpts = new RequestOptions()
    .addQueryParam("orderBy", "lastModifiedDateTime")
    .addQueryParam("status", "EXECUTING,DONE")
    .addQueryParam("maxPageSize", "10");
testRunClient.listTestRuns(reqOpts);

Key concepts

The following components make up the Azure Load Testing service. The Azure Load Test client library for Java allows you to interact with each of these components through the use of clients. There are two top-level clients which are the main entry points for the library

  • LoadTestingClient

  • LoadTestingAsyncClient

The two clients have similar methods in them except the methods in the async client are async as well.

The top-level clients have two sub-clients

  • LoadTestAdministration

  • TestRun

These sub-clients are used for managing and using different components of the service.

Load Test Administration Client

The LoadTestAdministration sub-clients is used to administer and configure the load tests, app components and metrics.

Test

A test specifies the test script, and configuration settings for running a load test. You can create one or more tests in an Azure Load Testing resource.

App Component

When you run a load test for an Azure-hosted application, you can monitor resource metrics for the different Azure application components (server-side metrics). While the load test runs, and after completion of the test, you can monitor and analyze the resource metrics in the Azure Load Testing dashboard.

Metrics

During a load test, Azure Load Testing collects metrics about the test execution. There are two types of metrics:

  1. Client-side metrics give you details reported by the test engine. These metrics include the number of virtual users, the request response time, the number of failed requests, or the number of requests per second.

  2. Server-side metrics are available for Azure-hosted applications and provide information about your Azure application components. Metrics can be for the number of database reads, the type of HTTP responses, or container resource consumption.

Test Run Client

The TestRun sub-clients is used to start and stop test runs corresponding to a load test. A test run represents one execution of a load test. It collects the logs associated with running the Apache JMeter script, the load test YAML configuration, the list of app components to monitor, and the results of the test.

Data-Plane Endpoint

Data-plane of Azure Load Testing resources is addressable using the following URL format:

00000000-0000-0000-0000-000000000000.aaa.cnt-prod.loadtesting.azure.com

The first GUID 00000000-0000-0000-0000-000000000000 is the unique identifier used for accessing the Azure Load Testing resource. This is followed by aaa which is the Azure region of the resource.

The data-plane endpoint is obtained from Control Plane APIs.

Example: 1234abcd-12ab-12ab-12ab-123456abcdef.eus.cnt-prod.loadtesting.azure.com

In the above example, eus represents the Azure region East US.

Examples

Creating a Load Test

LoadTestAdministrationClient adminClient = new LoadTestingClientBuilder()
        .credential(new DefaultAzureCredentialBuilder().build())
        .endpoint("<endpoint>")
        .buildLoadTestAdministrationClient();

// construct Test object using nested String:Object Maps
Map<String, Object> testMap = new HashMap<String, Object>();
testMap.put("displayName", "Sample Display Name");
testMap.put("description", "Sample Description");

// loadTestConfig describes the number of test engines to generate load
Map<String, Object> loadTestConfigMap = new HashMap<String, Object>();
loadTestConfigMap.put("engineInstances", 1);
testMap.put("loadTestConfiguration", loadTestConfigMap);

// environmentVariables are plain-text data passed to test engines
Map<String, Object> envVarMap = new HashMap<String, Object>();
envVarMap.put("a", "b");
envVarMap.put("x", "y");
testMap.put("environmentVariables", envVarMap);

// secrets are secure data sent using Azure Key Vault
Map<String, Object> secretMap = new HashMap<String, Object>();
Map<String, Object> sampleSecretMap = new HashMap<String, Object>();
sampleSecretMap.put("value", "https://samplevault.vault.azure.net/secrets/samplesecret/f113f91fd4c44a368049849c164db827");
sampleSecretMap.put("type", "AKV_SECRET_URI");
secretMap.put("sampleSecret", sampleSecretMap);
testMap.put("secrets", secretMap);

// passFailCriteria define the conditions to conclude the test as success
Map<String, Object> passFailMap = new HashMap<String, Object>();
Map<String, Object> passFailMetrics = new HashMap<String, Object>();
Map<String, Object> samplePassFailMetric = new HashMap<String, Object>();
samplePassFailMetric.put("clientmetric", "response_time_ms");
samplePassFailMetric.put("aggregate", "percentage");
samplePassFailMetric.put("condition", ">");
samplePassFailMetric.put("value", "20");
samplePassFailMetric.put("action", "continue");
passFailMetrics.put("fefd759d-7fe8-4f83-8b6d-aeebe0f491fe", samplePassFailMetric);
passFailMap.put("passFailMetrics", passFailMetrics);
testMap.put("passFailCriteria", passFailMap);

// convert the object Map to JSON BinaryData
BinaryData test = BinaryData.fromObject(testMap);

// receive response with BinaryData content
Response<BinaryData> testOutResponse = adminClient.createOrUpdateTestWithResponse("test12345", test, null);
System.out.println(testOutResponse.getValue().toString());

Uploading .jmx file to a Load Test

LoadTestAdministrationClient adminClient = new LoadTestingClientBuilder()
    .credential(new DefaultAzureCredentialBuilder().build())
    .endpoint("<endpoint>")
    .buildLoadTestAdministrationClient();

// extract file contents to BinaryData
BinaryData fileData = BinaryData.fromFile(new File("path/to/file").toPath());

// receive response with BinaryData content
Response<BinaryData> fileUrlOut = adminClient.uploadTestFileWithResponse("test12345", "sample-file.jmx", fileData, null);
System.out.println(fileUrlOut.getValue().toString());

Running a Load Test

LoadTestRunClient testRunClient = new LoadTestingClientBuilder()
    .credential(new DefaultAzureCredentialBuilder().build())
    .endpoint("<endpoint>")
    .buildLoadTestRunClient();

// construct Test Run object using nested String:Object Maps
Map<String, Object> testRunMap = new HashMap<String, Object>();
testRunMap.put("testId", "test12345");
testRunMap.put("displayName", "SDK-Created-TestRun");

// convert the object Map to JSON BinaryData
BinaryData testRun = BinaryData.fromObject(testRunMap);

// start test with poller
SyncPoller<BinaryData, BinaryData> poller = testRunClient.beginTestRun("testrun12345", testRun, null);
Duration pollInterval = Duration.ofSeconds(5);
poller = poller.setPollInterval(pollInterval);

// wait for test to reach terminal state
JsonNode testRunJson = null;
String testStatus;
PollResponse<BinaryData> pollResponse = poller.poll();
while (pollResponse.getStatus() == LongRunningOperationStatus.IN_PROGRESS || pollResponse.getStatus() == LongRunningOperationStatus.NOT_STARTED) {
    try {
        testRunJson = new ObjectMapper().readTree(pollResponse.getValue().toString());
        testStatus = testRunJson.get("status").asText();
        System.out.println("Test run status: " + testStatus);
    } catch (JsonProcessingException e) {
        System.out.println("Error processing JSON response");
        // handle error condition
    }

    // wait and check test status every 5 seconds
    try {
        Thread.sleep(pollInterval.toMillis());
    } catch (InterruptedException e) {
        // handle interruption
    }

    pollResponse = poller.poll();
}

poller.waitForCompletion();
BinaryData testRunBinary = poller.getFinalResult();
try {
    testRunJson = new ObjectMapper().readTree(testRunBinary.toString());
    testStatus = testRunJson.get("status").asText();
} catch (JsonProcessingException e) {
    System.out.println("Error processing JSON response");
    // handle error condition
}

String startDateTime = testRunJson.get("startDateTime").asText();
String endDateTime = testRunJson.get("endDateTime").asText();

// get list of all metric namespaces and pick the first one
Response<BinaryData> metricNamespacesOut = testRunClient.listMetricNamespacesWithResponse("testrun12345", null);
String metricNamespace = null;
// parse JSON and read first value
try {
    JsonNode metricNamespacesJson = new ObjectMapper().readTree(metricNamespacesOut.getValue().toString());
    metricNamespace = metricNamespacesJson.get("value").get(0).get("metricNamespaceName").asText();
} catch (JsonProcessingException e) {
    System.out.println("Error processing JSON response");
    // handle error condition
}

// get list of all metric definitions and pick the first one
Response<BinaryData> metricDefinitionsOut = testRunClient.listMetricDefinitionsWithResponse("testrun12345", metricNamespace, null);
String metricName = null;
// parse JSON and read first value
try {
    JsonNode metricDefinitionsJson = new ObjectMapper().readTree(metricDefinitionsOut.getValue().toString());
    metricName = metricDefinitionsJson.get("value").get(0).get("name").get("value").asText();
} catch (JsonProcessingException e) {
    System.out.println("Error processing JSON response");
    // handle error condition
}

// fetch client metrics using metric namespace and metric name
PagedIterable<BinaryData> clientMetricsOut = testRunClient.listMetrics("testrun12345", metricName, metricNamespace, startDateTime + '/' + endDateTime, null);
clientMetricsOut.forEach((clientMetric) -> {
    System.out.println(clientMetric.toString());
});

Troubleshooting

Azure SDKs for Java offer a consistent logging story to help aid in troubleshooting application errors and expedite their resolution. The logs produced will capture the flow of an application before reaching the terminal state to help locate the root issue. View the logging wiki for guidance about enabling logging.

Next steps

Azure Loading Testing Java SDK samples are available to you in the SDK's GitHub repository. These samples provide example code for additional scenarios commonly encountered. See Azure Load Testing samples.

Contributing

For details on contributing to this repository, see the contributing guide.

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request
Packages
Package
Description
Package containing the classes for LoadTestingClient.