In this lab, you will learn how to access Windows Azure Blob Service by using Windows Azure SDK for Java Developers.
This lab will focus on Windows Azure Blob Service which offers storage for large data items.
Blobs consist of unstructured file-based data stored in an array of bytes; containers store sets of individual blobs up to 50GB in size in hierarchical groups, which emulate a directory structure. Only blob containers and their content are available for public access.
Windows Azure Blob service supports a massively scalable blob system, where hot blobs will be served from many servers to scale out and meet the traffic needs of your application. Furthermore, the system is highly available and durable. You can always access your data from anywhere at any time, and the data is replicated at least 3 times for durability. In addition, strong consistency is provided to ensure that the object is immediately accessible once it is added or updated; a subsequent read will immediately see the changes made from a previously committed write.
Before doing this lab, if you not done so:
Note: |
|---|
Enter Windows Azure Account InformationTo use download lab sample and its JUnit, you must modify these static variables with your Windows Azure Account information:
|
All access to Windows Azure Storage is done through a storage account. For a user to create a storage account, this is done via the Windows Azure portal web interface. The user will receive a 256-bit secret key once the account is created. This secret key is then used to authenticate user requests to the storage system.
The Blob service stores sets of binary data. The Blob service offers the following three resources: the storage account, containers, and blobs.
The REST API for the Blob service provides a way to work with blobs via HTTP operations.
Within your storage account, containers provide a way to organize sets of blobs within your storage account. Once you have access to Windows Azure Storage through your storage account, you now have:
The namespace is used to perform all access to Windows Azure Blob Service. The URI for a specific blob is structured as follows:
| Blob Namespace | |
|---|---|
http://<account>.blob.core.windows.net/<container>/<blobname>
| |
The storage account name is specified as the first part of the hostname followed by the keyword "blob". This sends the request to the part of Windows Azure Storage that handles blob requests. The host name is followed by the container name, followed by "/", and then the blob name. Accounts and containers have naming restrictions (see the SDK document for details), for example, the container name cannot contain a "/".
To use Blobs within Windows Azure Storage, you need a create a client that will act as a communication proxy to this service.
An instance of BlobStorageClient creates a Blob Storage Client.
To access this Host, you will need to replace "MyAccountName" and "MyAccountKey" with your Windows Azure Services account information.
BlobSample::createStorageAccess() performs the following:
Note: |
|---|
Retry PoliciesA Storage Client can be assigned a retry policy. A retry policy specifies how the application will retry a request that has failed.
|
| Java — Creating Blob Storage Access | |
|---|---|
import java.net.URI;
import java.util.List;
import org.soyatec.windowsazure.blob.BlobStorageClient;
import org.soyatec.windowsazure.blob.internal.RetryPolicies;
import org.soyatec.windowsazure.error.StorageException;
import org.soyatec.windowsazure.internal.util.TimeSpan;
/* * * * */
protected static final String BLOB_HOST_NAME = "http://blob.core.windows.net/";
/*
* Must register with Windows Azure in order to get your Account Name and Account Key.
*/
protected static final String AZURE_ACCOUNT_NAME = "YourAccountName";
protected static final String AZURE_ACCOUNT_KEY = "YourAccountKey";
/**
* Create client proxy to Blob Storage service.
*
* @param strAccountName
* @param strAccountKey
* @return BlobStorageClient instance.
*/
public static BlobStorageClient createStorageAccess( String strAccountName,
String strAccountKey
)
{
/* * * * */
objBlobStorage = BlobStorageClient.create(
URI.create( BlobSample.BLOB_HOST_NAME ),
false,
strAccountName,
strAccountKey
);
/* Set retry policy for a time interval of 5 seconds. */
objBlobStorage.setRetryPolicy(RetryPolicies.retryN(1, TimeSpan.fromSeconds(5)));
/* * * * */
return objBlobStorage;
|
|
| JUnit — Test Creating a Blob Storage client | |
|---|---|
private BlobStorageClient m_objBlobStorage;
/**
* Sets up the test fixture.
*
* Called before every test case method.
*/
protected void setUp()
{
m_objBlobStorage = BlobSample.getBlobStorage();
BlobSample.emptyBlobStorage(m_objBlobStorage);
}
/**
* Test that blob storage was created.
*/
public void testValdidateSetUp()
{
assertNotNull(m_objBlobStorage);
int count = BlobSample.countBlobContainers(m_objBlobStorage);
assertEquals(0, count);
}
| |
Blob Container provides a grouping of a set of blobs. The container name is scoped by the account.
Containers are scoped by accounts. The storage system handles containers in a distributed manner, and there is no centralize resource bottleneck in terms of dealing with containers. The goal is to allow container operations to be on the high availability code paths of your application.
There can be a delay when recreating a recently deleted container, especially when there were a large number of blobs in that container. The system needs to reclaim the blobs in that container before the same container name can be created again. While the server is deleting all of the blobs, recreating the container will fail with an error indicating the container is being deleted.
When an application deletes a container or creates a brand new container, these commands are quickly committed on the server with acknowledgement back to the application, even though the delete can go on for awhile. Therefore, these can be on the high availability code paths for an application.
Create Container operation creates a new container under the specified account. If the container with the same name already exists, the operation fails.
The container resource includes metadata and properties for that container. It does not include a list of the blobs contained by the container.
A successful operation returns status code 201 (Created).
Note: |
|---|
Container NamesThe URL to reference a container must be unique. Because every account name is unique, two accounts can have containers with the same name. However, within a given storage account, every container must have a unique name.
The container name must be a valid DNS name, conforming to the following naming rules:
|
With the Blob Storage Account access through an instance of BlobStorageClient, you can get a reference to a newly created IBlobContainer object by using method BlobStorageClient::getBlobContainer().
BlobStorageClient::createContainer() operation creates a new container under the specified account. If the container with the same name already exists, the operation fails.
BlobSample::getBlobContainer() performs the following:
| Java — Get if Exists or Create Blob Container | |
|---|---|
public static IBlobContainer getBlobContainer_wMetadata (
BlobStorageClient objBlobStorage,
String strBlobContainerName,
NameValueCollection objMetadata
)
throws IllegalArgumentException
{
/* Create objBlobContainer by name */
IBlobContainer objBlobContainer = objBlobStorage.createContainer(strBlobContainerName);
if (null == objBlobContainer) {
throw new NullPointerException("BlobContainer");
}
/* Set metadata to Blob Container */
if (null != objMetadata) {
objBlobContainer.setMetadata(objMetadata);
}
return objBlobContainer;
}
| |
Delete Container operation marks the specified container for deletion. The container and any blobs contained within it are later deleted during garbage collection.
A successful operation returns status code 202 (Accepted).
When a container is deleted, a container with the same name cannot be created for at least 30 seconds; the container may not be available for more than 30 seconds if the service is still processing the request. While the container is being deleted, attempts to create a container of the same name will fail with status code 409 (Conflict), with the service returning additional error information indicating that the container is being deleted. All other operations, including operations on any blobs under the container, will fail with status code 404 (Not Found) while the container is being deleted.
BlobSample::deleteBlobContainer() performs the following:
| Java — Delete Blob Container | |
|---|---|
public static boolean deleteBlobContainer ( BlobStorageClient objBlobStorage,
IBlobContainer objBlobContainer,
boolean fConfirmDelete
)
throws Exception
{
/* * * * */
String containerName = objIBlobContainer.getContainerName();
if(objBlobContainer.isContainerExist()) {
if(!objBlobStorage.deleteContainer(containerName)) {
throw new Exception("Unexpected");
}
}
if (fConfirmDelete) {
/* The amount of delay for deleting container. */
Thread.sleep(40000);
fStatus = !objBlobContainer.isContainerExist();
} else {
fStatus = true;
}
return fStatus;
}
| |
| Java — Delete Blob Container by Name | |
|---|---|
public static boolean deleteBlobContainer ( BlobStorageClient objBlobStorage,
String strContainerName,
boolean fConfirmDelete
)
throws Exception
{
/* * * * */
IBlobContainer objBlobContainer = objBlobStorage.getBlobContainer(strContainerName);
return BlobSample.deleteBlobContainer(objBlobStorage, objBlobContainer, fConfirmDelete);
}
| |
BlobSample::deleteBlobContainersAll() performs the following:
| Java — Empty Blob Storage of Containers | |
|---|---|
public static boolean deleteBlobContainersAll( BlobStorageClient objBlobStorage,
boolean fConfirmDelete
)
{
/* * * * */
List<IBlobContainer> listBlobContainers = objBlobStorage.listBlobContainers();
if (null != listBlobContainers) {
for (IBlobContainer objBlobContainer : listBlobContainers)
{
String strContainerName = objBlobContainer.getContainerName();
if (!BlobSample.deleteBlobContainer(objBlobStorage, objBlobContainer, fConfirmDelete)) {
throw new Exception("Failed to delete " + strContainerName);
}
}
}
/* * * * */
| |
The Blob service API includes operations for enumerating the containers within an account.
BlobStorageClient::listBlobContainers() operation returns a list of the containers under the specified account.
BlobSample::listBlobContainers() uses BlobStorageClient to printout a listing a containers.
| Java — List Blob Containers | |
|---|---|
public static void listBlobContainers( BlobStorage objBlobStorage )
{
/* * * * */
List<IBlobContainer> listBlobContainers = objBlobStorage.listBlobContainers();
System.out.println("------------------");
if (null != listBlobContainers && !listBlobContainers.isEmpty()) {
System.out.printf("List of Blob Containers in Account %s\n",
objBlobStorage.getAccountName()
);
for ( IBlobContainer objBlobContainer : listBlobContainers ) {
System.out.println(objBlobContainer.getContainerName());
}
}
else {
System.out.printf("No Blob Containers in Account %s\n",
objBlobStorage.getAccountName()
);
}
System.out.println("------------------");
/* * * * */
}
| |
BlobSample::countBlobContainers() uses BlobStorage::listBlobContainers() to get the size of the list to determine count.
| Java — List Blob Containers | |
|---|---|
/**
* Number of Blob containers in storage account.
*
* @param objBlobStorage BlobStorageClient
* @return int Count
*/
public static int countBlobContainers( BlobStorageClient objBlobStorage )
{
/* * * * */
try {
List<IBlobContainer> listBlobContainers = objBlobStorage.listBlobContainers();
if (null != listBlobContainers) {
count = listBlobContainers.size();
}
/* * * * */
return count;
}
| |
Containers support custom metadata, represented as HTTP headers. Metadata headers can be set on a request that creates a new container, or on a request that explicitly creates a property on an existing container.
Metadata is a collection of one or more user-defined name/value pairs.
Names are case-insensitive. If two or more headers with the same name are submitted for a resource, the headers will be combined into a single header with a comma delimiting each value.
The total size of the metadata, including both the name and value together, may not exceed 8 KB in size.
Metadata on a container resource can be retrieved or set directly, without returning or altering the content of the resource.
Note: |
|---|
|
Metadata values can only be read or written in full; partial updates are not supported. Setting metadata on a resource overwrites any existing metadata values for that resource. |
NameValueCollection is used to build the user-defined metadata with one or more name-value pairs.
IBlobContainer::setMetadata() sets user-defined metadata for the specified container with a populated NameValueCollection.
IBlobContainer::getProperties() returns a ContainerProperties.
IContainerProperties holds the container's metadata.
IContainerProperties::getMetadata() returns a NameValueCollection which a collection of the container's metadata.
BlobSample::getBlobContainer_wMetadata() shows how to set and get a container's metadata.
| Java — Set and Get Container Metadata | |
|---|---|
import org.soyatec.windowsazure.util.NameValueCollection;
/* * * * */
public static IBlobContainer getBlobContainer_wMetadata (
BlobStorageClient objBlobStorage,
String strBlobContainerName,
NameValueCollection objMetadata
)
throws IllegalArgumentException
{
/* * * * */
/* Fetch objBlobContainer by name */
objBlobContainer = objBlobStorage.getBlobContainer(strBlobContainerName);
if (null == objBlobContainer) {
throw new NullPointerException("BlobContainer");
}
/* Check if it exist */
if (!objBlobContainer.isContainerExist()) {
/* If objBlobContainer does not exist, create it */
objBlobContainer = objBlobStorage.createContainer(strBlobContainerName);
/* Set metadata to Blob Container */
if (null != objMetadata) {
objBlobContainer.setMetadata(objMetadata);
}
} else {
if (null != objMetadata) {
IContainerProperties objContainerProperties = objBlobContainer.getProperties();
objMetadata = objContainerProperties.getMetadata();
}
}
| |
JUnit shows how BlobSample is called for setting and getting BlobContainer metadata within NameValueCollection.
| JUnit — Test Set and Get Container Metadata | |
|---|---|
/**
* Test Container with metadata.
*/
public void testContainer_wMetadata()
{
try {
/* * * * */
NameValueCollection objMetadataContainerPre = new NameValueCollection();
IBlobContainer objBlobContainerPre
= BlobSample.getBlobContainer_wMetadata(
m_objBlobStorage,
strContainerName,
objMetadataContainerPre /* No metadata */
);
NameValueCollection objMetadataPut = new NameValueCollection();
objMetadataPut.put("createdBy", METADATA_CREATED_BY);
fSuccess = BlobSample.setBlobContainer_wMetadata( objBlobContainerPre,
objMetadataPut);
assertTrue(fSuccess);
NameValueCollection objMetadataContainerPost = new NameValueCollection();
IBlobContainer objBlobContainerPost
= BlobSample.getBlobContainer_wMetadata(
m_objBlobStorage,
strContainerName,
objMetadataContainerPost
);
assertNotNull(objBlobContainerPost);
String strCreatedBy = (String) objMetadataContainerPost.getSingleValue("createdBy");
assertTrue(strCreatedBy.equals(METADATA_CREATED_BY));
| |
The Blob service is for storing unstructured data.
Blobs are written to the Blob service by using a PUT operation defined by the REST API. Blobs less than or equal to 64 MB in size can be uploaded with a single PUT operation. Blobs larger than 64 MB must be uploaded as a set of blocks, each of which is less than or equal to 4 MB in size. A set of successfully uploaded blocks can be assembled in a specified order into a single contiguous blob. One block can be specified multiple times in the list of blocks that will comprise a blob. The maximum blob size currently supported is 50 GB.
Blobs support conditional update operations that may be useful for concurrency control and efficient uploading.
Blobs can be read by using a GET operation defined by the REST API. A client may read the entire blob, or an arbitrary range of bytes.
Note: |
|---|
Blob NamesThe URL to reference a blob must be unique. Every blob within a given container must also have a unique name.
The blob name must conform to the following naming rules:
Avoid blob names that end with a dot (.), a forward slash (/), or a sequence or combination of the two. The URL that identifies a blob is constructed with the .NET URL class, which compacts a URL that ends with these sequences. A blob with a name that contains such a sequence may not be accessible via its original name. |
IBlobContainer::createBlockBlob() method to put a blob to the specified container.
Parameters:
BlobMemoryStream is used to write binary data into blob content.
BlobMemoryStream class creates streams that have memory as a backing store instead of a disk or a network connection, it encapsulates data stored as an unsigned byte array that is initialized upon creation of a BlobMemoryStream object, or the array can be created as empty. The encapsulated data is directly accessible in memory. Memory streams can reduce the need for temporary buffers and files in an application.
BlobSample::putBlob_wBinaryData_wMetadata() shows how to put a BlobMemoryStream into a blob that will be put into a specified container.
| Java — Put Blob with Binary Data into a Container | |
|---|---|
import org.soyatec.windowsazure.blob.IBlobProperties;
import org.soyatec.windowsazure.blob.IBlobContents;
import org.soyatec.windowsazure.blob.io.BlobMemoryStream;
import org.soyatec.windowsazure.internal.util.NameValueCollection;
/* * * * */
public static boolean putBlob_wBinaryData_wMetadata(
IBlobContainer objBlobContainer,
String strBlobName,
byte[] binaryBlobData,
NameValueCollection objMetadata,
boolean fOverwrite
)
throws Exception
{
/* * * * */
/* New Blob Properties */
IBlobProperties objBlobProperties = new BlobProperties(strBlobName);
objBlobProperties.setContentType(CONTENT_TYPE_BINARY);
/* Set Metadata */
if (null != objMetadata && (objMetadata instanceof NameValueCollection)) {
objBlobProperties.setMetadata(objMetadata);
}
/* Set Blob Contents */
BlobMemoryStream objStream = new BlobMemoryStream(binaryBlobData);
IBlobContents objBlobContents = new BlobContents(objStream);
if (!objBlobContainer.createBlockBlob( objBlobProperties,
objBlobContents)) {
throw new Exception("Failed to create blob");
}
| |
IBlob::getContents() method downloads the blob if it exists.
Parameters:
BlobSample::getBlob_wBinaryData_wMetadata() shows you how to get a blob with binary data.
| Java — Get Blob with Binary Data from a Container | |
|---|---|
public static byte[] getBlob_wBinaryData_wMetadata(
IBlobContainer objBlobContainer,
String strBlobName,
NameValueCollection objMetadata
)
throws Exception
{
/* * * * */
BlobMemoryStream objStream = new BlobMemoryStream();
IBlockBlob blob = objBlobContainer.getBlockBlobReference(strBlobName);
IBlobProperties objBlobProperties = blob.getProperties( );
/* * * * */
blob.getContents(objStream);
bytesResult = objStream.getBytes();
| |
JUnit shows how BlobSample uses IBlob to set and get blob binary data using BlobMemoryStream.
By default the access mode of a container is private. In JUnit, at /* Validate URL access */, URL access to the blob is tried when container is in private access mode and then in public access mode.
| JUnit — Test Put and Get Blob with Binary Data into a Container | |
|---|---|
/**
* Test Put and Get of Blob binary data into a Container
*/
public void testBlob_wBinaryData()
/* * * * */
/*
* Define the binary data to be held within a blob.
* To create binary data, transform a String into a byte array.
*/
String strTest1 = "a2Xy337u7bg9sbbxNcAU3SyQt8TExeQI";
String strBlobName = "RandomString";
int intStrLength = strTest1.length();
byte[] binaryData = strTest1.getBytes();
byte[] binaryDataResult = null;
/* False test, Blob should not exist */
binaryDataResult
= BlobSample.getBlob_wBinaryData_wMetadata(
objBlobContainer,
strBlobName,
null /* Get not metadata */
);
assertNull(binaryDataResult);
/* Create Blob "RandomString" with binary data */
fSuccess = BlobSample.putBlob_wBinaryData_wMetadata(
objBlobContainer,
strBlobName,
binaryData,
null, /* No metadata */
false
);
assertTrue(fSuccess);
int count = BlobSample.countBlobs(objBlobContainer, null);
assertEquals(1, count);
/* Get the binary data from Blob "RandomString" */
NameValueCollection objMetadataGet = new NameValueCollection();
binaryDataResult
= BlobSample.getBlob_wBinaryData_wMetadata (
objBlobContainer,
strBlobName,
objMetadataGet
);
assertNotNull(binaryDataResult);
| |
IBlobContainer::createBlockBlob() method to put a blob to the specified container.
BlobFileStream class is used to wrap the binary contents of a file, which will then be placed into a blob that will be placed into a container.
BlobSample::putBlob_wFile_wMetadata() shows how to use BlobContainer::createBlockBlob() to send a file to a blob assisted by BlobFileStream.
| Java — Put Blob with File binary into a Container | |
|---|---|
import org.soyatec.windowsazure.blob.IBlobProperties;
import org.soyatec.windowsazure.blob.IBlobContents;
import org.soyatec.windowsazure.blob.io.BlobFileStream;
/* * * * */
public static boolean putBlob_wFile_wMetadata (
BlobContainer objBlobContainer,
String strBlobName,
String strFilePath,
NameValueCollection objMetadata,
boolean fOverwrite
)
throws Exception
{
/* * * * */
/* Set Blob properties */
IBlobProperties objBlobProperties = new BlobProperties(strBlobName);
objBlobProperties.setContentType(CONTENT_TYPE_FILE);
/* Set Metadata */
if (null != objMetadata && (objMetadata instanceof NameValueCollection)) {
objBlobProperties.setMetadata(objMetadata);
}
/* Set Blob contents */
BlobFileStream objStream = new BlobFileStream(strFilePath);
IBlobContents objBlobContents = new BlobContents(objStream);
if (!objBlobContainer.createBlockBlob(objBlobProperties, objBlobContents)) {
throw new Exception("Failed to create blob");
}
/* * * * */
|
|
IBlob::getContents() method downloads the blob if it exists.
Parameters:
BlobSample::getBlob_wFile_wMetadata() shows you how to get a blob with file binary.
| Java — Get Blob with File binary from a Container | |
|---|---|
public static boolean getBlob_wFile_wMetadata (
IBlobContainer objBlobContainer,
String strBlobName,
String strFilePath,
NameValueCollection objMetadata,
boolean fOverwrite
)
throws Exception
{
/* * * * */
BlobFileStream objStream = new BlobFileStream(strFilePath);
IBlob blob = objBlobContainer.getBlockBlobReference( strBlobName);
IBlobContents objBlobContents = blob.getContents(objStream);
/* * * * */
| |
JUnit shows how BlobSample uses BlobContainer to set and get blob binary data using FileStream.
By default the access mode of a container is private. In JUnit, at /* Validate URL access */, URL access to the blob is tried when container is in private access mode and then in public access mode.
When access is public, then the blob image would be accessible through this URL: http://YOUR_ACCOUNT.blob.core.windows.net/testcontainer/WindowsAzure.jpg
| JUnit — Test Put and Get a Blob with File binary | |
|---|---|
/**
* Test Put and Get a Blob with File binary within a Container
*/
public void testBlob_wFile()
{
/* * * * */
/*
* Put File "WindowsAzure.jpg" binary into a Blob,
* Label Blob with name "WindowsAzureImage",
* then put Blob "WindowsAzure.jpg" into strContainerName Container.
*/
fSuccess = BlobSample.putBlob_wFile_wMetadata(
objBlobContainer,
strBlobName,
strFilePath,
null, /* No metadata */
true
);
assertTrue(fSuccess);
int count = BlobSample.countBlobs(objBlobContainer, null);
assertEquals(1, count);
/*
* Provide location to place retrieved File at "WindowsAzure2.jpg",
* Get Blob with name "WindowsAzureImage" from strContainerName Container,
* then copy retrieved Blob's File "WindowsAzure.jpg" binary into "WindowsAzure2.jpg".
*/
NameValueCollection objMetadataGet = new NameValueCollection();
fSuccess = BlobSample.getBlob_wFile_wMetadata( objBlobContainer,
strBlobName,
"WindowsAzure2.jpg",
objMetadataGet,
true /* Overwrite if exists */
);
assertTrue(fSuccess);
assertTrue(objMetadataGet.isEmpty());
| |
IBlobProperties class is used as a wrapper to hold Blob metadata.
NameValueCollection is used to build the user-defined Blob metadata with one or more name-value pairs.
IBlobProperties::setMetadata() sets user-defined metadata for the specified blob with a populated NameValueCollection.
| Java — Set Blob Metadata | |
|---|---|
/* Set Blob properties */
IBlobProperties objBlobProperties = new BlobProperties(strBlobName);
objBlobProperties.setContentType(CONTENT_TYPE_FILE);
/* Set Metadata */
if (null != objMetadata && (objMetadata instanceof NameValueCollection)) {
objBlobProperties.setMetadata(objMetadata);
blob.setProperties(objBlobProperties);
}
| |
IBlobProperties::getMetadata() gets user-defined metadata for the specified blob with a populated NameValueCollection.
| Java — Get Blob Metadata | |
|---|---|
IBlobProperties objBlobProperties = blob.getProperties( );
/* Get Blob metadata */
if ( null != objBlobProperties ) {
objMetadata = objBlobProperties.getMetadata();
}
| |
The Blob service API includes operations for enumerating the blobs within a container.
Using the REST API for the Blob service, developers can create a hierarchical namespace similar to a file system.
For example, the following are all valid and unique blob names:
Blob names may encode a hierarchy by using a configurable path separator. For example, the blob names MyGroup/MyBlob1 and MyGroup/MyBlob2 imply a virtual level of organization for blobs. The enumeration operation for blobs supports traversing the virtual hierarchy in a manner similar to that of a file system, so that you can return a set of blobs that are organized beneath a group. For example, you can enumerate all blobs organized under MyGroup/.
IBlobContainer::listBlobs(java.lang.String prefix, boolean combineCommonPrefixes) operation enumerates the list of blobs with the given prefix under the specified container.
IBlobContainer::listBlobs(java.lang.String prefix, boolean combineCommonPrefixes, int maxResults) operation specifies the maximum number of blobs to return per call with the given prefix under the specified container.
BlobSample::listBlobsAll() lists all Blobs in a Container because it set prefix to empty string "" and combineCommonPrefixes to false.
------------------ List of Blobs in Container testcontainer1 Random_1/blob_5HECN.txt Random_1/blob_BTXX4.txt Random_1/blob_fKTWw.txt Random_1/blob_qHntG.txt Random_1/blob_spigl.txt Random_2/blob_MFh9N.txt Random_2/blob_RMHZl.txt Random_2/blob_Tzut8.txt Random_2/blob_oW3VA.txt Random_2/blob_wRukc.txt ------------------
| Java — List All Blobs in a Container | |
|---|---|
public static boolean listBlobsAll ( IBlobContainer objBlobContainer,
Collection<IBlobProperties> listBlobProperties,
boolean fPrintList
)
{
return BlobSample.listBlobs(objBlobContainer,
null, /* No prefix */
listBlobProperties,
fPrintList
);
}
| |
BlobSample::listBlobs() lists all Blobs in a Container that begins with a prefix.
------------------ List of Blobs with prefix 'Random_1/' in Container 'testcontainer1' Random_1/blob5HECN.txt Random_1/blobBTXX4.txt Random_1/blobFKTWW.txt Random_1/blobQHNTG.txt Random_1/blobSPIGL.txt ------------------ ------------------ List of Blobs with prefix 'Random_2/' in Container 'testcontainer1' Random_2/blobMFH9N.txt Random_2/blobOW3VA.txt Random_2/blobRMHZL.txt Random_2/blobTZUT8.txt Random_2/blobWRUKC.txt ------------------
| Java — List Blobs in a Container | |
|---|---|
public static boolean listBlobs ( IBlobContainer objBlobContainer,
String strPrefix,
Collection<IBlobProperties> listBlobProperties,
boolean fPrintList
)
{
boolean fSuccess = false;
if ( null == strPrefix ) {
strPrefix = "";
}
try {
Iterator<IBlobProperties> listBlobPropertiesTmp = null;
listBlobPropertiesTmp = objBlobContainer.listBlobs( strPrefix, false);
if (fPrintList) {
System.out.println("------------------");
if (null != listBlobPropertiesTmp && listBlobPropertiesTmp.hasNext()) {
if (strPrefix.isEmpty()) {
System.out.printf( "List of Blobs in Container '%s'\n",
objBlobContainer.getContainerName()
);
} else {
System.out.printf( "List of Blobs with prefix '%s' in Container '%s'\n",
strPrefix,
objBlobContainer.getContainerName()
);
}
while (listBlobPropertiesTmp.hasNext()) {
IBlobProperties objBlobProperties = listBlobPropertiesTmp.next();
System.out.println(objBlobProperties.getName());
if ( null != listBlobProperties) {
listBlobProperties.add(objBlobProperties);
}
}
} else {
System.out.printf( "No Blobs in Container %s\n",
objBlobContainer.getContainerName() );
}
System.out.println("------------------");
}
fSuccess = true;
} catch ( StorageException e ) {
e.printStackTrace();
} catch ( Exception e ) {
e.printStackTrace();
}
return fSuccess;
}
| |
The Blob service API includes operations to copy a blob from a source blob to a destination blob within the same storage account. This copies the whole blob, including the blob metadata, properties, and committed block list.
This enables applications to:
IBlobContainer::copyBlob(String destContainer, String destBlobName, String sourceBlobName) method is to copy a blob to a destination within the storage account.
When the source blob and destination blob are the same, BlobContainer::copyBlob() removes any uncommitted blocks.
IBlobContainer::copyBlob(String destContainer, String destBlobName, String sourceBlobName, NameValueCollection metadata, IBlobConstraints constraints) method can specify one or more new metadata values for the destination blob.
If metadata is specified in this case, the existing metadata is overwritten with the new metadata.
BlobSample::copyBlob() demonstartes using copy operation.
| Java — Copy Blob from Source to Destination Container | |
|---|---|
public static boolean copyBlob( BlobStorageClient objBlobStorage,
String strContainerSrc,
String strContainerDest,
String strBlobNameSrc,
String strBlobNameDest,
boolean fOverwriteDest
)
{
boolean fSuccess = false;
try {
/* Validate Source container exists */
IBlobContainer objBlobContainerSrc
= objBlobStorage.getBlobContainer(strContainerSrc);
if (null == objBlobContainerSrc || !objBlobContainerSrc.doesContainerExist()) {
throw new Exception(String.format( "Source Container '%s' does not exist",
strContainerSrc));
}
/* Validate Source blob exists */
if ( !objBlobContainerSrc.isBlobExist(strBlobNameSrc) ) {
throw new Exception(String.format( "Source Blob '%s' does not exist",
strBlobNameSrc));
}
/* Validate Destination container exists */
IBlobContainer objBlobContainerDest
= objBlobStorage.getBlobContainer(strContainerDest);
if (null == objBlobContainerDest || !objBlobContainerDest.doesContainerExist()) {
throw new Exception(String.format( "Destination Container '%s' does not exist",
strContainerSrc));
}
/* Validate if Destination blob exists and do not overwrite */
if ( objBlobContainerDest.isBlobExist(strBlobNameDest) && !fOverwriteDest ) {
throw new Exception( String.format("Destination Blob '%s' does exist and do not overwrite.",
strBlobNameSrc));
}
fSuccess = objBlobContainerSrc.copyBlob( strContainerDest,
strBlobNameDest,
strBlobNameSrc );
} catch ( StorageException e ) {
e.printStackTrace();
} catch ( Exception e ) {
e.printStackTrace();
}
return fSuccess;
}
| |
JUnit shows how BlobSample uses BlobContainer to copy a blob.
| JUnit — Copy Blob from Source to Destination Container | |
|---|---|
/*
* Test Copy Blob.
*/
public void testCopyBlob()
{
try {
boolean fSuccess = false;
String strContainerSrc = "testcontainerSrc";
String strContainerDest = "testcontainerDest";
String strBlobNameSrc = "testblobSrc";
String strBlobNameDest = "testblobDest";
/* * * * */
/* Copy source blob to destination blob */
fSuccess = BlobSample.copyBlob( m_objBlobStorage,
strContainerSrc,
strContainerDest,
strBlobNameSrc,
strBlobNameDest,
true
);
assertTrue(fSuccess);
/* Get destination blob */
byte[] binaryDataDest
= BlobSample.getBlobBinaryData( objBlobContainerDest,
strBlobNameDest
);
assertNotNull(binaryDataDest);
/* * * * */
| |
When creating a container, by default it is in private access mode. In other words, it is only accessible by the account owner and not available to anonymous users.
When a container is changed to public access mode, then the contents (blobs) of the container are available to anonymous users.
IBlobContainer::setAccessControl() sets the access control list (ACL) for the specified container. The ACL indicates whether blobs in a container may be accessed publicly.
Enum IContainerAccessControl provides values Public and Private for setting the ACL.
BlobSample::setBlobContainerACL() provides the option on setting a container's access to Public or Private.
| Java — Setting Access Control to a Container | |
|---|---|
import org.soyatec.windowsazure.blob.IContainerAccessControl;
/* * * * */
public static boolean setBlobContainer_wACL ( IBlobContainer objBlobContainer,
boolean fPublicAccess
)
throws IllegalArgumentException
{
boolean fSuccess = false;
if ( null == objBlobContainer || !objBlobContainer.isContainerExist() ) {
throw new IllegalArgumentException("BlobContainer parameter not defined!");
}
try {
IContainerAccessControl enumAccess
= fPublicAccess ? IContainerAccessControl.Public
: IContainerAccessControl.Private;
objBlobContainer.setAccessControl(enumAccess);
fSuccess = true;
} catch ( StorageException e ) {
e.printStackTrace();
} catch ( Exception e ) {
e.printStackTrace();
}
return fSuccess;
}
| |
In this lab, you have learned how to...