/// <summary>Initializes a new instance of the <see cref="StoragePageBlob"/> class.</summary>
 /// <param name="parent">The parent blob container.</param>
 /// <param name="sdk">The SDK blob to wrap.</param>
 public StoragePageBlob(IStorageBlobContainer parent, CloudPageBlob sdk)
 {
     _parent = parent;
     _sdk = sdk;
     _properties = new StorageBlobProperties(sdk);
 }
 /// <summary>Initializes a new instance of the <see cref="StorageBlockBlob"/> class.</summary>
 /// <param name="parent">The parent blob container.</param>
 /// <param name="sdk">The SDK blob to wrap.</param>
 public StorageBlockBlob(IStorageBlobContainer parent, CloudBlockBlob sdk)
 {
     _parent     = parent;
     _sdk        = sdk;
     _properties = new StorageBlobProperties(sdk);
 }
        /// <summary>
        /// This method is called each polling interval for all containers. The method divides the
        /// budget of allocated number of blobs to query, for each container we query a page of
        /// that size and we keep the continuation token for the next time. AS a curser, we use
        /// the time stamp when the current cycle on the container started. blobs newer than that
        /// time will be considered new and registrations will be notified
        /// </summary>
        /// <param name="container"></param>
        /// <param name="containerScanInfo"> Information that includes the last cycle start
        /// the continuation token and the current cycle start for a container</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task <IEnumerable <IStorageBlob> > PollNewBlobsAsync(
            IStorageBlobContainer container, ContainerScanInfo containerScanInfo, CancellationToken cancellationToken)
        {
            IEnumerable <IStorageListBlobItem> currentBlobs;
            IStorageBlobResultSegment          blobSegment;
            int blobPollLimitPerContainer           = _scanBlobLimitPerPoll / _scanInfo.Count;
            BlobContinuationToken continuationToken = containerScanInfo.ContinuationToken;

            // if starting the cycle, reset the sweep time
            if (continuationToken == null)
            {
                containerScanInfo.CurrentSweepCycleLatestModified = DateTime.MinValue;
            }
            try
            {
                blobSegment = await container.ListBlobsSegmentedAsync(prefix : null, useFlatBlobListing : true,
                                                                      blobListingDetails : BlobListingDetails.None, maxResults : blobPollLimitPerContainer, currentToken : continuationToken,
                                                                      options : null, operationContext : null, cancellationToken : cancellationToken);

                currentBlobs = blobSegment.Results;
            }
            catch (StorageException exception)
            {
                if (exception.IsNotFound())
                {
                    return(Enumerable.Empty <IStorageBlob>());
                }
                else
                {
                    throw;
                }
            }

            List <IStorageBlob> newBlobs = new List <IStorageBlob>();

            // Type cast to IStorageBlob is safe due to useFlatBlobListing: true above.
            foreach (IStorageBlob currentBlob in currentBlobs)
            {
                cancellationToken.ThrowIfCancellationRequested();

                IStorageBlobProperties properties = currentBlob.Properties;
                DateTime lastModifiedTimestamp    = properties.LastModified.Value.UtcDateTime;

                if (lastModifiedTimestamp > containerScanInfo.CurrentSweepCycleLatestModified)
                {
                    containerScanInfo.CurrentSweepCycleLatestModified = lastModifiedTimestamp;
                }

                if (lastModifiedTimestamp > containerScanInfo.LastSweepCycleLatestModified)
                {
                    newBlobs.Add(currentBlob);
                }
            }

            // record continuation token for next chunk retrieval
            containerScanInfo.ContinuationToken = blobSegment.ContinuationToken;

            // if ending a cycle then copy currentSweepCycleStartTime to lastSweepCycleStartTime, if changed
            if (blobSegment.ContinuationToken == null &&
                containerScanInfo.CurrentSweepCycleLatestModified > containerScanInfo.LastSweepCycleLatestModified)
            {
                containerScanInfo.LastSweepCycleLatestModified = containerScanInfo.CurrentSweepCycleLatestModified;
            }

            return(newBlobs);
        }
        public static async Task <Tuple <IEnumerable <IStorageBlob>, DateTime> > PollNewBlobsAsync(
            IStorageBlobContainer container, DateTime previousTimestamp, CancellationToken cancellationToken)
        {
            DateTime updatedTimestamp = previousTimestamp;

            IList <IStorageListBlobItem> currentBlobs;

            try
            {
                currentBlobs = (await container.ListBlobsAsync(prefix: null, useFlatBlobListing: true,
                                                               cancellationToken: cancellationToken)).ToList();
            }
            catch (StorageException exception)
            {
                if (exception.IsNotFound())
                {
                    return(new Tuple <IEnumerable <IStorageBlob>, DateTime>(
                               Enumerable.Empty <IStorageBlob>(), updatedTimestamp));
                }
                else
                {
                    throw;
                }
            }

            List <IStorageBlob> newBlobs = new List <IStorageBlob>();

            // Type cast to IStorageBlob is safe due to useFlatBlobListing: true above.
            foreach (IStorageBlob currentBlob in currentBlobs)
            {
                cancellationToken.ThrowIfCancellationRequested();

                try
                {
                    await currentBlob.FetchAttributesAsync(cancellationToken);
                }
                catch (StorageException exception)
                {
                    if (exception.IsNotFound())
                    {
                        continue;
                    }
                    else
                    {
                        throw;
                    }
                }

                IStorageBlobProperties properties = currentBlob.Properties;
                DateTime lastModifiedTimestamp    = properties.LastModified.Value.UtcDateTime;

                if (lastModifiedTimestamp > updatedTimestamp)
                {
                    updatedTimestamp = lastModifiedTimestamp;
                }

                if (lastModifiedTimestamp > previousTimestamp)
                {
                    newBlobs.Add(currentBlob);
                }
            }

            return(new Tuple <IEnumerable <IStorageBlob>, DateTime>(newBlobs, updatedTimestamp));
        }