From e2d82ae952e84960ddf6868ca2bc1331ea889ae5 Mon Sep 17 00:00:00 2001 From: Xuanye Wong Date: Mon, 18 May 2020 16:15:44 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E6=96=B0=E5=A2=9E=E9=80=82?= =?UTF-8?q?=E9=85=8Dxxl-jobv2.2+=E4=BB=A5=E4=B8=8A=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DotXxlJob.sln | 51 +- README.md | 54 +- build/releasenotes.props | 7 +- build/version.props | 3 +- .../Extensions/XxlJobExecutorMiddleware.cs | 27 +- .../Properties/launchSettings.json | 2 +- samples/ASPNetCoreExecutor/appsettings.json | 8 +- samples/HessianReader/HessianReader.csproj | 23 - samples/HessianReader/NewFile1.txt | 73 -- samples/HessianReader/NewFile2.txt | 74 -- samples/HessianReader/Program.cs | 158 --- samples/HessianReader/kill.dat | Bin 288 -> 0 bytes samples/HessianReader/log.dat | Bin 305 -> 0 bytes samples/HessianReader/request.dat | Bin 528 -> 0 bytes samples/HessianReader/run.dat | Bin 602 -> 0 bytes scripts/nuget-hessian.sh | 18 - scripts/nuget.sh | 4 +- scripts/package.sh | 2 +- src/DotXxlJob.Core/AdminClient.cs | 147 +-- src/DotXxlJob.Core/DotXxlJob.Core.csproj | 12 +- src/DotXxlJob.Core/ExecutorRegistry.cs | 2 +- .../Extensions}/DateTimeExtension.cs | 9 +- .../Extensions/ServiceCollectionExtensions.cs | 2 +- .../Internal/HessianObjectConvert.cs | 132 --- .../Internal/HessianSerializer.cs | 79 -- src/DotXxlJob.Core/Logger/JobLogger.cs | 2 +- src/DotXxlJob.Core/Model/AddressEntity.cs | 2 +- src/DotXxlJob.Core/Model/IdleBeatRequest.cs | 15 + src/DotXxlJob.Core/Model/KillRequest.cs | 16 + src/DotXxlJob.Core/Model/LogRequest.cs | 21 + src/DotXxlJob.Core/Model/RegistryParam.cs | 6 +- src/DotXxlJob.Core/Model/TriggerParam.cs | 16 +- .../XxlRestfulServiceHandler.cs | 166 +++ src/DotXxlJob.Core/XxlRpcServiceHandler.cs | 217 ---- src/Hessian/ClassDef.cs | 59 - src/Hessian/ClassElement.cs | 11 - .../Collections/ForwardingDictionary.cs | 91 -- src/Hessian/Collections/IRefMap.cs | 32 - src/Hessian/Collections/ITwoWayDictionary.cs | 59 - src/Hessian/Collections/ListRefMap.cs | 34 - src/Hessian/Collections/TwoWayDictionary.cs | 123 -- .../Collections/TwoWayDictionaryRefMap.cs | 34 - src/Hessian/Conditions.cs | 114 -- src/Hessian/Deserializer.cs | 1015 ----------------- src/Hessian/DictionaryTypeResolver.cs | 46 - src/Hessian/Hessian.csproj | 24 - src/Hessian/HessianException.cs | 24 - src/Hessian/HessianObject.cs | 66 -- src/Hessian/HessianSerializationContext.cs | 27 - src/Hessian/InvalidRefException.cs | 15 - src/Hessian/ListTypeResolver.cs | 66 -- src/Hessian/Marker.cs | 39 - src/Hessian/PeekStream.cs | 142 --- src/Hessian/Platform/BigEndianBitConverter.cs | 25 - src/Hessian/Platform/EndianBitConverter.cs | 215 ---- .../Platform/LittleEndianBitConverter.cs | 25 - src/Hessian/PropertyElement.cs | 31 - src/Hessian/Serializer.cs | 523 --------- src/Hessian/StringBuilderExtensions.cs | 39 - src/Hessian/UnexpectedTagException.cs | 18 - src/Hessian/ValueReader.cs | 163 --- tests/Hessian.Tests/Hessian.Tests.csproj | 19 - tests/Hessian.Tests/UnitTest1.cs | 13 - 63 files changed, 333 insertions(+), 4107 deletions(-) delete mode 100644 samples/HessianReader/HessianReader.csproj delete mode 100644 samples/HessianReader/NewFile1.txt delete mode 100644 samples/HessianReader/NewFile2.txt delete mode 100644 samples/HessianReader/Program.cs delete mode 100644 samples/HessianReader/kill.dat delete mode 100644 samples/HessianReader/log.dat delete mode 100644 samples/HessianReader/request.dat delete mode 100644 samples/HessianReader/run.dat delete mode 100644 scripts/nuget-hessian.sh rename src/{Hessian => DotXxlJob.Core/Extensions}/DateTimeExtension.cs (89%) delete mode 100644 src/DotXxlJob.Core/Internal/HessianObjectConvert.cs delete mode 100644 src/DotXxlJob.Core/Internal/HessianSerializer.cs create mode 100644 src/DotXxlJob.Core/Model/IdleBeatRequest.cs create mode 100644 src/DotXxlJob.Core/Model/KillRequest.cs create mode 100644 src/DotXxlJob.Core/Model/LogRequest.cs create mode 100644 src/DotXxlJob.Core/XxlRestfulServiceHandler.cs delete mode 100644 src/DotXxlJob.Core/XxlRpcServiceHandler.cs delete mode 100644 src/Hessian/ClassDef.cs delete mode 100644 src/Hessian/ClassElement.cs delete mode 100644 src/Hessian/Collections/ForwardingDictionary.cs delete mode 100644 src/Hessian/Collections/IRefMap.cs delete mode 100644 src/Hessian/Collections/ITwoWayDictionary.cs delete mode 100644 src/Hessian/Collections/ListRefMap.cs delete mode 100644 src/Hessian/Collections/TwoWayDictionary.cs delete mode 100644 src/Hessian/Collections/TwoWayDictionaryRefMap.cs delete mode 100644 src/Hessian/Conditions.cs delete mode 100644 src/Hessian/Deserializer.cs delete mode 100644 src/Hessian/DictionaryTypeResolver.cs delete mode 100644 src/Hessian/Hessian.csproj delete mode 100644 src/Hessian/HessianException.cs delete mode 100644 src/Hessian/HessianObject.cs delete mode 100644 src/Hessian/HessianSerializationContext.cs delete mode 100644 src/Hessian/InvalidRefException.cs delete mode 100644 src/Hessian/ListTypeResolver.cs delete mode 100644 src/Hessian/Marker.cs delete mode 100644 src/Hessian/PeekStream.cs delete mode 100644 src/Hessian/Platform/BigEndianBitConverter.cs delete mode 100644 src/Hessian/Platform/EndianBitConverter.cs delete mode 100644 src/Hessian/Platform/LittleEndianBitConverter.cs delete mode 100644 src/Hessian/PropertyElement.cs delete mode 100644 src/Hessian/Serializer.cs delete mode 100644 src/Hessian/StringBuilderExtensions.cs delete mode 100644 src/Hessian/UnexpectedTagException.cs delete mode 100644 src/Hessian/ValueReader.cs delete mode 100644 tests/Hessian.Tests/Hessian.Tests.csproj delete mode 100644 tests/Hessian.Tests/UnitTest1.cs diff --git a/DotXxlJob.sln b/DotXxlJob.sln index f527a9c..a162bc0 100644 --- a/DotXxlJob.sln +++ b/DotXxlJob.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26124.0 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30104.148 MinimumVisualStudioVersion = 15.0.26124.0 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{97756BA5-1E7C-4536-A49E-AE2190C0E6A5}" EndProject @@ -13,13 +13,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{E959 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASPNetCoreExecutor", "samples\ASPNetCoreExecutor\ASPNetCoreExecutor.csproj", "{DC9E5AF3-18FF-4713-BDB4-672E47ADA4E5}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HessianReader", "samples\HessianReader\HessianReader.csproj", "{F822B528-95FD-40B4-9EE0-3AE8878075AC}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hessian", "src\Hessian\Hessian.csproj", "{BD9B8108-6528-430F-AD28-6F8434A29F55}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hessian.Tests", "tests\Hessian.Tests\Hessian.Tests.csproj", "{A51FACF0-C90F-43D1-898D-CD171977C1A1}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotXxlJob.Core.Tests", "tests\DotXxlJob.Core.Tests\DotXxlJob.Core.Tests.csproj", "{81C60471-7C1C-48CE-98C0-F252C267AC9F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotXxlJob.Core.Tests", "tests\DotXxlJob.Core.Tests\DotXxlJob.Core.Tests.csproj", "{81C60471-7C1C-48CE-98C0-F252C267AC9F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -55,42 +49,6 @@ Global {DC9E5AF3-18FF-4713-BDB4-672E47ADA4E5}.Release|x64.Build.0 = Release|Any CPU {DC9E5AF3-18FF-4713-BDB4-672E47ADA4E5}.Release|x86.ActiveCfg = Release|Any CPU {DC9E5AF3-18FF-4713-BDB4-672E47ADA4E5}.Release|x86.Build.0 = Release|Any CPU - {F822B528-95FD-40B4-9EE0-3AE8878075AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F822B528-95FD-40B4-9EE0-3AE8878075AC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F822B528-95FD-40B4-9EE0-3AE8878075AC}.Debug|x64.ActiveCfg = Debug|Any CPU - {F822B528-95FD-40B4-9EE0-3AE8878075AC}.Debug|x64.Build.0 = Debug|Any CPU - {F822B528-95FD-40B4-9EE0-3AE8878075AC}.Debug|x86.ActiveCfg = Debug|Any CPU - {F822B528-95FD-40B4-9EE0-3AE8878075AC}.Debug|x86.Build.0 = Debug|Any CPU - {F822B528-95FD-40B4-9EE0-3AE8878075AC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F822B528-95FD-40B4-9EE0-3AE8878075AC}.Release|Any CPU.Build.0 = Release|Any CPU - {F822B528-95FD-40B4-9EE0-3AE8878075AC}.Release|x64.ActiveCfg = Release|Any CPU - {F822B528-95FD-40B4-9EE0-3AE8878075AC}.Release|x64.Build.0 = Release|Any CPU - {F822B528-95FD-40B4-9EE0-3AE8878075AC}.Release|x86.ActiveCfg = Release|Any CPU - {F822B528-95FD-40B4-9EE0-3AE8878075AC}.Release|x86.Build.0 = Release|Any CPU - {BD9B8108-6528-430F-AD28-6F8434A29F55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BD9B8108-6528-430F-AD28-6F8434A29F55}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BD9B8108-6528-430F-AD28-6F8434A29F55}.Debug|x64.ActiveCfg = Debug|Any CPU - {BD9B8108-6528-430F-AD28-6F8434A29F55}.Debug|x64.Build.0 = Debug|Any CPU - {BD9B8108-6528-430F-AD28-6F8434A29F55}.Debug|x86.ActiveCfg = Debug|Any CPU - {BD9B8108-6528-430F-AD28-6F8434A29F55}.Debug|x86.Build.0 = Debug|Any CPU - {BD9B8108-6528-430F-AD28-6F8434A29F55}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BD9B8108-6528-430F-AD28-6F8434A29F55}.Release|Any CPU.Build.0 = Release|Any CPU - {BD9B8108-6528-430F-AD28-6F8434A29F55}.Release|x64.ActiveCfg = Release|Any CPU - {BD9B8108-6528-430F-AD28-6F8434A29F55}.Release|x64.Build.0 = Release|Any CPU - {BD9B8108-6528-430F-AD28-6F8434A29F55}.Release|x86.ActiveCfg = Release|Any CPU - {BD9B8108-6528-430F-AD28-6F8434A29F55}.Release|x86.Build.0 = Release|Any CPU - {A51FACF0-C90F-43D1-898D-CD171977C1A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A51FACF0-C90F-43D1-898D-CD171977C1A1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A51FACF0-C90F-43D1-898D-CD171977C1A1}.Debug|x64.ActiveCfg = Debug|Any CPU - {A51FACF0-C90F-43D1-898D-CD171977C1A1}.Debug|x64.Build.0 = Debug|Any CPU - {A51FACF0-C90F-43D1-898D-CD171977C1A1}.Debug|x86.ActiveCfg = Debug|Any CPU - {A51FACF0-C90F-43D1-898D-CD171977C1A1}.Debug|x86.Build.0 = Debug|Any CPU - {A51FACF0-C90F-43D1-898D-CD171977C1A1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A51FACF0-C90F-43D1-898D-CD171977C1A1}.Release|Any CPU.Build.0 = Release|Any CPU - {A51FACF0-C90F-43D1-898D-CD171977C1A1}.Release|x64.ActiveCfg = Release|Any CPU - {A51FACF0-C90F-43D1-898D-CD171977C1A1}.Release|x64.Build.0 = Release|Any CPU - {A51FACF0-C90F-43D1-898D-CD171977C1A1}.Release|x86.ActiveCfg = Release|Any CPU - {A51FACF0-C90F-43D1-898D-CD171977C1A1}.Release|x86.Build.0 = Release|Any CPU {81C60471-7C1C-48CE-98C0-F252C267AC9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {81C60471-7C1C-48CE-98C0-F252C267AC9F}.Debug|Any CPU.Build.0 = Debug|Any CPU {81C60471-7C1C-48CE-98C0-F252C267AC9F}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -110,9 +68,6 @@ Global GlobalSection(NestedProjects) = preSolution {FFFEEA78-CB09-4BFB-89B7-E9A46EC3ED65} = {97756BA5-1E7C-4536-A49E-AE2190C0E6A5} {DC9E5AF3-18FF-4713-BDB4-672E47ADA4E5} = {E959F9B5-F3EB-48B1-B842-2CDDFDB01900} - {F822B528-95FD-40B4-9EE0-3AE8878075AC} = {E959F9B5-F3EB-48B1-B842-2CDDFDB01900} - {BD9B8108-6528-430F-AD28-6F8434A29F55} = {97756BA5-1E7C-4536-A49E-AE2190C0E6A5} - {A51FACF0-C90F-43D1-898D-CD171977C1A1} = {352EC932-F112-4A2F-9DC3-F0761C85E068} {81C60471-7C1C-48CE-98C0-F252C267AC9F} = {352EC932-F112-4A2F-9DC3-F0761C85E068} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/README.md b/README.md index 5b9dfd3..831f118 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # DotXxlJob -xxl-job的dotnet core 执行器实现,支持XXL-JOB 2.0+ +xxl-job的dotnet core 最新执行器实现,支持XXL-JOB 2.2+ +> 注意XXL-JOB 2.0-2.2版本请使用 1.0.8的执行器实现 ## 1 XXL-JOB概述 [XXL-JOB][1]是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。以下是它的架构图 @@ -25,34 +26,37 @@ xxl-job的dotnet core 执行器实现,支持XXL-JOB 2.0+ 1. 声明一个AspNet的Middleware中间件,并扩展ApplicationBuilder,本质是拦截Post请求,解析Body中的流信息 ``` -public class XxlJobExecutorMiddleware -{ - private readonly IServiceProvider _provider; - private readonly RequestDelegate _next; - - private readonly XxlRpcServiceHandler _rpcService; - public XxlJobExecutorMiddleware(IServiceProvider provider, RequestDelegate next) + public class XxlJobExecutorMiddleware { - this._provider = provider; - this._next = next; - this._rpcService = _provider.GetRequiredService(); - } + private readonly IServiceProvider _provider; + private readonly RequestDelegate _next; - public async Task Invoke(HttpContext context) - { + private readonly XxlRestfulServiceHandler _rpcService; + public XxlJobExecutorMiddleware(IServiceProvider provider, RequestDelegate next) + { + this._provider = provider; + this._next = next; + this._rpcService = _provider.GetRequiredService(); + } - if ("POST".Equals(context.Request.Method, StringComparison.OrdinalIgnoreCase) && - "application/octet-stream".Equals(context.Request.ContentType, StringComparison.OrdinalIgnoreCase)) + + public async Task Invoke(HttpContext context) { - var rsp = await _rpcService.HandlerAsync(context.Request.Body); - context.Response.StatusCode = (int) HttpStatusCode.OK; - context.Response.ContentType = "text/plain;utf-8"; - await context.Response.Body.WriteAsync(rsp,0,rsp.Length); - return; + string contentType = context.Request.ContentType; + + if ("POST".Equals(context.Request.Method, StringComparison.OrdinalIgnoreCase) + && !string.IsNullOrEmpty(contentType) + && contentType.ToLower().StartsWith("application/json")) + { + + await _rpcService.HandlerAsync(context.Request,context.Response); + + return; + } + + await _next.Invoke(context); } - await _next.Invoke(context); } -} ``` 扩展ApplicationBuilderExtensions,可根据实际情况绑定在特殊的Url Path上 @@ -151,12 +155,10 @@ public class DemoJobHandler:AbstractJobHandler public int LogRetentionDays { get; set; } = 30; } ``` -## 在其他Http服务中使用 -只需要实现Http请求的拦截,并判断post请求中content-Type="application/octet-stream",并使用XxlRpcServiceHandler来处理流 即可。 ## 其他说明 -XXL-JOB内置的RPC是使用Hessian协议,这个有点坑。很多都是java特有的属性和标识,比如类名什么的。在本项目中,并没有实现完整的Hessian2协议,只实现了使用到的类型,当然扩展起来也非常方便。如果有人要单独使用Hessian 这个类库的话,要特别注意这个问题。 +注意XXL-JOB 2.0-2.2版本请使用 1.0.8的执行器实现 有任何问题,可Issue反馈 ,最后感谢 xxl-job diff --git a/build/releasenotes.props b/build/releasenotes.props index 2a76566..01d3604 100644 --- a/build/releasenotes.props +++ b/build/releasenotes.props @@ -1,10 +1,7 @@ - 1. 修复回调一次过多的问题 - - - 1. 实现基本的Hessian协议 - + 1. 修改接口方式为Restful方式,适配xxl-jobv2.2以上版本 + diff --git a/build/version.props b/build/version.props index f536820..c1ba8dc 100644 --- a/build/version.props +++ b/build/version.props @@ -1,6 +1,5 @@ - 1.0.8 - 1.0.1 + 2.0.0 diff --git a/samples/ASPNetCoreExecutor/Extensions/XxlJobExecutorMiddleware.cs b/samples/ASPNetCoreExecutor/Extensions/XxlJobExecutorMiddleware.cs index c1d9182..dea4386 100644 --- a/samples/ASPNetCoreExecutor/Extensions/XxlJobExecutorMiddleware.cs +++ b/samples/ASPNetCoreExecutor/Extensions/XxlJobExecutorMiddleware.cs @@ -13,35 +13,26 @@ namespace ASPNetCoreExecutor private readonly IServiceProvider _provider; private readonly RequestDelegate _next; - private readonly XxlRpcServiceHandler _rpcService; + private readonly XxlRestfulServiceHandler _rpcService; public XxlJobExecutorMiddleware(IServiceProvider provider, RequestDelegate next) { this._provider = provider; this._next = next; - this._rpcService = _provider.GetRequiredService(); + this._rpcService = _provider.GetRequiredService(); } public async Task Invoke(HttpContext context) { + string contentType = context.Request.ContentType; - if ("POST".Equals(context.Request.Method, StringComparison.OrdinalIgnoreCase) && - "application/octet-stream".Equals(context.Request.ContentType, StringComparison.OrdinalIgnoreCase)) + if ("POST".Equals(context.Request.Method, StringComparison.OrdinalIgnoreCase) + && !string.IsNullOrEmpty(contentType) + && contentType.ToLower().StartsWith("application/json")) { - /* - using (Stream file = File.Create("./"+DateTime.Now.ToUnixTimeSeconds()+".data")) - { - context.Request.Body.CopyTo(file); - } - - return; - */ - - var rsp = await _rpcService.HandlerAsync(context.Request.Body); - - context.Response.StatusCode = (int) HttpStatusCode.OK; - context.Response.ContentType = "text/plain;utf-8"; - await context.Response.Body.WriteAsync(rsp,0,rsp.Length); + + await _rpcService.HandlerAsync(context.Request,context.Response); + return; } diff --git a/samples/ASPNetCoreExecutor/Properties/launchSettings.json b/samples/ASPNetCoreExecutor/Properties/launchSettings.json index 21fccdb..b42d92a 100644 --- a/samples/ASPNetCoreExecutor/Properties/launchSettings.json +++ b/samples/ASPNetCoreExecutor/Properties/launchSettings.json @@ -21,7 +21,7 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, - "applicationUrl": "http://localhost:60088/" + "applicationUrl": "http://localhost:5000/" } } } \ No newline at end of file diff --git a/samples/ASPNetCoreExecutor/appsettings.json b/samples/ASPNetCoreExecutor/appsettings.json index b9ed814..c509c70 100644 --- a/samples/ASPNetCoreExecutor/appsettings.json +++ b/samples/ASPNetCoreExecutor/appsettings.json @@ -1,16 +1,16 @@ { "Logging": { "LogLevel": { - "Default": "Warning" + "Default": "Information" } }, "xxlJob": { - "adminAddresses":"http://127.0.0.1:8080", + "adminAddresses": "http://127.0.0.1:8080/xxl-job-admin", "appName": "xxl-job-executor-dotnet", "specialBindAddress": "127.0.0.1", "port": 5000, - "autoRegistry":false, - "accessToken": "", + "autoRegistry": true, + "accessToken": "", "logRetentionDays": 30 } diff --git a/samples/HessianReader/HessianReader.csproj b/samples/HessianReader/HessianReader.csproj deleted file mode 100644 index 37178a2..0000000 --- a/samples/HessianReader/HessianReader.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - - Exe - netcoreapp2.2 - - - - - - - - - - - - - - PreserveNewest - - - - diff --git a/samples/HessianReader/NewFile1.txt b/samples/HessianReader/NewFile1.txt deleted file mode 100644 index ce6b53e..0000000 --- a/samples/HessianReader/NewFile1.txt +++ /dev/null @@ -1,73 +0,0 @@ ------------- 0x43---------------- -ReadClassDefinition -Hessian.ClassDef={"Name":"com.xxl.rpc.remoting.net.params.XxlRpcRequest","Fields":["requestId","createMillisTime","accessToken","className","methodName","version","parameterTypes","parameters"]} ------------------------------------------------------------- ------------- 0x60---------------- -ReadObjectCompact XxlRpcRequest ------------- 0x30---------------- -ReadMediumString requestId ------------- 0x4c---------------- -ReadLongFull createMillisTime ------------- 0x00---------------- -ReadShortString accessToken ------------- 0x1d---------------- -ReadShortString className ------------- 0x08---------------- -ReadShortString methodName ------------- 0x4e---------------- -ReadNull version ------------- 0x71---------------- -ReadCompactFixList parameterTypes ------------- 0x43---------------- -ReadClassDefinition java.lang.Class ------------- 0x61---------------- -ReadObjectCompact java.lang.Class ------------- 0x0e---------------- -ReadShortString name -Hessian.HessianObject=[{"Item1":"requestId","Item2":"e24123be4a76417ca6f41f227532b235"},{"Item1":"createMillisTime","Item2":1547819469003},{"Item1":"accessToken","Item2":""},{"Item1":"className","Item2":"com.xxl.job.core.biz.AdminBiz"},{"It -em1":"methodName","Item2":"callback"},{"Item1":"version","Item2":null},{"Item1":"parameterTypes","Item2":[{"Name":"java.lang.Class","Fields":["name"]}]},{"Item1":"parameters","Item2":[{"Item1":"name","Item2":"java.util.List"}]}] ------------------------------------------------------------- ------------- 0x71---------------- -ReadCompactFixList parameters ------------- 0x72---------------- -ReadCompactFixList List ------------- 0x43---------------- -ReadClassDefinition HandleCallbackParam ------------- 0x62---------------- -ReadObjectCompact HandleCallbackParam ------------- 0x9b---------------- -ReadIntegerSingleByte logId ------------- 0x4c---------------- -ReadLongFull logDateTim ------------- 0x43---------------- -ReadClassDefinition executeResult -System.Collections.Generic.List`1[System.Object]=[[{"Name":"com.xxl.job.core.biz.model.HandleCallbackParam","Fields":["logId","logDateTim","executeResult"]},[{"Item1":"logId","Item2":11},{"Item1":"logDateTim","Item2":1547819469000},{"Item1" -:"executeResult","Item2":{"Name":"com.xxl.job.core.biz.model.ReturnT","Fields":["code","msg","content"]}}]]] ------------------------------------------------------------- ------------- 0x63---------------- -ReadObjectCompact executeResult ------------- 0xc8---------------- -ReadIntegerTwoBytes code ------------- 0x03---------------- -ReadShortString msg ------------- 0x07---------------- -ReadShortString content -Hessian.HessianObject=[{"Item1":"code","Item2":200},{"Item1":"msg","Item2":"1bc"},{"Item1":"content","Item2":"acd3323"}] ------------------------------------------------------------- ------------- 0x62---------------- -ReadObjectCompact HandleCallbackParam ------------- 0xa6---------------- -ReadIntegerSingleByte logId ------------- 0x4c---------------- -ReadLongFull logDateTim ------------- 0x63---------------- -ReadObjectCompact executeResult ------------- 0xc9---------------- -ReadIntegerTwoBytes code ------------- 0x03---------------- -ReadShortString msg ------------- 0x03---------------- -ReadShortString content -Hessian.HessianObject=[{"Item1":"logId","Item2":22},{"Item1":"logDateTim","Item2":1547819469000},{"Item1":"executeResult","Item2":[{"Item1":"code","Item2":500},{"Item1":"msg","Item2":"cac"},{"Item1":"content","Item2":"aad"}]}] ------------------------------------------------------------- ------------------------------------------------------------- diff --git a/samples/HessianReader/NewFile2.txt b/samples/HessianReader/NewFile2.txt deleted file mode 100644 index 1e00d2b..0000000 --- a/samples/HessianReader/NewFile2.txt +++ /dev/null @@ -1,74 +0,0 @@ ---------------------------------------------------------------- ------------- 0x43---------------- -ReadClassDefinition -Hessian.ClassDef={"Name":"com.xxl.rpc.remoting.net.params.XxlRpcRequest","Fields":["requestId","createMillisTime","accessToken","className","methodName","version","parameterTypes","parameters"]} ------------------------------------------------------------- ------------- 0x60---------------- -ReadObjectCompact ------------- 0x30---------------- -ReadMediumString ------------- 0x4c---------------- -ReadLongFull ------------- 0x00---------------- -ReadShortString ------------- 0x1d---------------- -ReadShortString ------------- 0x08---------------- -ReadShortString ------------- 0x4e---------------- -ReadNull ------------- 0x71---------------- -ReadCompactFixList ------------- 0x43---------------- -ReadClassDefinition ------------- 0x61---------------- -ReadObjectCompact ------------- 0x0e---------------- -ReadShortString -Hessian.HessianObject=[{"Item1":"requestId","Item2":"e24123be4a76417ca6f41f227532b235"},{"Item1":"createMillisTime","Item2":1547819469003},{"Item1":"accessToken","Item2":""},{"Item1":"className","Item2":"com.xxl.job.core.biz.AdminBiz"},{"I -tem1":"methodName","Item2":"callback"},{"Item1":"version","Item2":null},{"Item1":"parameterTypes","Item2":[{"Name":"java.lang.Class","Fields":["name"]}]},{"Item1":"parameters","Item2":[{"Item1":"name","Item2":"java.util.List"}]}] ------------------------------------------------------------- ------------- 0x71---------------- -ReadCompactFixList ------------- 0x72---------------- -ReadCompactFixList ------------- 0x43---------------- -ReadClassDefinition ------------- 0x62---------------- -ReadObjectCompact ------------- 0x9b---------------- -ReadIntegerSingleByte ------------- 0x4c---------------- -ReadLongFull ------------- 0x43---------------- -ReadClassDefinition -System.Collections.Generic.List`1[System.Object]=[[{"Name":"com.xxl.job.core.biz.model.HandleCallbackParam","Fields":["logId","logDateTim","executeResult"]},[{"Item1":"logId","Item2":11},{"Item1":"logDateTim","Item2":1547819469000},{"Item1 -":"executeResult","Item2":{"Name":"com.xxl.job.core.biz.model.ReturnT","Fields":["code","msg","content"]}}]]] ------------------------------------------------------------- ------------- 0x63---------------- -ReadObjectCompact ------------- 0xc8---------------- -ReadIntegerTwoBytes ------------- 0x03---------------- -ReadShortString ------------- 0x07---------------- -ReadShortString -Hessian.HessianObject=[{"Item1":"code","Item2":200},{"Item1":"msg","Item2":"1bc"},{"Item1":"content","Item2":"acd3323"}] ------------------------------------------------------------- ------------- 0x62---------------- -ReadObjectCompact ------------- 0xa6---------------- -ReadIntegerSingleByte ------------- 0x4c---------------- -ReadLongFull ------------- 0x63---------------- -ReadObjectCompact ------------- 0xc9---------------- -ReadIntegerTwoBytes ------------- 0x03---------------- -ReadShortString ------------- 0x03---------------- -ReadShortString -Hessian.HessianObject=[{"Item1":"logId","Item2":22},{"Item1":"logDateTim","Item2":1547819469000},{"Item1":"executeResult","Item2":[{"Item1":"code","Item2":500},{"Item1":"msg","Item2":"aad"},{"Item1":"content","Item2":"cac"}]}] ------------------------------------------------------------- ------------------------------------------------------------- diff --git a/samples/HessianReader/Program.cs b/samples/HessianReader/Program.cs deleted file mode 100644 index f43d6fb..0000000 --- a/samples/HessianReader/Program.cs +++ /dev/null @@ -1,158 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using DotXxlJob.Core; -using DotXxlJob.Core.Model; -using Hessian; -using Newtonsoft.Json; - -namespace HessianReader -{ - class Program - { - static void Main(string[] args) - { - /* */ - byte[] myBinary = File.ReadAllBytes("run.dat"); - - - foreach (var i in myBinary) - { - Console.Write("0x"); - Console.Write(i.ToString("x2")); - Console.Write(","); - } - - - Console.WriteLine(Environment.NewLine); - Console.WriteLine("---------------------------------------------------------------"); - - /* - byte[] myBinary; - var callbackParamList = new List { - new HandleCallbackParam { - LogId = 11, - LogDateTime = 1547819469000L, - ExecuteResult =new ReturnT { Code = 200,Content ="acd3323",Msg ="1bc" } - }, - new HandleCallbackParam { - LogId = 22, - LogDateTime = 1547819469000L, - ExecuteResult =new ReturnT { Code = 500,Content ="cac",Msg ="aad" } - } - }; - - var request = new RpcRequest { - RequestId ="e24123be4a76417ca6f41f227532b235", - CreateMillisTime = 1547819469003L, - AccessToken = "", - ClassName = "com.xxl.job.core.biz.AdminBiz", - MethodName = "callback", - ParameterTypes = new List {new JavaClass {Name = "java.util.List"}}, - Parameters = new List {callbackParamList} - }; - - using (var stream = new MemoryStream()) - { - HessianSerializer.SerializeRequest(stream,request); - - myBinary = stream.ToArray(); - } - */ - using (var stream1 = new MemoryStream(myBinary)) - { - var s1 = HessianSerializer.DeserializeRequest(stream1); - Console.WriteLine("{0}={1}",s1.GetType(),JsonConvert.SerializeObject(s1)); - /* - var s = new Deserializer(stream1); - - - while ( s.CanRead()) - { - var o = s.ReadValue(); - Console.WriteLine("{0}={1}",o.GetType(),JsonConvert.SerializeObject(o)); - Console.WriteLine("------------------------------------------------------------"); - } - */ - - - } - - Console.WriteLine("------------------------------------------------------------"); - - Console.ReadKey(); - /** - * - * Console.WriteLine("---------------------------------------------------------------"); - RpcRequest req = new RpcRequest { - RequestId = "71565f61-94e8-4dcf-9760-f2fb73a6886a", - CreateMillisTime = 1547621183585, - AccessToken = "", - ClassName = "com.xxl.job.core.biz.ExecutorBiz", - MethodName = "run", - ParameterTypes = new List {new JavaClass{ Name = "com.xxl.job.core.biz.model.TriggerParam"}}, - Version = null, - Parameters = new List() - }; - - var p =new TriggerParam { - JobId=1, - ExecutorHandler="demoJobHandler", - ExecutorParams="111", - ExecutorBlockStrategy="SERIAL_EXECUTION", - ExecutorTimeout=0, - LogId=5, - LogDateTime=1547621183414L, - GlueType="BEAN", - GlueSource="", - GlueUpdateTime=1541254891000, - BroadcastIndex=0, - BroadcastTotal=1 - }; - req.Parameters.Add(p); - - using (var stream2 = new MemoryStream()) - { - var serializer = new Serializer(stream2); - serializer.WriteObject(req); - Console.WriteLine("-----------------------------序列化成功---{0}-------------------------------",stream2.Length); - stream2.Position = 0; - - var s2 = HessianSerializer.DeserializeRequest(stream2); - Console.WriteLine(JsonConvert.SerializeObject(s2)); - } - * [{"Item1":"requestId","Item2":"71565f61-94e8-4dcf-9760-f2fb73a6886a"},{"Item1":"createMillisTime","Item2":1432957289},{"Item1":"accessToken","Item2":""},{"Item1":"className","Item2":"com.xxl.job.core.biz.ExecutorBiz"},{"Item1":"methodName","Item2":"run"},{"Item1":"version","Item2":null},{"Item1":"parameterT -ypes","Item2":[{"Name":"java.lang.Class","Fields":["name"]}]},{"Item1":"parameters","Item2":[{"Item1":"name","Item2":"com.xxl.job.core.biz.model.TriggerParam"}]}] -System.Collections.Generic.List`1[System.Object] -[{"Name":"com.xxl.job.core.biz.model.TriggerParam","Fields":["jobId","executorHandler","executorParams","executorBlockStrategy","executorTimeout","logId","logDateTim","glueType","glueSource","glueUpdatetime","broadcastIndex","broadcastTotal"]}] - Hessian.HessianObject -[{"Item1":"jobId","Item2":1},{"Item1":"executorHandler","Item2":"demoJobHandler"},{"Item1":"executorParams","Item2":"111"},{"Item1":"executorBlockStrategy","Item2":"SERIAL_EXECUTION"},{"Item1":"executorTimeout","Item2":0},{"Item1":"logId","Item2":5},{"Item1":"logDateTim","Item2":1432956926},{"Item1":"glueTy -pe","Item2":"BEAN"},{"Item1":"glueSource","Item2":""},{"Item1":"glueUpdatetime","Item2":-638368258},{"Item1":"broadcastIndex","Item2":0},{"Item1":"broadcastTotal","Item2":1}] - - * requestId='71565f61-94e8-4dcf-9760-f2fb73a6886a', - * createMillisTime=1547621183585, - * accessToken='', - * className='com.xxl.job.core.biz.ExecutorBiz', - * methodName='run', - * parameterTypes=[class com.xxl.job.core.biz.model.TriggerParam], - * parameters=[ - * TriggerParam{ - * jobId=1, - * executorHandler='demoJobHandler', - * executorParams='111', - * executorBlockStrategy='SERIAL_EXECUTION', - * executorTimeout=0, - * logId=5, - * logDateTim=1547621183414, - * glueType='BEAN', - * glueSource='', - * glueUpdatetime=1541254891000, - * broadcastIndex=0, - * broadcastTotal=1 - * } - * ], version='null' - * - */ - } - } -} \ No newline at end of file diff --git a/samples/HessianReader/kill.dat b/samples/HessianReader/kill.dat deleted file mode 100644 index 54767e02b76f431ebadd6ecf10c24ea90f5f34d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 288 zcmZ9HzfQw29E5|YRJBOZM_^!$6)2?XO2mK!9jXk7F8pGjs8jz*Y_|%13Dm7KugO9R zf`RS38&2QlNzAQgZL658Idjl9Nb|}J0;|c9_Ux%u^P11mtl`6c;C|pQFkssxaDX6ie1lij&v+dX!;9VR^Vax1)H5_JOBUy diff --git a/samples/HessianReader/log.dat b/samples/HessianReader/log.dat deleted file mode 100644 index a1ad998e1cc46437b21765d13261aa86edbf7833..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 305 zcmZ9HJx;?w6oicuDRPh?N1&kf%8pTDS}Y1Ah(zQ9k%qVHhqGpX%)U)za*K$DhJub; zaRBasNQj`Io0($fn>>z$)vRq5bB$mQwe`|e%%EotIMBpyS~YFN6dxBz{v~ufaZwJ0 zL-2Sdm6B9Qjr$-35*79VO(+x)O+aH`qo3PyD|<_HB&|94X-1E(cxsUPf0pjzW6Xf_ zVG0q?Mj|>%Gl*b39!95el9cxeCh16A2EpF^_UrXCh>w2pYs;Ci4jGp#cHW{`cZ}}E2Kl~T0yJmw3U1d!L9cldaGxcVc*C_mM?<0JFTYm$;0&H~v diff --git a/samples/HessianReader/request.dat b/samples/HessianReader/request.dat deleted file mode 100644 index f3a08a5d39a8dd56dd55fe4190098932fb29942f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 528 zcmaKoOG*Pl5QZaBMk78hAc%Y0d6|Ga9Ty5JGR#8A#+sTkcG8ceyGKTEA#Mcso@K=A zcmOB9Kv6eMbwU00)tC62s3of^!OR$$A*mf#1E$EaF&L1RomC9aAwfvS$j!bqvCfoV?+H-%M z!Z-+{oMPy8kKRc%Aqg|754+ pN~5y7S!~$a(hfY-%8_zd*XVHGGSG&^m?u)-nD zYtrV|mU;j&@1PgU(5R9z0{oyiO?feEm)h0a>I{j9K9FReugcK_S3kemcdRGwv| zzPVuLn-iJN2u=86$?pwoGUnT~boU8LE=YMRe&1KWUD3Xfcrh}{hMZkJid@pNHXA}_ zF>l-Z*uLB1>rB+-@@zXWlC?te92{5N{xDYNrAh)v&?YW9HBU5=21L5>xLyBenJ#^G x_*8>CTmzrZe^6%>4dbJev* _logger; - private List _addresses; - private int _currentIndex; - - public AdminClient(IOptions optionsAccessor - , IHttpClientFactory clientFactory + private static readonly string MAPPING = "/api"; + public AdminClient(IOptions optionsAccessor , ILogger logger) { Preconditions.CheckNotNull(optionsAccessor?.Value, "XxlJobExecutorOptions"); - this._options = optionsAccessor?.Value; - this._clientFactory = clientFactory; + this._options = optionsAccessor?.Value; this._logger = logger; InitAddress(); } @@ -42,9 +39,8 @@ namespace DotXxlJob.Core foreach (var item in this._options.AdminAddresses.Split(';')) { try - { - var uri = new Uri(item + MAPPING); - var entry = new AddressEntry { RequestUri = uri }; + { + var entry = new AddressEntry { RequestUri = item+ MAPPING }; this._addresses.Add(entry); } catch (Exception ex) @@ -56,121 +52,58 @@ namespace DotXxlJob.Core public Task Callback(List callbackParamList) { - return InvokeRpcService("callback", new List { new JavaClass { Name = Constants.JavaListFulName } }, callbackParamList); + + return InvokeRpcService("callback", callbackParamList); } public Task Registry(RegistryParam registryParam) { - return InvokeRpcService("registry", new List { new JavaClass { Name = "com.xxl.job.core.biz.model.RegistryParam" } }, registryParam, true); + return InvokeRpcService("registry", registryParam); } public Task RegistryRemove(RegistryParam registryParam) { - return InvokeRpcService("registryRemove", new List { new JavaClass { Name = "com.xxl.job.core.biz.model.RegistryParam" } }, registryParam, true); + return InvokeRpcService("registryRemove", registryParam); } - private async Task InvokeRpcService(string methodName, List parameterTypes, - object parameters, bool polling = false) - { - var request = new RpcRequest { - RequestId = Guid.NewGuid().ToString("N"), - CreateMillisTime = DateTime.Now.GetTotalMilliseconds(), - AccessToken = _options.AccessToken, - ClassName = "com.xxl.job.core.biz.AdminBiz", - MethodName = methodName, - ParameterTypes = parameterTypes, - Parameters = new List { parameters } - }; - byte[] postBuf; - using (var stream = new MemoryStream()) - { - HessianSerializer.SerializeRequest(stream, request); - - postBuf = stream.ToArray(); - } + private async Task InvokeRpcService(string methodName, object jsonObject) + { var triedTimes = 0; - var retList = new List(); + ReturnT ret = null; - using (var client = this._clientFactory.CreateClient(Constants.DefaultHttpClientName)) + while (triedTimes++ < this._addresses.Count) { - while (triedTimes++ < this._addresses.Count) - { - var address = this._addresses[this._currentIndex]; - this._currentIndex = (this._currentIndex + 1) % this._addresses.Count; - if (!address.CheckAccessible()) - continue; - - Stream resStream; - try - { - resStream = await DoPost(client, address, postBuf); - address.Reset(); - } - catch (Exception ex) - { - this._logger.LogError(ex, "request admin error.{0}", ex.Message); - address.SetFail(); - continue; - } - - RpcResponse res = null; - try - { - /* - using (StreamReader reader = new StreamReader(resStream)) - { - string content = await reader.ReadToEndAsync(); - this._logger.LogWarning(content); - } - */ - res = HessianSerializer.DeserializeResponse(resStream); - } - catch (Exception ex) - { - this._logger.LogError(ex, "DeserializeResponse error:{errorMessage}", ex.Message); - } + var address = this._addresses[this._currentIndex]; + this._currentIndex = (this._currentIndex + 1) % this._addresses.Count; + if (!address.CheckAccessible()) + continue; + try + { - if (res == null) - { - retList.Add(ReturnT.Failed("response is null")); - } - else if (res.IsError) - { - retList.Add(ReturnT.Failed(res.ErrorMsg)); - } - else if (res.Result is ReturnT ret) - { - retList.Add(ret); - } - else - { - retList.Add(ReturnT.Failed("response is null")); - } + var json = await address.RequestUri.AppendPathSegment(methodName) + .WithHeader("XXL-JOB-ACCESS-TOKEN", this._options.AccessToken) + .PostJsonAsync(jsonObject) + .ReceiveString(); - if (!polling) - { - return retList[0]; - } + //.ReceiveJson(); + ret = JsonConvert.DeserializeObject(json); + address.Reset(); } - - if (retList.Count > 0) + catch (Exception ex) { - return retList.Last(); + this._logger.LogError(ex, "request admin error.{0}", ex.Message); + address.SetFail(); + continue; } + } + if(ret == null) + { + ret = ReturnT.Failed("call admin fail"); } - throw new Exception("xxl-rpc server address not accessible."); + return ret; } - private async Task DoPost(HttpClient client, AddressEntry address, byte[] postBuf) - { - var content = new ByteArrayContent(postBuf); - content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); - var responseMessage = await client.PostAsync(address.RequestUri, content); - - responseMessage.EnsureSuccessStatusCode(); - return await responseMessage.Content.ReadAsStreamAsync(); - } } } \ No newline at end of file diff --git a/src/DotXxlJob.Core/DotXxlJob.Core.csproj b/src/DotXxlJob.Core/DotXxlJob.Core.csproj index 4ebc340..4ff9f03 100644 --- a/src/DotXxlJob.Core/DotXxlJob.Core.csproj +++ b/src/DotXxlJob.Core/DotXxlJob.Core.csproj @@ -23,14 +23,12 @@ - - - + + + + + - - - - diff --git a/src/DotXxlJob.Core/ExecutorRegistry.cs b/src/DotXxlJob.Core/ExecutorRegistry.cs index 84398cd..399a736 100644 --- a/src/DotXxlJob.Core/ExecutorRegistry.cs +++ b/src/DotXxlJob.Core/ExecutorRegistry.cs @@ -35,7 +35,7 @@ namespace DotXxlJob.Core var registryParam = new RegistryParam { RegistryGroup = "EXECUTOR", RegistryKey = _options.AppName, - RegistryValue = $"{_options.SpecialBindAddress}:{_options.Port}" + RegistryValue = $"http://{_options.SpecialBindAddress}:{_options.Port}/" }; _logger.LogInformation(">>>>>>>> start registry to admin <<<<<<<<"); diff --git a/src/Hessian/DateTimeExtension.cs b/src/DotXxlJob.Core/Extensions/DateTimeExtension.cs similarity index 89% rename from src/Hessian/DateTimeExtension.cs rename to src/DotXxlJob.Core/Extensions/DateTimeExtension.cs index 7a7800b..0f348fc 100644 --- a/src/Hessian/DateTimeExtension.cs +++ b/src/DotXxlJob.Core/Extensions/DateTimeExtension.cs @@ -1,10 +1,9 @@ using System; +using System.Collections.Generic; +using System.Text; -namespace Hessian +namespace DotXxlJob.Core.Extensions { - /// - /// - /// public static class DateTimeExtension { private const long Era = 62135596800000L; @@ -17,7 +16,7 @@ namespace Hessian /// public static long GetTotalMilliseconds(this DateTime dt) { - return dt.ToUniversalTime().Ticks / 10000 - Era; + return dt.ToUniversalTime().Ticks / 10000 - Era; } /// diff --git a/src/DotXxlJob.Core/Extensions/ServiceCollectionExtensions.cs b/src/DotXxlJob.Core/Extensions/ServiceCollectionExtensions.cs index fc1ab7e..cff4966 100644 --- a/src/DotXxlJob.Core/Extensions/ServiceCollectionExtensions.cs +++ b/src/DotXxlJob.Core/Extensions/ServiceCollectionExtensions.cs @@ -51,7 +51,7 @@ namespace DotXxlJob.Core services.AddHttpClient("DotXxlJobClient"); services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/src/DotXxlJob.Core/Internal/HessianObjectConvert.cs b/src/DotXxlJob.Core/Internal/HessianObjectConvert.cs deleted file mode 100644 index cb3712c..0000000 --- a/src/DotXxlJob.Core/Internal/HessianObjectConvert.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; -using System.Runtime.Serialization; -using DotXxlJob.Core.Model; -using Hessian; - -namespace DotXxlJob.Core -{ - public class HessianObjectHelper - { - - private static readonly Dictionary> TransferObjCache - = new Dictionary>(); - private static readonly Dictionary TransferTypeCache - = new Dictionary(); - static HessianObjectHelper() - { - - InitProperties(typeof(RpcRequest)); - - InitProperties(typeof(TriggerParam)); - - InitProperties(typeof(RpcResponse)); - - InitProperties(typeof(ReturnT)); - - InitProperties(typeof(HandleCallbackParam)); - - InitProperties(typeof(JavaClass)); - - InitProperties(typeof(RegistryParam)); - - InitProperties(typeof(LogResult)); - } - private static void InitProperties(Type type) - { - var propertyInfos = new Dictionary(); - var typeInfo = type.GetTypeInfo(); - var classAttr = type.GetCustomAttribute(); - if (classAttr == null) - { - return; - } - - foreach (var property in typeInfo.DeclaredProperties) - { - var attribute = property.GetCustomAttribute(); - - if (null == attribute) - { - continue; - } - - if (!property.CanRead || !property.CanWrite) - { - continue; - } - - propertyInfos.Add(attribute.Name,property); - } - TransferTypeCache.Add(classAttr.Name,type); - TransferObjCache.Add(classAttr.Name,propertyInfos); - } - - public static object GetRealObjectValue(Deserializer deserializer,object value) - { - if (value == null || IsSimpleType(value.GetType())) - { - return value; - } - - if (value is HessianObject hessianObject) - { - if(TransferObjCache.TryGetValue(hessianObject.TypeName,out var properties)) - { - var instance = Activator.CreateInstance(TransferTypeCache[hessianObject.TypeName]); - foreach (var (k, v) in hessianObject) - { - if (properties.TryGetValue(k, out var p)) - { - p.SetValue(instance,GetRealObjectValue(deserializer,v)); - } - } - - return instance; - } - } - - if (value is ClassDef) - { - return GetRealObjectValue(deserializer, deserializer.ReadValue()); - } - - if (IsListType(value.GetType())) - { - var listData = new List(); - - var cList = value as List; - foreach (var cItem in cList) - { - listData.Add(GetRealObjectValue(deserializer,cItem)); - } - - return listData; - } - - throw new HessianException($"unknown item:{value.GetType()}"); - } - - private static bool IsListType(Type type) - { - return typeof(ICollection).IsAssignableFrom(type); - } - private static bool IsSimpleType(Type typeInfo) - { - if (typeInfo.IsValueType || typeInfo.IsEnum || typeInfo.IsPrimitive) - { - return true; - } - - if (typeof (string) == typeInfo) - { - return true; - } - - return false; - } - - } -} \ No newline at end of file diff --git a/src/DotXxlJob.Core/Internal/HessianSerializer.cs b/src/DotXxlJob.Core/Internal/HessianSerializer.cs deleted file mode 100644 index 14bcd67..0000000 --- a/src/DotXxlJob.Core/Internal/HessianSerializer.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using System.IO; -using DotXxlJob.Core.Model; -using Hessian; - -namespace DotXxlJob.Core -{ - public static class HessianSerializer - { - - public static RpcRequest DeserializeRequest(Stream stream) - { - RpcRequest request = null; - - try - { - var deserializer = new Deserializer(stream); - var classDef = deserializer.ReadValue() as ClassDef; - if (!Constants.RpcRequestJavaFullName.Equals(classDef.Name)) - { - throw new HessianException($"unknown class :{classDef.Name}"); - } - request = HessianObjectHelper.GetRealObjectValue(deserializer,deserializer.ReadValue()) as RpcRequest; - } - catch (EndOfStreamException) - { - //没有数据可读了 - } - return request; - - } - - - public static void SerializeRequest(Stream stream,RpcRequest req) - { - var serializer = new Serializer(stream); - serializer.WriteObject(req); - } - - public static void SerializeResponse(Stream stream,RpcResponse res) - { - var serializer = new Serializer(stream); - serializer.WriteObject(res); - } - - - public static RpcResponse DeserializeResponse(Stream resStream) - { - RpcResponse rsp = null; - - try - { - var deserializer = new Deserializer(resStream); - var classDef = deserializer.ReadValue() as ClassDef; - if (!Constants.RpcResponseJavaFullName.Equals(classDef.Name)) - { - throw new HessianException($"unknown class :{classDef.Name}"); - } - - rsp = HessianObjectHelper.GetRealObjectValue(deserializer,deserializer.ReadValue()) as RpcResponse; - - } - catch (EndOfStreamException) - { - //没有数据可读了 - } - catch - { - //TODO: do something? - } - - return rsp; - } - - - } - - -} \ No newline at end of file diff --git a/src/DotXxlJob.Core/Logger/JobLogger.cs b/src/DotXxlJob.Core/Logger/JobLogger.cs index c0f964b..847efb3 100644 --- a/src/DotXxlJob.Core/Logger/JobLogger.cs +++ b/src/DotXxlJob.Core/Logger/JobLogger.cs @@ -5,8 +5,8 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using DotXxlJob.Core.Config; +using DotXxlJob.Core.Extensions; using DotXxlJob.Core.Model; -using Hessian; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; diff --git a/src/DotXxlJob.Core/Model/AddressEntity.cs b/src/DotXxlJob.Core/Model/AddressEntity.cs index 098881e..8ab2b3d 100644 --- a/src/DotXxlJob.Core/Model/AddressEntity.cs +++ b/src/DotXxlJob.Core/Model/AddressEntity.cs @@ -4,7 +4,7 @@ namespace DotXxlJob.Core.Model { public class AddressEntry { - public Uri RequestUri { get; set; } + public string RequestUri { get; set; } private DateTime? LastFailedTime { get; set; } diff --git a/src/DotXxlJob.Core/Model/IdleBeatRequest.cs b/src/DotXxlJob.Core/Model/IdleBeatRequest.cs new file mode 100644 index 0000000..9846b82 --- /dev/null +++ b/src/DotXxlJob.Core/Model/IdleBeatRequest.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Text; + +namespace DotXxlJob.Core.Model +{ + [DataContract] + public class IdleBeatRequest + { + + [DataMember(Name = "jobId", Order = 1)] + public int JobId { get; set; } + } +} diff --git a/src/DotXxlJob.Core/Model/KillRequest.cs b/src/DotXxlJob.Core/Model/KillRequest.cs new file mode 100644 index 0000000..e0f1209 --- /dev/null +++ b/src/DotXxlJob.Core/Model/KillRequest.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Text; + +namespace DotXxlJob.Core.Model +{ + + [DataContract] + public class KillRequest + { + + [DataMember(Name = "jobId", Order = 1)] + public int JobId { get; set; } + } +} diff --git a/src/DotXxlJob.Core/Model/LogRequest.cs b/src/DotXxlJob.Core/Model/LogRequest.cs new file mode 100644 index 0000000..75ce611 --- /dev/null +++ b/src/DotXxlJob.Core/Model/LogRequest.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Text; + +namespace DotXxlJob.Core.Model +{ + [DataContract] + public class LogRequest + { + [DataMember(Name = "logDateTim", Order =1)] + public long LogDateTime { get; set; } + + [DataMember(Name = "logId", Order = 2)] + public int LogId { get; set; } + + [DataMember(Name = "fromLineNum", Order = 3)] + public int FromLineNum { get; set; } + + } +} diff --git a/src/DotXxlJob.Core/Model/RegistryParam.cs b/src/DotXxlJob.Core/Model/RegistryParam.cs index 93925cd..fa18bca 100644 --- a/src/DotXxlJob.Core/Model/RegistryParam.cs +++ b/src/DotXxlJob.Core/Model/RegistryParam.cs @@ -5,14 +5,14 @@ namespace DotXxlJob.Core.Model [DataContract(Name = Constants.RegistryParamJavaFullName)] public class RegistryParam { - [DataMember(Name = "registGroup",Order = 1)] + [DataMember(Name = "registryGroup", Order = 1)] public string RegistryGroup { get; set; } - [DataMember(Name = "registryKey",Order = 2)] + [DataMember(Name = "registryKey", Order = 2)] public string RegistryKey { get; set; } - [DataMember(Name = "registryValue",Order = 3)] + [DataMember(Name = "registryValue", Order = 3)] public string RegistryValue { get; set; } } diff --git a/src/DotXxlJob.Core/Model/TriggerParam.cs b/src/DotXxlJob.Core/Model/TriggerParam.cs index fe571f9..2157a71 100644 --- a/src/DotXxlJob.Core/Model/TriggerParam.cs +++ b/src/DotXxlJob.Core/Model/TriggerParam.cs @@ -3,28 +3,28 @@ using System.Runtime.Serialization; namespace DotXxlJob.Core.Model { - [DataContract(Name = Constants.TriggerParamJavaFullName)] + [DataContract] public class TriggerParam { //static readonly long SerialVersionUID = 42L; - [DataMember(Name = "jobId",Order = 1)] + [DataMember(Name = "jobId", Order = 1)] public int JobId { get; set; } - [DataMember(Name = "executorHandler",Order = 2)] + [DataMember(Name = "executorHandler", Order = 2)] public string ExecutorHandler { get; set; } - [DataMember(Name = "executorParams",Order = 3)] + [DataMember(Name = "executorParams", Order = 3)] public string ExecutorParams{ get; set; } - [DataMember(Name = "executorBlockStrategy",Order = 4)] + [DataMember(Name = "executorBlockStrategy", Order = 4)] public string ExecutorBlockStrategy{ get; set; } - [DataMember(Name = "executorTimeout",Order = 5)] + [DataMember(Name = "executorTimeout", Order = 5)] public int ExecutorTimeout{ get; set; } [DataMember(Name = "logId",Order = 5)] public int LogId{ get; set; } - [DataMember(Name = "logDateTim",Order = 6)] + [DataMember(Name = "logDateTime", Order = 6)] public long LogDateTime{ get; set; } @@ -34,7 +34,7 @@ namespace DotXxlJob.Core.Model [DataMember(Name = "glueSource",Order = 8)] public string GlueSource{ get; set; } - [DataMember(Name = "glueUpdatetime",Order = 9)] + [DataMember(Name = "glueUpdatetime", Order = 9)] public long GlueUpdateTime{ get; set; } [DataMember(Name = "broadcastIndex",Order = 10)] diff --git a/src/DotXxlJob.Core/XxlRestfulServiceHandler.cs b/src/DotXxlJob.Core/XxlRestfulServiceHandler.cs new file mode 100644 index 0000000..4615549 --- /dev/null +++ b/src/DotXxlJob.Core/XxlRestfulServiceHandler.cs @@ -0,0 +1,166 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net.Cache; +using System.Text; +using System.Threading.Tasks; +using DotXxlJob.Core.Config; +using DotXxlJob.Core.Model; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Newtonsoft.Json; + +namespace DotXxlJob.Core +{ + public class XxlRestfulServiceHandler + { + private readonly JobDispatcher _jobDispatcher; + private readonly IJobLogger _jobLogger; + private readonly ILogger _logger; + private readonly XxlJobExecutorOptions _options; + + public XxlRestfulServiceHandler(IOptions optionsAccessor, + JobDispatcher jobDispatcher, + IJobLogger jobLogger, + ILogger logger) + { + + this._jobDispatcher = jobDispatcher; + this._jobLogger = jobLogger; + this._logger = logger; + + this._options = optionsAccessor.Value; + if (this._options == null) + { + throw new ArgumentNullException(nameof(XxlJobExecutorOptions)); + } + + } + + public async Task HandlerAsync(HttpRequest request,HttpResponse response) + { + + + var path = request.Path.Value ; + + ReturnT ret = null; + var arrParts = path.Split('/'); + var method = arrParts[arrParts.Length - 1].ToLower(); + + if (!string.IsNullOrEmpty(this._options.AccessToken)) + { + var reqToken = ""; + if (request.Headers.TryGetValue("XXL-JOB-ACCESS-TOKEN", out var tokenValues)) + { + reqToken = tokenValues[0].ToString(); + } + if(this._options.AccessToken != reqToken) + { + ret = ReturnT.Failed("ACCESS-TOKEN Auth Fail"); + response.ContentType = "application/json;charset=utf-8"; + await response.WriteAsync(JsonConvert.SerializeObject(ret)); + return; + } + } + try + { + string json = CollectBody(request.Body); + switch (method) + { + case "beat": + ret = Beat(); + break; + case "idleBeat": + ret = IdleBeat(JsonConvert.DeserializeObject(json)); + break; + case "run": + ret = Run(JsonConvert.DeserializeObject(json)); + break; + case "kill": + ret = Kill(JsonConvert.DeserializeObject(json)); + break; + case "log": + ret = Log(JsonConvert.DeserializeObject(json)); + break; + } + } + catch(Exception ex) + { + this._logger.LogError(ex,"响应出错"+ ex.Message); + ret = ReturnT.Failed("执行器内部错误"); + } + + + if(ret == null) + { + ret = ReturnT.Failed($"method {method} is not impl"); + } + response.ContentType = "application/json;charset=utf-8"; + await response.WriteAsync(JsonConvert.SerializeObject(ret)); + } + private string CollectBody(Stream body) + { + string bodyText; + using (var reader = new StreamReader(body)) + { + bodyText = reader.ReadToEnd(); + } + return bodyText; + } + + #region rpc service + + private ReturnT Beat() + { + return ReturnT.SUCCESS; + } + + private ReturnT IdleBeat(IdleBeatRequest req) + { + if(req == null) + { + return ReturnT.Failed("IdleBeat Error"); + } + return this._jobDispatcher.IdleBeat(req.JobId); + } + + private ReturnT Kill(KillRequest req) + { + if (req == null) + { + return ReturnT.Failed("Kill Error"); + } + return this._jobDispatcher.TryRemoveJobTask(req.JobId) ? + ReturnT.SUCCESS + : + ReturnT.Success("job thread already killed."); + } + + /// + /// read Log + /// + /// + private ReturnT Log(LogRequest req) + { + if (req == null) + { + return ReturnT.Failed("Log Error"); + } + var ret = ReturnT.Success(null); + ret.Content = this._jobLogger.ReadLog(req.LogDateTime,req.LogId, req.FromLineNum); + return ret; + } + + /// + /// 执行 + /// + /// + /// + private ReturnT Run(TriggerParam triggerParam) + { + return this._jobDispatcher.Execute(triggerParam); + } + #endregion + } +} diff --git a/src/DotXxlJob.Core/XxlRpcServiceHandler.cs b/src/DotXxlJob.Core/XxlRpcServiceHandler.cs deleted file mode 100644 index 0825155..0000000 --- a/src/DotXxlJob.Core/XxlRpcServiceHandler.cs +++ /dev/null @@ -1,217 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Threading.Tasks; -using Hessian; -using DotXxlJob.Core.Config; -using DotXxlJob.Core.Model; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; - -namespace DotXxlJob.Core -{ - - /// - /// 负责执行Http请求,序列化和反序列化并发送响应 - /// - public class XxlRpcServiceHandler - { - - private readonly JobDispatcher _jobDispatcher; - private readonly IJobLogger _jobLogger; - private readonly ILogger _logger; - private readonly XxlJobExecutorOptions _options; - - private readonly ConcurrentDictionary METHOD_CACHE = - new ConcurrentDictionary(); - - public XxlRpcServiceHandler(IOptions optionsAccessor, - JobDispatcher jobDispatcher, - IJobLogger jobLogger, - ILogger logger) - { - - this._jobDispatcher = jobDispatcher; - this._jobLogger = jobLogger; - this._logger = logger; - - this._options = optionsAccessor.Value; - if (this._options == null) - { - throw new ArgumentNullException(nameof(XxlJobExecutorOptions)); - } - - } - - /// - /// 处理XxlRpc请求流 - /// - /// - /// - public async Task HandlerAsync(Stream reqStream) - { - var req = HessianSerializer.DeserializeRequest(reqStream); - - var res = new RpcResponse { RequestId = req.RequestId}; - - if (!ValidRequest(req, out var error)) - { - this._logger.LogWarning("job task request is not valid:{error}",error); - res.ErrorMsg = error; - } - else - { - this._logger.LogDebug("receive job task ,req.RequestId={requestId},method={methodName}" - ,req.RequestId,req.MethodName); - await Invoke(req, res); - this._logger.LogDebug("completed receive job task ,req.RequestId={requestId},method={methodName},IsError={IsError}" - ,req.RequestId,req.MethodName,res.IsError); - } - - using (var outputStream = new MemoryStream()) - { - HessianSerializer.SerializeResponse(outputStream,res); - return outputStream.GetBuffer(); - } - - } - - /// - /// 校验请求信息 - /// - /// - /// - /// - private bool ValidRequest(RpcRequest req,out string error) - { - error = string.Empty; - if (req == null) - { - error = "unknown request stream data,codec fail"; - return false; - } - - if (!"com.xxl.job.core.biz.ExecutorBiz".Equals(req.ClassName)) // - { - error = "not supported request!"; - return false; - } - - if (DateTime.UtcNow.Subtract(req.CreateMillisTime.FromMilliseconds()) > Constants.RpcRequestExpireTimeSpan) - { - error = "request is timeout!"; - return false; - } - - if (!string.IsNullOrEmpty(this._options.AccessToken) && this._options.AccessToken != req.AccessToken) - { - error = "need authorize"; - return false; - } - - return true; - } - - /// - /// 执行请求,获取执行函数 - /// - /// - /// - /// - private Task Invoke(RpcRequest req, RpcResponse res) - { - try - { - var method = GetMethodInfo(req.MethodName); - if (method == null) - { - res.ErrorMsg = $"The method{req.MethodName} is not defined."; - this._logger.LogWarning( $"The method{req.MethodName} is not defined."); - } - else - { - var result = method.Invoke(this, req.Parameters.ToArray()); - - res.Result = result; - } - - } - catch (Exception ex) - { - res.ErrorMsg = ex.Message +"\n--------------\n"+ ex.StackTrace; - this._logger.LogError(ex,"invoke method error:{0}",ex.Message); - } - - return Task.CompletedTask; - - } - - private MethodInfo GetMethodInfo(string methodName) - { - if (METHOD_CACHE.TryGetValue(methodName, out var method)) - { - return method; - } - - var type = GetType(); - method = type.GetMethod( methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.IgnoreCase); - if (method != null) - { - METHOD_CACHE.TryAdd(methodName, method); - } - - return method; - } - - - #region rpc service - - private ReturnT Beat() - { - return ReturnT.SUCCESS; - } - - private ReturnT IdleBeat(int jobId) - { - return this._jobDispatcher.IdleBeat(jobId); - } - - private ReturnT Kill(int jobId) - { - return this._jobDispatcher.TryRemoveJobTask(jobId) ? - ReturnT.SUCCESS - : - ReturnT.Success("job thread already killed."); - } - - /// - /// read Log - /// - /// - /// - /// - /// - private ReturnT Log(long logDateTime, int logId, int fromLineNum) - { - var ret = ReturnT.Success(null); - ret.Content = this._jobLogger.ReadLog(logDateTime, logId, fromLineNum); - return ret; - } - - /// - /// 执行 - /// - /// - /// - private ReturnT Run(TriggerParam triggerParam) - { - return this._jobDispatcher.Execute(triggerParam); - } - #endregion - - - - } -} \ No newline at end of file diff --git a/src/Hessian/ClassDef.cs b/src/Hessian/ClassDef.cs deleted file mode 100644 index 1f00132..0000000 --- a/src/Hessian/ClassDef.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; - -namespace Hessian -{ - public class ClassDef : IEquatable - { - public string Name { get; private set; } - public string[] Fields { get; private set; } - - public ClassDef(string name, string[] fields) - { - Name = Conditions.CheckNotNull(name, "name"); - Fields = Conditions.CheckNotNull(fields, "fields"); - } - - public override int GetHashCode() - { - unchecked { - const uint prime = 16777619; - var hash = 2166136261; - - hash *= prime; - hash ^= (uint)Name.GetHashCode(); - - for (var i = 0; i < Fields.Length; ++i) { - hash *= prime; - hash ^= (uint)Fields[i].GetHashCode(); - } - - return (int)hash; - } - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) { - return false; - } - if (ReferenceEquals(this, obj)) { - return true; - } - if (obj.GetType() != GetType()) { - return false; - } - return Equals((ClassDef) obj); - } - - public bool Equals(ClassDef other) - { - if (ReferenceEquals(null, other)) { - return false; - } - if (ReferenceEquals(this, other)) { - return true; - } - return string.Equals(Name, other.Name) && Fields.Equals(other.Fields); - } - } -} diff --git a/src/Hessian/ClassElement.cs b/src/Hessian/ClassElement.cs deleted file mode 100644 index 9bac0b4..0000000 --- a/src/Hessian/ClassElement.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; - -namespace Hessian -{ - public class ClassElement - { - public string ClassName { get; set; } - - public List Fields { get; set; } - } -} \ No newline at end of file diff --git a/src/Hessian/Collections/ForwardingDictionary.cs b/src/Hessian/Collections/ForwardingDictionary.cs deleted file mode 100644 index 6b2d62e..0000000 --- a/src/Hessian/Collections/ForwardingDictionary.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System.Collections; -using System.Collections.Generic; - -namespace Hessian.Collections -{ - public abstract class ForwardingDictionary : IDictionary - { - protected abstract IDictionary Delegate { get; } - - public virtual ICollection Keys - { - get { return Delegate.Keys; } - } - - public virtual ICollection Values - { - get { return Delegate.Values; } - } - - public virtual IEnumerator> GetEnumerator() - { - return Delegate.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public virtual void Add(KeyValuePair item) - { - Delegate.Add(item); - } - - public virtual void Clear() - { - Delegate.Clear(); - } - - public virtual bool Contains(KeyValuePair item) - { - return Delegate.Contains(item); - } - - public virtual void CopyTo(KeyValuePair[] array, int arrayIndex) - { - Delegate.CopyTo(array, arrayIndex); - } - - public virtual bool Remove(KeyValuePair item) - { - return Delegate.Remove(item); - } - - public virtual int Count - { - get { return Delegate.Count; } - } - - public virtual bool IsReadOnly - { - get { return Delegate.IsReadOnly; } - } - - public virtual bool ContainsKey(TKey key) - { - return Delegate.ContainsKey(key); - } - - public virtual void Add(TKey key, TValue value) - { - Delegate.Add(key, value); - } - - public virtual bool Remove(TKey key) - { - return Delegate.Remove(key); - } - - public virtual bool TryGetValue(TKey key, out TValue value) - { - return Delegate.TryGetValue(key, out value); - } - - public virtual TValue this[TKey key] - { - get { return Delegate[key]; } - set { Delegate[key] = value; } - } - } -} diff --git a/src/Hessian/Collections/IRefMap.cs b/src/Hessian/Collections/IRefMap.cs deleted file mode 100644 index 5bf3f5e..0000000 --- a/src/Hessian/Collections/IRefMap.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace Hessian.Collections -{ - /// - /// Represents a map that associates objects with a zero-based integer - /// index. Specified in Hessian 2.0. - /// - /// - public interface IRefMap - { - /// - /// Adds an element to the ref map and returns its ID. - /// - /// - /// - int Add(T entry); - - /// - /// Retrieves the element identified by the given ID. - /// - /// - /// - T Get(int refId); - - /// - /// Looks up an element in the ref map and, if present, returns its ID. - /// - /// - /// Performance of this method is not guaranteed and is implementation-specific. - /// - int? Lookup(T entry); - } -} diff --git a/src/Hessian/Collections/ITwoWayDictionary.cs b/src/Hessian/Collections/ITwoWayDictionary.cs deleted file mode 100644 index 1da8ce5..0000000 --- a/src/Hessian/Collections/ITwoWayDictionary.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Collections.Generic; - -namespace Hessian.Collections -{ - /// - /// Represents a dictionary which maintains uniqueness of both keys and values, - /// allowing for the lookup of a key by its value in additon to the normal - /// operations expected of a dictionary. - /// - public interface ITwoWayDictionary : IDictionary - { - /// - /// Exposes a view of the current dictionary that reverses keys and - /// values. Note that the same underlying data is shared. - /// - ITwoWayDictionary Inverse { get; } - - /// - /// Gets or sets a key by the given value. - /// - /// - /// The value with which to get or set a key. - /// - /// - /// Returns the key indexing the given . - /// - TKey this[TValue valueKey] { get; set; } - - /// - /// Gets a value indicating whether the given - /// is contained in this dictionary. - /// - /// - /// The value whose presence is to be determined. - /// - /// - /// Returns if is in - /// this dictionary, and otherwise. - /// - bool ContainsValue(TValue value); - - /// - /// Attempts to look up a key by the given value. A return value - /// indicates whether the lookip is successful. - /// - /// - /// The value whose corresponding key is to be retrieved. - /// - /// - /// When the method returns, contains the looked-up key if the lookup - /// succeeded. - /// - /// - /// Returns if the lookup succeeded, and - /// otherwise. - /// - bool TryGetKey(TValue value, out TKey key); - } -} diff --git a/src/Hessian/Collections/ListRefMap.cs b/src/Hessian/Collections/ListRefMap.cs deleted file mode 100644 index 37369d5..0000000 --- a/src/Hessian/Collections/ListRefMap.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Collections.Generic; - -namespace Hessian.Collections -{ - public class ListRefMap : IRefMap - { - private readonly List list = new List(); - - public int Add(T entry) - { - list.Add(entry); - return list.Count - 1; - } - - public T Get(int refId) - { - if (refId < 0 || refId >= list.Count) { - throw new InvalidRefException(refId); - } - return list[refId]; - } - - public int? Lookup(T entry) - { - for (var i = 0; i < list.Count; ++i) { - if (entry.Equals(list[i])) { - return i; - } - } - - return null; - } - } -} diff --git a/src/Hessian/Collections/TwoWayDictionary.cs b/src/Hessian/Collections/TwoWayDictionary.cs deleted file mode 100644 index 1b0500d..0000000 --- a/src/Hessian/Collections/TwoWayDictionary.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System.Collections.Generic; - -namespace Hessian.Collections -{ - public class TwoWayDictionary : ForwardingDictionary, ITwoWayDictionary - { - private readonly IDictionary dict; - private readonly TwoWayDictionary inverse; - - protected override IDictionary Delegate { - get { return dict; } - } - - public override bool IsReadOnly { - get { return false; } - } - - public ITwoWayDictionary Inverse { - get { return inverse; } - } - - public override TValue this[TKey key] { - set { UpdateDictAndInverse(key, value, false); } - } - - public TKey this[TValue valueKey] { - get { return inverse[valueKey]; } - set { inverse[valueKey] = value; } - } - - public override ICollection Values { - get { return inverse.dict.Keys; } - } - - public TwoWayDictionary() - : this(new Dictionary(), new Dictionary()) - { - } - - public TwoWayDictionary(IDictionary forwards, IDictionary backwards) - { - dict = Conditions.CheckNotNull(forwards, "forwards"); - inverse = new TwoWayDictionary(backwards, this); - } - - private TwoWayDictionary(IDictionary dict, TwoWayDictionary inverse) - { - this.dict = Conditions.CheckNotNull(dict, "dict"); - this.inverse = inverse; - } - - public bool ContainsValue(TValue value) - { - return inverse.ContainsKey(value); - } - - public bool TryGetKey(TValue value, out TKey key) - { - return inverse.TryGetValue(value, out key); - } - - public override void Add(TKey key, TValue value) - { - UpdateDictAndInverse(key, value, true); - } - - public override bool Remove(TKey key) - { - return RemoveFromDictAndInverse(key); - } - - private void UpdateDictAndInverse(TKey key, TValue value, bool throwIfContained) - { - if (!throwIfContained) { - dict.Remove(key); - inverse.dict.Remove(value); - } - - dict.Add(key, value); - inverse.dict.Add(value, key); - } - - private bool RemoveFromDictAndInverse(TKey key) - { - TValue value; - if (!TryGetValue(key, out value)) { - return false; - } - - return RemoveFromDictAndInverse(key, value); - } - - private bool RemoveFromDictAndInverse(TKey key, TValue value) - { - if (!ContainsKey(key) || !ContainsValue(value)) { - return false; - } - - return dict.Remove(key) && inverse.dict.Remove(value); - } - - #region ICollection> - - - public override bool Remove(KeyValuePair kvp) - { - return RemoveFromDictAndInverse(kvp.Key, kvp.Value); - } - - public override void Clear() - { - dict.Clear(); - inverse.dict.Clear(); - } - - public override bool Contains(KeyValuePair kvp) - { - return ContainsKey(kvp.Key) && ContainsValue(kvp.Value); - } - - #endregion - } -} diff --git a/src/Hessian/Collections/TwoWayDictionaryRefMap.cs b/src/Hessian/Collections/TwoWayDictionaryRefMap.cs deleted file mode 100644 index f899219..0000000 --- a/src/Hessian/Collections/TwoWayDictionaryRefMap.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace Hessian.Collections -{ - public class TwoWayDictionaryRefMap : IRefMap - { - private readonly TwoWayDictionary map = new TwoWayDictionary(); - - public int Add(T value) - { - var refid = map.Count; - map.Add(value, refid); - return refid; - } - - public T Get(int refid) - { - T entry; - if (map.TryGetKey(refid, out entry)) { - return entry; - } - - throw new InvalidRefException(refid); - } - - public int? Lookup(T entry) - { - int refId; - if (map.TryGetValue(entry, out refId)) { - return refId; - } - - return null; - } - } -} diff --git a/src/Hessian/Conditions.cs b/src/Hessian/Conditions.cs deleted file mode 100644 index 22cffc7..0000000 --- a/src/Hessian/Conditions.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System; - -namespace Hessian -{ - public class Conditions - { - protected Conditions() - { - } - - public static void CheckArgument(bool condition, string message, params object[] args) - { - if (condition) { - return; - } - - if (args.Length > 0) { - message = String.Format(message, args); - } - - throw new ArgumentException(message); - } - - public static T CheckNotNull(T value, string name) - where T : class - { - if (!ReferenceEquals(value, null)) { - return value; - } - - throw new ArgumentNullException(name); - } - - public static TComparable CheckGreater(TComparable value, TComparand bounds, - string name) - where TComparable : IComparable - { - if (value.CompareTo(bounds) > 0) { - return value; - } - - throw new ArgumentOutOfRangeException(name); - } - - public static TComparable CheckLess(TComparable value, TComparand bounds, - string name) - where TComparable : IComparable - { - if (value.CompareTo(bounds) < 0) { - return value; - } - - throw new ArgumentOutOfRangeException(name); - } - - public static TComparable CheckGreaterOrEqual(TComparable value, TComparand bounds, - string name) - where TComparable : IComparable - { - if (value.CompareTo(bounds) >= 0) { - return value; - } - - throw new ArgumentOutOfRangeException(name); - } - - public static TComparable CheckLessOrEqual(TComparable value, TComparand bounds, - string name) - where TComparable : IComparable - { - if (value.CompareTo(bounds) <= 0) { - return value; - } - - throw new ArgumentOutOfRangeException(name); - } - - public static int CheckGreater(int value, int bounds, string name) - { - if (value > bounds) { - return value; - } - - throw new ArgumentOutOfRangeException(name); - } - - public static int CheckLess(int value, int bounds, string name) - { - if (value < bounds) { - return value; - } - - throw new ArgumentOutOfRangeException(name); - } - - public static int CheckGreaterOrEqual(int value, int bounds, string name) - { - if (value >= bounds) { - return value; - } - - throw new ArgumentOutOfRangeException(name); - } - - public static int CheckLessOrEqual(int value, int bounds, string name) - { - if (value <= bounds) { - return value; - } - - throw new ArgumentOutOfRangeException(name); - } - } -} diff --git a/src/Hessian/Deserializer.cs b/src/Hessian/Deserializer.cs deleted file mode 100644 index 53ee9b7..0000000 --- a/src/Hessian/Deserializer.cs +++ /dev/null @@ -1,1015 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Net.NetworkInformation; -using System.Text; - -using Hessian.Collections; -using Hessian.Platform; - -namespace Hessian -{ - public class Deserializer - { - private readonly ValueReader reader; - private readonly IRefMap classDefs; - private readonly IRefMap objectRefs; - private readonly IRefMap typeNameRefs; - private readonly Lazy listTypeResolver = new Lazy(); - private readonly Lazy dictTypeResolver = new Lazy(); - - private static readonly EndianBitConverter BitConverter = new BigEndianBitConverter(); - - public Deserializer (Stream stream) - { - if (stream == null) { - throw new ArgumentNullException(nameof(stream)); - } - - reader = new ValueReader(stream); - classDefs = new ListRefMap(); - objectRefs = new ListRefMap(); - typeNameRefs = new ListRefMap(); - } - - - public bool CanRead() - { - var tag = reader.Peek (); - return tag.HasValue; - } - - #region ReadValue - - public object ReadValue () - { - var tag = reader.Peek (); - - if (!tag.HasValue) { - throw new EndOfStreamException(); - } - //Console.WriteLine("------------ 0x{0:x2}----------------",tag.Value); - - switch (tag.Value) { - case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: - case 0x08: case 0x09: case 0x0A: case 0x0B: case 0x0C: case 0x0D: case 0x0E: case 0x0F: - case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: - case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D: case 0x1E: case 0x1F: - //Console.WriteLine("ReadShortString"); - return ReadShortString(); - - case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: - case 0x28: case 0x29: case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x2E: case 0x2F: - //Console.WriteLine("ReadShortBinary"); - return ReadShortBinary(); - - case 0x30: case 0x31: case 0x32: case 0x33: - //Console.WriteLine("ReadMediumString"); - return ReadMediumString(); - - case 0x34: case 0x35: case 0x36: case 0x37: - //Console.WriteLine("ReadMediumBinary"); - return ReadMediumBinary(); - - case 0x38: case 0x39: case 0x3A: case 0x3B: case 0x3C: case 0x3D: case 0x3E: case 0x3F: - //Console.WriteLine("ReadLongThreeBytes"); - return ReadLongThreeBytes(); - - case 0x40: - //Console.WriteLine("Reserved"); - return Reserved(); - - case 0x41: case 0x42: - //Console.WriteLine("ReadChunkedBinary"); - return ReadChunkedBinary(); - - case 0x43: - //Console.WriteLine("ReadClassDefinition"); - return ReadClassDefinition(); - - case 0x44: - //Console.WriteLine("ReadFullDouble"); - return ReadFullDouble(); - - case 0x45: - //Console.WriteLine("Reserved"); - return Reserved(); - - case 0x46: - //Console.WriteLine("ReadBoolean"); - return ReadBoolean(); - - case 0x47: - //Console.WriteLine("Reserved"); - return Reserved(); - - case 0x48: - //Console.WriteLine("ReadUntypedMap"); - return ReadUntypedMap(); - - case 0x49: - //Console.WriteLine("ReadInteger"); - return ReadInteger(); - - case 0x4A: - //Console.WriteLine("ReadDateInMillis"); - return ReadDateInMillis(); - - case 0x4B: - //Console.WriteLine("ReadDateInMinutes"); - return ReadDateInMinutes(); - - case 0x4C: - //Console.WriteLine("ReadLongFull"); - return ReadLongFull(); - - case 0x4D: - //Console.WriteLine("ReadTypedMap"); - return ReadTypedMap(); - - case 0x4E: - //Console.WriteLine("ReadNull"); - return ReadNull(); - - case 0x4F: - //Console.WriteLine("ReadObject"); - return ReadObject(); - - case 0x50: - //Console.WriteLine("Reserved"); - return Reserved(); - - case 0x51: - //Console.WriteLine("ReadRef"); - return ReadRef(); - - case 0x52: case 0x53: - //Console.WriteLine("ReadChunkedString"); - return ReadChunkedString(); - - case 0x54: - //Console.WriteLine("ReadBoolean"); - return ReadBoolean(); - - case 0x55: - //Console.WriteLine("ReadVarList"); - return ReadVarList(); - - case 0x56: - //Console.WriteLine("ReadFixList"); - return ReadFixList(); - - case 0x57: - //Console.WriteLine("ReadVarListUntyped"); - return ReadVarListUntyped(); - - case 0x58: - //Console.WriteLine("ReadFixListUntyped"); - return ReadFixListUntyped(); - - case 0x59: - //Console.WriteLine("ReadLongFourBytes"); - return ReadLongFourBytes(); - - case 0x5A: - // List terminator - solitary list terminators are most definitely not legit. - throw new UnexpectedTagException(0x5A, "value"); - - case 0x5B: case 0x5C: - //Console.WriteLine("ReadDoubleOneByte"); - return ReadDoubleOneByte(); - - case 0x5D: - //Console.WriteLine("ReadDoubleOneByte"); - return ReadDoubleOneByte(); - - case 0x5E: - //Console.WriteLine("ReadDoubleTwoBytes"); - return ReadDoubleTwoBytes(); - - case 0x5F: - //Console.WriteLine("ReadDoubleFourBytes"); - return ReadDoubleFourBytes(); - - case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: - case 0x68: case 0x69: case 0x6A: case 0x6B: case 0x6C: case 0x6D: case 0x6E: case 0x6F: - //Console.WriteLine("ReadObjectCompact"); - return ReadObjectCompact(); - - case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: - //Console.WriteLine("ReadCompactFixList"); - return ReadCompactFixList(); - - case 0x78: case 0x79: case 0x7A: case 0x7B: case 0x7C: case 0x7D: case 0x7E: case 0x7F: - //Console.WriteLine("ReadCompactFixListUntyped"); - return ReadCompactFixListUntyped(); - - case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: - case 0x88: case 0x89: case 0x8A: case 0x8B: case 0x8C: case 0x8D: case 0x8E: case 0x8F: - case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: - case 0x98: case 0x99: case 0x9A: case 0x9B: case 0x9C: case 0x9D: case 0x9E: case 0x9F: - case 0xA0: case 0xA1: case 0xA2: case 0xA3: case 0xA4: case 0xA5: case 0xA6: case 0xA7: - case 0xA8: case 0xA9: case 0xAA: case 0xAB: case 0xAC: case 0xAD: case 0xAE: case 0xAF: - case 0xB0: case 0xB1: case 0xB2: case 0xB3: case 0xB4: case 0xB5: case 0xB6: case 0xB7: - case 0xB8: case 0xB9: case 0xBA: case 0xBB: case 0xBC: case 0xBD: case 0xBE: case 0xBF: - //Console.WriteLine("ReadIntegerSingleByte"); - return ReadIntegerSingleByte(); - - case 0xC0: case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7: - case 0xC8: case 0xC9: case 0xCA: case 0xCB: case 0xCC: case 0xCD: case 0xCE: case 0xCF: - //Console.WriteLine("ReadIntegerTwoBytes"); - return ReadIntegerTwoBytes(); - - case 0xD0: case 0xD1: case 0xD2: case 0xD3: case 0xD4: case 0xD5: case 0xD6: case 0xD7: - //Console.WriteLine("ReadIntegerThreeBytes"); - return ReadIntegerThreeBytes(); - - case 0xD8: case 0xD9: case 0xDA: case 0xDB: case 0xDC: case 0xDD: case 0xDE: case 0xDF: - case 0xE0: case 0xE1: case 0xE2: case 0xE3: case 0xE4: case 0xE5: case 0xE6: case 0xE7: - case 0xE8: case 0xE9: case 0xEA: case 0xEB: case 0xEC: case 0xED: case 0xEE: case 0xEF: - //Console.WriteLine("ReadLongOneByte"); - return ReadLongOneByte(); - - case 0xF0: case 0xF1: case 0xF2: case 0xF3: case 0xF4: case 0xF5: case 0xF6: case 0xF7: - case 0xF8: case 0xF9: case 0xFA: case 0xFB: case 0xFC: case 0xFD: case 0xFE: case 0xFF: - //Console.WriteLine("ReadLongTwoBytes"); - return ReadLongTwoBytes(); - } - - throw new Exception("WTF: byte value " + tag.Value + " not accounted for!"); - } - - #endregion - - private string ReadTypeName() - { - var tag = reader.Peek(); - - if (!tag.HasValue) { - throw new EndOfStreamException(); - } - - // A type name is either a string, or an integer reference to a - // string already read and stored in the type-name ref map. - if ((tag >= 0x00 && tag < 0x20) - || (tag >= 0x30 && tag < 0x34) - || tag == 0x52 - || tag == 0x53) { - var typeName = ReadString(); - //Console.WriteLine("Type={0}",typeName); - typeNameRefs.Add(typeName); - return typeName; - } - - return typeNameRefs.Get(ReadInteger()); - } - - #region List - - private IList ReadVarList() - { - reader.ReadByte(); - var type = ReadTypeName(); - return ReadListCore(type: type); - } - - private IList ReadFixList() - { - reader.ReadByte(); - var type = ReadTypeName(); - var length = ReadInteger(); - return ReadListCore(length, type); - } - - private IList ReadVarListUntyped() - { - reader.ReadByte(); - return ReadListCore(); - } - - private IList ReadFixListUntyped() - { - reader.ReadByte(); - var length = ReadInteger(); - return ReadListCore(length); - } - - private IList ReadCompactFixList() - { - var tag = reader.ReadByte(); - var length = tag - 0x70; - var type = ReadTypeName(); - return ReadListCore(length, type); - } - - private IList ReadCompactFixListUntyped() - { - var tag = reader.ReadByte(); - var length = tag - 0x70; - return ReadListCore(length); - } - - private IList ReadListCore(int? length = null, string type = null) - { - var list = GetListInstance(type, length); - - objectRefs.Add(list); - - if (length.HasValue) { - PopulateFixLengthList(list, length.Value); - } else { - PopulateVarList(list); - } - return list; - } - - private IList GetListInstance(string type, int? length = null) - { - IList list; - - if (length.HasValue) { - if (!listTypeResolver.Value.TryGetListInstance(type, length.Value, out list)) { - list = new List(length.Value); - } - } else { - if (!listTypeResolver.Value.TryGetListInstance(type, out list)) { - list = new List(); - } - } - - return list; - } - - private void PopulateFixLengthList(IList list, int length) - { - // NOTE: 这里有BUG 第一层 如果是复杂对象 那第一个readValue的 - // 结果是 classDef,下一个才是真实的数据,但是如果数据的字段又是复杂类型 - // 下一个 就还是classDef 接着是真实数据,以此类型,但是呢,如果类型之前 - for (var i = 0; i < length; ++i) - { - var obj = ReadValue(); - switch (obj) - { - case ClassDef _: - { - var rVal = ReadValue() as HessianObject; // 真实的数据 - if (rVal == null) - { - throw new HessianException("decode error"); - } - list.Add(ReadRealObject(rVal)); - break; - } - case HessianObject vObj: - list.Add(ReadRealObject(vObj)); - break; - default: - list.Add(obj); - break; - } - } - } - - private HessianObject ReadRealObject(HessianObject hessianObject) - { - var builder = HessianObject.Builder.New(hessianObject.TypeName); - foreach (var (k,v) in hessianObject) - { - if (v is ClassDef) - { - if (!(ReadValue() is HessianObject rVal)) - { - throw new HessianException("decode error"); - } - - builder.Add(k,ReadRealObject(rVal)); - } - else if(v is HessianObject vObj) - { - builder.Add(k,ReadRealObject(vObj)); - } - else - { - builder.Add(k, v); - } - } - - return builder.Create(); - } - - private void PopulateVarList(IList list) - { - while (true) { - var tag = reader.Peek(); - if (!tag.HasValue) { - throw new EndOfStreamException(); - } - if (tag == 'Z') { - reader.ReadByte(); - break; - } - list.Add(ReadValue()); - } - } - - #endregion - - public object Reserved () - { - reader.ReadByte(); - return ReadValue(); - } - - #region String - - public string ReadString() - { - var tag = reader.Peek(); - - if (!tag.HasValue) { - throw new EndOfStreamException(); - } - - if (tag.Value < 0x20) { - return ReadShortString(); - } - - if (tag.Value >= 0x30 && tag.Value <= 0x33) { - return ReadMediumString(); - } - - if (tag.Value == 'R' || tag.Value == 'S') { - return ReadChunkedString(); - } - - throw new UnexpectedTagException(tag.Value, "string"); - } - - private string ReadShortString () - { - var length = reader.ReadByte(); - return ReadStringWithLength(length); - } - - private string ReadMediumString () - { - var b0 = reader.ReadByte (); - var b1 = reader.ReadByte (); - var length = ((b0 - 0x30) << 8) | b1; - return ReadStringWithLength(length); - } - - private string ReadStringWithLength (int length) - { - var sb = new StringBuilder (length); - while (length-- > 0) { - sb.AppendCodepoint(reader.ReadUtf8Codepoint()); - } - return sb.ToString(); - } - - private string ReadChunkedString() - { - var sb = new StringBuilder(); - var final = false; - - while (!final) { - var tag = reader.ReadByte(); - final = tag == 'S'; - var length = reader.ReadShort(); - while (length-- > 0) { - sb.AppendCodepoint(reader.ReadUtf8Codepoint()); - } - } - - return sb.ToString(); - } - - #endregion - - #region Binary - - public byte[] ReadBinary() - { - var tag = reader.Peek(); - if (!tag.HasValue) { - throw new EndOfStreamException(); - } - - if (tag.Value >= 0x20 && tag.Value <= 0x2F) { - return ReadShortBinary(); - } - - if (tag.Value >= 0x34 && tag.Value <= 0x37) { - return ReadMediumBinary(); - } - - if (tag.Value == 0x41 || tag.Value == 0x42) { - return ReadChunkedBinary(); - } - - throw new UnexpectedTagException(tag.Value, "binary"); - } - - private byte[] ReadShortBinary () - { - var length = reader.ReadByte(); - var data = new byte[length]; - reader.Read(data, length); - return data; - } - - private byte[] ReadMediumBinary() - { - var b0 = reader.ReadByte(); - var b1 = reader.ReadByte(); - var length = ((b0 - 0x34) << 8) | b1; - var data = new byte[length]; - reader.Read(data, length); - return data; - } - - public byte[] ReadChunkedBinary() - { - var data = new List(); - var final = false; - - while (!final) { - var tag = reader.ReadByte(); - final = tag == 'B'; - var length = reader.ReadShort(); - var buff = new byte[length]; - reader.Read(buff, length); - data.AddRange(buff); - } - - return data.ToArray(); - } - - #endregion Binary - - #region Integer - - public int ReadInteger() - { - var tag = reader.Peek(); - - if (!tag.HasValue) { - throw new EndOfStreamException(); - } - - // Full-length integer encoding is 'I' b0 b1 b2 b3 - i.e. a full 32-bit integer in big-endian order. - if (tag == 0x49) { - return ReadIntegerFull(); - } - - // Ints between -16 and 47 are encoded as value + 0x90. - if (tag >= 0x80 && tag <= 0xBF) { - return ReadIntegerSingleByte(); - } - - // Ints between -2048 and 2047 can be encoded as two octets with the leading byte from 0xC0 to 0xCF. - if (tag >= 0xC0 && tag <= 0xCF) { - return ReadIntegerTwoBytes(); - } - - // Ints between -262144 and 262143 can be three bytes with the first from 0xD0 to 0xD7. - if (tag >= 0xD0 && tag <= 0xD7) { - return ReadIntegerThreeBytes(); - } - - throw new UnexpectedTagException(tag.Value, "integer"); - } - - private int ReadIntegerFull() - { - reader.ReadByte(); // Discard tag. - byte b0 = reader.ReadByte(), - b1 = reader.ReadByte(), - b2 = reader.ReadByte(), - b3 = reader.ReadByte(); - - return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; - } - - private int ReadIntegerSingleByte() - { - return reader.ReadByte() - 0x90; - } - - private int ReadIntegerTwoBytes() - { - byte b0 = reader.ReadByte(), - b1 = reader.ReadByte(); - - return ((b0 - 0xC8) << 8) | b1; - } - - private int ReadIntegerThreeBytes() - { - byte b0 = reader.ReadByte(), - b1 = reader.ReadByte(), - b2 = reader.ReadByte(); - - return ((b0 - 0xD4) << 16) | (b1 << 8) | b2; - } - - #endregion Integer - - #region Class Definition - - public ClassDef ReadClassDefinition() - { - var tag = reader.ReadByte(); - if (tag != 'C') { - throw new UnexpectedTagException(tag, "classdef"); - } - var name = ReadString(); - var fieldCount = ReadInteger(); - var fields = new string[fieldCount]; - for (var i = 0; i < fields.Length; ++i) { - fields[i] = ReadString(); - } - - var classDef = new ClassDef(name, fields); - - classDefs.Add(classDef); - - return classDef; - } - - #endregion Class Definition - - #region Double - - public double ReadDouble() - { - var tag = reader.Peek(); - - if (!tag.HasValue) { - throw new EndOfStreamException(); - } - - if (tag == 0x44) { - return ReadFullDouble(); - } - - if (tag == 0x5B || tag == 0x5C) { - return ReadDoubleOneByte(); - } - - if (tag == 0x5D) { - return ReadDoubleTwoBytes(); - } - - if (tag == 0x5E) { - return ReadDoubleThreeBytes(); - } - - if (tag == 0x5F) { - return ReadDoubleFourBytes(); - } - - throw new UnexpectedTagException(tag.Value, "double"); - } - - private double ReadFullDouble() - { - var data = new byte[9]; // 9 bytes: tag + IEEE 8-byte double - reader.Read(data, data.Length); - return BitConverter.ToDouble(data, 1); - } - - private double ReadDoubleOneByte() - { - // 0x5B encodes the double value 0.0, and 0x5C encodes 1.0. - return reader.ReadByte() - 0x5B; - } - - private double ReadDoubleTwoBytes() - { - // Doubles representing integral values between -128.0 and 127.0 are - // encoded as single bytes. Java bytes are signed, .NET bytes aren't, - // so we have to cast it first. - reader.ReadByte(); - return (sbyte) reader.ReadByte(); - } - - private double ReadDoubleThreeBytes() - { - // Doubles representing integral values between -32768.0 and 32767.0 are - // encoded as two-byte integers. - reader.ReadByte(); - return reader.ReadShort(); - } - - private double ReadDoubleFourBytes() - { - // Doubles that can be represented as singles are thusly encoded. - var data = new byte[5]; - reader.Read(data, data.Length); - return BitConverter.ToSingle(data, 0); - } - - #endregion Double - - public bool ReadBoolean() - { - var tag = reader.ReadByte(); - - switch (tag) { - case 0x46: return false; - case 0x54: return true; - } - - throw new UnexpectedTagException(tag, "boolean"); - } - - #region Date - - public DateTime ReadDate() - { - var tag = reader.Peek(); - - if (!tag.HasValue) { - throw new EndOfStreamException(); - } - - if (tag == 0x4A) { - return ReadDateInMillis(); - } - - if (tag == 0x4B) { - return ReadDateInMinutes(); - } - - throw new UnexpectedTagException(tag.Value, "date"); - } - - private DateTime ReadDateInMillis() - { - var data = new byte[9]; - reader.Read(data, data.Length); - var millis = LongFromBytes(data, 1); - return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(millis); - } - - private DateTime ReadDateInMinutes() - { - var data = new byte[5]; - reader.Read(data, data.Length); - var minutes = IntFromBytes(data, 1); - return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMinutes(minutes); - } - - #endregion Date - - #region Long - - public long ReadLong() - { - var tag = reader.Peek(); - - if (!tag.HasValue) { - throw new EndOfStreamException(); - } - - if (tag == 0x4C) { - return ReadLongFull(); - } - - if (tag >= 0xD8 && tag <= 0xEF) { - return ReadLongOneByte(); - } - - if (tag >= 0xF0 && tag <= 0xFF) { - return ReadLongTwoBytes(); - } - - if (tag >= 0x38 && tag <= 0x3F) { - return ReadLongThreeBytes(); - } - - if (tag == 0x59) { - return ReadLongFourBytes(); - } - - throw new UnexpectedTagException(tag.Value, "long"); - } - - private long ReadLongFull() - { - var data = new byte[9]; - - - reader.Read(data, data.Length); - return LongFromBytes(data, 1); - - } - - - - private long ReadLongOneByte() - { - return reader.ReadByte() - 0xE0; - } - - private long ReadLongTwoBytes() - { - byte b0 = reader.ReadByte(), - b1 = reader.ReadByte(); - - return ((b0 - 0xF8) << 8) | b1; - } - - private long ReadLongThreeBytes() - { - byte b0 = reader.ReadByte(), - b1 = reader.ReadByte(), - b2 = reader.ReadByte(); - - return ((b0 - 0x3C) << 16) | (b1 << 8) | b2; - } - - private long ReadLongFourBytes() - { - var data = new byte[5]; - reader.Read(data, data.Length); - return IntFromBytes(data, 1); - } - - #endregion Long - - #region Dictionary/Map - - public IDictionary ReadMap() - { - var tag = reader.Peek(); - - if (!tag.HasValue) { - throw new EndOfStreamException(); - } - - if (tag == 'H') { - return ReadUntypedMap(); - } - - if (tag == 'M') { - return ReadTypedMap(); - } - - throw new UnexpectedTagException(tag.Value, "map"); - } - - private IDictionary ReadUntypedMap() - { - reader.ReadByte(); - return ReadMapCore(); - } - - private IDictionary ReadTypedMap() - { - reader.ReadByte(); - var typeName = ReadTypeName(); - return ReadMapCore(typeName); - } - - private IDictionary ReadMapCore(string type = null) - { - IDictionary dictionary; - if (type == null || !dictTypeResolver.Value.TryGetInstance("", out dictionary)) { - dictionary = new Dictionary(); - } - - objectRefs.Add(dictionary); - - while (true) { - var tag = reader.Peek(); - - if (!tag.HasValue) { - throw new EndOfStreamException(); - } - if (tag == 'Z') { - break; - } - - var key = ReadValue(); - var value = ReadValue(); - dictionary.Add(key, value); - } - - return dictionary; - } - - #endregion - - #region Object - - public object ReadObject() - { - var tag = reader.Peek(); - - if (!tag.HasValue) { - throw new EndOfStreamException(); - } - - if (tag == 'O') { - return ReadObjectFull(); - } - - if (tag >= 0x60 && tag < 0x70) { - return ReadObjectCompact(); - } - - throw new UnexpectedTagException(tag.Value, "object"); - } - - private object ReadObjectFull() - { - reader.ReadByte(); - var classDefId = ReadInteger(); - var classDef = classDefs.Get(classDefId); - return ReadObjectCore(classDef); - } - - private object ReadObjectCompact() - { - var classDefId = reader.ReadByte() - 0x60; - var classDef = classDefs.Get(classDefId); - return ReadObjectCore(classDef); - } - - private object ReadObjectCore(ClassDef classDef) - { - // XXX: This needs a better implementation - maybe, you know, constructing - // the requested type? - var builder = HessianObject.Builder.New(classDef.Name); - objectRefs.Add(builder.Object); - - foreach (var field in classDef.Fields) { - builder.Add(field, ReadValue()); - } - - return builder.Create(); - } - - #endregion - - public object ReadNull() - { - reader.ReadByte(); - return null; - } - - public object ReadRef() - { - var tag = reader.Peek(); - if (!tag.HasValue) { - throw new EndOfStreamException(); - } - if (tag != 0x51) { - throw new UnexpectedTagException(tag.Value, "ref"); - } - - reader.ReadByte();//过滤tag - - return objectRefs.Get(ReadInteger()); - } - - private static int IntFromBytes(byte[] buffer, int offset) - { - return (buffer[offset + 0] << 0x18) - | (buffer[offset + 1] << 0x10) - | (buffer[offset + 2] << 0x08) - | (buffer[offset + 3] << 0x00); - } - - private static long LongFromBytes(byte[] buffer, int offset) - { - /* - var value = (long) reader.ReadByte() << 56; - - value |= ((long) reader.ReadByte() << 48); - value |= ((long) reader.ReadByte() << 40); - value |= ((long) reader.ReadByte() << 32); - value |= ((long) reader.ReadByte() << 24); - value |= ((long) reader.ReadByte() << 16); - value |= ((long) reader.ReadByte() << 8); - value |= (uint)reader.ReadByte(); - - return value; - */ - return ((long)buffer[offset + 0] << 0x38) - + ((long)buffer[offset + 1] << 0x30) - | ((long)buffer[offset + 2] << 0x28) - | ((long)buffer[offset + 3] << 0x20) - | ((long)buffer[offset + 4] << 0x18) - | ((long)buffer[offset + 5] << 0x10) - | ((long)buffer[offset + 6] << 0x08) - | ((uint)buffer[offset + 7] << 0x00); - - - } - } -} - diff --git a/src/Hessian/DictionaryTypeResolver.cs b/src/Hessian/DictionaryTypeResolver.cs deleted file mode 100644 index 06748b4..0000000 --- a/src/Hessian/DictionaryTypeResolver.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Hessian -{ - public class DictionaryTypeResolver - { - private readonly Dictionary>> constructors; - - public DictionaryTypeResolver() - { - constructors = new Dictionary>> { - {"System.Collections.Hashtable", DefaultCtor}, - {"System.Collections.Generic.IDictionary`2", DefaultCtor}, - {"System.Collections.Generic.Dictionary`2", DefaultCtor}, - {"System.Collections.IDictionary", DefaultCtor}, - {"java.lang.Map", DefaultCtor}, - {"java.util.HashMap", DefaultCtor}, - {"java.util.EnumMap", DefaultCtor}, - {"java.util.TreeMap", DefaultCtor}, - {"java.util.concurrent.ConcurrentHashMap", DefaultCtor} - }; - - } - - public bool TryGetInstance(string type, out IDictionary instance) - { - instance = null; - - if (!constructors.TryGetValue(type, out var ctor)) { - return false; - } - - instance = ctor(); - return true; - } - - private static IDictionary DefaultCtor() - { - return new Dictionary(); - } - } -} diff --git a/src/Hessian/Hessian.csproj b/src/Hessian/Hessian.csproj deleted file mode 100644 index ab6cf27..0000000 --- a/src/Hessian/Hessian.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - - netstandard2.0 - $(DefineConstants);DOTNETCORE - Hessian的编解码实现,并不完全哦 - Xuanye @ 2018 - Xuanye - Hession DotNet port - Hessian - Hessian - $(HessianPackageVersion) - Hessian,xxl-job,protocol - - $(HessianPackageNotes) - - https://github.com/xuanye/DotXxlJob - https://github.com/xuanye/DotXxlJob/blob/master/LICENSE - false - git - https://github.com/xuanye/DotXxlJob - - diff --git a/src/Hessian/HessianException.cs b/src/Hessian/HessianException.cs deleted file mode 100644 index 7a3fdc3..0000000 --- a/src/Hessian/HessianException.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; - -namespace Hessian -{ - public class HessianException : ApplicationException - { - public HessianException() - { - - } - - public HessianException(string message) - : base(message) - { - - } - - public HessianException(string message, Exception innerException) - : base(message, innerException) - { - - } - } -} diff --git a/src/Hessian/HessianObject.cs b/src/Hessian/HessianObject.cs deleted file mode 100644 index f23a2ef..0000000 --- a/src/Hessian/HessianObject.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; - -namespace Hessian -{ - public class HessianObject : IReadOnlyCollection> - { - private readonly string typeName; - private readonly IDictionary fields; - - public string TypeName => typeName; - - public object this[string key] => fields[key]; - - public int Count => fields.Count; - - private HessianObject(string typeName) - { - this.typeName = Conditions.CheckNotNull(typeName, "typeName"); - fields = new Dictionary(); - } - - public IEnumerator> GetEnumerator() - { - return fields.Select(kvp => Tuple.Create(kvp.Key, kvp.Value)).GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public class Builder - { - private readonly HessianObject obj; - - public HessianObject Object - { - get { return obj; } - } - - private Builder(string typeName) - { - obj = new HessianObject(typeName); - } - - public static Builder New(string typeName) - { - return new Builder(typeName); - } - - public Builder Add(string field, object value) - { - obj.fields.Add(field, value); - return this; - } - - public HessianObject Create() - { - return obj; - } - } - } -} diff --git a/src/Hessian/HessianSerializationContext.cs b/src/Hessian/HessianSerializationContext.cs deleted file mode 100644 index d7322d6..0000000 --- a/src/Hessian/HessianSerializationContext.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Hessian -{ - public class HessianSerializationContext - { - public IList Classes - { - get; - private set; - } - - public IList Instances - { - get; - private set; - } - - public HessianSerializationContext() - { - Classes = new List(); - Instances = new List(); - } - } -} \ No newline at end of file diff --git a/src/Hessian/InvalidRefException.cs b/src/Hessian/InvalidRefException.cs deleted file mode 100644 index 2cc177a..0000000 --- a/src/Hessian/InvalidRefException.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Hessian -{ - public class InvalidRefException : HessianException - { - public int RefId { get; private set; } - - public InvalidRefException(int refId) - : base(String.Format("Invalid ref ID: {0}", refId)) - { - RefId = refId; - } - } -} diff --git a/src/Hessian/ListTypeResolver.cs b/src/Hessian/ListTypeResolver.cs deleted file mode 100644 index 07c2c3b..0000000 --- a/src/Hessian/ListTypeResolver.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Hessian -{ - public class ListTypeResolver - { - private readonly Dictionary>> constructors = new Dictionary>>(); - private readonly Dictionary>> length_constructors = new Dictionary>>(); - private readonly Func> empty_list_ctor = () => new List(); - private readonly Func> empty_list_ctor_with_length = length => new List(length); - - public ListTypeResolver() - { - constructors.Add("System.Collections.ArrayList", empty_list_ctor); - constructors.Add("System.Collections.List", empty_list_ctor); - constructors.Add("System.Collections.IList", empty_list_ctor); - constructors.Add("System.Collections.Generic.List`1", empty_list_ctor); - constructors.Add("System.Collections.Generic.IList`1", empty_list_ctor); - constructors.Add("System.Collections.ObjectModel.Collection`1", () => new Collection()); - constructors.Add("java.util.List", empty_list_ctor); - constructors.Add("java.util.Vector", empty_list_ctor); - constructors.Add("java.util.ArrayList", empty_list_ctor); - constructors.Add("java.util.LinkedList", empty_list_ctor); - - length_constructors.Add("System.Collections.List", empty_list_ctor_with_length); - length_constructors.Add("System.Collections.IList", empty_list_ctor_with_length); - length_constructors.Add("System.Collections.Generic.List`1", empty_list_ctor_with_length); - length_constructors.Add("System.Collections.Generic.IList`1", empty_list_ctor_with_length); - length_constructors.Add("java.util.List", empty_list_ctor_with_length); - length_constructors.Add("java.util.Vector", empty_list_ctor_with_length); - length_constructors.Add("java.util.ArrayList", empty_list_ctor_with_length); - length_constructors.Add("java.util.LinkedList", empty_list_ctor_with_length); - } - - public bool TryGetListInstance(string type, out IList list) - { - list = null; - - Func> ctor; - if (!constructors.TryGetValue(type, out ctor)) { - return false; - } - - list = ctor(); - return true; - } - - public bool TryGetListInstance(string type, int length, out IList list) - { - list = null; - - Func> ctor; - if (!length_constructors.TryGetValue(type, out ctor)) { - return false; - } - - list = ctor(length); - return true; - } - } -} diff --git a/src/Hessian/Marker.cs b/src/Hessian/Marker.cs deleted file mode 100644 index ef153be..0000000 --- a/src/Hessian/Marker.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace Hessian -{ - internal static class Marker - { - public const byte True = (byte) 'T';//0x54; - public const byte False = (byte) 'F';// 0x46; - public const byte Null = (byte) 'N';//0x4E; - public const byte BinaryNonfinalChunk = (byte) 'b';//0x41; - public const byte BinaryFinalChunk = (byte) 'B';//0x42; - public const byte ClassDefinition = (byte) 'C';//0x43; - public const byte DateTimeLong = 0x4A; - public const byte DateTimeCompact = 0x4B; - public const byte Double = 0x5A; - public const byte DoubleZero = 0x5B; - public const byte DoubleOne = 0x5C; - public const byte DoubleOctet = 0x5D; - public const byte DoubleShort = 0x5E; - public const byte DoubleFloat = 0x5F; - public const byte UnpackedInteger = (byte) 'I';// 0x49; - public const byte PackedLong = (byte) 'Y';// 0x59; - public const byte UnpackedLong = (byte) 'L';// 0x4C; - public const byte StringNonfinalChunk = 0x52; - public const byte StringFinalChunk = 0x53; - public const byte VarList = 0x55; - public const byte FixedList = 0x56; - public const byte VarListUntyped = 0x57; - public const byte FixListUntyped = 0x58; - - public const byte CompactFixListStart = 0x70; - public const byte CompactFixListEnd = 0x77; - public const byte CompactFixListUntypedStart = 0x78; - public const byte CompactFixListUntypedEnd = 0x7F; - - public const byte ClassReference = (byte) 'O';//0x4F - public const byte InstanceReference = (byte) 'Q'; //0x51; - - - } -} \ No newline at end of file diff --git a/src/Hessian/PeekStream.cs b/src/Hessian/PeekStream.cs deleted file mode 100644 index 98b5594..0000000 --- a/src/Hessian/PeekStream.cs +++ /dev/null @@ -1,142 +0,0 @@ -using System; -using System.IO; - -namespace Hessian -{ - public class PeekStream : Stream - { - private Stream inner; - private byte? peek; - - public PeekStream(Stream inner) - { - if (inner == null) { - throw new ArgumentNullException("inner"); - } - - this.inner = inner; - this.peek = null; - } - - public override bool CanRead { - get { - return inner.CanRead; - } - } - - public override bool CanSeek { - get { - return false; - } - } - - public override bool CanWrite { - get { - return false; - } - } - - public override long Length { - get { - return inner.Length; - } - } - - public override long Position { - get { - return inner.Position - (peek.HasValue ? 1 : 0); - } - set { - throw new NotSupportedException("Seeking not supported."); - } - } - - public byte? Peek () - { - if (!peek.HasValue) { - var b = inner.ReadByte(); - - if (b == -1) { - return null; - } - - peek = (byte) b; - } - - return peek; - } - - public override int ReadByte () - { - if (peek.HasValue) { - var val = peek.Value; - peek = null; - return val; - } - - return inner.ReadByte(); - } - - public override int Read (byte[] buffer, int offset, int count) - { - Conditions.CheckNotNull(buffer, "buffer"); - Conditions.CheckGreaterOrEqual(offset, 0, "offset"); - Conditions.CheckLess(offset, buffer.Length, "offset"); - Conditions.CheckGreaterOrEqual(count, 0, "count"); - Conditions.CheckArgument( - offset + count <= buffer.Length, - "Buffer is not big enough to contain the requested amount of data at the given offset."); - - if (count == 0) { - return 0; - } - - var bytesToRead = count; - - if (peek.HasValue) { - buffer[offset++] = peek.Value; - peek = null; - --bytesToRead; - } - - int bytesRead; - while (bytesToRead > 0 && (bytesRead = inner.Read (buffer, offset, bytesToRead)) != 0) { - offset += bytesRead; - bytesToRead -= bytesRead; - } - - return count - bytesToRead; - } - - public override void Write (byte[] buffer, int offset, int count) - { - throw new NotSupportedException("Writes not supported."); - } - - public override void SetLength (long value) - { - throw new NotSupportedException("Seeking not supported."); - } - - public override long Seek (long offset, SeekOrigin origin) - { - throw new NotSupportedException("Seeking not supported."); - } - - public override void Flush () - { - throw new NotSupportedException("Writes not supported."); - } - - protected override void Dispose (bool disposing) - { - if (inner != null) { - inner.Dispose (); - inner = null; - } - - base.Dispose (disposing); - } - } -} - diff --git a/src/Hessian/Platform/BigEndianBitConverter.cs b/src/Hessian/Platform/BigEndianBitConverter.cs deleted file mode 100644 index ea97841..0000000 --- a/src/Hessian/Platform/BigEndianBitConverter.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Hessian.Platform -{ - public class BigEndianBitConverter : EndianBitConverter - { - protected override long FromBytes(byte[] bytes, int offset, int count) - { - var result = 0L; - for (var i = 0; i < count; ++i) - { - result = (result << 8) | bytes[offset + i]; - } - return result; - } - - protected override void CopyBytes(long source, byte[] buffer, int offset, int count) - { - var end = offset + count - 1; - for (var i = 0; i < count; ++i) - { - buffer[end - i] = (byte)(source & 0xFF); - source >>= 8; - } - } - } -} diff --git a/src/Hessian/Platform/EndianBitConverter.cs b/src/Hessian/Platform/EndianBitConverter.cs deleted file mode 100644 index 523f1b3..0000000 --- a/src/Hessian/Platform/EndianBitConverter.cs +++ /dev/null @@ -1,215 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Hessian.Platform -{ - public abstract class EndianBitConverter - { - #region T -> byte[] - - public byte[] GetBytes(bool value) - { - // One byte, no endianness - return BitConverter.GetBytes(value); - } - - public byte[] GetBytes(char value) - { - return GetBytes(value, sizeof (char)); - } - - public byte[] GetBytes(short value) - { - return GetBytes(value, sizeof (short)); - } - - public byte[] GetBytes(ushort value) - { - return GetBytes(value, sizeof (ushort)); - } - - public byte[] GetBytes(int value) - { - return GetBytes(value, sizeof (int)); - } - - public byte[] GetBytes(uint value) - { - return GetBytes(value, sizeof (uint)); - } - - public byte[] GetBytes(long value) - { - return GetBytes(value, sizeof (long)); - } - - public byte[] GetBytes(ulong value) - { - return GetBytes((long)value, sizeof (ulong)); - } - - public byte[] GetBytes(float value) - { - return GetBytes(SingleToInt32(value), sizeof (int)); - } - - public byte[] GetBytes(double value) - { - return GetBytes(DoubleToInt64(value), sizeof (long)); - } - - private byte[] GetBytes(long value, int size) - { - var buffer = new byte[size]; - CopyBytes(value, buffer, 0, size); - return buffer; - } - - #endregion - - #region byte[] -> T - - public bool ToBoolean(byte[] value, int index) - { - // one byte, no endianness - return BitConverter.ToBoolean(value, index); - } - - public char ToChar(byte[] value, int index) - { - return (char) FromBytes(value, index, sizeof (char)); - } - - public short ToInt16(byte[] value, int index) - { - return (short) FromBytes(value, index, sizeof (short)); - } - - public ushort ToUInt16(byte[] value, int index) - { - return (ushort) FromBytes(value, index, sizeof (ushort)); - } - - public int ToInt32(byte[] value, int index) - { - return (int) FromBytes(value, index, sizeof (int)); - } - - public uint ToUInt32(byte[] value, int index) - { - return (uint) FromBytes(value, index, sizeof (uint)); - } - - public long ToInt64(byte[] value, int index) - { - return FromBytes(value, index, sizeof (long)); - } - - public ulong ToUInt64(byte[] value, int index) - { - return (ulong) FromBytes(value, index, sizeof (ulong)); - } - - public float ToSingle(byte[] value, int index) - { - var int32 = (int) FromBytes(value, index, sizeof (int)); - return Int32ToSingle(int32); - } - - public double ToDouble(byte[] value, int index) - { - var int64 = FromBytes(value, index, sizeof (long)); - return Int64ToDouble(int64); - } - - #endregion - - protected abstract long FromBytes(byte[] bytes, int offset, int count); - - protected abstract void CopyBytes(long source, byte[] buffer, int index, int count); - - private static int SingleToInt32(float value) - { - return new JonSkeetUnion32(value).AsInt; - } - - private static float Int32ToSingle(int value) - { - return new JonSkeetUnion32(value).AsFloat; - } - - private static long DoubleToInt64(double value) - { - return new JonSkeetUnion64(value).AsLong; - } - - private static double Int64ToDouble(long value) - { - return new JonSkeetUnion64(value).AsDouble; - } - - [StructLayout(LayoutKind.Explicit)] - private struct JonSkeetUnion32 - { - [FieldOffset(0)] - private readonly int i; - - [FieldOffset(0)] - private readonly float f; - - public int AsInt - { - get { return i; } - } - - public float AsFloat - { - get { return f; } - } - - public JonSkeetUnion32(int value) - { - f = 0; - i = value; - } - - public JonSkeetUnion32(float value) - { - i = 0; - f = value; - } - } - - [StructLayout(LayoutKind.Explicit)] - private struct JonSkeetUnion64 - { - [FieldOffset(0)] - private readonly long l; - - [FieldOffset(0)] - private readonly double d; - - public long AsLong - { - get { return l; } - } - - public double AsDouble - { - get { return d; } - } - - public JonSkeetUnion64(long value) - { - d = 0; - l = value; - } - - public JonSkeetUnion64(double value) - { - l = 0; - d = value; - } - } - } -} diff --git a/src/Hessian/Platform/LittleEndianBitConverter.cs b/src/Hessian/Platform/LittleEndianBitConverter.cs deleted file mode 100644 index 187a8cd..0000000 --- a/src/Hessian/Platform/LittleEndianBitConverter.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Hessian.Platform -{ - public class LittleEndianBitConverter : EndianBitConverter - { - protected override long FromBytes(byte[] bytes, int offset, int count) - { - var result = 0L; - var end = offset + count - 1; - for (var i = 0; i < count; ++i) - { - result = (result << 8) | bytes[end - i]; - } - return result; - } - - protected override void CopyBytes(long source, byte[] buffer, int offset, int count) - { - for (var i = 0; i < count; ++i) - { - buffer[offset + i] = (byte)(source & 0xFF); - source >>= 8; - } - } - } -} diff --git a/src/Hessian/PropertyElement.cs b/src/Hessian/PropertyElement.cs deleted file mode 100644 index 3cb8686..0000000 --- a/src/Hessian/PropertyElement.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; - -namespace Hessian -{ - public class PropertyElement - { - public string Name { get; set; } - public int Order { get; set; } - public PropertyInfo PropertyInfo { get; set; } - } - - internal class PropertyComparer : IComparer - { - private readonly IComparer comparer; - - public PropertyComparer() - { - comparer = Comparer.Default; - } - - public int Compare(PropertyElement x, PropertyElement y) - { - var eq = comparer.Compare(x.Order, y.Order); - return 0 == eq - ? String.Compare(x.Name, y.Name, StringComparison.Ordinal) - : eq; - } - } -} \ No newline at end of file diff --git a/src/Hessian/Serializer.cs b/src/Hessian/Serializer.cs deleted file mode 100644 index d9abfc1..0000000 --- a/src/Hessian/Serializer.cs +++ /dev/null @@ -1,523 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.Serialization; -using System.Text; - -namespace Hessian -{ - public class Serializer - { - static readonly ConcurrentDictionary ClassDefCache =new ConcurrentDictionary(); - - private readonly Stream _stream; - private readonly HessianSerializationContext _context; - - public Serializer (Stream stream) - { - this._stream = stream ?? throw new ArgumentNullException(nameof(stream)); - _context = new HessianSerializationContext(); - } - - public void WriteObject(object graph) - { - var objectType = graph.GetType(); - if (!ClassDefCache.TryGetValue(objectType, out var classDef)) - { - classDef = GetClassDef(objectType.GetTypeInfo()); - } - - var index = this._context.Instances.IndexOf(graph); - - if (index > -1) - { - WriteInstanceReference(index); - return; - } - - this._context.Instances.Add(graph); - - index = this._context.Classes.IndexOf(objectType); - - if (index < 0) - { - BeginClassDefinition(); - WriteString(classDef.ClassName); - WriteInt32(classDef.Fields.Count); - - foreach (var property in classDef.Fields) - { - WriteString(property.Name); - } - EndClassDefinition(); - - index = this._context.Classes.Count; - - this._context.Classes.Add(objectType); - } - WriteObjectReference(index); - foreach (var item in classDef.Fields) - { - var value = item.PropertyInfo.GetValue(graph); - WriteValue(value); - } - } - - public void WriteValue(object val) - { - if (val == null) - { - WriteNull(); - return; - } - var valType = val.GetType(); - var typeInfo = valType.GetTypeInfo(); - if (IsSimpleType(typeInfo)) - { - WriteSimpleValue(val); - return; - } - - if (IsListType(typeInfo)) - { - WriteListValue(val); - return; - } - - WriteObject(val); - } - - private void WriteListValue(object val) - { - var tag = (int)Marker.CompactFixListStart; - if (!(val is ICollection eVal)) - { - throw new HessianException("write list data error"); - } - tag += eVal.Count; - if (tag > Marker.CompactFixListEnd) - { - throw new HessianException("write list data error,tag too large"); - } - this._stream.WriteByte((byte)tag); - int index = 1; - foreach (var item in eVal) - { - if (index == 1) - { - WriteString("["+GetItemTypeName(item.GetType())); - } - WriteValue(item); - index++; - } - } - - private string GetItemTypeName(Type type) - { - var classType = type.GetCustomAttribute(); - if (classType != null) - { - return classType.Name; - } - - if (IsListType(type.GetTypeInfo())) - { - return "java.util.List"; - } - - return type.Name; - } - private void WriteSimpleValue(object val) - { - var valType = val.GetType(); - if (valType == typeof(int)) - { - WriteInt32((int)val); - } - else if (valType == typeof(bool)) - { - WriteBoolean((bool)val); - } - else if (valType == typeof(long)) - { - WriteInt64((long)val); - } - else if (valType == typeof(double)) - { - WriteDouble((double)val); - } - else if (valType == typeof(string)) - { - WriteString((string)val); - } - else if (valType == typeof(DateTime)) - { - WriteDateTime((DateTime)val); - } - } - - private ClassElement GetClassDef(TypeInfo typeInfo) - { - - var classAttr = typeInfo.GetCustomAttribute(); - if (classAttr == null) - { - throw new HessianException("DataContract must be set"); - } - - ClassElement ce = new ClassElement {ClassName = classAttr.Name, Fields = new List()}; - - //ClassDef def = new ClassDef(classAttr.Name); - foreach (var property in typeInfo.DeclaredProperties) - { - var attribute = property.GetCustomAttribute(); - - if (null == attribute) - { - continue; - } - - if (!property.CanRead || !property.CanWrite) - { - continue; - } - PropertyElement p = new PropertyElement { - Name = attribute.Name, - Order = attribute.Order, - PropertyInfo = property - }; - ce.Fields .Add( p ); - } - ce.Fields.Sort(new PropertyComparer()); - return ce; - } - - /// - /// Writes NULL token into stream - /// - public void WriteNull() - { - this._stream.WriteByte(Marker.Null); - } - - /// - /// Writes value into output stream. - /// - /// The value. - public void WriteBoolean(bool value) - { - this._stream.WriteByte(value ? Marker.True : Marker.False); - } - - /// - /// Writes array of into output stream. - /// - /// The value. - public void WriteBytes(byte[] buffer) - { - if (null == buffer) - { - WriteNull(); - return; - } - - WriteBytes(buffer, 0, buffer.Length); - } - - public void WriteBytes(byte[] buffer, int offset, int count) - { - if (offset < 0) - { - throw new ArgumentException("", nameof(offset)); - } - - if (null == buffer) - { - WriteNull(); - return; - } - - if (count < 0x10) - { - this._stream.WriteByte((byte)(0x20 + (count & 0x0F))); - this._stream.Write(buffer, offset, count); - return; - } - - const int chunkSize = 0x8000; - - while (count > chunkSize) - { - this._stream.WriteByte(Marker.BinaryNonfinalChunk); - this._stream.WriteByte(chunkSize >> 8); - this._stream.WriteByte(chunkSize & 0xFF); - this._stream.Write(buffer, offset, chunkSize); - - count -= chunkSize; - offset += chunkSize; - } - - this._stream.WriteByte(Marker.BinaryFinalChunk); - this._stream.WriteByte((byte)(count >> 8)); - this._stream.WriteByte((byte)(count & 0xFF)); - this._stream.Write(buffer, offset, count); - } - - public void WriteDateTime(DateTime value) - { - if (value.Second == 0) - { - var s = value.GetTotalMinutes(); - - this._stream.WriteByte(Marker.DateTimeCompact); - this._stream.WriteByte((byte)(s >> 24)); - this._stream.WriteByte((byte)(s >> 16)); - this._stream.WriteByte((byte)(s >> 8)); - this._stream.WriteByte((byte)s); - - return; - } - - var dt = value.GetTotalMilliseconds(); - - this._stream.WriteByte(Marker.DateTimeLong); - this._stream.WriteByte((byte)(dt >> 56)); - this._stream.WriteByte((byte)(dt >> 48)); - this._stream.WriteByte((byte)(dt >> 40)); - this._stream.WriteByte((byte)(dt >> 32)); - this._stream.WriteByte((byte)(dt >> 24)); - this._stream.WriteByte((byte)(dt >> 16)); - this._stream.WriteByte((byte)(dt >> 8)); - this._stream.WriteByte((byte)dt); - } - - public void WriteDouble(double value) - { - if (value.Equals(0.0d)) - { - this._stream.WriteByte(Marker.DoubleZero); - return; - } - - if (value.Equals(1.0d)) - { - this._stream.WriteByte(Marker.DoubleOne); - return; - } - - var fraction = Math.Abs(value - Math.Truncate(value)); - - if (Double.Epsilon >= fraction) - { - if (Byte.MinValue <= value && value <= Byte.MaxValue) - { - this._stream.WriteByte(Marker.DoubleOctet); - this._stream.WriteByte(Convert.ToByte(value)); - - return; - } - - if (Int16.MinValue <= value && value <= Int16.MaxValue) - { - var val = Convert.ToInt16(value); - - this._stream.WriteByte(Marker.DoubleShort); - this._stream.WriteByte((byte)(val >> 8)); - this._stream.WriteByte((byte)val); - - return; - } - } - - if (Single.MinValue <= value && value <= Single.MaxValue) - { - var bytes = BitConverter.GetBytes((float) value); - - this._stream.WriteByte(Marker.DoubleFloat); - - for (var index = bytes.Length - 1; index >= 0; index--) - { - this._stream.WriteByte(bytes[index]); - } - - return; - } - - var temp = BitConverter.DoubleToInt64Bits(value); - - this._stream.WriteByte(Marker.Double); - - for (var index = 56; index >= 0; index -= 8) - { - this._stream.WriteByte((byte) (temp >> index)); - } - } - - public void WriteInt32(int value) - { - if (-16 <= value && value < 48) - { - this._stream.WriteByte((byte)(0x90 + value)); - } - else if (-2048 <= value && value < 2048) - { - this._stream.WriteByte((byte)(0xC8 + (byte)(value >> 8))); - this._stream.WriteByte((byte)value); - } - else if (-262144 <= value && value < 262144) - { - this._stream.WriteByte((byte)(0xD4 + (byte)(value >> 16))); - this._stream.WriteByte((byte)(value >> 8)); - this._stream.WriteByte((byte)value); - } - else - { - this._stream.WriteByte(Marker.UnpackedInteger); - this._stream.WriteByte((byte)(value >> 24)); - this._stream.WriteByte((byte)(value >> 16)); - this._stream.WriteByte((byte)(value >> 8)); - this._stream.WriteByte((byte)value); - } - } - - public void WriteInt64(long value) - { - if (-8 <= value && value < 16) - { - this._stream.WriteByte((byte)(0xE0 + value)); - } - else if (-2048 <= value && value < 2048) - { - this._stream.WriteByte((byte)(0xF8 + (byte)(value >> 8))); - this._stream.WriteByte((byte)value); - } - else if (-262144 <= value && value < 262144) - { - this._stream.WriteByte((byte)(0x3C + (byte)(value >> 16))); - this._stream.WriteByte((byte)(value >> 8)); - this._stream.WriteByte((byte)value); - } - else if (Int32.MinValue <= value && value <= Int32.MaxValue) - { - this._stream.WriteByte(Marker.PackedLong); - this._stream.WriteByte((byte)(value >> 24)); - this._stream.WriteByte((byte)(value >> 16)); - this._stream.WriteByte((byte)(value >> 8)); - this._stream.WriteByte((byte)value); - } - else - { - this._stream.WriteByte(Marker.UnpackedLong); - this._stream.WriteByte((byte)(value >> 56)); - this._stream.WriteByte((byte)(value >> 48)); - this._stream.WriteByte((byte)(value >> 40)); - this._stream.WriteByte((byte)(value >> 32)); - this._stream.WriteByte((byte)(value >> 24)); - this._stream.WriteByte((byte)(value >> 16)); - this._stream.WriteByte((byte)(value >> 8)); - this._stream.WriteByte((byte)value); - } - } - - public void WriteString(string value) - { - if (string.IsNullOrEmpty(value)) - { - this._stream.WriteByte(0x00); - return; - } - - var length = value.Length; - - if (1024 > length) - { - var bytes = Encoding.UTF8.GetBytes(value.ToCharArray()); - - if (32 > length) - { - this._stream.WriteByte((byte) length); - } - else - { - this._stream.WriteByte((byte) (0x30 + (byte) (length >> 8))); - this._stream.WriteByte((byte) length); - } - - this._stream.Write(bytes, 0, bytes.Length); - - return; - } - - const int maxChunkLength = 1024; - var position = 0; - - while (position < length) - { - var count = Math.Min(length - position, maxChunkLength); - var final = length == (position + count); - var chunk = value.Substring(position, count); - var bytes = Encoding.UTF8.GetBytes(chunk.ToCharArray()); - - this._stream.WriteByte(final ? Marker.StringFinalChunk : Marker.StringNonfinalChunk); - this._stream.WriteByte((byte)(count >> 8)); - this._stream.WriteByte((byte)count); - this._stream.Write(bytes, 0, bytes.Length); - - position += count; - } - } - - public void BeginClassDefinition() - { - this._stream.WriteByte(Marker.ClassDefinition); - } - - public void EndClassDefinition() - { - } - - public void WriteObjectReference(int index) - { - if (index < 0x10) - { - this._stream.WriteByte((byte)(0x60 + index)); - } - else - { - this._stream.WriteByte(Marker.ClassReference); - WriteInt32(index); - } - } - - public void WriteInstanceReference(int index) - { - this._stream.WriteByte(Marker.InstanceReference); - WriteInt32(index); - } - - - private static bool IsSimpleType(TypeInfo typeInfo) - { - if (typeInfo.IsValueType || typeInfo.IsEnum || typeInfo.IsPrimitive) - { - return true; - } - - if (typeof (String) == typeInfo.AsType()) - { - return true; - } - - return false; - } - - private static bool IsListType(TypeInfo typeInfo) - { - return typeof(ICollection).IsAssignableFrom(typeInfo); - } - } -} \ No newline at end of file diff --git a/src/Hessian/StringBuilderExtensions.cs b/src/Hessian/StringBuilderExtensions.cs deleted file mode 100644 index 9bf4d20..0000000 --- a/src/Hessian/StringBuilderExtensions.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.IO; -using System.Text; - -namespace Hessian -{ - public static class StringBuilderExtensions - { - public static StringBuilder AppendCodepoint(this StringBuilder sb, uint codepoint) - { - if (codepoint < 0x10000) { - return sb.Append((char)codepoint); - } - - var n = codepoint - 0x10000; - var high = (char)((n >> 10) + 0xD800); - var low = (char)((n & 0x3FF) + 0xDC00); - - AssertValidSurrogates(high, low); - - return sb - .Append (high) - .Append (low); - } - - [System.Diagnostics.Conditional("DEBUG")] - private static void AssertValidSurrogates (char high, char low) - { - if (!Char.IsHighSurrogate (high)) { - throw new InvalidDataException ("Invalid high surrogate"); - } - - if (!Char.IsLowSurrogate (low)) { - throw new InvalidDataException ("Invalid low surrogate"); - } - } - } -} - diff --git a/src/Hessian/UnexpectedTagException.cs b/src/Hessian/UnexpectedTagException.cs deleted file mode 100644 index 4df5ea5..0000000 --- a/src/Hessian/UnexpectedTagException.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Hessian -{ - public class UnexpectedTagException : HessianException - { - public byte Tag { get; private set; } - - public UnexpectedTagException(byte tag, string expectedType) - : base(FormatErrorMessage(tag, expectedType)) - { - Tag = tag; - } - - private static string FormatErrorMessage(byte tag, string expectedType) - { - return string.Format("{0:X} is not a valid {1} tag.", tag, expectedType); - } - } -} diff --git a/src/Hessian/ValueReader.cs b/src/Hessian/ValueReader.cs deleted file mode 100644 index 9b2c127..0000000 --- a/src/Hessian/ValueReader.cs +++ /dev/null @@ -1,163 +0,0 @@ -using System; -using System.IO; - -namespace Hessian -{ - public class ValueReader - { - private byte[] buffer = new byte[8]; - private PeekStream stream; - - public ValueReader (Stream stream) - { - this.stream = stream as PeekStream ?? new PeekStream(stream); - } - - public byte? Peek () - { - return stream.Peek (); - } - - public short ReadShort () - { - Read (buffer, 0, 2); - return BitConverter.ToInt16(buffer, 0); - } - - public int ReadInt() - { - Read (buffer, 0, 4); - return BitConverter.ToInt32(buffer, 0); - } - - public uint ReadUtf8Codepoint () - { - const uint replacementChar = 0xFFFD; - - byte b0, b1, b2, b3; - b0 = ReadByte (); - - if (b0 < 0x80) { - return b0; - } - - if (b0 < 0xC2) { - return replacementChar; - } - - if (b0 < 0xE0) { - b1 = ReadByte (); - - if ((b1 ^ 0x80) >= 0x40) { - return replacementChar; - } - - return (b1 & 0x3Fu) | ((b0 & 0x1Fu) << 6); - } - - if (b0 < 0xF0) { - b1 = ReadByte (); - b2 = ReadByte (); - - // Valid range: E0 A0..BF 80..BF - if (b0 == 0xE0 && (b1 ^ 0xA0) >= 0x20) { - return replacementChar; - } - - // Valid range: ED 80..9F 80..BF - if (b0 == 0xED && (b1 ^ 0x80) >= 0x20) { - return replacementChar; - } - - // Valid range: E1..EC 80..BF 80..BF - if ((b1 ^ 0x80) >= 0x40 || (b2 ^ 0x80) >= 0x40) { - return replacementChar; - } - - return (b2 & 0x3Fu) - | ((b1 & 0x3Fu) << 6) - | ((b0 & 0x0Fu) << 12); - } - - if (b0 < 0xF1) { - b1 = ReadByte(); - - if ((b1 ^ 0x90) < 0x30) { - return replacementChar; - } - - b2 = ReadByte(); - b3 = ReadByte(); - - if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) { - return replacementChar; - } - - return (b3 & 0x3Fu) - | ((b2 & 0x3Fu) << 6) - | ((b1 & 0x3Fu) << 12) - | ((b0 & 0x07u) << 18); - } - - if (b0 < 0xF4) { - b1 = ReadByte (); - b2 = ReadByte (); - b3 = ReadByte (); - - // Valid range: F1..F3 80..BF 80..BF 80..BF - if ((b1 & 0xC0) != 0x80 || (b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) - { - return replacementChar; - } - - return (b3 & 0x3Fu) - | ((b2 & 0x3Fu) << 6) - | ((b1 & 0x3Fu) << 12) - | ((b0 & 0x07u) << 18); - } - - if (b0 < 0xF5) { - b1 = ReadByte (); - - // Valid range: F4 80..8F 80..BF 80..BF - if ((b1 ^ 0x80) >= 0x10) { - return replacementChar; - } - - b2 = ReadByte(); - b3 = ReadByte(); - - if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) - { - return replacementChar; - } - - return (b3 & 0x3Fu) - | ((b2 & 0x3Fu) << 6) - | ((b1 & 0x3Fu) << 12) - | ((b0 & 0x07u) << 18); - } - - return replacementChar; - } - - public byte ReadByte() - { - var b = stream.ReadByte(); - if (b == -1) throw new EndOfStreamException(); - return (byte)b; - } - - public void Read(byte[] buffer, int count) - { - Read (buffer, 0, count); - } - - private void Read(byte[] buffer, int offset, int count) - { - var bytesRead = stream.Read (buffer, offset, count); - if (bytesRead != count) throw new EndOfStreamException(); - } - } -} - diff --git a/tests/Hessian.Tests/Hessian.Tests.csproj b/tests/Hessian.Tests/Hessian.Tests.csproj deleted file mode 100644 index 314a58e..0000000 --- a/tests/Hessian.Tests/Hessian.Tests.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - netcoreapp2.2 - - false - - - - - - - - - - - - - diff --git a/tests/Hessian.Tests/UnitTest1.cs b/tests/Hessian.Tests/UnitTest1.cs deleted file mode 100644 index 4b82831..0000000 --- a/tests/Hessian.Tests/UnitTest1.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using Xunit; - -namespace Hessian.Tests -{ - public class UnitTest1 - { - [Fact] - public void Test1() - { - } - } -} \ No newline at end of file