CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-azure--azure-storage-blob

Microsoft Azure client library for Blob Storage - Azure Blob Storage is Microsoft's object storage solution for the cloud, optimized for storing massive amounts of unstructured data such as text or binary data.

Pending
Overview
Eval results
Files

container-client.mddocs/

Container Client Operations

Container clients provide comprehensive functionality for managing blob containers, including creation, configuration, blob management, and access control.

BlobContainerClient

The synchronous client for blob container operations.

Creating Container Clients

import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobContainerClientBuilder;
import com.azure.storage.blob.BlobServiceClient;

// From service client (recommended)
BlobServiceClient serviceClient = new BlobServiceClientBuilder()
    .connectionString("DefaultEndpointsProtocol=https;AccountName=myaccount;...")
    .buildClient();
BlobContainerClient containerClient = serviceClient.getBlobContainerClient("mycontainer");

// Direct creation using builder
BlobContainerClient containerClient = new BlobContainerClientBuilder()
    .connectionString("DefaultEndpointsProtocol=https;AccountName=myaccount;...")
    .containerName("mycontainer")
    .buildClient();

// Using endpoint and credential
BlobContainerClient containerClient = new BlobContainerClientBuilder()
    .endpoint("https://myaccount.blob.core.windows.net/mycontainer")
    .credential(new DefaultAzureCredentialBuilder().build())
    .buildClient();

Container Lifecycle Management

import com.azure.storage.blob.models.*;
import com.azure.core.http.rest.Response;
import com.azure.core.util.Context;

// Create container
containerClient.create();

// Create with options and metadata
Map<String, String> metadata = Map.of(
    "environment", "production",
    "team", "backend",
    "created-by", "deployment-script"
);

BlobContainerCreateOptions createOptions = new BlobContainerCreateOptions()
    .setMetadata(metadata)
    .setPublicAccessType(PublicAccessType.BLOB);

Response<Void> createResponse = containerClient.createWithResponse(
    createOptions, 
    Duration.ofSeconds(30), 
    Context.NONE
);

System.out.println("Container created, status: " + createResponse.getStatusCode());

// Create if not exists
boolean created = containerClient.createIfNotExists();
if (created) {
    System.out.println("Container was created");
} else {
    System.out.println("Container already exists");
}

// Check if container exists
Boolean exists = containerClient.exists();
System.out.println("Container exists: " + exists);

// Delete container
containerClient.delete();

// Delete with conditions
BlobRequestConditions conditions = new BlobRequestConditions()
    .setIfUnmodifiedSince(OffsetDateTime.now().minusDays(1));
    
Response<Void> deleteResponse = containerClient.deleteWithResponse(
    conditions,
    Duration.ofSeconds(30),
    Context.NONE
);

// Delete if exists
boolean deleted = containerClient.deleteIfExists();

Container Properties and Metadata

// Get container properties
BlobContainerProperties properties = containerClient.getProperties();
System.out.println("Last modified: " + properties.getLastModified());
System.out.println("ETag: " + properties.getETag());
System.out.println("Public access: " + properties.getPublicAccess());
System.out.println("Lease status: " + properties.getLeaseStatus());
System.out.println("Lease state: " + properties.getLeaseState());
System.out.println("Has immutability policy: " + properties.hasImmutabilityPolicy());
System.out.println("Has legal hold: " + properties.hasLegalHold());
System.out.println("Metadata: " + properties.getMetadata());

// Set metadata
Map<String, String> newMetadata = Map.of(
    "environment", "staging",
    "version", "2.0",
    "last-updated", OffsetDateTime.now().toString()
);

containerClient.setMetadata(newMetadata);

// Set metadata with conditions
BlobRequestConditions metadataConditions = new BlobRequestConditions()
    .setIfMatch(properties.getETag());

Response<Void> metadataResponse = containerClient.setMetadataWithResponse(
    newMetadata,
    metadataConditions,
    Duration.ofSeconds(30),
    Context.NONE
);

Access Policies and Permissions

import com.azure.storage.blob.models.*;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.ArrayList;

// Get current access policy
BlobContainerAccessPolicies accessPolicies = containerClient.getAccessPolicy();
System.out.println("Public access: " + accessPolicies.getBlobAccessType());

for (BlobSignedIdentifier identifier : accessPolicies.getIdentifiers()) {
    System.out.println("Policy ID: " + identifier.getId());
    BlobAccessPolicy policy = identifier.getAccessPolicy();
    System.out.println("Permissions: " + policy.getPermissions());
    System.out.println("Start time: " + policy.getStartsOn());
    System.out.println("Expiry time: " + policy.getExpiresOn());
}

// Set access policy with stored access policies
List<BlobSignedIdentifier> identifiers = new ArrayList<>();

BlobSignedIdentifier readOnlyPolicy = new BlobSignedIdentifier()
    .setId("ReadOnlyAccess")
    .setAccessPolicy(new BlobAccessPolicy()
        .setPermissions("r")
        .setStartsOn(OffsetDateTime.now())
        .setExpiresOn(OffsetDateTime.now().plusDays(30)));

BlobSignedIdentifier fullAccessPolicy = new BlobSignedIdentifier()
    .setId("FullAccess")
    .setAccessPolicy(new BlobAccessPolicy()
        .setPermissions("racwdl")
        .setStartsOn(OffsetDateTime.now())
        .setExpiresOn(OffsetDateTime.now().plusDays(7)));

identifiers.add(readOnlyPolicy);
identifiers.add(fullAccessPolicy);

// Apply access policies
containerClient.setAccessPolicy(PublicAccessType.CONTAINER, identifiers);

// Remove public access
containerClient.setAccessPolicy(null, identifiers);

Blob Management

// Get blob client
BlobClient blobClient = containerClient.getBlobClient("myfile.txt");

// Create blob client with snapshot
BlobClient snapshotClient = containerClient.getBlobClient("myfile.txt", "2023-12-01T10:30:00.1234567Z");

// Check if blob exists
boolean blobExists = blobClient.exists();

// Upload a simple blob
String content = "Hello, Azure Blob Storage!";
blobClient.upload(BinaryData.fromString(content), true); // overwrite if exists

// Upload with metadata and properties
Map<String, String> blobMetadata = Map.of("author", "system", "type", "log");
BlobHttpHeaders headers = new BlobHttpHeaders()
    .setContentType("text/plain")
    .setContentEncoding("utf-8")
    .setCacheControl("no-cache");

BlobUploadFromFileOptions uploadOptions = new BlobUploadFromFileOptions("local-file.txt")
    .setHeaders(headers)
    .setMetadata(blobMetadata)
    .setTags(Map.of("environment", "prod", "team", "backend"))
    .setTier(AccessTier.HOT);

Response<BlockBlobItem> uploadResponse = blobClient.uploadFromFileWithResponse(
    uploadOptions,
    Duration.ofMinutes(5),
    Context.NONE
);

Listing Blobs

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

// List all blobs
PagedIterable<BlobItem> blobs = containerClient.listBlobs();
for (BlobItem blob : blobs) {
    System.out.println("Blob: " + blob.getName());
    System.out.println("Size: " + blob.getProperties().getContentLength() + " bytes");
    System.out.println("Type: " + blob.getProperties().getBlobType());
    System.out.println("Last Modified: " + blob.getProperties().getLastModified());
    System.out.println("Access Tier: " + blob.getProperties().getAccessTier());
}

// List with options and filtering
ListBlobsOptions listOptions = new ListBlobsOptions()
    .setPrefix("logs/2023/")
    .setMaxResultsPerPage(100)
    .setDetails(new BlobListDetails()
        .setRetrieveDeletedBlobs(true)
        .setRetrieveMetadata(true)
        .setRetrieveTags(true)
        .setRetrieveSnapshots(true)
        .setRetrieveVersions(true)
        .setRetrieveUncommittedBlobs(false));

PagedIterable<BlobItem> filteredBlobs = containerClient.listBlobs(listOptions, Duration.ofMinutes(2));

for (BlobItem blob : filteredBlobs) {
    System.out.println("Blob: " + blob.getName());
    System.out.println("Metadata: " + blob.getMetadata());
    System.out.println("Tags: " + blob.getTags());
    System.out.println("Is deleted: " + blob.isDeleted());
    System.out.println("Is current version: " + blob.isCurrentVersion());
    if (blob.getSnapshot() != null) {
        System.out.println("Snapshot: " + blob.getSnapshot());
    }
}

// Hierarchical listing (simulating folders)
String delimiter = "/";
PagedIterable<BlobItem> hierarchicalBlobs = containerClient.listBlobsByHierarchy(delimiter);

for (BlobItem item : hierarchicalBlobs) {
    if (item.isPrefix()) {
        System.out.println("Directory: " + item.getName());
    } else {
        System.out.println("File: " + item.getName());
    }
}

// List with prefix and hierarchy
ListBlobsOptions hierarchicalOptions = new ListBlobsOptions()
    .setPrefix("documents/2023/");
    
PagedIterable<BlobItem> folderBlobs = containerClient.listBlobsByHierarchy(
    delimiter,
    hierarchicalOptions,
    Duration.ofMinutes(1)
);

Finding Blobs by Tags

// Find blobs in container using tag queries
String tagFilter = "environment='production' AND team='backend'";
PagedIterable<TaggedBlobItem> taggedBlobs = containerClient.findBlobsByTags(tagFilter);

for (TaggedBlobItem taggedBlob : taggedBlobs) {
    System.out.println("Blob: " + taggedBlob.getName());
    System.out.println("Tags: " + taggedBlob.getTags().toMap());
}

// Find with options
FindBlobsOptions findOptions = new FindBlobsOptions(tagFilter)
    .setMaxResultsPerPage(50);
    
PagedIterable<TaggedBlobItem> pagedTaggedBlobs = containerClient.findBlobsByTags(
    findOptions,
    Duration.ofSeconds(30)
);

Container SAS Generation

import com.azure.storage.blob.sas.*;
import java.time.OffsetDateTime;

// Generate container-level SAS token
OffsetDateTime expiryTime = OffsetDateTime.now().plusHours(2);

BlobContainerSasPermission permission = new BlobContainerSasPermission()
    .setReadPermission(true)
    .setListPermission(true)
    .setAddPermission(true)
    .setCreatePermission(true);

BlobServiceSasSignatureValues sasValues = new BlobServiceSasSignatureValues(expiryTime, permission)
    .setStartTime(OffsetDateTime.now())
    .setProtocol(SasProtocol.HTTPS_ONLY)
    .setSasIpRange(SasIpRange.parse("192.168.1.0/24"));

String containerSas = containerClient.generateSas(sasValues);
System.out.println("Container SAS: " + containerSas);

// Generate SAS with stored access policy
BlobServiceSasSignatureValues storedPolicySas = new BlobServiceSasSignatureValues()
    .setIdentifier("ReadOnlyAccess"); // Reference to stored policy

String storedPolicySasToken = containerClient.generateSas(storedPolicySas);

BlobContainerAsyncClient

The asynchronous client for blob container operations using reactive programming.

Creating Async Container Clients

import com.azure.storage.blob.BlobContainerAsyncClient;
import reactor.core.publisher.Mono;
import reactor.core.publisher.Flux;

// From async service client
BlobServiceAsyncClient asyncServiceClient = new BlobServiceClientBuilder()
    .connectionString("DefaultEndpointsProtocol=https;AccountName=myaccount;...")
    .buildAsyncClient();
BlobContainerAsyncClient asyncContainerClient = asyncServiceClient.getBlobContainerAsyncClient("mycontainer");

// Direct creation
BlobContainerAsyncClient asyncContainerClient = new BlobContainerClientBuilder()
    .connectionString("DefaultEndpointsProtocol=https;AccountName=myaccount;...")
    .containerName("mycontainer")
    .buildAsyncClient();

Async Container Operations

// Create container asynchronously
Mono<Void> createMono = asyncContainerClient.create();
createMono
    .doOnSuccess(v -> System.out.println("Container created successfully"))
    .doOnError(ex -> System.err.println("Container creation failed: " + ex.getMessage()))
    .subscribe();

// Chain operations
asyncContainerClient.createIfNotExists()
    .filter(created -> created) // Only proceed if container was actually created
    .flatMap(created -> {
        Map<String, String> metadata = Map.of("created-time", OffsetDateTime.now().toString());
        return asyncContainerClient.setMetadata(metadata);
    })
    .doOnSuccess(v -> System.out.println("Container created and metadata set"))
    .subscribe();

// Get properties asynchronously
Mono<BlobContainerProperties> propertiesMono = asyncContainerClient.getProperties();
propertiesMono
    .doOnNext(props -> {
        System.out.println("Container last modified: " + props.getLastModified());
        System.out.println("Public access: " + props.getPublicAccess());
        System.out.println("Metadata count: " + props.getMetadata().size());
    })
    .subscribe();

Async Blob Listing

// List blobs asynchronously
Flux<BlobItem> blobFlux = asyncContainerClient.listBlobs();

blobFlux
    .take(50) // Limit to first 50 blobs
    .doOnNext(blob -> System.out.println("Blob: " + blob.getName() + 
        " (" + blob.getProperties().getContentLength() + " bytes)"))
    .doOnComplete(() -> System.out.println("Listing complete"))
    .doOnError(ex -> System.err.println("Listing failed: " + ex.getMessage()))
    .subscribe();

// List with filtering
ListBlobsOptions listOptions = new ListBlobsOptions()
    .setPrefix("images/")
    .setMaxResultsPerPage(25);

Flux<BlobItem> filteredBlobFlux = asyncContainerClient.listBlobs(listOptions);

// Process blobs in parallel
filteredBlobFlux
    .flatMap(blob -> {
        BlobAsyncClient blobAsyncClient = asyncContainerClient.getBlobAsyncClient(blob.getName());
        return blobAsyncClient.getProperties()
            .map(props -> blob.getName() + " - " + props.getContentType());
    }, 5) // Max 5 concurrent operations
    .doOnNext(info -> System.out.println(info))
    .subscribe();

Error Handling with Async Container Client

import com.azure.storage.blob.models.BlobStorageException;

// Comprehensive error handling
asyncContainerClient.create()
    .doOnSuccess(v -> System.out.println("Container created"))
    .onErrorResume(BlobStorageException.class, ex -> {
        if (ex.getErrorCode() == BlobErrorCode.CONTAINER_ALREADY_EXISTS) {
            System.out.println("Container already exists, continuing...");
            return Mono.empty();
        } else {
            System.err.println("Storage error: " + ex.getErrorCode() + " - " + ex.getMessage());
            return Mono.error(ex);
        }
    })
    .onErrorResume(Exception.class, ex -> {
        System.err.println("Unexpected error: " + ex.getMessage());
        return Mono.error(new RuntimeException("Container creation failed", ex));
    })
    .subscribe();

// Retry operations
asyncContainerClient.getProperties()
    .retry(3) // Retry up to 3 times on any error
    .doOnNext(props -> System.out.println("Properties retrieved: " + props.getETag()))
    .doOnError(ex -> System.err.println("Failed after retries: " + ex.getMessage()))
    .subscribe();

Container Leasing

Lease Management

import com.azure.storage.blob.specialized.BlobLeaseClient;
import com.azure.storage.blob.specialized.BlobLeaseClientBuilder;

// Create lease client for container
BlobLeaseClient leaseClient = new BlobLeaseClientBuilder()
    .containerClient(containerClient)
    .buildClient();

// Acquire lease
String proposedLeaseId = UUID.randomUUID().toString();
String leaseId = leaseClient.acquireLease(60); // 60 second lease
System.out.println("Acquired lease: " + leaseId);

try {
    // Operations with lease
    BlobRequestConditions leaseConditions = new BlobRequestConditions()
        .setLeaseId(leaseId);
        
    containerClient.setMetadataWithResponse(
        Map.of("leased", "true"),
        leaseConditions,
        Duration.ofSeconds(30),
        Context.NONE
    );
    
    // Renew lease
    leaseClient.renewLease();
    
    // Break lease (if needed)
    Integer breakPeriod = leaseClient.breakLease();
    System.out.println("Lease will be broken in " + breakPeriod + " seconds");
    
} finally {
    // Always release lease
    try {
        leaseClient.releaseLease();
        System.out.println("Lease released");
    } catch (Exception ex) {
        System.err.println("Failed to release lease: " + ex.getMessage());
    }
}

Container Properties

Key Properties and Methods

// Container identification
String containerName = containerClient.getBlobContainerName();
String accountName = containerClient.getAccountName();
String containerUrl = containerClient.getBlobContainerUrl();

System.out.println("Container: " + containerName);
System.out.println("Account: " + accountName);
System.out.println("URL: " + containerUrl);

// Service information
BlobServiceVersion serviceVersion = containerClient.getServiceVersion();
System.out.println("Service version: " + serviceVersion.getVersion());

// Get account info through container
StorageAccountInfo accountInfo = containerClient.getAccountInfo();
System.out.println("Account kind: " + accountInfo.getAccountKind());
System.out.println("SKU: " + accountInfo.getSkuName());

Special Containers

Working with System Containers

// Root container ($root) - blobs accessible at account level
BlobContainerClient rootContainer = serviceClient.getBlobContainerClient(BlobContainerClient.ROOT_CONTAINER_NAME);

// Static website container ($web)
BlobContainerClient webContainer = serviceClient.getBlobContainerClient(BlobContainerClient.STATIC_WEBSITE_CONTAINER_NAME);

// Logs container ($logs) - for analytics logging
BlobContainerClient logsContainer = serviceClient.getBlobContainerClient(BlobContainerClient.LOG_CONTAINER_NAME);

// Check if system containers exist before using
if (rootContainer.exists()) {
    System.out.println("Root container is available");
}

// Upload to root container (blob accessible at https://account.blob.core.windows.net/filename)
BlobClient rootBlob = rootContainer.getBlobClient("favicon.ico");
rootBlob.uploadFromFile("favicon.ico");

Batch Operations

Bulk Container Operations

// Process multiple containers
List<String> containerNames = Arrays.asList("container1", "container2", "container3");

// Create multiple containers
containerNames.forEach(name -> {
    try {
        BlobContainerClient client = serviceClient.getBlobContainerClient(name);
        client.createIfNotExists();
        System.out.println("Ensured container exists: " + name);
    } catch (Exception ex) {
        System.err.println("Failed to create container " + name + ": " + ex.getMessage());
    }
});

// Set metadata on multiple containers
Map<String, String> commonMetadata = Map.of(
    "batch-operation", "true",
    "timestamp", OffsetDateTime.now().toString()
);

containerNames.forEach(name -> {
    try {
        BlobContainerClient client = serviceClient.getBlobContainerClient(name);
        if (client.exists()) {
            client.setMetadata(commonMetadata);
            System.out.println("Set metadata on: " + name);
        }
    } catch (Exception ex) {
        System.err.println("Failed to set metadata on " + name + ": " + ex.getMessage());
    }
});

Related Documentation

  • ← Back to Overview
  • ← Service Client Operations
  • Blob Operations →
  • Security & Authentication →
  • Configuration Options →

Install with Tessl CLI

npx tessl i tessl/maven-com-azure--azure-storage-blob

docs

blob-client.md

container-client.md

index.md

models.md

options.md

security.md

service-client.md

specialized-clients.md

streaming.md

tile.json