/// <inheritdoc/>
        public Task <HomeDocument> GetHomeAsync(CancellationToken cancellationToken)
        {
            if (_homeDocument != null)
            {
                return(InternalTaskExtensions.CompletedTask(_homeDocument));
            }

            UriTemplate template = new UriTemplate("/");
            Func <Task <Tuple <IdentityToken, Uri> >, HttpWebRequest> prepareRequest =
                PrepareRequestAsyncFunc(HttpMethod.GET, template, new Dictionary <string, string>());

            Func <Task <HttpWebRequest>, Task <HomeDocument> > requestResource =
                GetResponseAsyncFunc <HomeDocument>(cancellationToken);

            Func <Task <HomeDocument>, HomeDocument> cacheResult =
                task =>
            {
                _homeDocument = task.Result;
                return(task.Result);
            };

            return(AuthenticateServiceAsync(cancellationToken)
                   .Select(prepareRequest)
                   .Then(requestResource)
                   .Select(cacheResult));
        }
示例#2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Claim"/> class using the provided values.
        /// </summary>
        /// <param name="service">The queueing service.</param>
        /// <param name="queueName">The name of the queue.</param>
        /// <param name="location">The absolute URI of the claim resource. If no claim was allocated by the server, this value is <see langword="null"/>.</param>
        /// <param name="timeToLive">The time to live of the claim.</param>
        /// <param name="age">The age of the claim.</param>
        /// <param name="owner"><see langword="true"/> if the current instance owns the claim (and is responsible for releasing it); otherwise, <see langword="false"/>.</param>
        /// <param name="messages">A collection of messages belonging to the claim.</param>
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="service"/> is <see langword="null"/>.
        /// <para>-or-</para>
        /// <para>If <paramref name="queueName"/> is <see langword="null"/>.</para>
        /// <para>-or-</para>
        /// <para>If <paramref name="messages"/> is <see langword="null"/>.</para>
        /// </exception>
        public Claim(IQueueingService service, QueueName queueName, Uri location, TimeSpan timeToLive, TimeSpan age, bool owner, IEnumerable <QueuedMessage> messages)
        {
            if (service == null)
            {
                throw new ArgumentNullException("service");
            }
            if (queueName == null)
            {
                throw new ArgumentNullException("queueName");
            }
            if (messages == null)
            {
                throw new ArgumentNullException("messages");
            }

            _service    = service;
            _queueName  = queueName;
            _location   = location;
            _timeToLive = timeToLive;
            _age        = age;
            _messages   = messages.ToArray();
            if (!owner)
            {
                // prevent this object from releasing the resource
                _releaseTask = InternalTaskExtensions.CompletedTask();
            }
        }
        /// <inheritdoc/>
        /// <remarks>
        /// This method returns a cached base address if one is available. If no cached address is
        /// available, <see cref="ProviderBase{TProvider}.GetServiceEndpoint"/> is called to obtain
        /// an <see cref="Endpoint"/> with the type <c>rax:queues</c> and preferred type <c>cloudQueues</c>.
        /// </remarks>
        protected override Task <Uri> GetBaseUriAsync(CancellationToken cancellationToken)
        {
            if (_baseUri != null)
            {
                return(InternalTaskExtensions.CompletedTask(_baseUri));
            }

            return(Task.Factory.StartNew(
                       () =>
            {
                Endpoint endpoint = GetServiceEndpoint(null, "rax:queues", "cloudQueues", null);
                Uri baseUri = new Uri(_internalUrl ? endpoint.InternalURL : endpoint.PublicURL);
                _baseUri = baseUri;
                return baseUri;
            }));
        }
        /// <inheritdoc/>
        public Task <Claim> QueryClaimAsync(QueueName queueName, Claim claim, CancellationToken cancellationToken)
        {
            if (queueName == null)
            {
                throw new ArgumentNullException("queueName");
            }
            if (claim == null)
            {
                throw new ArgumentNullException("claim");
            }

            UriTemplate template = new UriTemplate("/queues/{queue_name}/claims/{claim_id}");

            var parameters =
                new Dictionary <string, string>()
            {
                { "queue_name", queueName.Value },
                { "claim_id", claim.Id.Value }
            };

            Func <Task <Tuple <IdentityToken, Uri> >, HttpWebRequest> prepareRequest =
                PrepareRequestAsyncFunc(HttpMethod.GET, template, parameters);

            Func <Task <Tuple <HttpWebResponse, string> >, Task <Tuple <Uri, TimeSpan, TimeSpan, IEnumerable <QueuedMessage> > > > parseResult =
                task =>
            {
                // this response uses ContentLocation instead of Location
                string location    = task.Result.Item1.Headers[HttpResponseHeader.ContentLocation];
                Uri    locationUri = location != null ? new Uri(_baseUri, location) : null;

                JObject  result = JsonConvert.DeserializeObject <JObject>(task.Result.Item2);
                TimeSpan age    = TimeSpan.FromSeconds((int)result["age"]);
                TimeSpan ttl    = TimeSpan.FromSeconds((int)result["ttl"]);
                IEnumerable <QueuedMessage> messages = result["messages"].ToObject <IEnumerable <QueuedMessage> >();
                return(InternalTaskExtensions.CompletedTask(Tuple.Create(locationUri, ttl, age, messages)));
            };
            Func <Task <HttpWebRequest>, Task <Tuple <Uri, TimeSpan, TimeSpan, IEnumerable <QueuedMessage> > > > requestResource =
                GetResponseAsyncFunc(cancellationToken, parseResult);

            Func <Task <Tuple <Uri, TimeSpan, TimeSpan, IEnumerable <QueuedMessage> > >, Claim> resultSelector =
                task => new Claim(this, queueName, task.Result.Item1, task.Result.Item2, task.Result.Item3, false, task.Result.Item4);

            return(AuthenticateServiceAsync(cancellationToken)
                   .Select(prepareRequest)
                   .Then(requestResource)
                   .Select(resultSelector));
        }
示例#5
0
        /// <summary>
        /// Asynchronously releases resources owned by this <see cref="Claim"/>.
        /// </summary>
        /// <remarks>
        /// This method calls <see cref="IQueueingService.ReleaseClaimAsync"/> to release messages
        /// claimed by this claim. To prevent other subscribers from re-claiming the messages, make
        /// sure to delete the messages before calling <see cref="DisposeAsync"/>.
        /// </remarks>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> that the task will observe.</param>
        /// <returns>A <see cref="Task"/> object representing the asynchronous operation.</returns>
        public Task DisposeAsync(CancellationToken cancellationToken)
        {
            lock (_lock)
            {
                if (_releaseTask == null)
                {
                    if (_messages.Length == 0)
                    {
                        _releaseTask = InternalTaskExtensions.CompletedTask();
                    }
                    else
                    {
                        _releaseTask = _service.ReleaseClaimAsync(_queueName, this, cancellationToken);
                    }
                }
            }

            return(_releaseTask);
        }
        /// <inheritdoc/>
        public Task <bool> CreateQueueAsync(QueueName queueName, CancellationToken cancellationToken)
        {
            if (queueName == null)
            {
                throw new ArgumentNullException("queueName");
            }

            UriTemplate template   = new UriTemplate("/queues/{queue_name}");
            var         parameters = new Dictionary <string, string>
            {
                { "queue_name", queueName.Value }
            };

            Func <Task <Tuple <IdentityToken, Uri> >, HttpWebRequest> prepareRequest =
                PrepareRequestAsyncFunc(HttpMethod.PUT, template, parameters);

            Func <Task <Tuple <HttpWebResponse, string> >, Task <bool> > parseResult =
                task =>
            {
                if (task.Result.Item1.StatusCode == HttpStatusCode.Created)
                {
                    return(InternalTaskExtensions.CompletedTask(true));
                }
                else
                {
                    return(InternalTaskExtensions.CompletedTask(false));
                }
            };

            Func <Task <HttpWebRequest>, Task <bool> > requestResource =
                GetResponseAsyncFunc(cancellationToken, parseResult);

            return(AuthenticateServiceAsync(cancellationToken)
                   .Select(prepareRequest)
                   .Then(requestResource));
        }
        /// <inheritdoc/>
        public Task <Claim> ClaimMessageAsync(QueueName queueName, int?limit, TimeSpan timeToLive, TimeSpan gracePeriod, CancellationToken cancellationToken)
        {
            if (queueName == null)
            {
                throw new ArgumentNullException("queueName");
            }
            if (limit < 0)
            {
                throw new ArgumentOutOfRangeException("limit");
            }
            if (timeToLive <= TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException("timeToLive");
            }
            if (gracePeriod < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException("gracePeriod");
            }

            UriTemplate template = new UriTemplate("/queues/{queue_name}/claims?limit={limit}");

            var parameters =
                new Dictionary <string, string>()
            {
                { "queue_name", queueName.Value },
            };

            if (limit != null)
            {
                parameters["limit"] = limit.ToString();
            }

            var request = new ClaimMessagesRequest(timeToLive, gracePeriod);

            Func <Task <Tuple <IdentityToken, Uri> >, Task <HttpWebRequest> > prepareRequest =
                PrepareRequestAsyncFunc(HttpMethod.POST, template, parameters, request);

            Func <Task <Tuple <HttpWebResponse, string> >, Task <Tuple <Uri, IEnumerable <QueuedMessage> > > > parseResult =
                task =>
            {
                string location    = task.Result.Item1.Headers[HttpResponseHeader.Location];
                Uri    locationUri = location != null ? new Uri(_baseUri, location) : null;

                if (task.Result.Item1.StatusCode == HttpStatusCode.NoContent)
                {
                    // the queue did not contain any messages to claim
                    Tuple <Uri, IEnumerable <QueuedMessage> > result = Tuple.Create(locationUri, Enumerable.Empty <QueuedMessage>());
                    return(InternalTaskExtensions.CompletedTask(result));
                }

                IEnumerable <QueuedMessage> messages = JsonConvert.DeserializeObject <IEnumerable <QueuedMessage> >(task.Result.Item2);

                return(InternalTaskExtensions.CompletedTask(Tuple.Create(locationUri, messages)));
            };
            Func <Task <HttpWebRequest>, Task <Tuple <Uri, IEnumerable <QueuedMessage> > > > requestResource =
                GetResponseAsyncFunc <Tuple <Uri, IEnumerable <QueuedMessage> > >(cancellationToken, parseResult);

            Func <Task <Tuple <Uri, IEnumerable <QueuedMessage> > >, Claim> resultSelector =
                task => new Claim(this, queueName, task.Result.Item1, timeToLive, TimeSpan.Zero, true, task.Result.Item2);

            return(AuthenticateServiceAsync(cancellationToken)
                   .Then(prepareRequest)
                   .Then(requestResource)
                   .Select(resultSelector));
        }