From 418446e9d2c6d1fb08e2132e12641c3e13601dd6 Mon Sep 17 00:00:00 2001 From: Mark van der Wal Date: Wed, 8 Apr 2020 11:43:53 +0200 Subject: [PATCH] Created a generalservice for helper methods. Moved constants to Farmmaps API project. --- .../Constants.cs | 0 FarmmapsApi/Extensions.cs | 1 + FarmmapsApi/Services/GeneralService.cs | 135 ++++++++++++++++++ FarmmapsApiSamples/Application.cs | 4 +- FarmmapsApiSamples/HerbicideService.cs | 123 ++-------------- FarmmapsApiSamples/NitrogenService.cs | 2 +- FarmmapsApiSamples/Program.cs | 2 +- 7 files changed, 150 insertions(+), 117 deletions(-) rename {FarmmapsApiSamples => FarmmapsApi}/Constants.cs (100%) create mode 100644 FarmmapsApi/Services/GeneralService.cs diff --git a/FarmmapsApiSamples/Constants.cs b/FarmmapsApi/Constants.cs similarity index 100% rename from FarmmapsApiSamples/Constants.cs rename to FarmmapsApi/Constants.cs diff --git a/FarmmapsApi/Extensions.cs b/FarmmapsApi/Extensions.cs index 7f0737f..a9b80dd 100644 --- a/FarmmapsApi/Extensions.cs +++ b/FarmmapsApi/Extensions.cs @@ -27,6 +27,7 @@ namespace FarmmapsApi .AddSingleton() .AddTransient() .AddTransient() + .AddTransient() .AddHttpClient() .AddHttpMessageHandler() .Services; diff --git a/FarmmapsApi/Services/GeneralService.cs b/FarmmapsApi/Services/GeneralService.cs new file mode 100644 index 0000000..377cc4e --- /dev/null +++ b/FarmmapsApi/Services/GeneralService.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using FarmmapsApi.Models; +using Google.Apis.Upload; +using Microsoft.Extensions.Logging; +using static FarmmapsApi.Extensions; +using static FarmmapsApiSamples.Constants; + +namespace FarmmapsApi.Services +{ + public class GeneralService + { + private readonly ILogger _logger; + private readonly FarmmapsApiService _farmmapsApiService; + + private readonly string _downloadFolder = "Downloads"; + + public GeneralService(ILogger logger, FarmmapsApiService farmmapsApiService) + { + _logger = logger; + _farmmapsApiService = farmmapsApiService; + } + + public async Task UploadDataAsync(UserRoot root, string itemType, string filePath, string itemName) + { + var startUpload = DateTime.UtcNow; + var result = await _farmmapsApiService.UploadFile(filePath, root.Code, + progress => _logger.LogInformation($"Status: {progress.Status} - BytesSent: {progress.BytesSent}")); + + if (result.Progress.Status == UploadStatus.Failed) + return null; + + return await FindChildItemAsync(root.Code, itemType, itemName, + i => i.Created >= startUpload && + i.Name.ToLower().Contains(itemName.ToLower())); + } + + public async Task UploadZipWithShapeAsync(UserRoot root, string filePath, string itemName) + { + var startUpload = DateTime.UtcNow; + var result = await _farmmapsApiService.UploadFile(filePath, root.Code, + progress => _logger.LogInformation($"Status: {progress.Status} - BytesSent: {progress.BytesSent}")); + + if (result.Progress.Status == UploadStatus.Failed) + return null; + + var zipName = Path.GetFileNameWithoutExtension(filePath); + Item shapeItem = null; + await PollTask(TimeSpan.FromSeconds(3), async source => + { + var uploadedFilesChildren = await _farmmapsApiService.GetItemChildrenAsync(root.Code); + var zipItems = uploadedFilesChildren.Where(i => i.Name.Contains(zipName)); + var childrenTasks = new List>>(); + foreach (var zipItem in zipItems) + { + childrenTasks.Add(_farmmapsApiService.GetItemChildrenAsync(zipItem.Code, + SHAPE_PROCESSED_ITEMTYPE)); + } + + List[] items = await Task.WhenAll(childrenTasks); + if (items.Length > 0) + { + var flatItems = items.SelectMany(i => i).Where(i => i.Name.Contains(itemName)).ToList(); + if (flatItems.Count > 0) + { + shapeItem = flatItems.Where(i => i.Created >= startUpload).OrderByDescending(i => i.Created) + .First(); + source.Cancel(); + } + } + }); + + return shapeItem; + } + + public async Task ShapeToGeotiff(Item shapeItemCode) + { + var shapeToGeotiffRequest = new TaskRequest() + { + TaskType = "vnd.farmmaps.task.shapetogeotiff" + }; + var taskCode = await _farmmapsApiService.QueueTaskAsync(shapeItemCode.Code, shapeToGeotiffRequest); + + await PollTask(TimeSpan.FromSeconds(3), async (tokenSource) => + { + _logger.LogInformation("Checking shapetogeotiff task status"); + var itemTaskStatus = await _farmmapsApiService.GetTaskStatusAsync(shapeItemCode.Code, taskCode); + if (itemTaskStatus.IsFinished) + tokenSource.Cancel(); + }); + + _logger.LogInformation("Data shape converted to geotiff"); + + // the parent of the shape item is now the tiff item + shapeItemCode = await _farmmapsApiService.GetItemAsync(shapeItemCode.Code); + return await _farmmapsApiService.GetItemAsync(shapeItemCode.ParentCode); + } + + public async Task FindChildItemAsync(string parentCode, string itemType, string containsName, + Func filter = null, int maxTries = 10) + { + Item dataItem = null; + int tries = 0; + await PollTask(TimeSpan.FromSeconds(3), async source => + { + _logger.LogInformation($"Trying to get {containsName} data"); + var uploadedFilesChildren = await _farmmapsApiService.GetItemChildrenAsync(parentCode, itemType); + if (uploadedFilesChildren.Count > 0) + { + Func func = filter ?? (i => i.Name.ToLower().Contains(containsName.ToLower())); + dataItem = uploadedFilesChildren.FirstOrDefault(func); + source.Cancel(); + } + else if (tries == maxTries) + { + source.Cancel(); + } + + tries++; + }); + + if (dataItem == null) + { + _logger.LogError("dataItem not found"); + return null; + } + + _logger.LogInformation($"Found {containsName} item"); + return dataItem; + } + } +} \ No newline at end of file diff --git a/FarmmapsApiSamples/Application.cs b/FarmmapsApiSamples/Application.cs index ef1ee4a..318764e 100644 --- a/FarmmapsApiSamples/Application.cs +++ b/FarmmapsApiSamples/Application.cs @@ -40,8 +40,8 @@ namespace FarmmapsApiSamples await _farmmapsApiService.GetCurrentUserCodeAsync(); var roots = await _farmmapsApiService.GetCurrentUserRootsAsync(); -// await _nitrogenService.TestFlow(roots); - await _herbicideService.TestFlow(roots); + await _nitrogenService.TestFlow(roots); +// await _herbicideService.TestFlow(roots); } catch (Exception ex) { diff --git a/FarmmapsApiSamples/HerbicideService.cs b/FarmmapsApiSamples/HerbicideService.cs index 44db5c0..8a1cf11 100644 --- a/FarmmapsApiSamples/HerbicideService.cs +++ b/FarmmapsApiSamples/HerbicideService.cs @@ -19,14 +19,17 @@ namespace FarmmapsApiSamples { private readonly ILogger _logger; private readonly FarmmapsApiService _farmmapsApiService; + private readonly GeneralService _generalService; private HerbicideAgent liberatorTarweAgent; private readonly string _downloadFolder = "Downloads"; - public HerbicideService(ILogger logger, FarmmapsApiService farmmapsApiService) + public HerbicideService(ILogger logger, FarmmapsApiService farmmapsApiService, + GeneralService generalService) { _logger = logger; _farmmapsApiService = farmmapsApiService; + _generalService = generalService; liberatorTarweAgent = new HerbicideAgent() { @@ -77,7 +80,7 @@ namespace FarmmapsApiSamples var cropfieldItem = await CreateCropfieldSingleLutumItemAsync(myDrive.Code); _logger.LogInformation("Uploading data"); - var inputItem = await UploadDataAsync(uploadedRoot, GEOTIFF_PROCESSED_ITEMTYPE, Path.Combine("Data", "Lutum.tiff"), "Lutum.tiff"); + var inputItem = await _generalService.UploadDataAsync(uploadedRoot, GEOTIFF_PROCESSED_ITEMTYPE, Path.Combine("Data", "Lutum.tiff"), "Lutum.tiff"); if(inputItem == null) { _logger.LogError($"Failed to upload data"); @@ -117,7 +120,7 @@ namespace FarmmapsApiSamples // upload data _logger.LogInformation("Uploading lutum data"); - var inputItem = await UploadZipWithShapeAsync(uploadedRoot, Path.Combine("Data", "vd_born_lutum.zip"), "Lutum"); + var inputItem = await _generalService.UploadZipWithShapeAsync(uploadedRoot, Path.Combine("Data", "vd_born_lutum.zip"), "Lutum"); if(inputItem == null) { _logger.LogError($"Failed to upload lutum data"); @@ -125,7 +128,7 @@ namespace FarmmapsApiSamples } _logger.LogInformation("Uploading organic matter data"); - var inputExtraItem = await UploadZipWithShapeAsync(uploadedRoot, Path.Combine("Data", "vd_born_om.zip"), "OS"); + var inputExtraItem = await _generalService.UploadZipWithShapeAsync(uploadedRoot, Path.Combine("Data", "vd_born_om.zip"), "OS"); if(inputExtraItem == null) { _logger.LogError($"Failed to upload organic matter data"); @@ -133,14 +136,14 @@ namespace FarmmapsApiSamples } // transform shape to geotiff as nbstask only supports tiff input item - var tiffInputItem = await ShapeToGeotiff(inputItem); + var tiffInputItem = await _generalService.ShapeToGeotiff(inputItem); if (tiffInputItem == null) { _logger.LogError($"Failed to convert shape to tiff for inputItem"); return; } - var tiffInputExtraItem = await ShapeToGeotiff(inputExtraItem); + var tiffInputExtraItem = await _generalService.ShapeToGeotiff(inputExtraItem); if (tiffInputExtraItem == null) { _logger.LogError($"Failed to convert shape to tiff for inputExtraItem"); @@ -196,57 +199,6 @@ namespace FarmmapsApiSamples return await _farmmapsApiService.CreateItemAsync(cropfieldItemRequest); } - private async Task UploadDataAsync(UserRoot root, string itemType, string filePath, string itemName) - { - var startUpload = DateTime.UtcNow; - var result = await _farmmapsApiService.UploadFile(filePath, root.Code, - progress => _logger.LogInformation($"Status: {progress.Status} - BytesSent: {progress.BytesSent}")); - - if (result.Progress.Status == UploadStatus.Failed) - return null; - - return await FindChildItemAsync(root.Code, itemType, itemName, - i => i.Created >= startUpload && - i.Name.ToLower().Contains(itemName.ToLower())); - } - - private async Task UploadZipWithShapeAsync(UserRoot root, string filePath, string itemName) - { - var startUpload = DateTime.UtcNow; - var result = await _farmmapsApiService.UploadFile(filePath, root.Code, - progress => _logger.LogInformation($"Status: {progress.Status} - BytesSent: {progress.BytesSent}")); - - if (result.Progress.Status == UploadStatus.Failed) - return null; - - var zipName = Path.GetFileNameWithoutExtension(filePath); - Item shapeItem = null; - await PollTask(TimeSpan.FromSeconds(3), async source => - { - var uploadedFilesChildren = await _farmmapsApiService.GetItemChildrenAsync(root.Code); - var zipItems = uploadedFilesChildren.Where(i => i.Name.Contains(zipName)); - var childrenTasks = new List>>(); - foreach (var zipItem in zipItems) - { - childrenTasks.Add(_farmmapsApiService.GetItemChildrenAsync(zipItem.Code, - SHAPE_PROCESSED_ITEMTYPE)); - } - - List[] items = await Task.WhenAll(childrenTasks); - if (items.Length > 0) - { - var flatItems = items.SelectMany(i => i).Where(i => i.Name.Contains(itemName)).ToList(); - if (flatItems.Count > 0) - { - shapeItem = flatItems.Where(i => i.Created >= startUpload).OrderByDescending(i => i.Created).First(); - source.Cancel(); - } - } - }); - - return shapeItem; - } - private async Task CalculateApplianceMapAsync(Item cropfieldItem, HerbicideAgent agent, params Item[] inputItem) { if (inputItem.Length == 0) @@ -279,7 +231,7 @@ namespace FarmmapsApiSamples } var itemName = $"VRAHerbicide {agent.Middel}"; - var applianceMapItem = await FindChildItemAsync(cropfieldItem.Code, + var applianceMapItem = await _generalService.FindChildItemAsync(cropfieldItem.Code, GEOTIFF_PROCESSED_ITEMTYPE, itemName, i => i.Updated >= itemTask.Finished.GetValueOrDefault(DateTime.UtcNow) && i.Name.ToLower().Contains(itemName.ToLower())); @@ -292,60 +244,5 @@ namespace FarmmapsApiSamples return applianceMapItem; } - - private async Task ShapeToGeotiff(Item shapeItemCode) - { - var shapeToGeotiffRequest = new TaskRequest() - { - TaskType = "vnd.farmmaps.task.shapetogeotiff" - }; - var taskCode = await _farmmapsApiService.QueueTaskAsync(shapeItemCode.Code, shapeToGeotiffRequest); - - await PollTask(TimeSpan.FromSeconds(3), async (tokenSource) => - { - _logger.LogInformation("Checking shapetogeotiff task status"); - var itemTaskStatus = await _farmmapsApiService.GetTaskStatusAsync(shapeItemCode.Code, taskCode); - if (itemTaskStatus.IsFinished) - tokenSource.Cancel(); - }); - - _logger.LogInformation("Data shape converted to geotiff"); - - // the parent of the shape item is now the tiff item - shapeItemCode = await _farmmapsApiService.GetItemAsync(shapeItemCode.Code); - return await _farmmapsApiService.GetItemAsync(shapeItemCode.ParentCode); - } - - private async Task FindChildItemAsync(string parentCode, string itemType, string containsName, - Func filter = null, int maxTries = 10) - { - Item dataItem = null; - int tries = 0; - await PollTask(TimeSpan.FromSeconds(3), async source => - { - _logger.LogInformation($"Trying to get {containsName} data"); - var uploadedFilesChildren = await _farmmapsApiService.GetItemChildrenAsync(parentCode, itemType); - if (uploadedFilesChildren.Count > 0) - { - Func func = filter ?? (i => i.Name.ToLower().Contains(containsName.ToLower())); - dataItem = uploadedFilesChildren.FirstOrDefault(func); - source.Cancel(); - } else if (tries == maxTries) - { - source.Cancel(); - } - - tries++; - }); - - if (dataItem == null) - { - _logger.LogError("dataItem not found"); - return null; - } - - _logger.LogInformation($"Found {containsName} item"); - return dataItem; - } } } \ No newline at end of file diff --git a/FarmmapsApiSamples/NitrogenService.cs b/FarmmapsApiSamples/NitrogenService.cs index d58f629..9e351f5 100644 --- a/FarmmapsApiSamples/NitrogenService.cs +++ b/FarmmapsApiSamples/NitrogenService.cs @@ -150,7 +150,7 @@ namespace FarmmapsApiSamples { _logger.LogInformation("Checking shapetogeotiff task status"); var itemTaskStatus = await _farmmapsApiService.GetTaskStatusAsync(isariaShapeItem.Code, taskCode); - if (itemTaskStatus.State == ItemTaskState.Error || itemTaskStatus.State == ItemTaskState.Ok) + if (itemTaskStatus.IsFinished) tokenSource.Cancel(); }); diff --git a/FarmmapsApiSamples/Program.cs b/FarmmapsApiSamples/Program.cs index e79121a..764b26c 100644 --- a/FarmmapsApiSamples/Program.cs +++ b/FarmmapsApiSamples/Program.cs @@ -30,7 +30,7 @@ namespace FarmmapsApiSamples .BuildServiceProvider(); await serviceProvider.GetService().AuthenticateAsync(); - await serviceProvider.GetService().StartEventHub(); +// await serviceProvider.GetService().StartEventHub(); await serviceProvider.GetService().RunAsync(); } }