Skip to content

Commit

Permalink
Refactor, start unit testing
Browse files Browse the repository at this point in the history
  • Loading branch information
Blind-Striker committed May 28, 2019
1 parent 50c745a commit 89400c3
Show file tree
Hide file tree
Showing 12 changed files with 367 additions and 86 deletions.
89 changes: 89 additions & 0 deletions src/LocalStack.AwsLocal/CommandDispatcher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using LocalStack.AwsLocal.Contracts;
using LocalStack.AwsLocal.EnvironmentContext;
using LocalStack.AwsLocal.Extensions;
using LocalStack.Client.Contracts;
using LocalStack.Client.Models;

namespace LocalStack.AwsLocal
{
public class CommandDispatcher
{
private const string UsageResource = "LocalStack.AwsLocal.Docs.Usage.txt";

private readonly IProcessHelper _processHelper;
private readonly IConfig _config;
private readonly TextWriter _textWriter;
private readonly string[] _args;

private CommandDispatcher()
{
}

public CommandDispatcher(IProcessHelper processHelper, IConfig config, TextWriter textWriter, string[] args)
{
_processHelper = processHelper;
_config = config;
_textWriter = textWriter;
_args = args;
}

public void Run()
{
if (_args.Length == 0 || (_args[0] == "-h"))
{
string usageInfo = GetUsageInfo();
_textWriter.WriteLine(usageInfo);
EnvironmentControl.Current.Exit(0);
return;
}

string serviceName = _args.ExtractServiceName();

if (string.IsNullOrEmpty(serviceName))
{
_textWriter.WriteLine("ERROR: Invalid argument, please enter a valid aws cli command");
EnvironmentControl.Current.Exit(1);
return;
}

AwsServiceEndpoint awsServiceEndpoint = _config.GetServiceEndpoint(serviceName);

if (awsServiceEndpoint == null)
{
_textWriter.WriteLine($"ERROR: Unable to find LocalStack endpoint for service {serviceName}");
EnvironmentControl.Current.Exit(1);
return;
}

string cliCommand = _args.GetCliCommand(awsServiceEndpoint.ServiceUrl);

string awsDefaultRegion = Environment.GetEnvironmentVariable("AWS_DEFAULT_REGION") ?? "us-east-1";
string awsAccessKeyId = Environment.GetEnvironmentVariable("AWS_ACCESS_KEY_ID") ?? "_not_needed_locally_";
string awsSecretAccessKey = Environment.GetEnvironmentVariable("AWS_SECRET_ACCESS_KEY") ?? "_not_needed_locally_";

_processHelper.CmdExecute(cliCommand, null, true, true, new Dictionary<string, string>
{
{"AWS_DEFAULT_REGION", awsDefaultRegion},
{"AWS_ACCESS_KEY_ID", awsAccessKeyId},
{"AWS_SECRET_ACCESS_KEY", awsSecretAccessKey}
});
}

private static string GetUsageInfo()
{
using (Stream stream = Assembly.GetCallingAssembly().GetManifestResourceStream(UsageResource))
{
using (var reader = new StreamReader(stream))
{
string result = reader.ReadToEnd();

return result;
}
}
}
}
}
2 changes: 1 addition & 1 deletion src/LocalStack.AwsLocal/Contracts/IProcessHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace LocalStack.AwsLocal.Contracts
{
internal interface IProcessHelper
public interface IProcessHelper
{
int CmdExecute(string command, string workingDirectoryPath, bool output = true, bool waitForExit = true, IDictionary<string, string> environmentVariables = null);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;

namespace LocalStack.AwsLocal.EnvironmentContext
{
public class DefaultEnvironmentControl : EnvironmentControl
{
private static readonly Lazy<DefaultEnvironmentControl> LazyInstance = new Lazy<DefaultEnvironmentControl>(() => new DefaultEnvironmentControl());

public override void Exit(int value)
{
Environment.Exit(value);
}

public static DefaultEnvironmentControl Instance => LazyInstance.Value;
}
}
23 changes: 23 additions & 0 deletions src/LocalStack.AwsLocal/EnvironmentContext/EnvironmentControl.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;

namespace LocalStack.AwsLocal.EnvironmentContext
{
public abstract class EnvironmentControl
{
private static EnvironmentControl _current = DefaultEnvironmentControl.Instance;

public static EnvironmentControl Current
{
get => _current;

set => _current = value ?? throw new ArgumentNullException(nameof(value));
}

public abstract void Exit(int value);

public static void ResetToDefault()
{
_current = DefaultEnvironmentControl.Instance;
}
}
}
37 changes: 37 additions & 0 deletions src/LocalStack.AwsLocal/Extensions/ArgumentExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.Collections.Generic;
using System.Linq;

namespace LocalStack.AwsLocal.Extensions
{
public static class ArgumentExtensions
{
public static string ExtractServiceName(this IEnumerable<string> args)
{
foreach (string arg in args)
{
if (arg.StartsWith('-'))
{
continue;
}

return arg == "s3api" ? "s3" : arg;
}

return string.Empty;
}

public static string GetCliCommand(this IEnumerable<string> args, string serviceUrl)
{
var arguments = args.ToList();
arguments.Insert(0, "aws");
arguments.Insert(1, $"--endpoint-url={serviceUrl}");

if (serviceUrl.StartsWith("https"))
{
arguments.Insert(2, "--no-verify-ssl");
}

return string.Join(' ', arguments);
}
}
}
16 changes: 16 additions & 0 deletions src/LocalStack.AwsLocal/Extensions/ConfigExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Linq;
using LocalStack.Client.Contracts;
using LocalStack.Client.Models;

namespace LocalStack.AwsLocal.Extensions
{
public static class ConfigExtensions
{
public static AwsServiceEndpoint GetServiceEndpoint(this IConfig config, string serviceName)
{
var awsServiceEndpoints = config.GetAwsServiceEndpoints();

return awsServiceEndpoints.SingleOrDefault(endpoint => endpoint.CliName == serviceName);
}
}
}
91 changes: 6 additions & 85 deletions src/LocalStack.AwsLocal/Program.cs
Original file line number Diff line number Diff line change
@@ -1,100 +1,21 @@
using LocalStack.AwsLocal.Contracts;
using LocalStack.Client;
using LocalStack.Client.Contracts;
using LocalStack.Client.Models;
using LocalStack.Client;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;

namespace LocalStack.AwsLocal
{
internal static class Program
{
private const string UsageResource = "LocalStack.AwsLocal.Docs.Usage.txt";

private static readonly IProcessHelper ProcessHelper = new ProcessHelper();
private static readonly string LocalStackHost = Environment.GetEnvironmentVariable("LOCALSTACK_HOST");
private static readonly IConfig Config = new Config(LocalStackHost);

private static IEnumerable<string> Args { get; set; }

private static void Main(string[] args)
{
Args = args;

if (args.Length == 0 || (args[0] == "-h"))
{
Usage();
}

(string service, AwsServiceEndpoint awsServiceEndpoint) = GetServiceEndpoint();

if (awsServiceEndpoint == null)
{
Console.WriteLine($"ERROR: Unable to find LocalStack endpoint for service {service}");
Environment.Exit(1);
}

var arguments = args.ToList();
arguments.Insert(0, "aws");
arguments.Insert(1, $"--endpoint-url={awsServiceEndpoint.ServiceUrl}");

if (awsServiceEndpoint.Host.Contains("https"))
{
arguments.Insert(2, "--no-verify-ssl");
}

string awsDefaultRegion = Environment.GetEnvironmentVariable("AWS_DEFAULT_REGION") ?? "us-east-1";
string awsAccessKeyId = Environment.GetEnvironmentVariable("AWS_ACCESS_KEY_ID") ?? "_not_needed_locally_";
string awsSecretAccessKey = Environment.GetEnvironmentVariable("AWS_SECRET_ACCESS_KEY") ?? "_not_needed_locally_";

ProcessHelper.CmdExecute(string.Join(' ', arguments), null, true, true, new Dictionary<string, string>
{
{"AWS_DEFAULT_REGION", awsDefaultRegion},
{"AWS_ACCESS_KEY_ID", awsAccessKeyId},
{"AWS_SECRET_ACCESS_KEY", awsSecretAccessKey}
});
}
var processHelper = new ProcessHelper();
var config = new Config(LocalStackHost);
var textWriter = Console.Out;

private static string GetService()
{
foreach (string arg in Args)
{
if (!arg.StartsWith('-'))
{
return arg;
}
}

return string.Empty;
}

private static (string service, AwsServiceEndpoint awsServiceEndpoint) GetServiceEndpoint()
{
string service = GetService();
if (service == "s3api")
{
service = "s3";
}

var awsServiceEndpoints = Config.GetAwsServiceEndpoints();
return (service, awsServiceEndpoints.SingleOrDefault(endpoint => endpoint.CliName == service));
}

private static void Usage()
{
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(UsageResource))
{
using (var reader = new StreamReader(stream))
{
string result = reader.ReadToEnd();
Console.WriteLine(result);
}
}
var commandDispatcher = new CommandDispatcher(processHelper, config, textWriter, args);

Environment.Exit(0);
commandDispatcher.Run();
}
}
}
11 changes: 11 additions & 0 deletions src/LocalStack.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ VisualStudioVersion = 16.0.28803.452
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LocalStack.AwsLocal", "LocalStack.AwsLocal\LocalStack.AwsLocal.csproj", "{D5116356-24F8-4B01-AB33-64CCFC5F0713}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D9F1CEF9-248C-49EA-BD93-5B5E6FD02967}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalStack.AwsLocal.Tests", "..\tests\LocalStack.AwsLocal.Tests\LocalStack.AwsLocal.Tests.csproj", "{5D6C622C-F940-4851-BFD9-B2755641C6D5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -15,10 +19,17 @@ Global
{D5116356-24F8-4B01-AB33-64CCFC5F0713}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D5116356-24F8-4B01-AB33-64CCFC5F0713}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D5116356-24F8-4B01-AB33-64CCFC5F0713}.Release|Any CPU.Build.0 = Release|Any CPU
{5D6C622C-F940-4851-BFD9-B2755641C6D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5D6C622C-F940-4851-BFD9-B2755641C6D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5D6C622C-F940-4851-BFD9-B2755641C6D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5D6C622C-F940-4851-BFD9-B2755641C6D5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{5D6C622C-F940-4851-BFD9-B2755641C6D5} = {D9F1CEF9-248C-49EA-BD93-5B5E6FD02967}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {479893D2-EC31-4B10-8F7C-DDA704071C4D}
EndGlobalSection
Expand Down
Loading

0 comments on commit 89400c3

Please sign in to comment.