changed some code around

This commit is contained in:
Mark van der Wal 2020-03-25 17:49:00 +01:00
parent d546edaa0d
commit e638370ad4
6 changed files with 154 additions and 160 deletions

View File

@ -1,5 +1,4 @@
using System; using System;
using System.Collections;
using System.IO; using System.IO;
using System.Net.Http; using System.Net.Http;
using System.Net.Mime; using System.Net.Mime;
@ -69,6 +68,8 @@ namespace FarmmapsApi.Services
contentStream.ThrowIfNull(nameof(contentStream)); contentStream.ThrowIfNull(nameof(contentStream));
_streamLength = ContentStream.CanSeek ? ContentStream.Length : UnknownSize; _streamLength = ContentStream.CanSeek ? ContentStream.Length : UnknownSize;
body.ChunkSize = ChunkSize;
Body = body; Body = body;
Path = "api/v1/file"; Path = "api/v1/file";
HttpClient = httpClient; HttpClient = httpClient;
@ -93,17 +94,13 @@ namespace FarmmapsApi.Services
/// <summary>Creates a request to initialize a request.</summary> /// <summary>Creates a request to initialize a request.</summary>
private HttpRequestMessage CreateInitializeRequest() private HttpRequestMessage CreateInitializeRequest()
{ {
var baseAddres = HttpClient.BaseAddress;
var uri = new Uri($"{baseAddres.Scheme}://{baseAddres.Host}:{baseAddres.Port}");
var builder = new RequestBuilder() var builder = new RequestBuilder()
{ {
BaseUri = uri, BaseUri = HttpClient.BaseAddress,
Path = Path, Path = Path,
Method = HttpMethod, Method = HttpMethod,
}; };
SetAllPropertyValues(builder);
HttpRequestMessage request = builder.CreateRequest(); HttpRequestMessage request = builder.CreateRequest();
if (ContentType != null) if (ContentType != null)
{ {
@ -121,40 +118,5 @@ namespace FarmmapsApi.Services
return request; return request;
} }
/// <summary>
/// Reflectively enumerate the properties of this object looking for all properties containing the
/// RequestParameterAttribute and copy their values into the request builder.
/// </summary>
private void SetAllPropertyValues(RequestBuilder requestBuilder)
{
Type myType = this.GetType();
var properties = myType.GetProperties();
foreach (var property in properties)
{
var attribute = property.GetCustomAttribute<RequestParameterAttribute>();
if (attribute != null)
{
string name = attribute.Name ?? property.Name.ToLower();
object value = property.GetValue(this, null);
if (value != null)
{
if (!(value is string) && value is IEnumerable valueAsEnumerable)
{
foreach (var elem in valueAsEnumerable)
{
requestBuilder.AddParameter(attribute.Type, name, Utilities.ConvertToString(elem));
}
}
else
{
// Otherwise just convert it to a string.
requestBuilder.AddParameter(attribute.Type, name, Utilities.ConvertToString(value));
}
}
}
}
}
} }
} }

View File

@ -0,0 +1,10 @@
namespace FarmmapsApiSamples
{
public static class Constants
{
public const string USERINPUT_ITEMTYPE = "vnd.farmmaps.itemtype.user.input";
public const string GEOTIFF_ITEMTYPE = "vnd.farmmaps.itemtype.geotiff";
public const string CROPFIELD_ITEMTYPE = "vnd.farmmaps.itemtype.cropfield";
public const string VRANBS_TASK = "vnd.farmmaps.task.vranbs";
}
}

View File

@ -1,5 +1,4 @@
using System; using System;
using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -8,24 +7,22 @@ using FarmmapsApi.Services;
using Google.Apis.Upload; using Google.Apis.Upload;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using static FarmmapsApi.Extensions; using static FarmmapsApiSamples.Constants;
namespace FarmmapsApiSamples namespace FarmmapsApiSamples
{ {
public class NbsApp : IApp public class NbsApp : IApp
{ {
private const string USERINPUT_ITEMTYPE = "vnd.farmmaps.itemtype.user.input";
private const string GEOTIFF_ITEMTYPE = "vnd.farmmaps.itemtype.geotiff";
private const string CROPFIELD_ITEMTYPE = "vnd.farmmaps.itemtype.cropfield";
private const string VRANBS_TASK = "vnd.farmmaps.task.vranbs";
private readonly ILogger<NbsApp> _logger; private readonly ILogger<NbsApp> _logger;
private readonly FarmmapsApiService _farmmapsApiService; private readonly FarmmapsApiService _farmmapsApiService;
private readonly NitrogenService _nitrogenService;
public NbsApp(ILogger<NbsApp> logger, FarmmapsApiService farmmapsApiService) public NbsApp(ILogger<NbsApp> logger, FarmmapsApiService farmmapsApiService,
NitrogenService nitrogenService)
{ {
_logger = logger; _logger = logger;
_farmmapsApiService = farmmapsApiService; _farmmapsApiService = farmmapsApiService;
_nitrogenService = nitrogenService;
farmmapsApiService.EventCallback += OnEvent; farmmapsApiService.EventCallback += OnEvent;
} }
@ -55,7 +52,7 @@ namespace FarmmapsApiSamples
progress => progress =>
{ {
_logger.LogInformation($"Status: {progress.Status} - BytesSent: {progress.BytesSent}"); _logger.LogInformation($"Status: {progress.Status} - BytesSent: {progress.BytesSent}");
if(progress.Status == UploadStatus.Failed) if (progress.Status == UploadStatus.Failed)
_logger.LogError($"Uploading failed {progress.Exception.Message}"); _logger.LogError($"Uploading failed {progress.Exception.Message}");
}); });
@ -67,7 +64,7 @@ namespace FarmmapsApiSamples
var cropfieldItem = await GetOrCreateCropfieldItem(myDriveRoot.Code); var cropfieldItem = await GetOrCreateCropfieldItem(myDriveRoot.Code);
_logger.LogInformation($"Calculating targetN with targetYield: {60}"); _logger.LogInformation($"Calculating targetN with targetYield: {60}");
var targetN = await CalculateTargetN(cropfieldItem, 60); var targetN = await _nitrogenService.CalculateTargetN(cropfieldItem, 60);
_logger.LogInformation($"TargetN: {targetN}"); _logger.LogInformation($"TargetN: {targetN}");
_logger.LogInformation("Calculating nitrogen map"); _logger.LogInformation("Calculating nitrogen map");
@ -84,7 +81,7 @@ namespace FarmmapsApiSamples
private async Task<Item> GetOrCreateCropfieldItem(string parentItemCode) private async Task<Item> GetOrCreateCropfieldItem(string parentItemCode)
{ {
var cropfieldItems = await var cropfieldItems = await
_farmmapsApiService.GetItemChildrenAsync(parentItemCode,CROPFIELD_ITEMTYPE); _farmmapsApiService.GetItemChildrenAsync(parentItemCode, CROPFIELD_ITEMTYPE);
if (cropfieldItems.Count > 0) if (cropfieldItems.Count > 0)
return cropfieldItems[0]; return cropfieldItems[0];
@ -105,106 +102,5 @@ namespace FarmmapsApiSamples
return await _farmmapsApiService.CreateItemAsync(cropfieldItemRequest); return await _farmmapsApiService.CreateItemAsync(cropfieldItemRequest);
} }
/// <summary>
/// Calculates TargetN, makes the assumption the cropfield and user.input(targetn) item have the same parent
/// </summary>
/// <param name="cropfieldItem">The cropfield to base the calculations on</param>
/// <param name="targetYield">The target yield input for the TargetN calculation</param>
/// <returns>The TargetN</returns>
private async Task<double> CalculateTargetN(Item cropfieldItem, int targetYield)
{
var targetNItems = await
_farmmapsApiService.GetItemChildrenAsync(cropfieldItem.ParentCode, USERINPUT_ITEMTYPE);
Item targetNItem;
if (targetNItems.Count == 0)
{
_logger.LogInformation("Creating targetN item");
var itemRequest = CreateTargetNItemRequest(cropfieldItem.ParentCode);
targetNItem = await _farmmapsApiService.CreateItemAsync(itemRequest);
}
else
{
targetNItem = targetNItems[0];
}
var nbsTargetNRequest = new TaskRequest {TaskType = VRANBS_TASK};
nbsTargetNRequest.attributes["operation"] = "targetn";
nbsTargetNRequest.attributes["inputCode"] = targetNItem.Code;
nbsTargetNRequest.attributes["inputType"] = "irmi";
nbsTargetNRequest.attributes["purposeType"] = "consumption";
nbsTargetNRequest.attributes["targetYield"] = targetYield.ToString();
string itemTaskCode = await _farmmapsApiService.QueueTaskAsync(cropfieldItem.Code, nbsTargetNRequest);
await PollTask(TimeSpan.FromSeconds(3), async (tokenSource) =>
{
var itemTaskStatus = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, itemTaskCode);
if (itemTaskStatus.State != ItemTaskState.Processing && itemTaskStatus.State != ItemTaskState.Scheduled)
tokenSource.Cancel();
});
var itemTask = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, itemTaskCode);
if(itemTask.State == ItemTaskState.Error)
{
_logger.LogError($"Something went wrong with task execution: {itemTask.Message}");
return 0;
}
var item = await _farmmapsApiService.GetItemAsync(targetNItem.Code);
if (item.Data.ContainsKey("TargetN"))
return item.Data["TargetN"].Value<double>();
return 0;
}
private async Task<Item> CalculateNitrogenMap(Item cropfieldItem, Item inputItem, double targetN)
{
var nbsNitrogenRequest = new TaskRequest {TaskType = VRANBS_TASK};
nbsNitrogenRequest.attributes["operation"] = "nitrogen";
nbsNitrogenRequest.attributes["inputCode"] = inputItem.Code;
nbsNitrogenRequest.attributes["inputType"] = "irmi";
nbsNitrogenRequest.attributes["targetN"] = targetN.ToString(CultureInfo.InvariantCulture);
string itemTaskCode = await _farmmapsApiService.QueueTaskAsync(cropfieldItem.Code, nbsNitrogenRequest);
await PollTask(TimeSpan.FromSeconds(5), async (tokenSource) =>
{
var itemTaskStatus = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, itemTaskCode);
if (itemTaskStatus.State != ItemTaskState.Processing && itemTaskStatus.State != ItemTaskState.Scheduled)
tokenSource.Cancel();
});
var itemTask = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, itemTaskCode);
if(itemTask.State == ItemTaskState.Error)
{
_logger.LogError($"Something went wrong with task execution: {itemTask.Message}");
return null;
}
var geotiffItems = await
_farmmapsApiService.GetItemChildrenAsync(cropfieldItem.Code, GEOTIFF_ITEMTYPE);
// how to uniquely know which item is really created!?
var nitrogenItem = geotiffItems.SingleOrDefault(i => i.Name.Contains("nitrogen"));
if (nitrogenItem == null)
{
_logger.LogError("Could not find the nitrogen geotiff child item under cropfield");
return null;
}
return nitrogenItem;
}
private ItemRequest CreateTargetNItemRequest(string parentItemCode)
{
return new ItemRequest()
{
ParentCode = parentItemCode,
ItemType = USERINPUT_ITEMTYPE,
Name = "TargetN",
DataDate = DateTime.UtcNow
};
}
} }
} }

View File

@ -0,0 +1,125 @@
using System;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using FarmmapsApi.Models;
using FarmmapsApi.Services;
using Microsoft.Extensions.Logging;
using static FarmmapsApi.Extensions;
using static FarmmapsApiSamples.Constants;
namespace FarmmapsApiSamples
{
public class NitrogenService
{
private readonly ILogger<NitrogenService> _logger;
private readonly FarmmapsApiService _farmmapsApiService;
public NitrogenService(ILogger<NitrogenService> logger, FarmmapsApiService farmmapsApiService)
{
_logger = logger;
_farmmapsApiService = farmmapsApiService;
}
/// <summary>
/// Calculates TargetN, makes the assumption the cropfield and user.input(targetn) item have the same parent
/// </summary>
/// <param name="cropfieldItem">The cropfield to base the calculations on</param>
/// <param name="targetYield">The target yield input for the TargetN calculation</param>
/// <returns>The TargetN</returns>
public async Task<double> CalculateTargetN(Item cropfieldItem, int targetYield)
{
var targetNItems = await
_farmmapsApiService.GetItemChildrenAsync(cropfieldItem.ParentCode, USERINPUT_ITEMTYPE);
Item targetNItem;
if (targetNItems.Count == 0)
{
_logger.LogInformation("Creating targetN item");
var itemRequest = CreateTargetNItemRequest(cropfieldItem.ParentCode);
targetNItem = await _farmmapsApiService.CreateItemAsync(itemRequest);
}
else
{
targetNItem = targetNItems[0];
}
var nbsTargetNRequest = new TaskRequest {TaskType = VRANBS_TASK};
nbsTargetNRequest.attributes["operation"] = "targetn";
nbsTargetNRequest.attributes["inputCode"] = targetNItem.Code;
nbsTargetNRequest.attributes["inputType"] = "irmi";
nbsTargetNRequest.attributes["purposeType"] = "consumption";
nbsTargetNRequest.attributes["targetYield"] = targetYield.ToString();
string itemTaskCode = await _farmmapsApiService.QueueTaskAsync(cropfieldItem.Code, nbsTargetNRequest);
await PollTask(TimeSpan.FromSeconds(3), async (tokenSource) =>
{
var itemTaskStatus = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, itemTaskCode);
if (itemTaskStatus.State != ItemTaskState.Processing && itemTaskStatus.State != ItemTaskState.Scheduled)
tokenSource.Cancel();
});
var itemTask = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, itemTaskCode);
if(itemTask.State == ItemTaskState.Error)
{
_logger.LogError($"Something went wrong with task execution: {itemTask.Message}");
return 0;
}
var item = await _farmmapsApiService.GetItemAsync(targetNItem.Code);
if (item.Data.ContainsKey("TargetN"))
return item.Data.Value<double>("TargetN");
return 0;
}
public async Task<Item> CalculateNitrogenMap(Item cropfieldItem, Item inputItem, double targetN)
{
var nbsNitrogenRequest = new TaskRequest {TaskType = VRANBS_TASK};
nbsNitrogenRequest.attributes["operation"] = "nitrogen";
nbsNitrogenRequest.attributes["inputCode"] = inputItem.Code;
nbsNitrogenRequest.attributes["inputType"] = "irmi";
nbsNitrogenRequest.attributes["targetN"] = targetN.ToString(CultureInfo.InvariantCulture);
string itemTaskCode = await _farmmapsApiService.QueueTaskAsync(cropfieldItem.Code, nbsNitrogenRequest);
await PollTask(TimeSpan.FromSeconds(5), async (tokenSource) =>
{
var itemTaskStatus = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, itemTaskCode);
if (itemTaskStatus.State != ItemTaskState.Processing && itemTaskStatus.State != ItemTaskState.Scheduled)
tokenSource.Cancel();
});
var itemTask = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, itemTaskCode);
if(itemTask.State == ItemTaskState.Error)
{
_logger.LogError($"Something went wrong with task execution: {itemTask.Message}");
return null;
}
var geotiffItems = await
_farmmapsApiService.GetItemChildrenAsync(cropfieldItem.Code, GEOTIFF_ITEMTYPE);
// how to uniquely know which item is really created!?
var nitrogenItem = geotiffItems.SingleOrDefault(i => i.Name.Contains("nitrogen"));
if (nitrogenItem == null)
{
_logger.LogError("Could not find the nitrogen geotiff child item under cropfield");
return null;
}
return nitrogenItem;
}
private ItemRequest CreateTargetNItemRequest(string parentItemCode)
{
return new ItemRequest()
{
ParentCode = parentItemCode,
ItemType = USERINPUT_ITEMTYPE,
Name = "TargetN",
DataDate = DateTime.UtcNow
};
}
}
}

View File

@ -27,6 +27,7 @@ namespace FarmmapsApiSamples
}) })
.AddFilter("System.Net.Http", LogLevel.Warning)) .AddFilter("System.Net.Http", LogLevel.Warning))
.AddFarmmapsServices(configuration) .AddFarmmapsServices(configuration)
.AddTransient<NitrogenService>()
.AddSingleton<IApp, NbsApp>() .AddSingleton<IApp, NbsApp>()
.BuildServiceProvider(); .BuildServiceProvider();

View File

@ -1,6 +1,6 @@
{ {
"Authority": "https://accounts.farmmaps.awtest.nl/", "Authority": "https://accounts.farmmaps.awtest.nl/",
"Endpoint": "http://localhost:8083", "Endpoint": "https://farmmaps.awtest.nl/",
"BasePath": "api/v1", "BasePath": "api/v1",
"DiscoveryEndpointUrl": "https://accounts.farmmaps.awtest.nl/.well-known/openid-configuration", "DiscoveryEndpointUrl": "https://accounts.farmmaps.awtest.nl/.well-known/openid-configuration",
"RedirectUri": "http://example.nl/api", "RedirectUri": "http://example.nl/api",