[#34] Adds support for deploying apps

This commit is contained in:
Chris Cheetham 2018-11-06 11:16:53 -05:00
Родитель d1e3ca11be
Коммит f2646c65ac
132 изменённых файлов: 3128 добавлений и 2887 удалений

2
.gitignore поставляемый
Просмотреть файл

@ -267,7 +267,7 @@ __pycache__/
\.*\.sw[A-z] \.*\.sw[A-z]
# test files # test files
\.steeltoe.tooling.yml steeltoe.yml
\.steeltoe.dummies \.steeltoe.dummies
dummy-service-backend.db dummy-service-backend.db

Просмотреть файл

@ -18,26 +18,26 @@ using Steeltoe.Tooling.Executor;
namespace Steeltoe.Cli namespace Steeltoe.Cli
{ {
[Command(Description = "Add a service.")] [Command(Description = "Add an app or service")]
public class AddCommand : Command public class AddCommand : Command
{ {
public const string Name = "add"; public const string Name = "add";
[Required(ErrorMessage = "Service type not specified")] [Required(ErrorMessage = "'app' or service type not specified")]
[Argument(0, Name = "type", Description = "Service type")] [Argument(0, Name = "type", Description = "'app' or service type")]
private string ServiceType { get; } = null; private string ProjectOrServiceType { get; } = null;
[Required(ErrorMessage = "Service name not specified")] [Required(ErrorMessage = "App or service name not specified")]
[Argument(1, Name = "service", Description = "Service name")] [Argument(1, Name = "name", Description = "App or service name")]
private string ServiceName { get; } = null; private string ProjectOrServiceName { get; } = null;
public AddCommand(IConsole console) : base(console) public AddCommand(IConsole console) : base(console)
{ {
} }
protected override IExecutor GetExecutor() protected override Executor GetExecutor()
{ {
return new AddServiceExecutor(ServiceName, ServiceType); return new AddExecutor(ProjectOrServiceName, ProjectOrServiceType);
} }
} }
} }

Просмотреть файл

@ -22,24 +22,24 @@ using Steeltoe.Tooling.Executor;
namespace Steeltoe.Cli namespace Steeltoe.Cli
{ {
[Command( [Command(
Description = "Set or get the deployment environment arguments for a service.", Description = "Set or get the deployment arguments for an app or service",
ExtendedHelpText = ExtendedHelpText =
"If run with no deployment environment arguments, show the service's current deployment environment arguments.", "If run with no arguments, show the current deployment arguments for the app or service.",
AllowArgumentSeparator = true AllowArgumentSeparator = true
)] )]
public class ArgsCommand : Command public class ArgsCommand : Command
{ {
public const string Name = "args"; public const string Name = "args";
[Required(ErrorMessage = "Deployment environment not specified")] [Required(ErrorMessage = "App or service name not specified")]
[Argument(0, Name = "environment", Description = "Deployment environment")] [Argument(0, Name = "name", Description = "App or service name")]
private string EnvironmentName { get; } private string ApplicationOrService { get; }
[Required(ErrorMessage = "Service name not specified")] [Required(ErrorMessage = "Deployment target name not specified")]
[Argument(1, Name = "service", Description = "Service name")] [Argument(1, Name = "target", Description = "Deployment target name")]
private string ServiceName { get; } private string Target { get; }
[Argument(2, Name = "args", Description = "Deployment environment arguments")] [Argument(2, Name = "args", Description = "Deployment arguments")]
private List<string> Arguments { get; } private List<string> Arguments { get; }
[Option("-F|--force", Description = "Overwrite existing deployment environment arguments")] [Option("-F|--force", Description = "Overwrite existing deployment environment arguments")]
@ -51,7 +51,7 @@ namespace Steeltoe.Cli
{ {
} }
protected override IExecutor GetExecutor() protected override Executor GetExecutor()
{ {
var args = new List<string>(); var args = new List<string>();
if (Arguments != null) if (Arguments != null)
@ -66,10 +66,10 @@ namespace Steeltoe.Cli
if (args.Count == 0) if (args.Count == 0)
{ {
return new GetServiceDeploymentArgsExecutor(EnvironmentName, ServiceName); return new GetArgsExecutor(ApplicationOrService, Target);
} }
return new SetServiceDeploymentArgsExecutor(EnvironmentName, ServiceName, string.Join(" ", args), Force); return new SetArgsExecutor(ApplicationOrService, Target, string.Join(" ", args), Force);
} }
} }
} }

Просмотреть файл

@ -35,38 +35,29 @@ namespace Steeltoe.Cli
{ {
try try
{ {
var executor = GetExecutor(); Logger.LogDebug($"tooling working directory: {app.WorkingDirectory}");
var minfo = executor.GetType();
Logger.LogDebug($"executor is {minfo}");
var requiresInitializedProject = false;
foreach (var attr in minfo.GetCustomAttributes(true))
{
var initAttr = attr as RequiresInitializationAttribute;
if (initAttr != null)
{
Logger.LogDebug($"{minfo} requires initialized project");
requiresInitializedProject = true;
}
}
Logger.LogDebug($"tooling working directory is {app.WorkingDirectory}");
var cfgFilePath = Program.ProjectConfigurationPath; var cfgFilePath = Program.ProjectConfigurationPath;
if (cfgFilePath == null) if (cfgFilePath == null)
{ {
cfgFilePath = app.WorkingDirectory; cfgFilePath = app.WorkingDirectory;
} }
var cfgFile = new ToolingConfigurationFile(cfgFilePath); Configuration cfg;
Logger.LogDebug($"tooling configuration file is {cfgFile.File}"); var cfgFile = new ConfigurationFile(cfgFilePath);
if (requiresInitializedProject && !cfgFile.Exists()) if (cfgFile.Exists())
{ {
throw new ToolingException("Project has not been initialized for Steeltoe Developer Tools"); cfg = cfgFile.Configuration;
Logger.LogDebug($"tooling configuration file: {cfgFile.File}");
}
else
{
cfg = null;
Logger.LogDebug($"tooling configuration file not found: {cfgFile.File}");
} }
var context = new Context( var context = new Context(
app.WorkingDirectory, app.WorkingDirectory,
cfgFile.ToolingConfiguration, cfg,
_console.Out, _console.Out,
new CommandShell() new CommandShell()
); );
@ -93,12 +84,12 @@ namespace Steeltoe.Cli
} }
catch (Exception e) catch (Exception e)
{ {
Logger.LogDebug($"unhandled exception: {e}{System.Environment.NewLine}{e.StackTrace}"); Logger.LogDebug($"unhandled exception: {e}{Environment.NewLine}{e.StackTrace}");
app.Error.WriteLine(e.Message); app.Error.WriteLine(e.Message);
return -1; return -1;
} }
} }
protected abstract IExecutor GetExecutor(); protected abstract Executor GetExecutor();
} }
} }

Просмотреть файл

@ -17,7 +17,7 @@ using Steeltoe.Tooling.Executor;
namespace Steeltoe.Cli namespace Steeltoe.Cli
{ {
[Command(Description = "Deploy enabled services to the targeted deployment environment.")] [Command(Description = "Deploy apps and services to the target")]
public class DeployCommand : Command public class DeployCommand : Command
{ {
public const string Name = "deploy"; public const string Name = "deploy";
@ -26,10 +26,9 @@ namespace Steeltoe.Cli
{ {
} }
protected override IExecutor protected override Executor GetExecutor()
GetExecutor()
{ {
return new DeployServicesExecutor(); return new DeployExecutor();
} }
} }
} }

Просмотреть файл

@ -1,41 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.ComponentModel.DataAnnotations;
using McMaster.Extensions.CommandLineUtils;
using Steeltoe.Tooling.Executor;
// ReSharper disable UnassignedGetOnlyAutoProperty
namespace Steeltoe.Cli
{
[Command(Description = "Disable a service.")]
public class DisableCommand : Command
{
public const string Name = "disable";
[Required(ErrorMessage = "Service name not specified")]
[Argument(0, Name = "service", Description = "Service name")]
private string ServiceName { get; }
public DisableCommand(IConsole console) : base(console)
{
}
protected override IExecutor GetExecutor()
{
return new DisableServiceExecutor(ServiceName);
}
}
}

Просмотреть файл

@ -18,7 +18,7 @@ using Steeltoe.Tooling.Executor;
namespace Steeltoe.Cli namespace Steeltoe.Cli
{ {
[Command(Description = "Check for potential problems.")] [Command(Description = "Check for potential problems")]
public class DoctorCommand : Command public class DoctorCommand : Command
{ {
public const string Name = "doctor"; public const string Name = "doctor";
@ -27,45 +27,45 @@ namespace Steeltoe.Cli
{ {
} }
protected override IExecutor GetExecutor() protected override Executor GetExecutor()
{ {
return new DoctorExecutor(); return new DoctorExecutor();
} }
} }
internal class DoctorExecutor : IExecutor internal class DoctorExecutor : Executor
{ {
public void Execute(Context context) protected override void Execute()
{ {
context.Console.WriteLine($"Steeltoe Developer Tools version ... {Program.GetVersion()}"); Context.Console.WriteLine($"Steeltoe Developer Tools version ... {Program.GetVersion()}");
// dotnet // dotnet
context.Console.Write("DotNet ... "); Context.Console.Write("DotNet ... ");
var dotnetVersion = new Tooling.Cli("dotnet", context.Shell).Run("--version").Trim(); var dotnetVersion = new Tooling.Cli("dotnet", Context.Shell).Run("--version").Trim();
context.Console.WriteLine($"dotnet version {dotnetVersion}"); Context.Console.WriteLine($"dotnet version {dotnetVersion}");
// is intialized? // is intialized?
context.Console.Write("initialized ... "); Context.Console.Write("initialized ... ");
var cfgFile = new ToolingConfigurationFile(context.ProjectDirectory); var cfgFile = new ConfigurationFile(Context.ProjectDirectory);
if (!cfgFile.Exists()) if (!cfgFile.Exists())
{ {
context.Console.WriteLine($"!!! no (run '{Program.Name} {InitCommand.Name}' to initialize)"); Context.Console.WriteLine($"!!! no (run '{Program.Name} {InitCommand.Name}' to initialize)");
return; return;
} }
context.Console.WriteLine("yes"); Context.Console.WriteLine("yes");
// target deployment environment // target deployment environment
context.Console.Write("target deployment environment ... "); Context.Console.Write("target ... ");
var target = cfgFile.ToolingConfiguration.EnvironmentName; string target = cfgFile.Configuration.Target;
if (target == null) if (target == null)
{ {
context.Console.WriteLine($"!!! not set (run '{Program.Name} {TargetCommand.Name} <env>' to set)"); Context.Console.WriteLine($"!!! not set (run '{Program.Name} {TargetCommand.Name} <env>' to set)");
return; return;
} }
context.Console.WriteLine(target); Context.Console.WriteLine(target);
Registry.GetEnvironment(target).IsHealthy(context); Registry.GetTarget(target).IsHealthy(Context);
} }
} }
} }

Просмотреть файл

@ -1,41 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.ComponentModel.DataAnnotations;
using McMaster.Extensions.CommandLineUtils;
using Steeltoe.Tooling.Executor;
// ReSharper disable UnassignedGetOnlyAutoProperty
namespace Steeltoe.Cli
{
[Command(Description = "Enable a service.")]
public class EnableCommand : Command
{
public const string Name = "enable";
[Required(ErrorMessage = "Service name not specified")]
[Argument(0, Name = "service", Description = "Service name")]
private string ServiceName { get; }
public EnableCommand(IConsole console) : base(console)
{
}
protected override IExecutor GetExecutor()
{
return new EnableServiceExecutor(ServiceName);
}
}
}

Просмотреть файл

@ -12,17 +12,14 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
using System;
using System.IO;
using McMaster.Extensions.CommandLineUtils; using McMaster.Extensions.CommandLineUtils;
using Steeltoe.Tooling;
using Steeltoe.Tooling.Executor; using Steeltoe.Tooling.Executor;
// ReSharper disable UnassignedGetOnlyAutoProperty // ReSharper disable UnassignedGetOnlyAutoProperty
namespace Steeltoe.Cli namespace Steeltoe.Cli
{ {
[Command(Description = "Initialize a project for Steeltoe Developer Tools.")] [Command(Description = "Initialize Steeltoe Developer Tools")]
public class InitCommand : Command public class InitCommand : Command
{ {
public const string Name = "init"; public const string Name = "init";
@ -34,35 +31,9 @@ namespace Steeltoe.Cli
{ {
} }
protected override IExecutor GetExecutor() protected override Executor GetExecutor()
{ {
return new InitExecutor(Force); return new InitializationExecutor(Program.ProjectConfigurationPath, Force);
}
}
internal class InitExecutor : IExecutor
{
private readonly bool _force;
internal InitExecutor(Boolean force = false)
{
_force = force;
}
public void Execute(Context context)
{
var cfgFilePath = Program.ProjectConfigurationPath == null
? context.ProjectDirectory
: Path.Combine(context.ProjectDirectory, Program.ProjectConfigurationPath);
var cfgFile = new ToolingConfigurationFile(cfgFilePath);
if (cfgFile.Exists() && !_force)
{
throw new ToolingException("Project already initialized");
}
cfgFile.Store();
context.Console.WriteLine("Project initialized for Steeltoe Developer Tools");
} }
} }
} }

Просмотреть файл

@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
using System;
using McMaster.Extensions.CommandLineUtils; using McMaster.Extensions.CommandLineUtils;
using Steeltoe.Tooling.Executor; using Steeltoe.Tooling.Executor;
@ -20,21 +19,11 @@ using Steeltoe.Tooling.Executor;
namespace Steeltoe.Cli namespace Steeltoe.Cli
{ {
[Command(Description = "List services, service types, or deployment environments.", [Command(Description = "List apps and services")]
ExtendedHelpText = "If run with no options, list services.")]
public class ListCommand : Command public class ListCommand : Command
{ {
public const string Name = "list"; public const string Name = "list";
[Option("-e|--environments", Description = "List deployment environments")]
private bool ListEnvironments { get; }
[Option("-s|--services", Description = "List services")]
private bool ListServices { get; }
[Option("-t|--service-types", Description = "List service types")]
private bool ListServiceTypes { get; }
[Option("-v|--verbose", Description = "Verbose")] [Option("-v|--verbose", Description = "Verbose")]
private bool Verbose { get; } private bool Verbose { get; }
@ -42,34 +31,9 @@ namespace Steeltoe.Cli
{ {
} }
protected override IExecutor GetExecutor() protected override Executor GetExecutor()
{ {
var optionCount = 0; return new ListExecutor(Verbose);
IExecutor executor = new ListServicesExecutor(Verbose);
if (ListServices)
{
++optionCount;
}
if (ListServiceTypes)
{
executor = new ListServiceTypesExecutor(Verbose);
++optionCount;
}
if (ListEnvironments)
{
executor = new ListEnvironmentsExecutor(Verbose);
++optionCount;
}
if (optionCount > 1)
{
throw new ArgumentException(
"Specify at most one of: -e|--environments, -s|--services, -t|--service-types");
}
return executor;
} }
} }
} }

Просмотреть файл

@ -24,8 +24,6 @@ namespace Steeltoe.Cli
[Subcommand(TargetCommand.Name, typeof(TargetCommand))] [Subcommand(TargetCommand.Name, typeof(TargetCommand))]
[Subcommand(AddCommand.Name, typeof(AddCommand))] [Subcommand(AddCommand.Name, typeof(AddCommand))]
[Subcommand(RemoveCommand.Name, typeof(RemoveCommand))] [Subcommand(RemoveCommand.Name, typeof(RemoveCommand))]
[Subcommand(DisableCommand.Name, typeof(DisableCommand))]
[Subcommand(EnableCommand.Name, typeof(EnableCommand))]
[Subcommand(DeployCommand.Name, typeof(DeployCommand))] [Subcommand(DeployCommand.Name, typeof(DeployCommand))]
[Subcommand(UndeployCommand.Name, typeof(UndeployCommand))] [Subcommand(UndeployCommand.Name, typeof(UndeployCommand))]
[Subcommand(StatusCommand.Name, typeof(StatusCommand))] [Subcommand(StatusCommand.Name, typeof(StatusCommand))]
@ -43,7 +41,7 @@ namespace Steeltoe.Cli
.InformationalVersion; .InformationalVersion;
[Option("-C|--config-file", Description = [Option("-C|--config-file", Description =
"Configure tooling using the specified file instead of .steeltoe.tooling.yml")] "Configure tooling using the specified file instead of steeltoe.yml")]
// ReSharper disable once UnassignedGetOnlyAutoProperty // ReSharper disable once UnassignedGetOnlyAutoProperty
public static string ProjectConfigurationPath { get; } public static string ProjectConfigurationPath { get; }

Просмотреть файл

@ -20,22 +20,22 @@ using Steeltoe.Tooling.Executor;
namespace Steeltoe.Cli namespace Steeltoe.Cli
{ {
[Command(Description = "Remove a service.")] [Command(Description = "Remove an app or service")]
public class RemoveCommand : Command public class RemoveCommand : Command
{ {
public const string Name = "remove"; public const string Name = "remove";
[Required(ErrorMessage = "Service name not specified")] [Required(ErrorMessage = "App or service name not specified")]
[Argument(0, Name = "service", Description = "Service name")] [Argument(0, Name = "name", Description = "App or service name")]
private string ServiceName { get; } private string AppOrServiceName { get; }
public RemoveCommand(IConsole console) : base(console) public RemoveCommand(IConsole console) : base(console)
{ {
} }
protected override IExecutor GetExecutor() protected override Executor GetExecutor()
{ {
return new RemoveServiceExecutor(ServiceName); return new RemoveExecutor(AppOrServiceName);
} }
} }
} }

Просмотреть файл

@ -17,7 +17,7 @@ using Steeltoe.Tooling.Executor;
namespace Steeltoe.Cli namespace Steeltoe.Cli
{ {
[Command(Description = "Show service statuses.")] [Command(Description = "Show app and service statuses")]
public class StatusCommand : Command public class StatusCommand : Command
{ {
public const string Name = "status"; public const string Name = "status";
@ -26,9 +26,9 @@ namespace Steeltoe.Cli
{ {
} }
protected override IExecutor GetExecutor() protected override Executor GetExecutor()
{ {
return new StatusServicesExecutor(); return new StatusExecutor();
} }
} }
} }

Просмотреть файл

@ -20,30 +20,30 @@ using Steeltoe.Tooling.Executor;
namespace Steeltoe.Cli namespace Steeltoe.Cli
{ {
[Command(Description = [Command(Description =
"Set or get the targeted deployment environment.", "Set or get the deployment target",
ExtendedHelpText = "If run with no args, show the currently targeted deployment environment.")] ExtendedHelpText = "If run with no args, show the current deployment target.")]
public class TargetCommand : Command public class TargetCommand : Command
{ {
public const string Name = "target"; public const string Name = "target";
[Argument(0, Name = "environment", Description = "Deployment environment")] [Argument(0, Name = "target", Description = "Deployment target name")]
private string EnvironmentName { get; } private string Target { get; }
[Option("-F|--force", Description = "Target the deployment environment even if checks fail")] [Option("-F|--force", Description = "Set the deployment target even if checks fail")]
private bool Force { get; } private bool Force { get; }
public TargetCommand(IConsole console) : base(console) public TargetCommand(IConsole console) : base(console)
{ {
} }
protected override IExecutor GetExecutor() protected override Executor GetExecutor()
{ {
if (EnvironmentName == null) if (Target == null)
{ {
return new GetTargetExecutor(); return new GetTargetExecutor();
} }
return new SetTargetExecutor(EnvironmentName, Force); return new SetTargetExecutor(Target, Force);
} }
} }
} }

Просмотреть файл

@ -17,7 +17,7 @@ using Steeltoe.Tooling.Executor;
namespace Steeltoe.Cli namespace Steeltoe.Cli
{ {
[Command(Description = "Undeploy enabled services from the targeted deployment environment.")] [Command(Description = "Undeploy apps and services from the target")]
public class UndeployCommand : Command public class UndeployCommand : Command
{ {
public const string Name = "undeploy"; public const string Name = "undeploy";
@ -26,9 +26,9 @@ namespace Steeltoe.Cli
{ {
} }
protected override IExecutor GetExecutor() protected override Executor GetExecutor()
{ {
return new UndeployServicesExecutor(); return new UndeployExecutor();
} }
} }
} }

Просмотреть файл

@ -14,17 +14,13 @@
namespace Steeltoe.Tooling namespace Steeltoe.Tooling
{ {
public class Service public class AppInfo
{ {
public string Name { get; } public string App { get; }
public string Type { get; } public AppInfo(string app)
public Service(string name, string type)
{ {
App = app;
Name = name;
Type = type;
} }
} }
} }

Просмотреть файл

@ -18,7 +18,7 @@ namespace Steeltoe.Tooling
{ {
public string Command { get; } public string Command { get; }
public Shell Shell { get; } private Shell Shell { get; }
public Cli(string command, Shell shell) public Cli(string command, Shell shell)
{ {

Просмотреть файл

@ -0,0 +1,130 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
namespace Steeltoe.Tooling.CloudFoundry
{
public class CloudFoundryBackend : IBackend
{
private readonly Context _context;
private readonly Cli _cfCli;
private readonly Cli _dotnetCli;
public CloudFoundryBackend(Context context)
{
_context = context;
_cfCli = new CloudFoundryCli(context.Shell);
_dotnetCli = new Cli("dotnet", _context.Shell);
}
public void DeployApp(string application)
{
var manifestPath = Path.Combine(_context.ProjectDirectory, "manifest-steeltoe.yml");
if (File.Exists(manifestPath))
{
File.Delete(manifestPath);
}
var manifestFile = new CloudFoundryManifestFile(manifestPath);
manifestFile.CloudFoundryManifest.Applications.Add(new CloudFoundryManifest.Application
{
Name = application,
Command = $"cmd /c .\\{Path.GetFileName(_context.ProjectDirectory)}",
BuildPacks = new List<string> {"binary_buildpack"},
Stack = "windows2016",
Memory = "512M",
Environment = new Dictionary<string, string> {{"ASPNETCORE_ENVIRONMENT", "development"}},
ServiceNames = _context.Configuration.GetServices()
}
);
manifestFile.Store();
_dotnetCli.Run("publish -f netcoreapp2.1 -r win10-x64");
_cfCli.Run("push -f manifest-steeltoe.yml -p bin/Debug/netcoreapp2.1/win10-x64/publish");
}
public void UndeployApp(string application)
{
_cfCli.Run($"delete {application} -f");
}
public Lifecycle.Status GetAppStatus(string application)
{
try
{
var appInfo = _cfCli.Run($"app {application}");
var state = new Regex(@"^#0\s+(\S+)", RegexOptions.Multiline).Match(appInfo).Groups[1].ToString()
.Trim();
switch (state)
{
case "down":
return Lifecycle.Status.Starting;
case "running":
return Lifecycle.Status.Online;
}
}
catch (CliException e)
{
if (e.Error.Contains($"App {application} not found"))
{
return Lifecycle.Status.Offline;
}
}
return Lifecycle.Status.Unknown;
}
public void DeployService(string service)
{
var svcInfo = _context.Configuration.GetServiceInfo(service);
var cfServiceDef = _context.Target.Configuration.ServiceTypeProperties[svcInfo.ServiceType];
_cfCli.Run($"create-service {cfServiceDef["service"]} {cfServiceDef["plan"]} {service}");
}
public void UndeployService(string service)
{
_cfCli.Run($"delete-service {service} -f");
}
public Lifecycle.Status GetServiceStatus(string service)
{
try
{
var serviceInfo = _cfCli.Run($"service {service}");
var state = new Regex(@"^status:\s+(.*)$", RegexOptions.Multiline).Match(serviceInfo).Groups[1]
.ToString().Trim();
switch (state)
{
case "create in progress":
return Lifecycle.Status.Starting;
case "create succeeded":
return Lifecycle.Status.Online;
}
}
catch (CliException e)
{
if (e.Error.Contains($"Service instance {service} not found"))
{
return Lifecycle.Status.Offline;
}
}
return Lifecycle.Status.Unknown;
}
}
}

Просмотреть файл

@ -0,0 +1,49 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Collections.Generic;
using YamlDotNet.Serialization;
namespace Steeltoe.Tooling.CloudFoundry
{
public class CloudFoundryManifest
{
[YamlMember(Alias = "applications")]
public List<Application> Applications { get; set; }= new List<Application>();
public class Application
{
[YamlMember(Alias = "name")]
public string Name { get; set; }
[YamlMember(Alias = "command")]
public string Command { get; set; }
[YamlMember(Alias = "buildpacks")]
public List<string> BuildPacks { get; set; }
[YamlMember(Alias = "stack")]
public string Stack { get; set; }
[YamlMember(Alias = "memory")]
public string Memory { get; set; }
[YamlMember(Alias = "env")]
public Dictionary<string, string> Environment { get; set; }
[YamlMember(Alias = "services")]
public List<string> ServiceNames { get; set; }
}
}
}

Просмотреть файл

@ -0,0 +1,54 @@
using System.IO;
using Microsoft.Extensions.Logging;
using YamlDotNet.Serialization;
namespace Steeltoe.Tooling.CloudFoundry
{
public class CloudFoundryManifestFile
{
private static readonly ILogger Logger = Logging.LoggerFactory.CreateLogger<CloudFoundryManifestFile>();
public CloudFoundryManifest CloudFoundryManifest { get; private set; }
public string File { get; }
public CloudFoundryManifestFile(string file)
{
File = file;
if (Exists())
{
Load();
}
else
{
CloudFoundryManifest = new CloudFoundryManifest();
}
}
public void Load()
{
Logger.LogDebug($"loading cloud foundry manifest from {File}");
var deserializer = new DeserializerBuilder().Build();
using (var reader = new StreamReader(File))
{
CloudFoundryManifest = deserializer.Deserialize<CloudFoundryManifest>(reader);
}
}
public void Store()
{
Logger.LogDebug($"storing cloud foundry manifest to {File}");
var serializer = new SerializerBuilder().Build();
var yaml = serializer.Serialize(CloudFoundryManifest);
using (var writer = new StreamWriter(File))
{
writer.Write(yaml);
}
}
public bool Exists()
{
return System.IO.File.Exists(File);
}
}
}

Просмотреть файл

@ -1,68 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Text.RegularExpressions;
namespace Steeltoe.Tooling.CloudFoundry
{
public class CloudFoundryServiceBackend : IServiceBackend
{
private readonly Context _context;
private readonly CloudFoundryCli _cli;
public CloudFoundryServiceBackend(Context context)
{
_context = context;
_cli = new CloudFoundryCli(_context.Shell);
}
public void DeployService(string name, string type)
{
var cfServiceDef = _context.Environment.Configuration.ServiceTypeProperties[type];
_cli.Run($"create-service {cfServiceDef["service"]} {cfServiceDef["plan"]} {name}");
}
public void UndeployService(string name)
{
_cli.Run($"delete-service {name} -f");
}
public ServiceLifecycle.State GetServiceLifecleState(string name)
{
try
{
var serviceInfo = _cli.Run($"service {name}");
var state = new Regex(@"^status:\s+(.*)$", RegexOptions.Multiline).Match(serviceInfo).Groups[1]
.ToString().TrimEnd();
switch (state)
{
case "create in progress":
return ServiceLifecycle.State.Starting;
case "create succeeded":
return ServiceLifecycle.State.Online;
}
}
catch (CliException e)
{
if (e.Error.Contains($"Service instance {name} not found"))
{
return ServiceLifecycle.State.Offline;
}
}
return ServiceLifecycle.State.Unknown;
}
}
}

Просмотреть файл

@ -14,15 +14,15 @@
namespace Steeltoe.Tooling.CloudFoundry namespace Steeltoe.Tooling.CloudFoundry
{ {
public class CloudFoundryEnvironment : Environment public class CloudFoundryTarget : Target
{ {
public CloudFoundryEnvironment(EnvironmentConfiguration config) : base(config) public CloudFoundryTarget(TargetConfiguration configuration) : base(configuration)
{ {
} }
public override IServiceBackend GetServiceBackend(Context context) public override IBackend GetBackend(Context context)
{ {
return new CloudFoundryServiceBackend(context); return new CloudFoundryBackend(context);
} }
public override bool IsHealthy(Context context) public override bool IsHealthy(Context context)

Просмотреть файл

@ -0,0 +1,184 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Logging;
using YamlDotNet.Serialization;
namespace Steeltoe.Tooling
{
public class Configuration
{
private static readonly ILogger Logger = Logging.LoggerFactory.CreateLogger<Configuration>();
[YamlMember(Alias = "target")] public string Target { get; set; }
[YamlMember(Alias = "apps")]
public SortedDictionary<string, App> Apps { get; set; } = new SortedDictionary<string, App>();
[YamlMember(Alias = "services")]
public SortedDictionary<string, Service> Services { get; set; } = new SortedDictionary<string, Service>();
private readonly List<IConfigurationListener> _listeners = new List<IConfigurationListener>();
public void AddApp(string app)
{
Logger.LogDebug($"adding app {app}");
if (Apps.ContainsKey(app))
{
throw new ToolingException($"App '{app}' already exists");
}
Apps[app] = new App();
NotifyChanged();
}
public void RemoveApp(string app)
{
Logger.LogDebug($"removing app {app}");
if (!Apps.Remove(app))
{
throw new NotFoundException(app, "app");
}
NotifyChanged();
}
public List<string> GetApps()
{
return Apps.Keys.ToList();
}
public AppInfo GetAppInfo(string app)
{
try
{
return new AppInfo(app);
}
catch (KeyNotFoundException)
{
throw new NotFoundException(app, "app");
}
}
public void AddService(string service, string serviceType)
{
Logger.LogDebug($"adding service {serviceType} '{service}'");
if (!Registry.GetServiceTypes().Contains(serviceType))
{
throw new NotFoundException(serviceType, "type");
}
if (Services.ContainsKey(service))
{
throw new ToolingException($"Service '{service}' already exists");
}
Services[service] = new Service {ServiceTypeName = serviceType};
NotifyChanged();
}
public void RemoveService(string service)
{
Logger.LogDebug($"removing service {service}");
if (!Services.Remove(service))
{
throw new NotFoundException(service, "service");
}
NotifyChanged();
}
public List<string> GetServices()
{
return Services.Keys.ToList();
}
public ServiceInfo GetServiceInfo(string service)
{
try
{
return new ServiceInfo(service, Services[service].ServiceTypeName);
}
catch (KeyNotFoundException)
{
throw new NotFoundException(service, "service");
}
}
public void SetServiceDeploymentArgs(string service, string target, string args)
{
Logger.LogDebug($"setting service '{service}' args for target '{target} to '{args}'");
if (!Registry.Targets.Contains(target))
{
throw new NotFoundException(target, "target");
}
if (!Services.ContainsKey(service))
{
throw new NotFoundException(service, "service");
}
Services[service].Args[target] = args;
NotifyChanged();
}
public string GetServiceDeploymentArgs(string service, string target)
{
if (!Registry.Targets.Contains(target))
{
throw new NotFoundException(target, "target");
}
try
{
var svc = Services[service];
string args;
svc.Args.TryGetValue(target, out args);
return args;
}
catch (KeyNotFoundException)
{
throw new NotFoundException(service, "service");
}
}
public void AddListener(IConfigurationListener listener)
{
_listeners.Add(listener);
}
public void NotifyChanged()
{
Logger.LogDebug("configuration changed");
foreach (var listener in _listeners)
{
listener.ConfigurationChangeEvent();
}
}
public class App
{
}
public class Service
{
[YamlMember(Alias = "type")] public string ServiceTypeName { get; set; }
[YamlMember(Alias = "args")]
public SortedDictionary<string, string> Args { get; set; } = new SortedDictionary<string, string>();
}
}
}

Просмотреть файл

@ -18,42 +18,46 @@ using YamlDotNet.Serialization;
namespace Steeltoe.Tooling namespace Steeltoe.Tooling
{ {
public class ToolingConfigurationFile : IToolingConfigurationListener public class ConfigurationFile : IConfigurationListener
{ {
private static readonly ILogger Logger = Logging.LoggerFactory.CreateLogger<ToolingConfigurationFile>(); private static readonly ILogger Logger = Logging.LoggerFactory.CreateLogger<ConfigurationFile>();
public const string DefaultFileName = ".steeltoe.tooling.yml"; public const string DefaultFileName = "steeltoe.yml";
public ToolingConfiguration ToolingConfiguration { get; private set; } = new ToolingConfiguration(); public Configuration Configuration { get; private set; }
public string File { get; } public string File { get; }
public ToolingConfigurationFile(string path) public ConfigurationFile(string path)
{ {
File = Directory.Exists(path) ? Path.Combine(path, DefaultFileName) : path; File = Directory.Exists(path) ? Path.Combine(path, DefaultFileName) : path;
if (Exists()) if (Exists())
{ {
Load(); Load();
} }
else
{
Configuration = new Configuration();
}
} }
public void Load() public void Load()
{ {
Logger.LogDebug($"loading tooling configuration from {File}"); Logger.LogDebug($"loading configuration from {File}");
var deserializer = new DeserializerBuilder().Build(); var deserializer = new DeserializerBuilder().Build();
using (var reader = new StreamReader(File)) using (var reader = new StreamReader(File))
{ {
ToolingConfiguration = deserializer.Deserialize<ToolingConfiguration>(reader); Configuration = deserializer.Deserialize<Configuration>(reader);
} }
ToolingConfiguration.AddListener(this); Configuration.AddListener(this);
} }
public void Store() public void Store()
{ {
Logger.LogDebug($"storing tooling configuration to {File}"); Logger.LogDebug($"storing configuration to {File}");
var serializer = new SerializerBuilder().Build(); var serializer = new SerializerBuilder().Build();
var yaml = serializer.Serialize(ToolingConfiguration); var yaml = serializer.Serialize(Configuration);
using (var writer = new StreamWriter(File)) using (var writer = new StreamWriter(File))
{ {
writer.Write(yaml); writer.Write(yaml);

Просмотреть файл

@ -20,35 +20,33 @@ namespace Steeltoe.Tooling
{ {
public string ProjectDirectory { get; } public string ProjectDirectory { get; }
public ToolingConfiguration ToolingConfiguration { get; } public Configuration Configuration { get; }
public TextWriter Console { get; } public TextWriter Console { get; }
public Shell Shell { get; } public Shell Shell { get; }
public Environment Environment public Target Target
{ {
get get
{ {
if (ToolingConfiguration?.EnvironmentName == null) if (Configuration?.Target == null)
{ {
throw new ToolingException("Target deployment environment not set"); throw new ToolingException("Target not set");
} }
return Registry.GetEnvironment(ToolingConfiguration.EnvironmentName); return Registry.GetTarget(Configuration.Target);
} }
} }
public ServiceManager ServiceManager { get; } public IBackend Backend => Target.GetBackend(this);
public Context(string dir, Configuration config, TextWriter console, Shell shell)
public Context(string dir, ToolingConfiguration config, TextWriter console, Shell shell)
{ {
ProjectDirectory = dir; ProjectDirectory = dir;
ToolingConfiguration = config; Configuration = config;
Console = console; Console = console;
Shell = shell; Shell = shell;
ServiceManager = new ServiceManager(this);
} }
} }
} }

Просмотреть файл

@ -19,7 +19,7 @@ using System.Text.RegularExpressions;
namespace Steeltoe.Tooling.Docker namespace Steeltoe.Tooling.Docker
{ {
public class DockerServiceBackend : IServiceBackend public class DockerBackend : IBackend
{ {
private const string Localhost = "127.0.0.1"; private const string Localhost = "127.0.0.1";
@ -27,24 +27,40 @@ namespace Steeltoe.Tooling.Docker
private readonly DockerCli _cli; private readonly DockerCli _cli;
internal DockerServiceBackend(Context context) internal DockerBackend(Context context)
{ {
_context = context; _context = context;
_cli = new DockerCli(_context.Shell); _cli = new DockerCli(_context.Shell);
} }
public void DeployService(string name, string type) public void DeployApp(string application)
{
throw new NotImplementedException();
}
public void UndeployApp(string application)
{
throw new NotImplementedException();
}
public Lifecycle.Status GetAppStatus(string application)
{
throw new NotImplementedException();
}
public void DeployService(string service)
{ {
var dockerInfo = new DockerCli(_context.Shell).Run("info"); var dockerInfo = new DockerCli(_context.Shell).Run("info");
var dockerOs = new Regex(@"OSType:\s*(.+)", RegexOptions.Multiline).Match(dockerInfo).Groups[1].ToString(); var dockerOs = new Regex(@"OSType:\s*(.+)", RegexOptions.Multiline).Match(dockerInfo).Groups[1].ToString();
DeployService(name, type, dockerOs); DeployService(service, dockerOs);
} }
public void DeployService(string name, string type, string os) public void DeployService(string service, string os)
{ {
var image = LookupImage(type, os); var svcInfo = _context.Configuration.GetServiceInfo(service);
var port = GetServicePort(type); var port = GetPort(svcInfo.ServiceType);
var args = _context.ServiceManager.GetServiceDeploymentArgs("docker", name); var image = LookupImage(svcInfo.ServiceType, os);
var args = _context.Configuration.GetServiceDeploymentArgs(service, "docker");
if (args == null) if (args == null)
{ {
args = ""; args = "";
@ -54,52 +70,52 @@ namespace Steeltoe.Tooling.Docker
args += " "; args += " ";
} }
_cli.Run($"run --name {name} --publish {port}:{port} --detach --rm {args}{image}"); _cli.Run($"run --name {service} --publish {port}:{port} --detach --rm {args}{image}");
} }
public void UndeployService(string name) public void UndeployService(string service)
{ {
_cli.Run($"stop {name}"); _cli.Run($"stop {service}");
} }
public ServiceLifecycle.State GetServiceLifecleState(string name) public Lifecycle.Status GetServiceStatus(string service)
{ {
var containerInfo = _cli.Run($"ps --no-trunc --filter name=^/{name}$").Split('\n'); var containerInfo = _cli.Run($"ps --no-trunc --filter name=^/{service}$").Split('\n');
if (containerInfo.Length <= 2) if (containerInfo.Length <= 2)
{ {
return ServiceLifecycle.State.Offline; return Lifecycle.Status.Offline;
} }
var statusStart = containerInfo[0].IndexOf("STATUS", StringComparison.Ordinal); var statusStart = containerInfo[0].IndexOf("STATUS", StringComparison.Ordinal);
if (!containerInfo[1].Substring(statusStart).StartsWith("Up ")) if (!containerInfo[1].Substring(statusStart).StartsWith("Up "))
{ {
return ServiceLifecycle.State.Unknown; return Lifecycle.Status.Unknown;
} }
var imageStart = containerInfo[0].IndexOf("IMAGE", StringComparison.Ordinal); var imageStart = containerInfo[0].IndexOf("IMAGE", StringComparison.Ordinal);
var image = new Regex(@"\S+").Match(containerInfo[1].Substring(imageStart)).ToString(); var image = new Regex(@"\S+").Match(containerInfo[1].Substring(imageStart)).ToString();
var svc = LookupServiceType(image); var svc = LookupServiceType(image);
var port = GetServicePort(svc); var port = GetPort(svc);
try try
{ {
new TcpClient(Localhost, port).Dispose(); new TcpClient(Localhost, port).Dispose();
return ServiceLifecycle.State.Online; return Lifecycle.Status.Online;
} }
catch (SocketException) catch (SocketException)
{ {
return ServiceLifecycle.State.Starting; return Lifecycle.Status.Starting;
} }
} }
private string LookupImage(string type, string os) private string LookupImage(string type, string os)
{ {
var images = _context.Environment.Configuration.ServiceTypeProperties[type]; var images = _context.Target.Configuration.ServiceTypeProperties[type];
return images.TryGetValue($"image-{os}", out var image) ? image : images["image"]; return images.TryGetValue($"image-{os}", out var image) ? image : images["image"];
} }
private string LookupServiceType(string image) private string LookupServiceType(string image)
{ {
var svcTypes = _context.Environment.Configuration.ServiceTypeProperties; var svcTypes = _context.Target.Configuration.ServiceTypeProperties;
foreach (var svcType in svcTypes.Keys) foreach (var svcType in svcTypes.Keys)
{ {
var images = svcTypes[svcType]; var images = svcTypes[svcType];
@ -112,9 +128,9 @@ namespace Steeltoe.Tooling.Docker
throw new ToolingException($"Failed to lookup service type for image '{image}'"); throw new ToolingException($"Failed to lookup service type for image '{image}'");
} }
private int GetServicePort(string name) private int GetPort(string serviceType)
{ {
return Registry.GetServiceType(name).Port; return Registry.GetServiceTypeInfo(serviceType).Port;
} }
} }
} }

Просмотреть файл

@ -16,15 +16,15 @@ using System.Text.RegularExpressions;
namespace Steeltoe.Tooling.Docker namespace Steeltoe.Tooling.Docker
{ {
public class DockerEnvironment : Environment public class DockerTarget : Target
{ {
public DockerEnvironment(EnvironmentConfiguration config) : base(config) public DockerTarget(TargetConfiguration configuration) : base(configuration)
{ {
} }
public override IServiceBackend GetServiceBackend(Context context) public override IBackend GetBackend(Context context)
{ {
return new DockerServiceBackend(context); return new DockerBackend(context);
} }
public override bool IsHealthy(Context context) public override bool IsHealthy(Context context)

Просмотреть файл

@ -14,45 +14,65 @@
namespace Steeltoe.Tooling.Dummy namespace Steeltoe.Tooling.Dummy
{ {
public class DummyServiceBackend : IServiceBackend public class DummyBackend : IBackend
{ {
private readonly string _path; private readonly string _path;
private DummyServiceDatabase _database; private DummyServiceDatabase _database;
public DummyServiceBackend(string path) public DummyBackend(string path)
{ {
_path = path; _path = path;
_database = DummyServiceDatabase.Load(_path); _database = DummyServiceDatabase.Load(_path);
} }
public void DeployService(string serviceName, string serviceTypeName) public void DeployApp(string app)
{ {
_database.Services[serviceName] = ServiceLifecycle.State.Starting; throw new System.NotImplementedException();
}
public void UndeployApp(string app)
{
throw new System.NotImplementedException();
}
public Lifecycle.Status GetAppStatus(string app)
{
return GetStatus(app);
}
public void DeployService(string service)
{
_database.Services[service] = Lifecycle.Status.Starting;
Store(); Store();
} }
public void UndeployService(string name) public void UndeployService(string service)
{ {
_database.Services[name] = ServiceLifecycle.State.Stopping; _database.Services[service] = Lifecycle.Status.Stopping;
Store(); Store();
} }
public ServiceLifecycle.State GetServiceLifecleState(string name) public Lifecycle.Status GetServiceStatus(string service)
{
return GetStatus(service);
}
private Lifecycle.Status GetStatus(string name)
{ {
if (!_database.Services.ContainsKey(name)) if (!_database.Services.ContainsKey(name))
{ {
return ServiceLifecycle.State.Offline; return Lifecycle.Status.Offline;
} }
var state = _database.Services[name]; var state = _database.Services[name];
switch (state) switch (state)
{ {
case ServiceLifecycle.State.Starting: case Lifecycle.Status.Starting:
_database.Services[name] = ServiceLifecycle.State.Online; _database.Services[name] = Lifecycle.Status.Online;
Store(); Store();
break; break;
case ServiceLifecycle.State.Stopping: case Lifecycle.Status.Stopping:
_database.Services.Remove(name); _database.Services.Remove(name);
Store(); Store();
break; break;

Просмотреть файл

@ -21,8 +21,8 @@ namespace Steeltoe.Tooling.Dummy
{ {
public class DummyServiceDatabase public class DummyServiceDatabase
{ {
public SortedDictionary<string, ServiceLifecycle.State> Services { get; set; } = public SortedDictionary<string, Lifecycle.Status> Services { get; set; } =
new SortedDictionary<string, ServiceLifecycle.State>(); new SortedDictionary<string, Lifecycle.Status>();
internal static void Store(string path, DummyServiceDatabase database) internal static void Store(string path, DummyServiceDatabase database)
{ {

Просмотреть файл

@ -16,15 +16,15 @@ using System.IO;
namespace Steeltoe.Tooling.Dummy namespace Steeltoe.Tooling.Dummy
{ {
public class DummyEnvironment : Environment public class DummyTarget : Target
{ {
public DummyEnvironment(EnvironmentConfiguration config) : base(config) public DummyTarget(TargetConfiguration configuration) : base(configuration)
{ {
} }
public override IServiceBackend GetServiceBackend(Context context) public override IBackend GetBackend(Context context)
{ {
return new DummyServiceBackend(Path.Combine(context.ProjectDirectory, "dummy-service-backend.db")); return new DummyBackend(Path.Combine(context.ProjectDirectory, "dummy-service-backend.db"));
} }
public override bool IsHealthy(Context context) public override bool IsHealthy(Context context)

Просмотреть файл

@ -14,19 +14,30 @@
namespace Steeltoe.Tooling.Executor namespace Steeltoe.Tooling.Executor
{ {
public class DeployServicesExecutor : ServicesExecutor [RequiresInitialization]
public class AddExecutor : Executor
{ {
protected override void Execute(Context context, string serviceName) private readonly string _itemName;
private readonly string _itemType;
public AddExecutor(string itemName, string itemType)
{ {
var state = context.ServiceManager.GetServiceState(serviceName); _itemName = itemName;
if (state == ServiceLifecycle.State.Disabled) _itemType = itemType;
}
protected override void Execute()
{
if (_itemType == "app")
{ {
context.Console.WriteLine($"Ignoring disabled service '{serviceName}'"); Context.Configuration.AddApp(_itemName);
Context.Console.WriteLine($"Added app '{_itemName}'");
} }
else else
{ {
context.Console.WriteLine($"Deploying service '{serviceName}'"); Context.Configuration.AddService(_itemName, _itemType);
context.ServiceManager.DeployService(serviceName); Context.Console.WriteLine($"Added {_itemType} service '{_itemName}'");
} }
} }
} }

Просмотреть файл

@ -0,0 +1,50 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Threading;
namespace Steeltoe.Tooling.Executor
{
public class DeployExecutor : GroupExecutor
{
public DeployExecutor() : base(false)
{
}
protected override void ExecuteForApp(string app)
{
foreach (var service in Context.Configuration.GetServices())
{
int count = 0;
while (Context.Backend.GetServiceStatus(service) != Lifecycle.Status.Online)
{
if (++count == 10)
{
throw new ToolingException("max check exceeded");
}
Context.Console.WriteLine($"Waiting for service '{service}' to come online");
Thread.Sleep(Settings.WaitDuration);
}
}
Context.Console.WriteLine($"Deploying app '{app}'");
new Lifecycle(Context, app).Deploy();
}
protected override void ExecuteForService(string service)
{
Context.Console.WriteLine($"Deploying service '{service}'");
new Lifecycle(Context, service).Deploy();
}
}
}

Просмотреть файл

@ -1,30 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling.Executor
{
public class DisableServiceExecutor : ServiceExecutor
{
public DisableServiceExecutor(string serviceName) : base(serviceName)
{
}
public override void Execute(Context context)
{
base.Execute(context);
context.ServiceManager.DisableService(ServiceName);
context.Console.WriteLine($"Disabled service '{ServiceName}'");
}
}
}

Просмотреть файл

@ -0,0 +1,57 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using Microsoft.Extensions.Logging;
namespace Steeltoe.Tooling.Executor
{
public abstract class Executor
{
private static readonly ILogger Logger = Logging.LoggerFactory.CreateLogger<Executor>();
protected Context Context { get; private set; }
public void Execute(Context context)
{
var type = GetType();
Logger.LogDebug($"executor is {type}");
foreach (var attr in type.GetCustomAttributes(true))
{
if (attr is RequiresInitializationAttribute)
{
Logger.LogDebug($"{type} requires configuration");
if (context.Configuration == null)
{
throw new ToolingException("Steeltoe Developer Tools has not been initialized");
}
}
if (attr is RequiresTargetAttribute)
{
Logger.LogDebug($"{type} requires target");
if (context.Target == null)
{
throw new ToolingException("Target has not been set");
}
}
}
Context = context;
Execute();
}
protected abstract void Execute();
}
}

Просмотреть файл

@ -14,17 +14,23 @@
namespace Steeltoe.Tooling.Executor namespace Steeltoe.Tooling.Executor
{ {
public class EnableServiceExecutor : ServiceExecutor public class GetArgsExecutor : ServiceExecutor
{ {
public EnableServiceExecutor(string serviceName) : base(serviceName) private string _target;
public GetArgsExecutor(string service, string target) : base(service)
{ {
_target = target;
} }
public override void Execute(Context context) protected override void Execute()
{ {
base.Execute(context); base.Execute();
context.ServiceManager.EnableService(ServiceName); var args = Context.Configuration.GetServiceDeploymentArgs(Service, _target);
context.Console.WriteLine($"Enabled service '{ServiceName}'"); if (args != null)
{
Context.Console.WriteLine(args);
}
} }
} }
} }

Просмотреть файл

@ -1,37 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling.Executor
{
public class GetServiceDeploymentArgsExecutor : ServiceExecutor
{
private string _environmentName;
public GetServiceDeploymentArgsExecutor(string environmentName, string serviceName) : base(serviceName)
{
_environmentName = environmentName;
}
public override void Execute(Context context)
{
Registry.GetEnvironment(_environmentName);
base.Execute(context);
var args = context.ServiceManager.GetServiceDeploymentArgs(_environmentName, ServiceName);
if (args != null)
{
context.Console.WriteLine(args);
}
}
}
}

Просмотреть файл

@ -14,18 +14,12 @@
namespace Steeltoe.Tooling.Executor namespace Steeltoe.Tooling.Executor
{ {
[RequiresInitialization] [RequiresTarget]
public class GetTargetExecutor : IExecutor public class GetTargetExecutor : Executor
{ {
public void Execute(Context context) protected override void Execute()
{ {
if (context.Environment == null) Context.Console.WriteLine(Context.Configuration.Target);
{
throw new ToolingException("Target deployment environment not set");
}
context.Console.WriteLine(
$"Target deployment environment set to '{context.Environment.Name}'.");
} }
} }
} }

Просмотреть файл

@ -0,0 +1,88 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.Threading.Tasks;
namespace Steeltoe.Tooling.Executor
{
[RequiresTarget]
public abstract class GroupExecutor : Executor
{
private readonly bool _appsFirst;
protected GroupExecutor(Boolean appsFirst)
{
_appsFirst = appsFirst;
}
protected override void Execute()
{
var services = Context.Configuration.GetServices();
var apps = Context.Configuration.GetApps();
if (Settings.ParallelExecutionEnabled)
{
try
{
if (_appsFirst)
{
Parallel.ForEach(apps, app => { ExecuteForApp(app); });
Parallel.ForEach(services, service => { ExecuteForService(service); });
}
else
{
Parallel.ForEach(services, service => { ExecuteForService(service); });
Parallel.ForEach(apps, app => { ExecuteForApp(app); });
}
}
catch (AggregateException e)
{
throw e.InnerException;
}
}
else
{
if (_appsFirst)
{
foreach (var app in apps)
{
ExecuteForApp(app);
}
foreach (var service in services)
{
ExecuteForService(service);
}
}
else
{
foreach (var service in services)
{
ExecuteForService(service);
}
foreach (var app in apps)
{
ExecuteForApp(app);
}
}
}
}
protected abstract void ExecuteForApp(string app);
protected abstract void ExecuteForService(string service);
}
}

Просмотреть файл

@ -0,0 +1,47 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.IO;
namespace Steeltoe.Tooling.Executor
{
public class InitializationExecutor : Executor
{
private readonly string _path;
private readonly bool _force;
public InitializationExecutor(string path = null, bool force = false)
{
_path = path;
_force = force;
}
protected override void Execute()
{
var path = _path == null
? Context.ProjectDirectory
: Path.Combine(Context.ProjectDirectory, _path);
var cfgFile = new ConfigurationFile(path);
if (cfgFile.Exists() && !_force)
{
throw new ToolingException("Steeltoe Developer Tools already initialized");
}
cfgFile.Store();
Context.Console.WriteLine("Initialized Steeltoe Developer Tools");
}
}
}

Просмотреть файл

@ -12,32 +12,47 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
using System.Linq;
namespace Steeltoe.Tooling.Executor namespace Steeltoe.Tooling.Executor
{ {
[RequiresInitialization] [RequiresInitialization]
public abstract class ListExecutor : IExecutor public class ListExecutor : GroupExecutor
{ {
private bool _verbose; private readonly bool _verbose;
protected ListExecutor(bool verbose) private string _format;
public ListExecutor(bool verbose = false) : base(false)
{ {
_verbose = verbose; _verbose = verbose;
} }
public void Execute(Context context) protected override void Execute()
{ {
var services = Context.Configuration.GetServices();
if (_verbose) if (_verbose)
{ {
ExecuteListVerbose(context); var max = services.Max(n => n.Length);
_format = "{0,-" + max + "} {1,5} {2}";
} }
else else
{ {
ExecuteList(context); _format = "{0}";
} }
base.Execute();
} }
protected abstract void ExecuteList(Context context); protected override void ExecuteForApp(string app)
{
Context.Console.WriteLine(_format, app, "", "app");
}
protected abstract void ExecuteListVerbose(Context context); protected override void ExecuteForService(string service)
{
var svcInfo = Context.Configuration.GetServiceInfo(service);
var svcTypeInfo = Registry.GetServiceTypeInfo(svcInfo.ServiceType);
Context.Console.WriteLine(_format, service, svcTypeInfo.Port, svcTypeInfo.Name);
}
} }
} }

Просмотреть файл

@ -22,24 +22,23 @@ namespace Steeltoe.Tooling.Executor
{ {
} }
protected override void ExecuteList(Context context) protected void ExecuteList(Context context)
{ {
foreach (var svcTypeName in Registry.ServiceTypeNames) foreach (var svcType in Registry.GetServiceTypes())
{ {
context.Console.WriteLine(svcTypeName); context.Console.WriteLine(svcType);
} }
} }
protected override void ExecuteListVerbose(Context context) protected void ExecuteListVerbose(Context context)
{ {
var svcTypeNames = Registry.ServiceTypeNames; var svcTypeNames = Registry.GetServiceTypes();
var max = svcTypeNames.Max(n => n.Length); var max = svcTypeNames.Max(n => n.Length);
var format = "{0,-" + max + "} {1,5} {2}"; var format = "{0,-" + max + "} {1,5} {2}";
foreach (var svcTypeName in svcTypeNames) foreach (var svcTypeName in svcTypeNames)
{ {
var svcType = Registry.GetServiceType(svcTypeName); var svcTypeInfo = Registry.GetServiceTypeInfo(svcTypeName);
context.Console.WriteLine(format, svcType.Name, svcType.Port, svcType.Description); context.Console.WriteLine(format, svcTypeInfo.Name, svcTypeInfo.Port, svcTypeInfo.Description);
} }
} }
} }

Просмотреть файл

@ -1,46 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Linq;
namespace Steeltoe.Tooling.Executor
{
public class ListServicesExecutor : ListExecutor
{
public ListServicesExecutor(bool verbose = false) : base(verbose)
{
}
protected override void ExecuteList(Context context)
{
foreach (var svcName in context.ServiceManager.GetServiceNames())
{
context.Console.WriteLine(svcName);
}
}
protected override void ExecuteListVerbose(Context context)
{
var svcNames = context.ServiceManager.GetServiceNames();
var max = svcNames.Max(n => n.Length);
var format = "{0,-" + max + "} {1,5} {2}";
foreach (var svcName in svcNames)
{
var svc = context.ServiceManager.GetService(svcName);
var svcType = Registry.GetServiceType(svc.Type);
context.Console.WriteLine(format, svcName, svcType.Port, svcType.Name);
}
}
}
}

Просмотреть файл

@ -16,29 +16,29 @@ using System.Linq;
namespace Steeltoe.Tooling.Executor namespace Steeltoe.Tooling.Executor
{ {
public class ListEnvironmentsExecutor : ListExecutor public class ListTargetsExecutor : ListExecutor
{ {
public ListEnvironmentsExecutor(bool verbose = false) : base(verbose) public ListTargetsExecutor(bool verbose = false) : base(verbose)
{ {
} }
protected override void ExecuteList(Context context) protected void ExecuteList(Context context)
{ {
foreach (var envName in Registry.EnvironmentNames) foreach (var envName in Registry.Targets)
{ {
context.Console.WriteLine(envName); context.Console.WriteLine(envName);
} }
} }
protected override void ExecuteListVerbose(Context context) protected void ExecuteListVerbose(Context context)
{ {
var envNames = Registry.EnvironmentNames; var targets = Registry.Targets;
var max = envNames.Max(n => n.Length); var max = targets.Max(n => n.Length);
var format = "{0,-" + max + "} {1}"; var format = "{0,-" + max + "} {1}";
foreach (var envName in Registry.EnvironmentNames) foreach (var target in targets)
{ {
var env = Registry.GetEnvironment(envName); var tgtInfo = Registry.GetTarget(target);
context.Console.WriteLine(format, env.Name, env.Description); context.Console.WriteLine(format, tgtInfo.Name, tgtInfo.Description);
} }
} }
} }

Просмотреть файл

@ -0,0 +1,49 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling.Executor
{
// TODO : write unit test for init req
[RequiresInitialization]
public class RemoveExecutor : Executor
{
private readonly string _name;
public RemoveExecutor(string name)
{
_name = name;
}
protected override void Execute()
{
var cfg = Context.Configuration;
if (cfg.GetApps().Contains(_name))
{
Context.Configuration.RemoveApp(_name);
Context.Console.WriteLine($"Removed app '{_name}'");
}
else if (cfg.GetServices().Contains(_name))
{
var svcInfo = cfg.GetServiceInfo(_name);
Context.Configuration.RemoveService(_name);
Context.Console.WriteLine($"Removed {svcInfo.ServiceType} service '{_name}'");
}
else
{
throw new NotFoundException(_name, "app or service");
}
}
}
}

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright 2018 the original author or authors. // Copyright 2018 the original author or authors.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -12,14 +12,12 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
namespace Steeltoe.Tooling using System;
namespace Steeltoe.Tooling.Executor
{ {
public interface IServiceBackend [AttributeUsage(AttributeTargets.Class)]
public class RequiresTargetAttribute: RequiresInitializationAttribute
{ {
void DeployService(string name, string type);
void UndeployService(string name);
ServiceLifecycle.State GetServiceLifecleState(string name);
} }
} }

Просмотреть файл

@ -15,21 +15,20 @@
namespace Steeltoe.Tooling.Executor namespace Steeltoe.Tooling.Executor
{ {
[RequiresInitialization] [RequiresInitialization]
public abstract class ServiceExecutor : IExecutor public abstract class ServiceExecutor : Executor
{ {
protected string ServiceName { get; } protected string Service { get; }
public ServiceExecutor(string serviceName) protected ServiceInfo ServiceInfo { get; private set; }
public ServiceExecutor(string service)
{ {
ServiceName = serviceName; Service = service;
} }
public virtual void Execute(Context context) protected override void Execute()
{ {
if (!context.ServiceManager.HasService(ServiceName)) ServiceInfo = Context.Configuration.GetServiceInfo(Service);
{
throw new ServiceNotFoundException(ServiceName);
}
} }
} }
} }

Просмотреть файл

@ -1,56 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Steeltoe.Tooling.Executor
{
[RequiresInitialization]
public abstract class ServicesExecutor : IExecutor
{
protected List<string> ServiceNames { get; private set; }
public virtual void Execute(Context context)
{
ServiceNames = context.ServiceManager.GetServiceNames();
if (ServiceNames.Count == 0)
{
return;
}
if (Settings.ParallelExecutionEnabled)
{
try
{
Parallel.ForEach(ServiceNames, svcName => { Execute(context, svcName); });
}
catch (AggregateException e)
{
throw e.InnerException;
}
}
else
{
foreach (var serviceName in ServiceNames)
{
Execute(context, serviceName);
}
}
}
protected abstract void Execute(Context context, string serviceName);
}
}

Просмотреть файл

@ -14,36 +14,34 @@
namespace Steeltoe.Tooling.Executor namespace Steeltoe.Tooling.Executor
{ {
public class SetServiceDeploymentArgsExecutor : ServiceExecutor public class SetArgsExecutor : ServiceExecutor
{ {
private readonly string _environmentName; private readonly string _target;
private readonly string _arguments; private readonly string _arguments;
private readonly bool _force; private readonly bool _force;
public SetServiceDeploymentArgsExecutor(string environmentName, string serviceName, string arguments, public SetArgsExecutor(string service, string target, string arguments, bool force = false) :
bool force = false) : base(service)
base(serviceName)
{ {
_environmentName = environmentName; _target = target;
_arguments = arguments; _arguments = arguments;
_force = force; _force = force;
} }
public override void Execute(Context context) protected override void Execute()
{ {
base.Execute(context); base.Execute();
var args = context.ServiceManager.GetServiceDeploymentArgs(_environmentName, ServiceName); var args = Context.Configuration.GetServiceDeploymentArgs(Service, _target);
if (args != null && !_force) if (args != null && !_force)
{ {
throw new ToolingException( throw new ToolingException(
$"'{_environmentName}' deployment environment arguments for service '{ServiceName}' already set."); $"Service '{Service}' args for target '{_target}' already set to '{args}'");
} }
context.ServiceManager.SetServiceDeploymentArgs(_environmentName, ServiceName, _arguments); Context.Configuration.SetServiceDeploymentArgs(Service, _target, _arguments);
context.Console.WriteLine( Context.Console.WriteLine($"Service '{Service}' args for target '{_target}' set to '{_arguments}'");
$"Set the '{_environmentName}' deployment environment arguments for service '{ServiceName}' to '{_arguments}'");
} }
} }
} }

Просмотреть файл

@ -15,36 +15,36 @@
namespace Steeltoe.Tooling.Executor namespace Steeltoe.Tooling.Executor
{ {
[RequiresInitialization] [RequiresInitialization]
public class SetTargetExecutor : IExecutor public class SetTargetExecutor : Executor
{ {
private readonly string _environmentName; private readonly string _target;
private readonly bool _force; private readonly bool _force;
public SetTargetExecutor(string environmentName, bool force = false) public SetTargetExecutor(string target, bool force = false)
{ {
_environmentName = environmentName; _target = target;
_force = force; _force = force;
} }
public void Execute(Context context) protected override void Execute()
{ {
Environment env = Registry.GetEnvironment(_environmentName); Target tgt = Registry.GetTarget(_target);
if (!env.IsHealthy(context)) if (!tgt.IsHealthy(Context))
{ {
if (!_force) if (!_force)
{ {
context.Console.WriteLine("Fix errors above or re-run with '-F|--force'"); Context.Console.WriteLine("Fix errors above or re-run with '-F|--force'");
throw new ToolingException($"Environment '{_environmentName }' does not appear healthy"); throw new ToolingException($"Target '{_target}' does not appear healthy");
} }
context.Console.WriteLine("Ignoring poor health report above :-("); Context.Console.WriteLine("Ignoring poor health report above :-(");
} }
context.ToolingConfiguration.EnvironmentName = _environmentName; Context.Configuration.Target = _target;
context.ToolingConfiguration.NotifyChanged(); Context.Configuration.NotifyChanged();
context.Console.WriteLine($"Target deployment environment set to '{_environmentName}'."); Context.Console.WriteLine($"Target set to '{_target}'");
} }
} }
} }

Просмотреть файл

@ -0,0 +1,24 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling.Executor
{
public class StatusApplicationsExecutor : Executor
{
protected override void Execute()
{
throw new System.NotImplementedException();
}
}
}

Просмотреть файл

@ -14,24 +14,22 @@
namespace Steeltoe.Tooling.Executor namespace Steeltoe.Tooling.Executor
{ {
[RequiresInitialization] public class StatusExecutor : GroupExecutor
public class AddServiceExecutor : IExecutor
{ {
private string _name; public StatusExecutor() : base(false)
private string _type;
public AddServiceExecutor(string serviceName, string serviceType)
{ {
_name = serviceName;
_type = serviceType;
} }
public void Execute(Context context) protected override void ExecuteForApp(string app)
{ {
context.ServiceManager.AddService(_name, _type); var status = Context.Backend.GetAppStatus(app);
context.ServiceManager.EnableService(_name); Context.Console.WriteLine($"{app} {status.ToString().ToLower()}");
context.Console.WriteLine($"Added {_type} service '{_name}'"); }
protected override void ExecuteForService(string service)
{
var status = Context.Backend.GetServiceStatus(service);
Context.Console.WriteLine($"{service} {status.ToString().ToLower()}");
} }
} }
} }

Просмотреть файл

@ -0,0 +1,25 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling.Executor
{
public class UndeployApplicationsExecutor : Executor
{
protected override void Execute()
{
// context.Console.WriteLine($"Undeploying project '{serviceName}'");
throw new System.NotImplementedException();
}
}
}

Просмотреть файл

@ -14,17 +14,22 @@
namespace Steeltoe.Tooling.Executor namespace Steeltoe.Tooling.Executor
{ {
public class RemoveServiceExecutor : ServiceExecutor public class UndeployExecutor : GroupExecutor
{ {
public RemoveServiceExecutor(string serviceName) : base(serviceName) public UndeployExecutor() : base(true)
{ {
} }
public override void Execute(Context context) protected override void ExecuteForApp(string app)
{ {
base.Execute(context); Context.Console.WriteLine($"Undeploying app '{app}'");
context.ServiceManager.RemoveService(ServiceName); new Lifecycle(Context, app).Undeploy();
context.Console.WriteLine($"Removed service '{ServiceName}'"); }
protected override void ExecuteForService(string service)
{
Context.Console.WriteLine($"Undeploying service '{service}'");
new Lifecycle(Context, service).Undeploy();
} }
} }
} }

Просмотреть файл

@ -1,33 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling.Executor
{
public class UndeployServicesExecutor : ServicesExecutor
{
protected override void Execute(Context context, string serviceName)
{
var state = context.ServiceManager.GetServiceState(serviceName);
if (state == ServiceLifecycle.State.Disabled)
{
context.Console.WriteLine($"Ignoring disabled service '{serviceName}'");
}
else
{
context.Console.WriteLine($"Undeploying service '{serviceName}'");
context.ServiceManager.UndeployService(serviceName);
}
}
}
}

Просмотреть файл

@ -12,14 +12,20 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
namespace Steeltoe.Tooling.Executor namespace Steeltoe.Tooling
{ {
public class StatusServicesExecutor : ServicesExecutor public interface IBackend
{ {
protected override void Execute(Context context, string serviceName) void DeployApp(string application);
{
var status = context.ServiceManager.GetServiceState(serviceName).ToString().ToLower(); void UndeployApp(string application);
context.Console.WriteLine($"{serviceName} {status}");
} Lifecycle.Status GetAppStatus(string application);
void DeployService(string service);
void UndeployService(string service);
Lifecycle.Status GetServiceStatus(string service);
} }
} }

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright 2018 the original author or authors. // Copyright 2018 the original author or authors.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -12,10 +12,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
namespace Steeltoe.Tooling.Executor namespace Steeltoe.Tooling
{ {
public interface IExecutor public interface IConfigurationListener
{ {
void Execute(Context context); void ConfigurationChangeEvent();
} }
} }

Просмотреть файл

@ -1,7 +0,0 @@
namespace Steeltoe.Tooling
{
public interface IToolingConfigurationListener
{
void ConfigurationChangeEvent();
}
}

Просмотреть файл

@ -0,0 +1,122 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling
{
public class Lifecycle
{
public enum Status
{
Offline,
Starting,
Online,
Stopping,
Unknown,
}
private readonly IBackend _backend;
private readonly string _name;
private readonly BackendBridge _bridge;
public Lifecycle(Context context, string name)
{
_backend = context.Backend;
_name = name;
_bridge = new ServiceBackendBridge();
}
public Status GetStatus()
{
return _bridge.GetStatus(_name, _backend);
}
public void Undeploy()
{
GetState().Undeploy(_name, _backend);
}
public void Deploy()
{
GetState().Deploy(_name, _backend);
}
private State GetState()
{
var status = GetStatus();
switch (status)
{
case Status.Offline:
return new OfflineState();
case Status.Starting:
return new StartingState();
case Status.Online:
return new OnlineState();
case Status.Stopping:
return new StoppingState();
default:
throw new ToolingException($"Unhandled lifecycle status: {status}");
}
}
abstract class State
{
internal virtual void Deploy(string name, IBackend backend)
{
}
internal virtual void Undeploy(string name, IBackend backend)
{
}
}
class OfflineState : State
{
internal override void Deploy(string name, IBackend backend)
{
backend.DeployService(name);
}
}
class StartingState : State
{
}
class OnlineState : State
{
internal override void Undeploy(string name, IBackend backend)
{
backend.UndeployService(name);
}
}
class StoppingState : State
{
}
abstract class BackendBridge
{
internal abstract Status GetStatus(string name, IBackend backend);
}
class ServiceBackendBridge : BackendBridge
{
internal override Status GetStatus(string name, IBackend backend)
{
return backend.GetServiceStatus(name);
}
}
}
}

Просмотреть файл

@ -14,14 +14,14 @@
namespace Steeltoe.Tooling namespace Steeltoe.Tooling
{ {
public class ServiceLifecycleException : ToolingException public class LifecycleException : ToolingException
{ {
public ServiceLifecycle.State State { get; } public Lifecycle.Status Status { get; }
public ServiceLifecycleException(ServiceLifecycle.State state) : base( public LifecycleException(Lifecycle.Status status) : base(
$"Invalid service status '{state.ToString().ToLower()}'") $"Invalid status '{status.ToString().ToLower()}'")
{ {
State = state; Status = status;
} }
} }
} }

Просмотреть файл

@ -0,0 +1,30 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling
{
public class NotFoundException : ToolingException
{
public string Name { get; }
public string Description { get; }
public NotFoundException(string itemName, string description) : base($"Unknown {description} '{itemName}'")
{
Name = itemName;
Description = description;
}
}
}

Просмотреть файл

@ -21,6 +21,7 @@ using Steeltoe.Tooling.CloudFoundry;
using Steeltoe.Tooling.Docker; using Steeltoe.Tooling.Docker;
using Steeltoe.Tooling.Dummy; using Steeltoe.Tooling.Dummy;
using YamlDotNet.Serialization; using YamlDotNet.Serialization;
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace Steeltoe.Tooling namespace Steeltoe.Tooling
{ {
@ -28,7 +29,51 @@ namespace Steeltoe.Tooling
{ {
private static readonly ILogger Logger = Logging.LoggerFactory.CreateLogger<Registry>(); private static readonly ILogger Logger = Logging.LoggerFactory.CreateLogger<Registry>();
private static RegistryConfiguration _configuration = new RegistryConfiguration(); public class Configuration
{
[YamlMember(Alias = "serviceTypes")]
public SortedDictionary<string, ServiceTypeInfo> ServiceTypes { get; set; } =
new SortedDictionary<string, ServiceTypeInfo>();
[YamlMember(Alias = "targets")]
public SortedDictionary<string, TargetConfiguration> TargetConfigurations { get; set; } =
new SortedDictionary<string, TargetConfiguration>();
public void DefineServiceType(string name, int port, string description)
{
ServiceTypes[name] = new ServiceTypeInfo {Port = port, Description = description};
}
public void DefineTarget(string target, string description)
{
TargetConfigurations[target] = new TargetConfiguration {Description = description};
}
public void DefineTargetServiceTypeProperty(
string target,
string serviceType,
string propertyName,
string propertyValue)
{
if (!TargetConfigurations.ContainsKey(target))
{
TargetConfigurations[target] = new TargetConfiguration();
}
var targetCfg = TargetConfigurations[target];
if (!targetCfg.ServiceTypeProperties.ContainsKey(serviceType))
{
targetCfg.ServiceTypeProperties[serviceType] = new Dictionary<string, string>();
}
targetCfg.ServiceTypeProperties[serviceType][propertyName] = propertyValue;
TargetConfigurations[target] = targetCfg;
}
}
private static Configuration _configuration = new Configuration();
public static List<string> Targets => _configuration.TargetConfigurations.Keys.ToList();
static Registry() static Registry()
{ {
@ -36,12 +81,12 @@ namespace Steeltoe.Tooling
if (Settings.DummiesEnabled) if (Settings.DummiesEnabled)
{ {
Logger.LogDebug("loading dummy registry"); Logger.LogDebug("loading dummy registry");
var dummyCfg = new RegistryConfiguration(); var dummyCfg = new Configuration();
var dummySvcType = new ServiceType {Port = 0, Description = "A Dummy Service"}; var dummySvcType = new ServiceTypeInfo {Port = 0, Description = "A Dummy Service"};
dummyCfg.ServiceTypes.Add("dummy-svc", dummySvcType); dummyCfg.ServiceTypes.Add("dummy-svc", dummySvcType);
var dummyEnvCfg = new EnvironmentConfiguration(); var dummyTarget = new TargetConfiguration();
dummyEnvCfg.Description = "A Dummy Environment"; dummyTarget.Description = "A Dummy Target";
dummyCfg.EnvironmentConfigurations.Add("dummy-env", dummyEnvCfg); dummyCfg.TargetConfigurations.Add("dummy-target", dummyTarget);
AddRegistryConfiguration(dummyCfg); AddRegistryConfiguration(dummyCfg);
} }
@ -52,48 +97,49 @@ namespace Steeltoe.Tooling
var deserializer = new DeserializerBuilder().Build(); var deserializer = new DeserializerBuilder().Build();
using (var reader = new StreamReader(path)) using (var reader = new StreamReader(path))
{ {
var defaultCfg = deserializer.Deserialize<RegistryConfiguration>(reader); var defaultCfg = deserializer.Deserialize<Configuration>(reader);
AddRegistryConfiguration(defaultCfg); AddRegistryConfiguration(defaultCfg);
} }
} }
public static List<string> ServiceTypeNames => _configuration.ServiceTypes.Keys.ToList(); public static List<string> GetServiceTypes()
public static ServiceType GetServiceType(string serviceTypeName)
{ {
ServiceType svcType; return _configuration.ServiceTypes.Keys.ToList();
if (_configuration.ServiceTypes.TryGetValue(serviceTypeName, out svcType)) }
public static ServiceTypeInfo GetServiceTypeInfo(string serviceType)
{
ServiceTypeInfo svcTypeInfo;
if (_configuration.ServiceTypes.TryGetValue(serviceType, out svcTypeInfo))
{ {
svcType.Name = serviceTypeName; svcTypeInfo.Name = serviceType;
return svcType; return svcTypeInfo;
} }
return null; return null;
} }
public static List<string> EnvironmentNames => _configuration.EnvironmentConfigurations.Keys.ToList(); public static Target GetTarget(string target)
public static Environment GetEnvironment(string environmentName)
{ {
EnvironmentConfiguration envCfg; TargetConfiguration targetCfg;
if (_configuration.EnvironmentConfigurations.TryGetValue(environmentName, out envCfg)) if (_configuration.TargetConfigurations.TryGetValue(target, out targetCfg))
{ {
envCfg.Name = environmentName; targetCfg.Name = target;
switch (envCfg.Name) switch (targetCfg.Name)
{ {
case "cloud-foundry": case "cloud-foundry":
return new CloudFoundryEnvironment(envCfg); return new CloudFoundryTarget(targetCfg);
case "docker": case "docker":
return new DockerEnvironment(envCfg); return new DockerTarget(targetCfg);
case "dummy-env": case "dummy-target":
return new DummyEnvironment(envCfg); return new DummyTarget(targetCfg);
} }
} }
throw new ToolingException($"Unknown deployment environment '{environmentName}'"); throw new ToolingException($"Unknown target '{target}'");
} }
private static void AddRegistryConfiguration(RegistryConfiguration configuration) private static void AddRegistryConfiguration(Configuration configuration)
{ {
foreach (var svcTypeEntry in configuration.ServiceTypes) foreach (var svcTypeEntry in configuration.ServiceTypes)
{ {
@ -101,10 +147,10 @@ namespace Steeltoe.Tooling
_configuration.ServiceTypes[svcTypeEntry.Key] = svcTypeEntry.Value; _configuration.ServiceTypes[svcTypeEntry.Key] = svcTypeEntry.Value;
} }
foreach (var envCfgEntry in configuration.EnvironmentConfigurations) foreach (var targetCfgEntry in configuration.TargetConfigurations)
{ {
envCfgEntry.Value.Name = null; targetCfgEntry.Value.Name = null;
_configuration.EnvironmentConfigurations[envCfgEntry.Key] = envCfgEntry.Value; _configuration.TargetConfigurations[targetCfgEntry.Key] = targetCfgEntry.Value;
} }
} }
} }

Просмотреть файл

@ -1,62 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Collections.Generic;
using YamlDotNet.Serialization;
namespace Steeltoe.Tooling
{
public class RegistryConfiguration
{
[YamlMember(Alias = "serviceTypes")]
public SortedDictionary<string, ServiceType> ServiceTypes { get; set; } =
new SortedDictionary<string, ServiceType>();
[YamlMember(Alias = "environments")]
public SortedDictionary<string, EnvironmentConfiguration> EnvironmentConfigurations { get; set; } =
new SortedDictionary<string, EnvironmentConfiguration>();
public void DefineServiceType(string name, int port, string description)
{
ServiceTypes[name] = new ServiceType {Port = port, Description = description};
}
public void DefineEnvironment(string environmentName, string description)
{
var envCfg = new EnvironmentConfiguration {Description = description};
EnvironmentConfigurations[environmentName] = envCfg;
}
public void DefineEnvironmentServiceTypeProperty(
string environmentName,
string serviceTypeName,
string propertyName,
string propertyValue)
{
if (!EnvironmentConfigurations.ContainsKey(environmentName))
{
EnvironmentConfigurations[environmentName] = new EnvironmentConfiguration();
}
var envCfg = EnvironmentConfigurations[environmentName];
if (!envCfg.ServiceTypeProperties.ContainsKey(serviceTypeName))
{
envCfg.ServiceTypeProperties[serviceTypeName] = new Dictionary<string, string>();
}
envCfg.ServiceTypeProperties[serviceTypeName][propertyName] = propertyValue;
EnvironmentConfigurations[environmentName] = envCfg;
}
}
}

Просмотреть файл

@ -14,13 +14,16 @@
namespace Steeltoe.Tooling namespace Steeltoe.Tooling
{ {
public class ServiceNotFoundException : ToolingException public class ServiceInfo
{ {
public string Name { get; } public string Service { get; }
public ServiceNotFoundException(string name) : base($"Service '{name}' not found") public string ServiceType { get; }
public ServiceInfo(string service, string serviceType)
{ {
Name = name; Service = service;
ServiceType = serviceType;
} }
} }
} }

Просмотреть файл

@ -1,194 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Steeltoe.Tooling
{
public class ServiceLifecycle
{
public enum State
{
Disabled,
Offline,
Starting,
Online,
Stopping,
Unknown,
}
public Context Context { get; }
public string Name { get; }
public ServiceLifecycle(Context context, string name)
{
Context = context;
Name = name;
}
public void Enable()
{
GetStateManager().Enable();
}
public void Disable()
{
GetStateManager().Disable();
}
public void Deploy()
{
GetStateManager().Deploy();
}
public void Undeploy()
{
GetStateManager().Undeploy();
}
private StateManager GetStateManager()
{
var state = Context.ServiceManager.GetServiceState(Name);
switch (state)
{
case State.Disabled:
return new ServiceDisabled(Context, Name, state);
case State.Offline:
return new ServiceOffline(Context, Name, state);
case State.Starting:
return new ServiceStarting(Context, Name, state);
case State.Online:
return new ServiceOnline(Context, Name, state);
case State.Stopping:
return new ServiceStopping(Context, Name, state);
}
throw new ToolingException($"Unhandled service state '{state.ToString().ToLower()}'");
}
private class StateManager
{
internal Context Context { get; }
internal string Name { get; }
internal State State { get; }
internal StateManager(Context context, string name, State state)
{
Context = context;
Name = name;
State = state;
}
internal virtual void Enable()
{
throw new ServiceLifecycleException(State);
}
internal virtual void Disable()
{
throw new ServiceLifecycleException(State);
}
internal virtual void Deploy()
{
throw new ServiceLifecycleException(State);
}
internal virtual void Undeploy()
{
throw new ServiceLifecycleException(State);
}
}
private class ServiceDisabled : StateManager
{
internal ServiceDisabled(Context context, string name, State state) : base(context, name, state)
{
}
internal override void Enable()
{
Context.ToolingConfiguration.Services[Name].Enabled = true;
Context.ToolingConfiguration.NotifyChanged();
}
internal override void Disable()
{
}
}
private class ServiceOffline : StateManager
{
internal ServiceOffline(Context context, string name, State state) : base(context, name, state)
{
}
internal override void Enable()
{
}
internal override void Disable()
{
Context.ToolingConfiguration.Services[Name].Enabled = false;
Context.ToolingConfiguration.NotifyChanged();
}
internal override void Deploy()
{
Context.ServiceManager.GetServiceBackend()
.DeployService(Name, Context.ToolingConfiguration.Services[Name].ServiceTypeName);
}
internal override void Undeploy()
{
}
}
private class ServiceOnline : StateManager
{
internal ServiceOnline(Context context, string name, State state) : base(context, name, state)
{
}
internal override void Deploy()
{
}
internal override void Undeploy()
{
Context.ServiceManager.GetServiceBackend().UndeployService(Name);
}
}
private class ServiceStarting : StateManager
{
internal ServiceStarting(Context context, string name, State state) : base(context, name, state)
{
}
internal override void Undeploy()
{
Context.ServiceManager.GetServiceBackend().UndeployService(Name);
}
}
private class ServiceStopping : StateManager
{
internal ServiceStopping(Context context, string name, State state) : base(context, name, state)
{
}
}
}
}

Просмотреть файл

@ -1,132 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Collections.Generic;
using System.Linq;
namespace Steeltoe.Tooling
{
public class ServiceManager
{
protected internal readonly Context Context;
public ServiceManager(Context context)
{
Context = context;
}
public IServiceBackend GetServiceBackend()
{
return Context.Environment.GetServiceBackend(Context);
}
public Service AddService(string name, string type)
{
if (!Registry.ServiceTypeNames.Contains(type))
{
throw new ToolingException($"Unknown service type '{type}'");
}
if (Context.ToolingConfiguration.Services.ContainsKey(name))
{
throw new ToolingException($"Service '{name}' already exists");
}
Context.ToolingConfiguration.Services[name] = new ToolingConfiguration.Service {ServiceTypeName = type};
Context.ToolingConfiguration.NotifyChanged();
return GetService(name);
}
public void RemoveService(string name)
{
if (!Context.ToolingConfiguration.Services.Remove(name))
{
throw new ServiceNotFoundException(name);
}
Context.ToolingConfiguration.NotifyChanged();
}
public Service GetService(string name)
{
try
{
var svcCfg = Context.ToolingConfiguration.Services[name];
return new Service(name, svcCfg.ServiceTypeName);
}
catch (KeyNotFoundException)
{
throw new ServiceNotFoundException(name);
}
}
public List<string> GetServiceNames()
{
return Context.ToolingConfiguration.Services.Keys.ToList();
}
public bool HasService(string name)
{
return Context.ToolingConfiguration.Services.ContainsKey(name);
}
public void SetServiceDeploymentArgs(string environmentName, string serviceName, string arguments)
{
Context.ToolingConfiguration.Services[serviceName].Args[environmentName] = arguments;
Context.ToolingConfiguration.NotifyChanged();
}
public string GetServiceDeploymentArgs(string environmentName, string serviceName)
{
try
{
return Context.ToolingConfiguration.Services[serviceName].Args[environmentName];
}
catch (KeyNotFoundException)
{
return null;
}
}
public ServiceLifecycle.State GetServiceState(string name)
{
if (!Context.ToolingConfiguration.Services[name].Enabled)
{
return ServiceLifecycle.State.Disabled;
}
return GetServiceBackend().GetServiceLifecleState(name);
}
public void EnableService(string name)
{
new ServiceLifecycle(Context, name).Enable();
}
public void DisableService(string name)
{
new ServiceLifecycle(Context, name).Disable();
}
public void DeployService(string name)
{
new ServiceLifecycle(Context, name).Deploy();
}
public void UndeployService(string name)
{
new ServiceLifecycle(Context, name).Undeploy();
}
}
}

Просмотреть файл

@ -16,10 +16,10 @@ using YamlDotNet.Serialization;
namespace Steeltoe.Tooling namespace Steeltoe.Tooling
{ {
public class ServiceType public class ServiceTypeInfo
{ {
[YamlMember(Alias = "name")] [YamlMember(Alias = "name")]
public string Name { get; set; } public string Name { get; set; }
[YamlMember(Alias = "port")] [YamlMember(Alias = "port")]
public int Port { get; set; } public int Port { get; set; }

Просмотреть файл

@ -24,6 +24,8 @@ namespace Steeltoe.Tooling
public static bool ParallelExecutionEnabled { get; set; } = true; public static bool ParallelExecutionEnabled { get; set; } = true;
public static int WaitDuration = 1000;
static Settings() static Settings()
{ {
DummiesEnabled = File.Exists(".steeltoe.dummies"); DummiesEnabled = File.Exists(".steeltoe.dummies");

Просмотреть файл

@ -14,26 +14,26 @@
namespace Steeltoe.Tooling namespace Steeltoe.Tooling
{ {
public abstract class Environment public abstract class Target
{ {
public EnvironmentConfiguration Configuration { get; } public TargetConfiguration Configuration { get; }
public string Name => Configuration.Name; public string Name => Configuration.Name;
public string Description => Configuration.Description; public string Description => Configuration.Description;
protected Environment(EnvironmentConfiguration config) protected Target(TargetConfiguration configuration)
{ {
Configuration = config; Configuration = configuration;
} }
public abstract IServiceBackend GetServiceBackend(Context context); public abstract IBackend GetBackend(Context context);
public abstract bool IsHealthy(Context context); public abstract bool IsHealthy(Context context);
public override string ToString() public override string ToString()
{ {
return $"Environment[name={Name},desc=\"{Description}\"]"; return $"Target[name={Name},desc=\"{Description}\"]";
} }
} }
} }

Просмотреть файл

@ -17,7 +17,7 @@ using YamlDotNet.Serialization;
namespace Steeltoe.Tooling namespace Steeltoe.Tooling
{ {
public class EnvironmentConfiguration public class TargetConfiguration
{ {
[YamlMember(Alias = "name")] public string Name { get; set; } [YamlMember(Alias = "name")] public string Name { get; set; }

Просмотреть файл

@ -1,61 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using YamlDotNet.Serialization;
namespace Steeltoe.Tooling
{
public class ToolingConfiguration
{
private static readonly ILogger Logger = Logging.LoggerFactory.CreateLogger<ToolingConfiguration>();
[YamlMember(Alias = "environment")]
public string EnvironmentName { get; set; }
[YamlMember(Alias = "services")]
public SortedDictionary<string, Service> Services { get; protected set; } =
new SortedDictionary<string, Service>();
public class Service
{
[YamlMember(Alias = "type")]
public string ServiceTypeName { get; set; }
[YamlMember(Alias = "enabled")]
public bool Enabled { get; set; }
[YamlMember(Alias = "args")]
public SortedDictionary<string, string> Args { get; protected set; } =
new SortedDictionary<string, string>();
}
private readonly List<IToolingConfigurationListener> _listeners = new List<IToolingConfigurationListener>();
public void AddListener(IToolingConfigurationListener listener)
{
_listeners.Add(listener);
}
public void NotifyChanged()
{
Logger.LogDebug("configuration changed");
foreach (var listener in _listeners)
{
listener.ConfigurationChangeEvent();
}
}
}
}

Просмотреть файл

@ -32,22 +32,25 @@ serviceTypes:
description: Zipkin Tracing Collector and UI description: Zipkin Tracing Collector and UI
port: 9411 port: 9411
environments: targets:
cloud-foundry: cloud-foundry:
description: Cloud Foundry description: Cloud Foundry
serviceTypeProperties: serviceTypeProperties:
circuit-breaker-dashboard: dummy-svc:
service: p-circuit-breaker-dashboard service: dummy-server
plan: standard plan: dummy-plan
config-server: config-server:
service: p-config-server service: p-config-server
plan: standard plan: standard
redis-server: eureka-server:
service: p-redis
plan: shared-vm
service-registry:
service: p-service-registry service: p-service-registry
plan: standard plan: standard
hystrix-dashboard:
service: p-circuit-breaker-dashboard
plan: standard
redis:
service: p-redis
plan: shared-vm
docker: docker:
description: Docker description: Docker
serviceTypeProperties: serviceTypeProperties:

Просмотреть файл

@ -12,17 +12,14 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended; using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2; using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test namespace Steeltoe.Cli.Test
{ {
[Label("add")]
public class AddFeature : FeatureSpecs public class AddFeature : FeatureSpecs
{ {
[Scenario] [Scenario]
[Label("help")]
public void AddHelp() public void AddHelp()
{ {
Runner.RunScenario( Runner.RunScenario(
@ -30,11 +27,11 @@ namespace Steeltoe.Cli.Test
when => the_developer_runs_cli_command("add --help"), when => the_developer_runs_cli_command("add --help"),
then => the_cli_should_output(new[] then => the_cli_should_output(new[]
{ {
"Add a service.", "Add an app or service",
$"Usage: {Program.Name} add [arguments] [options]", $"Usage: {Program.Name} add [arguments] [options]",
"Arguments:", "Arguments:",
"type Service type", "type 'app' or service type",
"service Service name", "name App or service name",
"Options:", "Options:",
"-?|-h|--help Show help information", "-?|-h|--help Show help information",
}) })
@ -45,15 +42,15 @@ namespace Steeltoe.Cli.Test
public void AddNotEnoughArgs() public void AddNotEnoughArgs()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_dotnet_project("add_not_enough_args0"), given => a_dotnet_project("add_not_enough"),
when => the_developer_runs_cli_command("add"), when => the_developer_runs_cli_command("add"),
then => the_cli_should_error(ErrorCode.Argument, "Service type not specified") then => the_cli_should_error(ErrorCode.Argument, "'app' or service type not specified")
); );
Console.Clear(); Console.Clear();
Runner.RunScenario( Runner.RunScenario(
given => a_dotnet_project("add_not_enough_args1"), given => a_dotnet_project("add_not_enough_args1"),
when => the_developer_runs_cli_command("add arg1"), when => the_developer_runs_cli_command("add arg1"),
then => the_cli_should_error(ErrorCode.Argument, "Service name not specified") then => the_cli_should_error(ErrorCode.Argument, "App or service name not specified")
); );
} }
@ -68,23 +65,44 @@ namespace Steeltoe.Cli.Test
} }
[Scenario] [Scenario]
public void AddUnknownServiceType() public void AddUninitialized()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_steeltoe_project("add_unknown_service_type"), given => a_dotnet_project("add_uninitialized"),
when => the_developer_runs_cli_command("add no-such-type foo"), when => the_developer_runs_cli_command("add dummy-svc my-service"),
then => the_cli_should_error(ErrorCode.Tooling, "Unknown service type 'no-such-type'") then => the_cli_should_error(ErrorCode.Tooling, "Steeltoe Developer Tools has not been initialized")
); );
} }
[Scenario] [Scenario]
public void AddUninitializedProject() public void AddUnknownServiceType()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_dotnet_project("add_uninitialized_project"), given => a_steeltoe_project("add_unknown_type"),
when => the_developer_runs_cli_command("add dummy-svc my-service"), when => the_developer_runs_cli_command("add no-such-service-type foo"),
then => the_cli_should_error(ErrorCode.Tooling, then => the_cli_should_error(ErrorCode.Tooling, "Unknown type 'no-such-service-type'")
"Project has not been initialized for Steeltoe Developer Tools") );
}
[Scenario]
public void AddApp()
{
Runner.RunScenario(
given => a_steeltoe_project("add_app"),
when => the_developer_runs_cli_command("add app my-app"),
then => the_cli_should_output("Added app 'my-app'"),
and => the_configuration_should_contain_app("my-app")
);
}
[Scenario]
public void AddExistingApp()
{
Runner.RunScenario(
given => a_steeltoe_project("add_existing_app"),
when => the_developer_runs_cli_command("add app existing-app"),
and => the_developer_runs_cli_command("add app existing-app"),
then => the_cli_should_error(ErrorCode.Tooling, "App 'existing-app' already exists")
); );
} }
@ -95,16 +113,15 @@ namespace Steeltoe.Cli.Test
given => a_steeltoe_project("add_service"), given => a_steeltoe_project("add_service"),
when => the_developer_runs_cli_command("add dummy-svc my-service"), when => the_developer_runs_cli_command("add dummy-svc my-service"),
then => the_cli_should_output("Added dummy-svc service 'my-service'"), then => the_cli_should_output("Added dummy-svc service 'my-service'"),
and => the_configuration_should_contain_service("my-service"), and => the_configuration_should_contain_service("my-service", "dummy-svc")
and => the_configuration_service_should_be_enabled("my-service")
); );
} }
[Scenario] [Scenario]
public void AddPreExistingService() public void AddExistingService()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_steeltoe_project("add_pre_existing_service"), given => a_steeltoe_project("add_existing_service"),
when => the_developer_runs_cli_command("add dummy-svc existing-service"), when => the_developer_runs_cli_command("add dummy-svc existing-service"),
and => the_developer_runs_cli_command("add dummy-svc existing-service"), and => the_developer_runs_cli_command("add dummy-svc existing-service"),
then => the_cli_should_error(ErrorCode.Tooling, "Service 'existing-service' already exists") then => the_cli_should_error(ErrorCode.Tooling, "Service 'existing-service' already exists")

Просмотреть файл

@ -12,17 +12,14 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended; using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2; using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test namespace Steeltoe.Cli.Test
{ {
[Label("args")]
public class ArgsFeature : FeatureSpecs public class ArgsFeature : FeatureSpecs
{ {
[Scenario] [Scenario]
[Label("help")]
public void ArgsHelp() public void ArgsHelp()
{ {
Runner.RunScenario( Runner.RunScenario(
@ -30,16 +27,16 @@ namespace Steeltoe.Cli.Test
when => the_developer_runs_cli_command("args --help"), when => the_developer_runs_cli_command("args --help"),
then => the_cli_should_output(new[] then => the_cli_should_output(new[]
{ {
"Set or get the deployment environment arguments for a service.", "Set or get the deployment arguments for an app or service",
$"Usage: {Program.Name} args [arguments] [options] [[--] <arg>...]", $"Usage: {Program.Name} args [arguments] [options] [[--] <arg>...]",
"Arguments:", "Arguments:",
"environment Deployment environment", "name App or service name",
"service Service name", "target Deployment target name",
"args Deployment environment arguments", "args Deployment arguments",
"Options:", "Options:",
"-F|--force Overwrite existing deployment environment arguments", "-F|--force Overwrite existing deployment environment arguments",
"-?|-h|--help Show help information", "-?|-h|--help Show help information",
"If run with no deployment environment arguments, show the service's current deployment environment arguments.", "If run with no arguments, show the current deployment arguments for the app or service.",
}) })
); );
} }
@ -48,109 +45,136 @@ namespace Steeltoe.Cli.Test
public void ArgsNotEnoughArgs() public void ArgsNotEnoughArgs()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_dotnet_project("args_not_enough_args0"), given => a_dotnet_project("args_not_enough"),
when => the_developer_runs_cli_command("args"), when => the_developer_runs_cli_command("args"),
then => the_cli_should_error(ErrorCode.Argument, "Deployment environment not specified") then => the_cli_should_error(ErrorCode.Argument, "App or service name not specified")
); );
Console.Clear(); Console.Clear();
Runner.RunScenario( Runner.RunScenario(
given => a_dotnet_project("args_not_enough_args1"), given => a_dotnet_project("args_not_enough_args1"),
when => the_developer_runs_cli_command("args arg1"), when => the_developer_runs_cli_command("args arg1"),
then => the_cli_should_error(ErrorCode.Argument, "Service name not specified") then => the_cli_should_error(ErrorCode.Argument, "Deployment target name not specified")
); );
} }
[Scenario] [Scenario]
public void ArgsUninitializedProject() public void ArgsGetUninitialized()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_dotnet_project("args_uninitialized_project"), given => a_dotnet_project("args_get_uninitialized"),
when => the_developer_runs_cli_command("args dummy-env a-service"), when => the_developer_runs_cli_command("args dummy-env my-service"),
then => the_cli_should_error(ErrorCode.Tooling, "Steeltoe Developer Tools has not been initialized")
);
}
[Scenario]
public void ArgsSetUninitialized()
{
Runner.RunScenario(
given => a_dotnet_project("args_set_uninitialized"),
when => the_developer_runs_cli_command("args dummy-env my-service arg1"),
then => the_cli_should_error(ErrorCode.Tooling, "Steeltoe Developer Tools has not been initialized")
);
}
[Scenario]
public void ArgsGetUnknownTarget()
{
Runner.RunScenario(
given => a_steeltoe_project("args_get_unknown_target"),
when => the_developer_runs_cli_command("add dummy-svc my-service"),
and => the_developer_runs_cli_command("args my-service no-such-target"),
then => the_cli_should_error(ErrorCode.Tooling, "Unknown target 'no-such-target'")
);
}
[Scenario]
public void ArgsSetUnknownTarget()
{
Runner.RunScenario(
given => a_steeltoe_project("args_set_unknown_target"),
when => the_developer_runs_cli_command("add dummy-svc my-service"),
and => the_developer_runs_cli_command("args my-service no-such-target arg1"),
then => the_cli_should_error(ErrorCode.Tooling, "Unknown target 'no-such-target'")
);
}
[Scenario]
public void ArgsGetUnknownService()
{
Runner.RunScenario(
given => a_steeltoe_project("args_get_unknown_service"),
when => the_developer_runs_cli_command("args no-such-svc dummy-target"),
then => the_cli_should_error(ErrorCode.Tooling, "Unknown service 'no-such-svc'")
);
}
[Scenario]
public void ArgsSetUnknownService()
{
Runner.RunScenario(
given => a_steeltoe_project("args_set_unknown_service"),
when => the_developer_runs_cli_command("args no-such-svc dummy-target arg1"),
then => the_cli_should_error(ErrorCode.Tooling, "Unknown service 'no-such-svc'")
);
}
[Scenario]
public void ArgsSet()
{
Runner.RunScenario(
given => a_steeltoe_project("args_set"),
when => the_developer_runs_cli_command("add dummy-svc my-service"),
and => the_developer_runs_cli_command("args my-service dummy-target arg1 arg2"),
then => the_cli_should_output("Service 'my-service' args for target 'dummy-target' set to 'arg1 arg2'")
);
}
[Scenario]
public void ArgsSetWithOpt()
{
Runner.RunScenario(
given => a_steeltoe_project("args_set_with_opt"),
when => the_developer_runs_cli_command("add dummy-svc my-service"),
and => the_developer_runs_cli_command("args my-service dummy-target -- arg1 -opt2"),
then => the_cli_should_output("Service 'my-service' args for target 'dummy-target' set to 'arg1 -opt2'")
);
}
[Scenario]
public void ArgsSetForce()
{
Runner.RunScenario(
given => a_steeltoe_project("args_set_force"),
when => the_developer_runs_cli_command("add dummy-svc my-service"),
and => the_developer_runs_cli_command("args my-service dummy-target arg1 arg2"),
and => the_developer_runs_cli_command("args my-service dummy-target arg1 arg2"),
then => the_cli_should_error(ErrorCode.Tooling, then => the_cli_should_error(ErrorCode.Tooling,
"Project has not been initialized for Steeltoe Developer Tools") "Service 'my-service' args for target 'dummy-target' already set to 'arg1 arg2'"),
when => the_developer_runs_cli_command("args my-service dummy-target arg3 --force"),
then => the_cli_should_output("Service 'my-service' args for target 'dummy-target' set to 'arg3'")
); );
} }
[Scenario] [Scenario]
public void ArgsUnknownEnvironment() public void ArgsGet()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_steeltoe_project("args_unknown_environment"), given => a_steeltoe_project("args_get"),
when => the_developer_runs_cli_command("args no-such-env a-service"), when => the_developer_runs_cli_command("add dummy-svc my-service"),
then => the_cli_should_error(ErrorCode.Tooling, "Unknown deployment environment 'no-such-env'") and => the_developer_runs_cli_command("args my-service dummy-target arg1 arg2"),
); and => the_developer_runs_cli_command("args my-service dummy-target"),
}
[Scenario]
public void ArgsNoSuchService()
{
Runner.RunScenario(
given => a_steeltoe_project("args_nonexistent_service"),
when => the_developer_runs_cli_command("args dummy-env no-such-svc"),
then => the_cli_should_error(ErrorCode.Tooling, "Service 'no-such-svc' not found")
);
Console.Clear();
Runner.RunScenario(
given => a_steeltoe_project("args_nonexistent_service"),
when => the_developer_runs_cli_command("args dummy-env no-such-svc arg1"),
then => the_cli_should_error(ErrorCode.Tooling, "Service 'no-such-svc' not found")
);
}
[Scenario]
public void ArgsSetDeploymentEnvironmentArgs()
{
Runner.RunScenario(
given => a_steeltoe_project("args_set_deployment_environment_args"),
when => the_developer_runs_cli_command("add dummy-svc a-service"),
and => the_developer_runs_cli_command("args dummy-env a-service arg1 arg2"),
then => the_cli_should_output(
"Set the 'dummy-env' deployment environment arguments for service 'a-service' to 'arg1 arg2'")
);
Runner.RunScenario(
given => a_steeltoe_project("args_set_deployment_environment_args_with_opt"),
when => the_developer_runs_cli_command("add dummy-svc a-service"),
and => the_developer_runs_cli_command("args dummy-env a-service -- arg1 -opt2"),
then => the_cli_should_output(
"Set the 'dummy-env' deployment environment arguments for service 'a-service' to 'arg1 -opt2'")
);
}
[Scenario]
public void ArgsSetDeploymentEnvironmentArgsForce()
{
Runner.RunScenario(
given => a_steeltoe_project("args_set_deployment_environment_args_force"),
when => the_developer_runs_cli_command("add dummy-svc a-service"),
and => the_developer_runs_cli_command("args dummy-env a-service arg1 arg2"),
and => the_developer_runs_cli_command("args dummy-env a-service arg1 arg2"),
then => the_cli_should_error(ErrorCode.Tooling,
"'dummy-env' deployment environment arguments for service 'a-service' already set."),
when => the_developer_runs_cli_command("args dummy-env a-service arg1 arg2 --force"),
then => the_cli_should_output(
"Set the 'dummy-env' deployment environment arguments for service 'a-service' to 'arg1 arg2'")
);
}
[Scenario]
public void ArgsGetDeploymentEnvironmentArgs()
{
Runner.RunScenario(
given => a_steeltoe_project("args_get_deployment_environment_args"),
when => the_developer_runs_cli_command("add dummy-svc a-service"),
and => the_developer_runs_cli_command("args dummy-env a-service arg1 arg2"),
and => the_developer_runs_cli_command("args dummy-env a-service"),
then => the_cli_should_output("arg1 arg2") then => the_cli_should_output("arg1 arg2")
); );
} }
[Scenario] [Scenario]
public void ArgsGetDeploymentEnvironmentNoArgs() public void ArgsGetNoArgs()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_steeltoe_project("args_get_deployment_environment_no_args"), given => a_steeltoe_project("args_get_no_args"),
when => the_developer_runs_cli_command("add dummy-svc a-service"), when => the_developer_runs_cli_command("add dummy-svc my-service"),
when => the_developer_runs_cli_command("args dummy-env a-service"), when => the_developer_runs_cli_command("args my-service dummy-target"),
then => the_cli_should_output_nothing() then => the_cli_should_output_nothing()
); );
} }

Просмотреть файл

@ -12,17 +12,14 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended; using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2; using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test namespace Steeltoe.Cli.Test
{ {
[Label("deploy")]
public class DeployFeature : FeatureSpecs public class DeployFeature : FeatureSpecs
{ {
[Scenario] [Scenario]
[Label("help")]
public void DeployHelp() public void DeployHelp()
{ {
Runner.RunScenario( Runner.RunScenario(
@ -30,7 +27,7 @@ namespace Steeltoe.Cli.Test
when => the_developer_runs_cli_command("deploy --help"), when => the_developer_runs_cli_command("deploy --help"),
then => the_cli_should_output(new[] then => the_cli_should_output(new[]
{ {
"Deploy enabled services to the targeted deployment environment.", "Deploy apps and services to the target",
$"Usage: {Program.Name} deploy [options]", $"Usage: {Program.Name} deploy [options]",
"Options:", "Options:",
"-?|-h|--help Show help information", "-?|-h|--help Show help information",
@ -49,44 +46,40 @@ namespace Steeltoe.Cli.Test
} }
[Scenario] [Scenario]
public void DeployUninitializedProject() public void DeployUninitialized()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_dotnet_project("deploy_uninitialized_project"), given => a_dotnet_project("deploy_uninitialized"),
when => the_developer_runs_cli_command("deploy"), when => the_developer_runs_cli_command("deploy"),
then => the_cli_should_error(ErrorCode.Tooling, then => the_cli_should_error(ErrorCode.Tooling, "Steeltoe Developer Tools has not been initialized")
"Project has not been initialized for Steeltoe Developer Tools")
); );
} }
[Scenario] [Scenario]
public void DeployServices() public void Deploy()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_steeltoe_project("deploy_services"), given => a_steeltoe_project("deploy_services"),
when => the_developer_runs_cli_command("add dummy-svc a-service"), when => the_developer_runs_cli_command("add app my-app"),
and => the_developer_runs_cli_command("add dummy-svc defunct-service"), and => the_developer_runs_cli_command("add dummy-svc my-service-a"),
and => the_developer_runs_cli_command("disable defunct-service"), and => the_developer_runs_cli_command("add dummy-svc my-service-b"),
and => the_developer_runs_cli_command("-S deploy"), and => the_developer_runs_cli_command("-S deploy"),
then => the_cli_should_output(new[] then => the_cli_should_output(new[]
{ {
"Deploying service 'a-service'", "Deploying service 'my-service-a'",
"Ignoring disabled service 'defunct-service'", "Deploying service 'my-service-b'",
}), "Waiting for service 'my-service-a' to come online",
when => the_developer_runs_cli_command("-S status"), "Waiting for service 'my-service-b' to come online",
then => the_cli_should_output(new[] "Deploying app 'my-app'",
{
"a-service starting",
"defunct-service disabled",
}) })
); );
} }
[Scenario] [Scenario]
public void DeployNoServices() public void DeployNothing()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_steeltoe_project("deploy_no_services"), given => a_steeltoe_project("deploy_nothing"),
when => the_developer_runs_cli_command("deploy"), when => the_developer_runs_cli_command("deploy"),
then => the_cli_should_output_nothing() then => the_cli_should_output_nothing()
); );
@ -100,7 +93,7 @@ namespace Steeltoe.Cli.Test
when => the_developer_runs_cli_command("init"), when => the_developer_runs_cli_command("init"),
and => the_developer_runs_cli_command("add dummy-svc a-server"), and => the_developer_runs_cli_command("add dummy-svc a-server"),
and => the_developer_runs_cli_command("deploy"), and => the_developer_runs_cli_command("deploy"),
then => the_cli_should_error(ErrorCode.Tooling, "Target deployment environment not set") then => the_cli_should_error(ErrorCode.Tooling, "Target not set")
); );
} }
} }

Просмотреть файл

@ -1,96 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test
{
[Label("disable")]
public class DisableFeature : FeatureSpecs
{
[Scenario]
[Label("help")]
public void DisableHelp()
{
Runner.RunScenario(
given => a_dotnet_project("disable_help"),
when => the_developer_runs_cli_command("disable --help"),
then => the_cli_should_output(new[]
{
"Disable a service.",
$"Usage: {Program.Name} disable [arguments] [options]",
"Arguments:",
"service Service name",
"Options:",
"-?|-h|--help Show help information",
})
);
}
[Scenario]
public void DisableNotEnoughArgs()
{
Runner.RunScenario(
given => a_dotnet_project("disable_not_enough_args"),
when => the_developer_runs_cli_command("disable"),
then => the_cli_should_error(ErrorCode.Argument, "Service name not specified")
);
}
[Scenario]
public void DisableTooManyArgs()
{
Runner.RunScenario(
given => a_dotnet_project("disable_too_many_args"),
when => the_developer_runs_cli_command("disable arg1 arg2"),
then => the_cli_should_fail_parse("Unrecognized command or argument 'arg2'")
);
}
[Scenario]
public void DisableUninitializedProject()
{
Runner.RunScenario(
given => a_dotnet_project("disable_uninitialized_project"),
when => the_developer_runs_cli_command("disable my-service"),
then => the_cli_should_error(ErrorCode.Tooling,
"Project has not been initialized for Steeltoe Developer Tools")
);
}
[Scenario]
public void DisableService()
{
Runner.RunScenario(
given => a_steeltoe_project("disable_service"),
when => the_developer_runs_cli_command("add dummy-svc my-service"),
and => the_developer_runs_cli_command("disable my-service"),
then => the_cli_should_output("Disabled service 'my-service'"),
and => the_configuration_service_should_not_be_enabled("my-service")
);
}
[Scenario]
public void DisableNonExistingService()
{
Runner.RunScenario(
given => a_steeltoe_project("disable_non_existing_service"),
when => the_developer_runs_cli_command("disable unknown-service"),
then => the_cli_should_error(ErrorCode.Tooling, "Service 'unknown-service' not found")
);
}
}
}

Просмотреть файл

@ -12,25 +12,22 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended; using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2; using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test namespace Steeltoe.Cli.Test
{ {
[Label("doctor")]
public class DoctorFeature : FeatureSpecs public class DoctorFeature : FeatureSpecs
{ {
[Scenario] [Scenario]
[Label("help")]
public void DoctorHelp() public void DoctorHelp()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_dotnet_project("dotnet_help"), given => a_dotnet_project("doctor_help"),
when => the_developer_runs_cli_command("doctor --help"), when => the_developer_runs_cli_command("doctor --help"),
then => the_cli_should_output(new[] then => the_cli_should_output(new[]
{ {
"Check for potential problems.", "Check for potential problems",
$"Usage: {Program.Name} doctor [options]", $"Usage: {Program.Name} doctor [options]",
"Options:", "Options:",
"-?|-h|--help Show help information", "-?|-h|--help Show help information",
@ -48,6 +45,27 @@ namespace Steeltoe.Cli.Test
); );
} }
[Scenario]
public void DoctorUninitialized()
{
Runner.RunScenario(
given => a_dotnet_project("doctor_uninitialized"),
when => the_developer_runs_cli_command("doctor"),
then => the_cli_output_should_include(
$"initialized ... !!! no (run '{Program.Name} init' to initialize)")
);
}
[Scenario]
public void DoctorInitialized()
{
Runner.RunScenario(
given => a_steeltoe_project("doctor_initialized"),
when => the_developer_runs_cli_command("doctor"),
then => the_cli_output_should_include("initialized ... yes")
);
}
[Scenario] [Scenario]
public void DoctorVersion() public void DoctorVersion()
{ {
@ -68,40 +86,25 @@ namespace Steeltoe.Cli.Test
); );
} }
[Scenario]
public void DoctorUninitializedProject()
{
Runner.RunScenario(
given => a_dotnet_project("doctor_uninitialized_project"),
when => the_developer_runs_cli_command("doctor"),
then => the_cli_output_should_include(
$"initialized ... !!! no (run '{Program.Name} init' to initialize)")
);
}
[Scenario]
public void DoctorInitializedProject()
{
Runner.RunScenario(
given => a_steeltoe_project("doctor_initialized_project"),
when => the_developer_runs_cli_command("doctor"),
then => the_cli_output_should_include("initialized ... yes")
);
}
[Scenario] [Scenario]
public void DoctorTarget() public void DoctorTarget()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_dotnet_project("doctor_target"), given => a_steeltoe_project("doctor_target"),
when => the_developer_runs_cli_command("doctor"),
then => the_cli_output_should_include("target ... dummy-target")
);
}
[Scenario]
public void DoctorNoTarget()
{
Runner.RunScenario(
given => a_dotnet_project("doctor_no_target"),
when => the_developer_runs_cli_command("init"), when => the_developer_runs_cli_command("init"),
and => the_developer_runs_cli_command("doctor"), and => the_developer_runs_cli_command("doctor"),
then => the_cli_output_should_include( then => the_cli_output_should_include(
$"target deployment environment ... !!! not set (run '{Program.Name} target <env>' to set)"), $"target ... !!! not set (run '{Program.Name} target <env>' to set)")
when => the_developer_runs_cli_command("target dummy-env"),
and => the_developer_runs_cli_command("doctor"),
then => the_cli_output_should_include("target deployment environment ... dummy-env"),
and => the_cli_output_should_include("dummy tool version ... 0.0.0")
); );
} }
} }

Просмотреть файл

@ -1,97 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test
{
[Label("enable")]
public class EnableFeature : FeatureSpecs
{
[Scenario]
[Label("help")]
public void EnableHelp()
{
Runner.RunScenario(
given => a_dotnet_project("enable_help"),
when => the_developer_runs_cli_command("enable --help"),
then => the_cli_should_output(new[]
{
"Enable a service.",
$"Usage: {Program.Name} enable [arguments] [options]",
"Arguments:",
"service Service name",
"Options:",
"-?|-h|--help Show help information",
})
);
}
[Scenario]
public void EnableNotEnoughArgs()
{
Runner.RunScenario(
given => a_dotnet_project("enable_not_enough_args"),
when => the_developer_runs_cli_command("enable"),
then => the_cli_should_error(ErrorCode.Argument, "Service name not specified")
);
}
[Scenario]
public void EnableTooManyArgs()
{
Runner.RunScenario(
given => a_dotnet_project("enable_too_many_args"),
when => the_developer_runs_cli_command("enable arg1 arg2"),
then => the_cli_should_fail_parse("Unrecognized command or argument 'arg2'")
);
}
[Scenario]
public void EnableUninitializedProject()
{
Runner.RunScenario(
given => a_dotnet_project("enable_uninitialized_project"),
when => the_developer_runs_cli_command("enable my-service"),
then => the_cli_should_error(ErrorCode.Tooling,
"Project has not been initialized for Steeltoe Developer Tools")
);
}
[Scenario]
public void EnableService()
{
Runner.RunScenario(
given => a_steeltoe_project("enable_service"),
when => the_developer_runs_cli_command("add dummy-svc my-service"),
and => the_developer_runs_cli_command("disable my-service"),
and => the_developer_runs_cli_command("enable my-service"),
then => the_cli_should_output("Enabled service 'my-service'"),
and => the_configuration_service_should_be_enabled("my-service")
);
}
[Scenario]
public void EnableNonExistingService()
{
Runner.RunScenario(
given => a_steeltoe_project("enable_non_existing_service"),
when => the_developer_runs_cli_command("enable unknown-service"),
then => the_cli_should_error(ErrorCode.Tooling, "Service 'unknown-service' not found")
);
}
}
}

Просмотреть файл

@ -90,8 +90,8 @@ namespace scratch
{ {
a_dotnet_project(name); a_dotnet_project(name);
Logger.LogInformation($"enabling steeltoe developer tools"); Logger.LogInformation($"enabling steeltoe developer tools");
var cfgFile = new ToolingConfigurationFile(ProjectDirectory); var cfgFile = new ConfigurationFile(ProjectDirectory);
cfgFile.ToolingConfiguration.EnvironmentName = "dummy-env"; cfgFile.Configuration.Target = "dummy-target";
cfgFile.Store(); cfgFile.Store();
} }
@ -212,33 +212,34 @@ namespace scratch
protected void the_configuration_should_target(string env) protected void the_configuration_should_target(string env)
{ {
Logger.LogInformation($"checking the target config '{env}' exists"); Logger.LogInformation($"checking the target config '{env}' exists");
new ToolingConfigurationFile(ProjectDirectory).ToolingConfiguration.EnvironmentName.ShouldBe(env); new ConfigurationFile(ProjectDirectory).Configuration.Target.ShouldBe(env);
} }
protected void the_configuration_should_contain_service(string service) protected void the_configuration_should_contain_app(string app)
{ {
Logger.LogInformation($"checking the service '{service}' exists"); Logger.LogInformation($"checking the app '{app}' exists");
new ToolingConfigurationFile(ProjectDirectory).ToolingConfiguration.Services.Keys.ShouldContain(service); var cfg = new ConfigurationFile(ProjectDirectory);
cfg.Configuration.Apps.Keys.ShouldContain(app);
}
protected void the_configuration_should_not_contain_app(string app)
{
Logger.LogInformation($"checking the app '{app}' does not exist");
new ConfigurationFile(ProjectDirectory).Configuration.Apps.Keys.ShouldNotContain(app);
}
protected void the_configuration_should_contain_service(string service, string serviceType)
{
Logger.LogInformation($"checking the service {serviceType} '{service}' exists");
var cfg = new ConfigurationFile(ProjectDirectory);
cfg.Configuration.Services.Keys.ShouldContain(service);
cfg.Configuration.Services[service].ServiceTypeName.ShouldBe(serviceType);
} }
protected void the_configuration_should_not_contain_service(string service) protected void the_configuration_should_not_contain_service(string service)
{ {
Logger.LogInformation($"checking the service '{service}' does not exist"); Logger.LogInformation($"checking the service '{service}' does not exist");
new ToolingConfigurationFile(ProjectDirectory).ToolingConfiguration.Services.Keys.ShouldNotContain(service); new ConfigurationFile(ProjectDirectory).Configuration.Services.Keys.ShouldNotContain(service);
}
protected void the_configuration_service_should_be_enabled(string service)
{
Logger.LogInformation($"checking the service '{service}' is enabled");
new ToolingConfigurationFile(ProjectDirectory).ToolingConfiguration.Services[service].Enabled
.ShouldBeTrue();
}
protected void the_configuration_service_should_not_be_enabled(string service)
{
Logger.LogInformation($"checking the service '{service}' is not enabled");
new ToolingConfigurationFile(ProjectDirectory).ToolingConfiguration.Services[service].Enabled
.ShouldBeFalse();
} }
private static string NormalizeString(string s) private static string NormalizeString(string s)

Просмотреть файл

@ -12,17 +12,14 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended; using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2; using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test namespace Steeltoe.Cli.Test
{ {
[Label("init")]
public class InitFeature : FeatureSpecs public class InitFeature : FeatureSpecs
{ {
[Scenario] [Scenario]
[Label("help")]
public void InitHelp() public void InitHelp()
{ {
Runner.RunScenario( Runner.RunScenario(
@ -30,7 +27,7 @@ namespace Steeltoe.Cli.Test
when => the_developer_runs_cli_command("init --help"), when => the_developer_runs_cli_command("init --help"),
then => the_cli_should_output(new[] then => the_cli_should_output(new[]
{ {
"Initialize a project for Steeltoe Developer Tools.", "Initialize Steeltoe Developer Tools",
$"Usage: {Program.Name} init [options]", $"Usage: {Program.Name} init [options]",
"Options:", "Options:",
"-F|--force Initialize the project even if already initialized", "-F|--force Initialize the project even if already initialized",
@ -50,24 +47,24 @@ namespace Steeltoe.Cli.Test
} }
[Scenario] [Scenario]
public void InitProject() public void Init()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_dotnet_project("init_project"), given => a_dotnet_project("init"),
when => the_developer_runs_cli_command("init"), when => the_developer_runs_cli_command("init"),
then => the_cli_should_output("Project initialized for Steeltoe Developer Tools") then => the_cli_should_output("Initialized Steeltoe Developer Tools")
); );
} }
[Scenario] [Scenario]
public void InitProjectForce() public void InitForce()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_steeltoe_project("init_project_already_initialized"), given => a_steeltoe_project("init_force"),
when => the_developer_runs_cli_command("init"), when => the_developer_runs_cli_command("init"),
then => the_cli_should_error(ErrorCode.Tooling, "Project already initialized"), then => the_cli_should_error(ErrorCode.Tooling, "Steeltoe Developer Tools already initialized"),
when => the_developer_runs_cli_command("init --force"), when => the_developer_runs_cli_command("init --force"),
then => the_cli_should_output("Project initialized for Steeltoe Developer Tools") then => the_cli_should_output("Initialized Steeltoe Developer Tools")
); );
} }
} }

Просмотреть файл

@ -12,17 +12,14 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended; using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2; using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test namespace Steeltoe.Cli.Test
{ {
[Label("list")]
public class ListFeature : FeatureSpecs public class ListFeature : FeatureSpecs
{ {
[Scenario] [Scenario]
[Label("help")]
public void ListHelp() public void ListHelp()
{ {
Runner.RunScenario( Runner.RunScenario(
@ -30,15 +27,11 @@ namespace Steeltoe.Cli.Test
when => the_developer_runs_cli_command("list --help"), when => the_developer_runs_cli_command("list --help"),
then => the_cli_should_output(new[] then => the_cli_should_output(new[]
{ {
"List services, service types, or deployment environments.", "List apps and services",
$"Usage: {Program.Name} list [options]", $"Usage: {Program.Name} list [options]",
"Options:", "Options:",
"-e|--environments List deployment environments",
"-s|--services List services",
"-t|--service-types List service types",
"-v|--verbose Verbose", "-v|--verbose Verbose",
"-?|-h|--help Show help information", "-?|-h|--help Show help information",
"If run with no options, list services.",
}) })
); );
} }
@ -54,27 +47,16 @@ namespace Steeltoe.Cli.Test
} }
[Scenario] [Scenario]
public void ListMutallyExclusiveOptions() public void ListUninitialized()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_steeltoe_project("list_mutually_exclusive_options"), given => a_dotnet_project("list_uninitialized"),
when => the_developer_runs_cli_command("list -e -t"),
then => the_cli_should_error(ErrorCode.Argument,
"Specify at most one of: -e|--environments, -s|--services, -t|--service-types")
);
}
[Scenario]
public void ListUninitializedProject()
{
Runner.RunScenario(
given => a_dotnet_project("list_uninitialized_project"),
when => the_developer_runs_cli_command("list"), when => the_developer_runs_cli_command("list"),
then => the_cli_should_error(ErrorCode.Tooling, then => the_cli_should_error(ErrorCode.Tooling, "Steeltoe Developer Tools has not been initialized")
"Project has not been initialized for Steeltoe Developer Tools")
); );
} }
/*
[Scenario] [Scenario]
public void ListEnvironments() public void ListEnvironments()
{ {
@ -85,11 +67,13 @@ namespace Steeltoe.Cli.Test
{ {
"cloud-foundry", "cloud-foundry",
"docker", "docker",
"dummy-env", "dummy-target",
}) })
); );
} }
*/
/*
[Scenario] [Scenario]
public void ListEnvironmentsVerbose() public void ListEnvironmentsVerbose()
{ {
@ -100,11 +84,13 @@ namespace Steeltoe.Cli.Test
{ {
"cloud-foundry Cloud Foundry", "cloud-foundry Cloud Foundry",
"docker Docker", "docker Docker",
"dummy-env A Dummy Environment", "dummy-target A Dummy Target",
}) })
); );
} }
*/
/*
[Scenario] [Scenario]
public void ListServiceTypes() public void ListServiceTypes()
{ {
@ -123,7 +109,9 @@ namespace Steeltoe.Cli.Test
}) })
); );
} }
*/
/*
[Scenario] [Scenario]
public void ListServiceTypesVerbose() public void ListServiceTypesVerbose()
{ {
@ -142,21 +130,22 @@ namespace Steeltoe.Cli.Test
}) })
); );
} }
*/
[Scenario] [Scenario]
public void ListServices() public void ListServices()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_steeltoe_project("list_services"), given => a_steeltoe_project("list_services"),
when => the_developer_runs_cli_command("add dummy-svc c-service"), when => the_developer_runs_cli_command("add dummy-svc my-service-c"),
and => the_developer_runs_cli_command("add dummy-svc b-service"), and => the_developer_runs_cli_command("add dummy-svc my-service-b"),
and => the_developer_runs_cli_command("add dummy-svc a-service"), and => the_developer_runs_cli_command("add dummy-svc my-service-a"),
and => the_developer_runs_cli_command("list"), and => the_developer_runs_cli_command("list"),
then => the_cli_should_output(new[] then => the_cli_should_output(new[]
{ {
"a-service", "my-service-a",
"b-service", "my-service-b",
"c-service", "my-service-c",
}) })
); );
} }
@ -166,15 +155,15 @@ namespace Steeltoe.Cli.Test
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_steeltoe_project("list_services_verbose"), given => a_steeltoe_project("list_services_verbose"),
and => the_developer_runs_cli_command("add dummy-svc b-service"), when => the_developer_runs_cli_command("add dummy-svc my-service-c"),
and => the_developer_runs_cli_command("add dummy-svc c-service"), and => the_developer_runs_cli_command("add dummy-svc my-service-b"),
when => the_developer_runs_cli_command("add dummy-svc a-service"), and => the_developer_runs_cli_command("add dummy-svc my-service-a"),
and => the_developer_runs_cli_command("list -s -v"), and => the_developer_runs_cli_command("-S list -v"),
then => the_cli_should_output(new[] then => the_cli_should_output(new[]
{ {
"a-service 0 dummy-svc", "my-service-a 0 dummy-svc",
"b-service 0 dummy-svc", "my-service-b 0 dummy-svc",
"c-service 0 dummy-svc", "my-service-c 0 dummy-svc",
}) })
); );
} }

Просмотреть файл

@ -12,14 +12,12 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended; using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2; using LightBDD.XUnit2;
using Steeltoe.Tooling; using Steeltoe.Tooling;
namespace Steeltoe.Cli.Test namespace Steeltoe.Cli.Test
{ {
[Label("program")]
public class ProgramFeature : FeatureSpecs public class ProgramFeature : FeatureSpecs
{ {
// [Scenario] // [Scenario]
@ -33,7 +31,6 @@ namespace Steeltoe.Cli.Test
// } // }
[Scenario] [Scenario]
[Label("help")]
public void ProgramHelp() public void ProgramHelp()
{ {
Runner.RunScenario( Runner.RunScenario(
@ -43,33 +40,30 @@ namespace Steeltoe.Cli.Test
{ {
"1.0.0", "1.0.0",
"Steeltoe Developer Tools", "Steeltoe Developer Tools",
$"Usage: {Program.Name} [options] [command]", $"Usage: st [options] [command]",
"Options:", "Options:",
"-V|--version Show version information", "-V|--version Show version information",
$"-C|--config-file Configure tooling using the specified file instead of {ToolingConfigurationFile.DefaultFileName}", $"-C|--config-file Configure tooling using the specified file instead of steeltoe.yml",
"-D|--debug Enable debug output", "-D|--debug Enable debug output",
"-S|--no-parallel Disable parallel execution", "-S|--no-parallel Disable parallel execution",
"-?|-h|--help Show help information", "-?|-h|--help Show help information",
"Commands:", "Commands:",
"add Add a service.", "add Add an app or service",
"args Set or get the deployment environment arguments for a service.", "args Set or get the deployment arguments for an app or service",
"deploy Deploy enabled services to the targeted deployment environment.", "deploy Deploy apps and services to the target",
"disable Disable a service.", "doctor Check for potential problems",
"doctor Check for potential problems.", "init Initialize Steeltoe Developer Tools",
"enable Enable a service.", "list List apps and services",
"init Initialize a project for Steeltoe Developer Tools.", "remove Remove an app or service",
"list List services, service types, or deployment environments.", "status Show app and service statuses",
"remove Remove a service.", "target Set or get the deployment target",
"status Show service statuses.", "undeploy Undeploy apps and services from the target",
"target Set or get the targeted deployment environment.", $"Run 'st [command] --help' for more information about a command.",
"undeploy Undeploy enabled services from the targeted deployment environment.",
$"Run '{Program.Name} [command] --help' for more information about a command.",
}) })
); );
} }
[Scenario] [Scenario]
[Label("version")]
public void ProgramVersion() public void ProgramVersion()
{ {
Runner.RunScenario( Runner.RunScenario(
@ -80,7 +74,6 @@ namespace Steeltoe.Cli.Test
} }
[Scenario] [Scenario]
[Label("version")]
public void ProgramDebug() public void ProgramDebug()
{ {
Runner.RunScenario( Runner.RunScenario(
@ -91,11 +84,10 @@ namespace Steeltoe.Cli.Test
} }
[Scenario] [Scenario]
[Label("version")]
public void ProgramNoParallel() public void ProgramNoParallel()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_dotnet_project("program_parallel"), given => a_dotnet_project("program_noparallel"),
when => the_developer_runs_cli_command("--no-parallel --version"), when => the_developer_runs_cli_command("--no-parallel --version"),
then => setting_should_be(Settings.ParallelExecutionEnabled, false) then => setting_should_be(Settings.ParallelExecutionEnabled, false)
); );

Просмотреть файл

@ -12,17 +12,14 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended; using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2; using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test namespace Steeltoe.Cli.Test
{ {
[Label("remove")]
public class RemoveFeature : FeatureSpecs public class RemoveFeature : FeatureSpecs
{ {
[Scenario] [Scenario]
[Label("help")]
public void RemoveHelp() public void RemoveHelp()
{ {
Runner.RunScenario( Runner.RunScenario(
@ -30,10 +27,10 @@ namespace Steeltoe.Cli.Test
when => the_developer_runs_cli_command("remove --help"), when => the_developer_runs_cli_command("remove --help"),
then => the_cli_should_output(new[] then => the_cli_should_output(new[]
{ {
"Remove a service.", "Remove an app or service",
$"Usage: {Program.Name} remove [arguments] [options]", $"Usage: {Program.Name} remove [arguments] [options]",
"Arguments:", "Arguments:",
"service Service name", "name App or service name",
"Options:", "Options:",
"-?|-h|--help Show help information", "-?|-h|--help Show help information",
}) })
@ -46,7 +43,7 @@ namespace Steeltoe.Cli.Test
Runner.RunScenario( Runner.RunScenario(
given => a_dotnet_project("remove_not_enough_args"), given => a_dotnet_project("remove_not_enough_args"),
when => the_developer_runs_cli_command("remove"), when => the_developer_runs_cli_command("remove"),
then => the_cli_should_error(ErrorCode.Argument, "Service name not specified") then => the_cli_should_error(ErrorCode.Argument, "App or service name not specified")
); );
} }
@ -61,13 +58,24 @@ namespace Steeltoe.Cli.Test
} }
[Scenario] [Scenario]
public void RemoveUninitializedProject() public void RemoveUninitialized()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_dotnet_project("remove_uninitialized_project"), given => a_dotnet_project("remove_uninitialized"),
when => the_developer_runs_cli_command("remove my-service"), when => the_developer_runs_cli_command("remove my-service"),
then => the_cli_should_error(ErrorCode.Tooling, then => the_cli_should_error(ErrorCode.Tooling, "Steeltoe Developer Tools has not been initialized")
"Project has not been initialized for Steeltoe Developer Tools") );
}
[Scenario]
public void RemoveApp()
{
Runner.RunScenario(
given => a_steeltoe_project("remove_app"),
when => the_developer_runs_cli_command("add app my-app"),
and => the_developer_runs_cli_command("remove my-app"),
then => the_cli_should_output("Removed app 'my-app'"),
and => the_configuration_should_not_contain_app("my-app")
); );
} }
@ -78,18 +86,18 @@ namespace Steeltoe.Cli.Test
given => a_steeltoe_project("remove_service"), given => a_steeltoe_project("remove_service"),
when => the_developer_runs_cli_command("add dummy-svc my-service"), when => the_developer_runs_cli_command("add dummy-svc my-service"),
and => the_developer_runs_cli_command("remove my-service"), and => the_developer_runs_cli_command("remove my-service"),
then => the_cli_should_output("Removed service 'my-service'"), then => the_cli_should_output("Removed dummy-svc service 'my-service'"),
and => the_configuration_should_not_contain_service("my-service") and => the_configuration_should_not_contain_service("my-service")
); );
} }
[Scenario] [Scenario]
public void RemoveNonExistingService() public void RemoveUnknownItem()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_steeltoe_project("remove_non_existing_service"), given => a_steeltoe_project("remove_unknown_item"),
when => the_developer_runs_cli_command("remove unknown-service"), when => the_developer_runs_cli_command("remove no-such-item"),
then => the_cli_should_error(ErrorCode.Tooling, "Service 'unknown-service' not found") then => the_cli_should_error(ErrorCode.Tooling, "Unknown app or service 'no-such-item'")
); );
} }
} }

Просмотреть файл

@ -12,17 +12,14 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended; using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2; using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test namespace Steeltoe.Cli.Test
{ {
[Label("status")]
public class StatusFeature : FeatureSpecs public class StatusFeature : FeatureSpecs
{ {
[Scenario] [Scenario]
[Label("help")]
public void StatusHelp() public void StatusHelp()
{ {
Runner.RunScenario( Runner.RunScenario(
@ -30,7 +27,7 @@ namespace Steeltoe.Cli.Test
when => the_developer_runs_cli_command("status --help"), when => the_developer_runs_cli_command("status --help"),
then => the_cli_should_output(new[] then => the_cli_should_output(new[]
{ {
"Show service statuses.", "Show app and service statuses",
$"Usage: {Program.Name} status [options]", $"Usage: {Program.Name} status [options]",
"Options:", "Options:",
"-?|-h|--help Show help information", "-?|-h|--help Show help information",
@ -49,13 +46,12 @@ namespace Steeltoe.Cli.Test
} }
[Scenario] [Scenario]
public void StatusUninitializedProject() public void StatusUninitialized()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_dotnet_project("status_uninitialized_project"), given => a_dotnet_project("status_uninitialized"),
when => the_developer_runs_cli_command("status"), when => the_developer_runs_cli_command("status"),
then => the_cli_should_error(ErrorCode.Tooling, then => the_cli_should_error(ErrorCode.Tooling, "Steeltoe Developer Tools has not been initialized")
"Project has not been initialized for Steeltoe Developer Tools")
); );
} }
@ -64,28 +60,13 @@ namespace Steeltoe.Cli.Test
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_steeltoe_project("status_services"), given => a_steeltoe_project("status_services"),
when => the_developer_runs_cli_command("add dummy-svc a-service"), when => the_developer_runs_cli_command("add dummy-svc my-service-a"),
when => the_developer_runs_cli_command("add dummy-svc defunct-service"), and => the_developer_runs_cli_command("add dummy-svc my-service-b"),
and => the_developer_runs_cli_command("disable defunct-service"), and => the_developer_runs_cli_command("status"),
and => the_developer_runs_cli_command("-S status"),
then => the_cli_should_output(new[] then => the_cli_should_output(new[]
{ {
"a-service offline", "my-service-a offline",
"defunct-service disabled", "my-service-b offline",
}),
when => the_developer_runs_cli_command("deploy"),
and => the_developer_runs_cli_command("-S status"),
then => the_cli_should_output(new[]
{
"a-service starting",
"defunct-service disabled",
}),
when => the_developer_runs_cli_command("undeploy"),
and => the_developer_runs_cli_command("-S status"),
then => the_cli_should_output(new[]
{
"a-service stopping",
"defunct-service disabled",
}) })
); );
} }
@ -108,7 +89,7 @@ namespace Steeltoe.Cli.Test
when => the_developer_runs_cli_command("init"), when => the_developer_runs_cli_command("init"),
and => the_developer_runs_cli_command("add dummy-svc a-server"), and => the_developer_runs_cli_command("add dummy-svc a-server"),
and => the_developer_runs_cli_command("status"), and => the_developer_runs_cli_command("status"),
then => the_cli_should_error(ErrorCode.Tooling, "Target deployment environment not set") then => the_cli_should_error(ErrorCode.Tooling, "Target not set")
); );
} }
} }

Просмотреть файл

@ -70,7 +70,7 @@ namespace Steeltoe.Cli.Test
public void RunNoSuchCommand() public void RunNoSuchCommand()
{ {
Runner.RunScenario( Runner.RunScenario(
when => the_command_is_run("NoSuchCommand"), when => the_command_is_run("no-such-command"),
then => the_command_should_raise_exception<ShellException>() then => the_command_should_raise_exception<ShellException>()
); );
} }

Просмотреть файл

@ -12,17 +12,14 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended; using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2; using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test namespace Steeltoe.Cli.Test
{ {
[Label("target")]
public class TargetFeature : FeatureSpecs public class TargetFeature : FeatureSpecs
{ {
[Scenario] [Scenario]
[Label("help")]
public void TargetHelp() public void TargetHelp()
{ {
Runner.RunScenario( Runner.RunScenario(
@ -30,14 +27,14 @@ namespace Steeltoe.Cli.Test
when => the_developer_runs_cli_command("target --help"), when => the_developer_runs_cli_command("target --help"),
then => the_cli_should_output(new[] then => the_cli_should_output(new[]
{ {
"Set or get the targeted deployment environment.", "Set or get the deployment target",
$"Usage: {Program.Name} target [arguments] [options]", $"Usage: {Program.Name} target [arguments] [options]",
"Arguments:", "Arguments:",
"environment Deployment environment", "target Deployment target name",
"Options:", "Options:",
"-F|--force Target the deployment environment even if checks fail", "-F|--force Set the deployment target even if checks fail",
"-?|-h|--help Show help information", "-?|-h|--help Show help information",
"If run with no args, show the currently targeted deployment environment.", "If run with no args, show the current deployment target.",
}) })
); );
} }
@ -53,39 +50,38 @@ namespace Steeltoe.Cli.Test
} }
[Scenario] [Scenario]
public void TargetUninitializedProject() public void TargetUninitialized()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_dotnet_project("target_uninitialized_project"), given => a_dotnet_project("target_uninitialized"),
when => the_developer_runs_cli_command("target"), when => the_developer_runs_cli_command("target"),
then => the_cli_should_error(ErrorCode.Tooling, then => the_cli_should_error(ErrorCode.Tooling, "Steeltoe Developer Tools has not been initialized")
"Project has not been initialized for Steeltoe Developer Tools")
); );
} }
[Scenario] [Scenario]
public void TargetEnvironment() public void TargetSet()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_dotnet_project("target_environment"), given => a_dotnet_project("target_set"),
when => the_developer_runs_cli_command("init"), when => the_developer_runs_cli_command("init"),
and => the_developer_runs_cli_command("target dummy-env"), and => the_developer_runs_cli_command("target dummy-target"),
then => the_cli_should_output(new[] then => the_cli_should_output(new[]
{ {
"dummy tool version ... 0.0.0", "dummy tool version ... 0.0.0",
"Target deployment environment set to 'dummy-env'.", "Target set to 'dummy-target'",
}), }),
and => the_configuration_should_target("dummy-env") and => the_configuration_should_target("dummy-target")
); );
} }
[Scenario] [Scenario]
public void TargetUnknownEnvironment() public void TargetSetUnknown()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_steeltoe_project("target_unknown_environment"), given => a_steeltoe_project("target_set_unknown"),
when => the_developer_runs_cli_command("target no-such-environment"), when => the_developer_runs_cli_command("target no-such-target"),
then => the_cli_should_error(ErrorCode.Tooling, "Unknown deployment environment 'no-such-environment'") then => the_cli_should_error(ErrorCode.Tooling, "Unknown target 'no-such-target'")
); );
} }
@ -95,7 +91,7 @@ namespace Steeltoe.Cli.Test
Runner.RunScenario( Runner.RunScenario(
given => a_steeltoe_project("show_target_environment"), given => a_steeltoe_project("show_target_environment"),
when => the_developer_runs_cli_command("target"), when => the_developer_runs_cli_command("target"),
then => the_cli_should_output("Target deployment environment set to 'dummy-env'.") then => the_cli_should_output("dummy-target")
); );
} }
} }

Просмотреть файл

@ -12,17 +12,14 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
using LightBDD.Framework;
using LightBDD.Framework.Scenarios.Extended; using LightBDD.Framework.Scenarios.Extended;
using LightBDD.XUnit2; using LightBDD.XUnit2;
namespace Steeltoe.Cli.Test namespace Steeltoe.Cli.Test
{ {
[Label("undeploy")]
public class UndeployFeature : FeatureSpecs public class UndeployFeature : FeatureSpecs
{ {
[Scenario] [Scenario]
[Label("help")]
public void UndeployHelp() public void UndeployHelp()
{ {
Runner.RunScenario( Runner.RunScenario(
@ -30,7 +27,7 @@ namespace Steeltoe.Cli.Test
when => the_developer_runs_cli_command("undeploy --help"), when => the_developer_runs_cli_command("undeploy --help"),
then => the_cli_should_output(new[] then => the_cli_should_output(new[]
{ {
"Undeploy enabled services from the targeted deployment environment.", "Undeploy apps and services from the target",
$"Usage: {Program.Name} undeploy [options]", $"Usage: {Program.Name} undeploy [options]",
"Options:", "Options:",
"-?|-h|--help Show help information", "-?|-h|--help Show help information",
@ -49,35 +46,40 @@ namespace Steeltoe.Cli.Test
} }
[Scenario] [Scenario]
public void UndeployService() public void UndeployUninitialized()
{
Runner.RunScenario(
given => a_dotnet_project("undeploy_uninitialized"),
when => the_developer_runs_cli_command("undeploy"),
then => the_cli_should_error(ErrorCode.Tooling, "Steeltoe Developer Tools has not been initialized")
);
}
[Scenario]
public void Undeploy()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_steeltoe_project("undeploy_services"), given => a_steeltoe_project("undeploy_services"),
when => the_developer_runs_cli_command("add dummy-svc a-service"), when => the_developer_runs_cli_command("add app my-app"),
and => the_developer_runs_cli_command("add dummy-svc defunct-service"), and => the_developer_runs_cli_command("add dummy-svc my-service-a"),
and => the_developer_runs_cli_command("disable defunct-service"), and => the_developer_runs_cli_command("add dummy-svc my-service-b"),
and => the_developer_runs_cli_command("deploy"), and => the_developer_runs_cli_command("deploy"),
when => the_developer_runs_cli_command("status"), and => the_developer_runs_cli_command("status"),
and => the_developer_runs_cli_command("-S undeploy"), and => the_developer_runs_cli_command("undeploy"),
then => the_cli_should_output(new[] then => the_cli_should_output(new[]
{ {
"Undeploying service 'a-service'", "Undeploying app 'my-app'",
"Ignoring disabled service 'defunct-service'", "Undeploying service 'my-service-a'",
}), "Undeploying service 'my-service-b'",
when => the_developer_runs_cli_command("-S status"),
then => the_cli_should_output(new[]
{
"a-service stopping",
"defunct-service disabled",
}) })
); );
} }
[Scenario] [Scenario]
public void DeployNoServices() public void DeployNothing()
{ {
Runner.RunScenario( Runner.RunScenario(
given => a_steeltoe_project("undeploy_no_services"), given => a_steeltoe_project("undeploy_nothing"),
when => the_developer_runs_cli_command("deploy"), when => the_developer_runs_cli_command("deploy"),
then => the_cli_should_output_nothing() then => the_cli_should_output_nothing()
); );
@ -91,7 +93,7 @@ namespace Steeltoe.Cli.Test
when => the_developer_runs_cli_command("init"), when => the_developer_runs_cli_command("init"),
and => the_developer_runs_cli_command("add dummy-svc a-server"), and => the_developer_runs_cli_command("add dummy-svc a-server"),
and => the_developer_runs_cli_command("undeploy"), and => the_developer_runs_cli_command("undeploy"),
then => the_cli_should_error(ErrorCode.Tooling, "Target deployment environment not set") then => the_cli_should_error(ErrorCode.Tooling, "Target not set")
); );
} }
} }

Просмотреть файл

@ -0,0 +1,164 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.IO;
using Shouldly;
using Steeltoe.Tooling.CloudFoundry;
using Xunit;
namespace Steeltoe.Tooling.Test.CloudFoundry
{
public class CloudFoundryBackendTest : ToolingTest
{
private readonly CloudFoundryBackend _backend;
public CloudFoundryBackendTest()
{
Context.Configuration.Target = "cloud-foundry";
_backend = Context.Target.GetBackend(Context) as CloudFoundryBackend;
}
[Fact]
public void TestDeployApp()
{
Context.Configuration.AddService("my-service", "dummy-svc");
Context.Configuration.AddApp("my-app");
_backend.DeployApp("my-app");
Shell.Commands.Count.ShouldBe(2);
Shell.Commands[0].ShouldBe("dotnet publish -f netcoreapp2.1 -r win10-x64");
Shell.Commands[1].ShouldBe("cf push -f manifest-steeltoe.yml -p bin/Debug/netcoreapp2.1/win10-x64/publish");
var manifestFile = new CloudFoundryManifestFile(Path.Combine(Context.ProjectDirectory, "manifest-steeltoe.yml"));
manifestFile.Exists().ShouldBeTrue();
manifestFile.CloudFoundryManifest.Applications.Count.ShouldBe(1);
var app = manifestFile.CloudFoundryManifest.Applications[0];
app.Name.ShouldBe("my-app");
app.Command.ShouldBe($"cmd /c .\\{Path.GetFileName(Context.ProjectDirectory)}");
app.BuildPacks.Count.ShouldBe(1);
app.BuildPacks[0].ShouldBe("binary_buildpack");
app.Stack.ShouldBe("windows2016");
app.Memory.ShouldBe("512M");
app.Environment["ASPNETCORE_ENVIRONMENT"].ShouldBe("development");
app.ServiceNames.Count.ShouldBe(1);
app.ServiceNames[0].ShouldBe("my-service");
}
[Fact]
public void TestDeployService()
{
Context.Configuration.AddService("my-service", "dummy-svc");
_backend.DeployService("my-service");
Shell.LastCommand.ShouldBe("cf create-service dummy-server dummy-plan my-service");
}
[Fact]
public void TestDeployConfigServer()
{
Context.Configuration.AddService("my-service", "config-server");
_backend.DeployService("my-service");
Shell.LastCommand.ShouldBe("cf create-service p-config-server standard my-service");
}
[Fact]
public void TestDeployEurekaServer()
{
Context.Configuration.AddService("my-service", "eureka-server");
_backend.DeployService("my-service");
Shell.LastCommand.ShouldBe("cf create-service p-service-registry standard my-service");
}
[Fact]
public void TestDeployHystrixDashboard()
{
Context.Configuration.AddService("my-service", "hystrix-dashboard");
_backend.DeployService("my-service");
Shell.LastCommand.ShouldBe("cf create-service p-circuit-breaker-dashboard standard my-service");
}
[Fact]
public void TestDeployRedis()
{
Context.Configuration.AddService("my-service", "redis");
_backend.DeployService("my-service");
Shell.LastCommand.ShouldBe("cf create-service p-redis shared-vm my-service");
}
[Fact]
public void TestUndeployApp()
{
Context.Configuration.AddApp("my-app");
_backend.UndeployApp("my-app");
Shell.LastCommand.ShouldBe("cf delete my-app -f");
}
[Fact]
public void TestUndeployService()
{
Context.Configuration.AddService("my-service", "dummy-svc");
_backend.UndeployService("my-service");
Shell.LastCommand.ShouldBe("cf delete-service my-service -f");
}
[Fact]
public void TestCheckApp()
{
Context.Configuration.AddApp("my-app");
_backend.GetAppStatus("my-app");
Shell.LastCommand.ShouldBe("cf app my-app");
}
[Fact]
public void TestCheckService()
{
Context.Configuration.AddService("my-service", "dummy-svc");
_backend.GetServiceStatus("my-service");
Shell.LastCommand.ShouldBe("cf service my-service");
}
[Fact]
public void TestServiceStarting()
{
Context.Configuration.AddService("my-service", "dummy-svc");
Shell.AddResponse("status: create in progress");
var status = _backend.GetServiceStatus("my-service");
status.ShouldBe(Lifecycle.Status.Starting);
}
[Fact]
public void TestAppOnline()
{
Context.Configuration.AddApp("my-app");
Shell.AddResponse("#0 running 2018-11-02T16:32:37Z 16.9% 129.2M of 512M 124.8M of 1G");
var status = _backend.GetAppStatus("my-app");
status.ShouldBe(Lifecycle.Status.Online);
}
[Fact]
public void TestServiceOnline()
{
Context.Configuration.AddService("my-service", "dummy-svc");
Shell.AddResponse("status: create succeeded");
var status = _backend.GetServiceStatus("my-service");
status.ShouldBe(Lifecycle.Status.Online);
}
[Fact]
public void TestServiceOffline()
{
Context.Configuration.AddService("my-service", "dummy-svc");
Shell.AddResponse("Service instance my-service not found", 1);
var status = _backend.GetServiceStatus("my-service");
status.ShouldBe(Lifecycle.Status.Offline);
}
}
}

Просмотреть файл

@ -0,0 +1,70 @@
using System.Collections.Generic;
using Shouldly;
using System.IO;
using Steeltoe.Tooling.CloudFoundry;
using Xunit;
namespace Steeltoe.Tooling.Test.CloudFoundry
{
public class CloudFoundryManifestFileTest : ToolingTest
{
private readonly string _configFile;
public CloudFoundryManifestFileTest()
{
_configFile = Path.Join(Context.ProjectDirectory, "config-file");
}
[Fact]
public void TestLoadFromFile()
{
File.WriteAllText(_configFile, SampleConfig);
var cfgFile = new CloudFoundryManifestFile(_configFile);
cfgFile.CloudFoundryManifest.Applications.Count.ShouldBe(1);
var app = cfgFile.CloudFoundryManifest.Applications[0];
app.Name.ShouldBe("myapp");
app.Command.ShouldBe("my command");
app.BuildPacks.Count.ShouldBe(1);
app.BuildPacks[0].ShouldBe("my_build_pack");
app.Stack.ShouldBe("my stack");
app.Memory.ShouldBe("my mem");
app.Environment.Count.ShouldBe(1);
app.Environment["myenv"].ShouldBe("my var");
app.ServiceNames.Count.ShouldBe(2);
app.ServiceNames.ShouldContain("my-service");
app.ServiceNames.ShouldContain("my-other-service");
}
[Fact]
public void TestStoreToFile()
{
var cfgFile = new CloudFoundryManifestFile(_configFile);
cfgFile.CloudFoundryManifest.Applications.Add(new CloudFoundryManifest.Application
{
Name = "myapp",
Command = "my command",
BuildPacks = new List<string> {"my_build_pack"},
Stack = "my stack",
Memory = "my mem",
Environment = new Dictionary<string, string> {{"myenv", "my var"}},
ServiceNames = new List<string> {"my-service", "my-other-service"},
});
cfgFile.Store();
File.ReadAllText(_configFile).ShouldBe(SampleConfig);
}
private const string SampleConfig = @"applications:
- name: myapp
command: my command
buildpacks:
- my_build_pack
stack: my stack
memory: my mem
env:
myenv: my var
services:
- my-service
- my-other-service
";
}
}

Просмотреть файл

@ -1,99 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using Shouldly;
using Steeltoe.Tooling.CloudFoundry;
using Xunit;
namespace Steeltoe.Tooling.Test.CloudFoundry
{
public class CloudFoundryServiceManagerTest : ToolingTest
{
private readonly IServiceBackend _backend;
public CloudFoundryServiceManagerTest()
{
Context.ToolingConfiguration.EnvironmentName = "cloud-foundry";
_backend = Context.Environment.GetServiceBackend(Context);
_backend.ShouldBeOfType(typeof(CloudFoundryServiceBackend));
}
[Fact]
public void TestDeployCircuitBreakerDashboard()
{
_backend.DeployService("my-service", "circuit-breaker-dashboard");
Shell.LastCommand.ShouldBe("cf create-service p-circuit-breaker-dashboard standard my-service");
}
[Fact]
public void TestDeployConfigServer()
{
_backend.DeployService("my-service", "config-server");
Shell.LastCommand.ShouldBe("cf create-service p-config-server standard my-service");
}
[Fact]
public void TestDeployRedisServer()
{
_backend.DeployService("my-service", "redis-server");
Shell.LastCommand.ShouldBe("cf create-service p-redis shared-vm my-service");
}
[Fact]
public void TestDeployServiceRegistry()
{
_backend.DeployService("my-service", "service-registry");
Shell.LastCommand.ShouldBe("cf create-service p-service-registry standard my-service");
}
[Fact]
public void TestStopService()
{
_backend.UndeployService("my-service");
Shell.LastCommand.ShouldBe("cf delete-service my-service -f");
}
[Fact]
public void TestCheckService()
{
_backend.GetServiceLifecleState("my-service");
Shell.LastCommand.ShouldBe("cf service my-service");
}
[Fact]
public void TestServiceStarting()
{
Shell.AddResponse("status: create in progress");
var state = _backend.GetServiceLifecleState("my-service");
state.ShouldBe(ServiceLifecycle.State.Starting);
}
[Fact]
public void TestServiceOnline()
{
Shell.AddResponse("status: create succeeded");
var state = _backend.GetServiceLifecleState("my-service");
state.ShouldBe(ServiceLifecycle.State.Online);
}
[Fact]
public void TestServiceOffline()
{
Shell.AddResponse("Service instance my-service not found", 1);
var state = _backend.GetServiceLifecleState("my-service");
state.ShouldBe(ServiceLifecycle.State.Offline);
}
}
}

Просмотреть файл

@ -18,39 +18,38 @@ using Xunit;
namespace Steeltoe.Tooling.Test.CloudFoundry namespace Steeltoe.Tooling.Test.CloudFoundry
{ {
public class CloudFoundryEnvironmentTest : ToolingTest public class CloudFoundryTargetTest : ToolingTest
{ {
private readonly Environment _env; private readonly CloudFoundryTarget _target;
public CloudFoundryEnvironmentTest() public CloudFoundryTargetTest()
{ {
_env = Registry.GetEnvironment("cloud-foundry"); _target = Registry.GetTarget("cloud-foundry") as CloudFoundryTarget;
_env.ShouldBeOfType<CloudFoundryEnvironment>();
} }
[Fact] [Fact]
public void TestGetName() public void TestGetName()
{ {
_env.Name.ShouldBe("cloud-foundry"); _target.Name.ShouldBe("cloud-foundry");
} }
[Fact] [Fact]
public void TestGetDescription() public void TestGetDescription()
{ {
_env.Description.ShouldBe("Cloud Foundry"); _target.Description.ShouldBe("Cloud Foundry");
} }
[Fact] [Fact]
public void TestGetServiceManager() public void TestGetBackend()
{ {
_env.GetServiceBackend(Context).ShouldBeOfType<CloudFoundryServiceBackend>(); _target.GetBackend(Context).ShouldBeOfType<CloudFoundryBackend>();
} }
[Fact] [Fact]
public void TestIsHealthy() public void TestIsHealthy()
{ {
Shell.AddResponse("cf version SOME VERSION"); Shell.AddResponse("cf version SOME VERSION");
var healthy = _env.IsHealthy(Context); var healthy = _target.IsHealthy(Context);
healthy.ShouldBeTrue(); healthy.ShouldBeTrue();
var expected = new[] var expected = new[]
{ {
@ -71,7 +70,7 @@ namespace Steeltoe.Tooling.Test.CloudFoundry
{ {
Shell.AddResponse(""); Shell.AddResponse("");
Shell.AddResponse("", 1); Shell.AddResponse("", 1);
var healthy = _env.IsHealthy(Context); var healthy = _target.IsHealthy(Context);
healthy.ShouldBeFalse(); healthy.ShouldBeFalse();
Console.ToString().ShouldContain("logged into Cloud Foundry ... !!! no"); Console.ToString().ShouldContain("logged into Cloud Foundry ... !!! no");
} }

Просмотреть файл

@ -0,0 +1,78 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.IO;
using Shouldly;
using Xunit;
namespace Steeltoe.Tooling.Test
{
public class ConfigurationFileTest : ToolingTest
{
[Fact]
public void TestLoadFromFile()
{
var file = Path.Combine(Context.ProjectDirectory, "config-file");
File.WriteAllText(file, SampleConfig);
var cfgFile = new ConfigurationFile(file);
cfgFile.Configuration.Target.ShouldBe("dummy-target");
cfgFile.Configuration.GetServices().ShouldContain("my-service");
cfgFile.Configuration.GetServiceInfo("my-service").ServiceType.ShouldBe("dummy-svc");
}
[Fact]
public void TestLoadFromDirectory()
{
var defaultFile = Path.Combine(Context.ProjectDirectory, ConfigurationFile.DefaultFileName);
File.WriteAllText(defaultFile, SampleConfig);
var cfgFile = new ConfigurationFile(Context.ProjectDirectory);
cfgFile.Configuration.Target.ShouldBe("dummy-target");
cfgFile.Configuration.GetServices().ShouldContain("my-service");
cfgFile.Configuration.GetServiceInfo("my-service").ServiceType.ShouldBe("dummy-svc");
}
[Fact]
public void TestStoreToFile()
{
var file = Path.Combine(Context.ProjectDirectory, "config-file");
var cfgFile = new ConfigurationFile(file);
cfgFile.Configuration.Target = "dummy-target";
cfgFile.Configuration.AddApp("my-app");
cfgFile.Configuration.AddService("my-service", "dummy-svc");
cfgFile.Store();
File.ReadAllText(file).ShouldBe(SampleConfig);
}
[Fact]
public void TestStoreToDirectory()
{
var cfgFile = new ConfigurationFile(Context.ProjectDirectory);
cfgFile.Configuration.Target = "dummy-target";
cfgFile.Configuration.AddApp("my-app");
cfgFile.Configuration.AddService("my-service", "dummy-svc");
cfgFile.Store();
var defaultFile = Path.Combine(Context.ProjectDirectory, ConfigurationFile.DefaultFileName);
File.ReadAllText(defaultFile).ShouldBe(SampleConfig);
}
private const string SampleConfig = @"target: dummy-target
apps:
my-app: {}
services:
my-service:
type: dummy-svc
args: {}
";
}
}

Просмотреть файл

@ -0,0 +1,218 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using Shouldly;
using Xunit;
namespace Steeltoe.Tooling.Test
{
public class ConfigurationTest : ToolingTest
{
private readonly Configuration _cfg;
private readonly MyListener _listener;
public ConfigurationTest()
{
_cfg = new Configuration();
_listener = new MyListener();
_cfg.AddListener(_listener);
}
[Fact]
public void TestAddService()
{
_cfg.AddService("my-service", "dummy-svc");
_cfg.Services.Count.ShouldBe(1);
_cfg.Services.Keys.ShouldContain("my-service");
_cfg.Services["my-service"].ServiceTypeName.ShouldBe("dummy-svc");
}
[Fact]
public void TestListenAddService()
{
_cfg.AddService("my-service", "dummy-svc");
_listener.ReceivedEvent.ShouldBeTrue();
}
[Fact]
public void TestAddAlreadyExistingService()
{
_cfg.AddService("preexisting-service", "dummy-svc");
var e = Assert.Throws<ToolingException>(
() => _cfg.AddService("preexisting-service", "dummy-svc")
);
e.Message.ShouldBe("Service 'preexisting-service' already exists");
}
[Fact]
public void TestAddServiceUnknownServiceType()
{
var e = Assert.Throws<NotFoundException>(
() => _cfg.AddService("my-service", "no-such-service-type")
);
e.Name.ShouldBe("no-such-service-type");
e.Description.ShouldBe("type");
}
[Fact]
public void TestRemoveService()
{
_cfg.AddService("my-service", "dummy-svc");
_cfg.RemoveService("my-service");
_cfg.Services.Count.ShouldBe(0);
}
[Fact]
public void TestListenRemoveService()
{
_cfg.AddService("my-service", "dummy-svc");
_listener.ReceivedEvent = false;
_cfg.RemoveService("my-service");
_listener.ReceivedEvent.ShouldBeTrue();
}
[Fact]
public void TestRemoveUnknownService()
{
var e = Assert.Throws<NotFoundException>(
() => _cfg.RemoveService("no-such-service")
);
e.Name.ShouldBe("no-such-service");
}
[Fact]
public void TestGetServiceInfo()
{
_cfg.AddService("my-service", "dummy-svc");
var info = _cfg.GetServiceInfo("my-service");
info.Service.ShouldBe("my-service");
info.ServiceType.ShouldBe("dummy-svc");
}
[Fact]
public void TestGetServiceInfoUnknownService()
{
var e = Assert.Throws<NotFoundException>(
() => _cfg.GetServiceInfo("no-such-service")
);
e.Name.ShouldBe("no-such-service");
}
[Fact]
public void TestGetServiceNames()
{
_cfg.GetServices().Count.ShouldBe(0);
_cfg.AddService("my-service", "dummy-svc");
_cfg.AddService("another-service", "dummy-svc");
var names = _cfg.GetServices();
names.Remove("my-service").ShouldBeTrue();
names.Remove("another-service").ShouldBeTrue();
names.Count.ShouldBe(0);
}
[Fact]
public void TestSetServiceDeploymentArgs()
{
_cfg.AddService("my-service", "dummy-svc");
_cfg.SetServiceDeploymentArgs("my-service", "dummy-target", "arg1 arg2");
_cfg.Services["my-service"].Args["dummy-target"].ShouldBe("arg1 arg2");
}
[Fact]
public void TestListenSetServiceDeploymentArgs()
{
_cfg.AddService("my-service", "dummy-svc");
_listener.ReceivedEvent = false;
_cfg.SetServiceDeploymentArgs("my-service", "dummy-target", "arg1 arg2");
_listener.ReceivedEvent.ShouldBeTrue();
}
[Fact]
public void TestSetServiceDeploymentArgsUnknownService()
{
var e = Assert.Throws<NotFoundException>(
() => _cfg.SetServiceDeploymentArgs("no-such-service", "dummy-target", "arg1 arg2")
);
e.Name.ShouldBe("no-such-service");
e.Description.ShouldBe("service");
}
[Fact]
public void TestSetServiceDeploymentArgsUnknownEnvironment()
{
var e = Assert.Throws<NotFoundException>(
() => _cfg.SetServiceDeploymentArgs("my-service", "no-such-target", "arg1 arg2")
);
e.Name.ShouldBe("no-such-target");
e.Description.ShouldBe("target");
}
[Fact]
public void TestGetServiceDeploymentArgs()
{
_cfg.AddService("my-service", "dummy-svc");
_cfg.SetServiceDeploymentArgs("my-service", "dummy-target", "arg1 arg2");
_cfg.GetServiceDeploymentArgs("my-service", "dummy-target").ShouldBe("arg1 arg2");
}
[Fact]
public void TestGetServiceDeploymentNoArgs()
{
_cfg.AddService("my-service", "dummy-svc");
_cfg.GetServiceDeploymentArgs("my-service", "dummy-target").ShouldBe(null);
}
[Fact]
public void TestGetServiceDeploymentArgsUnknownService()
{
var e = Assert.Throws<NotFoundException>(
() => _cfg.GetServiceDeploymentArgs("no-such-service", "dummy-target")
);
e.Name.ShouldBe("no-such-service");
e.Description.ShouldBe("service");
}
[Fact]
public void TestGetServiceDeploymentArgsUnknownTarget()
{
_cfg.AddService("my-service", "dummy-svc");
var e = Assert.Throws<NotFoundException>(
() => _cfg.GetServiceDeploymentArgs("my-service", "no-such-target")
);
e.Name.ShouldBe("no-such-target");
e.Description.ShouldBe("target");
}
[Fact]
public void TestChangeEvent()
{
var cfg = new Configuration();
var listener = new MyListener();
cfg.AddListener(listener);
cfg.NotifyChanged();
listener.ReceivedEvent.ShouldBeTrue();
}
internal class MyListener : IConfigurationListener
{
internal bool ReceivedEvent { get; set; }
public void ConfigurationChangeEvent()
{
ReceivedEvent = true;
}
}
}
}

Просмотреть файл

@ -22,29 +22,12 @@ namespace Steeltoe.Tooling.Test
[Fact] [Fact]
public void TestContext() public void TestContext()
{ {
var cfg = new ToolingConfiguration(); var cfg = new Configuration();
cfg.EnvironmentName = "dummy-env"; cfg.Target = "dummy-target";
var ctx = new Context(null, cfg, Console, Shell); var ctx = new Context(null, cfg, Console, Shell);
ctx.ToolingConfiguration.ShouldBe(cfg); ctx.Configuration.ShouldBe(cfg);
ctx.Shell.ShouldBe(Shell); ctx.Shell.ShouldBe(Shell);
ctx.Environment.Name.ShouldBe("dummy-env"); ctx.Target.Name.ShouldBe("dummy-target");
ctx.ServiceManager.ShouldNotBeNull();
}
[Fact]
public void TestContextEnvironmentNotSet()
{
var cfg = new ToolingConfiguration();
var ctx = new Context(null, cfg, Console, Shell);
try
{
var unused = ctx.Environment;
Assert.True(false, "expected ToolingException");
}
catch (ToolingException e)
{
e.Message.ShouldBe("Target deployment environment not set");
}
} }
} }
} }

Просмотреть файл

@ -18,38 +18,50 @@ using Xunit;
namespace Steeltoe.Tooling.Test.Docker namespace Steeltoe.Tooling.Test.Docker
{ {
public class DockerServiceManagerTest : ToolingTest public class DockerBackendTest : ToolingTest
{ {
private readonly DockerServiceBackend _backend; private readonly DockerBackend _backend;
public DockerServiceManagerTest() public DockerBackendTest()
{ {
Context.ToolingConfiguration.EnvironmentName = "docker"; Context.Configuration.Target = "docker";
_backend = Context.Environment.GetServiceBackend(Context) as DockerServiceBackend; _backend = Context.Target.GetBackend(Context) as DockerBackend;
_backend.ShouldBeOfType(typeof(DockerServiceBackend));
} }
[Fact] [Fact]
public void TestDeployService() public void TestDeployService()
{ {
_backend.DeployService("a-service", "dummy-svc"); Context.Configuration.AddService("my-service", "dummy-svc");
_backend.DeployService("my-service");
Shell.LastCommand.ShouldBe( Shell.LastCommand.ShouldBe(
"docker run --name a-service --publish 0:0 --detach --rm dummy-server:0.1"); "docker run --name my-service --publish 0:0 --detach --rm dummy-server:0.1");
}
[Fact]
public void TestDeployServiceWithArgs()
{
Context.Configuration.AddService("my-service", "dummy-svc");
Context.Configuration.SetServiceDeploymentArgs("my-service", "docker", "arg1 arg2");
_backend.DeployService("my-service", "dummy-svc");
Shell.LastCommand.ShouldBe(
"docker run --name my-service --publish 0:0 --detach --rm arg1 arg2 dummy-server:0.1");
} }
[Fact] [Fact]
public void TestDeployServiceForOs() public void TestDeployServiceForOs()
{ {
Context.Configuration.AddService("my-service", "dummy-svc");
Shell.AddResponse("OSType: dummyos"); Shell.AddResponse("OSType: dummyos");
_backend.DeployService("a-service", "dummy-svc"); _backend.DeployService("my-service");
Shell.LastCommand.ShouldBe( Shell.LastCommand.ShouldBe(
"docker run --name a-service --publish 0:0 --detach --rm dummy-server:for_dummyos"); "docker run --name my-service --publish 0:0 --detach --rm dummy-server:for_dummyos");
} }
[Fact] [Fact]
public void TestDeployConfigServer() public void TestDeployConfigServer()
{ {
_backend.DeployService("my-service", "config-server"); Context.Configuration.AddService("my-service", "config-server");
_backend.DeployService("my-service");
Shell.LastCommand.ShouldBe( Shell.LastCommand.ShouldBe(
"docker run --name my-service --publish 8888:8888 --detach --rm steeltoeoss/config-server:2.0.1"); "docker run --name my-service --publish 8888:8888 --detach --rm steeltoeoss/config-server:2.0.1");
} }
@ -57,7 +69,8 @@ namespace Steeltoe.Tooling.Test.Docker
[Fact] [Fact]
public void TestDeployEurekaServer() public void TestDeployEurekaServer()
{ {
_backend.DeployService("my-service", "eureka-server"); Context.Configuration.AddService("my-service", "eureka-server");
_backend.DeployService("my-service");
Shell.LastCommand.ShouldBe( Shell.LastCommand.ShouldBe(
"docker run --name my-service --publish 8761:8761 --detach --rm steeltoeoss/eureka-server:2.0.1"); "docker run --name my-service --publish 8761:8761 --detach --rm steeltoeoss/eureka-server:2.0.1");
} }
@ -65,18 +78,20 @@ namespace Steeltoe.Tooling.Test.Docker
[Fact] [Fact]
public void TestDeployHystrixDashboard() public void TestDeployHystrixDashboard()
{ {
_backend.DeployService("my-service", "hystrix-dashboard"); Context.Configuration.AddService("my-service", "hystrix-dashboard");
_backend.DeployService("my-service");
Shell.LastCommand.ShouldBe( Shell.LastCommand.ShouldBe(
"docker run --name my-service --publish 7979:7979 --detach --rm steeltoeoss/hystrix-dashboard:1.4.5"); "docker run --name my-service --publish 7979:7979 --detach --rm steeltoeoss/hystrix-dashboard:1.4.5");
} }
[Fact] [Fact]
public void TestDeployMssql() public void TestDeployMicrosoftSqlServer()
{ {
_backend.DeployService("my-service", "mssql", "linux"); Context.Configuration.AddService("my-service", "mssql");
_backend.DeployService("my-service", "linux");
Shell.LastCommand.ShouldBe( Shell.LastCommand.ShouldBe(
"docker run --name my-service --publish 1433:1433 --detach --rm steeltoeoss/mssql:2017-CU11-linux"); "docker run --name my-service --publish 1433:1433 --detach --rm steeltoeoss/mssql:2017-CU11-linux");
_backend.DeployService("my-service", "mssql", "windows"); _backend.DeployService("my-service", "windows");
Shell.LastCommand.ShouldBe( Shell.LastCommand.ShouldBe(
"docker run --name my-service --publish 1433:1433 --detach --rm steeltoeoss/mssql:2017-CU1-windows"); "docker run --name my-service --publish 1433:1433 --detach --rm steeltoeoss/mssql:2017-CU1-windows");
} }
@ -84,10 +99,11 @@ namespace Steeltoe.Tooling.Test.Docker
[Fact] [Fact]
public void TestDeployRedis() public void TestDeployRedis()
{ {
_backend.DeployService("my-service", "redis", "linux"); Context.Configuration.AddService("my-service", "redis");
_backend.DeployService("my-service", "linux");
Shell.LastCommand.ShouldBe( Shell.LastCommand.ShouldBe(
"docker run --name my-service --publish 6379:6379 --detach --rm steeltoeoss/redis:4.0.11-linux"); "docker run --name my-service --publish 6379:6379 --detach --rm steeltoeoss/redis:4.0.11-linux");
_backend.DeployService("my-service", "redis", "windows"); _backend.DeployService("my-service", "windows");
Shell.LastCommand.ShouldBe( Shell.LastCommand.ShouldBe(
"docker run --name my-service --publish 6379:6379 --detach --rm steeltoeoss/redis:3.0.504-windows"); "docker run --name my-service --publish 6379:6379 --detach --rm steeltoeoss/redis:3.0.504-windows");
} }
@ -95,40 +111,31 @@ namespace Steeltoe.Tooling.Test.Docker
[Fact] [Fact]
public void TestDeployZipkin() public void TestDeployZipkin()
{ {
_backend.DeployService("my-service", "zipkin"); Context.Configuration.AddService("my-service", "zipkin");
_backend.DeployService("my-service");
Shell.LastCommand.ShouldBe( Shell.LastCommand.ShouldBe(
"docker run --name my-service --publish 9411:9411 --detach --rm steeltoeoss/zipkin:2.11.6"); "docker run --name my-service --publish 9411:9411 --detach --rm steeltoeoss/zipkin:2.11.6");
} }
[Fact]
public void TestDeployServiceWithArgs()
{
Context.ServiceManager.AddService("a-service", "dummy-svc");
Context.ServiceManager.SetServiceDeploymentArgs("docker", "a-service", "arg1 arg2");
_backend.DeployService("a-service", "dummy-svc");
Shell.LastCommand.ShouldBe(
"docker run --name a-service --publish 0:0 --detach --rm arg1 arg2 dummy-server:0.1");
}
[Fact] [Fact]
public void TestUndeployService() public void TestUndeployService()
{ {
_backend.UndeployService("a-service"); _backend.UndeployService("my-service");
Shell.LastCommand.ShouldBe("docker stop a-service"); Shell.LastCommand.ShouldBe("docker stop my-service");
} }
[Fact] [Fact]
public void TestGetServiceLifecycleStateCommand() public void TestGetServiceLifecycleStateCommand()
{ {
_backend.GetServiceLifecleState("a-service"); _backend.GetServiceStatus("my-service");
Shell.LastCommand.ShouldBe("docker ps --no-trunc --filter name=^/a-service$"); Shell.LastCommand.ShouldBe("docker ps --no-trunc --filter name=^/my-service$");
} }
[Fact] [Fact]
public void TestGetServiceLifecycleStateOffline() public void TestGetServiceLifecycleStateOffline()
{ {
var state = _backend.GetServiceLifecleState("a-service"); var state = _backend.GetServiceStatus("my-service");
state.ShouldBe(ServiceLifecycle.State.Offline); state.ShouldBe(Lifecycle.Status.Offline);
} }
[Fact] [Fact]
@ -136,10 +143,10 @@ namespace Steeltoe.Tooling.Test.Docker
{ {
Shell.AddResponse( Shell.AddResponse(
@"CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES @"CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0000000000000000000000000000000000000000000000000000000000000000 dummy-server:0.1 java -Djava.security.egd=file:/dev/./urandom -jar config-server.jar 37 seconds ago Up 36 seconds 0.0.0.0:0000->0000/tcp a-service 0000000000000000000000000000000000000000000000000000000000000000 dummy-server:0.1 java -Djava.security.egd=file:/dev/./urandom -jar config-server.jar 37 seconds ago Up 36 seconds 0.0.0.0:0000->0000/tcp my-service
"); ");
var state = _backend.GetServiceLifecleState("a-service"); var state = _backend.GetServiceStatus("my-service");
state.ShouldBe(ServiceLifecycle.State.Starting); state.ShouldBe(Lifecycle.Status.Starting);
} }
[Fact] [Fact]
@ -147,11 +154,11 @@ namespace Steeltoe.Tooling.Test.Docker
{ {
Shell.AddResponse( Shell.AddResponse(
@"CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES @"CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0000000000000000000000000000000000000000000000000000000000000000 dummy-server:for_dummyos java -Djava.security.egd=file:/dev/./urandom -jar config-server.jar 37 seconds ago Up 36 seconds 0.0.0.0:0000->0000/tcp a-service 0000000000000000000000000000000000000000000000000000000000000000 dummy-server:for_dummyos java -Djava.security.egd=file:/dev/./urandom -jar config-server.jar 37 seconds ago Up 36 seconds 0.0.0.0:0000->0000/tcp my-service
"); ");
Shell.AddResponse("OSType: dummyos"); Shell.AddResponse("OSType: dummyos");
var state = _backend.GetServiceLifecleState("a-service"); var state = _backend.GetServiceStatus("my-service");
state.ShouldBe(ServiceLifecycle.State.Starting); state.ShouldBe(Lifecycle.Status.Starting);
} }
} }
} }

Просмотреть файл

@ -18,14 +18,13 @@ using Xunit;
namespace Steeltoe.Tooling.Test.Docker namespace Steeltoe.Tooling.Test.Docker
{ {
public class DockerEnvironmentTest : ToolingTest public class DockerTargetTest : ToolingTest
{ {
private readonly Environment _env; private readonly DockerTarget _env;
public DockerEnvironmentTest() public DockerTargetTest()
{ {
_env = Registry.GetEnvironment("docker"); _env = Registry.GetTarget("docker") as DockerTarget;
_env.ShouldBeOfType<DockerEnvironment>();
} }
[Fact] [Fact]
@ -41,9 +40,9 @@ namespace Steeltoe.Tooling.Test.Docker
} }
[Fact] [Fact]
public void TestGetServiceManager() public void TestGetBackend()
{ {
_env.GetServiceBackend(Context).ShouldBeOfType<DockerServiceBackend>(); _env.GetBackend(Context).ShouldBeOfType<DockerBackend>();
} }
[Fact] [Fact]

Просмотреть файл

@ -21,17 +21,17 @@ using Xunit;
namespace Steeltoe.Tooling.Test.Dummy namespace Steeltoe.Tooling.Test.Dummy
{ {
public class DummyServiceBackendTest : ToolingTest public class DummyBackendTest : ToolingTest
{ {
private readonly string _dbFile; private readonly string _dbFile;
private readonly DummyServiceBackend _backend; private readonly DummyBackend _backend;
public DummyServiceBackendTest() public DummyBackendTest()
{ {
Directory.CreateDirectory(Context.ProjectDirectory); Directory.CreateDirectory(Context.ProjectDirectory);
_dbFile = Path.Combine(Context.ProjectDirectory, "dummy.db"); _dbFile = Path.Combine(Context.ProjectDirectory, "dummy.db");
_backend = new DummyServiceBackend(_dbFile); _backend = new DummyBackend(_dbFile);
} }
[Fact] [Fact]
@ -40,17 +40,17 @@ namespace Steeltoe.Tooling.Test.Dummy
File.Exists(_dbFile).ShouldBeTrue(); File.Exists(_dbFile).ShouldBeTrue();
// start state -> offline // start state -> offline
_backend.GetServiceLifecleState("a-service").ShouldBe(ServiceLifecycle.State.Offline); _backend.GetServiceStatus("my-service").ShouldBe(Lifecycle.Status.Offline);
// offline -> deploy -> starting -> online // offline -> deploy -> starting -> online
_backend.DeployService("a-service", "dummy-svc"); _backend.DeployService("my-service");
_backend.GetServiceLifecleState("a-service").ShouldBe(ServiceLifecycle.State.Starting); _backend.GetServiceStatus("my-service").ShouldBe(Lifecycle.Status.Starting);
_backend.GetServiceLifecleState("a-service").ShouldBe(ServiceLifecycle.State.Online); _backend.GetServiceStatus("my-service").ShouldBe(Lifecycle.Status.Online);
// online -> undeploy -> stopping -> offline // online -> undeploy -> stopping -> offline
_backend.UndeployService("a-service"); _backend.UndeployService("my-service");
_backend.GetServiceLifecleState("a-service").ShouldBe(ServiceLifecycle.State.Stopping); _backend.GetServiceStatus("my-service").ShouldBe(Lifecycle.Status.Stopping);
_backend.GetServiceLifecleState("a-service").ShouldBe(ServiceLifecycle.State.Offline); _backend.GetServiceStatus("my-service").ShouldBe(Lifecycle.Status.Offline);
} }
} }
} }

Просмотреть файл

@ -18,26 +18,25 @@ using Xunit;
namespace Steeltoe.Tooling.Test.Dummy namespace Steeltoe.Tooling.Test.Dummy
{ {
public class DummyEnvironmentTest : ToolingTest public class DummyTargetTest : ToolingTest
{ {
private readonly Environment _env; private readonly DummyTarget _target;
public DummyEnvironmentTest() public DummyTargetTest()
{ {
_env = Registry.GetEnvironment("dummy-env"); _target = Registry.GetTarget("dummy-target") as DummyTarget;
_env.ShouldBeOfType<DummyEnvironment>();
} }
[Fact] [Fact]
public void TestGetName() public void TestGetName()
{ {
_env.Name.ShouldBe("dummy-env"); _target.Name.ShouldBe("dummy-target");
} }
[Fact] [Fact]
public void TestGetDescription() public void TestGetDescription()
{ {
_env.Description.ShouldBe("A Dummy Environment"); _target.Description.ShouldBe("A Dummy Target");
} }
} }
} }

Просмотреть файл

@ -0,0 +1,77 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using Shouldly;
using Steeltoe.Tooling.Executor;
using Xunit;
namespace Steeltoe.Tooling.Test.Executor
{
public class AddExecutorTest : ToolingTest
{
[Fact]
public void TestAddApplication()
{
new AddExecutor("my-app", "app").Execute(Context);
Console.ToString().Trim().ShouldBe("Added app 'my-app'");
Context.Configuration.GetApps().Count.ShouldBe(1);
Context.Configuration.GetApps()[0].ShouldBe("my-app");
var appInfo = Context.Configuration.GetAppInfo("my-app");
appInfo.App.ShouldBe("my-app");
}
[Fact]
public void TestAddExistingApplication()
{
Context.Configuration.AddApp("existing-app");
var e = Assert.Throws<ToolingException>(
() => new AddExecutor("existing-app", "app").Execute(Context)
);
e.Message.ShouldBe("App 'existing-app' already exists");
}
[Fact]
public void TestAddService()
{
new AddExecutor("my-service", "dummy-svc").Execute(Context);
Console.ToString().Trim().ShouldBe("Added dummy-svc service 'my-service'");
Context.Configuration.GetServices().Count.ShouldBe(1);
var svcName = Context.Configuration.GetServices()[0];
svcName.ShouldBe("my-service");
var svcInfo = Context.Configuration.GetServiceInfo(svcName);
svcInfo.Service.ShouldBe("my-service");
svcInfo.ServiceType.ShouldBe("dummy-svc");
}
[Fact]
public void TestAddExistingService()
{
Context.Configuration.AddService("existing-service", "dummy-svc");
var e = Assert.Throws<ToolingException>(
() => new AddExecutor("existing-service", "dummy-svc").Execute(Context)
);
e.Message.ShouldBe("Service 'existing-service' already exists");
}
[Fact]
public void TestAddUnknownServiceType()
{
var e = Assert.Throws<NotFoundException>(
() => new AddExecutor("unknown-service", "unknown-service-type").Execute(Context)
);
e.Name.ShouldBe("unknown-service-type");
e.Description.ShouldBe("type");
}
}
}

Просмотреть файл

@ -1,57 +0,0 @@
// Copyright 2018 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using Shouldly;
using Steeltoe.Tooling.Executor;
using Xunit;
namespace Steeltoe.Tooling.Test.Executor
{
public class AddServiceExecutorTest : ToolingTest
{
[Fact]
public void TestAddService()
{
new AddServiceExecutor("a-service", "dummy-svc").Execute(Context);
Console.ToString().Trim().ShouldBe("Added dummy-svc service 'a-service'");
Context.ServiceManager.GetServiceNames().Count.ShouldBe(1);
var svcName = Context.ServiceManager.GetServiceNames()[0];
svcName.ShouldBe("a-service");
var svc = Context.ServiceManager.GetService(svcName);
svc.Type.ShouldBe("dummy-svc");
Context.ServiceManager.GetServiceState("a-service").ShouldBe(ServiceLifecycle.State.Offline);
}
[Fact]
public void TestAddPreExistingService()
{
Context.ServiceManager.AddService("pre-existing-service", "dummy-svc");
var executor = new AddServiceExecutor("pre-existing-service", "dummy-svc");
var e = Assert.Throws<ToolingException>(
() => executor.Execute(Context)
);
e.Message.ShouldBe("Service 'pre-existing-service' already exists");
}
[Fact]
public void TestAddUnknownServiceType()
{
var executor = new AddServiceExecutor("unknown-service", "unknown-service-type");
var e = Assert.Throws<ToolingException>(
() => executor.Execute(Context)
);
e.Message.ShouldBe("Unknown service type 'unknown-service-type'");
}
}
}

Просмотреть файл

@ -0,0 +1,38 @@
using Xunit;
namespace Steeltoe.Tooling.Test.Executor
{
public class DeployApplicationsExecutorTest : ToolingTest
{
[Fact]
public void TestDeployApplications()
{
// Context.ApplicationManager.AddApplication("an-app");
// Context.ApplicationManager.AddApplication("another-app");
// ClearConsole();
// new DeployApplicationsExecutor().Execute(Context);
// Console.ToString().ShouldContain("Deploying application 'an-app'");
// Console.ToString().ShouldContain("Deploying application 'another-app'");
// Context.ApplicationManager.GetApplicationState("an-app").ShouldBe(Lifecycle.State.Starting);
// Context.ApplicationManager.GetApplicationState("another-app").ShouldBe(Lifecycle.State.Starting);
}
[Fact]
public void TestDeployNoApplications()
{
// new DeployApplicationsExecutor().Execute(Context);
// Console.ToString().Trim().ShouldBeEmpty();
}
[Fact]
public void TestDeployNoTarget()
{
// Context.Configuration.EnvironmentName = null;
// Context.ApplicationManager.AddApplication("an-app");
// var e = Assert.Throws<ToolingException>(
// () => new DeployApplicationsExecutor().Execute(Context)
// );
// e.Message.ShouldBe("Target deployment environment not set");
}
}
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше