Пример #1
0
 public BlobQueueTriggerExecutor(IBlobCausalityReader causalityReader, BlobTriggerSource blobTriggerSource, IBlobWrittenWatcher blobWrittenWatcher, ILogger <BlobListener> logger)
 {
     _causalityReader    = causalityReader;
     _blobTriggerSource  = blobTriggerSource;
     _blobWrittenWatcher = blobWrittenWatcher;
     _registrations      = new ConcurrentDictionary <string, BlobQueueRegistration>();
     _logger             = logger ?? throw new ArgumentNullException(nameof(logger));
 }
Пример #2
0
 public SharedBlobQueueListenerFactory(
     QueueServiceClient hostQueueServiceClient,
     SharedQueueWatcher sharedQueueWatcher,
     QueueClient hostBlobTriggerQueue,
     BlobsOptions blobsOptions,
     IWebJobsExceptionHandler exceptionHandler,
     ILoggerFactory loggerFactory,
     IBlobWrittenWatcher blobWrittenWatcher,
     FunctionDescriptor functionDescriptor,
     BlobTriggerSource blobTriggerSource)
 {
     _hostQueueServiceClient = hostQueueServiceClient ?? throw new ArgumentNullException(nameof(hostQueueServiceClient));
     _sharedQueueWatcher     = sharedQueueWatcher ?? throw new ArgumentNullException(nameof(sharedQueueWatcher));
     _hostBlobTriggerQueue   = hostBlobTriggerQueue ?? throw new ArgumentNullException(nameof(hostBlobTriggerQueue));
     _blobsOptions           = blobsOptions ?? throw new ArgumentNullException(nameof(blobsOptions));
     _exceptionHandler       = exceptionHandler ?? throw new ArgumentNullException(nameof(exceptionHandler));
     _loggerFactory          = loggerFactory;
     _blobWrittenWatcher     = blobWrittenWatcher;
     _functionDescriptor     = functionDescriptor;
     _blobTriggerSource      = blobTriggerSource;
 }
Пример #3
0
        public BlobTriggerBinding(ParameterInfo parameter,
                                  BlobServiceClient hostBlobServiceClient,
                                  QueueServiceClient hostQueueServiceClient,
                                  BlobServiceClient dataBlobServiceClient,
                                  QueueServiceClient dataQueueServiceClient,
                                  IBlobPathSource path,
                                  BlobTriggerSource blobTriggerSource,
                                  IHostIdProvider hostIdProvider,
                                  BlobsOptions blobsOptions,
                                  IWebJobsExceptionHandler exceptionHandler,
                                  IContextSetter <IBlobWrittenWatcher> blobWrittenWatcherSetter,
                                  BlobTriggerQueueWriterFactory blobTriggerQueueWriterFactory,
                                  ISharedContextProvider sharedContextProvider,
                                  IHostSingletonManager singletonManager,
                                  ILoggerFactory loggerFactory,
                                  ConcurrencyManager concurrencyManager)
        {
            _parameter              = parameter ?? throw new ArgumentNullException(nameof(parameter));
            _hostBlobServiceClient  = hostBlobServiceClient ?? throw new ArgumentNullException(nameof(hostBlobServiceClient));
            _hostQueueServiceClient = hostQueueServiceClient ?? throw new ArgumentNullException(nameof(hostQueueServiceClient));
            _dataBlobServiceClient  = dataBlobServiceClient ?? throw new ArgumentNullException(nameof(dataBlobServiceClient));
            _dataQueueServiceClient = dataQueueServiceClient ?? throw new ArgumentNullException(nameof(dataQueueServiceClient));

            _accountName                   = _dataBlobServiceClient.AccountName;
            _path                          = path ?? throw new ArgumentNullException(nameof(path));
            _blobTriggerSource             = blobTriggerSource;
            _hostIdProvider                = hostIdProvider ?? throw new ArgumentNullException(nameof(hostIdProvider));
            _blobsOptions                  = blobsOptions ?? throw new ArgumentNullException(nameof(blobsOptions));
            _exceptionHandler              = exceptionHandler ?? throw new ArgumentNullException(nameof(exceptionHandler));
            _blobWrittenWatcherSetter      = blobWrittenWatcherSetter ?? throw new ArgumentNullException(nameof(blobWrittenWatcherSetter));
            _blobTriggerQueueWriterFactory = blobTriggerQueueWriterFactory ?? throw new ArgumentNullException(nameof(blobTriggerQueueWriterFactory));
            _sharedContextProvider         = sharedContextProvider ?? throw new ArgumentNullException(nameof(sharedContextProvider));
            _singletonManager              = singletonManager ?? throw new ArgumentNullException(nameof(singletonManager));
            _concurrencyManager            = concurrencyManager ?? throw new ArgumentNullException(nameof(concurrencyManager));
            _loggerFactory                 = loggerFactory;
            _converter                     = CreateConverter(_dataBlobServiceClient);
            _bindingDataContract           = CreateBindingDataContract(path);
        }
Пример #4
0
 public BlobListenerFactory(IHostIdProvider hostIdProvider,
                            BlobsOptions blobsOptions,
                            IWebJobsExceptionHandler exceptionHandler,
                            IContextSetter <IBlobWrittenWatcher> blobWrittenWatcherSetter,
                            BlobTriggerQueueWriterFactory blobTriggerQueueWriterFactory,
                            ISharedContextProvider sharedContextProvider,
                            ILoggerFactory loggerFactory,
                            FunctionDescriptor functionDescriptor,
                            BlobServiceClient hostBlobServiceClient,
                            QueueServiceClient hostQueueServiceClient,
                            BlobServiceClient dataBlobServiceClient,
                            QueueServiceClient dataQueueServiceClient,
                            BlobContainerClient container,
                            IBlobPathSource input,
                            BlobTriggerSource triggerKind,
                            ITriggeredFunctionExecutor executor,
                            IHostSingletonManager singletonManager,
                            ConcurrencyManager concurrencyManager)
 {
     _hostIdProvider = hostIdProvider ?? throw new ArgumentNullException(nameof(hostIdProvider));
     _blobTriggerQueueWriterFactory = blobTriggerQueueWriterFactory ?? throw new ArgumentNullException(nameof(blobTriggerQueueWriterFactory));
     _blobsOptions             = blobsOptions ?? throw new ArgumentNullException(nameof(blobsOptions));
     _exceptionHandler         = exceptionHandler ?? throw new ArgumentNullException(nameof(exceptionHandler));
     _blobWrittenWatcherSetter = blobWrittenWatcherSetter ?? throw new ArgumentNullException(nameof(blobWrittenWatcherSetter));
     _sharedContextProvider    = sharedContextProvider ?? throw new ArgumentNullException(nameof(sharedContextProvider));
     _functionDescriptor       = functionDescriptor ?? throw new ArgumentNullException(nameof(functionDescriptor));
     _loggerFactory            = loggerFactory;
     _hostBlobServiceClient    = hostBlobServiceClient ?? throw new ArgumentNullException(nameof(hostBlobServiceClient));
     _hostQueueServiceClient   = hostQueueServiceClient ?? throw new ArgumentNullException(nameof(hostQueueServiceClient));
     _dataBlobServiceClient    = dataBlobServiceClient ?? throw new ArgumentNullException(nameof(dataBlobServiceClient));
     _dataQueueServiceClient   = dataQueueServiceClient ?? throw new ArgumentNullException(nameof(dataQueueServiceClient));
     _container          = container ?? throw new ArgumentNullException(nameof(container));
     _input              = input ?? throw new ArgumentNullException(nameof(input));
     _blobTriggerSource  = triggerKind;
     _executor           = executor ?? throw new ArgumentNullException(nameof(executor));
     _singletonManager   = singletonManager ?? throw new ArgumentNullException(nameof(singletonManager));
     _concurrencyManager = concurrencyManager ?? throw new ArgumentNullException(nameof(concurrencyManager));
 }
 public static void BlobMessageEnqueued(ILogger <BlobListener> logger, string functionName, string blobName, string queueMessageId, string queueName, string pollId, BlobTriggerSource triggerSource) =>
 _blobMessageEnqueued(logger, blobName, functionName, queueMessageId, queueName, pollId, triggerSource, null);
 public static void BlobAlreadyProcessed(ILogger <BlobListener> logger, string functionName, string blobName, string eTag, string pollId, BlobTriggerSource triggerSource) =>
 _blobAlreadyProcessed(logger, blobName, functionName, eTag, pollId, triggerSource, null);
 public static void BlobHasNoETag(ILogger <BlobListener> logger, string functionName, string blobName, string pollId, BlobTriggerSource triggerSource) =>
 _blobHasNoETag(logger, blobName, functionName, pollId, triggerSource, null);
 public static void BlobDoesNotMatchPattern(ILogger <BlobListener> logger, string functionName, string blobName, string pattern, string pollId, BlobTriggerSource triggerSource) =>
 _blobDoesNotMatchPattern(logger, blobName, functionName, pattern, pollId, triggerSource, null);
        public async Task <FunctionResult> ExecuteAsync(BlobTriggerExecutorContext context, CancellationToken cancellationToken)
        {
            BlobBaseClient    value         = context.Blob.BlobClient;
            BlobTriggerSource triggerSource = context.TriggerSource;
            string            pollId        = context.PollId;

            // Avoid unnecessary network calls for non-matches. First, check to see if the blob matches this trigger.
            IReadOnlyDictionary <string, object> bindingData = _input.CreateBindingData(value.ToBlobPath());

            if (bindingData == null)
            {
                string pattern = new BlobPath(_input.ContainerNamePattern, _input.BlobNamePattern).ToString();
                Logger.BlobDoesNotMatchPattern(_logger, _functionDescriptor.LogName, value.Name, pattern, pollId, triggerSource);

                // Blob is not a match for this trigger.
                return(new FunctionResult(true));
            }

            // Next, check to see if the blob currently exists (and, if so, what the current ETag is).
            BlobProperties blobProperties = await value.FetchPropertiesOrNullIfNotExistAsync(cancellationToken).ConfigureAwait(false);

            string possibleETag = null;

            if (blobProperties != null)
            {
                possibleETag = blobProperties.ETag.ToString();
            }

            if (possibleETag == null)
            {
                Logger.BlobHasNoETag(_logger, _functionDescriptor.LogName, value.Name, pollId, triggerSource);

                // If the blob doesn't exist and have an ETag, don't trigger on it.
                return(new FunctionResult(true));
            }

            var receiptBlob = _receiptManager.CreateReference(_hostId, _functionDescriptor.Id, value.BlobContainerName,
                                                              value.Name, possibleETag);

            // Check for the completed receipt. If it's already there, noop.
            BlobReceipt unleasedReceipt = await _receiptManager.TryReadAsync(receiptBlob, cancellationToken).ConfigureAwait(false);

            if (unleasedReceipt != null && unleasedReceipt.IsCompleted)
            {
                Logger.BlobAlreadyProcessed(_logger, _functionDescriptor.LogName, value.Name, possibleETag, pollId, triggerSource);

                return(new FunctionResult(true));
            }
            else if (unleasedReceipt == null)
            {
                // Try to create (if not exists) an incomplete receipt.
                if (!await _receiptManager.TryCreateAsync(receiptBlob, cancellationToken).ConfigureAwait(false))
                {
                    // Someone else just created the receipt; wait to try to trigger until later.
                    // Alternatively, we could just ignore the return result and see who wins the race to acquire the
                    // lease.
                    return(new FunctionResult(false));
                }
            }

            string leaseId = await _receiptManager.TryAcquireLeaseAsync(receiptBlob, cancellationToken).ConfigureAwait(false);

            if (leaseId == null)
            {
                // If someone else owns the lease and just took over this receipt or deleted it;
                // wait to try to trigger until later.
                return(new FunctionResult(false));
            }

            try
            {
                // Check again for the completed receipt. If it's already there, noop.
                BlobReceipt receipt = await _receiptManager.TryReadAsync(receiptBlob, cancellationToken).ConfigureAwait(false);

                Debug.Assert(receipt != null); // We have a (30 second) lease on the blob; it should never disappear on us.

                if (receipt.IsCompleted)
                {
                    Logger.BlobAlreadyProcessed(_logger, _functionDescriptor.LogName, value.Name, possibleETag, pollId, triggerSource);

                    await _receiptManager.ReleaseLeaseAsync(receiptBlob, leaseId, cancellationToken).ConfigureAwait(false);

                    return(new FunctionResult(true));
                }

                // We've successfully acquired a lease to enqueue the message for this blob trigger. Enqueue the message,
                // complete the receipt and release the lease.

                // Enqueue a message: function ID + blob path + ETag
                BlobTriggerMessage message = new BlobTriggerMessage
                {
                    FunctionId    = _functionDescriptor.Id,
                    BlobType      = blobProperties.BlobType,
                    ContainerName = value.BlobContainerName,
                    BlobName      = value.Name,
                    ETag          = possibleETag
                };

                var(queueName, messageId) = await _queueWriter.EnqueueAsync(message, cancellationToken).ConfigureAwait(false);

                Logger.BlobMessageEnqueued(_logger, _functionDescriptor.LogName, value.Name, messageId, queueName, pollId, triggerSource);

                // Complete the receipt
                await _receiptManager.MarkCompletedAsync(receiptBlob, leaseId, cancellationToken).ConfigureAwait(false);

                return(new FunctionResult(true));
            }
            finally
            {
                await _receiptManager.ReleaseLeaseAsync(receiptBlob, leaseId, cancellationToken).ConfigureAwait(false);
            }
        }
Пример #10
0
 public BlobQueueTriggerExecutor(BlobTriggerSource blobTriggerSource, IBlobWrittenWatcher blobWrittenWatcher, ILogger <BlobListener> logger)
     : this(BlobCausalityReader.Instance, blobTriggerSource, blobWrittenWatcher, logger)
 {
 }