diff --git a/Insomnia/MAPO-IOC.json b/Insomnia/MAPO-IOC.json new file mode 100644 index 00000000..0db921f7 --- /dev/null +++ b/Insomnia/MAPO-IOC.json @@ -0,0 +1 @@ +{"_type":"export","__export_format":4,"__export_date":"2024-10-23T15:46:37.409Z","__export_source":"insomnia.desktop.app:v2023.5.8","resources":[{"_id":"req_d6789dcf78d94816bbd8572ed8e50c32","parentId":"wrk_e3f940b0e7364ede9659ddc904ed76da","modified":1680674272654,"created":1680674272654,"url":"https://localhost:7212/api/Recipe/GetRecipe?idxPODL=1656","name":"New Request","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1680616613017,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"wrk_e3f940b0e7364ede9659ddc904ed76da","parentId":null,"modified":1680674272619,"created":1680674272619,"name":"MP-IOC","description":"","scope":"collection","_type":"workspace"},{"_id":"req_0990f1f8b8054c6aa775c08233beb68a","parentId":"wrk_e3f940b0e7364ede9659ddc904ed76da","modified":1680674272646,"created":1680674272646,"url":"{{ _.BASE_URL }}/api/Recipe/GetRecipe?idxPODL=1656","name":"GET RECIPE (calc)","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1680615241541.5,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_86ef875060b240979a923807d5726572","parentId":"wrk_e3f940b0e7364ede9659ddc904ed76da","modified":1680674272651,"created":1680674272651,"url":"{{ BASE_URL }}/api/RecipeArchive/GetFile?idxMacc=SIMUL_02&fileName=10002.xml","name":"GET FILE (from archive)","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1679846511868.4375,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_80ed4f0bb8ac463b90112c98d457c478","parentId":"wrk_e3f940b0e7364ede9659ddc904ed76da","modified":1680679124960,"created":1680679120652,"url":"{{ BASE_URL }}/api/RecipeArchive/GetFile?idxMacc=SIMUL_02&fileName=999.xml","name":"GET FILE - not exists","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1679462147031.9062,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"env_ca021599ba8443c1a79a2eb69aa92128","parentId":"wrk_e3f940b0e7364ede9659ddc904ed76da","modified":1680674272620,"created":1680674272620,"name":"Base Environment","data":{},"dataPropertyOrder":{},"color":null,"isPrivate":false,"metaSortKey":1680615228640,"_type":"environment"},{"_id":"jar_8fed13ca3e9a477dad1b0a6699c43b70","parentId":"wrk_e3f940b0e7364ede9659ddc904ed76da","modified":1680674272634,"created":1680674272634,"name":"Default Jar","cookies":[],"_type":"cookie_jar"},{"_id":"spc_aaf61ce728e747a89c242f3c012bb23c","parentId":"wrk_e3f940b0e7364ede9659ddc904ed76da","modified":1680674272662,"created":1680674272637,"fileName":"MP-IOC","contents":"","contentType":"yaml","_type":"api_spec"},{"_id":"env_b5e3d19ecc18458b96877ecc73b04729","parentId":"env_ca021599ba8443c1a79a2eb69aa92128","modified":1680679494694,"created":1680674272621,"name":"DEV","data":{"BASE_URL":"https://localhost:7050"},"dataPropertyOrder":{"&":["BASE_URL"]},"color":"#ff0000","isPrivate":false,"metaSortKey":1680615301619,"_type":"environment"},{"_id":"env_89e83800dd9d435ebe6745b4f80b2082","parentId":"env_ca021599ba8443c1a79a2eb69aa92128","modified":1680674621408,"created":1680674272628,"name":"IIS01","data":{"BASE_URL":"https://iis01.egalware.com/MP/IOC"},"dataPropertyOrder":{"&":["BASE_URL"]},"color":"#6600ff","isPrivate":false,"metaSortKey":1680615328099,"_type":"environment"}]} \ No newline at end of file diff --git a/Insomnia/MAPO-PROG.json b/Insomnia/MAPO-PROG.json new file mode 100644 index 00000000..9258b930 --- /dev/null +++ b/Insomnia/MAPO-PROG.json @@ -0,0 +1 @@ +{"_type":"export","__export_format":4,"__export_date":"2024-10-23T15:45:49.150Z","__export_source":"insomnia.desktop.app:v2023.5.8","resources":[{"_id":"req_bb23a3e0a78f44999350ddcefebaaf82","parentId":"wrk_0d1a3f6f42fe486dacbeeea3026c648b","modified":1729691634502,"created":1729691518776,"url":"{{ _.BASE_URL }}/api/Health","name":"Health","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1680616613017,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"wrk_0d1a3f6f42fe486dacbeeea3026c648b","parentId":null,"modified":1729691518738,"created":1729691518738,"name":"MAPO-PROG","description":"","scope":"collection","_type":"workspace"},{"_id":"req_2b3ff677e75040ed9dfe30463fb5d408","parentId":"fld_cf0e8b6c31334d67bc421487d31a5540","modified":1729691689274,"created":1729691666872,"url":"{{ _.BASE_URL }}/api/FileChange","name":"FileChange Health","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1729691677997,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"fld_cf0e8b6c31334d67bc421487d31a5540","parentId":"wrk_0d1a3f6f42fe486dacbeeea3026c648b","modified":1729691675552,"created":1729691673364,"name":"FileChange","description":"","environment":{},"environmentPropertyOrder":null,"metaSortKey":-1680616270148.125,"_type":"request_group"},{"_id":"req_8fa584b2405b4c3588e1da50c6c02cbc","parentId":"fld_cf0e8b6c31334d67bc421487d31a5540","modified":1729691870054,"created":1729691818717,"url":"{{ _.BASE_URL }}/api/FileChange/approve/ALL?numDayPrev=7","name":"FileChange AutoSave","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1726323968489,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_b28dbcb90b9f4a30ae621f46ca80abf1","parentId":"fld_cf0e8b6c31334d67bc421487d31a5540","modified":1729698051601,"created":1729698043734,"url":"{{ _.BASE_URL }}/api/FileChange/check/ALL?numDayPrev=0","name":"FileChange CheckAll","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1724640113735,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"env_f533a867e5e74bc7a712974eb5185fe2","parentId":"wrk_0d1a3f6f42fe486dacbeeea3026c648b","modified":1729691518740,"created":1729691518740,"name":"Base Environment","data":{},"dataPropertyOrder":{},"color":null,"isPrivate":false,"metaSortKey":1680615228640,"_type":"environment"},{"_id":"jar_52975036fdb946749a04bf8b105649dc","parentId":"wrk_0d1a3f6f42fe486dacbeeea3026c648b","modified":1729691518752,"created":1729691518752,"name":"Default Jar","cookies":[],"_type":"cookie_jar"},{"_id":"spc_034d8153209c43289ef94bb511a381e4","parentId":"wrk_0d1a3f6f42fe486dacbeeea3026c648b","modified":1729691518782,"created":1729691518757,"fileName":"MAPO-PROG","contents":"","contentType":"yaml","_type":"api_spec"},{"_id":"env_6acd2ea246a54f2fa42dfa7191704e4f","parentId":"env_f533a867e5e74bc7a712974eb5185fe2","modified":1729691571662,"created":1729691518742,"name":"DEV","data":{"BASE_URL":"https://localhost:5001"},"dataPropertyOrder":{"&":["BASE_URL"]},"color":"#ff0000","isPrivate":false,"metaSortKey":1680615301619,"_type":"environment"},{"_id":"env_add3f929a9774e949eaacdfef9669698","parentId":"env_f533a867e5e74bc7a712974eb5185fe2","modified":1729691576277,"created":1729691518746,"name":"IIS01","data":{"BASE_URL":"https://iis01.egalware.com/MP/PROG"},"dataPropertyOrder":{"&":["BASE_URL"]},"color":"#6600ff","isPrivate":false,"metaSortKey":1680615328099,"_type":"environment"},{"_id":"env_78f831742ec84968878b6bb3e2dbbee3","parentId":"env_f533a867e5e74bc7a712974eb5185fe2","modified":1729691592437,"created":1729691579006,"name":"PROD","data":{"BASE_URL":"https://iis01.egalware.com/MP/PROG"},"dataPropertyOrder":{"&":["BASE_URL"]},"color":"#6600ff","isPrivate":false,"metaSortKey":1692979703520,"_type":"environment"}]} \ No newline at end of file diff --git a/Insomnia/MAPO-SPEC.json b/Insomnia/MAPO-SPEC.json index b14c98f9..65a34e4a 100644 --- a/Insomnia/MAPO-SPEC.json +++ b/Insomnia/MAPO-SPEC.json @@ -1 +1 @@ -{"_type":"export","__export_format":4,"__export_date":"2023-04-04T15:23:33.215Z","__export_source":"insomnia.desktop.app:v2023.1.0","resources":[{"_id":"req_cd57cb8728854cd5a7d026b9aba60047","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680616613886,"created":1680616613017,"url":"https://localhost:7212/api/Recipe/GetRecipe?idxPODL=1656","name":"New Request","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1680616613017,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","parentId":null,"modified":1680615228636,"created":1680615228636,"name":"MAPO-SPEC","description":"","scope":"collection","_type":"workspace"},{"_id":"req_4d233d6fb970485ea929bdffdcfae05a","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680621773464,"created":1680615246346,"url":"{{ _.BASE_URL }}/api/Recipe/GetRecipe?idxPODL=1656","name":"GET RECIPE (calc)","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1680615241541.5,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_278d5f0a6555457e88ad2e58cfdaae23","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680621754168,"created":1680615436433,"url":"{{ BASE_URL }}/api/RecipeArchive/GetFile?idxMacc=SIMUL_02&fileName=10002.xml","name":"GET FILE (from archive)","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1679846511868.4375,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"env_ea1cd34b6839260f9a1edf3546f3c605bb6f3a2c","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680615377532,"created":1680615228640,"name":"Base Environment","data":{},"dataPropertyOrder":{},"color":null,"isPrivate":false,"metaSortKey":1680615228640,"_type":"environment"},{"_id":"jar_ea1cd34b6839260f9a1edf3546f3c605bb6f3a2c","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680615228642,"created":1680615228642,"name":"Default Jar","cookies":[],"_type":"cookie_jar"},{"_id":"spc_b61936e963e34a759001c6a22ad8da60","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680615228637,"created":1680615228637,"fileName":"MAPO-SPEC","contents":"","contentType":"yaml","_type":"api_spec"},{"_id":"env_2757d8ba1b17435987847d0499e9369e","parentId":"env_ea1cd34b6839260f9a1edf3546f3c605bb6f3a2c","modified":1680616993850,"created":1680615301619,"name":"DEV","data":{"BASE_URL":"https://localhost:7212"},"dataPropertyOrder":{"&":["BASE_URL"]},"color":"#ff0000","isPrivate":false,"metaSortKey":1680615301619,"_type":"environment"},{"_id":"env_f5b6aef3c2b444aab04c9056404d63f9","parentId":"env_ea1cd34b6839260f9a1edf3546f3c605bb6f3a2c","modified":1680616996428,"created":1680615328099,"name":"IIS01","data":{"BASE_URL":"https://iis01.egalware.com/MP/SPEC"},"dataPropertyOrder":{"&":["BASE_URL"]},"color":"#6600ff","isPrivate":false,"metaSortKey":1680615328099,"_type":"environment"}]} \ No newline at end of file +{"_type":"export","__export_format":4,"__export_date":"2024-10-23T15:46:09.187Z","__export_source":"insomnia.desktop.app:v2023.5.8","resources":[{"_id":"req_cd57cb8728854cd5a7d026b9aba60047","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680616613886,"created":1680616613017,"url":"https://localhost:7212/api/Recipe/GetRecipe?idxPODL=1656","name":"New Request","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1680616613017,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","parentId":null,"modified":1680615228636,"created":1680615228636,"name":"MAPO-SPEC","description":"","scope":"collection","_type":"workspace"},{"_id":"req_4d233d6fb970485ea929bdffdcfae05a","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680621773464,"created":1680615246346,"url":"{{ _.BASE_URL }}/api/Recipe/GetRecipe?idxPODL=1656","name":"GET RECIPE (calc)","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1680615241541.5,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_278d5f0a6555457e88ad2e58cfdaae23","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680621754168,"created":1680615436433,"url":"{{ BASE_URL }}/api/RecipeArchive/GetFile?idxMacc=SIMUL_02&fileName=10002.xml","name":"GET FILE (from archive)","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1679846511868.4375,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"env_ea1cd34b6839260f9a1edf3546f3c605bb6f3a2c","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680615377532,"created":1680615228640,"name":"Base Environment","data":{},"dataPropertyOrder":{},"color":null,"isPrivate":false,"metaSortKey":1680615228640,"_type":"environment"},{"_id":"jar_ea1cd34b6839260f9a1edf3546f3c605bb6f3a2c","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680615228642,"created":1680615228642,"name":"Default Jar","cookies":[],"_type":"cookie_jar"},{"_id":"spc_b61936e963e34a759001c6a22ad8da60","parentId":"wrk_86debe1a96ca41cdbfb53ed71a9d6d84","modified":1680615228637,"created":1680615228637,"fileName":"MAPO-SPEC","contents":"","contentType":"yaml","_type":"api_spec"},{"_id":"env_2757d8ba1b17435987847d0499e9369e","parentId":"env_ea1cd34b6839260f9a1edf3546f3c605bb6f3a2c","modified":1680616993850,"created":1680615301619,"name":"DEV","data":{"BASE_URL":"https://localhost:7212"},"dataPropertyOrder":{"&":["BASE_URL"]},"color":"#ff0000","isPrivate":false,"metaSortKey":1680615301619,"_type":"environment"},{"_id":"env_f5b6aef3c2b444aab04c9056404d63f9","parentId":"env_ea1cd34b6839260f9a1edf3546f3c605bb6f3a2c","modified":1680616996428,"created":1680615328099,"name":"IIS01","data":{"BASE_URL":"https://iis01.egalware.com/MP/SPEC"},"dataPropertyOrder":{"&":["BASE_URL"]},"color":"#6600ff","isPrivate":false,"metaSortKey":1680615328099,"_type":"environment"}]} \ No newline at end of file diff --git a/MP-LAND.sln b/MP-LAND.sln index 7c54065e..2113d66c 100644 --- a/MP-LAND.sln +++ b/MP-LAND.sln @@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.AppAuth", "MP.AppAuth\MP EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Egw.Core", "Egw.Core\Egw.Core.csproj", "{D3D348EF-1313-43DF-94FB-28CD38B68212}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.Data", "MP.Data\MP.Data.csproj", "{EE871AE5-9B5E-493E-8E59-F77234979AD7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug_LiManDebug|Any CPU = Debug_LiManDebug|Any CPU @@ -22,8 +24,8 @@ Global {D949AB45-9B65-4594-A97E-182BC3831707}.Debug|Any CPU.Build.0 = Debug|Any CPU {D949AB45-9B65-4594-A97E-182BC3831707}.Release|Any CPU.ActiveCfg = Release|Any CPU {D949AB45-9B65-4594-A97E-182BC3831707}.Release|Any CPU.Build.0 = Release|Any CPU - {E8B1E617-87BC-4638-A8B6-04EEBA3B8F47}.Debug_LiManDebug|Any CPU.ActiveCfg = Debug|Any CPU - {E8B1E617-87BC-4638-A8B6-04EEBA3B8F47}.Debug_LiManDebug|Any CPU.Build.0 = Debug|Any CPU + {E8B1E617-87BC-4638-A8B6-04EEBA3B8F47}.Debug_LiManDebug|Any CPU.ActiveCfg = Debug_LiManDebug|Any CPU + {E8B1E617-87BC-4638-A8B6-04EEBA3B8F47}.Debug_LiManDebug|Any CPU.Build.0 = Debug_LiManDebug|Any CPU {E8B1E617-87BC-4638-A8B6-04EEBA3B8F47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E8B1E617-87BC-4638-A8B6-04EEBA3B8F47}.Debug|Any CPU.Build.0 = Debug|Any CPU {E8B1E617-87BC-4638-A8B6-04EEBA3B8F47}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -34,6 +36,12 @@ Global {D3D348EF-1313-43DF-94FB-28CD38B68212}.Debug|Any CPU.Build.0 = Debug|Any CPU {D3D348EF-1313-43DF-94FB-28CD38B68212}.Release|Any CPU.ActiveCfg = Release|Any CPU {D3D348EF-1313-43DF-94FB-28CD38B68212}.Release|Any CPU.Build.0 = Release|Any CPU + {EE871AE5-9B5E-493E-8E59-F77234979AD7}.Debug_LiManDebug|Any CPU.ActiveCfg = Debug|Any CPU + {EE871AE5-9B5E-493E-8E59-F77234979AD7}.Debug_LiManDebug|Any CPU.Build.0 = Debug|Any CPU + {EE871AE5-9B5E-493E-8E59-F77234979AD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EE871AE5-9B5E-493E-8E59-F77234979AD7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EE871AE5-9B5E-493E-8E59-F77234979AD7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EE871AE5-9B5E-493E-8E59-F77234979AD7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/MP.AppAuth/AppAuthContext.cs b/MP.AppAuth/AppAuthContext.cs index c8c74357..35fedc43 100644 --- a/MP.AppAuth/AppAuthContext.cs +++ b/MP.AppAuth/AppAuthContext.cs @@ -10,7 +10,7 @@ namespace MP.AppAuth { #region Private Fields - private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); + private static Logger Log = LogManager.GetCurrentClassLogger(); private IConfiguration _configuration; diff --git a/MP.AppAuth/MP.AppAuth.csproj b/MP.AppAuth/MP.AppAuth.csproj index b8b2a8c4..95ecb38c 100644 --- a/MP.AppAuth/MP.AppAuth.csproj +++ b/MP.AppAuth/MP.AppAuth.csproj @@ -2,6 +2,7 @@ net6.0 + Debug;Release;Debug_LiManDebug @@ -16,7 +17,10 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + + + diff --git a/MP.Land/Data/SyncService.cs b/MP.AppAuth/Services/SyncService.cs similarity index 96% rename from MP.Land/Data/SyncService.cs rename to MP.AppAuth/Services/SyncService.cs index a51aa105..123b9074 100644 --- a/MP.Land/Data/SyncService.cs +++ b/MP.AppAuth/Services/SyncService.cs @@ -1,7 +1,4 @@ -using Egw.Core; -using Microsoft.Extensions.Caching.Distributed; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Configuration; using MP.AppAuth.DTO; using MP.AppAuth.Models; using Newtonsoft.Json; @@ -11,12 +8,12 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using System.Threading.Tasks; using System.Web; -using static Egw.Core.LiManObj; using static System.Net.Mime.MediaTypeNames; -namespace MP.Land.Data +namespace MP.AppAuth.Services { public class SyncService { @@ -31,15 +28,17 @@ namespace MP.Land.Data _configuration = configuration; // sistemo conf secondo Target compilazione - - #if DEBUG_LIMANDEBUG apiUrl = "https://localhost:5003/"; #else apiUrl = "https://liman.egalware.com/ELM.API/"; #endif // fix opzioni base del RestClient - restOptStd = new RestClientOptions { Timeout = TimeSpan.FromSeconds(60), BaseUrl = new Uri(apiUrl) }; + restOptStd = new RestClientOptions + { + Timeout = TimeSpan.FromSeconds(60), + BaseUrl = new Uri(apiUrl) + }; } #endregion Public Constructors @@ -82,7 +81,7 @@ namespace MP.Land.Data answ = response.Content.Replace("\"", ""); } } - return await Task.FromResult(answ); + return answ; } /// @@ -241,16 +240,20 @@ namespace MP.Land.Data private static IConfiguration? _configuration; - /// - /// URL dell'API x chiamate gestione licenze - /// - private string apiUrl { get; set; } = "https://localhost:5003/"; - /// /// Classe logger /// private static Logger Log = LogManager.GetCurrentClassLogger(); + #endregion Private Fields + + #region Private Properties + + /// + /// URL dell'API x chiamate gestione licenze + /// + private string apiUrl { get; set; } = "https://localhost:5003/"; + /// /// Conf client RestSharp standard: /// - base URI al sito @@ -258,6 +261,6 @@ namespace MP.Land.Data /// private RestClientOptions restOptStd { get; set; } = new RestClientOptions(); - #endregion Private Fields + #endregion Private Properties } } \ No newline at end of file diff --git a/MP.Data/Controllers/MpLandController.cs b/MP.Data/Controllers/MpLandController.cs new file mode 100644 index 00000000..e4998388 --- /dev/null +++ b/MP.Data/Controllers/MpLandController.cs @@ -0,0 +1,474 @@ +using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using MP.Data.DatabaseModels; +using MP.Data.Objects; +using NLog; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using static MP.Data.Objects.Enums; + +namespace MP.Data.Controllers +{ + public class MpLandController : IDisposable + { + #region Public Constructors + + public MpLandController(IConfiguration configuration) + { + _configuration = configuration; + Log.Info("Avviato MpLandController"); + } + + #endregion Public Constructors + + #region Public Methods + + public DateTime CalcNextExe(TaskListModel taskRec) + { + DateTime dtNext = DateTime.Today; + try + { + // calcolo next exec da tipo... + switch (taskRec.Freq) + { + case TaskFreqType.ND: + dtNext = taskRec.DtLastExec.AddDays(taskRec.Cad); + break; + + case TaskFreqType.Sec: + dtNext = taskRec.DtLastExec.AddSeconds(taskRec.Cad); + break; + + case TaskFreqType.Min: + dtNext = taskRec.DtLastExec.AddMinutes(taskRec.Cad); + break; + + case TaskFreqType.Hour: + dtNext = taskRec.DtLastExec.AddHours(taskRec.Cad); + break; + + case TaskFreqType.Day: + dtNext = taskRec.DtLastExec.AddDays(taskRec.Cad); + break; + + case TaskFreqType.Week: + dtNext = taskRec.DtLastExec.AddDays(7 * taskRec.Cad); + break; + + case TaskFreqType.Month: + dtNext = taskRec.DtLastExec.AddMonths(taskRec.Cad); + break; + + case TaskFreqType.Year: + dtNext = taskRec.DtLastExec.AddYears(taskRec.Cad); + break; + + default: + dtNext = taskRec.DtLastExec.AddDays(taskRec.Cad); + break; + } + } + catch (Exception exc) + { + Log.Error($"Eccezione in CalcNextExe{Environment.NewLine}{exc}"); + } + return dtNext; + } + + /// + /// Elenco da tabella Config + /// + /// + public List ConfigGetAll() + { + List dbResult = new List(); + using (var dbCtx = new MoonProContext(_configuration)) + { + dbResult = dbCtx + .DbSetConfig + .AsNoTracking() + .OrderBy(x => x.Chiave) + .ToList(); + } + return dbResult; + } + + public void Dispose() + { + _configuration = null; + } + + /// + /// Elenco operatori + /// + /// + public List ElencoOperatori() + { + List dbResult = new List(); + using (var dbCtx = new MoonProContext(_configuration)) + { + dbResult = dbCtx + .DbOperatori + .Where(s => s.MatrOpr > 0) + .AsNoTracking() + .OrderBy(x => x.MatrOpr) + .ToList(); + } + return dbResult; + } + + /// + /// Chiamata esecuzione di un singolo task programmato + /// + /// + /// Se true rischedula successiva chiamata + /// + public TaskResultModel ExecuteSqlTask(int TaskId, bool SchedNext) + { + TaskResultModel callRes = new TaskResultModel(); + using (var dbCtx = new MoonPro_STATSContext(_configuration)) + { + // imposto timeout a 5 min + //var currTimeout = dbCtx.Database.GetCommandTimeout(); + dbCtx.Database.SetCommandTimeout(TimeSpan.FromMinutes(5)); + try + { + DateTime dtStart = DateTime.Now; + // recupero i dati da richiamare... + var currRec = dbCtx + .DbSetTaskList + .Where(x => x.TaskId == TaskId) + .FirstOrDefault(); + if (currRec != null) + { + // recupero comando + string sqlCommand = currRec.Command; + string rawParams = currRec.Args; + callRes = dbCtx + .DbSetTaskResult + .FromSqlRaw($"EXEC {sqlCommand} {rawParams}") + .AsNoTracking() + .AsEnumerable() + .FirstOrDefault(); + DateTime dtEnd = DateTime.Now; + + // preparo record esecuzione... + TaskExecModel resRec = new TaskExecModel() + { + TaskId = TaskId, + DtStart = dtStart, + DtEnd = dtEnd, + IsError = callRes.ExecResult < 0, + Result = callRes.TextResult + }; + dbCtx + .DbSetTaskExe + .Add(resRec); + + // aggiorno record chiamata... + currRec.DtLastExec = dtStart; + currRec.LastResult = resRec.Result; + currRec.LastIsError = resRec.IsError; + currRec.LastDuration = dtEnd.Subtract(dtStart).TotalSeconds; + // solo se richiesto rischedulazione ricalcola chiamata + if (SchedNext) + { + // calcolo prossima esecuzione... + currRec.DtNextExec = CalcNextExe(currRec); + } + // segno modificato + dbCtx.Entry(currRec).State = EntityState.Modified; + + // salvo modifiche! + dbCtx.SaveChanges(); + } + } + catch (Exception exc) + { + Log.Error($"Eccezione in ExecuteSqlCommand{Environment.NewLine}{exc}"); + } + } + return callRes; + } + + + /// + /// Annulla modifiche su una specifica entity (cancel update) + /// + /// + /// + public bool RollBackEntity(object item) + { + bool answ = false; + using (var dbCtx = new MoonPro_STATSContext(_configuration)) + { + try + { + if (dbCtx.Entry(item).State == Microsoft.EntityFrameworkCore.EntityState.Deleted || dbCtx.Entry(item).State == Microsoft.EntityFrameworkCore.EntityState.Modified) + { + dbCtx.Entry(item).Reload(); + } + } + catch (Exception exc) + { + Log.Error($"Eccezione in rollBackEntity{Environment.NewLine}{exc}"); + } + } + return answ; + } + + /// + /// Ricerca task dato tipo + num max (desc) + /// + /// TaskId da cui deriva + /// + public List TaskExecGetFilt(int TaskId, int maxRec) + { + List dbResult = new List(); + using (var dbCtx = new MoonProContext(_configuration)) + { + dbResult = dbCtx + .DbSetTaskExe + .Include(x => x.TaskListNav) + .Where(x => (x.TaskId == TaskId)) + .OrderByDescending(x => x.DtStart) + .Take(maxRec) + .ToList(); + } + return dbResult; + } + + /// + /// Upsert record TaskExec + /// + /// Record da aggiornare/inserire + /// + public bool TaskExecUpsert(TaskExecModel rec2upd) + { + bool done = false; + using (var dbCtx = new MoonProContext(_configuration)) + { + try + { + var currData = dbCtx + .DbSetTaskExe + .Where(x => x.TaskExecId == rec2upd.TaskExecId) + .FirstOrDefault(); + if (currData != null) + { + currData.TaskId = rec2upd.TaskId; + currData.DtStart = rec2upd.DtStart; + currData.DtEnd = rec2upd.DtEnd; + currData.IsError = rec2upd.IsError; + currData.Result = rec2upd.Result; + dbCtx.Entry(currData).State = EntityState.Modified; + } + else + { + dbCtx + .DbSetTaskExe + .Add(rec2upd); + } + dbCtx.SaveChanges(); + done = true; + } + catch (Exception exc) + { + Log.Error($"Eccezione in TaskExecUpsert{Environment.NewLine}{exc}"); + } + } + return done; + } + + /// + /// Ricerca task dato tipo e + /// + /// + /// + public List TaskListGetAll(Task2ExeType TType) + { + List dbResult = new List(); + using (var dbCtx = new MoonProContext(_configuration)) + { + dbResult = dbCtx + .DbSetTaskList + .Where(x => (TType == Task2ExeType.ND || x.TType == TType)) + .OrderBy(x => x.Ordinal) + .ToList(); + } + return dbResult; + } + + + /// + /// Esegue registrazione di un Task generico (NON SQL) + /// + /// + /// Se true rischedula successiva chiamata + /// Record esecuzione task esterno + /// + public TaskResultModel TaskExecSaveExecuted(int TaskId, bool SchedNext, TaskExecModel ResRec) + { + TaskResultModel callRes = new TaskResultModel(); + using (var dbCtx = new MoonProContext(_configuration)) + { + try + { + // recupero i dati da richiamare... + var currRec = dbCtx + .DbSetTaskList + .Where(x => x.TaskId == TaskId) + .FirstOrDefault(); + if (currRec != null) + { + // registro task ricevuto + dbCtx + .DbSetTaskExe + .Add(ResRec); + + // aggiorno record chiamata... + currRec.DtLastExec = ResRec.DtStart; + currRec.LastResult = ResRec.Result; + currRec.LastIsError = ResRec.IsError; + currRec.LastDuration = ResRec.DtEnd.Subtract(ResRec.DtStart).TotalSeconds; + // solo se richiesto rischedulazione ricalcola chiamata + if (SchedNext) + { + // calcolo prossima esecuzione... + currRec.DtNextExec = CalcNextExe(currRec); + } + // segno modificato + dbCtx.Entry(currRec).State = EntityState.Modified; + + // salvo modifiche! + dbCtx.SaveChanges(); + } + } + catch (Exception exc) + { + Log.Error($"Eccezione in TaskExecSaveExecuted{Environment.NewLine}{exc}"); + } + } + return callRes; + } + /// + /// Update ordinamento task + /// + /// Record da spostare x priorità + /// + public bool TaskListMove(TaskListModel rec2upd, bool moveUp) + { + bool done = false; + using (var dbCtx = new MoonProContext(_configuration)) + { + try + { + var currData = dbCtx + .DbSetTaskList + .Where(x => x.TaskId == rec2upd.TaskId) + .FirstOrDefault(); + if (currData != null) + { + int actOrdinal = currData.Ordinal; + TaskListModel? otherRec = null; + // cerco, secondo richiesta, precedente o successivo + if (moveUp) + { + otherRec = dbCtx + .DbSetTaskList + .Where(x => x.Ordinal < currData.Ordinal) + .OrderByDescending(x => x.Ordinal) + .FirstOrDefault(); + } + else + { + otherRec = dbCtx + .DbSetTaskList + .Where(x => x.Ordinal > currData.Ordinal) + .OrderBy(x => x.Ordinal) + .FirstOrDefault(); + } + // inverto ordinale SE ho record + if (otherRec != null) + { + currData.Ordinal = otherRec.Ordinal; + otherRec.Ordinal = actOrdinal; + dbCtx.Entry(currData).State = EntityState.Modified; + dbCtx.Entry(otherRec).State = EntityState.Modified; + } + } + //salvo + dbCtx.SaveChanges(); + done = true; + } + catch (Exception exc) + { + Log.Error($"Eccezione in TaskListUpsert{Environment.NewLine}{exc}"); + } + } + return done; + } + + /// + /// Upsert record TaskList + /// + /// Record da aggiornare/inserire + /// + public bool TaskListUpsert(TaskListModel rec2upd) + { + bool done = false; + using (var dbCtx = new MoonProContext(_configuration)) + { + try + { + var currData = dbCtx + .DbSetTaskList + .Where(x => x.TaskId == rec2upd.TaskId && rec2upd.TaskId > 0) + .FirstOrDefault(); + if (currData != null) + { + currData.Ordinal = rec2upd.Ordinal; + currData.Name = rec2upd.Name; + currData.Descript = rec2upd.Descript; + currData.Command = rec2upd.Command; + currData.Args = rec2upd.Args; + currData.Freq = rec2upd.Freq; + currData.Cad = rec2upd.Cad; + currData.DtLastExec = rec2upd.DtLastExec; + currData.DtNextExec = rec2upd.DtNextExec; + currData.LastDuration = rec2upd.LastDuration; + currData.LastResult = rec2upd.LastResult; + dbCtx.Entry(currData).State = EntityState.Modified; + } + else + { + dbCtx + .DbSetTaskList + .Add(rec2upd); + } + dbCtx.SaveChanges(); + done = true; + } + catch (Exception exc) + { + Log.Error($"Eccezione in TaskListUpsert{Environment.NewLine}{exc}"); + } + } + return done; + } + + #endregion Public Methods + + #region Private Fields + + private static IConfiguration _configuration; + + private static Logger Log = LogManager.GetCurrentClassLogger(); + + #endregion Private Fields + } +} \ No newline at end of file diff --git a/MP.Data/Controllers/MpStatsController.cs b/MP.Data/Controllers/MpStatsController.cs index a03ae446..8dadbbb8 100644 --- a/MP.Data/Controllers/MpStatsController.cs +++ b/MP.Data/Controllers/MpStatsController.cs @@ -541,7 +541,7 @@ namespace MP.Data.Controllers } /// - /// Ricerca task dato tipo e + /// Ricerca task dato tipo /// /// /// diff --git a/MP.Data/MP.Data.csproj b/MP.Data/MP.Data.csproj index feb3bf54..fb544465 100644 --- a/MP.Data/MP.Data.csproj +++ b/MP.Data/MP.Data.csproj @@ -34,6 +34,8 @@ + + \ No newline at end of file diff --git a/MP.Data/MoonProContext.cs b/MP.Data/MoonProContext.cs index e8a2bb3c..99e1199b 100644 --- a/MP.Data/MoonProContext.cs +++ b/MP.Data/MoonProContext.cs @@ -99,6 +99,11 @@ namespace MP.Data public virtual DbSet DbSetParetoFluxLog { get; set; } + public virtual DbSet DbSetTaskList { get; set; } + public virtual DbSet DbSetTaskExe { get; set; } + public virtual DbSet DbSetTaskResult { get; set; } + + #endregion Public Properties #region Private Methods @@ -122,6 +127,10 @@ namespace MP.Data { connString = _configuration.GetConnectionString("MP.STATS"); } + if (string.IsNullOrEmpty(connString)) + { + connString = _configuration.GetConnectionString("MP.Land"); + } optionsBuilder.UseSqlServer(connString); //optionsBuilder.UseSqlServer("Server=SQL2016DEV;Database=MoonPro;Trusted_Connection=True;"); diff --git a/MP.Data/Objects/Enums.cs b/MP.Data/Objects/Enums.cs index e9b8f5ce..91506d00 100644 --- a/MP.Data/Objects/Enums.cs +++ b/MP.Data/Objects/Enums.cs @@ -271,7 +271,17 @@ namespace MP.Data.Objects /// /// Chiamata a SQL Stored Procedure /// - SqlStored + SqlStored, + + /// + /// Chiamata REST tipo Get + /// + RestCallGet, + + ///// + ///// Chiamata REST tipo Post + ///// + //RestCallPost } //[JsonConverter(typeof(StringEnumConverter))] diff --git a/MP.Data/Services/RestCallService.cs b/MP.Data/Services/RestCallService.cs new file mode 100644 index 00000000..8173f3fc --- /dev/null +++ b/MP.Data/Services/RestCallService.cs @@ -0,0 +1,111 @@ +using Microsoft.Extensions.Configuration; +using Newtonsoft.Json; +using NLog; +using RestSharp; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Web; +using static System.Net.Mime.MediaTypeNames; + +namespace MP.AppAuth.Services +{ + public class RestCallService + { + #region Public Constructors + + /// + /// Init classe + /// + /// + public RestCallService(IConfiguration configuration) + { + _configuration = configuration; + // verifico la url base + apiUrl = _configuration.GetValue("ServerConf:Prog.ApiUrl"); + // fix opzioni base del RestClient + restOptStd = new RestClientOptions + { + Timeout = TimeSpan.FromSeconds(60), + BaseUrl = new Uri(apiUrl) + }; + } + + private string apiUrl = ""; + + #endregion Public Constructors + + #region Public Methods + + /// + /// Stato server da chiamare x verifiche preliminari stato API REST + /// + /// + /// + public async Task CheckServer() + { + string answ = "ND"; + // cerco online + using (RestClient client = new RestClient(restOptStd)) + { + var request = new RestRequest($"api/health", Method.Get); + var response = await client.GetAsync(request); + // controllo risposta + if (response.StatusCode == System.Net.HttpStatusCode.OK) + { + // verifico risposta + if (response.Content != null) + { + answ = response.Content.Replace("\"", ""); + } + } + } + return answ; + } + + /// + /// Effettua una generica chiamata ApiRest + /// + /// URL Api di base + /// Richiesta completa + /// + public async Task CallRestGet(string ApiUrl, string ApiRequest) + { + RestResponse response; + // cerco online + using (RestClient client = new RestClient(ApiUrl)) + { + var request = new RestRequest(ApiRequest, Method.Get); + response = await client.GetAsync(request); + } + return response; + } + + #endregion Public Methods + + #region Private Fields + + private static IConfiguration? _configuration; + + /// + /// Classe logger + /// + private static Logger Log = LogManager.GetCurrentClassLogger(); + + #endregion Private Fields + + #region Private Properties + + /// + /// Conf client RestSharp standard: + /// - base URI al sito + /// - timeout 1 min + /// + private RestClientOptions restOptStd { get; set; } = new RestClientOptions(); + + #endregion Private Properties + } +} \ No newline at end of file diff --git a/MP.Data/Services/TaskService.cs b/MP.Data/Services/TaskService.cs new file mode 100644 index 00000000..6e866e4a --- /dev/null +++ b/MP.Data/Services/TaskService.cs @@ -0,0 +1,370 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; +using MP.AppAuth.Services; +using MP.Data.Controllers; +using MP.Data.DatabaseModels; +using Newtonsoft.Json; +using NLog; +using StackExchange.Redis; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static MP.Data.Objects.Enums; + +namespace MP.Data.Services +{ + public class TaskService : BaseServ, IDisposable + { + #region Public Constructors + + /// + /// Init servizio TAB + /// + /// + public TaskService(IConfiguration configuration) + { + _configuration = configuration; + + // setup compoenti REDIS + redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis")); + redisDb = redisConn.GetDatabase(); + + // conf DB + ConnStr = _configuration.GetConnectionString("MP.All"); + if (string.IsNullOrEmpty(ConnStr)) + { + Log.Error("ConnString empty!"); + } + else + { + StringBuilder sb = new StringBuilder(); + MLController = new MpLandController(configuration); + sb.AppendLine($"TaskService | MpLandController OK"); + Log.Info(sb.ToString()); + // sistemo i parametri x redHas... + CodModulo = _configuration.GetValue("ServerConf:CodModulo"); + var cstringArray = ConnStr.Split(";"); + foreach (var item in cstringArray) + { + var cData = item.Trim().Split("="); + if (cData.Length == 2) + { + if (!connStrParams.ContainsKey(cData[0])) + { + connStrParams.Add(cData[0], cData[1]); + } + } + } + // sistemo + DataSource = connStrParams["Server"]; + DataBase = connStrParams["Database"]; + } + + // conf rest call service + RCallService = new RestCallService(_configuration); + } + + #endregion Public Constructors + + #region Public Events + + /// + /// Evento richiesta rilettura dati pagina (x refresh pagine aperte) + /// + public event EventHandler ReloadRequest = delegate { }; + + #endregion Public Events + + #region Public Methods + + public void Dispose() + { + // Clear database controller + MLController.Dispose(); + // redis dispose + redisConn = null; + redisDb = null; + } + + /// + /// Chiamata esecuzione di un singolo task programmato + /// + /// Task richiesto + /// Se true rischedula successiva chiamata + /// + public async Task ExecuteTask(TaskListModel TaskRec, bool SchedNext) + { + TaskResultModel answ = new TaskResultModel() + { + Task = $"TaskId: {TaskRec.TaskId} | {TaskRec.TType}", + ExecResult = -1, + TextResult = "Task Not recognized" + }; + // verifico tipo di task ed eseguo di conseguenza... + switch (TaskRec.TType) + { + //case Task2ExeType.ND: + // break; + //case Task2ExeType.Exe: + // break; + //case Task2ExeType.SqlCommand: + // break; + case Task2ExeType.SqlStored: + answ = MLController.ExecuteSqlTask(TaskRec.TaskId, SchedNext); + break; + case Task2ExeType.RestCallGet: + DateTime dtStart = DateTime.Now; + // in primis testo la chiamata al servizio Health + string rAnsw = await RCallService.CheckServer(); + // se ok effettuo vera chiamata... + if (rAnsw.ToUpper() == "OK") + { + var callResp = await RCallService.CallRestGet(TaskRec.Command, TaskRec.Args); + DateTime dtEnd = DateTime.Now; + TaskExecModel tExeMod = new TaskExecModel() + { + DtEnd = dtEnd, + DtStart = dtStart, + IsError = callResp.StatusCode != System.Net.HttpStatusCode.OK, + TaskId = TaskRec.TaskId, + Result = $"{callResp.Content}".Replace("\"", ""), + }; + // salvo su DB + answ = MLController.TaskExecSaveExecuted(TaskRec.TaskId, SchedNext, tExeMod); + } + break; + default: + break; + } + // svuoto cache! + await FlushCache("Task"); + return answ; + } + + /// + /// Pulizia cache Redis (tutta) + /// + /// + public async Task FlushCache() + { + RedisValue pattern = new RedisValue($"{redisBaseKey}:*"); + bool answ = await ExecFlushRedisPattern(pattern); + return answ; + } + + /// + /// Pulizia cache Redis per chiave specifica (da redisBaseKey...) + /// + /// + public async Task FlushCache(string KeyReq) + { + RedisValue pattern = new RedisValue($"{redisBaseKey}:{KeyReq}:*"); + bool answ = await ExecFlushRedisPattern(pattern); + return answ; + } + + /// + /// Invio notifica rilettura (con parametro) + /// + /// + public void NotifyReloadRequest(string message) + { + if (ReloadRequest != null) + { + // messaggio + ReloadEventArgs rea = new ReloadEventArgs(message); + ReloadRequest.Invoke(this, rea); + } + } + + public void rollBackEdit(object item) + { + MLController.RollBackEntity(item); + } + + /// + /// Ricerca task dato tipo + num max (desc) + /// + /// TaskId da cui deriva + /// + public async Task> TaskExecGetFilt(int TaskId, int maxRec, string searchVal) + { + // setup parametri costanti + string source = "DB"; + Stopwatch sw = new Stopwatch(); + sw.Start(); + List result = new List(); + // cerco in redis... + DateTime adesso = DateTime.Now; + string currKey = $"{redisBaseKey}:Task:ExecList:{TaskId}:{adesso:yyMMdd}:{adesso:HHmm}:{maxRec}"; + RedisValue rawData = await redisDb.StringGetAsync(currKey); + if (rawData.HasValue) + { + result = JsonConvert.DeserializeObject>($"{rawData}"); + source = "REDIS"; + } + else + { + result = MLController.TaskExecGetFilt(TaskId, maxRec); + // serializzp e salvo... + rawData = JsonConvert.SerializeObject(result); + await redisDb.StringSetAsync(currKey, rawData, FastCache); + } + if (result == null) + { + result = new List(); + } + sw.Stop(); + Log.Debug($"TaskExecGetFilt | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + return result; + } + + /// + /// Elenco TaskList gestiti + /// + /// + /// + /// + public async Task> TaskListAll(Task2ExeType TType, string searchVal = "") + { + // setup parametri costanti + string source = "DB"; + Stopwatch sw = new Stopwatch(); + sw.Start(); + List result = new List(); + // cerco in redis... + DateTime adesso = DateTime.Now; + string currKey = $"{redisBaseKey}:Task:List:{TType}"; + RedisValue rawData = await redisDb.StringGetAsync(currKey); + if (rawData.HasValue) + { + result = JsonConvert.DeserializeObject>($"{rawData}"); + source = "REDIS"; + } + else + { + result = MLController.TaskListGetAll(TType); + // serializzp e salvo... + rawData = JsonConvert.SerializeObject(result); + await redisDb.StringSetAsync(currKey, rawData, FastCache); + } + if (result == null) + { + result = new List(); + } + // se necessario filtro.. + if (!string.IsNullOrEmpty(searchVal)) + { + result = result + .Where(x => x.Name.Contains(searchVal, StringComparison.InvariantCultureIgnoreCase) + || x.Descript.Contains(searchVal, StringComparison.InvariantCultureIgnoreCase)) + .ToList(); + } + sw.Stop(); + Log.Debug($"TaskListAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + return result; + } + + /// + /// Update ordinamento task + /// + /// Record da spostare x priorità + /// + public async Task TaskListMove(TaskListModel rec2upd, bool moveUp) + { + bool dbResult = MLController.TaskListMove(rec2upd, moveUp); + // svuoto cache! + await FlushCache("Task"); + return await Task.FromResult(dbResult); + } + + /// + /// Update/Insert record TaskList + /// + /// + /// + public async Task TaskListUpsert(TaskListModel rec2upd) + { + bool dbResult = MLController.TaskListUpsert(rec2upd); + // svuoto cache! + await FlushCache("Task"); + return dbResult; + } + + #endregion Public Methods + + #region Protected Fields + + /// + /// Oggetto per connessione a REDIS + /// + protected ConnectionMultiplexer redisConn = null!; + + /// + /// Oggetto DB redis da impiegare x chiamate R/W + /// + protected IDatabase redisDb = null!; + + #endregion Protected Fields + + #region Private Fields + + private static Logger Log = LogManager.GetCurrentClassLogger(); + + private string CodModulo = ""; + + private string ConnStr = ""; + + private Dictionary connStrParams = new Dictionary(); + + private string DataBase = ""; + + private string DataSource = ""; + + private string redisBaseKey = "MP:TASK"; + + #endregion Private Fields + + #region Private Properties + + private static MpLandController MLController { get; set; } = null!; + private RestCallService RCallService { get; set; } = null!; + + #endregion Private Properties + + #region Private Methods + + /// + /// Esegue flush memoria redis dato pattern + /// + /// + /// + private async Task ExecFlushRedisPattern(RedisValue pattern) + { + bool answ = false; + var listEndpoints = redisConn.GetEndPoints(); + foreach (var endPoint in listEndpoints) + { + //var server = redisConnAdmin.GetServer(listEndpoints[0]); + var server = redisConn.GetServer(endPoint); + if (server != null) + { + var keyList = server.Keys(redisDb.Database, pattern); + foreach (var item in keyList) + { + await redisDb.KeyDeleteAsync(item); + } + answ = true; + } + } + // notifico update ai client in ascolto x reset cache + NotifyReloadRequest($"FlushRedisCache | {pattern}"); + return answ; + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/MP.FileData/Controllers/FileController.cs b/MP.FileData/Controllers/FileController.cs index acdb8df1..40a17543 100644 --- a/MP.FileData/Controllers/FileController.cs +++ b/MP.FileData/Controllers/FileController.cs @@ -115,8 +115,9 @@ namespace MP.FileData.Controllers /// Forza il controllo dei Tags /// Regole di ricerca applicate /// Utente connesso x approvazione + /// indica se vada approvata la modifica o lasciato "in sospeso" /// - public int CheckFileArchived(string idxMacchina, string path, int numDayPre, string searchPattern, bool forceTag, SearchRules currRule, string UserName) + public int CheckFileArchived(string idxMacchina, string path, int numDayPre, string searchPattern, bool forceTag, SearchRules currRule, string UserName, bool DoApprove) { Log.Info($"CheckFileArchived S00 | macchina: {idxMacchina} | path: {path} | pattern: {searchPattern} | # ExcludedFileExt: {currRule.ExcludedFileExt.Count()}"); int checkDone = 0; @@ -213,7 +214,7 @@ namespace MP.FileData.Controllers if (fileNew != null && fileNew.Count > 0) { checkDone += fileNew.Count; - FileInsert(idxMacchina, path, fileNew, UserName, 0, currRule); + FileInsert(idxMacchina, path, fileNew, UserName, 0, currRule, DoApprove); Log.Trace($"CheckFileArchived S03 | insert {fileNew.Count} files"); } // aggiorno i file modificati @@ -247,7 +248,7 @@ namespace MP.FileData.Controllers dbCtx.Dispose(); } - public int FileCountFilt(string IdxMacchina, bool OnlyActive, bool OnlyMod, bool OnlyNoTag, string FileName, string Tag, string SearchVal) + public int FileCountFilt(string IdxMacchina, bool OnlyActive, bool OnlyMod, bool OnlyNoTag, string FileName, string UserName, string Tag, string SearchVal) { int answ = 0; using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration)) @@ -259,6 +260,7 @@ namespace MP.FileData.Controllers && (x.Active == OnlyActive || !OnlyActive) && (x.Tags.Count() == 0 || !OnlyNoTag) && (!OnlyMod || x.DiskStatus != FileState.Ok) && (x.Path.Equals(FileName) || string.IsNullOrEmpty(FileName)) + && (x.UserAppr.Equals(UserName) || string.IsNullOrEmpty(UserName)) && (x.Tags.Where(t => t.TagId == Tag).Count() > 0 || string.IsNullOrEmpty(Tag)) && ((!string.IsNullOrEmpty(SearchVal) && (x.Path.Contains(SearchVal) || x.Tags.Where(t => t.TagId.Contains(SearchVal)).Count() > 0)) || string.IsNullOrEmpty(SearchVal)) ).Count(); @@ -281,24 +283,26 @@ namespace MP.FileData.Controllers .DbSetProgFile .Where(x => x.FileId == currItem.FileId) .FirstOrDefault(); - localDbCtx - .DbSetProgFile - .Remove(file2del); // se ce ne fosse un altro precedente --> lo (ri)attiva var file2open = localDbCtx - .DbSetProgFile - .Where(x => x.Name == currItem.Name && x.IdxMacchina == currItem.IdxMacchina) - .OrderByDescending(y => y.Rev) - .FirstOrDefault(); + .DbSetProgFile + .Where(x => !x.Active && x.IdxMacchina == currItem.IdxMacchina && x.Path == currItem.Path) + .OrderByDescending(y => y.Rev) + .FirstOrDefault(); if (file2open != null) { file2open.Active = true; } + // elimino record! + localDbCtx + .DbSetProgFile + .Remove(file2del); + // salvo! - localDbCtx.SaveChanges(); - done = true; + int numDone = localDbCtx.SaveChanges(); + done = numDone != 0; } return done; } @@ -331,6 +335,11 @@ namespace MP.FileData.Controllers return done; } + /// + /// Cerca il file x chiave ID + /// + /// + /// public FileModel FileGetByKey(int FileId) { FileModel thisFile = null; @@ -344,9 +353,42 @@ namespace MP.FileData.Controllers return thisFile; } - public List FileGetByPath(string path, bool onlyActive) + /// + /// Cerca un file dato un fice successivo specificando rev richiesta) + /// + /// + /// + /// + public FileModel FileGetByKeyRev(int FileId, int Rev) { - List dbResult = new List(); + FileModel oFile = null; + FileModel tFile = null; + using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration)) + { + oFile = localDbCtx + .DbSetProgFile + .Where(x => x.FileId == FileId) + .FirstOrDefault(); + // se la rev è diversa --> la cerco! + if (oFile.Rev == Rev) + { + tFile = oFile; + } + else + { + tFile = localDbCtx + .DbSetProgFile + .Where(x => x.Name == oFile.Name && x.IdxMacchina == oFile.IdxMacchina && x.Path == oFile.Path) + .FirstOrDefault(); + } + } + return tFile; + } + + + public List FileGetByPath(string path, bool onlyActive) + { + List dbResult = new List(); using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration)) { dbResult = localDbCtx @@ -359,9 +401,9 @@ namespace MP.FileData.Controllers return dbResult; } - public List FileGetFilt(string IdxMacchina, bool OnlyActive, bool OnlyMod, bool OnlyNoTag, string FileName, string Tag, string SearchVal, int NumStart, int NumRecords) + public List FileGetFilt(string IdxMacchina, bool OnlyActive, bool OnlyMod, bool OnlyNoTag, string FileName, string UserName, string Tag, string SearchVal, int NumStart, int NumRecords) { - List dbResult = new List(); + List dbResult = new List(); using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration)) { dbResult = localDbCtx @@ -373,6 +415,7 @@ namespace MP.FileData.Controllers && (x.Active == OnlyActive || !OnlyActive) && (x.Tags.Count() == 0 || !OnlyNoTag) && (!OnlyMod || x.DiskStatus != FileState.Ok) && (x.Path.Equals(FileName) || string.IsNullOrEmpty(FileName)) + && (x.UserAppr.Equals(UserName) || string.IsNullOrEmpty(UserName)) && (x.Tags.Where(t => t.TagId == Tag).Count() > 0 || string.IsNullOrEmpty(Tag)) && ((!string.IsNullOrEmpty(SearchVal) && (x.Path.Contains(SearchVal) || x.Tags.Where(t => t.TagId.Contains(SearchVal)).Count() > 0)) || string.IsNullOrEmpty(SearchVal)) ).OrderByDescending(x => x.LastMod) @@ -392,8 +435,9 @@ namespace MP.FileData.Controllers /// Utente che ha approvato la modifica, "" = NON confermata/eliminabile /// rev da usare x creazione /// Configuraizone ricerca + /// indica se vada approvata la modifica o lasciato "in sospeso" /// - public bool FileInsert(string idxMacchina, string basePath, List newFiles, string UserName, int rev, SearchRules currRule) + public bool FileInsert(string idxMacchina, string basePath, List newFiles, string UserName, int rev, SearchRules currRule, bool DoApprove) { // fare: lettura conf x macchina Log.Info($"FileInsert S01 per macchina {idxMacchina}: {newFiles.Count} files da valutare"); @@ -408,7 +452,7 @@ namespace MP.FileData.Controllers List newRec = newFiles.Select(o => new FileModel() { Active = true, - DiskStatus = FileState.Ok, + DiskStatus = DoApprove ? FileState.Ok : FileState.Changed, IdxMacchina = idxMacchina, LastCheck = adesso, LastMod = o.LastWriteTime, @@ -496,6 +540,38 @@ namespace MP.FileData.Controllers return answ; } + /// + /// Imposta utente approvazione + data modifica File + /// + /// + /// + /// + public bool FileSetUserApp(FileModel currFile, string UserName) + { + bool done = false; + List listUpdate = new List(); + using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration)) + { + FileModel currRec = localDbCtx + .DbSetProgFile + .Where(x => x.FileId == currFile.FileId) + .FirstOrDefault(); + if (currRec != null) + { + DateTime adesso = DateTime.Now; + currRec.UserAppr = UserName; + currRec.LastMod = adesso; + currRec.LastCheck = adesso; + //currFile.DiskStatus = FileState.Ok; + localDbCtx.Entry(currRec).State = EntityState.Modified; + // salvo DB + localDbCtx.SaveChanges(); + } + } + return done; + } + + /// /// Approvazione modifica File /// @@ -505,8 +581,6 @@ namespace MP.FileData.Controllers public bool FileModApprove(FileModel currFile, string UserName) { bool done = false; - // recupero file regole json da macchina.. - List listUpdate = new List(); using (MoonPro_ProgContext localDbCtx = new MoonPro_ProgContext(_configuration)) { @@ -535,7 +609,7 @@ namespace MP.FileData.Controllers if (currRule.Name != "ND") { // inserisco come REVISIONE - FileInsert(currFile.IdxMacchina, currMacchina.BasePath, listUpdate, UserName, currFile.Rev + 1, currRule); + FileInsert(currFile.IdxMacchina, currMacchina.BasePath, listUpdate, UserName, currFile.Rev + 1, currRule, true); // archivio vecchio file currFile.Active = false; diff --git a/MP.Land/Components/TaskEdit.razor b/MP.Land/Components/TaskEdit.razor new file mode 100644 index 00000000..69d6674a --- /dev/null +++ b/MP.Land/Components/TaskEdit.razor @@ -0,0 +1,101 @@ +@if (CurrRecord != null) +{ +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+ @*
+
+ + +
+
+
+
+ + +
+
*@ +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+ +
+
+} + diff --git a/MP.Land/Components/TaskEdit.razor.cs b/MP.Land/Components/TaskEdit.razor.cs new file mode 100644 index 00000000..da8867a9 --- /dev/null +++ b/MP.Land/Components/TaskEdit.razor.cs @@ -0,0 +1,47 @@ +using Microsoft.AspNetCore.Components; +using MP.Data.DatabaseModels; +using MP.Data.Services; +using System.Threading.Tasks; + +namespace MP.Land.Components +{ + public partial class TaskEdit + { + #region Public Properties + + [Parameter] + public TaskListModel? CurrRecord { get; set; } = null; + + [Parameter] + public EventCallback EC_update { get; set; } + + #endregion Public Properties + + #region Protected Properties + + [Inject] + protected TaskService TService { get; set; } + + #endregion Protected Properties + + #region Protected Methods + + protected async Task doCancel() + { + await EC_update.InvokeAsync(false); + } + + protected async Task doSave() + { + bool fatto = false; + await Task.Delay(1); + if (CurrRecord != null) + { + fatto = await TService.TaskListUpsert(CurrRecord); + } + await EC_update.InvokeAsync(fatto); + } + + #endregion Protected Methods + } +} \ No newline at end of file diff --git a/MP.Land/Components/TaskExeList.razor b/MP.Land/Components/TaskExeList.razor new file mode 100644 index 00000000..99220f54 --- /dev/null +++ b/MP.Land/Components/TaskExeList.razor @@ -0,0 +1,100 @@ + +
+
+
+
+
+ History +
+
+ @if (CurrRecord != null) + { +
@TextReduce(CurrRecord.Command, 40)
+
@TextReduce(CurrRecord.Args, 60)
+ } +
+
+
+
+ +
+
+
+
+
+ @if (ListRecords == null) + { + + } + else if (totalCount == 0) + { +
Nessun record trovato
+ } + else + { +
+
+ + + + + + + + + + + @foreach (var record in ListRecords) + { + + + + + + + + + + } + +
#InizioFineEsito
+ @record.TaskExecId + + @($"{record.DtStart:HH:mm:ss.fff}") +
@($"{record.DtStart:yyyy-MM.dd ddd}")
+
+ @($"{record.DtEnd:HH:mm:ss.fff}") +
@($"{record.DtEnd:yyyy-MM.dd ddd}")
+
+
+
+ @if (@record.IsError) + { + + } + else + { + + } +
+
+ @($"{record.Duration:N3}") sec +
+
+
+
+
@record.Result
+
+
+
+
+ } +
+ +
\ No newline at end of file diff --git a/MP.Land/Components/TaskExeList.razor.cs b/MP.Land/Components/TaskExeList.razor.cs new file mode 100644 index 00000000..67658db4 --- /dev/null +++ b/MP.Land/Components/TaskExeList.razor.cs @@ -0,0 +1,136 @@ +using MailKit; +using Microsoft.AspNetCore.Components; +using MongoDB.Bson; +using MP.Data.DatabaseModels; +using MP.Data.Services; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using NLog; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace MP.Land.Components +{ + public partial class TaskExeList + { + #region Public Properties + + [Parameter] + public TaskListModel? CurrRecord { get; set; } = null; + + #endregion Public Properties + + #region Protected Fields + + protected bool isLoading = false; + + #endregion Protected Fields + + #region Protected Properties + + [Inject] + protected NavigationManager NavManager { get; set; } + + /// + /// Show error mode: 0 = tutti 1 = solo errori 2 = solo ok + /// + protected int ShowErrorMode + { + get => showErrorMode; + set + { + if (showErrorMode != value) + { + showErrorMode = value; + var pUpd = Task.Run(async () => await ReloadData()); + pUpd.Wait(); + } + } + } + + protected int totalCount { get; set; } = 0; + + [Inject] + protected TaskService TService { get; set; } + + #endregion Protected Properties + + #region Protected Methods + + protected string alCss(TaskExecModel TaskRec) + { + return TaskRec.IsError ? "alert-danger" : "alert-success"; + } + + protected async Task ForceReload(int newNum) + { + numRecord = newNum; + await ReloadData(); + } + + protected async Task ForceReloadPage(int newNum) + { + currPage = newNum; + await ReloadData(); + } + + protected override async Task OnInitializedAsync() + { + await ReloadData(); + } + + protected string TextReduce(string textOriginal, int maxChar) + { + string answ = textOriginal; + if (answ.Length > maxChar) + { + answ = $"{textOriginal.Substring(0, maxChar / 2)} ... {textOriginal.Substring(answ.Length - maxChar / 2)}"; + } + return answ; + } + + #endregion Protected Methods + + #region Private Fields + + private static Logger Log = LogManager.GetCurrentClassLogger(); + + private List ListRecords; + private List SearchRecords; + + #endregion Private Fields + + #region Private Properties + + private int currPage { get; set; } = 1; + private int numRecord { get; set; } = 10; + private int showErrorMode { get; set; } = 0; + + #endregion Private Properties + + #region Private Methods + + private async Task ReloadData() + { + SearchRecords = await TService.TaskExecGetFilt(CurrRecord.TaskId, 1000, ""); + // se non tutti filtro... + if (ShowErrorMode != 0) + { + if (ShowErrorMode == 1) + { + SearchRecords = SearchRecords.FindAll(x => x.IsError); + } + else if (ShowErrorMode == 2) + { + SearchRecords = SearchRecords.FindAll(x => !x.IsError); + } + } + totalCount = SearchRecords.Count; + ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList(); + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index 3efa1241..0a170296 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net6.0 MP.Land - 6.16.2410.2215 + 6.16.2410.2519 Debug;Release;Debug_LiManDebug @@ -62,6 +62,7 @@ + diff --git a/MP.Land/Pages/ConfSync.razor.cs b/MP.Land/Pages/ConfSync.razor.cs index eecae5c4..f5873115 100644 --- a/MP.Land/Pages/ConfSync.razor.cs +++ b/MP.Land/Pages/ConfSync.razor.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Components; using Microsoft.Extensions.Configuration; using MP.AppAuth; using MP.AppAuth.Models; +using MP.AppAuth.Services; using MP.Land.Data; using System; using System.Collections.Generic; diff --git a/MP.Land/Pages/TaskScheduler.razor b/MP.Land/Pages/TaskScheduler.razor new file mode 100644 index 00000000..accc34b3 --- /dev/null +++ b/MP.Land/Pages/TaskScheduler.razor @@ -0,0 +1,191 @@ +@page "/TaskScheduler" + +
+
+
+
+
+
+ TaskList +
+
+
+ @if (TypeSel != MP.Data.Objects.Enums.Task2ExeType.ND) + { + @if (currRecord == null) + { + + } + else + { + + } + } + else + { + + } + +
+
+
+ +
+
+ @if (isLoading) + { + + + } + else if (ListRecords == null) + { + + } + else if (totalCount == 0) + { +
Nessun record trovato
+ } + else + { +
+
+ + + + + + + + @if (detRecord == null) + { + + } + + @if (detRecord == null) + { + + + + + } + + + + @foreach (var record in ListRecords) + { + + + + + + @if (detRecord == null) + { + + } + + @if (detRecord == null) + { + + + + + } + + @if (DetailTaskId != null && DetailTaskId.TaskId == record.TaskId) + { + + + + } + } + +
+ + OrdTaskTipoCommandSched.LastNextResult + +
+ + @if (detRecord == null) + { + @if (currRecord == null) + { + + + } + else + { + + } + } + + @if (detRecord == null) + { + @if (record.Ordinal == minOrdinal) + { + + } + else + { + + } + } + @record.Ordinal + @if (detRecord == null) + { + @if (record.Ordinal == maxOrdinal) + { + + } + else + { + + } + } + +
@record.Name
+
@record.Descript
+
+ @record.TType + +
@TextReduce(record.Command, 32)
+
@TextReduce(record.Args, 40)
+
@record.Freq × @record.Cad +
@($"{record.DtLastExec:yyyy-MM-dd}")
+
@($"{record.DtLastExec:ddd HH:mm:ss}")
+
+
@($"{record.DtNextExec:yyyy-MM-dd}")
+
@($"{record.DtNextExec:ddd HH:mm:ss}")
+
+ @($"{record.LastDuration:N3}") sec + + +
+
+
+
@record.LastResult
+
+
+
+
+
+ } +
+ +
+
+ @if (detRecord != null && !isLoading) + { +
+ +
+ } +
\ No newline at end of file diff --git a/MP.Land/Pages/TaskScheduler.razor.cs b/MP.Land/Pages/TaskScheduler.razor.cs new file mode 100644 index 00000000..74a66a89 --- /dev/null +++ b/MP.Land/Pages/TaskScheduler.razor.cs @@ -0,0 +1,404 @@ +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; +using MP.Data.DatabaseModels; +using MP.Land.Data; +using static MP.Data.Objects.Enums; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using System; +using System.Linq; +using MP.Data.Services; +using DnsClient.Protocol; + +namespace MP.Land.Pages +{ + public partial class TaskScheduler : ComponentBase, IDisposable + { + #region Public Methods + + public string checkSelect(int TaskId) + { + string answ = ""; + if (currRecord != null) + { + try + { + answ = (currRecord.TaskId == TaskId) ? "table-info" : ""; + } + catch + { } + } + else if (detRecord != null) + { + answ = (detRecord.TaskId == TaskId) ? "table-info" : ""; + } + return answ; + } + + public void Dispose() + { + MessageService.EA_SearchUpdated -= OnSeachUpdated; + } + + public async void OnSeachUpdated() + { + await InvokeAsync(() => + { + Task task = ReloadData(); + StateHasChanged(); + }); + } + + #endregion Public Methods + + #region Protected Fields + + protected string fileName = "TaskList.csv"; + + #endregion Protected Fields + + #region Protected Properties + + [Inject] + protected IJSRuntime JSRuntime { get; set; } + + protected string mainCss + { + get => detRecord == null ? "col-12" : "col-6"; + } + + protected int maxOrdinal { get; set; } = 999; + + [Inject] + protected Data.MessageService MessageService { get; set; } + + protected int minOrdinal { get; set; } = 0; + + [Inject] + protected NavigationManager NavManager { get; set; } + + protected int totalCount { get; set; } = 0; + + [Inject] + protected TaskService TService { get; set; } + + protected Task2ExeType TypeSel + { + get => typeSel; + set + { + if (typeSel != value) + { + typeSel = value; + var pUpd = Task.Run(async () => + { + await ReloadData(); + }); + pUpd.Wait(); + } + } + } + + #endregion Protected Properties + + #region Protected Methods + + protected async Task addNew() + { + currRecord = new TaskListModel() + { + Name = "Nuovo Task", + TType = TypeSel, + Descript = "Descrizione Task", + DtLastExec = DateTime.Today, + DtNextExec = DateTime.Today.AddDays(1) + }; + await ReloadData(); + } + + /// + /// Gestione display avanzamento step + /// + /// + protected async Task advStep(int currStep) + { + currVal = currStep; + nextVal = currVal + 1; + await InvokeAsync(StateHasChanged); + } + + protected string alCss(TaskListModel TaskRec) + { + return TaskRec.LastIsError ? "alert-danger" : "alert-success"; + } + + protected string btnCss(TaskListModel TaskRec) + { + string answ = DetailTaskId != null && DetailTaskId.TaskId == TaskRec.TaskId ? "btn-" : "btn-outline-"; + answ += TaskRec.LastIsError ? "danger" : "success"; + return answ; + } + + protected async Task doCancel() + { + currRecord = null; + detRecord = null; + await ReloadData(); + } + + protected async Task doClone(TaskListModel selRec) + { + if (!await JSRuntime.InvokeAsync("confirm", $"Confermi di voler duplicare il record selezionato?")) + return; + currRecord = new TaskListModel() + { + Args = selRec.Args, + Name = $"Copia di {selRec.Name}", + Cad = selRec.Cad, + Command = selRec.Command, + Descript = $"Copia di {selRec.Descript}", + DtNextExec = DateTime.Today.AddDays(1), + DtLastExec = DateTime.Today.AddYears(-10), + Freq = selRec.Freq, + LastDuration = 0, + LastIsError = false, + LastResult = "", + TType = selRec.TType, + Ordinal = SearchRecords.Count + 1, + }; + await ReloadData(); + } + + protected async Task doEdit(TaskListModel selRec) + { + currRecord = selRec; + await ReloadData(); + } + + protected async Task doMove(TaskListModel currRec, bool goUp) + { + await TService.TaskListMove(currRec, goUp); + detRecord = null; + currRecord = null; + await ReloadData(); + } + + protected async Task doReset() + { + detRecord = null; + currRecord = null; + await TService.FlushCache(); + await ReloadData(); + } + + protected async Task doRun(TaskListModel selRec) + { + // SE non è ancora scaduto chiedo conferma + if (selRec.DtNextExec > DateTime.Now) + { + if (!await JSRuntime.InvokeAsync("confirm", $"Confermi esecuzione forzata task non scaduto?{Environment.NewLine}[{selRec.TaskId}]: {selRec.Name} - {selRec.Descript}{Environment.NewLine}Prossima schedulazione: {selRec.DtNextExec:yyyy-MM-dd HH:mm:ss}")) + return; + } + + // imposto tempo atteso esecuzione da ultimo... + isLoading = true; + MaxVal = 4; + int currStep = 0; + await advStep(currStep); + expTimeMsec = (int)(1000 * selRec.LastDuration) / 4; + detRecord = null; + await advStep(currStep++); + await Task.Delay(100); + await advStep(currStep++); + // chiama esecuzione task + var result = await TService.ExecuteTask(selRec, false); + await advStep(currStep++); + isLoading = false; + await Task.Delay(100); + await advStep(currStep++); + await ReloadData(); + } + + protected async Task doSelect(TaskListModel selRec) + { + detRecord = null; + currRecord = null; + DetailTaskId = null; + isLoading = true; + detRecord = selRec; + await ReloadData(); + isLoading = false; + } + + protected async Task forceAll() + { + if (!await JSRuntime.InvokeAsync("confirm", $"Confermi esecuzione forzata di tutti i task?")) + return; + + isLoading = true; + detRecord = null; + await Task.Delay(100); + foreach (var taskRec in SearchRecords) + { + var result = await TService.ExecuteTask(taskRec, false); + } + isLoading = false; + await Task.Delay(100); + await ReloadData(); + } + + protected async Task ForceReload(int newNum) + { + numRecord = newNum; + await ReloadData(); + } + + protected async Task ForceReloadPage(int newNum) + { + currPage = newNum; + await ReloadData(); + } + + protected async Task forceUpdate(bool doForce) + { + currRecord = null; + await ReloadData(); + } + + protected string iconCss(TaskListModel TaskRec) + { + return TaskRec.LastIsError ? "fa-thumbs-down" : "fa-thumbs-up"; + } + + protected override async Task OnInitializedAsync() + { + clearFile(); + numRecord = 10; + MessageService.ShowSearch = false; + MessageService.PageName = "Task Scheduler"; + MessageService.PageIcon = "oi oi-clock"; + MessageService.EA_SearchUpdated += OnSeachUpdated; + await ReloadData(); + } + + protected void ResetData() + { + clearFile(); + TService.rollBackEdit(currRecord); + currRecord = null; + } + + protected async Task ResetFilter(SelectData newFilter) + { + clearFile(); + detRecord = null; + currRecord = null; + SearchRecords = null; + ListRecords = null; + await ReloadData(); + } + + protected double righDiv(double num, double den) + { + if (den == 0) + { + den = 1; + } + double answ = num / den; + return answ; + } + + protected string TextReduce(string textOriginal, int maxChar) + { + string answ = textOriginal; + if (answ.Length > maxChar) + { + answ = $"{textOriginal.Substring(0, maxChar / 2)} ... {textOriginal.Substring(answ.Length - maxChar / 2)}"; + } + return answ; + } + + protected void ToggleDetail(TaskListModel TaskRec) + { + if (DetailTaskId == null) + { + DetailTaskId = TaskRec; + } + else + { + DetailTaskId = (DetailTaskId.TaskId == TaskRec.TaskId) ? null : TaskRec; + } + } + + #endregion Protected Methods + + #region Private Fields + + private double currVal = 0; + private TaskListModel? DetailTaskId = null; + private List ListRecords; + private int MaxVal = 10; + private double nextVal = 0; + private List SearchRecords; + + #endregion Private Fields + + #region Private Properties + + private int currPage { get; set; } = 1; + + private TaskListModel currRecord { get; set; } = null; + + private TaskListModel detRecord { get; set; } = null; + + private int expTimeMsec { get; set; } = 30000; + + private string fullPath + { + get => $"{Directory.GetCurrentDirectory()}\\temp\\{fileName}"; + } + + private bool isLoading { get; set; } = false; + private int numRecord { get; set; } = 10; + + private Task2ExeType typeSel { get; set; } = Task2ExeType.ND; + + #endregion Private Properties + + #region Private Methods + + private string btnRunCss(DateTime dtNextExe) + { + DateTime adesso = DateTime.Now; + string answ = dtNextExe < adesso ? "btn-success" : "btn-warning"; + return answ; + } + + private async void clearFile() + { + await Task.Run(() => File.Delete(fullPath)); + } + + private async Task ExportCsv() + { + isLoading = true; + // salvo davvero! + await MP.Data.Utils.SaveToCsv(SearchRecords, fullPath, ';'); + isLoading = false; + } + + private async Task ReloadData() + { + SearchRecords = await TService.TaskListAll(TypeSel, ""); + totalCount = SearchRecords.Count; + var firstRec = SearchRecords.OrderBy(x => x.Ordinal).FirstOrDefault(); + minOrdinal = firstRec != null ? firstRec.Ordinal : 0; + var lastRec = SearchRecords.OrderByDescending(x => x.Ordinal).FirstOrDefault(); + maxOrdinal = lastRec != null ? lastRec.Ordinal : 9999; + ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList(); + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/MP.Land/Pages/UpdateManager.razor.cs b/MP.Land/Pages/UpdateManager.razor.cs index 9b42b410..f900506b 100644 --- a/MP.Land/Pages/UpdateManager.razor.cs +++ b/MP.Land/Pages/UpdateManager.razor.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Configuration; using MP.AppAuth; +using MP.AppAuth.Services; using MP.Land.Data; using Newtonsoft.Json; using NLog; @@ -501,7 +502,7 @@ namespace MP.Land.Pages /// private async Task UploadZip() { - // chiamo SendZipFile di SyncService... + // chiamo SendZipFile di RestCallService... FileInfo zFileInfo = new FileInfo(zFileName); var fatto = await SyncServ.SendZipFile(LicServ.Applicazione, LicServ.Installazione, true, false, zFileInfo); Log.Info($"Richiesto invio file | Applicazione: {LicServ.Applicazione} | Installazione: {LicServ.Installazione}"); diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 1755be06..bf8768b4 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

Versione: 6.16.2410.2215

+

Versione: 6.16.2410.2519


Note di rilascio:
    diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index 892d8f51..cb3fa8a3 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -6.16.2410.2215 +6.16.2410.2519 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index cd262318..6d0111d0 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 6.16.2410.2215 + 6.16.2410.2519 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.Land/Shared/MainLayout.razor b/MP.Land/Shared/MainLayout.razor index 9ab2ea95..a7fe6136 100644 --- a/MP.Land/Shared/MainLayout.razor +++ b/MP.Land/Shared/MainLayout.razor @@ -13,11 +13,11 @@ -
    +
    -
    +
    @Body
    diff --git a/MP.Land/Shared/NavMenu.razor b/MP.Land/Shared/NavMenu.razor index 547e2abb..58b2fa2d 100644 --- a/MP.Land/Shared/NavMenu.razor +++ b/MP.Land/Shared/NavMenu.razor @@ -53,6 +53,14 @@ System Info
    + @if (IsSuperAdmin) + { + + }