Ejemplo n.º 1
0
        /// <summary>
        /// Main workflow entry point
        /// </summary>
        /// <param name="subscription">Pass here valid subscription key</param>
        /// <param name="name">Pass here name for subscription, will be used to store cached file.</param>
        /// <returns></returns>
        public async Task DoWork(string subscription, string name)
        {
            _logger.Information("Checking API subscription {Name}", name);
            // Define main place holder for subscription information block from API.
            SubscriptionModel sub;

            try
            {
                // Download subscription information from API
                sub = JsonConvert.DeserializeObject <SubscriptionModel>(
                    await ApiRequestClient.GetString($"{ApiBase}Subscriptions?subscription={subscription}"));
            }
            catch (Exception e)
            {
                _logger.Fatal(e, "Error while reading subscription for {Name}", name);
                return;
            }
            // Check if subscription is missing.
            if (sub == null)
            {
                _logger.Error("Subscription for {Name} is empty, check key value", name);
                return;
            }
            // Check if subscription has any data sets.
            if (sub.DataSets == null || sub.DataSets.Count == 0)
            {
                _logger.Warning("Subscription {Name} has no data sets, exiting", name);
                return;
            }
            // Check cached json to check if subscription has new data.
            if (!await NeedToProcessDataSet(name, sub))
            {
                _logger.Information("No changes in data for {Name}, exiting", name);
                return;
            }
            // Start processing subscription data.
            _logger.Information("Loaded subscription {Name} data, will process {NumOfSets} data sets",
                                name, sub.DataSets.Count);
            // Loop through all data sets on the subscription.
            foreach (var dataSet in sub.DataSets)
            {
                var fileName = Path.Combine(_basePath, $"{dataSet.DataSourceKey}.json");
                await DownloadDataSet(subscription, dataSet.DataSourceKey, dataSet.NumberOfPoints, fileName);
            }
            // Replace or save subscription block from API to cached file, this will be used to check if there
            // are any updates in future requests.
            try
            {
                await File.WriteAllTextAsync(GetSubscriptionCachedFileName(name),
                                             JsonConvert.SerializeObject(sub));
            }
            catch (Exception e)
            {
                _logger.Error(e, "Writing subscription cache file caused exception");
            }
            _logger.Information("Completed all tasks, exiting");
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Download and save data set into JSON text file.
        /// Please note:
        /// This is simplistic text processing approach that does not include JSON validation
        /// When creating a tool that will later convert or move data to another format, please change the method
        /// to use DTO conversion and validate data context.
        /// </summary>
        /// <param name="subscription">Subscription key</param>
        /// <param name="key">Data set key</param>
        /// <param name="rows">How many rows data set has</param>
        /// <param name="fileName">File name where json will be saved</param>
        /// <returns></returns>
        private async Task DownloadDataSet(string subscription, int key, int rows, string fileName)
        {
            _logger.Information("Downloading data set {Id} to {File}", key, fileName);
            // Set remaining rows count
            var remaining = rows;
            // Set start of download page, we load from 0
            var skip = 0;
            // We will collect JSON strings into string builder, this is simplistic approach and we do not validate data.
            var data = new StringBuilder();

            // Since saved json will contain array of points, append start of array.
            data.Append('[');
            // Loop to page through data segments.
            while (remaining > 0)
            {
                _logger.Information("Remaining rows: {Rows}", remaining);
                // build API request url
                var url = $"{ApiBase}Data?subscription={subscription}&key={key}&numberOfItems={DownloadPageSize}&skip={skip}";
                // shift loop variables
                remaining -= DownloadPageSize;
                skip      += DownloadPageSize;

                // read json
                var json = await ApiRequestClient.GetString(url);

                // Check if response has any data

                if (string.IsNullOrWhiteSpace(json))
                {
                    _logger.Warning("Reading data at point {Skip} returned empty result, ignoring", skip);
                    continue;
                }
                // Small sanity check to make sure response is array like thing.
                if (!json.Contains("[") || !json.Contains("]"))
                {
                    continue;
                }
                // returned json is list, remove list symbols to convert them into block, then append
                json = json.Remove(json.IndexOf('['), 1);
                json = json.Remove(json.LastIndexOf(']'), 1);
                data.AppendLine(json);
                if (remaining > 0)
                {
                    data.Append(',');
                }
            }
            // append array closing symbol.
            data.Append(']');
            // write string builder memory stream into final string.
            var finalJson = data.ToString();

            // check if json ends in a way that will cause error
            if (finalJson.EndsWith(",]"))
            {
                // remove trailing ,
                finalJson = finalJson.Remove(finalJson.LastIndexOf(','), 1);
            }
            // write json to file
            await File.WriteAllTextAsync(fileName, finalJson);

            _logger.Information("Completed saving {File}", fileName);
        }