protected internal WriteApiAsync(InfluxDBClientOptions options, WriteService service,
                                         InfluxDBClient influxDbClient)
        {
            Arguments.CheckNotNull(service, nameof(service));
            Arguments.CheckNotNull(influxDbClient, nameof(_influxDbClient));

            _options        = options;
            _influxDbClient = influxDbClient;
            _service        = service;
        }
        /// <summary>
        /// Post onboarding request, to setup initial user, org and bucket.
        /// </summary>
        /// <param name="url">the url to connect to the InfluxDB</param>
        /// <param name="onboarding">the defaults</param>
        /// <returns>Created default user, bucket, org.</returns>
        public static async Task <OnboardingResponse> Onboarding(string url, OnboardingRequest onboarding)
        {
            Arguments.CheckNonEmptyString(url, nameof(url));
            Arguments.CheckNotNull(onboarding, nameof(onboarding));


            using (var client = new InfluxDBClient(InfluxDBClientOptions.Builder.CreateNew().Url(url).Build()))
            {
                return(await client.OnboardingAsync(onboarding));
            }
        }
        private async Task UpdateUserPasswordAsync(string userId, string userName, string oldPassword,
                                                   string newPassword)
        {
            Arguments.CheckNotNull(userId, nameof(userId));
            Arguments.CheckNotNull(userName, nameof(userName));
            Arguments.CheckNotNull(oldPassword, nameof(oldPassword));
            Arguments.CheckNotNull(newPassword, nameof(newPassword));

            var header = InfluxDBClient.AuthorizationHeader(userName, oldPassword);

            await _service.PutUsersIDPasswordAsync(userId, new PasswordResetBody(newPassword), null, header);
        }
        /// <summary>
        /// Update the password to a currently authenticated user.
        /// </summary>
        /// <param name="oldPassword">old password</param>
        /// <param name="newPassword">new password</param>
        /// <returns>currently authenticated user</returns>
        public async Task MeUpdatePasswordAsync(string oldPassword, string newPassword)
        {
            Arguments.CheckNotNull(oldPassword, nameof(oldPassword));
            Arguments.CheckNotNull(newPassword, nameof(newPassword));

            var me = await MeAsync().ConfigureAwait(false);

            if (me == null)
            {
                Trace.WriteLine("User is not authenticated.");
                return;
            }

            var header = InfluxDBClient.AuthorizationHeader(me.Name, oldPassword);

            await _service.PutMePasswordAsync(new PasswordResetBody(newPassword), null, header).ConfigureAwait(false);
        }
        /// <summary>
        /// Update the password to a currently authenticated user.
        /// </summary>
        /// <param name="oldPassword">old password</param>
        /// <param name="newPassword">new password</param>
        /// <returns>currently authenticated user</returns>
        public async Task MeUpdatePasswordAsync(string oldPassword, string newPassword)
        {
            Arguments.CheckNotNull(oldPassword, nameof(oldPassword));
            Arguments.CheckNotNull(newPassword, nameof(newPassword));

            await MeAsync().ContinueWith(async t =>
            {
                if (t.Result == null)
                {
                    Trace.WriteLine("User is not authenticated.");

                    return;
                }

                var header = InfluxDBClient.AuthorizationHeader(t.Result.Name, oldPassword);

                await _service.PutMePasswordAsync(new PasswordResetBody(newPassword), null, header);
            }).Unwrap();
        }
        protected internal WriteApi(InfluxDBClientOptions options, WriteService service, WriteOptions writeOptions,
                                    InfluxDBClient influxDbClient)
        {
            Arguments.CheckNotNull(service, nameof(service));
            Arguments.CheckNotNull(writeOptions, nameof(writeOptions));
            Arguments.CheckNotNull(influxDbClient, nameof(_influxDbClient));

            _options        = options;
            _influxDbClient = influxDbClient;

            // backpreasure - is not implemented in C#
            //
            // => use unbound buffer
            //
            // https://github.com/dotnet/reactive/issues/19

            var observable = _subject.ObserveOn(writeOptions.WriteScheduler);

            var boundary = observable
                           .Buffer(TimeSpan.FromMilliseconds(writeOptions.FlushInterval), writeOptions.BatchSize,
                                   writeOptions.WriteScheduler)
                           .Merge(_flush);

            observable
            //
            // Batching
            //
            .Window(boundary)
            //
            // Group by key - same bucket, same org
            //
            .SelectMany(it => it.GroupBy(batchWrite => batchWrite.Options))
            //
            // Create Write Point = bucket, org, ... + data
            //
            .Select(grouped =>
            {
                var aggregate = grouped
                                .Aggregate(new StringBuilder(""), (builder, batchWrite) =>
                {
                    var data = batchWrite.ToLineProtocol();

                    if (string.IsNullOrEmpty(data))
                    {
                        return(builder);
                    }

                    if (builder.Length > 0)
                    {
                        builder.Append("\n");
                    }

                    return(builder.Append(data));
                }).Select(builder => builder.ToString());

                return(aggregate.Select(records => new BatchWriteRecord(grouped.Key, records)));
            })
            //
            // Jitter
            //
            .Select(source =>
            {
                if (writeOptions.JitterInterval <= 0)
                {
                    return(source);
                }

                return(source.Delay(_ => Observable.Timer(TimeSpan.FromMilliseconds(JitterDelay(writeOptions)), Scheduler.CurrentThread)));
            })
            .Concat()
            //
            // Map to Async request
            //
            .Where(batchWriteItem => !string.IsNullOrEmpty(batchWriteItem.ToLineProtocol()))
            .Select(batchWriteItem =>
            {
                var org          = batchWriteItem.Options.OrganizationId;
                var bucket       = batchWriteItem.Options.Bucket;
                var lineProtocol = batchWriteItem.ToLineProtocol();
                var precision    = batchWriteItem.Options.Precision;

                return(Observable
                       .Defer(() =>
                              service.PostWriteAsyncWithIRestResponse(org, bucket,
                                                                      Encoding.UTF8.GetBytes(lineProtocol), null,
                                                                      "identity", "text/plain; charset=utf-8", null, "application/json", null, precision)
                              .ToObservable())
                       .RetryWhen(f => f.SelectMany(e =>
                {
                    if (e is HttpException httpException)
                    {
                        //
                        // This types is not able to retry
                        //
                        if (httpException.Status != 429 && httpException.Status != 503)
                        {
                            throw httpException;
                        }

                        var retryInterval = (httpException.RetryAfter * 1000 ?? writeOptions.RetryInterval) +
                                            JitterDelay(writeOptions);

                        var retryable = new WriteRetriableErrorEvent(org, bucket, precision, lineProtocol,
                                                                     httpException, retryInterval);
                        Publish(retryable);

                        return Observable.Timer(TimeSpan.FromMilliseconds(retryInterval));
                    }

                    throw e;
                }))
                       .Select(result =>
                {
                    // ReSharper disable once ConvertIfStatementToReturnStatement
                    if (result.IsSuccessful)
                    {
                        return Notification.CreateOnNext(result);
                    }

                    return Notification.CreateOnError <IRestResponse>(HttpException.Create(result));
                })
                       .Catch <Notification <IRestResponse>, Exception>(ex =>
                {
                    var error = new WriteErrorEvent(org, bucket, precision, lineProtocol, ex);
                    Publish(error);

                    return Observable.Return(Notification.CreateOnError <IRestResponse>(ex));
                }).Do(res =>
                {
                    if (res.Kind == NotificationKind.OnNext)
                    {
                        var success = new WriteSuccessEvent(org, bucket, precision, lineProtocol);
                        Publish(success);
                    }
                }));
            })
            .Concat()
            .Subscribe(
                notification =>
            {
                switch (notification.Kind)
                {
                case NotificationKind.OnNext:
                    Trace.WriteLine($"The batch item: {notification} was processed successfully.");
                    break;

                case NotificationKind.OnError:
                    Trace.WriteLine(
                        $"The batch item wasn't processed successfully because: {notification.Exception}");
                    break;

                default:
                    Trace.WriteLine($"The batch item: {notification} was processed");
                    break;
                }
            },
                exception => Trace.WriteLine($"The unhandled exception occurs: {exception}"),
                () => Trace.WriteLine("The WriteApi was disposed."));
        }
示例#7
0
        /// <summary>
        /// Get a sources health.
        /// </summary>
        /// <param name="sourceId">source to check health</param>
        /// <returns>health of source</returns>
        public async Task <HealthCheck> Health(string sourceId)
        {
            Arguments.CheckNonEmptyString(sourceId, nameof(sourceId));

            return(await InfluxDBClient.GetHealth(_service.GetSourcesIDHealthAsync(sourceId)));
        }
示例#8
0
        protected internal WriteApi(
            InfluxDBClientOptions options,
            WriteService service,
            WriteOptions writeOptions,
            IDomainObjectMapper mapper,
            InfluxDBClient influxDbClient,
            IObservable <Unit> disposeCommand)
        {
            Arguments.CheckNotNull(service, nameof(service));
            Arguments.CheckNotNull(writeOptions, nameof(writeOptions));
            Arguments.CheckNotNull(mapper, nameof(mapper));
            Arguments.CheckNotNull(influxDbClient, nameof(_influxDbClient));
            Arguments.CheckNotNull(disposeCommand, nameof(disposeCommand));

            _options        = options;
            _mapper         = mapper;
            _influxDbClient = influxDbClient;

            _unsubscribeDisposeCommand = disposeCommand.Subscribe(_ => Dispose());

            // backpreasure - is not implemented in C#
            //
            // => use unbound buffer
            //
            // https://github.com/dotnet/reactive/issues/19



            IObservable <IObservable <BatchWriteRecord> > batches = _subject
                                                                    //
                                                                    // Batching
                                                                    //
                                                                    .Publish(connectedSource =>
            {
                var trigger = Observable.Merge(
                    // triggered by time & count
                    connectedSource.Window(TimeSpan.FromMilliseconds(
                                               writeOptions.FlushInterval),
                                           writeOptions.BatchSize,
                                           writeOptions.WriteScheduler),
                    // flush trigger
                    _flush
                    );
                return(connectedSource
                       .Window(trigger));
            })
                                                                    //
                                                                    // Group by key - same bucket, same org
                                                                    //
                                                                    .SelectMany(it => it.GroupBy(batchWrite => batchWrite.Options))
                                                                    //
                                                                    // Create Write Point = bucket, org, ... + data
                                                                    //
                                                                    .Select(grouped =>
            {
                var aggregate = grouped
                                .Aggregate(_stringBuilderPool.Get(), (builder, batchWrite) =>
                {
                    var data = batchWrite.ToLineProtocol();

                    if (string.IsNullOrEmpty(data))
                    {
                        return(builder);
                    }

                    if (builder.Length > 0)
                    {
                        builder.Append("\n");
                    }

                    return(builder.Append(data));
                }).Select(builder =>
                {
                    var result = builder.ToString();
                    builder.Clear();
                    _stringBuilderPool.Return(builder);
                    return(result);
                });

                return(aggregate.Select(records => new BatchWriteRecord(grouped.Key, records))
                       .Where(batchWriteItem => !string.IsNullOrEmpty(batchWriteItem.ToLineProtocol())));
            });

            if (writeOptions.JitterInterval > 0)
            {
                batches = batches
                          //
                          // Jitter
                          //
                          .Select(source =>
                {
                    return(source.Delay(_ => Observable.Timer(TimeSpan.FromMilliseconds(RetryAttempt.JitterDelay(writeOptions)), writeOptions.WriteScheduler)));
                });
            }
            var query = batches
                        .Concat()
                        //
                        // Map to Async request
                        //
                        .Select(batchWriteItem =>
            {
                var org          = batchWriteItem.Options.OrganizationId;
                var bucket       = batchWriteItem.Options.Bucket;
                var lineProtocol = batchWriteItem.ToLineProtocol();
                var precision    = batchWriteItem.Options.Precision;

                return(Observable
                       .Defer(() =>
                              service.PostWriteAsyncWithIRestResponse(org, bucket,
                                                                      Encoding.UTF8.GetBytes(lineProtocol), null,
                                                                      "identity", "text/plain; charset=utf-8", null, "application/json", null, precision)
                              .ToObservable())
                       .RetryWhen(f => f
                                  .Zip(Observable.Range(1, writeOptions.MaxRetries + 1), (exception, count)
                                       => new RetryAttempt(exception, count, writeOptions))
                                  .SelectMany(attempt =>
                {
                    if (attempt.IsRetry())
                    {
                        var retryInterval = attempt.GetRetryInterval();

                        var retryable = new WriteRetriableErrorEvent(org, bucket, precision, lineProtocol,
                                                                     attempt.Error, retryInterval);

                        Publish(retryable);

                        return Observable.Timer(TimeSpan.FromMilliseconds(retryInterval),
                                                writeOptions.WriteScheduler);
                    }

                    throw attempt.Error;
                }))
                       .Select(result =>
                {
                    // ReSharper disable once ConvertIfStatementToReturnStatement
                    if (result.IsSuccessful)
                    {
                        return Notification.CreateOnNext(result);
                    }

                    return Notification.CreateOnError <IRestResponse>(HttpException.Create(result, result.Content));
                })
                       .Catch <Notification <IRestResponse>, Exception>(ex =>
                {
                    var error = new WriteErrorEvent(org, bucket, precision, lineProtocol, ex);
                    Publish(error);

                    return Observable.Return(Notification.CreateOnError <IRestResponse>(ex));
                }).Do(res =>
                {
                    if (res.Kind == NotificationKind.OnNext)
                    {
                        var success = new WriteSuccessEvent(org, bucket, precision, lineProtocol);
                        Publish(success);
                    }
                }));
            })
                        .Concat()
                        .Subscribe(
                notification =>
            {
                switch (notification.Kind)
                {
                case NotificationKind.OnNext:
                    Trace.WriteLine($"The batch item: {notification} was processed successfully.");
                    break;

                case NotificationKind.OnError:
                    Trace.WriteLine(
                        $"The batch item wasn't processed successfully because: {notification.Exception}");
                    break;

                default:
                    Trace.WriteLine($"The batch item: {notification} was processed");
                    break;
                }
            },
                exception =>
            {
                _disposed = true;
                Trace.WriteLine($"The unhandled exception occurs: {exception}");
            },
                () =>
            {
                _disposed = true;
                Trace.WriteLine("The WriteApi was disposed.");
            });
        }