diff --git a/.gitignore b/.gitignore
index e81bfb9e..31f175bb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -287,3 +287,4 @@ __pycache__/
*.odx.cs
*.xsd.cs
/App_Data
+/Bot.WebStarter/App_Data/bot-rasa.db
diff --git a/Bot.Rasa.RestApi/AgentController.cs b/Bot.Rasa.RestApi/AgentController.cs
index 34843c60..25524b54 100644
--- a/Bot.Rasa.RestApi/AgentController.cs
+++ b/Bot.Rasa.RestApi/AgentController.cs
@@ -1,5 +1,5 @@
using Bot.Rasa.Agents;
-using Bot.Rasa.Console;
+using Bot.Rasa.Consoles;
using EntityFrameworkCore.BootKit;
using Microsoft.AspNetCore.Mvc;
using System;
diff --git a/Bot.Rasa.RestApi/Bot.Rasa.RestApi.csproj b/Bot.Rasa.RestApi/Bot.Rasa.RestApi.csproj
index dcb02a5a..a43c3086 100644
--- a/Bot.Rasa.RestApi/Bot.Rasa.RestApi.csproj
+++ b/Bot.Rasa.RestApi/Bot.Rasa.RestApi.csproj
@@ -10,9 +10,8 @@
-
-
-
+
+
diff --git a/Bot.Rasa.RestApi/EntityDbContextBuilderExtensions.cs b/Bot.Rasa.RestApi/EntityDbContextBuilderExtensions.cs
new file mode 100644
index 00000000..9db6eb0a
--- /dev/null
+++ b/Bot.Rasa.RestApi/EntityDbContextBuilderExtensions.cs
@@ -0,0 +1,25 @@
+using EntityFrameworkCore.BootKit;
+using Microsoft.Extensions.Configuration;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.AspNetCore.Builder
+{
+ public static class EntityDbContextBuilderExtensions
+ {
+ ///
+ /// Use CustomEntityFoundation
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static void UseEntityDbContext(this IApplicationBuilder app, IConfiguration configuration, String contentRootPath, String[] assembles)
+ {
+ Database.Configuration = configuration;
+ Database.Assemblies = assembles;
+ Database.ContentRootPath = contentRootPath;
+ }
+ }
+}
diff --git a/Bot.Rasa.RestApi/EssentialController.cs b/Bot.Rasa.RestApi/EssentialController.cs
index ea322c6c..c7db40c5 100644
--- a/Bot.Rasa.RestApi/EssentialController.cs
+++ b/Bot.Rasa.RestApi/EssentialController.cs
@@ -1,6 +1,7 @@
-using Bot.Rasa.Console;
+using Bot.Rasa.Consoles;
using DotNetToolkit;
using EntityFrameworkCore.BootKit;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Data.Sqlite;
using MySql.Data.MySqlClient;
@@ -12,9 +13,7 @@ using System.Text;
namespace Bot.Rasa.RestApi
{
-#if !DEBUG
- [Authorize]
-#endif
+ //[Authorize]
[Produces("application/json")]
[Route("bot/[controller]")]
public class EssentialController : ControllerBase
@@ -23,46 +22,7 @@ namespace Bot.Rasa.RestApi
public EssentialController()
{
- dc = new Database();
-
- string db = RasaConsole.Options.DbName;
- string connectionString = RasaConsole.Options.DbConnectionString;
-
- if (db.Equals("SqlServer"))
- {
- dc.BindDbContext(new DatabaseBind
- {
- MasterConnection = new SqlConnection(connectionString),
- CreateDbIfNotExist = true,
- AssemblyNames = RasaConsole.Options.Assembles
- });
- }
- else if (db.Equals("Sqlite"))
- {
- connectionString = connectionString.Replace("|DataDirectory|\\", RasaConsole.Options.ContentRootPath + "\\App_Data\\");
- dc.BindDbContext(new DatabaseBind
- {
- MasterConnection = new SqliteConnection(connectionString),
- CreateDbIfNotExist = true,
- AssemblyNames = RasaConsole.Options.Assembles
- });
- }
- else if (db.Equals("MySql"))
- {
- dc.BindDbContext(new DatabaseBind
- {
- MasterConnection = new MySqlConnection(connectionString),
- CreateDbIfNotExist = true,
- AssemblyNames = RasaConsole.Options.Assembles
- });
- }
- else if (db.Equals("InMemory"))
- {
- dc.BindDbContext(new DatabaseBind
- {
- AssemblyNames = RasaConsole.Options.Assembles
- });
- }
+ dc = new DefaultDataContextLoader().GetDefaultDc();
}
[HttpPatch("{table}/{id}")]
diff --git a/Bot.Rasa.RestApi/InitLoaderBuilderExtensions.cs b/Bot.Rasa.RestApi/InitLoaderBuilderExtensions.cs
new file mode 100644
index 00000000..9390668e
--- /dev/null
+++ b/Bot.Rasa.RestApi/InitLoaderBuilderExtensions.cs
@@ -0,0 +1,20 @@
+using Microsoft.Extensions.Configuration;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Bot.Rasa.Loader;
+
+namespace Microsoft.AspNetCore.Builder
+{
+ public static class InitLoaderBuilderExtensions
+ {
+ ///
+ /// Initialize Loader
+ ///
+ ///
+ public static void UseInitLoader(this IApplicationBuilder app)
+ {
+ new InitializationLoader().Load();
+ }
+ }
+}
diff --git a/Bot.Rasa/Bot.Rasa.csproj b/Bot.Rasa/Bot.Rasa.csproj
index 1aa114b2..6528de66 100644
--- a/Bot.Rasa/Bot.Rasa.csproj
+++ b/Bot.Rasa/Bot.Rasa.csproj
@@ -6,9 +6,10 @@
-
-
-
+
+
+
+
diff --git a/Bot.Rasa/Console/RasaConsole.cs b/Bot.Rasa/Consoles/RasaConsole.cs
similarity index 98%
rename from Bot.Rasa/Console/RasaConsole.cs
rename to Bot.Rasa/Consoles/RasaConsole.cs
index 04331388..41d8115f 100644
--- a/Bot.Rasa/Console/RasaConsole.cs
+++ b/Bot.Rasa/Consoles/RasaConsole.cs
@@ -11,7 +11,7 @@ using System.IO;
using System.Linq;
using System.Text;
-namespace Bot.Rasa.Console
+namespace Bot.Rasa.Consoles
{
public class RasaConsole
{
diff --git a/Bot.Rasa/Console/RasaOptions.cs b/Bot.Rasa/Consoles/RasaOptions.cs
similarity index 92%
rename from Bot.Rasa/Console/RasaOptions.cs
rename to Bot.Rasa/Consoles/RasaOptions.cs
index 81456305..75b9e1bc 100644
--- a/Bot.Rasa/Console/RasaOptions.cs
+++ b/Bot.Rasa/Consoles/RasaOptions.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
-namespace Bot.Rasa.Console
+namespace Bot.Rasa.Consoles
{
public class RasaOptions
{
diff --git a/Bot.Rasa/Console/RequestExtension.cs b/Bot.Rasa/Consoles/RequestExtension.cs
similarity index 98%
rename from Bot.Rasa/Console/RequestExtension.cs
rename to Bot.Rasa/Consoles/RequestExtension.cs
index 0d35244b..4ea225c7 100644
--- a/Bot.Rasa/Console/RequestExtension.cs
+++ b/Bot.Rasa/Consoles/RequestExtension.cs
@@ -9,7 +9,7 @@ using System.Collections.Generic;
using System.IO;
using System.Text;
-namespace Bot.Rasa.Console
+namespace Bot.Rasa.Consoles
{
public static class RequestExtension
{
diff --git a/Bot.Rasa/Loader/DbInitializer.cs b/Bot.Rasa/Loader/DbInitializer.cs
new file mode 100644
index 00000000..9b311eff
--- /dev/null
+++ b/Bot.Rasa/Loader/DbInitializer.cs
@@ -0,0 +1,28 @@
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Linq;
+using EntityFrameworkCore.BootKit;
+using DotNetToolkit;
+
+namespace Bot.Rasa.Loader
+{
+ public class DbInitializer : IInitializationLoader
+ {
+ public int Priority => 1;
+
+ public void Initialize()
+ {
+ var dc = new DefaultDataContextLoader().GetDefaultDc();
+
+ var instances = TypeHelper.GetInstanceWithInterface(Database.Assemblies).OrderBy(x => x.Priority).ToList();
+
+ for (int idx = 0; idx < instances.Count; idx++)
+ {
+ DateTime start = DateTime.UtcNow;
+ Console.WriteLine($"{instances[idx].ToString()} P:{instances[idx].Priority} started at {DateTime.UtcNow}");
+ int effected = dc.DbTran(() => instances[idx].Load(Database.Configuration, dc));
+ Console.WriteLine($"{instances[idx].ToString()} effected [{effected}] records in {(DateTime.UtcNow - start).TotalMilliseconds} ms");
+ }
+ }
+ }
+}
diff --git a/Bot.Rasa/Loader/IHookDbInitializer.cs b/Bot.Rasa/Loader/IHookDbInitializer.cs
new file mode 100644
index 00000000..420df8ea
--- /dev/null
+++ b/Bot.Rasa/Loader/IHookDbInitializer.cs
@@ -0,0 +1,27 @@
+using EntityFrameworkCore.BootKit;
+using Microsoft.Extensions.Configuration;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Bot.Rasa.Loader
+{
+ ///
+ /// Initialize data for modules
+ ///
+ public interface IHookDbInitializer
+ {
+ ///
+ /// value smaller is higher priority
+ ///
+ int Priority { get; }
+
+ ///
+ /// Load data
+ ///
+ ///
+ ///
+ ///
+ void Load(IConfiguration config, Database dc);
+ }
+}
diff --git a/Bot.Rasa/Loader/IInitializationLoader.cs b/Bot.Rasa/Loader/IInitializationLoader.cs
new file mode 100644
index 00000000..746c2c92
--- /dev/null
+++ b/Bot.Rasa/Loader/IInitializationLoader.cs
@@ -0,0 +1,13 @@
+using System.Text;
+
+namespace Bot.Rasa.Loader
+{
+ ///
+ /// Implement a customzied loader
+ ///
+ public interface IInitializationLoader
+ {
+ int Priority { get; }
+ void Initialize();
+ }
+}
diff --git a/Bot.Rasa/Loader/InitializationLoader.cs b/Bot.Rasa/Loader/InitializationLoader.cs
new file mode 100644
index 00000000..153f4a64
--- /dev/null
+++ b/Bot.Rasa/Loader/InitializationLoader.cs
@@ -0,0 +1,34 @@
+using DotNetToolkit;
+using EntityFrameworkCore.BootKit;
+using Microsoft.Extensions.Configuration;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Bot.Rasa.Loader
+{
+ public class InitializationLoader
+ {
+ public void Load()
+ {
+ DateTime startAll = DateTime.UtcNow;
+ Console.WriteLine();
+ Console.WriteLine($"*** *** *** *** InitializationLoader running *** *** *** ***");
+ Console.WriteLine();
+
+ var coreLoaders = TypeHelper.GetInstanceWithInterface(Database.Assemblies);
+
+ coreLoaders.ForEach(loader =>
+ {
+ DateTime start = DateTime.UtcNow;
+ Console.WriteLine($"{loader.ToString()} P:{loader.Priority}...");
+ loader.Initialize();
+ Console.WriteLine($"{loader.ToString()} completed in {(DateTime.UtcNow - start).TotalSeconds} s.");
+ Console.WriteLine();
+ });
+
+ Console.WriteLine($"*** *** *** *** InitializationLoader completed in {(DateTime.UtcNow - startAll).TotalSeconds} s. *** *** *** ***");
+ Console.WriteLine();
+ }
+ }
+}
diff --git a/Bot.UnitTest/AgentTest.cs b/Bot.UnitTest/AgentTest.cs
index 8c7597b9..3b8319c5 100644
--- a/Bot.UnitTest/AgentTest.cs
+++ b/Bot.UnitTest/AgentTest.cs
@@ -1,6 +1,6 @@
using Bot.Rasa;
using Bot.Rasa.Agents;
-using Bot.Rasa.Console;
+using Bot.Rasa.Consoles;
using EntityFrameworkCore.BootKit;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
diff --git a/Bot.UnitTest/Bot.UnitTest.csproj b/Bot.UnitTest/Bot.UnitTest.csproj
index 020eafdb..4978c4ec 100644
--- a/Bot.UnitTest/Bot.UnitTest.csproj
+++ b/Bot.UnitTest/Bot.UnitTest.csproj
@@ -7,7 +7,9 @@
-
+
+
+
diff --git a/Bot.UnitTest/TestEssential.cs b/Bot.UnitTest/TestEssential.cs
index ee839977..5d633b31 100644
--- a/Bot.UnitTest/TestEssential.cs
+++ b/Bot.UnitTest/TestEssential.cs
@@ -1,21 +1,39 @@
-using Bot.Rasa.Console;
+using Bot.Rasa.Consoles;
using EntityFrameworkCore.BootKit;
using Microsoft.Data.Sqlite;
+using Microsoft.Extensions.Configuration;
using System;
using System.IO;
+using System.Linq;
namespace Bot.UnitTest
{
public abstract class TestEssential
{
protected Database dc { get; set; }
+ protected string contentRoot;
public TestEssential()
{
+ contentRoot = $"{Directory.GetCurrentDirectory()}\\..\\..\\..\\..\\Bot.WebStarter";
+
+ ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
+ var settings = Directory.GetFiles(contentRoot, "settings.*.json");
+ settings.ToList().ForEach(setting =>
+ {
+ configurationBuilder.AddJsonFile(setting, optional: false, reloadOnChange: true);
+ });
+ Database.Configuration = configurationBuilder.Build();
+
+ Database.Assemblies = new String[] { "Bot.Rasa" };
+ Database.ContentRootPath = contentRoot;
+
+ dc = new DefaultDataContextLoader().GetDefaultDc();
+
RasaConsole.Options = new RasaOptions
{
HostUrl = "http://192.168.56.101:5000",
- ContentRootPath = $"{Directory.GetCurrentDirectory()}\\..\\..\\..\\..\\Bot.WebStarter",
+ ContentRootPath = contentRoot,
Assembles = new String[] { "Bot.Rasa" }
};
@@ -24,8 +42,7 @@ namespace Bot.UnitTest
dc.BindDbContext(new DatabaseBind
{
MasterConnection = new SqliteConnection($"Data Source={RasaConsole.Options.ContentRootPath}\\App_Data\\bot-rasa.db"),
- CreateDbIfNotExist = true,
- AssemblyNames = new string[] { "Bot.Rasa" }
+ CreateDbIfNotExist = true
});
}
}
diff --git a/Bot.WebStarter/Bot.WebStarter.csproj b/Bot.WebStarter/Bot.WebStarter.csproj
index 6c62ba3a..cb56ae3a 100644
--- a/Bot.WebStarter/Bot.WebStarter.csproj
+++ b/Bot.WebStarter/Bot.WebStarter.csproj
@@ -13,7 +13,10 @@
-
+
+
+
+
diff --git a/Bot.WebStarter/Program.cs b/Bot.WebStarter/Program.cs
index 56a33126..0e164648 100644
--- a/Bot.WebStarter/Program.cs
+++ b/Bot.WebStarter/Program.cs
@@ -19,6 +19,16 @@ namespace Bot.WebStarter
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
+ .ConfigureAppConfiguration((hostingContext, config) =>
+ {
+ var env = hostingContext.HostingEnvironment;
+ var settings = Directory.GetFiles("./", "settings.*.json");
+ settings.ToList().ForEach(setting =>
+ {
+ config.AddJsonFile(setting, optional: false, reloadOnChange: true);
+ });
+ })
+ .UseUrls("http://localhost:9900")
.UseStartup()
.Build();
}
diff --git a/Bot.WebStarter/Startup.cs b/Bot.WebStarter/Startup.cs
index 5dee6b04..bacfce11 100644
--- a/Bot.WebStarter/Startup.cs
+++ b/Bot.WebStarter/Startup.cs
@@ -1,14 +1,19 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Threading.Tasks;
-using Bot.Rasa.Console;
+using Bot.Rasa.Consoles;
+using DotNetToolkit.JwtHelper;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
+using Microsoft.Extensions.PlatformAbstractions;
+using Newtonsoft.Json.Serialization;
+using Swashbuckle.AspNetCore.Swagger;
namespace Bot.WebStarter
{
@@ -24,7 +29,32 @@ namespace Bot.WebStarter
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
+ services.AddCors();
+ services.AddJwtAuth(Configuration);
+
services.AddMvc();
+
+ // Add framework services.
+ services.AddMvc(options =>
+ {
+ options.RespectBrowserAcceptHeader = true;
+ }).AddJsonOptions(options =>
+ {
+ options.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
+ options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
+ //options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
+ });
+
+ services.AddSwaggerGen(c =>
+ {
+ c.AddSecurityDefinition("Bearer", new ApiKeyScheme() { In = "header", Description = "Please insert JWT with Bearer into field", Name = "Authorization", Type = "apiKey" });
+
+ var info = Configuration.GetSection("Swagger").Get();
+ c.SwaggerDoc(info.Version, info);
+
+ var filePath = Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "Bot.Rasa.RestApi.xml");
+ c.IncludeXmlComments(filePath);
+ });
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -35,17 +65,24 @@ namespace Bot.WebStarter
app.UseDeveloperExceptionPage();
}
+ app.UseStaticFiles();
+
+ app.UseSwagger();
+ app.UseSwaggerUI(c =>
+ {
+ c.SupportedSubmitMethods(SubmitMethod.Get, SubmitMethod.Post, SubmitMethod.Put, SubmitMethod.Patch, SubmitMethod.Delete);
+ c.ShowExtensions();
+ c.SwaggerEndpoint("/swagger/v1/swagger.json", "API v1");
+ c.RoutePrefix = "api";
+ });
+
+ app.UseCors(builder => builder.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().AllowCredentials());
+
+ app.UseAuthentication();
app.UseMvc();
- string db = RasaConsole.Configuration.GetSection("Database:Default").Value;
- RasaConsole.Options = new RasaOptions
- {
- HostUrl = Configuration.GetSection("Rasa:Host").Value,
- Assembles = new String[] { "Bot.Rasa" },
- ContentRootPath = env.ContentRootPath,
- DbName = db,
- DbConnectionString = Configuration.GetSection("Database:ConnectionStrings")[db]
- };
+ app.UseEntityDbContext(Configuration, env.ContentRootPath, new String[] { "Bot.Rasa" });
+ app.UseInitLoader();
}
}
}
diff --git a/Bot.WebStarter/Settings/appsettings.json b/Bot.WebStarter/settings.app.json
similarity index 78%
rename from Bot.WebStarter/Settings/appsettings.json
rename to Bot.WebStarter/settings.app.json
index 287e2813..26bb0ac7 100644
--- a/Bot.WebStarter/Settings/appsettings.json
+++ b/Bot.WebStarter/settings.app.json
@@ -11,9 +11,5 @@
"Default": "Warning"
}
}
- },
-
- "Rasa": {
- "Host": "http://192.168.56.101:5000"
}
}
diff --git a/Bot.WebStarter/settings.auth.json b/Bot.WebStarter/settings.auth.json
new file mode 100644
index 00000000..e02ee249
--- /dev/null
+++ b/Bot.WebStarter/settings.auth.json
@@ -0,0 +1,11 @@
+{
+ "TokenAuthentication": {
+ "SecretKey": "tK5aNR0FTEm4htInv+HA3A==",
+ "Subject": "Voicecoin",
+ "Issuer": "Voicecoin",
+ "Audience": "Voicecoin",
+ "TokenPath": "/token",
+ "CookieName": "token",
+ "LoginPath": "/login"
+ }
+}
\ No newline at end of file
diff --git a/Bot.WebStarter/settings.aws.json b/Bot.WebStarter/settings.aws.json
new file mode 100644
index 00000000..6336e421
--- /dev/null
+++ b/Bot.WebStarter/settings.aws.json
@@ -0,0 +1,10 @@
+{
+ "AWS": {
+ "AWSRegionEndPoint": "us-east-1",
+ "AWSSecretKey": "38+UqlSqOVbKfL3LrS6hSmgW/ZSPgZzUa/Hom7ip",
+ "AWSAccessKey": "AKIAIPXFRDXOTKZWOVXQ",
+ "AWSEncoding": "utf-8",
+ "SESVerifiedEmail": "haiping008@gmail.com",
+ "AWSBucketPrefix": "voicecoin.ico"
+ }
+}
\ No newline at end of file
diff --git a/Bot.WebStarter/Settings/dbsettings.json b/Bot.WebStarter/settings.db.json
similarity index 100%
rename from Bot.WebStarter/Settings/dbsettings.json
rename to Bot.WebStarter/settings.db.json
diff --git a/Bot.WebStarter/settings.json b/Bot.WebStarter/settings.json
new file mode 100644
index 00000000..e69de29b
diff --git a/Bot.WebStarter/settings.rasa.json b/Bot.WebStarter/settings.rasa.json
new file mode 100644
index 00000000..f1bb10fb
--- /dev/null
+++ b/Bot.WebStarter/settings.rasa.json
@@ -0,0 +1,5 @@
+{
+ "Rasa": {
+ "Host": "http://192.168.56.101:5000"
+ }
+}
diff --git a/Bot.WebStarter/settings.swagger.json b/Bot.WebStarter/settings.swagger.json
new file mode 100644
index 00000000..b5a580a8
--- /dev/null
+++ b/Bot.WebStarter/settings.swagger.json
@@ -0,0 +1,12 @@
+{
+ "Swagger": {
+ "Version": "v1",
+ "Title": "RasaBot API",
+ "Description": "RasaBot API",
+ "TermsOfService": "MIT",
+ "Contact": {
+ "Name": "Haiping Chen",
+ "Email": "haiping008@gmail.com"
+ }
+ }
+}