Skip to content

Commit

Permalink
feat(Solution): Added the CLI application to the solution (WIP)
Browse files Browse the repository at this point in the history
Signed-off-by: Charles d'Avernas <[email protected]>
  • Loading branch information
cdavernas committed Jun 1, 2024
1 parent dd2c375 commit 59e1962
Show file tree
Hide file tree
Showing 31 changed files with 837 additions and 42 deletions.
9 changes: 8 additions & 1 deletion Synapse.sln
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Synapse.Runtime.Containeriz
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Synapse.Runner", "src\runner\Synapse.Runner\Synapse.Runner.csproj", "{E5FAA9BA-07C3-49CF-AD3B-897AE1D0B018}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Synapse.Dashboard.StateManagement", "src\dashboard\Synapse.Dashboard.StateManagement\Synapse.Dashboard.StateManagement.csproj", "{91EF9F64-4997-407C-B353-C26B1421D0FB}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Synapse.Dashboard.StateManagement", "src\dashboard\Synapse.Dashboard.StateManagement\Synapse.Dashboard.StateManagement.csproj", "{91EF9F64-4997-407C-B353-C26B1421D0FB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Synapse.Operator", "src\operator\Synapse.Operator\Synapse.Operator.csproj", "{A9085F4A-5FDF-4F4A-B267-A03BC5E0FDB0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Synapse.Cli", "src\cli\Synapse.Cli\Synapse.Cli.csproj", "{C86F6C8B-5946-433D-9E09-2C0269CE6372}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -131,6 +133,10 @@ Global
{A9085F4A-5FDF-4F4A-B267-A03BC5E0FDB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A9085F4A-5FDF-4F4A-B267-A03BC5E0FDB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A9085F4A-5FDF-4F4A-B267-A03BC5E0FDB0}.Release|Any CPU.Build.0 = Release|Any CPU
{C86F6C8B-5946-433D-9E09-2C0269CE6372}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C86F6C8B-5946-433D-9E09-2C0269CE6372}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C86F6C8B-5946-433D-9E09-2C0269CE6372}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C86F6C8B-5946-433D-9E09-2C0269CE6372}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -160,6 +166,7 @@ Global
{E5FAA9BA-07C3-49CF-AD3B-897AE1D0B018} = {1DA47E5F-B23A-4D3C-96AA-4BD2662AB946}
{91EF9F64-4997-407C-B353-C26B1421D0FB} = {7DF998B8-0FB1-470E-8ED0-EA1CC7B16901}
{A9085F4A-5FDF-4F4A-B267-A03BC5E0FDB0} = {32EAD165-3D99-42CD-B3AF-05136DCC7F35}
{C86F6C8B-5946-433D-9E09-2C0269CE6372} = {D3B3B95D-B598-4B13-B754-4A7E530405A6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2A6C03D6-355A-4B39-9F2B-D0FDE429C0E2}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using Synapse.Api.Client.Http.Configuration;
using Synapse.Api.Client.Services;

namespace Synapse.Api.Client;

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using Neuroglia.Data.Infrastructure.ResourceOriented;
using Synapse.Api.Client.Services;

namespace Synapse.Api.Client;

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using Microsoft.Extensions.Logging;
using Neuroglia;
using Neuroglia.Serialization;
using System.Net.Mime;
using System.Text;

namespace Synapse.Api.Client.Services;

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using Microsoft.Extensions.Logging;
using Neuroglia;
using Neuroglia.Data;
using Neuroglia.Data.Infrastructure.ResourceOriented;
using Neuroglia.Serialization;
using System.Net.Mime;
using System.Text;

namespace Synapse.Api.Client.Services;

/// <summary>
Expand Down Expand Up @@ -229,7 +221,7 @@ public virtual async Task DeleteAsync(string name, string @namespace, Cancellati
var resource = new TResource();
var uri = $"/api/{resource.Definition.Version}/{resource.Definition.Plural}/{@namespace}/{name}";
using var request = await this.ProcessRequestAsync(new HttpRequestMessage(HttpMethod.Delete, uri), cancellationToken).ConfigureAwait(false);
await ProcessResponseAsync(await this.HttpClient.SendAsync(request, cancellationToken).ConfigureAwait(false), cancellationToken).ConfigureAwait(false);
await this.ProcessResponseAsync(await this.HttpClient.SendAsync(request, cancellationToken).ConfigureAwait(false), cancellationToken).ConfigureAwait(false);
}

/// <summary>
Expand Down
2 changes: 0 additions & 2 deletions src/api/Synapse.Api.Client.Http/Services/ResourceWatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using Neuroglia.Data.Infrastructure.ResourceOriented;

namespace Synapse.Api.Client.Services;

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using Microsoft.AspNetCore.SignalR.Client;
using Neuroglia.Data.Infrastructure.ResourceOriented;
using Neuroglia.Eventing.CloudEvents;
using System.Reactive.Linq;
using System.Reactive.Subjects;

namespace Synapse.Api.Client.Services;

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Neuroglia;
using Neuroglia.Data.Infrastructure.ResourceOriented;
using Neuroglia.Serialization;

namespace Synapse.Api.Client.Services;

/// <summary>
Expand Down
16 changes: 16 additions & 0 deletions src/api/Synapse.Api.Client.Http/Usings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.

global using Microsoft.AspNetCore.SignalR.Client;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.DependencyInjection.Extensions;
global using Microsoft.Extensions.Logging;
global using Microsoft.Extensions.Options;
global using Neuroglia;
global using Neuroglia.Data;
global using Neuroglia.Data.Infrastructure.ResourceOriented;
global using Neuroglia.Eventing.CloudEvents;
global using Neuroglia.Serialization;
global using Synapse.Api.Client.Http.Configuration;
global using Synapse.Api.Client.Services;
global using Synapse.Resources;
global using System.Net.Mime;
global using System.Reactive.Linq;
global using System.Reactive.Subjects;
global using System.Text;
14 changes: 14 additions & 0 deletions src/cli/Synapse.Cli/CliConstants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Synapse.Cli;

/// <summary>
/// Exposes constants and statics used by the CLI
/// </summary>
internal static class CliConstants
{

/// <summary>
/// Gets the name of the CLI configuration file
/// </summary>
public const string ConfigurationFileName = "config.yaml";

}
41 changes: 41 additions & 0 deletions src/cli/Synapse.Cli/Commands/Command.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
namespace Synapse.Cli.Commands;

/// <summary>
/// Represents the base class for all <see cref="System.CommandLine.Command"/> implementations
/// </summary>
public abstract class Command
: System.CommandLine.Command
{

/// <summary>
/// Initializes a new <see cref="Command"/>
/// </summary>
/// <param name="serviceProvider">The current <see cref="IServiceProvider"/></param>
/// <param name="loggerFactory">The service used to create <see cref="ILogger"/>s</param>
/// <param name="api">The service used to interact with the remote Synapse API</param>
/// <param name="name">The <see cref="Command"/>'s name</param>
/// <param name="description">The <see cref="Command"/>'s description</param>
protected Command(IServiceProvider serviceProvider, ILoggerFactory loggerFactory, ISynapseApiClient api, string name, string description)
: base(name, description)
{
this.ServiceProvider = serviceProvider;
this.Logger = loggerFactory.CreateLogger(this.GetType());
this.Api = api;
}

/// <summary>
/// Gets the current <see cref="IServiceProvider"/>
/// </summary>
protected IServiceProvider ServiceProvider { get; }

/// <summary>
/// Gets the service used to perform logging
/// </summary>
protected ILogger Logger { get; }

/// <summary>
/// Gets the service used to interact with the remote Synapse API
/// </summary>
protected ISynapseApiClient Api { get; }

}
56 changes: 56 additions & 0 deletions src/cli/Synapse.Cli/Commands/Config/DeleteApiCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using Microsoft.Extensions.Options;
using Synapse.Cli.Configuration;
using Synapse.Cli.Services;

namespace Synapse.Cli.Commands.Config;

/// <summary>
/// Represents the <see cref="Command"/> used to configure the CLI to delete the specified API configuration
/// </summary>
internal class DeleteApiCommand
: Command
{

/// <summary>
/// Gets the <see cref="UseApiCommand"/>'s name
/// </summary>
public const string CommandName = "delete-api";
/// <summary>
/// Gets the <see cref="UseApiCommand"/>'s description
/// </summary>
public const string CommandDescription = "Deletes the API configuration with the specified name.";

/// <inheritdoc/>
public DeleteApiCommand(IServiceProvider serviceProvider, ILoggerFactory loggerFactory, ISynapseApiClient api, IOptionsManager optionsManager, IOptionsMonitor<ApplicationOptions> applicationOptions)
: base(serviceProvider, loggerFactory, api, CommandName, CommandDescription)
{
this.OptionsManager = optionsManager;
this.ApplicationOptions = applicationOptions;
this.Add(new Argument<string>("name") { Description = "The name of the API configuration to delete." });
this.Handler = CommandHandler.Create<string>(HandleAsync);
}

/// <summary>
/// Gets the service used to manage the application's options
/// </summary>
protected IOptionsManager OptionsManager { get; }

/// <summary>
/// Gets the current <see cref="ApplicationOptions"/>
/// </summary>
protected IOptionsMonitor<ApplicationOptions> ApplicationOptions { get; }

/// <summary>
/// Handles the <see cref="DeleteApiCommand"/>
/// </summary>
/// <param name="name">The name of the API configuration to use</param>
/// <returns>A new awaitable <see cref="Task"/></returns>
public async Task HandleAsync(string name)
{
ArgumentException.ThrowIfNullOrWhiteSpace(name);
if (this.ApplicationOptions.CurrentValue.Api.Current == name) throw new NotSupportedException($"Failed to delete the API configuration with name '{name}' because it is the API currently in use.");
if (!this.ApplicationOptions.CurrentValue.Api.Configurations.Remove(name)) throw new NullReferenceException($"Failed to find a configured API with name '{name}'.");
await this.OptionsManager.UpdateOptionsAsync(this.ApplicationOptions.CurrentValue);
}

}
72 changes: 72 additions & 0 deletions src/cli/Synapse.Cli/Commands/Config/GetApisCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using Microsoft.Extensions.Options;
using Synapse.Cli.Configuration;
using Synapse.Cli.Services;
using Synapse.Resources;

namespace Synapse.Cli.Commands.Config;

/// <summary>
/// Represents the <see cref="Command"/> used to configure the API used by the Synapse CLI
/// </summary>
internal class GetApisCommand
: Command
{

/// <summary>
/// Gets the <see cref="GetApisCommand"/>'s name
/// </summary>
public const string CommandName = "get-apis";
/// <summary>
/// Gets the <see cref="GetApisCommand"/>'s description
/// </summary>
public const string CommandDescription = "Retrieves all configured APIs";

/// <inheritdoc/>
public GetApisCommand(IServiceProvider serviceProvider, ILoggerFactory loggerFactory, ISynapseApiClient api, IOptionsManager optionsManager, IOptionsMonitor<ApplicationOptions> applicationOptions)
: base(serviceProvider, loggerFactory, api, CommandName, CommandDescription)
{
this.OptionsManager = optionsManager;
this.ApplicationOptions = applicationOptions;
this.Handler = CommandHandler.Create(HandleAsync);
}

/// <summary>
/// Gets the service used to manage the application's options
/// </summary>
protected IOptionsManager OptionsManager { get; }

/// <summary>
/// Gets the current <see cref="ApplicationOptions"/>
/// </summary>
protected IOptionsMonitor<ApplicationOptions> ApplicationOptions { get; }

/// <summary>
/// Handles the <see cref="GetApisCommand"/>
/// </summary>
/// <returns>A new awaitable <see cref="Task"/></returns>
public async Task HandleAsync()
{
var table = new Table();
table.Border(TableBorder.None);
table.AddColumn("CURRENT");
table.AddColumn("NAME");
foreach (var apiConfig in this.ApplicationOptions.CurrentValue.Api.Configurations)
{
table.AddRow
(
this.ApplicationOptions.CurrentValue.Api.Current == apiConfig.Key || this.ApplicationOptions.CurrentValue.Api.Configurations.Count == 1 ? "*" : string.Empty,
apiConfig.Key
);
}
AnsiConsole.Write(table);
await Task.CompletedTask;
}

static class CommandOptions
{

public static Option<Uri> Server => new(["-s", "--server"], "The address of the API server to use");

}

}
Loading

0 comments on commit 59e1962

Please sign in to comment.