com.microsoft.azure.storage.AccessCondition Java Examples

The following examples show how to use com.microsoft.azure.storage.AccessCondition. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: BlobRequest.java    From azure-storage-android with Apache License 2.0 8 votes vote down vote up
/**
 * Generates a web request to abort a copy operation.
 * 
 * @param uri
 *            A <code>java.net.URI</code> object that specifies the absolute URI.
 * @param blobOptions
 *            A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout
 *            settings for the operation. Specify <code>null</code> to use the request options specified on the
 *            {@link CloudBlobClient}.
 * @param opContext
 *            An {@link OperationContext} object that represents the context for the current operation. This object
 *            is used to track requests to the storage service, and to provide additional runtime information about
 *            the operation.
 * @param accessCondition
 *            The access condition to apply to the request. Only lease conditions are supported for this operation.
 * @param copyId
 *            A <code>String</code> object that identifying the copy operation.
 * @return a HttpURLConnection configured for the operation.
 * @throws StorageException
 *             an exception representing any error which occurred during the operation.
 * @throws IllegalArgumentException
 * @throws IOException
 * @throws URISyntaxException
 */
public static HttpURLConnection abortCopy(final URI uri, final BlobRequestOptions blobOptions,
        final OperationContext opContext, final AccessCondition accessCondition, final String copyId)
        throws StorageException, IOException, URISyntaxException {

    final UriQueryBuilder builder = new UriQueryBuilder();

    builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.COPY);
    builder.add(Constants.QueryConstants.COPY_ID, copyId);

    final HttpURLConnection request = BaseRequest.createURLConnection(uri, blobOptions, builder, opContext);

    request.setFixedLengthStreamingMode(0);
    request.setDoOutput(true);
    request.setRequestMethod(Constants.HTTP_PUT);

    request.setRequestProperty(Constants.HeaderConstants.COPY_ACTION_HEADER,
            Constants.HeaderConstants.COPY_ACTION_ABORT);

    if (accessCondition != null) {
        accessCondition.applyLeaseConditionToRequest(request);
    }

    return request;
}
 
Example #2
Source File: AzureStorageService.java    From crate with Apache License 2.0 7 votes vote down vote up
public void writeBlob(String container, String blobName, InputStream inputStream, long blobSize,
                      boolean failIfAlreadyExists)
    throws URISyntaxException, StorageException, IOException {
    LOGGER.trace(() -> new ParameterizedMessage("writeBlob({}, stream, {})", blobName, blobSize));
    final Tuple<CloudBlobClient, Supplier<OperationContext>> client = client();
    final CloudBlobContainer blobContainer = client.v1().getContainerReference(container);
    final CloudBlockBlob blob = blobContainer.getBlockBlobReference(blobName);
    try {
        final AccessCondition accessCondition =
            failIfAlreadyExists ? AccessCondition.generateIfNotExistsCondition() : AccessCondition.generateEmptyCondition();
        blob.upload(inputStream, blobSize, accessCondition, null, client.v2().get());
    } catch (final StorageException se) {
        if (failIfAlreadyExists && se.getHttpStatusCode() == HttpURLConnection.HTTP_CONFLICT &&
            StorageErrorCodeStrings.BLOB_ALREADY_EXISTS.equals(se.getErrorCode())) {
            throw new FileAlreadyExistsException(blobName, null, se.getMessage());
        }
        throw se;
    }
    LOGGER.trace(() -> new ParameterizedMessage("writeBlob({}, stream, {}) - done", blobName, blobSize));
}
 
Example #3
Source File: CloudAppendBlobTests.java    From azure-storage-android with Apache License 2.0 6 votes vote down vote up
@Test
public void testAppendBlobMaxSizeCondition() throws URISyntaxException,
        StorageException, IOException {
    final int blobLength = 16 * 1024;

    String blobName = BlobTestHelper
            .generateRandomBlobNameWithPrefix("testblob");
    final CloudAppendBlob blobRef = this.container
            .getAppendBlobReference(blobName);

    final byte[] buff = BlobTestHelper.getRandomBuffer(blobLength);
    ByteArrayInputStream sourceStream = new ByteArrayInputStream(buff);
    
    // Max length position failure
    AccessCondition cond = new AccessCondition();
    cond.setIfMaxSizeLessThanOrEqual(blobLength - 1L);
    
    try {
        blobRef.upload(sourceStream, blobLength, cond, null, null);
        fail("Expected IOException for exceeding the max size");
    } catch (IOException ex) {
        assertEquals(SR.INVALID_BLOCK_SIZE, ex.getMessage());
    }
}
 
Example #4
Source File: CloudBlobContainer.java    From azure-storage-android with Apache License 2.0 6 votes vote down vote up
/**
 * Deletes the container if it exists using the specified request options and operation context.
 * 
 * @param accessCondition
 *            An {@link AccessCondition} object that represents the access conditions for the container.
 * @param options
 *            A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying
 *            <code>null</code> will use the default request options from the associated service client (
 *            {@link CloudBlobClient}).
 * @param opContext
 *            An {@link OperationContext} object that represents the context for the current operation. This object
 *            is used to track requests to the storage service, and to provide additional runtime information about
 *            the operation.
 * 
 * @return <code>true</code> if the container existed and was deleted; otherwise, <code>false</code>.
 * 
 * @throws StorageException
 *             If a storage service error occurred.
 */
@DoesServiceRequest
public boolean deleteIfExists(AccessCondition accessCondition, BlobRequestOptions options,
        OperationContext opContext) throws StorageException {
    options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.UNSPECIFIED, this.blobServiceClient);

    boolean exists = this.exists(true /* primaryOnly */, accessCondition, options, opContext);
    if (exists) {
        try {
            this.delete(accessCondition, options, opContext);
            return true;
        }
        catch (StorageException e) {
            if (e.getHttpStatusCode() == HttpURLConnection.HTTP_NOT_FOUND
                    && StorageErrorCodeStrings.CONTAINER_NOT_FOUND.equals(e.getErrorCode())) {
                return false;
            }
            else {
                throw e;
            }
        }
    }
    else {
        return false;
    }
}
 
Example #5
Source File: BlobRequest.java    From azure-storage-android with Apache License 2.0 6 votes vote down vote up
/**
 * Sets the ACL for the container. Sign with length of aclBytes.
 * 
 * @param uri
 *            A <code>java.net.URI</code> object that specifies the absolute URI.
 * @param blobOptions
 *            A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout
 *            settings for the operation. Specify <code>null</code> to use the request options specified on the
 *            {@link CloudBlobClient}.
 * @param opContext
 *            An {@link OperationContext} object that represents the context for the current operation. This object
 *            is used to track requests to the storage service, and to provide additional runtime information about
 *            the operation.
 * @param accessCondition
 *            An {@link AccessCondition} object that represents the access conditions for the container.
 * @param publicAccess
 *            The type of public access to allow for the container.
 * @return a HttpURLConnection configured for the operation.
 * @throws StorageException
 * */
public static HttpURLConnection setAcl(final URI uri, final BlobRequestOptions blobOptions,
        final OperationContext opContext, final AccessCondition accessCondition,
        final BlobContainerPublicAccessType publicAccess) throws IOException, URISyntaxException, StorageException {
    if (publicAccess == BlobContainerPublicAccessType.UNKNOWN) {
        throw new IllegalArgumentException(String.format(Utility.LOCALE_US, SR.ARGUMENT_OUT_OF_RANGE_ERROR, "accessType", publicAccess));
    }

    final UriQueryBuilder builder = getContainerUriQueryBuilder();
    builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.ACL);

    final HttpURLConnection request = createURLConnection(uri, builder, blobOptions, opContext);

    request.setRequestMethod(Constants.HTTP_PUT);
    request.setDoOutput(true);

    if (publicAccess != BlobContainerPublicAccessType.OFF) {
        request.setRequestProperty(BlobConstants.BLOB_PUBLIC_ACCESS_HEADER, publicAccess.toString().toLowerCase());
    }

    if (accessCondition != null) {
        accessCondition.applyLeaseConditionToRequest(request);
    }

    return request;
}
 
Example #6
Source File: BlobUtils.java    From samza with Apache License 2.0 6 votes vote down vote up
/**
 * Writes the job model to the blob.
 * Write is successful only if the lease ID passed is valid and the processor holds the lease.
 * Called by the leader.
 * @param prevJM Previous job model version that the processor was operating on.
 * @param currJM Current job model version that the processor is operating on.
 * @param prevJMV Previous job model version that the processor was operating on.
 * @param currJMV Current job model version that the processor is operating on.
 * @param leaseId LeaseID of the lease that the processor holds on the blob. Null if there is no lease.
 * @return true if write to the blob is successful, false if leaseID is null or an Azure storage service error or IO exception occurred.
 */
public boolean publishJobModel(JobModel prevJM, JobModel currJM, String prevJMV, String currJMV, String leaseId) {
  try {
    if (leaseId == null) {
      return false;
    }
    JobModelBundle bundle = new JobModelBundle(prevJM, currJM, prevJMV, currJMV);
    byte[] data = SamzaObjectMapper.getObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsBytes(bundle);
    byte[] pageData = Arrays.copyOf(data, (int) JOB_MODEL_BLOCK_SIZE);
    InputStream is = new ByteArrayInputStream(pageData);
    blob.uploadPages(is, 0, JOB_MODEL_BLOCK_SIZE, AccessCondition.generateLeaseCondition(leaseId), null, null);
    LOG.info("Uploaded {} jobModel to blob", bundle.getCurrJobModel());
    return true;
  } catch (StorageException | IOException e) {
    LOG.error("JobModel publish failed for version = " + currJMV, e);
    return false;
  }
}
 
Example #7
Source File: LeaseTests.java    From azure-storage-android with Apache License 2.0 6 votes vote down vote up
@Test
public void testBlobLeaseAcquireAndRelease() throws URISyntaxException, StorageException, IOException {
    final int length = 128;
    final CloudBlob blobRef = BlobTestHelper.uploadNewBlob(this.container, BlobType.BLOCK_BLOB, "test", 128, null);

    // Get Lease 
    OperationContext operationContext = new OperationContext();
    final String leaseID = blobRef.acquireLease(15, null /*proposed lease id */, null /*access condition*/,
            null/* BlobRequestOptions */, operationContext);
    final AccessCondition leaseCondition = AccessCondition.generateLeaseCondition(leaseID);
    assertTrue(operationContext.getLastResult().getStatusCode() == HttpURLConnection.HTTP_CREATED);

    tryUploadWithBadLease(length, blobRef, null, StorageErrorCodeStrings.LEASE_ID_MISSING);

    // Try to upload with lease
    blobRef.upload(BlobTestHelper.getRandomDataStream(length), -1, leaseCondition, null, null);

    // Release lease
    blobRef.releaseLease(leaseCondition);

    // now upload with no lease specified.
    blobRef.upload(BlobTestHelper.getRandomDataStream(length), -1);
}
 
Example #8
Source File: CloudBlockBlobTests.java    From azure-storage-android with Apache License 2.0 6 votes vote down vote up
@Test
public void testBlobUploadFromStreamAccessConditionTest() throws URISyntaxException, StorageException, IOException {
    final String blockBlobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob");
    final CloudBlockBlob blockBlobRef = this.container.getBlockBlobReference(blockBlobName);
    AccessCondition accessCondition = AccessCondition.generateIfNotModifiedSinceCondition(new Date());

    int length = 2 * 1024;
    ByteArrayInputStream srcStream = BlobTestHelper.getRandomDataStream(length);
    blockBlobRef.upload(srcStream, -1, accessCondition, null, null);
    ByteArrayOutputStream dstStream = new ByteArrayOutputStream();
    blockBlobRef.download(dstStream);
    BlobTestHelper.assertStreamsAreEqual(srcStream, new ByteArrayInputStream(dstStream.toByteArray()));

    length = 5 * 1024 * 1024;
    srcStream = BlobTestHelper.getRandomDataStream(length);
    blockBlobRef.upload(srcStream, length);
    dstStream = new ByteArrayOutputStream();
    blockBlobRef.download(dstStream);
    BlobTestHelper.assertStreamsAreEqual(srcStream, new ByteArrayInputStream(dstStream.toByteArray()));
}
 
Example #9
Source File: BlobOutputStream.java    From azure-storage-android with Apache License 2.0 6 votes vote down vote up
/**
 * Initializes a new instance of the BlobOutputStream class for a CloudAppendBlob
 * 
 * @param parentBlob
 *            A {@link CloudAppendBlob} object which represents the blob that this stream is associated with.
 * @param accessCondition
 *            An {@link AccessCondition} object which represents the access conditions for the blob.
 * @param options
 *            A {@link BlobRequestOptions} object which specifies any additional options for the request
 * @param opContext
 *            An {@link OperationContext} object which is used to track the execution of the operation
 * 
 * @throws StorageException
 *             An exception representing any error which occurred during the operation.
 */
@DoesServiceRequest
protected BlobOutputStream(final CloudAppendBlob parentBlob, final AccessCondition accessCondition, 
        final BlobRequestOptions options, final OperationContext opContext)
        throws StorageException {
    this((CloudBlob)parentBlob, accessCondition, options, opContext);
    this.streamType = BlobType.APPEND_BLOB;
    
    this.accessCondition = accessCondition != null ? accessCondition : new AccessCondition();
    if (this.accessCondition.getIfAppendPositionEqual() != null) {
        this.currentBlobOffset = this.accessCondition.getIfAppendPositionEqual();
    } 
    else {
        // If this is an existing blob, we've done a downloadProperties to get the length
        // If this is a new blob, getLength will correctly return 0
        this.currentBlobOffset = parentBlob.getProperties().getLength();
    }
    
    this.internalWriteThreshold = this.parentBlobRef.getStreamWriteSizeInBytes();
}
 
Example #10
Source File: CloudFileDirectory.java    From azure-storage-android with Apache License 2.0 6 votes vote down vote up
/**
 * Deletes the directory if it exists using the specified request options and operation context.
 * 
 * @param accessCondition
 *            An {@link AccessCondition} object that represents the access conditions for the directory.
 * @param options
 *            A {@link FileRequestOptions} object that specifies any additional options for the request. Specifying
 *            <code>null</code> will use the default request options from the associated service client (
 *            {@link CloudFileClient}).
 * @param opContext
 *            An {@link OperationContext} object that represents the context for the current operation. This object
 *            is used to track requests to the storage service, and to provide additional runtime information about
 *            the operation.
 * 
 * @return <code>true</code> if the directory existed and was deleted; otherwise, <code>false</code>.
 * 
 * @throws StorageException
 *             If a storage service error occurred.
 * @throws URISyntaxException 
 */
@DoesServiceRequest
public boolean deleteIfExists(AccessCondition accessCondition, FileRequestOptions options,
        OperationContext opContext) throws StorageException, URISyntaxException {
    options = FileRequestOptions.populateAndApplyDefaults(options, this.fileServiceClient);

    boolean exists = this.exists(true /* primaryOnly */, accessCondition, options, opContext);
    if (exists) {
        try {
            this.delete(accessCondition, options, opContext);
            return true;
        }
        catch (StorageException e) {
            if (e.getHttpStatusCode() == HttpURLConnection.HTTP_NOT_FOUND
                    && StorageErrorCodeStrings.RESOURCE_NOT_FOUND.equals(e.getErrorCode())) {
                return false;
            }
            else {
                throw e;
            }
        }
    }
    else {
        return false;
    }
}
 
Example #11
Source File: FileRequest.java    From azure-storage-android with Apache License 2.0 6 votes vote down vote up
/**
 * Generates a web request to abort a copy operation.
 * 
 * @param uri
 *            A <code>java.net.URI</code> object that specifies the absolute URI.
 * @param fileOptions
 *            A {@link FileRequestOptions} object that specifies execution options such as retry policy and timeout
 *            settings for the operation. Specify <code>null</code> to use the request options specified on the
 *            {@link CloudFileClient}.
 * @param opContext
 *            An {@link OperationContext} object that represents the context for the current operation. This object
 *            is used to track requests to the storage service, and to provide additional runtime information about
 *            the operation.
 * @param accessCondition
 *            The access condition to apply to the request. Only lease conditions are supported for this operation.
 * @param copyId
 *            A <code>String</code> object that identifying the copy operation.
 * @return a <code>HttpURLConnection</code> configured for the operation.
 * @throws StorageException
 *             An exception representing any error which occurred during the operation.
 * @throws IllegalArgumentException
 * @throws IOException
 * @throws URISyntaxException
 */
public static HttpURLConnection abortCopy(final URI uri, final FileRequestOptions fileOptions,
        final OperationContext opContext, final AccessCondition accessCondition, final String copyId)
        throws StorageException, IOException, URISyntaxException {

    final UriQueryBuilder builder = new UriQueryBuilder();

    builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.COPY);
    builder.add(Constants.QueryConstants.COPY_ID, copyId);

    final HttpURLConnection request = BaseRequest.createURLConnection(uri, fileOptions, builder, opContext);

    request.setFixedLengthStreamingMode(0);
    request.setDoOutput(true);
    request.setRequestMethod(Constants.HTTP_PUT);

    request.setRequestProperty(Constants.HeaderConstants.COPY_ACTION_HEADER,
            Constants.HeaderConstants.COPY_ACTION_ABORT);

    if (accessCondition != null) {
        accessCondition.applyConditionToRequest(request);
    }

    return request;
}
 
Example #12
Source File: BlobRequest.java    From azure-storage-android with Apache License 2.0 6 votes vote down vote up
/**
 * Constructs a web request to return the ACL for this container. Sign with no length specified.
 * 
 * @param uri
 *            The absolute URI to the container.
 * @param timeout
 *            The server timeout interval.
 * @param accessCondition
 *            An {@link AccessCondition} object that represents the access conditions for the container.
 * @param opContext
 *            An {@link OperationContext} object that represents the context for the current operation. This object
 *            is used to track requests to the storage service, and to provide additional runtime information about
 *            the operation.
 * @return a HttpURLConnection configured for the operation.
 * @throws StorageException
 */
public static HttpURLConnection getAcl(final URI uri, final BlobRequestOptions blobOptions,
        final AccessCondition accessCondition, final OperationContext opContext) throws IOException,
        URISyntaxException, StorageException {
    final UriQueryBuilder builder = getContainerUriQueryBuilder();
    builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.ACL);

    final HttpURLConnection request = createURLConnection(uri, builder, blobOptions, opContext);

    request.setRequestMethod(Constants.HTTP_GET);

    if (accessCondition != null) {
        accessCondition.applyLeaseConditionToRequest(request);
    }

    return request;
}
 
Example #13
Source File: NativeAzureFileSystemBaseTest.java    From hadoop with Apache License 2.0 5 votes vote down vote up
@Test
// Acquire and free a Lease object. Wait for more than the lease
// timeout, to make sure the lease renews itself.
public void testSelfRenewingLease() throws IllegalArgumentException, IOException,
  InterruptedException, StorageException {

  SelfRenewingLease lease;
  final String FILE_KEY = "file";
  fs.create(new Path(FILE_KEY));
  NativeAzureFileSystem nfs = (NativeAzureFileSystem) fs;
  String fullKey = nfs.pathToKey(nfs.makeAbsolute(new Path(FILE_KEY)));
  AzureNativeFileSystemStore store = nfs.getStore();
  lease = store.acquireLease(fullKey);
  assertTrue(lease.getLeaseID() != null);

  // The sleep time for the keep-alive thread is 40 seconds, so sleep just
  // a little beyond that, to make sure the keep-alive thread wakes up
  // and renews the lease.
  Thread.sleep(42000);
  lease.free();

  // Check that the lease is really freed.
  CloudBlob blob = lease.getCloudBlob();

  // Try to acquire it again, using direct Azure blob access.
  // If that succeeds, then the lease was already freed.
  String differentLeaseID = null;
  try {
    differentLeaseID = blob.acquireLease(15, null);
  } catch (Exception e) {
    e.printStackTrace();
    fail("Caught exception trying to directly re-acquire lease from Azure");
  } finally {
    assertTrue(differentLeaseID != null);
    AccessCondition accessCondition = AccessCondition.generateEmptyCondition();
    accessCondition.setLeaseID(differentLeaseID);
    blob.releaseLease(accessCondition);
  }
}
 
Example #14
Source File: SelfRenewingLease.java    From big-c with Apache License 2.0 5 votes vote down vote up
/**
 * Free the lease and stop the keep-alive thread.
 * @throws StorageException
 */
public void free() throws StorageException {
  AccessCondition accessCondition = AccessCondition.generateEmptyCondition();
  accessCondition.setLeaseID(leaseID);
  try {
    blobWrapper.getBlob().releaseLease(accessCondition);
  } catch (StorageException e) {
    if (e.getErrorCode().equals("BlobNotFound")) {

      // Don't do anything -- it's okay to free a lease
      // on a deleted file. The delete freed the lease
      // implicitly.
    } else {

      // This error is not anticipated, so re-throw it.
      LOG.warn("Unanticipated exception when trying to free lease " + leaseID
          + " on " +  blobWrapper.getStorageUri());
      throw(e);
    }
  } finally {

    // Even if releasing the lease fails (e.g. because the file was deleted),
    // make sure to record that we freed the lease, to terminate the
    // keep-alive thread.
    leaseFreed = true;
    LOG.debug("Freed lease " + leaseID + " on " + blobWrapper.getUri()
        + " managed by thread " + renewer.getName());
  }
}
 
Example #15
Source File: LeaseBlobManager.java    From samza with Apache License 2.0 5 votes vote down vote up
/**
 * Releases the lease on the blob.
 * @param leaseId ID of the lease to be released.
 * @return True if released successfully, false otherwise.
 */
public boolean releaseLease(String leaseId) {
  try {
    leaseBlob.releaseLease(AccessCondition.generateLeaseCondition(leaseId));
    return true;
  } catch (StorageException storageException) {
    LOG.error("Wasn't able to release lease with lease id: " + leaseId, storageException);
    return false;
  }
}
 
Example #16
Source File: LeaseBlobManager.java    From samza with Apache License 2.0 5 votes vote down vote up
/**
 * Renews the lease on the blob.
 * @param leaseId ID of the lease to be renewed.
 * @return True if lease was renewed successfully, false otherwise.
 */
public boolean renewLease(String leaseId) {
  try {
    leaseBlob.renewLease(AccessCondition.generateLeaseCondition(leaseId));
    return true;
  } catch (StorageException storageException) {
    LOG.error("Wasn't able to renew lease with lease id: " + leaseId, storageException);
    return false;
  }
}
 
Example #17
Source File: LeaseTests.java    From azure-storage-android with Apache License 2.0 5 votes vote down vote up
/**
 * Try to upload with a bad lease
 * 
 * @param length
 * @param blobRef
 * @throws IOException
 */
private void tryUploadWithBadLease(final int length, final CloudBlob blobRef, final AccessCondition leaseCondition,
        final String expectedError) throws IOException {
    try {
        blobRef.upload(BlobTestHelper.getRandomDataStream(length), -1, leaseCondition, null, null);
        fail("Did not throw expected exception");
    }
    catch (final StorageException ex) {
        assertEquals(ex.getHttpStatusCode(), 412);
        assertEquals(ex.getErrorCode(), expectedError);
    }
}
 
Example #18
Source File: CloudBlob.java    From azure-storage-android with Apache License 2.0 5 votes vote down vote up
/**
 * Deletes the blob if it exists, using the specified snapshot and request options, and operation context.
 * <p>
 * A blob that has snapshots cannot be deleted unless the snapshots are also deleted. If a blob has snapshots, use
 * the {@link DeleteSnapshotsOption#DELETE_SNAPSHOTS_ONLY} or {@link DeleteSnapshotsOption#INCLUDE_SNAPSHOTS} value
 * in the <code>deleteSnapshotsOption</code> parameter to specify how the snapshots should be handled when the blob
 * is deleted.
 *
 * @param deleteSnapshotsOption
 *            A {@link DeleteSnapshotsOption} object that indicates whether to delete only snapshots, or the blob
 *            and its snapshots.
 * @param accessCondition
 *            An {@link AccessCondition} object that represents the access conditions for the blob.
 * @param options
 *            A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying
 *            <code>null</code> will use the default request options from the associated service client (
 *            {@link CloudBlobClient}).
 * @param opContext
 *            An {@link OperationContext} object that represents the context for the current operation. This object
 *            is used to track requests to the storage service, and to provide additional runtime information about
 *            the operation.
 *
 * @return <code>true</code> if the blob existed and was deleted; otherwise, <code>false</code>
 *
 * @throws StorageException
 *             If a storage service error occurred.
 */
@DoesServiceRequest
public final boolean deleteIfExists(final DeleteSnapshotsOption deleteSnapshotsOption,
        final AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext)
        throws StorageException {
    options = BlobRequestOptions.populateAndApplyDefaults(options, this.properties.getBlobType(), this.blobServiceClient);

    boolean exists = this.exists(true, accessCondition, options, opContext);
    if (exists) {
        try {
            this.delete(deleteSnapshotsOption, accessCondition, options, opContext);
            return true;
        }
        catch (StorageException e) {
            if (e.getHttpStatusCode() == HttpURLConnection.HTTP_NOT_FOUND
                    && StorageErrorCodeStrings.BLOB_NOT_FOUND.equals(e.getErrorCode())) {
                return false;
            }
            else {
                throw e;
            }
        }

    }
    else {
        return false;
    }
}
 
Example #19
Source File: CloudBlockBlobTests.java    From azure-storage-android with Apache License 2.0 5 votes vote down vote up
/**
 * Create a block blob.
 *
 * @throws StorageException
 * @throws URISyntaxException
 * @throws IOException
 */
@Test
@Category({ DevFabricTests.class, DevStoreTests.class })
public void testBlockBlobCreate() throws StorageException, URISyntaxException, IOException {
    final CloudBlockBlob blob = this.container.getBlockBlobReference(BlobTestHelper
            .generateRandomBlobNameWithPrefix("testBlob"));

    assertFalse(blob.exists());

    // Create
    blob.uploadText("text");
    assertTrue(blob.exists());

    // Create again (should succeed)
    blob.uploadText("text");
    assertTrue(blob.exists());

    // Create again, specifying not to if it already exists
    // This should fail
    // Add 15 min to account for clock skew
    Calendar cal = Calendar.getInstance();
    cal.setTime(new Date());
    cal.add(Calendar.MINUTE, 15);
    AccessCondition condition = new AccessCondition();
    condition.setIfModifiedSinceDate(cal.getTime());

    try {
        blob.uploadText("text", null, condition, null, null);
        fail("Create should fail do to access condition.");
    } catch (StorageException ex) {
        assertEquals(HttpURLConnection.HTTP_PRECON_FAILED, ex.getHttpStatusCode());
        assertEquals("The condition specified using HTTP conditional header(s) is not met.", ex.getMessage());
        assertEquals("ConditionNotMet", ex.getErrorCode());
    }
}
 
Example #20
Source File: CloudBlockBlobTests.java    From azure-storage-android with Apache License 2.0 5 votes vote down vote up
@Test
@Category({ DevFabricTests.class, DevStoreTests.class })
public void testBlobMultiConditionHeaders() throws URISyntaxException, StorageException, IOException {
    final String blockBlobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob");
    final CloudBlockBlob blockBlobRef = this.container.getBlockBlobReference(blockBlobName);

    final int length = 2 * 1024;
    ByteArrayInputStream srcStream = BlobTestHelper.getRandomDataStream(length);
    OperationContext context = new OperationContext();
    blockBlobRef.upload(srcStream, -1, null, null, context);

    AccessCondition condition = AccessCondition.generateIfMatchCondition(context.getLastResult().getEtag());
    condition.setIfUnmodifiedSinceDate(context.getLastResult().getStartDate());

    StorageEvent<SendingRequestEvent> event = new StorageEvent<SendingRequestEvent>() {

        @Override
        public void eventOccurred(SendingRequestEvent eventArg) {
            HttpURLConnection connection = (HttpURLConnection) eventArg.getConnectionObject();
            assertNotNull(connection.getRequestProperty("If-Unmodified-Since"));
            assertNotNull(connection.getRequestProperty("If-Match"));
        }
    };

    context.getSendingRequestEventHandler().addListener(event);

    blockBlobRef.upload(srcStream, -1, condition, null, context);
}
 
Example #21
Source File: BlobRequest.java    From azure-storage-android with Apache License 2.0 5 votes vote down vote up
/**
 * Constructs a HttpURLConnection to Acquire,Release,Break, or Renew a blob/container lease. Sign with 0 length.
 * 
 * @param uri
 *            A <code>java.net.URI</code> object that specifies the absolute URI.
 * @param blobOptions
 *            A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout
 *            settings for the operation. Specify <code>null</code> to use the request options specified on the
 *            {@link CloudBlobClient}.
 * @param opContext
 *            An {@link OperationContext} object that represents the context for the current operation. This object
 *            is used to track requests to the storage service, and to provide additional runtime information about
 *            the operation.
 * @param accessCondition
 *            An {@link AccessCondition} object that represents the access conditions for the blob.
 * @param action
 *            the LeaseAction to perform
 * @param proposedLeaseId
 *            A <code>String</code> that represents the proposed lease ID for the new lease,
 *            or null if no lease ID is proposed.
 * @param breakPeriodInSeconds
 *            Specifies the amount of time to allow the lease to remain, in seconds.
 *            If null, the break period is the remainder of the current lease, or zero for infinite leases.
 * @param visibilityTimeoutInSeconds
 *            Specifies the the span of time for which to acquire the lease, in seconds.
 *            If null, an infinite lease will be acquired. If not null, this must be greater than zero.
 * @return a HttpURLConnection to use to perform the operation.
 * @throws IOException
 *             if there is an error opening the connection
 * @throws URISyntaxException
 *             if the resource URI is invalid
 * @throws StorageException
 *             an exception representing any error which occurred during the operation.
 * @throws IllegalArgumentException
 */
private static HttpURLConnection lease(final URI uri, final BlobRequestOptions blobOptions,
        final OperationContext opContext, final AccessCondition accessCondition, final LeaseAction action,
        final Integer leaseTimeInSeconds, final String proposedLeaseId, final Integer breakPeriodInSeconds,
        final UriQueryBuilder builder) throws IOException, URISyntaxException, StorageException {
    final HttpURLConnection request = createURLConnection(uri, builder, blobOptions, opContext);

    request.setDoOutput(true);
    request.setRequestMethod(Constants.HTTP_PUT);
    request.setFixedLengthStreamingMode(0);
    request.setRequestProperty(HeaderConstants.LEASE_ACTION_HEADER, action.toString());

    // Lease duration should only be sent for acquire.
    if (action == LeaseAction.ACQUIRE) {
        // Assert lease duration is in bounds
        if (leaseTimeInSeconds != null && leaseTimeInSeconds != -1) {
            Utility.assertInBounds("leaseTimeInSeconds", leaseTimeInSeconds, Constants.LEASE_DURATION_MIN,
                    Constants.LEASE_DURATION_MAX);
        }

        request.setRequestProperty(HeaderConstants.LEASE_DURATION, leaseTimeInSeconds == null ? "-1"
                : leaseTimeInSeconds.toString());
    }

    if (proposedLeaseId != null) {
        request.setRequestProperty(HeaderConstants.PROPOSED_LEASE_ID_HEADER, proposedLeaseId);
    }

    if (breakPeriodInSeconds != null) {
        // Assert lease break period is in bounds
        Utility.assertInBounds("breakPeriodInSeconds", breakPeriodInSeconds, Constants.LEASE_BREAK_PERIOD_MIN,
                Constants.LEASE_BREAK_PERIOD_MAX);
        request.setRequestProperty(HeaderConstants.LEASE_BREAK_PERIOD_HEADER, breakPeriodInSeconds.toString());
    }

    if (accessCondition != null) {
        accessCondition.applyConditionToRequest(request);
    }
    return request;
}
 
Example #22
Source File: BlobRequest.java    From azure-storage-android with Apache License 2.0 5 votes vote down vote up
/**
 * Constructs a HttpURLConnection to delete the blob, Sign with no length specified.
 * 
 * @param uri
 *            A <code>java.net.URI</code> object that specifies the absolute URI.
 * @param blobOptions
 *            A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout
 *            settings for the operation. Specify <code>null</code> to use the request options specified on the
 *            {@link CloudBlobClient}.
 * @param opContext
 *            An {@link OperationContext} object that represents the context for the current operation. This object
 *            is used to track requests to the storage service, and to provide additional runtime information about
 *            the operation.
 * @param accessCondition
 *            An {@link AccessCondition} object that represents the access conditions for the blob.
 * @param snapshotVersion
 *            The snapshot version, if the blob is a snapshot.
 * @param deleteSnapshotsOption
 *            A set of options indicating whether to delete only blobs, only snapshots, or both.
 * @return a HttpURLConnection to use to perform the operation.
 * @throws IOException
 *             if there is an error opening the connection
 * @throws URISyntaxException
 *             if the resource URI is invalid
 * @throws StorageException
 *             an exception representing any error which occurred during the operation.
 * @throws IllegalArgumentException
 */
public static HttpURLConnection deleteBlob(final URI uri, final BlobRequestOptions blobOptions,
        final OperationContext opContext, final AccessCondition accessCondition, final String snapshotVersion,
        final DeleteSnapshotsOption deleteSnapshotsOption) throws IOException, URISyntaxException, StorageException {

    if (snapshotVersion != null && deleteSnapshotsOption != DeleteSnapshotsOption.NONE) {
        throw new IllegalArgumentException(String.format(SR.DELETE_SNAPSHOT_NOT_VALID_ERROR,
                "deleteSnapshotsOption", "snapshot"));
    }

    final UriQueryBuilder builder = new UriQueryBuilder();
    BlobRequest.addSnapshot(builder, snapshotVersion);
    final HttpURLConnection request = BaseRequest.delete(uri, blobOptions, builder, opContext);

    if (accessCondition != null) {
        accessCondition.applyConditionToRequest(request);
    }

    switch (deleteSnapshotsOption) {
        case NONE:
            // nop
            break;
        case INCLUDE_SNAPSHOTS:
            request.setRequestProperty(Constants.HeaderConstants.DELETE_SNAPSHOT_HEADER,
                    BlobConstants.INCLUDE_SNAPSHOTS_VALUE);
            break;
        case DELETE_SNAPSHOTS_ONLY:
            request.setRequestProperty(Constants.HeaderConstants.DELETE_SNAPSHOT_HEADER,
                    BlobConstants.SNAPSHOTS_ONLY_VALUE);
            break;
        default:
            break;
    }

    return request;
}
 
Example #23
Source File: BlobOutputStream.java    From azure-storage-android with Apache License 2.0 5 votes vote down vote up
/**
 * Initializes a new instance of the BlobOutputStream class.
 * 
 * @param parentBlob
 *            A {@link CloudBlob} object which represents the blob that this stream is associated with.
 * @param accessCondition
 *            An {@link AccessCondition} object which represents the access conditions for the blob.
 * @param options
 *            A {@link BlobRequestOptions} object which specifies any additional options for the request.
 * @param opContext
 *            An {@link OperationContext} object which is used to track the execution of the operation.
 * 
 * @throws StorageException
 *             An exception representing any error which occurred during the operation.
 */
private BlobOutputStream(final CloudBlob parentBlob, final AccessCondition accessCondition,
        final BlobRequestOptions options, final OperationContext opContext) throws StorageException {
    this.accessCondition = accessCondition;
    this.parentBlobRef = parentBlob;
    this.parentBlobRef.assertCorrectBlobType();
    this.options = new BlobRequestOptions(options);
    this.outBuffer = new ByteArrayOutputStream();
    this.opContext = opContext;

    if (this.options.getConcurrentRequestCount() < 1) {
        throw new IllegalArgumentException("ConcurrentRequestCount");
    }
    
    this.futureSet = Collections.newSetFromMap(new ConcurrentHashMap<Future<Void>, Boolean>(
            this.options.getConcurrentRequestCount() == null ? 1 : this.options.getConcurrentRequestCount() * 2));

    if (this.options.getStoreBlobContentMD5()) {
        try {
            this.md5Digest = MessageDigest.getInstance("MD5");
        }
        catch (final NoSuchAlgorithmException e) {
            // This wont happen, throw fatal.
            throw Utility.generateNewUnexpectedStorageException(e);
        }
    }

    // V2 cachedThreadPool for perf.        
    this.threadExecutor = new ThreadPoolExecutor(
            this.options.getConcurrentRequestCount(),
            this.options.getConcurrentRequestCount(),
            10, 
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>());
    this.completionService = new ExecutorCompletionService<Void>(this.threadExecutor);
}
 
Example #24
Source File: FileOutputStream.java    From azure-storage-android with Apache License 2.0 5 votes vote down vote up
/**
 * Initializes a new instance of the FileOutputStream class.
 * 
 * @param parentFile
 *            A {@link CloudFile} object which represents the file that this stream is associated with.
 * @param length
 *            A <code>long</code> which represents the length of the file in bytes.
 * @param accessCondition
 *            An {@link AccessCondition} object which represents the access conditions for the file.
 * @param options
 *            A {@link FileRequestOptions} object which specifies any additional options for the request.
 * @param opContext
 *            An {@link OperationContext} object which is used to track the execution of the operation
 * 
 * @throws StorageException
 *             An exception representing any error which occurred during the operation.
 */
@DoesServiceRequest
protected FileOutputStream(final CloudFile parentFile, final long length, final AccessCondition accessCondition,
        final FileRequestOptions options, final OperationContext opContext) throws StorageException {
    this.accessCondition = accessCondition;
    this.parentFileRef = parentFile;
    this.options = new FileRequestOptions(options);
    this.outBuffer = new ByteArrayOutputStream();
    this.opContext = opContext;
    this.streamFaulted = false;

    if (this.options.getConcurrentRequestCount() < 1) {
        throw new IllegalArgumentException("ConcurrentRequestCount");
    }

    if (this.options.getStoreFileContentMD5()) {
        try {
            this.md5Digest = MessageDigest.getInstance("MD5");
        }
        catch (final NoSuchAlgorithmException e) {
            // This wont happen, throw fatal.
            throw Utility.generateNewUnexpectedStorageException(e);
        }
    }

    // V2 cachedThreadPool for perf.
    this.threadExecutor = Executors.newFixedThreadPool(this.options.getConcurrentRequestCount());
    this.completionService = new ExecutorCompletionService<Void>(this.threadExecutor);
    this.internalWriteThreshold = (int) Math.min(this.parentFileRef.getStreamWriteSizeInBytes(), length);
}
 
Example #25
Source File: NativeAzureFileSystemBaseTest.java    From big-c with Apache License 2.0 5 votes vote down vote up
@Test
// Acquire and free a Lease object. Wait for more than the lease
// timeout, to make sure the lease renews itself.
public void testSelfRenewingLease() throws IllegalArgumentException, IOException,
  InterruptedException, StorageException {

  SelfRenewingLease lease;
  final String FILE_KEY = "file";
  fs.create(new Path(FILE_KEY));
  NativeAzureFileSystem nfs = (NativeAzureFileSystem) fs;
  String fullKey = nfs.pathToKey(nfs.makeAbsolute(new Path(FILE_KEY)));
  AzureNativeFileSystemStore store = nfs.getStore();
  lease = store.acquireLease(fullKey);
  assertTrue(lease.getLeaseID() != null);

  // The sleep time for the keep-alive thread is 40 seconds, so sleep just
  // a little beyond that, to make sure the keep-alive thread wakes up
  // and renews the lease.
  Thread.sleep(42000);
  lease.free();

  // Check that the lease is really freed.
  CloudBlob blob = lease.getCloudBlob();

  // Try to acquire it again, using direct Azure blob access.
  // If that succeeds, then the lease was already freed.
  String differentLeaseID = null;
  try {
    differentLeaseID = blob.acquireLease(15, null);
  } catch (Exception e) {
    e.printStackTrace();
    fail("Caught exception trying to directly re-acquire lease from Azure");
  } finally {
    assertTrue(differentLeaseID != null);
    AccessCondition accessCondition = AccessCondition.generateEmptyCondition();
    accessCondition.setLeaseID(differentLeaseID);
    blob.releaseLease(accessCondition);
  }
}
 
Example #26
Source File: LeaseTests.java    From azure-storage-android with Apache License 2.0 4 votes vote down vote up
@Test
public void testBlobLeaseChange() throws StorageException, IOException, URISyntaxException {
    final int length = 128;
    final CloudBlob blobRef = BlobTestHelper.uploadNewBlob(this.container, BlobType.BLOCK_BLOB, "test", 128, null);

    // Get Lease 
    OperationContext operationContext = new OperationContext();
    final String leaseID1 = blobRef.acquireLease(15, null /*proposed lease id */, null /*access condition*/,
            null/* BlobRequestOptions */, operationContext);
    final AccessCondition leaseCondition1 = AccessCondition.generateLeaseCondition(leaseID1);
    assertTrue(operationContext.getLastResult().getStatusCode() == HttpURLConnection.HTTP_CREATED);

    final String leaseID2 = UUID.randomUUID().toString();
    final AccessCondition leaseCondition2 = AccessCondition.generateLeaseCondition(leaseID2);

    // Try to upload without lease
    tryUploadWithBadLease(length, blobRef, null, StorageErrorCodeStrings.LEASE_ID_MISSING);

    // Try to upload with incorrect lease
    tryUploadWithBadLease(length, blobRef, leaseCondition2,
            StorageErrorCodeStrings.LEASE_ID_MISMATCH_WITH_BLOB_OPERATION);

    // Try to upload with correct lease
    blobRef.upload(BlobTestHelper.getRandomDataStream(length), -1, leaseCondition1, null, null);

    // Fail to change the lease with a bad accessCondition
    try {
        blobRef.changeLease(leaseID2, leaseCondition2);
        fail("Did not throw expected exception.");
    }
    catch (final StorageException ex) {
        assertEquals(ex.getHttpStatusCode(), 409);
        assertEquals(ex.getErrorCode(), StorageErrorCodeStrings.LEASE_ID_MISMATCH_WITH_LEASE_OPERATION);
    }

    // Change the lease
    blobRef.changeLease(leaseID2, leaseCondition1);

    // Try to upload without lease
    tryUploadWithBadLease(length, blobRef, null, StorageErrorCodeStrings.LEASE_ID_MISSING);

    // Try to upload with incorrect lease
    tryUploadWithBadLease(length, blobRef, leaseCondition1,
            StorageErrorCodeStrings.LEASE_ID_MISMATCH_WITH_BLOB_OPERATION);

    // Try to upload with correct lease
    blobRef.upload(BlobTestHelper.getRandomDataStream(length), -1, leaseCondition2, null, null);
}
 
Example #27
Source File: BlobRequest.java    From azure-storage-android with Apache License 2.0 4 votes vote down vote up
/**
 * Constructs a web request to commit a block to an append blob.
 * 
 * @param uri
 *            A <code>java.net.URI</code> object that specifies the absolute URI.
 * @param blobOptions
 *            A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout
 *            settings for the operation. Specify <code>null</code> to use the request options specified on the
 *            {@link CloudBlobClient}.
 * @param opContext
 *            An {@link OperationContext} object that represents the context for the current operation. This object
 *            is used to track requests to the storage service, and to provide additional runtime information about
 *            the operation.
 * @param accessCondition
 *            An {@link AccessCondition} object that represents the access conditions for the blob.
 * @return a HttpURLConnection to use to perform the operation.
 * @throws IOException
 *             if there is an error opening the connection
 * @throws URISyntaxException
 *             if the resource URI is invalid
 * @throws StorageException
 *             an exception representing any error which occurred during the operation.
 */
public static HttpURLConnection appendBlock(final URI uri, final BlobRequestOptions blobOptions,
        final OperationContext opContext, final AccessCondition accessCondition) 
                throws StorageException, IOException, URISyntaxException
{
    final UriQueryBuilder builder = new UriQueryBuilder();
    builder.add(Constants.QueryConstants.COMPONENT, APPEND_BLOCK_QUERY_ELEMENT_NAME);

    final HttpURLConnection request = createURLConnection(uri, builder, blobOptions, opContext);

    request.setDoOutput(true);
    request.setRequestMethod(Constants.HTTP_PUT);

    if (accessCondition != null) {
        accessCondition.applyConditionToRequest(request);
        accessCondition.applyAppendConditionToRequest(request);
    }

    return request;
}
 
Example #28
Source File: BlobRequest.java    From azure-storage-android with Apache License 2.0 4 votes vote down vote up
/**
 * Constructs a HttpURLConnection to set the page blob's size, Sign with zero length specified.
 * 
 * @param uri
 *            A <code>java.net.URI</code> object that specifies the absolute URI.
 * @param blobOptions
 *            A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout
 *            settings for the operation. Specify <code>null</code> to use the request options specified on the
 *            {@link CloudBlobClient}.
 * @param opContext
 *            An {@link OperationContext} object that represents the context for the current operation. This object
 *            is used to track requests to the storage service, and to provide additional runtime information about
 *            the operation.
 * @param accessCondition
 *            An {@link AccessCondition} object that represents the access conditions for the blob.
 * @param newBlobSize
 *            The new blob size, if the blob is a page blob. Set this parameter to null to keep the existing blob
 *            size.
 * @return a HttpURLConnection to use to perform the operation.
 * @throws IOException
 *             if there is an error opening the connection
 * @throws URISyntaxException
 *             if the resource URI is invalid
 * @throws StorageException
 *             an exception representing any error which occurred during the operation.
 * @throws IllegalArgumentException
 */
public static HttpURLConnection resize(final URI uri, final BlobRequestOptions blobOptions,
        final OperationContext opContext, final AccessCondition accessCondition, final Long newBlobSize)
        throws IOException, URISyntaxException, StorageException {
    final UriQueryBuilder builder = new UriQueryBuilder();
    builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.PROPERTIES);

    final HttpURLConnection request = createURLConnection(uri, builder, blobOptions, opContext);

    request.setFixedLengthStreamingMode(0);
    request.setDoOutput(true);
    request.setRequestMethod(Constants.HTTP_PUT);

    if (accessCondition != null) {
        accessCondition.applyConditionToRequest(request);
    }

    if (newBlobSize != null) {
        request.setRequestProperty(BlobConstants.SIZE, newBlobSize.toString());
    }

    return request;
}
 
Example #29
Source File: BlobRequest.java    From azure-storage-android with Apache License 2.0 4 votes vote down vote up
/**
 * Constructs a HttpURLConnection to set the blob's properties, Sign with zero length specified.
 * 
 * @param uri
 *            A <code>java.net.URI</code> object that specifies the absolute URI.
 * @param blobOptions
 *            A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout
 *            settings for the operation. Specify <code>null</code> to use the request options specified on the
 *            {@link CloudBlobClient}.
 * @param opContext
 *            An {@link OperationContext} object that represents the context for the current operation. This object
 *            is used to track requests to the storage service, and to provide additional runtime information about
 *            the operation.
 * @param accessCondition
 *            An {@link AccessCondition} object that represents the access conditions for the blob.
 * @param properties
 *            The properties to upload.
 * @return a HttpURLConnection to use to perform the operation.
 * @throws IOException
 *             if there is an error opening the connection
 * @throws URISyntaxException
 *             if the resource URI is invalid
 * @throws StorageException
 *             an exception representing any error which occurred during the operation.
 * @throws IllegalArgumentException
 */
public static HttpURLConnection setBlobProperties(final URI uri, final BlobRequestOptions blobOptions,
        final OperationContext opContext, final AccessCondition accessCondition, final BlobProperties properties)
        throws IOException, URISyntaxException, StorageException {
    final UriQueryBuilder builder = new UriQueryBuilder();
    builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.PROPERTIES);

    final HttpURLConnection request = createURLConnection(uri, builder, blobOptions, opContext);

    request.setFixedLengthStreamingMode(0);
    request.setDoOutput(true);
    request.setRequestMethod(Constants.HTTP_PUT);

    if (accessCondition != null) {
        accessCondition.applyConditionToRequest(request);
    }

    if (properties != null) {
        addProperties(request, properties);
    }

    return request;
}
 
Example #30
Source File: BlobRequest.java    From azure-storage-android with Apache License 2.0 4 votes vote down vote up
/**
 * Constructs a HttpURLConnection to return a list of the PageBlob's page ranges. Sign with no length specified.
 * 
 * @param uri
 *            A <code>java.net.URI</code> object that specifies the absolute URI.
 * @param blobOptions
 *            A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout
 *            settings for the operation. Specify <code>null</code> to use the request options specified on the
 *            {@link CloudBlobClient}.
 * @param opContext
 *            An {@link OperationContext} object that represents the context for the current operation. This object
 *            is used to track requests to the storage service, and to provide additional runtime information about
 *            the operation.
 * @param accessCondition
 *            An {@link AccessCondition} object that represents the access conditions for the blob.
 * @param snapshotVersion
 *            The snapshot version, if the blob is a snapshot.
 * @param previousSnapshot
 *            A string representing the snapshot timestamp to use as the starting point for the diff. If this
 *            CloudPageBlob represents a snapshot, the previousSnapshot parameter must be prior to the current
 *            snapshot.
 * @param offset
 *            The offset at which to begin returning content.
 * @param count
 *            The number of bytes to return.
 * @return a HttpURLConnection to use to perform the operation.
 * @throws IOException
 *             if there is an error opening the connection
 * @throws URISyntaxException
 *             if the resource URI is invalid
 * @throws StorageException
 *             an exception representing any error which occurred during the operation.
 * @throws IllegalArgumentException
 */
public static HttpURLConnection getPageRangesDiff(final URI uri, final BlobRequestOptions blobOptions,
        final OperationContext opContext, final AccessCondition accessCondition, final String snapshotVersion,
        final String previousSnapshot, final Long offset, final Long count) throws StorageException,
        IOException, URISyntaxException {

    final UriQueryBuilder builder = new UriQueryBuilder();
    builder.add(Constants.QueryConstants.COMPONENT, PAGE_LIST_QUERY_ELEMENT_NAME);
    builder.add(BlobConstants.PREV_SNAPSHOT, previousSnapshot);
    BlobRequest.addSnapshot(builder, snapshotVersion);

    final HttpURLConnection request = createURLConnection(uri, builder, blobOptions, opContext);
    request.setRequestMethod(Constants.HTTP_GET);

    if (accessCondition != null) {
        accessCondition.applyConditionToRequest(request);
    }
    
    addRange(request, offset, count);

    return request;
}