diff --git a/projects/IoTCenter/Api/ProductController.cs b/projects/IoTCenter/Api/ProductController.cs
index 9ed2c797..e32335ec 100644
--- a/projects/IoTCenter/Api/ProductController.cs
+++ b/projects/IoTCenter/Api/ProductController.cs
@@ -35,21 +35,25 @@ namespace IoTCenter.Api.Controllers
{
try
{
- var model = this._productRepo.ReadOnlyTable()
- .OrderBy(o => o.DisplayOrder)
- .ThenBy(o => o.Name)
- .ToList()
- .Select(o => new
- {
- o.Id,
- o.Name,
- o.Number,
- o.Image,
- o.DisplayOrder,
- Count = _deviceRepo.ReadOnlyTable()
- .WhereIf(!string.IsNullOrWhiteSpace(organNumber), o => o.Node.OrganNodes.Any(o => o.Organ.Number == organNumber))
- .Count(d => d.ProductId == o.Id)
- });
+ var model = this._organNodeRepo.ReadOnlyTable()
+ .WhereIf(!string.IsNullOrEmpty(organNumber), o => o.Organ.Number == organNumber)
+ .SelectMany(o => o.Node.Devices)
+ .GroupBy(o => new
+ {
+ o.Product.Id,
+ o.Product.Name,
+ o.Product.Number,
+ o.Product.DisplayOrder
+ })
+ .Select(o => new
+ {
+ o.Key.Id,
+ o.Key.Name,
+ o.Key.Number,
+ o.Key.DisplayOrder,
+ Count = o.Count()
+ })
+ .ToList();
return Ok(model);
}
catch (Exception ex)
@@ -65,12 +69,13 @@ namespace IoTCenter.Api.Controllers
try
{
var model = this._productRepo.ReadOnlyTable().Where(o => o.Number == number).FirstOrDefault();
- model.Devices = this._deviceRepo.ReadOnlyTable()
- .Where(o => o.Product.Id == model.Id)
- .WhereIf(!string.IsNullOrWhiteSpace(organNumber), o => o.Node.OrganNodes.Any(o => o.Organ.Number == organNumber))
- .Include(o => o.Node)
- .Include(o => o.Data)
- .ToList();
+ model.Devices = this._organNodeRepo.ReadOnlyTable()
+ .WhereIf(!string.IsNullOrEmpty(organNumber), o => o.Organ.Number == organNumber)
+ .SelectMany(o => o.Node.Devices)
+ .Include(o => o.Data)
+ .ToList()
+ .Where(o => o.ProductId == model.Id)
+ .ToList();
return Ok(model);
}
catch (Exception ex)
diff --git a/projects/IoTCenter/Api/SiteController.cs b/projects/IoTCenter/Api/SiteController.cs
index d6eb9e23..44892abd 100644
--- a/projects/IoTCenter/Api/SiteController.cs
+++ b/projects/IoTCenter/Api/SiteController.cs
@@ -1,4 +1,6 @@
using Application.Domain.Entities;
+using Hangfire;
+using Hangfire.Storage;
using Infrastructure.Application.Services.Settings;
using Infrastructure.Data;
using Infrastructure.Extensions;
@@ -87,7 +89,12 @@ namespace IoTCenter.Api.Controllers
[HttpPost]
public IActionResult UpdateTimer()
{
- this.RemoveJobs();
+ using var conn = JobStorage.Current.GetConnection();
+ var jobs = conn.GetRecurringJobs();
+ foreach (var job in jobs)
+ {
+ RecurringJob.RemoveIfExists(job.Id);
+ }
var timers = this._organSceneTimerRepo.ReadOnlyTable().ToList();
foreach (var timer in timers)
{
diff --git a/projects/IoTCenter/IoTCenter.csproj b/projects/IoTCenter/IoTCenter.csproj
index e96f01e6..28cda419 100644
--- a/projects/IoTCenter/IoTCenter.csproj
+++ b/projects/IoTCenter/IoTCenter.csproj
@@ -9,6 +9,9 @@
Linux
+
+
+
diff --git a/projects/IoTCenter/Startup.cs b/projects/IoTCenter/Startup.cs
index 5285e65d..0f3ddddd 100644
--- a/projects/IoTCenter/Startup.cs
+++ b/projects/IoTCenter/Startup.cs
@@ -1,15 +1,22 @@
-using Infrastructure.Data;
+using Hangfire;
+using Hangfire.Dashboard.BasicAuthorization;
+using Hangfire.MySql;
+using Infrastructure.Data;
using Infrastructure.Email;
using Infrastructure.Sms;
using Infrastructure.UI;
using Infrastructure.Web;
using IoT.Shared.Services;
using IoTCenter.Services;
+using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using System;
using System.Collections.Generic;
+using System.Transactions;
namespace IoTCenter
{
@@ -30,6 +37,47 @@ namespace IoTCenter
services.AddTransient();
services.AddHostedService();
base.ConfigureServices(services);
+ var connectionString = Configuration.GetConnectionString("HangfireConnection");
+ services.AddHangfire(configuration => configuration.UseStorage(new MySqlStorage(connectionString, new MySqlStorageOptions
+ {
+ TransactionIsolationLevel = IsolationLevel.ReadCommitted,
+ QueuePollInterval = TimeSpan.FromSeconds(15),
+ JobExpirationCheckInterval = TimeSpan.FromHours(1),
+ CountersAggregateInterval = TimeSpan.FromMinutes(5),
+ PrepareSchemaIfNecessary = true,
+ DashboardJobListLimit = 50000,
+ TransactionTimeout = TimeSpan.FromMinutes(1),
+ TablesPrefix = "Hangfire"
+ })));
+ }
+
+ public override void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
+ {
+ base.Configure(app, env, loggerFactory);
+ var options = new DashboardOptions
+ {
+ Authorization = new[] { new BasicAuthAuthorizationFilter(new BasicAuthAuthorizationFilterOptions
+ {
+ RequireSsl = false,
+ SslRedirect = false,
+ LoginCaseSensitive = true,
+ Users = new []
+ {
+ new BasicAuthAuthorizationUser
+ {
+ Login = Configuration["auth:usr"],
+ PasswordClear = Configuration["auth:pwd"]
+ }
+ }
+ }) }
+ };
+
+ app.UseHangfireDashboard("/job", options);
+
+ app.UseHangfireServer(new BackgroundJobServerOptions
+ {
+ ServerName = $"IoTCenter:{Guid.NewGuid()}",
+ });
}
public override void ConfigureOptions(IServiceCollection services)
diff --git a/projects/IoTCenter/appsettings.Development.json b/projects/IoTCenter/appsettings.Development.json
index 45fe774a..89be7064 100644
--- a/projects/IoTCenter/appsettings.Development.json
+++ b/projects/IoTCenter/appsettings.Development.json
@@ -1,9 +1,19 @@
-{
+{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
+ },
+ "ConnectionStrings": {
+ "postgresql": "User ID=root;Host=localhost;Port=26257;Database=iotcenter;CommandTimeout=600;TrustServerCertificate=true;",
+ "sqlite": "Data Source=iotcenter.db",
+ "mysql": "Server=localhost;Port=3306;Database=iotcenter;Uid=root;Pwd=aA123456!;",
+ "HangfireConnection": "Server=localhost;Port=3306;Database=jobserver;Uid=root;Pwd=aA123456!;Allow User Variables=True;",
+ "redis": "localhost:6379,password=aA123456!,allowAdmin=true",
+ "srs": "http://localhost:1985",
+ "JobServer": "http://localhost/JobServer",
+ "JobCallBack": "http://localhost/IoTCenter/api/v1/Api/ExecTimer"
}
}
\ No newline at end of file
diff --git a/projects/IoTCenter/appsettings.Docker.json b/projects/IoTCenter/appsettings.Docker.json
index 5ac01f23..5c32a172 100644
--- a/projects/IoTCenter/appsettings.Docker.json
+++ b/projects/IoTCenter/appsettings.Docker.json
@@ -5,6 +5,7 @@
"ConnectionStrings": {
"postgresql": "User ID=root;Host=postgresql;Port=26257;Database=iotcenter;CommandTimeout=120",
"mysql": "Server=172.172.0.30;Port=3306;Database=iotcenter;Uid=root;Pwd=aA123456!;",
+ "HangfireConnection": "Server=172.172.0.30;Port=3306;Database=jobserver;Uid=root;Pwd=aA123456!;Allow User Variables=True;",
"redis": "172.172.0.40:6379,password=aA123456!,allowAdmin=true",
"srs": "http://172.172.0.60:1985",
"JobServer": "http://172.172.0.12/JobServer",
diff --git a/projects/IoTCenter/appsettings.json b/projects/IoTCenter/appsettings.json
index f4b0ca92..a39048a0 100644
--- a/projects/IoTCenter/appsettings.json
+++ b/projects/IoTCenter/appsettings.json
@@ -59,6 +59,7 @@
"postgresql": "User ID=root;Host=localhost;Port=26257;Database=iotcenter;CommandTimeout=600;TrustServerCertificate=true;",
"sqlite": "Data Source=iotcenter.db",
"mysql": "Server=mysql;Port=3306;Database=iotcenter;Uid=root;Pwd=aA123456!;",
+ "HangfireConnection": "Server=mysql;Port=3306;Database=jobserver;Uid=root;Pwd=aA123456!;Allow User Variables=True;",
"redis": "redis:6379,password=aA123456!,allowAdmin=true",
"srs": "http://srs:1985",
"JobServer": "http://jobserver/JobServer",
@@ -81,5 +82,9 @@
"username": "admin",
"password": "admin"
}
+ },
+ "auth": {
+ "usr": "admin",
+ "pwd": "admin"
}
}
\ No newline at end of file
diff --git a/projects/UserCenter/appsettings.Development.json b/projects/UserCenter/appsettings.Development.json
index 45fe774a..51598c5f 100644
--- a/projects/UserCenter/appsettings.Development.json
+++ b/projects/UserCenter/appsettings.Development.json
@@ -1,9 +1,15 @@
-{
+{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
+ },
+ "ConnectionStrings": {
+ "postgresql": "User ID=root;Host=localhost;Port=26257;Database=usercenter;CommandTimeout=120",
+ "sqlite": "Data Source=usercenter.db",
+ "mysql": "Server=localhost;Port=3306;Database=usercenter;Uid=root;Pwd=aA123456!;",
+ "redis": "localhost:6379,password=aA123456!,allowAdmin=true"
}
}
\ No newline at end of file
diff --git a/projects/projects.sln b/projects/projects.sln
index 41c34d27..202a2385 100644
--- a/projects/projects.sln
+++ b/projects/projects.sln
@@ -39,8 +39,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UI", "UI", "{11BCB5F9-0020-
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebSPA", "WebSPA\WebSPA.csproj", "{6F839910-580D-4CD1-A0C0-6FAF542B4480}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JobServer", "JobServer\JobServer.csproj", "{6E2766D8-9ECF-469E-8662-A20F673E52CC}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IoTDameon", "IoTDameon\IoTDameon.csproj", "{60596088-3C4E-4EA2-933A-B66CD269845B}"
EndProject
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{5AEB0613-6424-4A0A-A36E-2CBBA8BD264C}"
@@ -151,18 +149,6 @@ Global
{6F839910-580D-4CD1-A0C0-6FAF542B4480}.Release|iPhone.Build.0 = Release|Any CPU
{6F839910-580D-4CD1-A0C0-6FAF542B4480}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{6F839910-580D-4CD1-A0C0-6FAF542B4480}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
- {6E2766D8-9ECF-469E-8662-A20F673E52CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6E2766D8-9ECF-469E-8662-A20F673E52CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6E2766D8-9ECF-469E-8662-A20F673E52CC}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {6E2766D8-9ECF-469E-8662-A20F673E52CC}.Debug|iPhone.Build.0 = Debug|Any CPU
- {6E2766D8-9ECF-469E-8662-A20F673E52CC}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {6E2766D8-9ECF-469E-8662-A20F673E52CC}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
- {6E2766D8-9ECF-469E-8662-A20F673E52CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6E2766D8-9ECF-469E-8662-A20F673E52CC}.Release|Any CPU.Build.0 = Release|Any CPU
- {6E2766D8-9ECF-469E-8662-A20F673E52CC}.Release|iPhone.ActiveCfg = Release|Any CPU
- {6E2766D8-9ECF-469E-8662-A20F673E52CC}.Release|iPhone.Build.0 = Release|Any CPU
- {6E2766D8-9ECF-469E-8662-A20F673E52CC}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {6E2766D8-9ECF-469E-8662-A20F673E52CC}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{60596088-3C4E-4EA2-933A-B66CD269845B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{60596088-3C4E-4EA2-933A-B66CD269845B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{60596088-3C4E-4EA2-933A-B66CD269845B}.Debug|iPhone.ActiveCfg = Debug|Any CPU
@@ -200,11 +186,10 @@ Global
{BE6DEBC5-004F-4811-8BDC-67C74D9E8C2F} = {AE34E06D-C5C7-44BC-B168-85808318516C}
{C66B39B3-D863-4651-99CD-74104CA65C47} = {11BCB5F9-0020-463A-92FB-BC25E2A0BF75}
{6F839910-580D-4CD1-A0C0-6FAF542B4480} = {11BCB5F9-0020-463A-92FB-BC25E2A0BF75}
- {6E2766D8-9ECF-469E-8662-A20F673E52CC} = {E1681DC3-9AC2-4FF6-B3DE-37EF826E6F8A}
{60596088-3C4E-4EA2-933A-B66CD269845B} = {AE34E06D-C5C7-44BC-B168-85808318516C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
- BuildVersion_StartDate = 2000/1/1
SolutionGuid = {0B7095FB-5E70-4EF8-805A-CB4A91AE4B0A}
+ BuildVersion_StartDate = 2000/1/1
EndGlobalSection
EndGlobal