/// <summary>
        /// Serializes the payload as json string.
        /// </summary>
        /// <param name="payloadBundle">The payload bundle.</param>
        /// <returns>System.Nullable&lt;System.String&gt;.</returns>
        private string?SerializePayloadAsJsonString(PayloadBundle payloadBundle)
        {
            Payload?payload = payloadBundle.GetPayload();

            string jsonData;

            try
            {
                jsonData = JsonConvert.SerializeObject(payload);
            }
            catch (System.Exception exception)
            {
                RollbarErrorUtility.Report(
                    this._rollbarLogger,
                    payload,
                    InternalRollbarError.PayloadSerializationError,
                    "While serializing a payload...",
                    exception,
                    payloadBundle
                    );

                return(null);
            }

            return(jsonData);
        }
Example #2
0
        /// <summary>
        /// Builds the payload record.
        /// </summary>
        /// <param name="payloadBundle">The payload bundle.</param>
        /// <param name="payloadQueue">The payload queue.</param>
        /// <returns>PayloadRecord.</returns>
        private IPayloadRecord?BuildPayloadRecord(PayloadBundle payloadBundle, PayloadQueue payloadQueue)
        {
            try
            {
                if (payloadBundle.Ignorable ||
                    payloadBundle.GetPayload() == null ||
                    !payloadQueue.Client.EnsureHttpContentToSend(payloadBundle)
                    )
                {
                    return(null);
                }

                if (payloadBundle.AsHttpContentToSend == null)
                {
                    return(null);
                }

                Task <string> task = payloadBundle.AsHttpContentToSend.ReadAsStringAsync();
                task.Wait();
                string  payloadContent = task.Result;
                Payload?payload        = payloadBundle.GetPayload();

                if (payload != null && !string.IsNullOrWhiteSpace(payloadContent))
                {
                    return(_storeRepository?.CreatePayloadRecord(payload, payloadContent));
                }
                else
                {
                    return(null);
                }
            }
            catch (System.Exception ex)
            {
                RollbarErrorUtility.Report(
                    payloadQueue.Logger,
                    payloadBundle.GetPayload(),
                    InternalRollbarError.PersistentPayloadRecordError,
                    "While attempting to build persistent payload record...",
                    ex,
                    null
                    );
                return(null);
            }
        }
Example #3
0
        /// <summary>
        /// Processes the specified queue.
        /// </summary>
        /// <param name="queue">The queue.</param>
        /// <param name="response">The response.</param>
        /// <returns>PayloadBundle.</returns>
        private PayloadBundle?Process(PayloadQueue queue, out RollbarResponse?response)
        {
            response = null;

            PayloadBundle?payloadBundle = GetFirstTransmittableBundle(queue);

            if (payloadBundle == null)
            {
                return(null);
            }

            Payload?payload = payloadBundle?.GetPayload();

            if (payload == null) // one more sanity check before proceeding further...
            {
                return(null);
            }

            if (queue.Logger?.Config != null && !queue.Logger.Config.RollbarDeveloperOptions.Transmit)
            {
                response = new RollbarResponse();
                this.OnRollbarEvent(
                    new TransmissionOmittedEventArgs(queue.Logger, payload)
                    );
                return(payloadBundle);
            }

            try
            {
                response = queue.Client.PostAsJson(payloadBundle !);
            }
            catch (System.Exception ex)
            {
                this.OnRollbarEvent(
                    new CommunicationErrorEventArgs(queue.Logger, payload, ex, 0)
                    );
                payloadBundle?.Register(ex);
                throw;
            }

            if (response != null)
            {
                this.OnRollbarEvent(
                    new CommunicationEventArgs(queue.Logger, payload, response)
                    );
            }
            else
            {
                queue.Dequeue(); //we tried our best...
                payloadBundle?.Register(new RollbarException(InternalRollbarError.DequeuingError, "Payload dropped!"));
            }

            return(payloadBundle);
        }
Example #4
0
        /// <summary>
        /// Scrubs the HTTP messages.
        /// </summary>
        /// <param name="payloadBundle">The payload bundle.</param>
        /// <returns><c>true</c> if scrubbed successfully, <c>false</c> otherwise.</returns>
        public bool ScrubHttpMessages(PayloadBundle payloadBundle)
        {
            Payload?payload = payloadBundle.GetPayload();

            if (payload == null)
            {
                return(true);
            }

            DTOs.Request?request = payload.Data.Request;
            if (request?.PostBody is string requestBody &&
                request.Headers != null &&
                request.Headers.TryGetValue("Content-Type", out string?requestContentTypeHeader)
                )
            {
                request.PostBody =
                    this.ScrubHttpMessageBodyContentString(
                        requestBody,
                        requestContentTypeHeader,
                        this.ScrubMask,
                        this.PayloadFieldNames,
                        this.HttpRequestBodyPaths);
            }

            DTOs.Response?response = payload.Data.Response;
            if (response?.Body is string responseBody &&
                response.Headers != null &&
                response.Headers.TryGetValue("Content-Type", out string?responseContentTypeHeader)
                )
            {
                response.Body =
                    this.ScrubHttpMessageBodyContentString(
                        responseBody,
                        responseContentTypeHeader,
                        this.ScrubMask,
                        this.PayloadFieldNames,
                        this.HttpResponseBodyPaths);
            }

            return(true);
        }
Example #5
0
        /// <summary>
        /// Processes the queues.
        /// </summary>
        /// <param name="tokenMetadata">The token metadata.</param>
        private void ProcessQueues(AccessTokenQueuesMetadata tokenMetadata)
        {
            // let's see if we can unregister any recently released queues:
            var releasedQueuesToRemove = tokenMetadata.GetPayloadQueues().Where(q => q.IsReleased && (q.GetPayloadCount() == 0)).ToArray();

            if (releasedQueuesToRemove != null && releasedQueuesToRemove.LongLength > 0)
            {
                foreach (var queue in releasedQueuesToRemove)
                {
                    this.Unregister(queue);
                }
            }

            // process the access token's queues:
            foreach (var queue in tokenMetadata.GetPayloadQueues())
            {
                if (DateTimeOffset.Now < queue.NextDequeueTime)
                {
                    // this means the queue overrides its reporting rate limit via its configuration settings
                    // let's observe its settings and skip processing:
                    continue;
                }

                if (tokenMetadata.IsTransmissionSuspended && DateTimeOffset.Now < tokenMetadata.NextTimeTokenUsage)
                {
                    // the token is suspended and the next usage time is not reached,
                    // let's flush the token queues (we are not allowed to transmit anyway)
                    // and quit processing this token's queues this time (until next processing iteration):
                    foreach (var tokenQueue in tokenMetadata.GetPayloadQueues())
                    {
                        foreach (var flushedBundle in tokenQueue.Flush())
                        {
                            this.OnRollbarEvent(
                                new PayloadDropEventArgs(
                                    queue.Logger,
                                    flushedBundle.GetPayload(),
                                    PayloadDropEventArgs.DropReason.TokenSuspension
                                    )
                                );
                        }
                    }
                    return;
                }

                PayloadBundle?  payloadBundle = null;
                RollbarResponse?response      = null;
                try
                {
                    payloadBundle = Process(queue, out response);
                }
                catch (AggregateException aggregateException)
                {
                    if (aggregateException.InnerExceptions.Any(e => e is HttpRequestException))
                    {
                        this.Persist(queue);
                        continue;
                    }
                    else
                    {
                        var bundle = queue.Dequeue();
                        this.OnRollbarEvent(
                            new PayloadDropEventArgs(queue.Logger, bundle?.GetPayload(), PayloadDropEventArgs.DropReason.InvalidPayload)
                            );
                        queue.Dequeue();
                        throw;
                    }
                }
                catch (System.Exception ex)
                {
                    Debug.WriteLine($"EXCEPTION: {ex}");
                    this.Persist(queue);
                    continue;
                }

                if (payloadBundle != null && response == null)
                {
                    var bundle = queue.Dequeue();
                    this.OnRollbarEvent(
                        new PayloadDropEventArgs(queue.Logger, bundle?.GetPayload(), PayloadDropEventArgs.DropReason.AllTransmissionRetriesFailed)
                        );
                }

                if (payloadBundle == null || response == null)
                {
                    continue;
                }

                tokenMetadata.UpdateNextTimeTokenUsage(response.RollbarRateLimit);

                switch (response.Error)
                {
                case (int)RollbarApiErrorEventArgs.RollbarError.None:
                    payloadBundle.Signal?.Release();
                    queue.Dequeue();
                    break;

                case (int)RollbarApiErrorEventArgs.RollbarError.TooManyRequests:
                    ObeyPayloadTimeout(payloadBundle, queue);
                    this.OnRollbarEvent(
                        new RollbarApiErrorEventArgs(queue.Logger, payloadBundle?.GetPayload(), response)
                        );
                    return;

                default:
                    ObeyPayloadTimeout(payloadBundle, queue);
                    this.OnRollbarEvent(
                        new RollbarApiErrorEventArgs(queue.Logger, payloadBundle?.GetPayload(), response)
                        );
                    break;
                }
            }
        }
        /// <summary>
        /// Ensures the HTTP content to send.
        /// </summary>
        /// <param name="payloadBundle">The payload bundle.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public bool EnsureHttpContentToSend(PayloadBundle payloadBundle)
        {
            if (payloadBundle.AsHttpContentToSend != null)
            {
                return(true);
            }

            Payload?payload = payloadBundle.GetPayload();

            Assumption.AssertNotNull(payload, nameof(payload));

            if (this._payloadTruncator == null ||
                !this._payloadTruncator.TruncatePayload(payloadBundle)
                )
            {
                return(false);
            }

            if (this._payloadScrubber == null ||
                !this._payloadScrubber.ScrubHttpMessages(payloadBundle)
                )
            {
                return(false);
            }

            string?jsonData = SerializePayloadAsJsonString(payloadBundle);

            if (string.IsNullOrWhiteSpace(jsonData))
            {
                return(false);
            }

            try
            {
                jsonData = this._payloadScrubber.ScrubPayload(jsonData !);
            }
            catch (System.Exception exception)
            {
                RollbarErrorUtility.Report(
                    this._rollbarLogger,
                    payload,
                    InternalRollbarError.PayloadScrubbingError,
                    "While scrubbing a payload...",
                    exception,
                    payloadBundle
                    );

                return(false);
            }

            payloadBundle.AsHttpContentToSend =
                new StringContent(jsonData, Encoding.UTF8, "application/json"); //CONTENT-TYPE header

            Assumption.AssertNotNull(
                payloadBundle.AsHttpContentToSend,
                nameof(payloadBundle.AsHttpContentToSend)
                );
#pragma warning disable CA1307 // Specify StringComparison for clarity
            _ = Assumption.AssertTrue(
                string.Equals(payload !.AccessToken, this._rollbarLoggerConfig.RollbarDestinationOptions.AccessToken),
                nameof(payload.AccessToken)
                );
#pragma warning restore CA1307 // Specify StringComparison for clarity

            return(true);
        }