void CanConstructRequestException()
        {
            RequestException requestException;

            foreach (var type in new MessageType[] { MessageType.Debug, MessageType.Error, MessageType.Fatal, MessageType.Information, MessageType.Warning })
            {
                var details = new ReadOnlyCollection<Message>(new Message[] 
                {
                    new Message(type, "Information on the cause of the RequestException")
                });
                
                requestException = new RequestException(new HttpResponseMessage(HttpStatusCode.InternalServerError), details);

                Assert.Equal(string.Format("500: Internal Server Error\n  {0}: Information on the cause of the RequestException", type), requestException.Message);
                Assert.Equal(HttpStatusCode.InternalServerError, requestException.StatusCode);
                Assert.Equal(1, requestException.Details.Count);
                Assert.Equal(details, requestException.Details.AsEnumerable());
            }

            requestException = new RequestException(new HttpResponseMessage(HttpStatusCode.NoContent), null);
            Assert.Equal("204: No Content", requestException.Message);
            Assert.Equal(0, requestException.Details.Count);
            Assert.Equal(HttpStatusCode.NoContent, requestException.StatusCode);

            for (int i = 2; i < 10; ++i)
            {
                var message = new StringBuilder("204: No Content");
                var details = new Message[i];

                for (int j = 0; j < i; ++j)
                {
                    details[j] = new Message(MessageType.Warning, "Information on the cause of the RequestException");
                    message.Append("\n  ");
                    message.Append(details[j]);
                }

                requestException = new RequestException(
                    new HttpResponseMessage(HttpStatusCode.NoContent), new ReadOnlyCollection<Message>(details));

                Assert.Equal(HttpStatusCode.NoContent, requestException.StatusCode);
                Assert.Equal(message.ToString(), requestException.Message);
                Assert.Equal(i, requestException.Details.Count);
                Assert.Equal(details, requestException.Details.AsEnumerable());
            }
        }
Exemple #2
0
        /// <summary>
        /// Throw request exception asynchronous.
        /// </summary>
        /// <exception cref="RequestException">
        /// Thrown when a Request error condition occurs.
        /// </exception>
        /// <returns>
        /// A <see cref="Task"/> representing the operation.
        /// </returns>
        internal async Task ThrowRequestExceptionAsync()
        {
            var details = await Splunk.Client.Message.ReadMessagesAsync(this.XmlReader).ConfigureAwait(false);
            RequestException requestException;

            switch (this.Message.StatusCode)
            {
                case HttpStatusCode.BadRequest:
                    requestException = new BadRequestException(this.Message, details);
                    break;
                case HttpStatusCode.Forbidden:
                    requestException = new UnauthorizedAccessException(this.Message, details);
                    break;
                case HttpStatusCode.InternalServerError:
                    requestException = new InternalServerErrorException(this.Message, details);
                    break;
                case HttpStatusCode.NotFound:
                    requestException = new ResourceNotFoundException(this.Message, details);
                    break;
                case HttpStatusCode.Unauthorized:
                    requestException = new AuthenticationFailureException(this.Message, details);
                    break;
                default:
                    requestException = new RequestException(this.Message, details);
                    break;
            }

            throw requestException;
        }
        /// <summary>
        /// Throws a <see cref="RequestException"/> if the current <see cref=
        /// "Response.Message.StatusCode"/> is different than <see cref=
        /// "expected"/>.
        /// </summary>
        /// <param name="expected">
        /// The expected <see cref="HttpStatusCode"/>.
        /// </param>
        /// <returns></returns>
        public async Task EnsureStatusCodeAsync(HttpStatusCode expected)
        {
            var statusCode = this.Message.StatusCode;

            if (statusCode == expected)
                return;

            var details = await Splunk.Client.Message.ReadMessagesAsync(this.XmlReader);
            RequestException requestException;

            switch (statusCode)
            {
                case HttpStatusCode.Forbidden:
                    requestException = new UnauthorizedAccessException(this.Message, details);
                    break;
                case HttpStatusCode.NotFound:
                    requestException = new ResourceNotFoundException(this.Message, details);
                    break;
                case HttpStatusCode.Unauthorized:
                    requestException = new AuthenticationFailureException(this.Message, details);
                    break;
                default:
                    requestException = new RequestException(this.Message, details);
                    break;
            }

            throw requestException;
        }
Exemple #4
0
        /// <summary>
        /// Refreshes the cached state of the current <see cref="Entity<TEntity>"/>.
        /// </summary>
        public override async Task GetAsync()
        {
            //// TODO: This retry logic is for jobs. Parmeterize it and move it into the Job class

            // FJR: I assume the retry logic is for jobs, since nothing else requires this. I suggest moving it
            // into Job. Also, it's insufficient. If you're just trying to get some state, this will do it, but
            // as of Splunk 6, getting a 200 and content back does not imply you have all the fields. For pivot
            // support, they're now shoving fields in as they become ready, so you have to wait until the dispatchState
            // field of the Atom entry reaches a certain point.

            RequestException requestException = null;

            for (int i = 3; i > 0; --i)
            {
                try
                {
                    //// Guarantee: unique result because entities have specific namespaces

                    using (var response = await this.Context.GetAsync(this.Namespace, this.ResourceName))
                    {
                        //// TODO: Use Response.EnsureStatusCode. Is it true that gets always return HttpStatusCode.OK?

                        if (response.Message.StatusCode == HttpStatusCode.NoContent)
                        {
                            throw new RequestException(response.Message, new Message(MessageType.Warning, string.Format("Resource '{0}/{1}' is not ready.", this.Namespace, this.ResourceName)));
                        }

                        if (!response.Message.IsSuccessStatusCode)
                        {
                            throw new RequestException(response.Message, await Message.ReadMessagesAsync(response.XmlReader));
                        }

                        var reader = response.XmlReader;
                        await reader.ReadAsync();

                        if (reader.NodeType == XmlNodeType.XmlDeclaration)
                        {
                            await response.XmlReader.ReadAsync();
                        }

                        if (reader.NodeType != XmlNodeType.Element)
                        {
                            throw new InvalidDataException(); // TODO: Diagnostics
                        }

                        AtomEntry entry;

                        if (reader.Name == "feed")
                        {
                            AtomFeed feed = new AtomFeed();

                            await feed.ReadXmlAsync(reader);

                            int count = feed.Entries.Count;

                            foreach (var feedEntry in feed.Entries)
                            {
                                string id = feedEntry.Title;
                                id.Trim();
                            }

                            if (feed.Entries.Count != 1)
                            {
                                throw new InvalidDataException(); // TODO: Diagnostics
                            }

                            entry = feed.Entries[0];
                        }
                        else
                        {
                            entry = new AtomEntry();
                            await entry.ReadXmlAsync(reader);
                        }

                        this.Snapshot = new EntitySnapshot(entry);
                    }

                    return;
                }
                catch (RequestException e)
                {
                    if (e.StatusCode != System.Net.HttpStatusCode.NoContent)
                    {
                        throw;
                    }
                    requestException = e;
                }
                await Task.Delay(500);
            }

            throw requestException;
        }