Skip to content

Commit

Permalink
Additional refactoring and updates to projects using client
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenkuhn committed Feb 6, 2024
1 parent 21cd7ac commit ce5447b
Show file tree
Hide file tree
Showing 55 changed files with 841 additions and 725 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/dotnet-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,7 @@ jobs:
- name: Build CLI v2
run: dotnet build -c Release Meadow.CLI/Source/v2/Meadow.CLI.v2.sln

- name: Unit Test CLI v2
run: dotnet test -c Release --no-build --no-restore --filter "FullyQualifiedName~.Unit.Tests" .\Meadow.CLI\Source\v2\Meadow.CLI.v2.sln


1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ PublishScripts/
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
!**/Source/v2/Meadow.Cloud.Client/**/packages/*
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
Expand Down
1 change: 0 additions & 1 deletion Source/v2/Meadow.CLI.Core/Meadow.CLI.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Meadow.Cloud.Client\Meadow.Cloud.Client.csproj" />
<ProjectReference Include="..\Meadow.HCom\Meadow.HCom.csproj" />
<ProjectReference Include="..\Meadow.SoftwareManager\Meadow.SoftwareManager.csproj" />
<ProjectReference Include="..\Meadow.UsbLib.Core\Meadow.UsbLib.Core.csproj" />
Expand Down
1 change: 0 additions & 1 deletion Source/v2/Meadow.CLI/Meadow.CLI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@

<ItemGroup>
<ProjectReference Include="..\Meadow.CLI.Core\Meadow.CLI.Core.csproj" />
<ProjectReference Include="..\Meadow.SoftwareManager\Meadow.SoftwareManager.csproj" />
<ProjectReference Include="..\Meadow.UsbLibClassic\Meadow.UsbLibClassic.csproj" />
<ProjectReference Include="..\Meadow.UsbLib\Meadow.UsbLib.csproj" />
</ItemGroup>
Expand Down
1 change: 0 additions & 1 deletion Source/v2/Meadow.Cli/Commands/Current/BaseCloudCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ namespace Meadow.CLI.Commands.DeviceManagement;
public abstract class BaseCloudCommand<T> : BaseCommand<T>
{
public const string DefaultHost = "https://www.meadowcloud.co";
public const string StagingHost = "https://staging.meadowcloud.dev";

protected IdentityManager IdentityManager { get; }
protected UserService UserService { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,12 @@ public FirmwareDownloadCommand(

protected override async ValueTask ExecuteCommand()
{
//Host ??= MeadowCloudClient.DefaultHost;

await _meadowCloudClient.AuthenticateAsync(Host, CancellationToken);

//Logger?.LogInformation($"Retrieving firmware information from Meadow.Cloud{(Host != BaseCloudCommand<FirmwareDownloadCommand>.DefaultHost ? $" ({Host.ToLowerInvariant()})" : string.Empty)}...");

//var token = await IdentityManager.GetAccessToken(CancellationToken);
//if (string.IsNullOrWhiteSpace(token))
//{
// Logger?.LogError($"You must be signed into Meadow.Cloud to execute this command. Run 'meadow cloud login' to do so.");
// return;
//}

//FileManager.MeadowCloudClient.BaseAddress = new Uri(Host);
//FileManager.MeadowCloudClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var isAuthenticated = await _meadowCloudClient.Authenticate(Host, CancellationToken);
if (!isAuthenticated)
{
Logger?.LogError($"You must be signed into Meadow.Cloud to execute this command. Run 'meadow cloud login' to do so.");
return;
}

await FileManager.Refresh();

Expand All @@ -65,7 +56,7 @@ protected override async ValueTask ExecuteCommand()

if (latest == null)
{
Logger?.LogError($"Unable to get latest version information");
Logger?.LogError($"Unable to get latest version information.");
return;
}

Expand All @@ -86,6 +77,12 @@ protected override async ValueTask ExecuteCommand()
return;
}

if (collection[Version] != null)
{
Logger?.LogInformation($"Firmware package '{Version}' already exists locally.");
return;
}

Logger?.LogInformation($"Downloading firmware package '{Version}'...");

try
Expand All @@ -96,11 +93,11 @@ protected override async ValueTask ExecuteCommand()

if (!result)
{
Logger?.LogError($"Unable to download package '{Version}'");
Logger?.LogError($"Unable to download package '{Version}'.");
}
else
{
Logger?.LogInformation($"Firmware package '{Version}' downloaded");
Logger?.LogInformation($"Firmware package '{Version}' downloaded.");

if (explicitVersion == false)
{
Expand Down
9 changes: 9 additions & 0 deletions Source/v2/Meadow.Cloud.Client/ApiTokens/ApiTokenClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Meadow.Cloud.Client.ApiTokens;

public interface IApiTokenClient
{
}

public class ApiTokenClient : IApiTokenClient
{
}
9 changes: 9 additions & 0 deletions Source/v2/Meadow.Cloud.Client/Collections/CollectionClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Meadow.Cloud.Client.Collections;

public interface ICollectionClient
{
}

public class CollectionClient : ICollectionClient
{
}
9 changes: 9 additions & 0 deletions Source/v2/Meadow.Cloud.Client/Commands/CommandClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Meadow.Cloud.Client.Commands;

public interface ICommandClient
{
}

public class CommandClient : ICommandClient
{
}
4 changes: 1 addition & 3 deletions Source/v2/Meadow.Cloud.Client/Constants.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System.ComponentModel;

namespace Meadow.Cloud.Client;
namespace Meadow.Cloud.Client;

public static class Constants
{
Expand Down
9 changes: 9 additions & 0 deletions Source/v2/Meadow.Cloud.Client/Devices/DeviceClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Meadow.Cloud.Client.Devices;

public interface IDeviceClient
{
}

public class DeviceClient : IDeviceClient
{
}
75 changes: 44 additions & 31 deletions Source/v2/Meadow.Cloud.Client/Firmware/FirmwareClient.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
using System;
using System.Net;

namespace Meadow.Cloud.Client.Firmware;
namespace Meadow.Cloud.Client.Firmware;

public interface IFirmwareClient
{
Task<MeadowCloudResponse<IEnumerable<GetFirmwareVersionsResponse>>> GetFirmwareVersionsAsync(string type, CancellationToken cancellationToken = default);
Task<IEnumerable<GetFirmwareVersionsResponse>> GetVersions(string type, CancellationToken cancellationToken = default);

Task<GetFirmwareVersionResponse?> GetVersion(string type, string version, CancellationToken cancellationToken = default);

Task<MeadowCloudResponse<GetFirmwareVersionResponse>> GetFirmwareVersionAsync(string type, string version, CancellationToken cancellationToken = default);
Task<HttpResponseMessage> GetDownloadResponse(string url, CancellationToken cancellationToken = default);

Task<HttpResponseMessage> GetFirmwareDownloadResponseAsync(string path, CancellationToken cancellationToken = default);
Task<HttpResponseMessage> GetDownloadResponse(Uri url, CancellationToken cancellationToken = default);
}

public class FirmwareClient : MeadowCloudClientBase, IFirmwareClient
Expand All @@ -21,7 +20,7 @@ public FirmwareClient(HttpClient httpClient)
_httpClient = httpClient;
}

public async Task<MeadowCloudResponse<IEnumerable<GetFirmwareVersionsResponse>>> GetFirmwareVersionsAsync(string type, CancellationToken cancellationToken = default)
public async Task<IEnumerable<GetFirmwareVersionsResponse>> GetVersions(string type, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(type))
{
Expand All @@ -31,10 +30,15 @@ public async Task<MeadowCloudResponse<IEnumerable<GetFirmwareVersionsResponse>>>
using var request = CreateHttpRequestMessage(HttpMethod.Get, "api/v1/firmware/{0}", type);
using var response = await _httpClient.SendAsync(request, cancellationToken);

return await ProcessResponseAsync<IEnumerable<GetFirmwareVersionsResponse>>(response, cancellationToken);
if (response.StatusCode == HttpStatusCode.NotFound)
{
return Enumerable.Empty<GetFirmwareVersionsResponse>();
}

return await ProcessResponse<IEnumerable<GetFirmwareVersionsResponse>>(response, cancellationToken);
}

public async Task<MeadowCloudResponse<GetFirmwareVersionResponse>> GetFirmwareVersionAsync(string type, string version, CancellationToken cancellationToken = default)
public async Task<GetFirmwareVersionResponse?> GetVersion(string type, string version, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(type))
{
Expand All @@ -54,46 +58,55 @@ public async Task<MeadowCloudResponse<GetFirmwareVersionResponse>> GetFirmwareVe
using var request = CreateHttpRequestMessage(HttpMethod.Get, "api/v1/firmware/{0}/{1}", type, version);
using var response = await _httpClient.SendAsync(request, cancellationToken);

return await ProcessResponseAsync<GetFirmwareVersionResponse>(response, cancellationToken);
if (response.StatusCode == HttpStatusCode.NotFound)
{
return null;
}

return await ProcessResponse<GetFirmwareVersionResponse>(response, cancellationToken);
}

public async Task<HttpResponseMessage> GetFirmwareDownloadResponseAsync(string path, CancellationToken cancellationToken = default)
public async Task<HttpResponseMessage> GetDownloadResponse(string url, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(path))
if (string.IsNullOrWhiteSpace(url))
{
throw new ArgumentException($"'{nameof(path)}' cannot be null or whitespace.", nameof(path));
throw new ArgumentException($"'{nameof(url)}' cannot be null or whitespace.", nameof(url));
}

if (!path.EndsWith(".zip", StringComparison.OrdinalIgnoreCase))
if (!url.EndsWith(".zip", StringComparison.OrdinalIgnoreCase))
{
throw new ArgumentException($"'{nameof(path)}' must be a string that ends with '.zip'.", nameof(path));
throw new ArgumentException($"'{nameof(url)}' must be a URL that ends with '.zip'.", nameof(url));
}

var baseAddress = _httpClient.BaseAddress?.ToString();
if (baseAddress != null && path.StartsWith(baseAddress))
if (baseAddress != null && url.StartsWith(baseAddress))
{
path = path[baseAddress.Length..];
url = url[baseAddress.Length..];
}

using var request = new HttpRequestMessage(HttpMethod.Get, path);
using var request = new HttpRequestMessage(HttpMethod.Get, url);
var response = await _httpClient.SendAsync(request, cancellationToken);

if (!response.IsSuccessStatusCode)
try
{
await EnsureSuccessfulStatusCode(response, cancellationToken);
}
catch
{
var headers = GetHeaders(response);
var statusCode = response.StatusCode;

var message = statusCode switch
{
HttpStatusCode.BadRequest => "The request is missing required information or is malformed.",
HttpStatusCode.Unauthorized => "The request failed due to invalid credentials.",
_ => "The HTTP status code of the response was not expected (" + (int)statusCode + ")."
};

response.Dispose();
throw new MeadowCloudException(message, response.StatusCode, string.Empty, headers, null);
throw;
}

return response;
}

public async Task<HttpResponseMessage> GetDownloadResponse(Uri url, CancellationToken cancellationToken = default)
{
if (url is null)
{
throw new ArgumentNullException(nameof(url));
}

return await GetDownloadResponse(url.ToString(), cancellationToken);
}
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
using System.Text.Json.Serialization;
namespace Meadow.Cloud.Client.Firmware;

namespace Meadow.Cloud.Client.Firmware;

public class GetFirmwareVersionResponse
public class GetFirmwareVersionResponse(string version, string minCLIVersion, string downloadUrl, string networkDownloadUrl)
{
public GetFirmwareVersionResponse(string version, string minCLIVersion, string downloadUrl, string networkDownloadUrl)
{
Version = version;
MinCLIVersion = minCLIVersion;
DownloadUrl = downloadUrl;
NetworkDownloadUrl = networkDownloadUrl;
}

[JsonPropertyName("version")]
public string Version { get; set; }
public string Version { get; set; } = version;

[JsonPropertyName("minCLIVersion")]
public string MinCLIVersion { get; set; }
public string MinCLIVersion { get; set; } = minCLIVersion;

[JsonPropertyName("downloadUrl")]
public string DownloadUrl { get; set; }
public string DownloadUrl { get; set; } = downloadUrl;

[JsonPropertyName("networkDownloadUrl")]
public string NetworkDownloadUrl { get; set; }
public string NetworkDownloadUrl { get; set; } = networkDownloadUrl;
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
using System.Text.Json.Serialization;
namespace Meadow.Cloud.Client.Firmware;

namespace Meadow.Cloud.Client.Firmware;

public class GetFirmwareVersionsResponse
public class GetFirmwareVersionsResponse(string version, DateTimeOffset lastModifiedAt)
{
public GetFirmwareVersionsResponse(string version, DateTimeOffset lastModifiedAt)
{
Version = version;
LastModifiedAt = lastModifiedAt;
}

[JsonPropertyName("version")]
public string Version { get; set; }
public string Version { get; set; } = version;

[JsonPropertyName("lastModifiedAt")]
public DateTimeOffset LastModifiedAt { get; set; }
public DateTimeOffset LastModifiedAt { get; set; } = lastModifiedAt;
}
Loading

0 comments on commit ce5447b

Please sign in to comment.