private async static Task <InfluxResultSet <TInfluxRow> > CreateBasedOnInterfaceAsync <TInfluxRow, TTimestamp>( InfluxClient client, IEnumerable <QueryResult> queryResults, string db, bool allowMetadataQuerying, InfluxQueryOptions options) where TInfluxRow : IInfluxRow <TTimestamp>, new() { var timestampParser = client.TimestampParserRegistry.FindTimestampParserOrNull <TTimestamp>(); // In this case, we will contruct objects based on the IInfluxRow interface Dictionary <int, InfluxResult <TInfluxRow> > results = new Dictionary <int, InfluxResult <TInfluxRow> >(); foreach (var queryResult in queryResults) { foreach (var result in queryResult.Results) { InfluxResult <TInfluxRow> existingResult; if (!results.TryGetValue(result.StatementId, out existingResult)) { existingResult = new InfluxResult <TInfluxRow>(result.StatementId, result.Error ?? (result.Series == null ? Errors.UnexpectedQueryResult : null)); results.Add(result.StatementId, existingResult); } else { existingResult.AppendErrorMessage(result.Error); } if (existingResult.Succeeded) { foreach (var series in result.Series) { var name = series.Name; // create influx series var tags = series.Tags?.ToDictionary(x => x.Key, x => x.Value == string.Empty ? null : (object)x.Value) ?? new Dictionary <string, object>(); // find or create influx serie var influxSerie = existingResult.FindGroupInternal(name, tags, true); if (influxSerie == null) { influxSerie = new InfluxSeries <TInfluxRow>(name, tags); existingResult.Series.Add(influxSerie); } // add data to found series await AddValuesToInfluxSeriesByInterfaceAsync <TInfluxRow, TTimestamp>(influxSerie, series, client, db, allowMetadataQuerying, options, timestampParser); } } } } return(new InfluxResultSet <TInfluxRow>(results.Values.ToList())); }
private static InfluxResultSet <TInfluxRow> CreateBasedOnAttributes <TInfluxRow, TTimestamp>( InfluxClient client, IEnumerable <QueryResult> queryResults, InfluxQueryOptions options, InfluxRowTypeInfo <TInfluxRow> propertyMap) where TInfluxRow : new() { // Create type based on attributes Dictionary <int, InfluxResult <TInfluxRow> > results = new Dictionary <int, InfluxResult <TInfluxRow> >(); var timestampParser = client.TimestampParserRegistry.FindTimestampParserOrNull <TTimestamp>(); foreach (var queryResult in queryResults) { foreach (var result in queryResult.Results) { InfluxResult <TInfluxRow> existingResult; if (!results.TryGetValue(result.StatementId, out existingResult)) { existingResult = new InfluxResult <TInfluxRow>(result.StatementId, result.Error ?? (result.Series == null ? Errors.UnexpectedQueryResult : null)); results.Add(result.StatementId, existingResult); } else { existingResult.AppendErrorMessage(result.Error); } // TODO: What if error message is given in following query? if (existingResult.Succeeded) { foreach (var series in result.Series) { var name = series.Name; // create new dictionary, with correct typing (we must potentially convert strings to enums, if the column being used in the GROUP BY is an enum) var tags = CreateTagDictionaryFromSerieBasedOnAttributes(series, propertyMap.All); // find or create influx serie var influxSerie = existingResult.FindGroupInternal(name, tags, true); if (influxSerie == null) { influxSerie = new InfluxSeries <TInfluxRow>(name, tags); existingResult.Series.Add(influxSerie); } // add data to found serie AddValuesToInfluxSeriesByAttributes <TInfluxRow, TTimestamp>(influxSerie, series, propertyMap, options, timestampParser); } } } } return(new InfluxResultSet <TInfluxRow>(results.Values.ToList())); }
public async Task <List <MeasurementRow> > ReadAllMeasurements() { InfluxResult <MeasurementRow> resultSet = await _influxClient.ShowMeasurementsAsync(TimeSeriesSettings.InfluxDatabase); if (resultSet.Series.Count > 0) { InfluxSeries <MeasurementRow> result = resultSet.Series[0]; return(result.Rows); } else { return(new List <MeasurementRow>()); } }
public async Task Handle(TimeSeriesAnalysisRequestEvent @event, string operationName) { UserAnalyticsOperation operation = @event.Operation; try { InfluxResult <DynamicInfluxRow> influxResult = await _timeSeriesService.ReadMeasurementById(operation.TimeSeriesId); List <DynamicInfluxRow> rowsList = influxResult.Series[0].Rows; Series <DateTime?, double> series = rowsList .Select(x => KeyValue.Create( x.Timestamp, (double)x.Fields[operation.Arguments["column"].ToString()])). ToSeries(); // apply operation switch (operationName) { case "Mean": System.Console.WriteLine(series.Mean()); break; case "Min": System.Console.WriteLine(series.Min()); break; case "Max": System.Console.WriteLine(series.Max()); break; default: throw new NotSupportedException(); } operation.Status = OperationStatus.Complete; } catch (Exception e) { operation.Status = OperationStatus.Error; } finally { _eventBus.Publish(new DiagnosticsResponseEvent(operation)); } }
public IActionResult DeleteTimeSeriesById([FromRoute] string timeSeriesMetadataId) { TimeSeriesMetadata timeSeriesMetadata = _timeSeriesMetadataService.GetTimeSeriesMetadata(timeSeriesMetadataId); if (timeSeriesMetadata == null || !timeSeriesMetadata.UserId.ToString().Equals(UserId)) { return(NotFound("user does not have this timeseries")); } string timeSeriesId = timeSeriesMetadata.InfluxId.ToString(); InfluxResult result = _timeSeriesService.DeleteMeasurementById(timeSeriesId).Result; if (!result.Succeeded) { return(NotFound()); } _timeSeriesMetadataService.DeleteTimeSeriesMetadata(timeSeriesMetadataId).Wait(); return(NoContent()); }
public IActionResult GetTimeSeriesMetadataById(string timeseriesId, int pageSize = 20, int offset = 0) { InfluxResult <DynamicInfluxRow> measurementsResult = _timeSeriesService.ReadMeasurementById(timeseriesId).Result; { List <InfluxSeries <DynamicInfluxRow> > series = measurementsResult.Series; if (series.Count != 0) { List <TimeSeriesJsonEntity> timeseriesJsonEntities = new List <TimeSeriesJsonEntity>(); foreach (InfluxSeries <DynamicInfluxRow> t in series) { List <DynamicInfluxRow> rows = t.Rows; foreach (DynamicInfluxRow t1 in rows) { timeseriesJsonEntities.Add(new TimeSeriesJsonEntity() { Id = Guid.NewGuid().ToString(), Name = "", Description = "", Tags = t1.Tags }); } } List <TimeSeriesJsonEntity> page = timeseriesJsonEntities.Skip(offset).Take(pageSize).ToList(); ApiEntityListPage <TimeSeriesJsonEntity> listOfResults = new ApiEntityListPage <TimeSeriesJsonEntity>(page, HttpContext.Request.Path.ToString(), new PaginationProperties() { PageSize = pageSize, Offset = offset, Count = page.Count, HasMore = timeseriesJsonEntities.Count > page.Count }); return(Ok(listOfResults)); } else { return(NotFound()); } } }
public async Task <InfluxResult <DynamicInfluxRow> > ReadMeasurementById(string measurementId, string from, string to, string step) { StringBuilder query = new StringBuilder($"SELECT last(*) FROM \"{measurementId}\""); Dictionary <string, string> parameters = new Dictionary <string, string>(); bool hasStartTime = !string.IsNullOrWhiteSpace(from); bool hasEndTime = !string.IsNullOrWhiteSpace(to); if (hasStartTime || hasEndTime) { query.Append(" WHERE "); if (hasStartTime) { query.Append("time >= $from"); parameters.Add("from", from); } if (hasStartTime && hasEndTime) { query.Append(" AND "); } if (hasEndTime) { query.Append("time <= $to"); parameters.Add("to", to); } } // Vibrant.InfluxDB.Client substitutes all parameters with single quotes (e.g. ...GROUP BY time('1m')) // but InfluxDB requires parameter for time(<interval>) function without quotes (e.g. ...time(1m)) // so, the <step> string parameter should be validated in controller when received from user if (!string.IsNullOrWhiteSpace(step)) { query.Append($" GROUP BY time({step})"); } InfluxResultSet <DynamicInfluxRow> resultSet = await _influxClient.ReadAsync <DynamicInfluxRow>(TimeSeriesSettings.InfluxDatabase, query.ToString(), parameters); // resultSet will contain 1 result in the Results collection (or multiple if you execute multiple queries at once) InfluxResult <DynamicInfluxRow> result = resultSet.Results[0]; return(result); }
private IActionResult MakePageFromMeasurements(InfluxResult <DynamicInfluxRow> measurementsResult, int pageSize, int offset) { List <InfluxSeries <DynamicInfluxRow> > series = measurementsResult.Series; if (series.Count == 0) { return(NotFound()); } List <TimeSeriesDataJsonEntity> timeseriesDataJsonEntities = new List <TimeSeriesDataJsonEntity>(); foreach (InfluxSeries <DynamicInfluxRow> t in series) { List <DynamicInfluxRow> rows = t.Rows; foreach (DynamicInfluxRow t1 in rows) { timeseriesDataJsonEntities.Add(new TimeSeriesDataJsonEntity { Timestamp = t1.Timestamp.ToString(), Tags = t1.Tags, Fields = t1.Fields }); } } List <TimeSeriesDataJsonEntity> page = timeseriesDataJsonEntities.Skip(offset).Take(pageSize).ToList(); ApiEntityListPage <TimeSeriesDataJsonEntity> listOfResults = new ApiEntityListPage <TimeSeriesDataJsonEntity>(page, HttpContext.Request.Path.ToString(), new PaginationProperties() { PageSize = pageSize, Offset = offset, Count = page.Count, HasMore = timeseriesDataJsonEntities.Count > page.Count }); return(Ok(listOfResults)); }
public async Task <InfluxResult> CreateUser(string username, string password) { InfluxResult result = await _influxClient.CreateUserAsync(username, password); return(result); }
public async Task <InfluxResult> DeleteMeasurementById(string measurementId) { InfluxResult result = await _influxClient.DropSeries(TimeSeriesSettings.InfluxDatabase, measurementId); return(result); }
public async Task <bool> ConsumeNextSerieAsync(CancellationToken cancellationToken = default) { if (_consumeCurrentSerieNextTime) { _consumeCurrentSerieNextTime = false; if (_currentStatementId != _currentResult.StatementId) { _consumeCurrentResultNextTime = true; _currentTags = null; _capturedSerie = null; return(false); } if (!InfluxSeriesComparer.Compare(_currentSerie.GroupedTags, _currentTags)) { _currentTags = _currentSerie.GroupedTags; _capturedSerie = _currentSerie; _currentBatch = _currentSerie.Rows; return(true); } } bool hasMoreSeries; bool hasMoreResultsForCurrentStatement = true; while (hasMoreResultsForCurrentStatement) // hasMoreResults { do { // might need to consume both results and series hasMoreSeries = await _resultIterator.ConsumeNextSerieAsync(cancellationToken).ConfigureAwait(false); if (hasMoreSeries) { // consume until the grouped tags changes _currentSerie = _resultIterator.CurrentSerie; if (!InfluxSeriesComparer.Compare(_currentSerie.GroupedTags, _currentTags)) { _currentTags = _currentSerie.GroupedTags; _currentBatch = _currentSerie.Rows; _capturedSerie = _currentSerie; return(true); } } } while(hasMoreSeries); // handle the next result to see if it contains more data for the current statement var hasMoreResults = await _resultIterator.ConsumeNextResultAsync(cancellationToken).ConfigureAwait(false); if (hasMoreResults) { _currentResult = _resultIterator.CurrentResult; hasMoreResultsForCurrentStatement = _currentResult.StatementId == _currentStatementId; if (!hasMoreResultsForCurrentStatement) { _consumeCurrentResultNextTime = true; } } else { hasMoreResultsForCurrentStatement = false; } } _capturedSerie = null; _currentTags = null; return(false); }