diff --git a/src/samples/WebApiSample/WebApiSample.sln b/src/samples/WebApiSample/WebApiSample.sln index f2e46941d..740bdab76 100644 --- a/src/samples/WebApiSample/WebApiSample.sln +++ b/src/samples/WebApiSample/WebApiSample.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28307.168 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32526.322 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApiSample", "WebApiSample\WebApiSample.csproj", "{14489389-A65D-4993-8DE2-F51701A5AF60}" EndProject diff --git a/src/samples/WebApiSample/WebApiSample/DataTypes/MyDataType.cs b/src/samples/WebApiSample/WebApiSample/DataTypes/MyDataType.cs new file mode 100644 index 000000000..cb462a211 --- /dev/null +++ b/src/samples/WebApiSample/WebApiSample/DataTypes/MyDataType.cs @@ -0,0 +1,9 @@ +namespace WebApiSample.DataTypes +{ + public class MyDataType + { + public int Number { get; set; } + + public string Home { get; set; } + } +} diff --git a/src/samples/WebApiSample/WebApiSample/Providers/IDefinitionProvider.cs b/src/samples/WebApiSample/WebApiSample/Providers/IDefinitionProvider.cs new file mode 100644 index 000000000..a18897781 --- /dev/null +++ b/src/samples/WebApiSample/WebApiSample/Providers/IDefinitionProvider.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace WebApiSample.Providers +{ + public interface IDefinitionProvider + { + IEnumerable GetDefinitions(); + } +} diff --git a/src/samples/WebApiSample/WebApiSample/Providers/WorkflowDefinitionFileProvider.cs b/src/samples/WebApiSample/WebApiSample/Providers/WorkflowDefinitionFileProvider.cs new file mode 100644 index 000000000..837e4d9b2 --- /dev/null +++ b/src/samples/WebApiSample/WebApiSample/Providers/WorkflowDefinitionFileProvider.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace WebApiSample.Providers +{ + public class WorkflowDefinitionFileProvider : IDefinitionProvider + { + private const string DefaultTemplateSearchPattern = "*.yml"; + + public IEnumerable GetDefinitions() + { + return LoadDefinitionFromDirectory(); + } + + private IEnumerable LoadDefinitionFromDirectory() + { + var directory = new DirectoryInfo("./WorkflowDSL"); + + foreach (var file in directory.GetFiles(DefaultTemplateSearchPattern, SearchOption.AllDirectories) + .OrderBy(f => f.FullName)) + { + var name = Path.GetRelativePath(directory.FullName, file.FullName); + var rawContent = string.Empty; + + try + { + using var stream = File.Open(file.FullName, FileMode.Open, FileAccess.Read, FileShare.Read); + using var streamReader = new StreamReader(stream); + rawContent = streamReader.ReadToEnd(); + } + catch (Exception ex) + { + throw new Exception($"Fail to load template file {file.FullName}.", ex); + } + + if (!string.IsNullOrEmpty(rawContent)) + { + yield return rawContent; + } + } + } + } +} diff --git a/src/samples/WebApiSample/WebApiSample/Startup.cs b/src/samples/WebApiSample/WebApiSample/Startup.cs index 13a19ddd8..0f8f7c0c8 100644 --- a/src/samples/WebApiSample/WebApiSample/Startup.cs +++ b/src/samples/WebApiSample/WebApiSample/Startup.cs @@ -1,44 +1,64 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; +using Microsoft.Extensions.Hosting; +using Microsoft.OpenApi.Models; + using Nest; -using Swashbuckle.AspNetCore.Swagger; -using WebApiSample.Workflows; + using WorkflowCore.Interface; +using WorkflowCore.Services.DefinitionStorage; + +using WebApiSample.Steps; +using WebApiSample.Providers; +using WebApiSample.Workflows; namespace WebApiSample { public class Startup { - public Startup(IConfiguration configuration) + public Startup(IConfiguration configuration, IWebHostEnvironment environment) { Configuration = configuration; + Environment = environment; } public IConfiguration Configuration { get; } + public IWebHostEnvironment Environment { get; } + public void ConfigureServices(IServiceCollection services) { - services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); - - services.AddWorkflow(cfg => + if (this.Environment.IsDevelopment()) { - cfg.UseMongoDB(@"mongodb://mongo:27017", "workflow"); - cfg.UseElasticsearch(new ConnectionSettings(new Uri("http://elastic:9200")), "workflows"); - }); + services.AddWorkflow(); + } + else + { + services.AddWorkflow(cfg => + { + cfg.UseMongoDB(@"mongodb://mongo:27017", "workflow"); + cfg.UseElasticsearch(new ConnectionSettings(new Uri("http://elastic:9200")), "workflows"); + }); + } - services.AddSwaggerGen(c => c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" })); + services.AddSingleton(); + + services.AddControllers(); + services.AddMvc().AddNewtonsoftJson(); + + services.AddWorkflowDSL(); + + // Add workflow steps + services.AddTransient(); + + + services.AddSwaggerGen(c => c.SwaggerDoc("v1", new OpenApiInfo { Title = "RunneraaS API", Version = "v1" })); } - public void Configure(IApplicationBuilder app, IHostingEnvironment env) + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { @@ -48,10 +68,31 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env) app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1")); - app.UseMvc(); + app.UseHttpsRedirection(); + app.UseRouting(); + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + + // DSL load + var loader = app.ApplicationServices.GetService(); + var definitionProvider = app.ApplicationServices.GetService(); + foreach (var def in definitionProvider.GetDefinitions()) + { + try + { + loader.LoadDefinition(def, Deserializers.Yaml); + } + catch (Exception) + { + throw; + } + } var host = app.ApplicationServices.GetService(); host.RegisterWorkflow(); + host.Start(); } } diff --git a/src/samples/WebApiSample/WebApiSample/Steps/DSLHelloWorldStep.cs b/src/samples/WebApiSample/WebApiSample/Steps/DSLHelloWorldStep.cs new file mode 100644 index 000000000..ed437353c --- /dev/null +++ b/src/samples/WebApiSample/WebApiSample/Steps/DSLHelloWorldStep.cs @@ -0,0 +1,24 @@ +using Newtonsoft.Json.Linq; +using System.Collections.Generic; +using System.Linq; +using WorkflowCore.Interface; +using WorkflowCore.Models; + +namespace WebApiSample.Steps +{ + public class DSLHelloWorldStep : StepBody + { + public JObject Home { get; set; } + + public string Result { get; set; } + + public override ExecutionResult Run(IStepExecutionContext context) + { + var home = Home.ToObject>(); + + Result = string.Join(";", home.Select(x => x.Key + "=" + x.Value).ToArray()); + + return ExecutionResult.Next(); + } + } +} diff --git a/src/samples/WebApiSample/WebApiSample/WebApiSample.csproj b/src/samples/WebApiSample/WebApiSample/WebApiSample.csproj index 3290c0dbf..6ab50957d 100644 --- a/src/samples/WebApiSample/WebApiSample/WebApiSample.csproj +++ b/src/samples/WebApiSample/WebApiSample/WebApiSample.csproj @@ -3,22 +3,39 @@ Linux ..\docker-compose.dcproj + net6.0;netcoreapp3.1 - + + Always + PreserveNewest + - - - - - - - - + + + + + + + + + Always + + + + + 6.0.5 + + + + + 3.1.9 + + diff --git a/src/samples/WebApiSample/WebApiSample/WorkflowDSL/TestDSLWorkflow.yml b/src/samples/WebApiSample/WebApiSample/WorkflowDSL/TestDSLWorkflow.yml new file mode 100644 index 000000000..888b37436 --- /dev/null +++ b/src/samples/WebApiSample/WebApiSample/WorkflowDSL/TestDSLWorkflow.yml @@ -0,0 +1,14 @@ +Id: TestDSLHelloWorld +Version: 1 +DataType: WebApiSample.DataTypes.MyDataType, WebApiSample +Steps: +- Id: HelloWorldId + Name: HelloWorld + StepType: WebApiSample.Steps.DSLHelloWorldStep, WebApiSample + Inputs: + Home: + City: '"HelloWorld City"' + Street: '"HelloWorld Street"' + "@Number": data.Number + Outputs: + Home: step.Result \ No newline at end of file