Browse Source

[add]添加独立的AsnAgent程序

master
贾荣国 2 years ago
parent
commit
33dc04b14b
  1. 7
      WebApiService/Win_in.Sfs.Scp.WebApi.sln
  2. 27
      WebApiService/src/Win_in.Sfs.Scp.WebApi.Agent/AgentModule.cs
  3. 16
      WebApiService/src/Win_in.Sfs.Scp.WebApi.Agent/AgentOptions.cs
  4. 2
      WebApiService/src/Win_in.Sfs.Scp.WebApi.Agent/AgentService.cs
  5. 136
      WebApiService/src/Win_in.Sfs.Scp.WebApi.Agent/AsnBackgroundWorker/AsnBackgroundWorker.cs
  6. 67
      WebApiService/src/Win_in.Sfs.Scp.WebApi.Agent/IncomingDataWorker.cs
  7. 16
      WebApiService/src/Win_in.Sfs.Scp.WebApi.Agent/Program.cs
  8. 7
      WebApiService/src/Win_in.Sfs.Scp.WebApi.Agent/Win_in.Sfs.Scp.WebApi.Agent.csproj
  9. 66
      WebApiService/src/Win_in.Sfs.Scp.WebApi.Agent/appsettings.json
  10. 11
      WebApiService/src/Win_in.Sfs.Scp.WebApi.HttpApi.Host/WebApiHttpApiHostModule.cs

7
WebApiService/Win_in.Sfs.Scp.WebApi.sln

@ -53,6 +53,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Win_in.Sfs.Scp.WebApi.Conso
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "apps", "apps", "{F4E990AA-C8C9-4574-9027-CC2640A6C1BB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Win_in.Sfs.Scp.WebApi.Agent", "src\Win_in.Sfs.Scp.WebApi.Agent\Win_in.Sfs.Scp.WebApi.Agent.csproj", "{3A1F3A44-0574-4CAA-AAB8-305EAF54D43E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -135,6 +137,10 @@ Global
{FAC4C418-08A2-48C5-A966-A832FB091C78}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FAC4C418-08A2-48C5-A966-A832FB091C78}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FAC4C418-08A2-48C5-A966-A832FB091C78}.Release|Any CPU.Build.0 = Release|Any CPU
{3A1F3A44-0574-4CAA-AAB8-305EAF54D43E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3A1F3A44-0574-4CAA-AAB8-305EAF54D43E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3A1F3A44-0574-4CAA-AAB8-305EAF54D43E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3A1F3A44-0574-4CAA-AAB8-305EAF54D43E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -161,6 +167,7 @@ Global
{925EA68F-25D1-444F-A79B-EB9BF754EC3C} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
{A79A01B2-9532-4C6B-880F-193251F3B9F3} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
{FAC4C418-08A2-48C5-A966-A832FB091C78} = {F4E990AA-C8C9-4574-9027-CC2640A6C1BB}
{3A1F3A44-0574-4CAA-AAB8-305EAF54D43E} = {F4E990AA-C8C9-4574-9027-CC2640A6C1BB}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F}

27
WebApiService/src/Win_in.Sfs.Scp.WebApi.Agent/AgentModule.cs

@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Volo.Abp;
using Volo.Abp.Autofac;
@ -7,6 +8,7 @@ using Volo.Abp.BackgroundJobs;
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Modularity;
using Volo.Abp.MultiTenancy;
using Win_in.Sfs.Scp.v1.Domain;
using Win_in.Sfs.Scp.v1.EntityFrameworkCore;
@ -16,11 +18,14 @@ namespace Win_in.Sfs.Scp.WebApi.Agent
typeof(AbpAutofacModule),
typeof(AbpAutoMapperModule),
typeof(AbpBackgroundJobsModule),
typeof(AbpBackgroundWorkersModule)
typeof(AbpBackgroundWorkersModule),
typeof(AbpMultiTenancyModule)
)]
[DependsOn(
typeof(V1ScpDomainModule),
typeof(V1ScpEntityFrameworkCoreModule)
typeof(V1ScpEntityFrameworkCoreModule),
typeof(WebApiApplicationModule),
typeof(WebApiEntityFrameworkCoreModule)
)]
public class AgentModule : AbpModule
{
@ -36,24 +41,24 @@ namespace Win_in.Sfs.Scp.WebApi.Agent
options.UseSqlServer();
});
context.Services.AddHostedService<AgentHostedService>();
Configure<AgentOptions>(configuration.GetSection("AgentOptions"));
ConfigureMultiTenancy(configuration);
context.Services.AddHostedService<AgentHostedService>();
Configure<AsnOptions>(configuration.GetSection("AsnOptions"));
context.Services.AddAutoMapperObjectMapper<AgentModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddMaps<AgentModule>(validate: false);
});
}
private void ConfigureMultiTenancy(IConfiguration configuration)
{
Configure<AbpMultiTenancyOptions>(options => { options.IsEnabled = true; });
}
public override void OnApplicationInitialization(
ApplicationInitializationContext context)
{
context.AddBackgroundWorker<IncomingDataWorker>();
context.AddBackgroundWorker<AsnBackgroundWorker>();
}
}

16
WebApiService/src/Win_in.Sfs.Scp.WebApi.Agent/AgentOptions.cs

@ -1,16 +0,0 @@
namespace Win_in.Sfs.Scp.WebApi.Agent
{
public class AgentOptions
{
public IncomingOptions IncomingOptions { get; set; }
}
public class IncomingOptions
{
public bool Active { get; set; } = false;
public int PeriodSeconds { get; set; } = 5 * 60;
public int RetryTimes { get; set; } = 3;
public int BatchSize { get; set; } = 100;
}
}

2
WebApiService/src/Win_in.Sfs.Scp.WebApi.Agent/AgentService.cs

@ -7,7 +7,7 @@ namespace Win_in.Sfs.Scp.WebApi.Agent
{
public void Start()
{
Console.WriteLine("Wms dataExchange service has started...");
Console.WriteLine("Scp ASN agent service has started...");
}
}

136
WebApiService/src/Win_in.Sfs.Scp.WebApi.Agent/AsnBackgroundWorker/AsnBackgroundWorker.cs

@ -0,0 +1,136 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.MultiTenancy;
using Volo.Abp.TenantManagement;
using Volo.Abp.Threading;
using Volo.Abp.Uow;
using Win_in.Sfs.Scp.v1.Domain;
using Win_in.Sfs.Scp.v1.Domain.Asns;
using Win_in.Sfs.Scp.WebApi.Asns;
namespace Win_in.Sfs.Scp.WebApi
{
public class AsnBackgroundWorker : AsyncPeriodicBackgroundWorkerBase
{
private readonly IOptions<AsnOptions> _options;
public AsnBackgroundWorker(
AbpAsyncTimer timer,
IOptions<AsnOptions> options,
IServiceScopeFactory serviceScopeFactory
) : base(timer, serviceScopeFactory)
{
_options = options;
Timer.Period = options.Value.PeriodSeconds * 1000; //default 5 minutes
}
[UnitOfWork]
protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext)
{
Logger.LogInformation("Get ASN from SCP: Start");
if (!_options.Value.Active)
{
Logger.LogInformation("Get ASN from SCP: Switch is closed!");
return;
}
//Resolve dependencies
var scpAsnManager = workerContext.ServiceProvider.GetRequiredService<IScpAsnManager>();
var x12AsnRepository = workerContext.ServiceProvider.GetRequiredService<IX12AsnRepository>();
var tenantStore = workerContext.ServiceProvider.GetRequiredService<ITenantStore>();
var currentTenant = workerContext.ServiceProvider.GetRequiredService<ICurrentTenant>();
var dataFilter = workerContext.ServiceProvider.GetRequiredService<IDataFilter>();
//Do the work
var asnX12List = new List<X12Asn>();
foreach (var site in _options.Value.Sites)
{
var siteCode = site.Code;
var siteMinUid = site.MinUid;
try
{
var tenant = await tenantStore.FindAsync(siteCode);
using (currentTenant.Change(tenant.Id, tenant.Name))
{
using (dataFilter.Disable<IMultiTenant>())
{
long lastUid = 0;
var x12 = await x12AsnRepository
.Where(p => p.Site == siteCode)
.OrderByDescending(p => p.UID)
.FirstOrDefaultAsync();
lastUid = x12?.UID ?? 0;
if (lastUid < siteMinUid)
{
lastUid = siteMinUid;
}
Logger.LogInformation($"{siteCode}: Last UID is {lastUid}");
var scpAsns =
await scpAsnManager.GetUnreadAsnsAsync(siteCode, lastUid, _options.Value.BatchSize);
Logger.LogInformation($"{siteCode}: {scpAsns.Count} ASNs were Found");
foreach (var asn in scpAsns)
{
var barcodes = await scpAsnManager.GetBarcodesAsync(siteCode, asn.AsnBillNum);
var asnFactory = new AsnFactory();
var asnX128563060 =
asnFactory.CreateAsnX128563060(_options.Value.Receiver, asn, barcodes);
var jsonString = JsonSerializer.Serialize(asnX128563060);
var ediString = asnX128563060.ToString();
var asnX12 = new X12Asn(asn.Id, asn.Site, asn.AsnBillNum, jsonString, ediString,
asn.ShipTime ?? DateTime.Today);
asnX12List.Add(asnX12);
Logger.LogInformation($"{siteCode}:{asn.Id} {asn.AsnBillNum} was loaded");
}
}
}
}
catch (Exception ex)
{
Logger.LogException(ex);
}
}
foreach (var x12Asn in asnX12List)
{
var exist = await x12AsnRepository.FirstOrDefaultAsync(
p => p.UID == x12Asn.UID && p.Site == x12Asn.Site);
if (exist == null)
{
await x12AsnRepository.InsertAsync(x12Asn);
}
else
{
exist.JsonString = x12Asn.JsonString;
exist.Reset();
await x12AsnRepository.UpdateAsync(exist);
}
}
await x12AsnRepository.InsertManyAsync(asnX12List, true);
Logger.LogInformation("Get ASN from SCP: Complete");
}
}
}

67
WebApiService/src/Win_in.Sfs.Scp.WebApi.Agent/IncomingDataWorker.cs

@ -1,67 +0,0 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.Threading;
using Volo.Abp.Uow;
namespace Win_in.Sfs.Scp.WebApi.Agent
{
public class IncomingDataWorker : AsyncPeriodicBackgroundWorkerBase
{
private readonly IOptions<AgentOptions> _options;
public IncomingDataWorker(
AbpAsyncTimer timer,
IOptions<AgentOptions> options,
IServiceScopeFactory serviceScopeFactory
) : base(timer, serviceScopeFactory)
{
_options = options;
Timer.Period = options.Value.IncomingOptions.PeriodSeconds * 1000; //default 5 minutes
}
[UnitOfWork]
protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext)
{
Logger.LogInformation("Starting: Handling Incoming Exchange data...");
if (!_options.Value.IncomingOptions.Active)
{
Logger.LogInformation("Incoming Exchange is not active!");
return;
}
//Resolve dependencies
var incomingDataManager = workerContext
.ServiceProvider
.GetRequiredService<IIncomingDataManager>();
//Do the work
var incomingDataList = await incomingDataManager.GetReadyListAsync();
foreach (var incomingData in incomingDataList)
{
try
{
await UpdateWmsAsync(incomingData);
}
catch (Exception e)
{
e = e.GetBaseException();
incomingData.SetError(EnumExchangeDataErrorCode.Exception, e.Message);
}
//归档并删除
await incomingDataManager.FileAndDeleteAsync(incomingData);
}
Logger.LogInformation("Completed: Handling Incoming Exchange data...");
}
private async Task UpdateWmsAsync(object incomingData)
{
throw new NotImplementedException();
}
}
}

16
WebApiService/src/Win_in.Sfs.Scp.WebApi.Agent/Program.cs

@ -1,9 +1,13 @@
using System;
using System.Configuration;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Serilog.Events;
using Serilog.Sinks.MSSqlServer;
namespace Win_in.Sfs.Scp.WebApi.Agent
{
@ -11,6 +15,17 @@ namespace Win_in.Sfs.Scp.WebApi.Agent
{
public static async Task<int> Main(string[] args)
{
IConfigurationRoot configuration =
new ConfigurationBuilder()
.AddJsonFile("appsettings.json", false, true)
.Build();
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.CreateLogger();
/*
Log.Logger = new LoggerConfiguration()
#if DEBUG
.MinimumLevel.Debug()
@ -22,6 +37,7 @@ namespace Win_in.Sfs.Scp.WebApi.Agent
.WriteTo.Async(c => c.File("Logs/logs.txt"))
.WriteTo.Async(c => c.Console())
.CreateLogger();
*/
try
{

7
WebApiService/src/Win_in.Sfs.Scp.WebApi.Agent/Win_in.Sfs.Scp.WebApi.Agent.csproj

@ -8,10 +8,12 @@
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.*" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.*" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="3.1.0" />
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.MSSqlServer" Version="5.7.0" />
<PackageReference Include="Volo.Abp.AspNetCore.MultiTenancy" Version="4.4.2" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore.SqlServer" Version="4.4.2" />
<PackageReference Include="Volo.Abp.BackgroundJobs" Version="4.4.2" />
<PackageReference Include="Volo.Abp.BackgroundWorkers" Version="4.4.2" />
@ -29,6 +31,9 @@
<ItemGroup>
<ProjectReference Include="..\Win_in.Sfs.Scp.v1.Domain\Win_in.Sfs.Scp.v1.Domain.csproj" />
<ProjectReference Include="..\Win_in.Sfs.Scp.v1.EntityFrameworkCore\Win_in.Sfs.Scp.v1.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\Win_in.Sfs.Scp.WebApi.Application\Win_in.Sfs.Scp.WebApi.Application.csproj" />
<ProjectReference Include="..\Win_in.Sfs.Scp.WebApi.Domain.Shared\Win_in.Sfs.Scp.WebApi.Domain.Shared.csproj" />
<ProjectReference Include="..\Win_in.Sfs.Scp.WebApi.EntityFrameworkCore\Win_in.Sfs.Scp.WebApi.EntityFrameworkCore.csproj" />
</ItemGroup>

66
WebApiService/src/Win_in.Sfs.Scp.WebApi.Agent/appsettings.json

@ -1,14 +1,68 @@
{
"ConnectionStrings": {
"DataExchange": "Server=127.0.0.1;Database=DataExchange_Test;uid=sa;pwd=Microsoft2008;"
"Default": "Server=127.0.0.1;Database=Scp_WebApi;User ID=sa;Password=Microsoft2008;connection timeout=600;"
},
"Serilog": {
"Using": [ "Serilog.Sinks.File", "Serilog.Sinks.Async", "Serilog.Sinks.Console", "Serilog.Sinks.MSSqlServer" ],
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Microsoft": "Information",
"Microsoft.EntityFrameworkCore": "Warning"
}
},
"WriteTo": [
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "File",
"Args": {
"path": "Logs\\log.txt",
"rollingInterval": "Day",
"restrictedToMinimumLevel": "Debug"
}
"AgentOptions": {
"IncomingOptions": {
"Active": false,
"PeriodSeconds": 300,
}
]
}
},
{
"Name": "Console",
"Args": {
"restrictedToMinimumLevel": "Debug",
"outputTemplate": "{Timestamp:HH:mm:ss.fff zzz} [{Level}] {Message} {NewLine}{Exception}"
}
},
{
"Name": "MSSqlServer",
"Args": {
"connectionString": "Server=127.0.0.1;Database=Scp_WebApi;User ID=sa;Password=Microsoft2008;connection timeout=600;",
"tableName": "AgentLogs",
"autoCreateSqlTable": true
}
}
],
"Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ]
},
"AsnOptions": {
"Active": true,
"PeriodSeconds": 10,
"RetryTimes": 3,
"BatchSize": 100
"BatchSize": 10,
"MaxCount": 100,
"Receiver": "IACNA_ID",
"Sites": [
{
"Code": "T8",
"MinUid": 200
},
{
"Code": "T5",
"MinUid": 100
}
]
}
}

11
WebApiService/src/Win_in.Sfs.Scp.WebApi.HttpApi.Host/WebApiHttpApiHostModule.cs

@ -44,11 +44,8 @@ using Volo.Abp.Data;
namespace Win_in.Sfs.Scp.WebApi
{
[DependsOn(
typeof(WebApiHttpApiModule),
typeof(AbpAutofacModule),
typeof(AbpAspNetCoreMultiTenancyModule),
typeof(WebApiApplicationModule),
typeof(WebApiEntityFrameworkCoreModule),
typeof(AbpAspNetCoreMvcUiBasicThemeModule),
typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
typeof(AbpAccountWebIdentityServerModule),
@ -58,7 +55,13 @@ namespace Win_in.Sfs.Scp.WebApi
typeof(AbpBackgroundWorkersModule)
)]
[DependsOn(
typeof(V1ScpEntityFrameworkCoreModule))]
typeof(WebApiHttpApiModule),
typeof(WebApiApplicationModule),
typeof(WebApiEntityFrameworkCoreModule)
)]
[DependsOn(
typeof(V1ScpEntityFrameworkCoreModule)
)]
public class WebApiHttpApiHostModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)

Loading…
Cancel
Save