Skip to content

Commit

Permalink
Merge pull request Azure#392 from christav/dev
Browse files Browse the repository at this point in the history
BlobWriter implementation
  • Loading branch information
Chris Tavares committed Oct 16, 2012
2 parents d714960 + 0c05d74 commit ca93fd6
Show file tree
Hide file tree
Showing 6 changed files with 547 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@
*/
package com.microsoft.windowsazure.services.media;

import java.net.URI;

import com.microsoft.windowsazure.services.core.Configuration;
import com.microsoft.windowsazure.services.media.implementation.MediaBlobContainerWriter;
import com.microsoft.windowsazure.services.media.models.LocatorInfo;
import com.microsoft.windowsazure.services.media.models.LocatorType;
import com.sun.jersey.api.client.Client;

/**
*
Expand Down Expand Up @@ -64,4 +70,55 @@ public static MediaContract create(String profile) {
public static MediaContract create(String profile, Configuration config) {
return config.create(profile, MediaContract.class);
}

/**
* Creates an instance of the <code>WritableBlobContainerContract</code> API that will
* write to the blob container given by the provided locator.
*
* @param locator
* locator specifying where to upload to
* @return the implementation of <code>WritableBlobContainerContract</code>
*/
public static WritableBlobContainerContract createBlobWriter(LocatorInfo locator) {
if (locator.getLocatorType() != LocatorType.SAS) {
throw new IllegalArgumentException("Can only write to SAS locators");
}

LocatorParser p = new LocatorParser(locator);

return new MediaBlobContainerWriter(createUploaderClient(), p.getAccountName(), p.getStorageUri(),
p.getContainer(), p.getSASToken());
}

/**
* Helper class to encapsulate pulling information out of the locator.
*/
private static class LocatorParser {
URI locatorPath;

LocatorParser(LocatorInfo locator) {
locatorPath = URI.create(locator.getPath());
}

String getAccountName() {
return locatorPath.getHost().split("\\.")[0];
}

String getStorageUri() {
return locatorPath.getScheme() + "://" + locatorPath.getAuthority();
}

String getContainer() {
return locatorPath.getPath().substring(1);
}

String getSASToken() {
return locatorPath.getRawQuery();
}
}

private static Client createUploaderClient() {
Client client = Client.create();
return client;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
/**
* Copyright 2012 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.microsoft.windowsazure.services.media;

import java.io.InputStream;

import com.microsoft.windowsazure.services.blob.models.BlockList;
import com.microsoft.windowsazure.services.blob.models.CommitBlobBlocksOptions;
import com.microsoft.windowsazure.services.blob.models.CreateBlobBlockOptions;
import com.microsoft.windowsazure.services.blob.models.CreateBlobOptions;
import com.microsoft.windowsazure.services.blob.models.CreateBlobResult;
import com.microsoft.windowsazure.services.core.FilterableService;
import com.microsoft.windowsazure.services.core.ServiceException;

/**
* Contract for uploading media files to blob storage managed
* by Media Services.
*
*/
public interface WritableBlobContainerContract extends FilterableService<WritableBlobContainerContract> {

/**
* Creates a block blob from a content stream.
*
* @param container
* A {@link String} containing the name of the container to create the blob in.
* @param blob
* A {@link String} containing the name of the blob to create. A blob name can contain any combination of
* characters, but reserved URL characters must be properly escaped. A blob name must be at least one
* character long and cannot be more than 1,024 characters long, and must be unique within the container.
* @param contentStream
* An {@link InputStream} reference to the content stream to upload to the new blob.
* @throws ServiceException
* if an error occurs accessing the storage service.
*/
CreateBlobResult createBlockBlob(String blob, InputStream contentStream) throws ServiceException;

/**
* Creates a block blob from a content stream, using the specified options.
* <p>
* Use the {@link CreateBlobOptions options} parameter to optionally specify the server timeout for the operation,
* the MIME content type and content encoding for the blob, the content language, the MD5 hash, a cache control
* value, and blob metadata.
*
* @param blob
* A {@link String} containing the name of the blob to create. A blob name can contain any combination of
* characters, but reserved URL characters must be properly escaped. A blob name must be at least one
* character long and cannot be more than 1,024 characters long, and must be unique within the container.
* @param contentStream
* An {@link InputStream} reference to the content to upload to the new blob.
* @param options
* A {@link CreateBlobOptions} instance containing options for the request.
* @throws ServiceException
* if an error occurs accessing the storage service.
*/
CreateBlobResult createBlockBlob(String blob, InputStream contentStream, CreateBlobOptions options)
throws ServiceException;

/**
* Creates a new uncommited block from a content stream.
* <p>
* This method creates an uncommitted block for a block blob specified by the <em>blob</em> and <em>container</em>
* parameters. The <em>blockId</em> parameter is a client-specified ID for the block, which must be less than or
* equal to 64 bytes in size. For a given blob, the length of the value specified for the <em>blockId</em> parameter
* must be the same size for each block. The <em>contentStream</em> parameter specifies the content to be copied to
* the block. The content for the block must be less than or equal to 4 MB in size.
* <p>
* To create or update a block blob, the blocks that have been successfully written to the server with this method
* must be committed using a call to {@link WritableBlobContainerContract#commitBlobBlocks(String, BlockList)} or
* {@link WritableBlobContainerContract#commitBlobBlocks(String, BlockList, CommitBlobBlocksOptions)}.
*
* @param blob
* A {@link String} containing the name of the blob to create the block for.
* @param blockId
* A {@link String} containing a client-specified ID for the block.
* @param contentStream
* An {@link InputStream} reference to the content to copy to the block.
* @throws ServiceException
* if an error occurs accessing the storage service.
*/
void createBlobBlock(String blob, String blockId, InputStream contentStream) throws ServiceException;

/**
* Creates a new uncommitted block from a content stream, using the specified options.
* <p>
* This method creates an uncommitted block for a block blob specified by the <em>blob</em> and <em>container</em>
* parameters. The <em>blockId</em> parameter is a client-specified ID for the block, which must be less than or
* equal to 64 bytes in size. For a given blob, the length of the value specified for the <em>blockId</em> parameter
* must be the same size for each block. The <em>contentStream</em> parameter specifies the content to be copied to
* the block. The content for the block must be less than or equal to 4 MB in size. Use the
* {@link CreateBlobBlockOptions options} parameter to optionally specify the server timeout for the operation, the
* lease ID if the blob has an active lease, and the MD5 hash value for the block content.
* <p>
* To create or update a block blob, the blocks that have been successfully written to the server with this method
* must be committed using a call to {@link WritableBlobContainerContract#commitBlobBlocks(String, BlockList)} or
* {@link WritableBlobContainerContract#commitBlobBlocks(String, BlockList, CommitBlobBlocksOptions)}.
*
* @param blob
* A {@link String} containing the name of the blob to create the block for.
* @param blockId
* A {@link String} containing a client-specified ID for the block.
* @param contentStream
* An {@link InputStream} reference to the content to copy to the block.
* @param options
* A {@link CreateBlobBlockOptions} instance containing options for the request.
* @throws ServiceException
* if an error occurs accessing the storage service.
*/
void createBlobBlock(String blob, String blockId, InputStream contentStream, CreateBlobBlockOptions options)
throws ServiceException;

/**
* Commits a list of blocks to a block blob.
* <p>
* This method creates or updates the block blob specified by the <em>blob</em> and <em>container</em> parameters.
* You can call this method to update a blob by uploading only those blocks that have changed, then committing the
* new and existing blocks together. You can do this with the <em>blockList</em> parameter by specifying whether to
* commit a block from the committed block list or from the uncommitted block list, or to commit the most recently
* uploaded version of the block, whichever list it may belong to.
* <p>
* In order to be written as part of a blob, each block in the list must have been successfully written to the
* server with a call to {@link WritableBlobContainerContract#createBlobBlock(String, String, InputStream)} or
* {@link WritableBlobContainerContract#createBlobBlock(String, String, InputStream, CreateBlobBlockOptions)}.
*
* @param blob
* A {@link String} containing the name of the block blob to create or update.
* @param blockList
* A {@link BlockList} containing the list of blocks to commit to the block blob.
* @throws ServiceException
* if an error occurs accessing the storage service.
*/
void commitBlobBlocks(String blob, BlockList blockList) throws ServiceException;

/**
* Commits a block list to a block blob, using the specified options.
* <p>
* This method creates or updates the block blob specified by the <em>blob</em> and <em>container</em> parameters.
* You can call this method to update a blob by uploading only those blocks that have changed, then committing the
* new and existing blocks together. You can do this with the <em>blockList</em> parameter by specifying whether to
* commit a block from the committed block list or from the uncommitted block list, or to commit the most recently
* uploaded version of the block, whichever list it may belong to. Use the {@link CommitBlobBlocksOptions options}
* parameter to optionally specify the server timeout for the operation, the MIME content type and content encoding
* for the blob, the content language, the MD5 hash, a cache control value, blob metadata, the lease ID if the blob
* has an active lease, and any access conditions for the operation.
* <p>
* In order to be written as part of a blob, each block in the list must have been successfully written to the
* server with a call to {@link WritableBlobContainerContract#createBlobBlock(String, String, InputStream)} or
* {@link WritableBlobContainerContract#createBlobBlock(String, String, InputStream, CreateBlobBlockOptions)}.
*
* @param blob
* A {@link String} containing the name of the block blob to create or update.
* @param blockList
* A {@link BlockList} containing the list of blocks to commit to the block blob.
* @param options
* A {@link CommitBlobBlocksOptions} instance containing options for the request.
* @throws ServiceException
* if an error occurs accessing the storage service.
*/
void commitBlobBlocks(String blob, BlockList blockList, CommitBlobBlocksOptions options) throws ServiceException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/**
* Copyright 2012 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.microsoft.windowsazure.services.media.implementation;

import java.io.InputStream;

import com.microsoft.windowsazure.services.blob.BlobContract;
import com.microsoft.windowsazure.services.blob.implementation.BlobExceptionProcessor;
import com.microsoft.windowsazure.services.blob.models.BlockList;
import com.microsoft.windowsazure.services.blob.models.CommitBlobBlocksOptions;
import com.microsoft.windowsazure.services.blob.models.CreateBlobBlockOptions;
import com.microsoft.windowsazure.services.blob.models.CreateBlobOptions;
import com.microsoft.windowsazure.services.blob.models.CreateBlobResult;
import com.microsoft.windowsazure.services.core.ServiceException;
import com.microsoft.windowsazure.services.core.ServiceFilter;
import com.microsoft.windowsazure.services.media.WritableBlobContainerContract;
import com.sun.jersey.api.client.Client;

/**
* Implementation of WritableBlobContainerContract, used to upload blobs to the
* Media Services storage.
*
*/
public class MediaBlobContainerWriter implements WritableBlobContainerContract {

private final BlobContract blobService;
private final BlobContract restProxy;
private final String containerName;

/**
*
*/
public MediaBlobContainerWriter(Client client, String accountName, String blobServiceUri, String containerName,
String sasToken) {
this.containerName = containerName;
this.restProxy = new MediaBlobRestProxy(client, accountName, blobServiceUri, new SASTokenFilter(sasToken));
this.blobService = new BlobExceptionProcessor(this.restProxy);
}

private MediaBlobContainerWriter(MediaBlobContainerWriter baseWriter, ServiceFilter filter) {
this.containerName = baseWriter.containerName;
this.restProxy = baseWriter.restProxy.withFilter(filter);
this.blobService = new BlobExceptionProcessor(this.restProxy);
}

/* (non-Javadoc)
* @see com.microsoft.windowsazure.services.core.FilterableService#withFilter(com.microsoft.windowsazure.services.core.ServiceFilter)
*/
@Override
public WritableBlobContainerContract withFilter(ServiceFilter filter) {
return new MediaBlobContainerWriter(this, filter);
}

/* (non-Javadoc)
* @see com.microsoft.windowsazure.services.media.WritableBlobContainerContract#createBlockBlob(java.lang.String, java.io.InputStream)
*/
@Override
public CreateBlobResult createBlockBlob(String blob, InputStream contentStream) throws ServiceException {
return blobService.createBlockBlob(containerName, blob, contentStream);
}

/* (non-Javadoc)
* @see com.microsoft.windowsazure.services.media.WritableBlobContainerContract#createBlockBlob(java.lang.String, java.io.InputStream, com.microsoft.windowsazure.services.blob.models.CreateBlobOptions)
*/
@Override
public CreateBlobResult createBlockBlob(String blob, InputStream contentStream, CreateBlobOptions options)
throws ServiceException {
return blobService.createBlockBlob(containerName, blob, contentStream, options);
}

/* (non-Javadoc)
* @see com.microsoft.windowsazure.services.media.WritableBlobContainerContract#createBlobBlock(java.lang.String, java.lang.String, java.io.InputStream)
*/
@Override
public void createBlobBlock(String blob, String blockId, InputStream contentStream) throws ServiceException {
blobService.createBlobBlock(containerName, blob, blockId, contentStream);

}

/* (non-Javadoc)
* @see com.microsoft.windowsazure.services.media.WritableBlobContainerContract#createBlobBlock(java.lang.String, java.lang.String, java.io.InputStream, com.microsoft.windowsazure.services.blob.models.CreateBlobBlockOptions)
*/
@Override
public void createBlobBlock(String blob, String blockId, InputStream contentStream, CreateBlobBlockOptions options)
throws ServiceException {
blobService.createBlobBlock(containerName, blob, blockId, contentStream, options);
}

/* (non-Javadoc)
* @see com.microsoft.windowsazure.services.media.WritableBlobContainerContract#commitBlobBlocks(java.lang.String, com.microsoft.windowsazure.services.blob.models.BlockList)
*/
@Override
public void commitBlobBlocks(String blob, BlockList blockList) throws ServiceException {
blobService.commitBlobBlocks(containerName, blob, blockList);
}

/* (non-Javadoc)
* @see com.microsoft.windowsazure.services.media.WritableBlobContainerContract#commitBlobBlocks(java.lang.String, com.microsoft.windowsazure.services.blob.models.BlockList, com.microsoft.windowsazure.services.blob.models.CommitBlobBlocksOptions)
*/
@Override
public void commitBlobBlocks(String blob, BlockList blockList, CommitBlobBlocksOptions options)
throws ServiceException {
blobService.commitBlobBlocks(containerName, blob, blockList, options);
}
}
Loading

0 comments on commit ca93fd6

Please sign in to comment.