├── .gitattributes ├── .gitignore ├── CODE_OF_CONDUCT.md ├── GlobalAssemblyInfo.cs ├── LICENSE ├── README.md ├── Thrifty.sln ├── assembly.snk ├── del-bin.bat ├── packge.bat ├── psd-123456.pem ├── run-benchmark.bat ├── samples ├── Thrifty.Samples.Common │ ├── CallResult.cs │ ├── Entity.cs │ ├── IService.cs │ ├── MyException.cs │ └── Thrifty.Samples.Common.csproj ├── Thrifty.Samples.NiftyClient │ ├── Program.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── PublishProfiles │ │ │ ├── FolderProfile.pubxml │ │ │ ├── FolderProfile1.pubxml │ │ │ └── FolderProfile2.pubxml │ │ └── launchSettings.json │ ├── Thrifty.Samples.NiftyClient.csproj │ └── ca.crt └── Thrifty.Samples.NiftyServer │ ├── IDL │ ├── LogEntry.cs │ ├── ResultCode.cs │ ├── Scribe.cs │ └── scribe.thrift │ ├── Program.cs │ ├── Properties │ ├── AssemblyInfo.cs │ ├── PublishProfiles │ │ ├── FolderProfile.pubxml │ │ ├── FolderProfile1.pubxml │ │ └── FolderProfile2.pubxml │ └── launchSettings.json │ ├── ServiceImpl.cs │ ├── Swifty │ ├── LogEntry.cs │ ├── ResultCode.cs │ ├── Scribe.cs │ └── ScribeTest2.cs │ └── Thrifty.Samples.NiftyServer.csproj ├── shared.props ├── src ├── Thrifty.Core │ ├── Buffers.cs │ ├── DelegateRunnable.cs │ ├── DelegateTProtocolFactory.cs │ ├── Exceptions │ │ ├── ThriftyApplicationException.cs │ │ ├── ThriftyProtocolException.cs │ │ ├── ThriftyRuntimeException.cs │ │ └── ThriftyTransportException.cs │ ├── Guard.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── TaskCompletionSourceEx.cs │ ├── Threading │ │ ├── AtomicBoolean.cs │ │ ├── ITimerExtensions.cs │ │ ├── InterLockedEx.cs │ │ └── LimitedConcurrencyLevelTaskScheduler.cs │ ├── Thrift │ │ ├── Collections │ │ │ ├── TCollections.cs │ │ │ └── THashSet.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── Protocol │ │ │ ├── TAbstractBase.cs │ │ │ ├── TBase.cs │ │ │ ├── TBase64Utils.cs │ │ │ ├── TBinaryProtocol.cs │ │ │ ├── TCompactProtocol.cs │ │ │ ├── TField.cs │ │ │ ├── TJSONProtocol.cs │ │ │ ├── TList.cs │ │ │ ├── TMap.cs │ │ │ ├── TMessage.cs │ │ │ ├── TMessageType.cs │ │ │ ├── TMultiplexedProcessor.cs │ │ │ ├── TMultiplexedProtocol.cs │ │ │ ├── TProtocol.cs │ │ │ ├── TProtocolDecorator.cs │ │ │ ├── TProtocolException.cs │ │ │ ├── TProtocolFactory.cs │ │ │ ├── TProtocolUtil.cs │ │ │ ├── TSet.cs │ │ │ ├── TStruct.cs │ │ │ └── TType.cs │ │ ├── Server │ │ │ ├── TServer.cs │ │ │ ├── TServerEventHandler.cs │ │ │ ├── TSimpleServer.cs │ │ │ ├── TThreadPoolServer.cs │ │ │ └── TThreadedServer.cs │ │ ├── TApplicationException.cs │ │ ├── TException.cs │ │ ├── TProcessor.cs │ │ └── Transport │ │ │ ├── TBufferedTransport.cs │ │ │ ├── TFramedTransport.cs │ │ │ ├── TMemoryBuffer.cs │ │ │ ├── TNamedPipeClientTransport.cs │ │ │ ├── TNamedPipeServerTransport.cs │ │ │ ├── TServerSocket.cs │ │ │ ├── TServerTransport.cs │ │ │ ├── TSilverlightSocket.cs │ │ │ ├── TSocket.cs │ │ │ ├── TStreamTransport.cs │ │ │ ├── TTLSServerSocket.cs │ │ │ ├── TTLSSocket.cs │ │ │ ├── TTransport.cs │ │ │ ├── TTransportException.cs │ │ │ └── TTransportFactory.cs │ ├── Thrifty.Core.csproj │ ├── ThriftyException.cs │ └── ThriftyUtilities.cs ├── Thrifty.MicroServices │ ├── Client │ │ ├── ChannelKey.cs │ │ ├── DiscoveryEnabledServer.cs │ │ ├── LoadBalanceKey.cs │ │ ├── Pooling │ │ │ ├── IClientConnectionPool.cs │ │ │ ├── IEvictionTimer.cs │ │ │ ├── NiftyClientChannelFactory.cs │ │ │ ├── NiftyClientChannelPool.cs │ │ │ ├── NoneClientChannelPool.cs │ │ │ └── PooledClientChannel.cs │ │ ├── ServiceAddressUsage.cs │ │ ├── ThriftyClient.FakeProxy.cs │ │ ├── ThriftyClient.cs │ │ ├── ThriftyClientEurekaConfig.cs │ │ ├── ThriftyClientOptions.cs │ │ ├── ThriftyPing.cs │ │ ├── ThriftyRequest.cs │ │ ├── ThriftyResponse.cs │ │ └── VersionAffinityFilter.cs │ ├── Commons │ │ ├── HealthCheckIdentifier.cs │ │ ├── IHealthCheck.cs │ │ ├── InstanceOptions.cs │ │ ├── ThriftyHealthCheck.cs │ │ └── Utils.cs │ ├── InstanceInfoExtensions.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Ribbon │ │ ├── BaseLoadBalancer.cs │ │ ├── Client │ │ │ ├── AbstractLoadBalancerAwareClient.cs │ │ │ ├── DefaultClientRequest.cs │ │ │ ├── IClient.cs │ │ │ ├── IClientRequest.cs │ │ │ ├── IResponse.cs │ │ │ └── RequestSpecificRetryHandler.cs │ │ ├── Compatibilities.cs │ │ ├── Config.cs │ │ ├── DefaultRetryHandler.cs │ │ ├── DefaultServerStatusCollector.cs │ │ ├── DefaultServerWeightAccumulater.cs │ │ ├── Distribution.cs │ │ ├── EventHandles.cs │ │ ├── ILoadBalancer.cs │ │ ├── IPing.cs │ │ ├── IPingStrategy.cs │ │ ├── IRetryHandler.cs │ │ ├── IRule.cs │ │ ├── IServerStatus.cs │ │ ├── IServerStatusCollector.cs │ │ ├── IServerWeightAccumulater.cs │ │ ├── LoadBalancerBuilder.cs │ │ ├── LoadBalancerCommand.cs │ │ ├── LoadBalancerContext.cs │ │ ├── Rules │ │ │ ├── AvailabilityFilteringRule.cs │ │ │ ├── BestAvailableRule.cs │ │ │ ├── FilterableRule.cs │ │ │ ├── IFilter.cs │ │ │ ├── RandomRule.cs │ │ │ ├── RetryRule.cs │ │ │ ├── RoundRobinRule.cs │ │ │ └── WeightedResponseTimeRule.cs │ │ ├── SerialPingStrategy.cs │ │ └── Server.cs │ ├── Server │ │ ├── EurekaRegisterInfo.cs │ │ ├── IServerFuture.cs │ │ ├── ThriftyBootstrap.cs │ │ ├── ThriftyRegistryService.cs │ │ ├── ThriftyServer.cs │ │ ├── ThriftyServerOptions.cs │ │ ├── ThriftyServiceDescriptor.cs │ │ └── ThriftyServiceMetadata.cs │ └── Thrifty.MicroServices.csproj ├── Thrifty.Nifty.Client │ ├── AbstractClientChannel.IoThreadBoundTimerTask.cs │ ├── AbstractClientChannel.ReadTimeoutTask.cs │ ├── AbstractClientChannel.Request.cs │ ├── AbstractClientChannel.cs │ ├── AbstractClientConnector.cs │ ├── ClientSslConfig.cs │ ├── FramedClientChannel.cs │ ├── FramedClientConnector.cs │ ├── IClientRequestContext.cs │ ├── IListener.cs │ ├── INiftyClientChannel.cs │ ├── INiftyClientConnector.cs │ ├── IRequestChannel.cs │ ├── NettyClientConfig.cs │ ├── NiftyClient.cs │ ├── NiftyClientChannelPipelineSetup.cs │ ├── NiftyClientRequestContext.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── TNiftyClientChannelTransport.cs │ ├── Thrifty.Nifty.Client.csproj │ ├── TimeoutHandler.cs │ ├── UnframedClientChannel.cs │ └── UnframedClientConnector.cs ├── Thrifty.Nifty │ ├── Codecs │ │ ├── DefaultThriftFrameCodec.cs │ │ ├── DefaultThriftFrameCodecFactory.cs │ │ ├── DefaultThriftFrameDecoder.cs │ │ ├── DefaultThriftFrameEncoder.cs │ │ ├── IThriftFrameCodec.cs │ │ ├── IThriftFrameCodecFactory.cs │ │ ├── ThriftFrameDecoder.cs │ │ └── ThriftFrameEncoder.cs │ ├── Core │ │ ├── ConnectionContext.cs │ │ ├── ConnectionContextHandler.cs │ │ ├── INiftySecurityFactory.cs │ │ ├── INiftySecurityHandlers.cs │ │ ├── IRequestContext.cs │ │ ├── IdleDisconnectHandler.cs │ │ ├── NettyServerConfig.cs │ │ ├── NettyServerTransport.ConnectionLimiter.cs │ │ ├── NettyServerTransport.cs │ │ ├── NiftyBootstrap.cs │ │ ├── NiftyConnectionContext.cs │ │ ├── NiftyDispatcher.cs │ │ ├── NiftyRequestContext.cs │ │ ├── ShutdownUtil.cs │ │ ├── TChannelBufferInputTransport.cs │ │ ├── TChannelBufferOutputTransport.cs │ │ ├── TNiftyTransport.cs │ │ ├── ThriftMessage.cs │ │ ├── ThriftServerDef.cs │ │ ├── ThriftTransportType.cs │ │ └── ThriftUnframedDecoder.cs │ ├── Duplex │ │ ├── TDuplexProtocolFactory.cs │ │ ├── TProtocolPair.cs │ │ └── TTransportPair.cs │ ├── NiftyException.cs │ ├── Processors │ │ ├── INiftyProcessor.cs │ │ ├── INiftyProcessorFactory.cs │ │ ├── NiftyProcessorAdapters.cs │ │ └── Processors.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Ssl │ │ ├── CertificateHelper.cs │ │ ├── SslConfig.cs │ │ └── SslSession.cs │ └── Thrifty.Nifty.csproj └── Thrifty.Services │ ├── Annotations │ ├── ThriftConstructorAttribute.cs │ ├── ThriftExceptionAttribute.cs │ ├── ThriftFieldAttribute.cs │ ├── ThriftIdlAttribute.cs │ ├── ThriftMethodAttribute.cs │ ├── ThriftServiceAttribute.cs │ └── ThriftStructAttribute.cs │ ├── Codecs │ ├── DelegateCodec.cs │ ├── IThriftCodec.cs │ ├── Internal │ │ ├── Builtin │ │ │ ├── AbstractThriftCodec.cs │ │ │ ├── BooleanArrayThriftCodec.cs │ │ │ ├── BooleanThriftCodec.cs │ │ │ ├── ByteBufferThriftCodec.cs │ │ │ ├── ByteThriftCodec.cs │ │ │ ├── DateTimeArrayThriftCodec.cs │ │ │ ├── DateTimeThriftCodec.cs │ │ │ ├── DecimalThriftCodec.cs │ │ │ ├── DoubleArrayThriftCodec.cs │ │ │ ├── DoubleThriftCodec.cs │ │ │ ├── FloatArrayThriftCodec.cs │ │ │ ├── FloatThriftCodec.cs │ │ │ ├── GuidThriftCodec.cs │ │ │ ├── IntArrayThriftCodec.cs │ │ │ ├── IntThriftCodec.cs │ │ │ ├── ListThriftCodec.cs │ │ │ ├── LongArrayThriftCodec.cs │ │ │ ├── LongThriftCodec.cs │ │ │ ├── MapThriftCodec.cs │ │ │ ├── SetThriftCodec.cs │ │ │ ├── ShortArrayThriftCodec.cs │ │ │ ├── ShortThriftCodec.cs │ │ │ ├── StringThriftCodec.cs │ │ │ └── VoidThriftCodec.cs │ │ ├── Coercion │ │ │ └── CoercionThriftCodec.cs │ │ ├── EnumThriftCodec.cs │ │ ├── IThriftCodecFactory.cs │ │ ├── Reflection │ │ │ ├── AbstractReflectionThriftCodec.cs │ │ │ ├── ReflectionThriftCodecFactory.cs │ │ │ └── ReflectionThriftStructCodec.cs │ │ ├── TProtocolReader.cs │ │ └── TProtocolWriter.cs │ ├── Metadata │ │ ├── AbstractThriftMetadataBuilder.cs │ │ ├── DefaultThriftTypeReference.cs │ │ ├── DependencyInjection │ │ │ ├── ConstructorInjection.cs │ │ │ ├── FieldInjection.cs │ │ │ ├── Injection.cs │ │ │ └── ParameterInjection.cs │ │ ├── Extractor.cs │ │ ├── FieldExtractor.cs │ │ ├── FieldKind.cs │ │ ├── FieldMetadata.cs │ │ ├── IThriftExtraction.cs │ │ ├── IThriftInjection.cs │ │ ├── IThriftTypeReference.cs │ │ ├── MetadataErrorException.cs │ │ ├── MetadataErrors.cs │ │ ├── MetadataWarningException.cs │ │ ├── MethodExtractor.cs │ │ ├── MethodInjection.cs │ │ ├── RecursiveThriftTypeReference.cs │ │ ├── ThriftCatalog.cs │ │ ├── ThriftConstructorInjection.cs │ │ ├── ThriftEnumMetadata.cs │ │ ├── ThriftFieldExtractor.cs │ │ ├── ThriftFieldInjection.cs │ │ ├── ThriftFieldMetadata.cs │ │ ├── ThriftMethodExtractor.cs │ │ ├── ThriftMethodInjection.cs │ │ ├── ThriftParameterInjection.cs │ │ ├── ThriftStructMetadata.cs │ │ ├── ThriftStructMetadataBuilder.cs │ │ ├── ThriftType.cs │ │ └── TypeCoercion.cs │ ├── ThriftCodecManager.cs │ ├── ThriftOrderAttribute.cs │ └── ThriftProtocolType.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── ReflectionHelper.cs │ ├── Services │ ├── ClientContextChain.cs │ ├── ContextChain.cs │ ├── DynamicProxy │ │ ├── DynamicProxyClientFactory.cs │ │ ├── Fake.cs │ │ └── ThriftInvocationHandler.cs.bak │ ├── INiftyClientChannelAware.cs │ ├── IServiceLocator.cs │ ├── IThriftClientFactory.cs │ ├── Metadata │ │ ├── ThriftMethodMetadata.cs │ │ └── ThriftServiceMetadata.cs │ ├── SyncClientHelpers.cs │ ├── ThriftClient.cs │ ├── ThriftClientConfig.cs │ ├── ThriftClientEventHandler.cs │ ├── ThriftClientManager.cs │ ├── ThriftClientMetadata.cs │ ├── ThriftEventHandler.cs │ ├── ThriftMethodHandler.ParameterHandler.cs │ ├── ThriftMethodHandler.cs │ ├── ThriftMethodProcessor.cs │ ├── ThriftServer.cs │ ├── ThriftServerConfig.cs │ └── ThriftServiceProcessor.cs │ ├── ThriftSerializer.cs │ ├── Thrifty.Services.csproj │ └── ThriftyServiceNotFoundException.cs └── test ├── Ribbon.Test ├── EasyHttpPing.cs ├── HttpServer.cs ├── ITest.cs ├── Just4Fun │ ├── IContainer.cs │ ├── IProcedure.cs │ ├── IProcedureDiscovery.cs │ ├── IProcedureParameter.cs │ ├── IRemoteProcedure.cs │ ├── IRemoteProcedureCaller.cs │ ├── IServer.cs │ ├── IServerSelector.cs │ └── IServiceInstance.cs ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── RandomRuleTest.cs └── Ribbon.Test.csproj ├── Swifty.Benchmark ├── LogCase │ ├── LogCase.cs │ ├── LogEntry.cs │ └── ResultCode.cs ├── LogTester.cs ├── LogTester1.cs ├── LogTester2.cs ├── LogTester3.cs ├── Program.cs └── Thrifty.Benchmark.csproj └── Swifty.Tests ├── AssertEx.cs ├── MicroServices ├── Server │ ├── ServerBootStrupTest.cs │ └── ThriftyTypeMetadataTest.cs └── Stup │ ├── INoServiceInterface.cs │ └── IServiceStup.cs ├── Properties └── AssemblyInfo.cs ├── Services ├── AsyncServiceTest.cs ├── ClientProtocolTest.cs ├── Codecs │ ├── Internal │ │ ├── EnumThriftCodecTest.cs │ │ └── Reflection │ │ │ └── ReflectionThriftStructCodecTest.cs │ └── Metadata │ │ ├── ThriftServiceMetadataTest.cs │ │ └── ThriftStructMetadataBuilderTest.cs ├── ExceptionServerTest.cs ├── MicroServices │ ├── BaseLoadBalancerTest.cs │ ├── BaseTest.cs │ └── EasyHttpPing.cs ├── MultipleParameterServiceTest.cs ├── OneWayServiceTest.cs ├── ScopedServer.cs └── ThriftServerTest.cs ├── TestModel ├── Codecs │ ├── BaseServiceImplementation.cs │ ├── CombinedServiceImplementation.cs │ ├── ComplexStruct.cs │ ├── DerivedStruct.cs │ ├── EnumStruct.cs │ ├── IBaseService.cs │ ├── ICombinedService.cs │ ├── IDerivedServiceOne.cs │ ├── IDerivedServiceTwo.cs │ ├── MultipleDerivedServiceImplementation.cs │ ├── MultipleDerivedServiceImplementationWithExplicitAttribute.cs │ ├── RecursiveStruct.cs │ ├── SimpleStruct.cs │ ├── SingleDerivedServiceImplementation.cs │ └── StructWithConstructor.cs └── Services │ ├── AsyncService.cs │ ├── IExceptionService.cs │ ├── LogEntry.cs │ ├── MultipleParameterService.cs │ ├── OneWayService.cs │ ├── ResultCode.cs │ ├── Scribe.cs │ └── SimpleService.cs └── Thrifty.Tests.csproj /GlobalAssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | // General Information about an assembly is controlled through the following 4 | // set of attributes. Change these attribute values to modify the information 5 | // associated with an assembly. 6 | //[assembly: AssemblyCopyright("Copyright © 2016 labijie.com. All rights reserved.")] 7 | 8 | 9 | // Version information for an assembly consists of the following four values: 10 | // 11 | // Major Version 12 | // Minor Version 13 | // Build Number 14 | // Revision 15 | // 16 | // You can specify all the values or you can default the Build and Revision Numbers 17 | // by using the '*' as shown below: 18 | //[assembly: AssemblyVersion("1.5.0.*")] 19 | //[assembly: AssemblyKeyFile("assembly.snk")] 20 | -------------------------------------------------------------------------------- /assembly.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/endink/Thrifty/d1c4921b9babe7c37d74197e7b75e9340f781e0d/assembly.snk -------------------------------------------------------------------------------- /del-bin.bat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/endink/Thrifty/d1c4921b9babe7c37d74197e7b75e9340f781e0d/del-bin.bat -------------------------------------------------------------------------------- /packge.bat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/endink/Thrifty/d1c4921b9babe7c37d74197e7b75e9340f781e0d/packge.bat -------------------------------------------------------------------------------- /run-benchmark.bat: -------------------------------------------------------------------------------- 1 | dotnet %~dp0test\Thrifty.Benchmark\bin\Release\netcoreapp1.1\Thrifty.Benchmark.dll 2 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.Common/CallResult.cs: -------------------------------------------------------------------------------- 1 | namespace Thrifty.Samples.Common 2 | { 3 | [ThriftStruct("CallResult")] 4 | public class CallResult 5 | { 6 | [ThriftField(1)] 7 | public string ErrorMessage { get; set; } 8 | [ThriftField(2)] 9 | public T Payload { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.Common/Entity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Thrifty.Samples.Common 4 | { 5 | [ThriftStruct("Entity")] 6 | public class Entity 7 | { 8 | [ThriftField(1)] 9 | public DayOfWeek Day { get; set; } 10 | [ThriftField(2)] 11 | public string StringValue { get; set; } 12 | [ThriftField(3)] 13 | public bool BoolValue { get; set; } 14 | [ThriftField(4)] 15 | public byte ByteNumber { get; set; } 16 | [ThriftField(5)] 17 | public short ShortNumber { get; set; } 18 | [ThriftField(6)] 19 | public int IntNumber { get; set; } 20 | [ThriftField(7)] 21 | public long LongNumber { get; set; } 22 | [ThriftField(8)] 23 | public double DoubleNumber { get; set; } 24 | [ThriftField(9)] 25 | public DateTime Now { get; set; } = DateTime.Now; 26 | //不支持guid 27 | 28 | [ThriftField(10)] 29 | public int[] IntArray { get; set; } 30 | 31 | [ThriftField(11)] 32 | public Guid? Guid { get; set; } 33 | 34 | [ThriftField(12)] 35 | public Guid[] GuidArray { get; set; } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.Common/MyException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Thrift; 5 | 6 | namespace Thrifty.Samples.Common 7 | { 8 | [ThriftStruct("Exception")] 9 | public class MyException : Exception 10 | { 11 | [ThriftConstructor] 12 | public MyException(string message) 13 | { 14 | Message = message; 15 | } 16 | [ThriftField(1)] 17 | public override string Message { get; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.Common/Thrifty.Samples.Common.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp1.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.NiftyClient/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Thrifty.Samples.NiftyClient")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("6345bf83-e679-4234-a624-97e680ce7276")] 20 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.NiftyClient/Properties/PublishProfiles/FolderProfile.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | FileSystem 9 | Release 10 | netcoreapp1.1 11 | bin\Release\PublishOutput 12 | win7-x64 13 | 14 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.NiftyClient/Properties/PublishProfiles/FolderProfile1.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | FileSystem 9 | Release 10 | netcoreapp1.1 11 | bin\Release\PublishOutput\centos.7-x64 12 | centos.7-x64 13 | 14 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.NiftyClient/Properties/PublishProfiles/FolderProfile2.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | FileSystem 9 | Release 10 | netcoreapp1.1 11 | bin\Release\PublishOutput\win7-x64 12 | win7-x64 13 | 14 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.NiftyClient/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Thrifty.Samples.NiftyClient": { 4 | "commandName": "Project", 5 | "commandLineArgs": "10.66.30.50 10 5" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /samples/Thrifty.Samples.NiftyClient/Thrifty.Samples.NiftyClient.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp1.1 5 | Thrifty.Samples.NiftyClient 6 | Exe 7 | Thrifty.Samples.NiftyClient 8 | 1.1.2 9 | false 10 | false 11 | false 12 | win10-x64;centos.7-x64;win7-x64 13 | 14 | 15 | 16 | true 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.NiftyClient/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDtzCCAp+gAwIBAgIJAIOCB5ij7Vm7MA0GCSqGSIb3DQEBBQUAMHIxCzAJBgNV 3 | BAYTAkNOMQ8wDQYDVQQIDAZZdW5uYW4xEDAOBgNVBAcMB0t1bm1pbmcxETAPBgNV 4 | BAoMCGd6bmIuY29tMRMwEQYDVQQLDAppbmZyYSB0ZWFtMRgwFgYDVQQDDA9jbG91 5 | ZC5nem5iLmNvcnAwHhcNMTcxMTIyMDYwMDM4WhcNMjMwNDAzMDYwMDM4WjByMQsw 6 | CQYDVQQGEwJDTjEPMA0GA1UECAwGWXVubmFuMRAwDgYDVQQHDAdLdW5taW5nMREw 7 | DwYDVQQKDAhnem5iLmNvbTETMBEGA1UECwwKaW5mcmEgdGVhbTEYMBYGA1UEAwwP 8 | Y2xvdWQuZ3puYi5jb3JwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA 9 | 7yuI3ozZUW+ctG+F+4sIbNi5DBAOiCrCAKgJh7EXV3rTM9tI1p1Vi4j1TMS2cPXm 10 | caPssiXLWjJx3izcRc863l2Tp9318Kw45PDXXj0fHF6kHHs2Q+S/x9u/6ktOhoP4 11 | uhQYajLa9WXiMs1VqBQW5tBVhHp7DEztG5z/rl9Gu14FOsrjlY5a+Bh53TERAID9 12 | l+p2bTgXQK0ArUmT76+jbkkhUjQcgpEM/Bb6xsjBWligd2IAQ71ePrl9mNFWNMrv 13 | W5TZIsicxcY9eo16DYyJyOcYCCL6bLuVDGceHK1JK7KQIw4Jln6NGwj0KqdpXdo8 14 | CckXcoEaoaMlzBmdFbTwwwIDAQABo1AwTjAdBgNVHQ4EFgQUIxHDClE7t8C1tSHk 15 | ZqQhLSWvDxMwHwYDVR0jBBgwFoAUIxHDClE7t8C1tSHkZqQhLSWvDxMwDAYDVR0T 16 | BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAeJIiQDLomHcWSByouBY8kT5cTQfk 17 | lbBevxFAc2GVkj4MwXm4761lGM6I/75Wg6xFu8eERGVFO4Psubbr4B9HYhuLYE+5 18 | UcuMZFHIVrOFtOVdGuZsXC48AsqO0p97qa+NHGXBHw1XaFVkvzKE8H4kWEFf+H98 19 | fBsjha1Ckn2Q350e+LZmc+EEsyJSawXzW36GeXub5sIc4+pupvEfqtpCQ9ue4vOy 20 | OrplljbG7KLKGmMP3uLwIi3AG9GRO62IistCsc+gwD2dJnaPtmpdJb4S15lQ3PE5 21 | DBtrFV4ULsFloFeCIlEZX4obRuDl/jxz3GO0ZtdgS8BhGKS1TItm75Yndg== 22 | -----END CERTIFICATE----- 23 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.NiftyServer/IDL/ResultCode.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * Autogenerated by Thrift Compiler (0.9.3) 3 | * 4 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | * @generated 6 | */ 7 | 8 | namespace Thrifty.Samples 9 | { 10 | public enum ResultCode 11 | { 12 | OK = 0, 13 | TRY_LATER = 1, 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.NiftyServer/IDL/scribe.thrift: -------------------------------------------------------------------------------- 1 | namespace java com.labijie.mozart.test.thrift.idl 2 | namespace csharp Thrift.Samples 3 | 4 | 5 | enum ResultCode { 6 | OK, TRY_LATER 7 | } 8 | 9 | struct LogEntry { 10 | 1: string category; 11 | 2: string message; 12 | } 13 | 14 | service Scribe { 15 | ResultCode Log(1: list messages); 16 | list getMessages(); 17 | } 18 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.NiftyServer/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Thrifty.Samples.NiftyServer")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("02636ff9-72fd-4efb-bab4-afda4add986b")] 20 | [assembly: InternalsVisibleTo("Thrifty.Tests")] 21 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.NiftyServer/Properties/PublishProfiles/FolderProfile.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | FileSystem 9 | Release 10 | netcoreapp1.1 11 | bin\Release\PublishOutput 12 | win7-x64 13 | 14 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.NiftyServer/Properties/PublishProfiles/FolderProfile1.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | FileSystem 9 | Release 10 | netcoreapp1.1 11 | bin\Release\PublishOutput\win7 12 | win7-x64 13 | 14 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.NiftyServer/Properties/PublishProfiles/FolderProfile2.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | FileSystem 9 | Release 10 | netcoreapp1.1 11 | bin\Release\PublishOutput\centos7-x64 12 | centos.7-x64 13 | 14 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.NiftyServer/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Thrifty.Samples.NiftyServer": { 4 | "commandName": "Project", 5 | "commandLineArgs": "10.66.30.50 5" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /samples/Thrifty.Samples.NiftyServer/Swifty/LogEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Samples.Thrifty 7 | { 8 | [ThriftStruct] 9 | public class LogEntry 10 | { 11 | [ThriftField(1)] 12 | public string Category { get; set; } 13 | 14 | [ThriftField(2)] 15 | public string Message { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.NiftyServer/Swifty/ResultCode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Samples.Thrifty 7 | { 8 | public enum ResultCode 9 | { 10 | OK, 11 | TRY_LATER 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.NiftyServer/Swifty/Scribe.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Samples.Thrifty 7 | { 8 | using global::Thrifty.MicroServices; 9 | [ThriftService("Scribe")] 10 | public interface IScribe 11 | { 12 | [ThriftMethod] 13 | List getMessages(); 14 | 15 | [ThriftMethod] 16 | ResultCode log(List messages); 17 | } 18 | 19 | public class ScribeTest : IScribe 20 | { 21 | public List getMessages() 22 | { 23 | return new List 24 | { 25 | new LogEntry { Category = "c1", Message = Guid.NewGuid().ToString() }, 26 | new LogEntry { Category = "c2", Message = Guid.NewGuid().ToString() }, 27 | new LogEntry { Category = "c3", Message = Guid.NewGuid().ToString() } 28 | 29 | }; 30 | } 31 | 32 | public ResultCode log(List messages) 33 | { 34 | return ResultCode.TRY_LATER; 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /samples/Thrifty.Samples.NiftyServer/Swifty/ScribeTest2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Samples.Thrifty 7 | { 8 | using global::Thrifty.MicroServices; 9 | [ThriftService("Scribe2")] 10 | public interface IScribe2 11 | { 12 | [ThriftMethod] 13 | List getMessages(); 14 | 15 | [ThriftMethod] 16 | ResultCode log(List messages); 17 | } 18 | 19 | public class ScribeTest2 : IScribe2 20 | { 21 | public List getMessages() 22 | { 23 | return new List 24 | { 25 | new LogEntry { Category = "c1", Message = Guid.NewGuid().ToString() }, 26 | new LogEntry { Category = "c2", Message = Guid.NewGuid().ToString() }, 27 | new LogEntry { Category = "c3", Message = Guid.NewGuid().ToString() } 28 | 29 | }; 30 | } 31 | 32 | public ResultCode log(List messages) 33 | { 34 | return ResultCode.TRY_LATER; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /shared.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.0.6 4 | 5 | -------------------------------------------------------------------------------- /src/Thrifty.Core/DelegateRunnable.cs: -------------------------------------------------------------------------------- 1 | using DotNetty.Common.Concurrency; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty 8 | { 9 | public class DelegateRunnable : IRunnable 10 | { 11 | readonly Action action; 12 | 13 | public DelegateRunnable(Action action) 14 | { 15 | this.action = action; 16 | } 17 | 18 | public void Run() => this.action(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Thrifty.Core/DelegateTProtocolFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrift.Protocol; 6 | using Thrift.Transport; 7 | 8 | namespace Thrifty 9 | { 10 | public class DelegateTProtocolFactory : TProtocolFactory 11 | { 12 | private Func _func = null; 13 | 14 | public DelegateTProtocolFactory(Func func) 15 | { 16 | if (func == null) 17 | { 18 | throw new ArgumentNullException($"DelegateTProtocolFactory 构造函数 {nameof(func)} 参数不能为空。"); 19 | } 20 | _func = func; 21 | } 22 | 23 | public TProtocol GetProtocol(TTransport trans) 24 | { 25 | return _func(trans); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Thrifty.Core/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | //// General Information about an assembly is controlled through the following 6 | //// set of attributes. Change these attribute values to modify the information 7 | //// associated with an assembly. 8 | //[assembly: AssemblyConfiguration("")] 9 | //[assembly: AssemblyCompany("")] 10 | //[assembly: AssemblyProduct("Swfity.Core")] 11 | //[assembly: AssemblyTrademark("")] 12 | 13 | //// Setting ComVisible to false makes the types in this assembly not visible 14 | //// to COM components. If you need to access a type in this assembly from 15 | //// COM, set the ComVisible attribute to true on that type. 16 | //[assembly: ComVisible(false)] 17 | 18 | //// The following GUID is for the ID of the typelib if this project is exposed to COM 19 | //[assembly: Guid("abea2453-7a4e-4ed0-ba7c-ac6ea74ae19f")] 20 | -------------------------------------------------------------------------------- /src/Thrifty.Core/Threading/ITimerExtensions.cs: -------------------------------------------------------------------------------- 1 | using DotNetty.Common.Utilities; 2 | using Thrifty.Threading; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace Thrifty 10 | { 11 | [EditorBrowsable(EditorBrowsableState.Never)] 12 | public static class ITimerExtensions 13 | { 14 | /// 15 | /// 以 设置的时间,启动一个定时任务。 16 | /// 该任务只执行一次,并在 指定的时间之后执行。 17 | /// 18 | /// 19 | /// 20 | /// 21 | /// 22 | public static ITimeout NewTimeout(this ITimer timer, Action task, TimeSpan delay) 23 | { 24 | if (task == null) 25 | { 26 | throw new ArgumentNullException($"{nameof(ITimerExtensions)}.{nameof(NewTimeout)} 函数 {nameof(task)} 参数不能为空。"); 27 | } 28 | return timer.NewTimeout(new DelegateTimerTask(task), delay); 29 | } 30 | 31 | public class DelegateTimerTask : ITimerTask 32 | { 33 | private Action _func = null; 34 | 35 | public DelegateTimerTask(Action task) 36 | { 37 | _func = task; 38 | } 39 | 40 | public void Run(ITimeout timeout) 41 | { 42 | _func(timeout); 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Thrifty.Core/Threading/InterLockedEx.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty.Threading 8 | { 9 | public static class InterLockedEx 10 | { 11 | /// 12 | /// 和 功能相同,区别在于返回原始值。 13 | /// 14 | public static int GetAndIncrement(ref int location) 15 | { 16 | return Interlocked.Increment(ref location) - 1; 17 | } 18 | 19 | /// 20 | /// 和 功能相同,区别在于返回原始值。 21 | /// 22 | public static long GetAndIncrement(ref long location) 23 | { 24 | return Interlocked.Increment(ref location) - 1; 25 | } 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Thrifty.Core/Thrift/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | //// General Information about an assembly is controlled through the following 6 | //// set of attributes. Change these attribute values to modify the information 7 | //// associated with an assembly. 8 | //[assembly: AssemblyConfiguration("")] 9 | //[assembly: AssemblyTrademark("")] 10 | 11 | //// Setting ComVisible to false makes the types in this assembly not visible 12 | //// to COM components. If you need to access a type in this assembly from 13 | //// COM, set the ComVisible attribute to true on that type. 14 | //[assembly: ComVisible(false)] 15 | 16 | //// The following GUID is for the ID of the typelib if this project is exposed to COM 17 | //[assembly: Guid("c2509b0c-af5b-4f42-93ed-dc669ffb93bf")] 18 | -------------------------------------------------------------------------------- /src/Thrifty.Core/Thrift/Protocol/TAbstractBase.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | namespace Thrift.Protocol 21 | { 22 | public interface TAbstractBase 23 | { 24 | /// 25 | /// Writes the objects out to the protocol 26 | /// 27 | void Write(TProtocol tProtocol); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Thrifty.Core/Thrift/Protocol/TBase.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | namespace Thrift.Protocol 21 | { 22 | public interface TBase : TAbstractBase 23 | { 24 | /// 25 | /// Reads the TObject from the given input protocol. 26 | /// 27 | void Read(TProtocol tProtocol); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Thrifty.Core/Thrift/Protocol/TMessageType.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | using System; 21 | 22 | namespace Thrift.Protocol 23 | { 24 | public enum TMessageType 25 | { 26 | Call = 1, 27 | Reply = 2, 28 | Exception = 3, 29 | Oneway = 4 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Thrifty.Core/Thrift/Protocol/TProtocolFactory.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | * 19 | * Contains some contributions under the Thrift Software License. 20 | * Please see doc/old-thrift-license.txt in the Thrift distribution for 21 | * details. 22 | */ 23 | 24 | using System; 25 | using Thrift.Transport; 26 | 27 | namespace Thrift.Protocol 28 | { 29 | public interface TProtocolFactory 30 | { 31 | TProtocol GetProtocol(TTransport trans); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Thrifty.Core/Thrift/Protocol/TStruct.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | * 19 | * Contains some contributions under the Thrift Software License. 20 | * Please see doc/old-thrift-license.txt in the Thrift distribution for 21 | * details. 22 | */ 23 | 24 | using System; 25 | using System.Collections.Generic; 26 | using System.Text; 27 | 28 | namespace Thrift.Protocol 29 | { 30 | public struct TStruct 31 | { 32 | private string name; 33 | 34 | public TStruct(string name) 35 | :this() 36 | { 37 | this.name = name; 38 | } 39 | 40 | public string Name 41 | { 42 | get { return name; } 43 | set { name = value; } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Thrifty.Core/Thrift/Protocol/TType.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | * 19 | * Contains some contributions under the Thrift Software License. 20 | * Please see doc/old-thrift-license.txt in the Thrift distribution for 21 | * details. 22 | */ 23 | 24 | using System; 25 | 26 | namespace Thrift.Protocol 27 | { 28 | public enum TType : byte 29 | { 30 | Stop = 0, 31 | Void = 1, 32 | Bool = 2, 33 | Byte = 3, 34 | Double = 4, 35 | I16 = 6, 36 | I32 = 8, 37 | I64 = 10, 38 | String = 11, 39 | Struct = 12, 40 | Map = 13, 41 | Set = 14, 42 | List = 15 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Thrifty.Core/Thrift/TException.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | * 19 | * Contains some contributions under the Thrift Software License. 20 | * Please see doc/old-thrift-license.txt in the Thrift distribution for 21 | * details. 22 | */ 23 | 24 | using System; 25 | 26 | namespace Thrift 27 | { 28 | public class TException : Exception 29 | { 30 | public TException() 31 | { 32 | } 33 | 34 | public TException( string message) 35 | : base(message) 36 | { 37 | } 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Thrifty.Core/Thrift/TProcessor.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | * 19 | * Contains some contributions under the Thrift Software License. 20 | * Please see doc/old-thrift-license.txt in the Thrift distribution for 21 | * details. 22 | */ 23 | 24 | using System; 25 | using Thrift.Protocol; 26 | 27 | namespace Thrift 28 | { 29 | public interface TProcessor 30 | { 31 | bool Process(TProtocol iprot, TProtocol oprot); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Thrifty.Core/Thrift/Transport/TServerTransport.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | * 19 | * Contains some contributions under the Thrift Software License. 20 | * Please see doc/old-thrift-license.txt in the Thrift distribution for 21 | * details. 22 | */ 23 | 24 | using System; 25 | 26 | namespace Thrift.Transport 27 | { 28 | public abstract class TServerTransport 29 | { 30 | public abstract void Listen(); 31 | public abstract void Close(); 32 | protected abstract TTransport AcceptImpl(); 33 | 34 | public TTransport Accept() 35 | { 36 | TTransport transport = AcceptImpl(); 37 | if (transport == null) { 38 | throw new TTransportException("accept() may not return NULL"); 39 | } 40 | return transport; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Thrifty.Core/Thrift/Transport/TTransportFactory.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | * 19 | * Contains some contributions under the Thrift Software License. 20 | * Please see doc/old-thrift-license.txt in the Thrift distribution for 21 | * details. 22 | */ 23 | 24 | using System; 25 | 26 | namespace Thrift.Transport 27 | { 28 | /// 29 | /// From Mark Slee & Aditya Agarwal of Facebook: 30 | /// Factory class used to create wrapped instance of Transports. 31 | /// This is used primarily in servers, which get Transports from 32 | /// a ServerTransport and then may want to mutate them (i.e. create 33 | /// a BufferedTransport from the underlying base transport) 34 | /// 35 | public class TTransportFactory 36 | { 37 | public virtual TTransport GetTransport(TTransport trans) 38 | { 39 | return trans; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Client/DiscoveryEnabledServer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Steeltoe.Discovery.Eureka.AppInfo; 3 | using Thrifty.MicroServices.Server; 4 | using Newtonsoft.Json; 5 | namespace Thrifty.MicroServices.Client 6 | { 7 | public class DiscoveryEnabledServer : Ribbon.Server 8 | { 9 | public DiscoveryEnabledServer(InstanceInfo instanceInfo, bool useSecurePort, ServiceAddressUsage addressUsage) 10 | : base(instanceInfo.GetAddress(addressUsage), 11 | useSecurePort && instanceInfo.IsSecurePortEnabled ? instanceInfo.SecurePort : instanceInfo.Port) 12 | { 13 | InstanceInfo = instanceInfo; 14 | Metadata = instanceInfo.Metadata; 15 | } 16 | 17 | public InstanceInfo InstanceInfo { get; } 18 | 19 | public IDictionary Metadata { get; } 20 | 21 | private static T Parse(string json) 22 | { 23 | try 24 | { 25 | return JsonConvert.DeserializeObject(json); 26 | } 27 | catch 28 | { 29 | return default(T); 30 | } 31 | } 32 | private ThriftyServiceMetadata[] _serviceMetadata; 33 | public ThriftyServiceMetadata[] ServiceMetadata 34 | { 35 | get 36 | { 37 | if (_serviceMetadata == null) 38 | { 39 | //cache result 40 | _serviceMetadata = Parse(Metadata["services"]) ?? new ThriftyServiceMetadata[0]; 41 | } 42 | return _serviceMetadata; 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Client/LoadBalanceKey.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Thrifty.MicroServices.Client 4 | { 5 | public class LoadBalanceKey : IEquatable 6 | { 7 | public LoadBalanceKey(string version, string vipAddress) 8 | { 9 | Version = version; 10 | VipAddress = vipAddress; 11 | } 12 | 13 | public string Version { get; } 14 | 15 | public string VipAddress { get; } 16 | 17 | public bool Equals(LoadBalanceKey other) 18 | { 19 | if (ReferenceEquals(null, other)) return false; 20 | if (ReferenceEquals(this, other)) return true; 21 | return string.Equals(Version, other.Version) && string.Equals(VipAddress, other.VipAddress); 22 | } 23 | 24 | public override bool Equals(object obj) 25 | { 26 | if (ReferenceEquals(null, obj)) return false; 27 | if (ReferenceEquals(this, obj)) return true; 28 | if (obj.GetType() != this.GetType()) return false; 29 | return Equals((LoadBalanceKey)obj); 30 | } 31 | 32 | public override int GetHashCode() 33 | { 34 | unchecked 35 | { 36 | return ((Version != null ? Version.GetHashCode() : 0) * 397) ^ (VipAddress != null ? VipAddress.GetHashCode() : 0); 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Client/Pooling/IClientConnectionPool.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.MicroServices.Ribbon; 2 | using Thrifty.Nifty.Client; 3 | using System; 4 | 5 | namespace Thrifty.MicroServices.Client.Pooling 6 | { 7 | public interface IClientConnectionPool : IDisposable 8 | { 9 | INiftyClientChannel BorrowChannel(ChannelKey key); 10 | 11 | void ClearChannel(ChannelKey key); 12 | 13 | void ReturnChannel(ChannelKey key,INiftyClientChannel channel); 14 | } 15 | } -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Client/Pooling/NiftyClientChannelPool.cs: -------------------------------------------------------------------------------- 1 | using Chopin.Pooling.Impl; 2 | using Thrifty.Nifty.Client; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using Chopin.Pooling; 9 | using Thrifty.Services; 10 | 11 | namespace Thrifty.MicroServices.Client.Pooling 12 | { 13 | public class NiftyClientChannelPool : GenericKeyedObjectPool, IClientConnectionPool 14 | { 15 | public NiftyClientChannelPool(ThriftClientManager thriftClientManager, IEvictionTimer timer, ThriftyClientOptions options) 16 | : base(new NiftyClientChannelFactory(thriftClientManager, options), options.ConnectionPool, timer, options.LoggerFactory) 17 | { 18 | 19 | 20 | } 21 | 22 | public INiftyClientChannel BorrowChannel(ChannelKey key) 23 | { 24 | return this.BorrowObject(key); 25 | } 26 | 27 | public void ClearChannel(ChannelKey key) 28 | { 29 | this.Clear(key); 30 | } 31 | 32 | public void ReturnChannel(ChannelKey key,INiftyClientChannel channel) 33 | { 34 | this.ReturnObject(key,channel); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Client/ServiceAddressUsage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty.MicroServices.Client 8 | { 9 | public enum ServiceAddressUsage 10 | { 11 | IPAddress, 12 | HostName 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Client/ThriftyClientEurekaConfig.cs: -------------------------------------------------------------------------------- 1 | using Steeltoe.Discovery.Eureka; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Thrifty.MicroServices.Client 9 | { 10 | public sealed class ThriftyClientEurekaConfig : EurekaClientConfig 11 | { 12 | public ServiceAddressUsage AddressUsage { get; set; } = ServiceAddressUsage.IPAddress; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Client/ThriftyPing.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.MicroServices.Commons; 2 | using Thrifty.MicroServices.Ribbon; 3 | using Thrifty.Services; 4 | 5 | namespace Thrifty.MicroServices.Client 6 | { 7 | internal class ThriftyPing : IPing 8 | { 9 | private readonly ThriftClientManager _thriftClientManager; 10 | internal ThriftyPing(ThriftClientManager thriftClientManager) 11 | { 12 | _thriftClientManager = thriftClientManager; 13 | } 14 | 15 | public bool IsAlive(Ribbon.Server server) 16 | { 17 | var discoveryEnabledServer = server as DiscoveryEnabledServer; 18 | var host = discoveryEnabledServer == null ? server.Host : discoveryEnabledServer.InstanceInfo.IpAddr; 19 | var port = discoveryEnabledServer?.Port ?? server.Port; 20 | var checker = _thriftClientManager.CreateClientAsync(host, port).GetAwaiter().GetResult(); 21 | var x = checker.Ping(); 22 | return x == (byte)1; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Client/ThriftyRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using Thrifty.MicroServices.Ribbon.Client; 4 | 5 | namespace Thrifty.MicroServices.Client 6 | { 7 | public class ThriftyRequest : IClientRequest 8 | { 9 | public ThriftyRequest(bool retriable, int retriesNextServer, int retriesSameServer, 10 | int readTimeout, int writeTimeout, int reveiveTimeout, int connectTimeout, object[] args, MethodInfo method) 11 | { 12 | Retriable = retriable; 13 | RetriesNextServer = retriesNextServer; 14 | RetriesSameServer = retriesSameServer; 15 | ReadTimeout = readTimeout; 16 | WriteTimeout = writeTimeout; 17 | ReveiveTimeout = reveiveTimeout; 18 | ConnectTimeout = connectTimeout; 19 | Args = args; 20 | Method = method; 21 | } 22 | public Uri Uri { get; set; } 23 | public bool Retriable { get; } 24 | public ChannelKey ChannelKey { get; set; } 25 | public object Stub { get; set; } 26 | public int RetriesNextServer { get; } 27 | public int RetriesSameServer { get; } 28 | public int WriteTimeout { get; } 29 | public int ReadTimeout { get; } 30 | public int ConnectTimeout { get; } 31 | public int ReveiveTimeout { get; } 32 | 33 | public object[] Args { get; } 34 | public MethodInfo Method { get; } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Client/ThriftyResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Thrifty.MicroServices.Client 4 | { 5 | public class ThriftyResponse : Ribbon.Client.IResponse 6 | { 7 | public ThriftyResponse(object result, bool success) 8 | { 9 | Payload = result; 10 | Success = success; 11 | } 12 | public object Payload { get; } 13 | public bool HasPayload => Payload != null; 14 | public bool Success { get; } 15 | public Uri RequestedUri => null; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Commons/HealthCheckIdentifier.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Services.Metadata; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Thrifty.MicroServices.Commons 9 | { 10 | public static class HealthCheckIdentifier 11 | { 12 | public const String ServiceName = "_HealthCheck"; 13 | 14 | public const String PingMethodName = "ping"; 15 | 16 | public static String PingMethodQualifiedName 17 | { 18 | get { return ThriftMethodMetadata.GetQualifiedName(ServiceName, PingMethodName); } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Commons/IHealthCheck.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Thrifty.MicroServices.Commons 4 | { 5 | [ThriftService(HealthCheckIdentifier.ServiceName)] 6 | public interface IHealthCheck 7 | { 8 | [ThriftMethod(HealthCheckIdentifier.PingMethodName)] 9 | byte Ping(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Commons/InstanceOptions.cs: -------------------------------------------------------------------------------- 1 | namespace Thrifty.MicroServices.Commons 2 | { 3 | public class InstanceDescription 4 | { 5 | /// 初始化 类的新实例。 6 | /// app name. 7 | /// virtual host name or address. 8 | /// ip address or hostName 9 | public InstanceDescription(string appName, string vipAddress, string publicAddress = "127.0.0.1") 10 | { 11 | Guard.ArgumentNotNull(publicAddress, nameof(publicAddress)); 12 | this.AppName = appName; 13 | this.VipAddress = vipAddress; 14 | this.PublicAddress = publicAddress; 15 | } 16 | 17 | public string PublicAddress { get; } 18 | 19 | public string AppName { get; } 20 | 21 | 22 | public string VipAddress { get; } 23 | } 24 | } -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Commons/ThriftyHealthCheck.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.MicroServices.Commons 7 | { 8 | class ThriftyHealthCheck : IHealthCheck 9 | { 10 | public byte Ping() => 1; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Commons/Utils.cs: -------------------------------------------------------------------------------- 1 | using DotNetty.Common.Utilities; 2 | using System; 3 | namespace Thrifty.MicroServices.Commons 4 | { 5 | internal interface IIntervalAction 6 | { 7 | void Start(); 8 | void Stop(); 9 | } 10 | internal class Utils 11 | { 12 | private class HashedWheelTimerWrapper : IDisposable 13 | { 14 | public static readonly HashedWheelTimerWrapper Instance = new HashedWheelTimerWrapper(); 15 | public HashedWheelTimer Timer { get; } = 16 | new HashedWheelTimer(TimeSpan.FromMilliseconds(500), 2 * 60, -1);// 一分钟的时间轮,每个刻度 500 毫秒。 17 | public void Dispose() 18 | { 19 | Timer.StopAsync().GetAwaiter().GetResult(); 20 | } 21 | } 22 | public static HashedWheelTimer Timer => HashedWheelTimerWrapper.Instance.Timer; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/InstanceInfoExtensions.cs: -------------------------------------------------------------------------------- 1 | using Steeltoe.Discovery.Eureka.AppInfo; 2 | using Thrifty.MicroServices.Client; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Thrifty.MicroServices 10 | { 11 | internal static class InstanceInfoExtensions 12 | { 13 | public static string GetAddress(this InstanceInfo instance, ServiceAddressUsage usage) 14 | { 15 | switch (usage) 16 | { 17 | case ServiceAddressUsage.HostName: 18 | return instance.HostName; 19 | case ServiceAddressUsage.IPAddress: 20 | default: 21 | return instance.IpAddr; 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Thrifty.MicroServices")] 11 | [assembly: AssemblyTrademark("")] 12 | // Setting ComVisible to false makes the types in this assembly not visible 13 | // to COM components. If you need to access a type in this assembly from 14 | // COM, set the ComVisible attribute to true on that type. 15 | [assembly: ComVisible(false)] 16 | 17 | // The following GUID is for the ID of the typelib if this project is exposed to COM 18 | [assembly: Guid("085b1aca-eaa3-42d6-bb5f-cbf3820028dc")] 19 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/Client/AbstractLoadBalancerAwareClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Thrifty.MicroServices.Ribbon.Client 4 | { 5 | public abstract class AbstractLoadBalancerAwareClient : IClient 6 | where TRes : IResponse 7 | where TReq : IClientRequest 8 | { 9 | protected abstract RequestSpecificRetryHandler GetRetryHandler(TReq request); 10 | public TRes Execute(TReq request) 11 | { 12 | throw new NotImplementedException(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/Client/DefaultClientRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Thrifty.MicroServices.Ribbon.Client 4 | { 5 | public class DefaultClientRequest : IClientRequest 6 | { 7 | public DefaultClientRequest(Uri uri, bool retriable) 8 | { 9 | Uri = uri; 10 | Retriable = retriable; 11 | } 12 | 13 | public Uri Uri { get; } 14 | 15 | public bool Retriable { get; } 16 | 17 | public IClientRequest ReplaceUri(Uri uri) => new DefaultClientRequest(uri, Retriable); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/Client/IClient.cs: -------------------------------------------------------------------------------- 1 | namespace Thrifty.MicroServices.Ribbon.Client 2 | { 3 | public interface IClient 4 | where TRes : IResponse 5 | where TReq : IClientRequest 6 | { 7 | TRes Execute(TReq request); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/Client/IClientRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Thrifty.MicroServices.Ribbon.Client 4 | { 5 | public interface IClientRequest 6 | { 7 | Uri Uri { get; } 8 | bool Retriable { get; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/Client/IResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Thrifty.MicroServices.Ribbon.Client 4 | { 5 | public interface IResponse 6 | { 7 | object Payload { get; } 8 | bool HasPayload { get; } 9 | bool Success { get; } 10 | Uri RequestedUri { get; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/Client/RequestSpecificRetryHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.MicroServices.Ribbon.Client 7 | { 8 | public class RequestSpecificRetryHandler : IRetryHandler 9 | { 10 | public bool IsRetriableException(Exception exception, bool isSameServer) 11 | { 12 | throw new NotImplementedException(); 13 | } 14 | 15 | public bool IsCircuitTrippingException(Exception exception) 16 | { 17 | throw new NotImplementedException(); 18 | } 19 | 20 | public int MaxRetriesOnSameServer { get; } 21 | public int MaxRetriesOnNextServer { get; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/Compatibilities.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | 4 | namespace Thrifty.MicroServices.Ribbon 5 | { 6 | public class Counter 7 | { 8 | private long _counter; 9 | public void Increment() => Interlocked.Increment(ref _counter); 10 | public void Decrement() => Interlocked.Decrement(ref _counter); 11 | public long Value 12 | { 13 | get => _counter; 14 | set => Interlocked.Exchange(ref _counter, value); 15 | } 16 | } 17 | 18 | 19 | public abstract class Disposable : IDisposable 20 | { 21 | bool disposed = false; 22 | public void Dispose() 23 | { 24 | Dispose(true); 25 | GC.SuppressFinalize(this); 26 | } 27 | 28 | protected virtual void DisposeUnmanagedResource() { } 29 | protected abstract void DisposeManagedResource(); 30 | private void Dispose(bool disposing) 31 | { 32 | if (disposed) return; 33 | if (disposing) 34 | { 35 | DisposeManagedResource(); 36 | } 37 | disposed = true; 38 | DisposeUnmanagedResource(); 39 | } 40 | ~Disposable() 41 | { 42 | Dispose(false); 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/Config.cs: -------------------------------------------------------------------------------- 1 | namespace Thrifty.MicroServices.Ribbon 2 | { 3 | public class ClientOptions 4 | { 5 | public string ClientName { get; set; } 6 | 7 | } 8 | 9 | 10 | public class DefaultRetryPolicyOptions 11 | { 12 | public bool Enabled { get; set; } 13 | public bool MaxRetriesOnSameServer { get; set; } 14 | public bool MaxRetriesOnNextServer { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/DefaultRetryHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Thrifty.MicroServices.Ribbon 4 | { 5 | public class DefaultRetryHandler : IRetryHandler 6 | { 7 | private readonly int _retrySameServer; 8 | private readonly int _retryNextServer; 9 | private readonly bool _retryEnabled; 10 | private readonly Predicate _isCircuitTrippingException; 11 | private readonly Func _isRetriableException; 12 | 13 | public DefaultRetryHandler(int retrySameServer = 0, 14 | int retryNextServer = 0, 15 | bool retryEnabled = false, 16 | Predicate isCircuitTrippingException = null, 17 | Func isRetriableException = null) 18 | { 19 | _retrySameServer = retrySameServer; 20 | _retryNextServer = retryNextServer; 21 | _retryEnabled = retryEnabled; 22 | _isCircuitTrippingException = isCircuitTrippingException ?? (e => true); 23 | _isRetriableException = isRetriableException ?? ((e, s) => false); 24 | } 25 | 26 | public int MaxRetriesOnNextServer => _retryEnabled ? _retryNextServer : 0; 27 | public int MaxRetriesOnSameServer => _retryEnabled ? _retrySameServer : 0; 28 | public bool IsCircuitTrippingException(Exception exception) => _isCircuitTrippingException(exception); 29 | public bool IsRetriableException(Exception exception, bool sameServer) => _isRetriableException(exception, sameServer); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/ILoadBalancer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Thrifty.MicroServices.Ribbon 4 | { 5 | /// 6 | /// 负载均衡 7 | /// 8 | public interface ILoadBalancer 9 | { 10 | /// 11 | /// 添加服务器 12 | /// 13 | /// 14 | void AddServers(IList servers); 15 | /// 16 | /// 选择一个服务器 17 | /// 18 | /// 19 | Server Choose(); 20 | /// 21 | /// 下线服务器 22 | /// 23 | /// 24 | void MarkServerDown(Server server); 25 | /// 26 | /// 可达的服务器 27 | /// 28 | /// 29 | IList ReachableServers(); 30 | /// 31 | /// 全部服务器 32 | /// 33 | /// 34 | IList AllServers(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/IPing.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Thrifty.MicroServices.Ribbon 4 | { 5 | public interface IPing 6 | { 7 | bool IsAlive(Server server); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/IPingStrategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.MicroServices.Ribbon 7 | { 8 | /// 9 | /// ping的结果 10 | /// 11 | public class PingResult 12 | { 13 | public PingResult(bool isAlive, Server server) 14 | { 15 | IsAlive = isAlive; 16 | Server = server; 17 | } 18 | /// 19 | /// 服务器是否alive 20 | /// 21 | public bool IsAlive { get; } 22 | /// 23 | /// 服务器 24 | /// 25 | public Server Server { get; } 26 | } 27 | 28 | public interface IPingStrategy 29 | { 30 | IList PingServers(IPing ping, IList servers); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/IRetryHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Thrifty.MicroServices.Ribbon 4 | { 5 | public interface IRetryHandler 6 | { 7 | /// 8 | /// 是否重试的异常 9 | /// 10 | bool IsRetriableException(Exception exception, bool isSameServer); 11 | /// 12 | /// 是否中断异常 13 | /// 14 | bool IsCircuitTrippingException(Exception exception); 15 | /// 16 | /// 同server最大retry次数 17 | /// 18 | int MaxRetriesOnSameServer { get; } 19 | /// 20 | /// 新server最大retry次数 21 | /// 22 | int MaxRetriesOnNextServer { get; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/IRule.cs: -------------------------------------------------------------------------------- 1 |  2 | using System.Collections.Generic; 3 | 4 | namespace Thrifty.MicroServices.Ribbon 5 | { 6 | /// 7 | /// 负载均衡的规则 8 | /// 9 | public interface IRule 10 | { 11 | Server Choose(ILoadBalancer loadBalancer); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/IServerStatus.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Thrifty.MicroServices.Ribbon 4 | { 5 | /// 6 | /// 服务状态 7 | /// 8 | public interface IServerStatus 9 | { 10 | /// 11 | /// 所属的服务器 12 | /// 13 | Server Server { get; } 14 | /// 15 | /// 失败次数 16 | /// 17 | long FailureCount { get; } 18 | /// 19 | /// 打开的连接次数 20 | /// 21 | long OpenConnectionsCount { get; } 22 | /// 23 | /// 激活的请求数 24 | /// 25 | long ActiveRequestsCount { get; } 26 | /// 27 | /// 请求数 28 | /// 29 | long RequestCount { get; } 30 | /// 31 | /// 连续失败次数 32 | /// 33 | long SuccessiveConnectionFailureCount { get; } 34 | /// 35 | /// 响应时间的平均值 36 | /// 37 | double ResponseTimeAverage { get; } 38 | /// 39 | /// 响应时间的偏差 40 | /// 41 | double ResponseTimeStdDev { get; } 42 | /// 43 | /// 最大响应时间 44 | /// 45 | double MaximumResponseTime { get; } 46 | /// 47 | /// 最小响应时间 48 | /// 49 | double MinimumResponseTime { get; } 50 | /// 51 | /// 服务器是否暂时被中断 52 | /// 53 | /// 时间 54 | /// 是否暂时被中断 55 | bool IsCircuitBreakerTripped(DateTime time); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/IServerWeightAccumulater.cs: -------------------------------------------------------------------------------- 1 | namespace Thrifty.MicroServices.Ribbon 2 | { 3 | public interface IServerWeightAccumulater 4 | { 5 | double[] AccumulatedWeights { get; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/LoadBalancerBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.Extensions.Logging; 4 | 5 | namespace Thrifty.MicroServices.Ribbon 6 | { 7 | /// 8 | /// 负载均衡构建器 9 | /// 10 | public sealed class LoadBalancerBuilder 11 | { 12 | private LoadBalancerBuilder() { } 13 | private LoadBalancerBuilder SetField(F field, Action setter) 14 | { 15 | setter(this, field); 16 | return this; 17 | } 18 | 19 | public static LoadBalancerBuilder NewBuilder() => new LoadBalancerBuilder(); 20 | 21 | private IRule _rule; 22 | private IPing _ping; 23 | private IPingStrategy _pingStrategy; 24 | private ILoggerFactory _loggerFactory; 25 | public LoadBalancerBuilder WithLoggerFactory(ILoggerFactory factory) => SetField(factory, (b, f) => b._loggerFactory = f); 26 | public LoadBalancerBuilder WithRule(IRule rule) => SetField(rule, (b, f) => b._rule = f); 27 | public LoadBalancerBuilder WithPing(IPing ping) => SetField(ping, (b, f) => b._ping = f); 28 | public LoadBalancerBuilder WithPingStrategy(IPingStrategy pingStrategy) => SetField(pingStrategy, (b, f) => b._pingStrategy = f); 29 | 30 | public ILoadBalancer Build(string name, int pingInterval) 31 | { 32 | if (_ping == null) throw new ThriftyException($"{nameof(LoadBalancerBuilder)} missing {nameof(IPing)} configuration"); 33 | return new BaseLoadBalancer(pingInterval, name, _rule ?? new Rules.RoundRobinRule(), _ping, _pingStrategy ?? new SerialPingStrategy(), _loggerFactory); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/LoadBalancerContext.cs: -------------------------------------------------------------------------------- 1 | namespace Thrifty.MicroServices.Ribbon 2 | { 3 | public class LoadBalancerContext 4 | { 5 | public int MaxAutoRetriesNextServer { get; } 6 | public int MaxAutoRetries { get; } 7 | public ILoadBalancer LoadBalancer { get; } 8 | public string ClinetName { get; } 9 | public IRetryHandler RetryHandler { get; } 10 | public bool RetryOnAllOperations { get; } 11 | public string VipAddress { get; } 12 | 13 | public LoadBalancerContext(ILoadBalancer loadBalancer, string vipAddress) 14 | { 15 | ClinetName = "default"; 16 | MaxAutoRetriesNextServer = 1; 17 | MaxAutoRetries = 0; 18 | RetryHandler = new DefaultRetryHandler(); 19 | RetryOnAllOperations = false; 20 | VipAddress = vipAddress; 21 | LoadBalancer = loadBalancer; 22 | } 23 | 24 | public LoadBalancerContext(ILoadBalancer loadBalancer, IRetryHandler retryHandler, string vipAddress) 25 | : this(loadBalancer, vipAddress) 26 | { 27 | RetryHandler = retryHandler; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/Rules/AvailabilityFilteringRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Thrifty.MicroServices.Ribbon.Rules 6 | { 7 | public class AvailabilityFilteringRule : FilterableRule, IRule 8 | { 9 | private class AvailabilityFilter : IFilter 10 | { 11 | private readonly IServerStatusCollector _collector; 12 | private static bool EnableCircuitBreakerFiltering = false; 13 | private static int MaxActiveRequestsCount = 200; 14 | private RoundRobinRule _ribonRule; 15 | private RoundRobinRule RibonRule => _ribonRule ?? (_ribonRule = new RoundRobinRule()); 16 | 17 | private bool ShouldSkipServer(Server server) 18 | { 19 | if (_collector == null) return true; 20 | var status = _collector.ServerStatus(server); 21 | return (EnableCircuitBreakerFiltering && status.IsCircuitBreakerTripped(DateTime.Now)) 22 | || status.ActiveRequestsCount > MaxActiveRequestsCount; 23 | } 24 | public AvailabilityFilter(IServerStatusCollector collector) 25 | { 26 | _collector = collector; 27 | } 28 | 29 | public IEnumerable Filtration(IEnumerable servers) => servers.Where(x => !ShouldSkipServer(x)).ToArray(); 30 | } 31 | 32 | public AvailabilityFilteringRule(IServerStatusCollector collector) : base(new AvailabilityFilter(collector)) 33 | { 34 | 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/Rules/FilterableRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading; 4 | 5 | namespace Thrifty.MicroServices.Ribbon.Rules 6 | { 7 | public class FilterableRule : IRule 8 | { 9 | private static readonly Random Random = new Random(); 10 | private readonly IFilter _filter; 11 | 12 | public FilterableRule(IFilter filter) 13 | { 14 | if (filter == null) throw new NullReferenceException(nameof(filter)); 15 | _filter = filter; 16 | } 17 | public Server Choose(ILoadBalancer loadBalancer) 18 | { 19 | while (true) 20 | { 21 | var servers = _filter.Filtration(loadBalancer.ReachableServers()).ToArray(); 22 | var serversCount = servers?.Length ?? 0; 23 | if (serversCount == 0) return null; 24 | var server = servers[Random.Next(0, serversCount)]; 25 | if (server == null) 26 | { 27 | Thread.Sleep(5 * 1000); 28 | continue; 29 | } 30 | if (server.IsAlive && server.ReadyToServe) return server; 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/Rules/IFilter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Thrifty.MicroServices.Ribbon.Rules 4 | { 5 | public interface IFilter 6 | { 7 | IEnumerable Filtration(IEnumerable servers); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/Rules/RandomRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.MicroServices.Ribbon.Rules 7 | { 8 | public class RandomRule : IRule 9 | { 10 | private static readonly Random Random = new Random(); 11 | 12 | public Server Choose(ILoadBalancer loadBalancer) 13 | { 14 | while (true) 15 | { 16 | var servers = loadBalancer.ReachableServers(); 17 | var serversCount = servers?.Count ?? 0; 18 | if (serversCount == 0) return null; 19 | var server = servers[Random.Next(0, serversCount)]; 20 | if (server == null) 21 | { 22 | Thread.Sleep(5 * 1000); 23 | continue; 24 | } 25 | if (server.IsAlive && server.ReadyToServe) return server; 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/Rules/RoundRobinRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.MicroServices.Ribbon.Rules 7 | { 8 | public class RoundRobinRule : IRule 9 | { 10 | 11 | private volatile int _timer = 0; 12 | 13 | public Server Choose(ILoadBalancer loadBalancer) 14 | { 15 | var count = 0; 16 | while (count++ < 10) 17 | { 18 | var servers = loadBalancer.ReachableServers(); 19 | var serversCount = servers?.Count ?? 0; 20 | if (serversCount == 0) return null; 21 | var server = servers[GetModulo(serversCount)]; 22 | if (server == null) 23 | { 24 | Thread.Sleep(5 * 1000); 25 | continue; 26 | } 27 | if (server.IsAlive && server.ReadyToServe) return server; 28 | } 29 | return null; 30 | } 31 | 32 | 33 | private int GetModulo(int modulo) 34 | { 35 | while (true) 36 | { 37 | Interlocked.Add(ref _timer, 1); 38 | var current = _timer; 39 | var next = (current + 1) % modulo; 40 | //var value = Interlocked.CompareExchange(ref _timer, next, current); 41 | //if (value == current) 42 | return next; 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Ribbon/SerialPingStrategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Thrifty.MicroServices.Ribbon 6 | { 7 | public class SerialPingStrategy : IPingStrategy 8 | { 9 | 10 | private bool IsAlive(IPing ping, Server server) 11 | { 12 | try 13 | { 14 | return ping.IsAlive(server); 15 | } 16 | catch 17 | { 18 | return false; 19 | } 20 | } 21 | public IList PingServers(IPing ping, IList servers) 22 | => (from server in servers select new PingResult(IsAlive(ping, server), server)) 23 | .ToList() 24 | .AsReadOnly(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Server/IServerFuture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.MicroServices.Server 7 | { 8 | /// 9 | /// 服务器特征 10 | /// 11 | public interface IServerFuture 12 | { 13 | /// 14 | /// 服务器是否启动 15 | /// 16 | bool IsStart { get; } 17 | 18 | /// 19 | /// 服务器是否关闭 20 | /// 21 | bool IsClosed { get; } 22 | 23 | /// 24 | /// 服务器是否出错 25 | /// 26 | bool IsError { get; } 27 | 28 | /// 29 | /// 服务器关闭 30 | /// 31 | /// 32 | Task ShutdownAsync(); 33 | 34 | /// 35 | /// 服务器启动 36 | /// 37 | /// 38 | Task StartAsync(); 39 | 40 | /// 41 | /// 添加启动监听器 42 | /// 43 | /// 44 | /// 45 | IServerFuture AddStartListener(Action action); 46 | 47 | /// 48 | /// 添加关闭监听器 49 | /// 50 | /// 51 | /// 52 | IServerFuture AddShutdownListener(Action action); 53 | } 54 | } -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Server/ThriftyServerOptions.cs: -------------------------------------------------------------------------------- 1 | using Steeltoe.Discovery.Eureka; 2 | using Thrifty.MicroServices.Commons; 3 | using Thrifty.Services; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using Thrifty.Nifty.Ssl; 10 | 11 | namespace Thrifty.MicroServices.Server 12 | { 13 | public class ThriftyServerOptions : ThriftServerConfig 14 | { 15 | private EurekaClientConfig _eurekaConfig = null; 16 | private SslConfig _sslConfig = null; 17 | 18 | public ThriftyServerOptions() 19 | { 20 | this.EurekaEnabled = true; 21 | } 22 | 23 | public bool EurekaEnabled { get; set; } 24 | 25 | public SslConfig Ssl 26 | { 27 | get { return _sslConfig ?? (_sslConfig = new SslConfig()); } 28 | set { _sslConfig = value; } 29 | } 30 | 31 | 32 | public EurekaClientConfig Eureka 33 | { 34 | get { return _eurekaConfig ?? (_eurekaConfig = new EurekaClientConfig()); } 35 | set { _eurekaConfig = value; } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Thrifty.MicroServices/Server/ThriftyServiceDescriptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty.MicroServices.Server 8 | { 9 | public class ThriftyServiceDescriptor : IEquatable 10 | { 11 | public ThriftyServiceDescriptor(Type serviceType, string version = "1.0.0") 12 | { 13 | Guard.ArgumentNotNull(serviceType, nameof(serviceType)); 14 | this.ServiceType = serviceType; 15 | this.Metadata = new ThriftyServiceMetadata(serviceType, version); 16 | } 17 | 18 | public Type ServiceType { get; } 19 | 20 | public ThriftyServiceMetadata Metadata { get; } 21 | 22 | public bool Equals(ThriftyServiceDescriptor other) 23 | { 24 | if (ReferenceEquals(null, other)) return false; 25 | if (ReferenceEquals(this, other)) return true; 26 | return Equals(ServiceType, other.ServiceType) && Equals(Metadata, other.Metadata); 27 | } 28 | 29 | public override bool Equals(object obj) 30 | { 31 | if (ReferenceEquals(null, obj)) return false; 32 | if (ReferenceEquals(this, obj)) return true; 33 | if (obj.GetType() != this.GetType()) return false; 34 | return Equals((ThriftyServiceDescriptor)obj); 35 | } 36 | 37 | public override int GetHashCode() 38 | { 39 | unchecked 40 | { 41 | return ((ServiceType != null ? ServiceType.GetHashCode() : 0) * 397) ^ (Metadata != null ? Metadata.GetHashCode() : 0); 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty.Client/AbstractClientChannel.IoThreadBoundTimerTask.cs: -------------------------------------------------------------------------------- 1 | using DotNetty.Common.Utilities; 2 | using Thrifty.Threading; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace Thrifty.Nifty.Client 9 | { 10 | partial class AbstractClientChannel 11 | { 12 | 13 | /** 14 | * Used to create TimerTasks that will fire 15 | */ 16 | private class IoThreadBoundTimerTask : ITimerTask 17 | { 18 | private INiftyClientChannel channel; 19 | private ITimerTask timerTask; 20 | 21 | public IoThreadBoundTimerTask(INiftyClientChannel channel, Action timerTask) 22 | : this(channel, new ITimerExtensions.DelegateTimerTask(timerTask)) 23 | { 24 | 25 | } 26 | 27 | public IoThreadBoundTimerTask(INiftyClientChannel channel, ITimerTask timerTask) 28 | { 29 | this.channel = channel; 30 | this.timerTask = timerTask; 31 | } 32 | 33 | public void Run(ITimeout timeout) 34 | { 35 | channel.ExecuteInIoThread(new DelegateRunnable(() => 36 | { 37 | try 38 | { 39 | timerTask.Run(timeout); 40 | } 41 | catch (Exception e) 42 | { 43 | channel.NettyChannel.Pipeline.FireExceptionCaught(e); 44 | } 45 | })); 46 | } 47 | 48 | 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty.Client/AbstractClientChannel.Request.cs: -------------------------------------------------------------------------------- 1 | using DotNetty.Common.Utilities; 2 | using Thrifty.Threading; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace Thrifty.Nifty.Client 9 | { 10 | partial class AbstractClientChannel 11 | { 12 | 13 | /** 14 | * Bundles the details of a client request that has started, but for which a response hasn't 15 | * yet been received (or in the one-way case, the send operation hasn't completed yet). 16 | */ 17 | private class Request 18 | { 19 | 20 | public Request(IListener listener) 21 | { 22 | this.Listener = listener; 23 | } 24 | 25 | 26 | public IListener Listener { get; } 27 | public ITimeout SendTimeout { get; set; } 28 | public ITimeout ReceiveTimeout { get; set; } 29 | 30 | public ITimeout ReadTimeout { get; set; } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty.Client/FramedClientChannel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using DotNetty.Buffers; 6 | using DotNetty.Transport.Channels; 7 | using Microsoft.Extensions.Logging; 8 | using Thrifty.Nifty.Duplex; 9 | using Thrifty.Threading; 10 | using DotNetty.Common.Utilities; 11 | 12 | namespace Thrifty.Nifty.Client 13 | { 14 | public class FramedClientChannel : AbstractClientChannel 15 | { 16 | public FramedClientChannel(IChannel nettyChannel, ITimer timer, TDuplexProtocolFactory protocolFactory, ILoggerFactory loggerFactory = null) 17 | : base(nettyChannel, timer, protocolFactory, loggerFactory) 18 | { 19 | } 20 | 21 | protected override IByteBuffer ExtractResponse(object message) 22 | { 23 | IByteBuffer buffer = message as IByteBuffer; 24 | if (buffer == null) { 25 | return null; 26 | } 27 | 28 | 29 | if (!buffer.IsReadable()) 30 | { 31 | return null; 32 | } 33 | 34 | return buffer; 35 | } 36 | 37 | protected override Task WriteRequestAsync(IByteBuffer request) 38 | { 39 | return this.NettyChannel.WriteAndFlushAsync(request); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty.Client/IClientRequestContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Threading.Tasks; 6 | using Thrift.Protocol; 7 | 8 | namespace Thrifty.Nifty.Client 9 | { 10 | public interface IClientRequestContext 11 | { 12 | TProtocol OutputProtocol { get; } 13 | 14 | TProtocol InputProtocol { get; } 15 | 16 | IRequestChannel RequestChannel { get; } 17 | 18 | EndPoint RemoteAddress { get; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty.Client/INiftyClientChannel.cs: -------------------------------------------------------------------------------- 1 | using DotNetty.Common.Concurrency; 2 | using DotNetty.Transport.Channels; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace Thrifty.Nifty.Client 9 | { 10 | public interface INiftyClientChannel : IRequestChannel 11 | { 12 | /// 13 | /// a timeout used to limit elapsed time for sending a message. 14 | /// 15 | TimeSpan? SendTimeout { get; set; } 16 | 17 | /// 18 | /// Sets a timeout used to limit elapsed time between successful send, and reception of the response. 19 | /// 20 | TimeSpan? ReceiveTimeout { get; set; } 21 | 22 | /// 23 | /// Sets a timeout used to limit the time that the client waits for data to be sent by the server. 24 | /// 25 | TimeSpan? ReadTimeout { get; set; } 26 | 27 | /// 28 | /// Executes the given {@link Runnable} on the I/O thread that manages reads/writes for this channel. 29 | /// 30 | /// 31 | void ExecuteInIoThread(IRunnable runnable); 32 | 33 | IChannel NettyChannel { get; } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty.Client/INiftyClientConnector.cs: -------------------------------------------------------------------------------- 1 | using DotNetty.Transport.Bootstrapping; 2 | using DotNetty.Transport.Channels; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Net; 7 | using System.Threading.Tasks; 8 | 9 | namespace Thrifty.Nifty.Client 10 | { 11 | public interface INiftyClientConnector 12 | where T : IRequestChannel 13 | { 14 | 15 | EndPoint ServerAddress { get; } 16 | 17 | Task ConnectAsync(Bootstrap bootstrap); 18 | 19 | T NewThriftClientChannel(IChannel channel, NettyClientConfig clientConfig); 20 | 21 | void ConfigureChannelPipeline(IChannelPipeline pipeline, int maxFrameSize, NettyClientConfig clientConfig, ClientSslConfig sslConfig); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty.Client/IRequestChannel.cs: -------------------------------------------------------------------------------- 1 | using DotNetty.Buffers; 2 | using Thrifty.Nifty.Duplex; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using Thrift; 9 | 10 | namespace Thrifty.Nifty.Client 11 | { 12 | public interface IRequestChannel 13 | { 14 | void WaitForFree(); 15 | 16 | /// 17 | /// Sends a single message asynchronously, and notifies the {@link Listener}when the request is finished sending, 18 | /// when the response has arrived, and/or when an error occurs. 19 | /// 20 | void SendAsynchronousRequest(IByteBuffer request, 21 | bool oneway, IListener listener); 22 | 23 | /// 24 | /// Closes the channel 25 | /// 26 | /// 27 | Task CloseAsync(); 28 | 29 | /// 30 | /// Checks whether the channel has encountered an error. 31 | /// 32 | bool HasError { get; } 33 | 34 | /// 35 | /// Returns the {@link TException} representing the error the channel encountered, if any. 36 | /// 37 | /// An instance of {@link TException} or {@code null} if the channel is still good. 38 | TException GetError(); 39 | 40 | 41 | /// 42 | /// Returns the {@link TDuplexProtocolFactory} that should be used by clients code to serialize messages for sending on this channel. 43 | /// 44 | TDuplexProtocolFactory ProtocolFactory { get; } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty.Client/NettyClientConfig.cs: -------------------------------------------------------------------------------- 1 | using DotNetty.Common.Concurrency; 2 | using DotNetty.Common.Utilities; 3 | using DotNetty.Transport.Channels; 4 | using Thrifty.Threading; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Net; 9 | using System.Threading.Tasks; 10 | using Thrifty.Nifty.Ssl; 11 | 12 | namespace Thrifty.Nifty.Client 13 | { 14 | public class NettyClientConfig 15 | { 16 | private readonly IDictionary _bootstrapOptions; 17 | 18 | public NettyClientConfig(IDictionary bootstrapOptions = null, 19 | ITimer timer = null, 20 | IEventLoopGroup workerExecutor = null) 21 | { 22 | this._bootstrapOptions = bootstrapOptions ?? new Dictionary(); 23 | //this.DefaultSocksProxyAddress = defaultSocksProxyAddress; 24 | this.Timer = timer ?? new HashedWheelTimer(); 25 | //this.BossExecutor = bossExecutor ?? new MultithreadEventLoopGroup(1); 26 | this.WorkerExecutor = workerExecutor ?? new MultithreadEventLoopGroup(); 27 | //this.sslClientConfiguration = sslClientConfiguration; 28 | } 29 | 30 | //public IEventExecutorGroup BossExecutor { get; } 31 | 32 | /// 33 | /// 获取 Sock代理,当前版本无效,总是返回 null. 34 | /// 35 | public IPEndPoint DefaultSocksProxyAddress { get; } 36 | 37 | public ITimer Timer { get; } 38 | 39 | public IEventLoopGroup WorkerExecutor { get; } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty.Client/NiftyClientChannelPipelineSetup.cs: -------------------------------------------------------------------------------- 1 | using DotNetty.Codecs; 2 | using DotNetty.Transport.Channels; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace Thrifty.Nifty.Client 9 | { 10 | internal class NiftyClientChannelPipelineSetup 11 | { 12 | private readonly int _maxFrameSize; 13 | 14 | NiftyClientChannelPipelineSetup(int maxFrameSize) 15 | { 16 | this._maxFrameSize = maxFrameSize; 17 | } 18 | 19 | private IChannelPipeline Setup(IChannelPipeline cp) 20 | { 21 | cp.AddLast("frameEncoder", new LengthFieldPrepender(4)); 22 | cp.AddLast("frameDecoder", new LengthFieldBasedFrameDecoder(_maxFrameSize, 0, 4, 0, 4)); 23 | return cp; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty.Client/NiftyClientRequestContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Threading.Tasks; 6 | using Thrift.Protocol; 7 | 8 | namespace Thrifty.Nifty.Client 9 | { 10 | public class NiftyClientRequestContext : IClientRequestContext 11 | { 12 | public NiftyClientRequestContext(TProtocol inputProtocol, TProtocol outputProtocol, IRequestChannel requestChannel, EndPoint remoteAddress) 13 | { 14 | this.InputProtocol = inputProtocol; 15 | this.OutputProtocol = outputProtocol; 16 | this.RequestChannel = requestChannel; 17 | this.RemoteAddress = remoteAddress; 18 | } 19 | 20 | public TProtocol InputProtocol { get; } 21 | 22 | public TProtocol OutputProtocol { get; } 23 | 24 | public EndPoint RemoteAddress { get; } 25 | 26 | public IRequestChannel RequestChannel { get; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty.Client/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Thrifty.Nifty.Client")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("499a85dc-b61c-4a54-ad57-d5ed22952ba0")] 20 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty.Client/UnframedClientChannel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using DotNetty.Buffers; 6 | using DotNetty.Transport.Channels; 7 | using Microsoft.Extensions.Logging; 8 | using Thrifty.Nifty.Duplex; 9 | using Thrifty.Threading; 10 | using DotNetty.Common.Utilities; 11 | 12 | namespace Thrifty.Nifty.Client 13 | { 14 | public class UnframedClientChannel : AbstractClientChannel 15 | { 16 | public UnframedClientChannel(IChannel nettyChannel, ITimer timer, TDuplexProtocolFactory protocolFactory, ILoggerFactory loggerFactory = null) : 17 | base(nettyChannel, timer, protocolFactory, loggerFactory) 18 | { 19 | } 20 | 21 | protected override IByteBuffer ExtractResponse(object message) 22 | { 23 | IByteBuffer buffer = message as IByteBuffer; 24 | if (buffer == null) 25 | { 26 | return null; 27 | } 28 | 29 | 30 | if (!buffer.IsReadable()) 31 | { 32 | return null; 33 | } 34 | 35 | return buffer; 36 | } 37 | 38 | protected override Task WriteRequestAsync(IByteBuffer request) 39 | { 40 | return this.NettyChannel.WriteAndFlushAsync(request); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty.Client/UnframedClientConnector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Threading.Tasks; 6 | using DotNetty.Transport.Channels; 7 | using Thrifty.Nifty.Duplex; 8 | using Thrifty.Nifty.Core; 9 | 10 | namespace Thrifty.Nifty.Client 11 | { 12 | public class UnframedClientConnector : AbstractClientConnector 13 | { 14 | public UnframedClientConnector(EndPoint address) : this(address, UnframedClientConnector.GetDefaultProtocolFactory()) 15 | { 16 | } 17 | 18 | public UnframedClientConnector(EndPoint address, TDuplexProtocolFactory protocolFactory) : base(address, protocolFactory) 19 | { 20 | } 21 | 22 | protected override void OnConfigureChannelPipeline(IChannelPipeline pipeline, int maxFrameSize, NettyClientConfig clientConfig) 23 | { 24 | TimeoutHandler.AddToPipeline(pipeline); 25 | pipeline.AddLast("thriftUnframedDecoder", new ThriftUnframedDecoder()); 26 | //if (clientConfig.sslClientConfiguration() != null) 27 | //{ 28 | // pipeline.addFirst("ssl", clientConfig.sslClientConfiguration().createHandler(address)); 29 | //} 30 | } 31 | 32 | public override UnframedClientChannel NewThriftClientChannel(IChannel nettyChannel, NettyClientConfig clientConfig) 33 | { 34 | UnframedClientChannel channel = new UnframedClientChannel(nettyChannel, clientConfig.Timer, this.ProtocolFactory); 35 | var cp = nettyChannel.Pipeline; 36 | TimeoutHandler.AddToPipeline(cp); 37 | cp.AddLast("thriftHandler", channel); 38 | return channel; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Codecs/DefaultThriftFrameCodecFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using DotNetty.Transport.Channels; 6 | using Thrift.Protocol; 7 | using Microsoft.Extensions.Logging; 8 | 9 | namespace Thrifty.Nifty.Codecs 10 | { 11 | public class DefaultThriftFrameCodecFactory : IThriftFrameCodecFactory 12 | { 13 | public IChannelHandler Create(long maxFrameSize, TProtocolFactory defaultProtocolFactory, ILoggerFactory loggerFactory) 14 | { 15 | defaultProtocolFactory = defaultProtocolFactory ?? new TBinaryProtocol.Factory(); 16 | return new DefaultThriftFrameCodec(maxFrameSize, defaultProtocolFactory); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Codecs/IThriftFrameCodec.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using DotNetty; 6 | using DotNetty.Transport.Channels; 7 | 8 | namespace Thrifty.Nifty.Codecs 9 | { 10 | /// 11 | /// 表示一个 Thrift 帧解析的 12 | /// 13 | public interface IThriftFrameCodec : IChannelHandler 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Codecs/IThriftFrameCodecFactory.cs: -------------------------------------------------------------------------------- 1 | using DotNetty.Transport.Channels; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using Thrift.Protocol; 8 | 9 | namespace Thrifty.Nifty.Codecs 10 | { 11 | public interface IThriftFrameCodecFactory 12 | { 13 | IChannelHandler Create(long maxFrameSize, TProtocolFactory defaultProtocolFactory, ILoggerFactory loggerFactory); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Codecs/ThriftFrameDecoder.cs: -------------------------------------------------------------------------------- 1 | using DotNetty.Codecs; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using DotNetty.Buffers; 7 | using DotNetty.Transport.Channels; 8 | using Thrift.Protocol; 9 | using Thrifty.Nifty.Core; 10 | 11 | namespace Thrifty.Nifty.Codecs 12 | { 13 | /// 14 | /// 提供 Thrift 解码 15 | /// 16 | public abstract class ThriftFrameDecoder : ByteToMessageDecoder 17 | { 18 | protected abstract ThriftMessage Decode(IChannelHandlerContext ctx, IByteBuffer buffer); 19 | 20 | protected override void Decode(IChannelHandlerContext context, IByteBuffer message, List output) 21 | { 22 | Guard.ArgumentNotNull(context, nameof(context)); 23 | Guard.ArgumentNotNull(message, nameof(message)); 24 | Guard.ArgumentNotNull(output, nameof(output)); 25 | 26 | var decoded = this.Decode(context, message); 27 | 28 | if (decoded != null) 29 | { 30 | output.Add(decoded); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Core/ConnectionContextHandler.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Nifty.Ssl; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using DotNetty.Transport.Channels; 7 | using DotNetty.Common.Utilities; 8 | using DotNetty.Buffers; 9 | 10 | namespace Thrifty.Nifty.Core 11 | { 12 | public class ConnectionContextHandler : ChannelHandlerAdapter 13 | { 14 | public const String NiftyConnectionContextKey = "Nifty.NContext"; 15 | 16 | 17 | public override void ChannelRead(IChannelHandlerContext context, object message) 18 | { 19 | AttributeKey key = AttributeKey.ValueOf(NiftyConnectionContextKey); 20 | NiftyConnectionContext nContext = context.GetAttribute(key).Get(); 21 | base.ChannelRead(context, message); 22 | } 23 | 24 | public override void ChannelActive(IChannelHandlerContext context) 25 | { 26 | base.ChannelActive(context); 27 | NiftyConnectionContext ncontext = new NiftyConnectionContext(); 28 | ncontext.RemoteAddress = context.Channel.RemoteAddress; 29 | AttributeKey key = AttributeKey.ValueOf(NiftyConnectionContextKey); 30 | context.GetAttribute(key).Set(ncontext); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Core/INiftySecurityFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Nifty.Core 7 | { 8 | public interface INiftySecurityFactory 9 | { 10 | INiftySecurityHandlers GetSecurityHandlers(ThriftServerDef def, NettyServerConfig serverConfig); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Core/INiftySecurityHandlers.cs: -------------------------------------------------------------------------------- 1 | using DotNetty.Transport.Channels; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty.Nifty.Core 8 | { 9 | public interface INiftySecurityHandlers 10 | { 11 | IChannelHandler GetAuthenticationHandler(); 12 | IChannelHandler GetEncryptionHandler(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Core/IdleDisconnectHandler.cs: -------------------------------------------------------------------------------- 1 | using DotNetty.Handlers.Timeout; 2 | using DotNetty.Transport.Channels; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace Thrifty.Nifty.Core 9 | { 10 | public class IdleDisconnectHandler : ChannelHandlerAdapter 11 | { 12 | public override void UserEventTriggered(IChannelHandlerContext context, object evt) 13 | { 14 | IdleStateEvent idleStateEvent = evt as IdleStateEvent; 15 | if (idleStateEvent != null && idleStateEvent.State == IdleState.ReaderIdle) 16 | { 17 | //异步关闭,无需等待线程。 18 | context.Channel.CloseAsync(); 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Core/NettyServerTransport.ConnectionLimiter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using DotNetty.Transport.Channels; 6 | using System.Threading; 7 | using Microsoft.Extensions.Logging; 8 | using Thrifty; 9 | using Microsoft.Extensions.Logging.Abstractions; 10 | 11 | namespace Thrifty.Nifty.Core 12 | { 13 | partial class NettyServerTransport 14 | { 15 | private class ConnectionLimiter : ChannelHandlerAdapter 16 | { 17 | private int numConnections; 18 | private readonly int maxConnections; 19 | private ILogger _logger = null; 20 | 21 | public ConnectionLimiter(int maxConnections, ILoggerFactory loggerFactory = null) 22 | { 23 | this.maxConnections = maxConnections; 24 | _logger = loggerFactory?.CreateLogger() ?? (ILogger)NullLogger.Instance; 25 | } 26 | 27 | public override void ChannelActive(IChannelHandlerContext context) 28 | { 29 | if (maxConnections > 0 && Interlocked.Increment(ref numConnections) > maxConnections) 30 | { 31 | context.Channel.CloseAsync().GetAwaiter().GetResult(); 32 | // numConnections will be decremented in channelClosed 33 | _logger.LogInformation("Accepted connection above limit (%s). Dropping.", maxConnections); 34 | } 35 | base.ChannelActive(context); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Core/NiftyConnectionContext.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Nifty.Ssl; 2 | using System; 3 | using System.Collections.Concurrent; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Net; 7 | using System.Threading.Tasks; 8 | 9 | namespace Thrifty.Nifty.Core 10 | { 11 | public class NiftyConnectionContext : IConnectionContext 12 | { 13 | //private SslSession _sslSession; 14 | private ConcurrentDictionary _attributes = new ConcurrentDictionary(); 15 | 16 | public EndPoint RemoteAddress { get; set; } 17 | 18 | public SslSession SslSession { get; set; } 19 | 20 | public IEnumerable> Attributes 21 | { 22 | get { return _attributes; } 23 | } 24 | 25 | public object GetAttribute(string attributeName) 26 | { 27 | Guard.ArgumentNullOrWhiteSpaceString(attributeName, nameof(attributeName)); 28 | Object val = null; 29 | this._attributes.TryGetValue(attributeName, out val); 30 | return val; 31 | } 32 | 33 | public object SetAttribute(string attributeName, object value) 34 | { 35 | Guard.ArgumentNullOrWhiteSpaceString(attributeName, nameof(attributeName)); 36 | this._attributes[attributeName] = value; 37 | return value; 38 | } 39 | 40 | public object RemoveAttribute(string attributeName) 41 | { 42 | Guard.ArgumentNullOrWhiteSpaceString(attributeName, nameof(attributeName)); 43 | Object old = null; 44 | this._attributes.TryRemove(attributeName, out old); 45 | return old; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Core/NiftyRequestContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using Thrift.Protocol; 5 | 6 | namespace Thrifty.Nifty.Core 7 | { 8 | public class NiftyRequestContext : IRequestContext 9 | { 10 | private ConcurrentDictionary _data; 11 | public TProtocol OutputProtocol { get; } 12 | 13 | public TProtocol InputProtocol { get; } 14 | 15 | public IConnectionContext ConnectionContext { get; } 16 | 17 | public IEnumerable> ContextData => this._data; 18 | 19 | public TNiftyTransport NiftyTransport { get; } 20 | 21 | public Guid Id { get; } 22 | 23 | public NiftyRequestContext(IConnectionContext context, TProtocol inputProtocol, TProtocol outputProtocol, TNiftyTransport niftyTransport) 24 | { 25 | _data = new ConcurrentDictionary(); 26 | this.ConnectionContext = context; 27 | this.InputProtocol = inputProtocol; 28 | this.OutputProtocol = outputProtocol; 29 | this.NiftyTransport = niftyTransport; 30 | this.Id = Guid.NewGuid(); 31 | } 32 | 33 | public void SetContextData(string key, object val) 34 | { 35 | this._data[key] = val; 36 | } 37 | 38 | public object GetContextData(string key) 39 | { 40 | object val = null; 41 | this._data.TryGetValue(key, out val); 42 | return val; 43 | } 44 | 45 | public void ClearContextData(string key) 46 | { 47 | this._data.Clear(); 48 | } 49 | 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Core/ShutdownUtil.cs: -------------------------------------------------------------------------------- 1 | using DotNetty.Common.Concurrency; 2 | using DotNetty.Transport.Channels.Groups; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace Thrifty.Nifty.Core 9 | { 10 | public class ShutdownUtil 11 | { 12 | public static Task ShutdownChannelAsync( 13 | IEventExecutorGroup bossExecutor, 14 | IEventExecutorGroup workerExecutor, 15 | IChannelGroup allChannels, 16 | TimeSpan timeSpan) 17 | { 18 | timeSpan = timeSpan.TotalSeconds <= 2 ? TimeSpan.FromSeconds(3) : timeSpan; 19 | List tasks = new List(); 20 | // Close all channels 21 | if (allChannels != null) 22 | { 23 | tasks.Add(allChannels.CloseAsync()); 24 | } 25 | 26 | // Stop boss threads 27 | if (bossExecutor != null) 28 | { 29 | tasks.Add(bossExecutor.ShutdownGracefullyAsync(TimeSpan.FromSeconds(2), timeSpan)); 30 | } 31 | 32 | // Finally stop I/O workers 33 | if (workerExecutor != null) 34 | { 35 | tasks.Add(workerExecutor.ShutdownGracefullyAsync(TimeSpan.FromSeconds(2), timeSpan)); 36 | } 37 | return Task.WhenAll(tasks.ToArray()); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Core/ThriftTransportType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Nifty.Core 7 | { 8 | public enum ThriftTransportType 9 | { 10 | Unframed, 11 | Framed, 12 | Http, 13 | Header 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Core/ThriftUnframedDecoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using DotNetty.Buffers; 6 | using DotNetty.Transport.Channels; 7 | using Thrift.Transport; 8 | using Thrift.Protocol; 9 | 10 | namespace Thrifty.Nifty.Core 11 | { 12 | public class ThriftUnframedDecoder : DotNetty.Codecs.ByteToMessageDecoder 13 | { 14 | 15 | protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List output) 16 | { 17 | int messageBeginIndex = input.ReaderIndex; 18 | IByteBuffer messageBuffer = null; 19 | 20 | try 21 | { 22 | using (TTransport transport = new TChannelBufferInputTransport(input)) 23 | { 24 | using (TBinaryProtocol protocol = new TBinaryProtocol(transport)) 25 | { 26 | protocol.ReadMessageBegin(); 27 | TProtocolUtil.Skip(protocol, TType.Struct); 28 | protocol.ReadMessageEnd(); 29 | 30 | messageBuffer = input.Slice(messageBeginIndex, input.ReaderIndex); 31 | } 32 | } 33 | 34 | } 35 | catch (IndexOutOfRangeException) 36 | { 37 | input.SetReaderIndex(messageBeginIndex); 38 | return; 39 | } 40 | catch (Exception ex) 41 | { 42 | ex.ThrowIfNecessary(); 43 | input.SetReaderIndex(messageBeginIndex); 44 | return; 45 | } 46 | 47 | output.Add(messageBuffer); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Duplex/TProtocolPair.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrift.Protocol; 6 | 7 | namespace Thrifty.Nifty.Duplex 8 | { 9 | /// 10 | /// Represents a pair of protocols: one for input and one for output. 11 | /// 12 | public class TProtocolPair 13 | { 14 | protected TProtocolPair(TProtocol inputProtocol, TProtocol outputProtocol) 15 | { 16 | this.InputProtocol = inputProtocol; 17 | this.OutputProtocol = outputProtocol; 18 | } 19 | 20 | public TProtocol InputProtocol { get; } 21 | 22 | public TProtocol OutputProtocol { get; } 23 | 24 | public static TProtocolPair FromSeparateProtocols(TProtocol inputProtocol, TProtocol outputProtocol) 25 | { 26 | return new TProtocolPair(inputProtocol, outputProtocol); 27 | } 28 | 29 | public static TProtocolPair FromSingleProtocol(TProtocol protocol) 30 | { 31 | return new TProtocolPair(protocol, protocol); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Duplex/TTransportPair.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrift.Transport; 6 | 7 | namespace Thrifty.Nifty.Duplex 8 | { 9 | /// 10 | /// Represents a pair of transports: one for input and one for output. 11 | /// 12 | public class TTransportPair 13 | { 14 | protected TTransportPair(TTransport inputTransport, TTransport outputTransport) 15 | { 16 | this.InputTransport = inputTransport; 17 | this.OutputTransport = outputTransport; 18 | } 19 | 20 | public TTransport InputTransport { get; private set; } 21 | 22 | public TTransport OutputTransport { get; private set; } 23 | 24 | public static TTransportPair FromSeparateTransports(TTransport inputTransport, TTransport outputTransport) 25 | { 26 | return new TTransportPair(inputTransport, outputTransport); 27 | } 28 | 29 | public static TTransportPair FromSingleTransport(TTransport transport) 30 | { 31 | return new TTransportPair(transport, transport); 32 | } 33 | 34 | public void Release() 35 | { 36 | this.InputTransport = null; 37 | this.OutputTransport = null; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Processors/INiftyProcessor.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Nifty.Core; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Thrift; 7 | using Thrift.Protocol; 8 | 9 | namespace Thrifty.Nifty.Processors 10 | { 11 | public interface INiftyProcessor 12 | { 13 | Task ProcessAsync(TProtocol protocolIn, TProtocol protocolOut, IRequestContext requestContext); 14 | } 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Processors/INiftyProcessorFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrift.Transport; 6 | 7 | namespace Thrifty.Nifty.Processors 8 | { 9 | public interface INiftyProcessorFactory 10 | { 11 | INiftyProcessor GetProcessor(TTransport transport); 12 | } 13 | 14 | public class DelegateNiftyProcessorFactory : INiftyProcessorFactory 15 | { 16 | private Func _func; 17 | public DelegateNiftyProcessorFactory(Func func) 18 | { 19 | Guard.ArgumentNotNull(func, nameof(func)); 20 | _func = func; 21 | } 22 | 23 | public INiftyProcessor GetProcessor(TTransport transport) 24 | { 25 | return _func(transport); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Processors/Processors.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Nifty.Core; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Thrift; 7 | using Thrift.Protocol; 8 | 9 | namespace Thrifty.Nifty.Processors 10 | { 11 | public class DelegateNiftyProcessor : INiftyProcessor 12 | { 13 | private readonly Func _func; 14 | 15 | public DelegateNiftyProcessor(Func func) 16 | { 17 | Guard.ArgumentNotNull(func, nameof(func)); 18 | _func = func; 19 | } 20 | 21 | public Task ProcessAsync(TProtocol protocolIn, TProtocol protocolOut, IRequestContext requestContext) 22 | { 23 | return Task.Run(() => _func(protocolIn, protocolOut, requestContext)); 24 | } 25 | } 26 | 27 | public class DelegateTProcessor : TProcessor 28 | { 29 | private readonly Func _func; 30 | 31 | public DelegateTProcessor(Func func) 32 | { 33 | Guard.ArgumentNotNull(func, nameof(func)); 34 | _func = func; 35 | } 36 | 37 | public bool Process(TProtocol iprot, TProtocol oprot) 38 | { 39 | return _func(iprot, oprot); 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | //[assembly: AssemblyConfiguration("")] 9 | //[assembly: AssemblyCompany("")] 10 | //[assembly: AssemblyProduct("Thrifty.Nifty")] 11 | //[assembly: AssemblyTrademark("")] 12 | 13 | //// Setting ComVisible to false makes the types in this assembly not visible 14 | //// to COM components. If you need to access a type in this assembly from 15 | //// COM, set the ComVisible attribute to true on that type. 16 | //[assembly: ComVisible(false)] 17 | 18 | //// The following GUID is for the ID of the typelib if this project is exposed to COM 19 | //[assembly: Guid("9bf75e37-de41-4219-a73e-b65c746db9c9")] 20 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Ssl/SslConfig.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.FileProviders; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Thrifty.Nifty.Ssl 10 | { 11 | 12 | public class SslConfig 13 | { 14 | private IFileProvider _fileProvider; 15 | 16 | public string CertFile { get; set; } 17 | 18 | public string CertPassword { get; set; } 19 | 20 | public IFileProvider CertFileProvider 21 | { 22 | get { return _fileProvider ?? (_fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory())); } 23 | set { _fileProvider = value; } 24 | } 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Thrifty.Nifty/Ssl/SslSession.cs: -------------------------------------------------------------------------------- 1 | using DotNetty.Handlers.Tls; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Security.Cryptography.X509Certificates; 6 | using System.Threading.Tasks; 7 | 8 | namespace Thrifty.Nifty.Ssl 9 | { 10 | public class SslSession 11 | { 12 | public SslSession( 13 | TlsSettings settings, 14 | X509Certificate peerCert) 15 | { 16 | this.PeerCert = peerCert; 17 | } 18 | 19 | 20 | public TlsSettings TlsSettings { get; } 21 | 22 | public X509Certificate PeerCert { get; } 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Annotations/ThriftConstructorAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty 7 | { 8 | /// 9 | /// 标识一个 Thrift 结构的序列化时所使用的构造函数。 10 | /// 11 | [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)] 12 | public class ThriftConstructorAttribute : Attribute 13 | { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Annotations/ThriftExceptionAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty 8 | { 9 | //暂时不支持异常处理 10 | [AttributeUsage(AttributeTargets.Method, AllowMultiple =true, Inherited = true)] 11 | internal class ThriftExceptionAttribute : Attribute 12 | { 13 | public ThriftExceptionAttribute(short id, String name, Type exceptionType) 14 | { 15 | Guard.ArgumentNotNull(exceptionType, nameof(exceptionType)); 16 | if (!typeof(Exception).GetTypeInfo().IsAssignableFrom(exceptionType)) 17 | { 18 | throw new ArgumentException($"{nameof(ThriftExceptionAttribute)} 构造函数参数 {nameof(exceptionType)} 必须是一个 {nameof(Exception)} 类型。", nameof(exceptionType)); 19 | } 20 | 21 | this.Id = id; 22 | this.Name = name; 23 | this.ExceptionType = exceptionType; 24 | } 25 | public Type ExceptionType { get; } 26 | 27 | public short Id { get; } 28 | public String Name { get; } = ""; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Annotations/ThriftIdlAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty 7 | { 8 | //暂时不支持 Idl 反向生成 9 | [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, 10 | AllowMultiple = true, Inherited = false)] 11 | internal class ThriftIdlAttribute : Attribute 12 | { 13 | public String Key { get; set; } = ""; 14 | public String Value { get; set; } = ""; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Annotations/ThriftMethodAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty 7 | { 8 | /// 9 | /// 标识一个 Thrift 服务中的方法。 10 | /// 11 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 12 | public sealed class ThriftMethodAttribute : Attribute 13 | { 14 | public ThriftMethodAttribute(String name = null) 15 | { 16 | this.Name = name; 17 | } 18 | 19 | public String Name { get; } 20 | 21 | /// 22 | /// 获取或设置一个值,指示服务方法是否是单向(one-way)的。 23 | /// 24 | public bool OneWay { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Annotations/ThriftServiceAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty 7 | { 8 | /// 9 | /// 标识一个 Thrift 服务。 10 | /// 11 | [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class, AllowMultiple =false, Inherited =false)] 12 | public sealed class ThriftServiceAttribute : Attribute 13 | { 14 | public ThriftServiceAttribute(String name = null) 15 | { 16 | this.Name = name; 17 | } 18 | 19 | public String Name { get; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Annotations/ThriftStructAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty 7 | { 8 | /// 9 | /// 标识一个 Thrift 结构(对应 IDL 中的 struct)。 10 | /// 11 | [AttributeUsage(AttributeTargets.Class, AllowMultiple =false, Inherited =false)] 12 | public sealed class ThriftStructAttribute : Attribute 13 | { 14 | public ThriftStructAttribute(String name = null) 15 | { 16 | this.Name = name; 17 | } 18 | 19 | /// 20 | /// 获取 Thrift 结构的唯一标识符号。 21 | /// 22 | public String Name { get; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/DelegateCodec.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Codecs.Metadata; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Thrift.Protocol; 7 | 8 | namespace Thrifty.Codecs 9 | { 10 | public class DelegateCodec : IThriftCodec 11 | { 12 | private ThriftCodecManager codecManager; 13 | 14 | public DelegateCodec(ThriftCodecManager codecManager) 15 | { 16 | this.codecManager = codecManager; 17 | } 18 | 19 | public ThriftType Type 20 | { 21 | get { return GetCodecFromCache().Type; } 22 | } 23 | 24 | public T Read(TProtocol protocol) 25 | { 26 | return GetCodecFromCache().Read(protocol); 27 | } 28 | 29 | public object ReadObject(TProtocol protocol) 30 | { 31 | return this.Read(protocol); 32 | } 33 | 34 | public void Write(T value, TProtocol protocol) 35 | { 36 | GetCodecFromCache().Write(value, protocol); 37 | } 38 | 39 | public void WriteObject(object value, TProtocol protocol) 40 | { 41 | this.Write((T)value, protocol); 42 | } 43 | 44 | private IThriftCodec GetCodecFromCache() 45 | { 46 | IThriftCodec codec = codecManager.GetCachedCodecIfPresent(); 47 | if (codec == null) 48 | { 49 | throw new ThriftyException( 50 | "Tried to encodec/decode using a DelegateCodec before the target codec was " + 51 | "built (likely a bug in recursive type support)"); 52 | } 53 | return codec; 54 | } 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/AbstractThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Codecs.Metadata; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Thrift.Protocol; 7 | 8 | namespace Thrifty.Codecs.Internal.Builtin 9 | { 10 | public abstract class AbstractThriftCodec : IThriftCodec 11 | { 12 | public abstract ThriftType Type { get; } 13 | 14 | public T Read(TProtocol protocol) 15 | { 16 | Guard.ArgumentNotNull(protocol, nameof(protocol)); 17 | return this.OnRead(new TProtocolReader(protocol)); 18 | } 19 | 20 | public object ReadObject(TProtocol protocol) 21 | { 22 | return this.Read(protocol); 23 | } 24 | 25 | public void Write(T value, TProtocol protocol) 26 | { 27 | Guard.ArgumentNotNull(value, nameof(value)); 28 | Guard.ArgumentNotNull(protocol, nameof(protocol)); 29 | this.OnWrite(value, new TProtocolWriter(protocol)); 30 | } 31 | 32 | public void WriteObject(object value, TProtocol protocol) 33 | { 34 | this.Write((T)value, protocol); 35 | } 36 | 37 | protected abstract T OnRead(TProtocolReader reader); 38 | protected abstract void OnWrite(T value, TProtocolWriter writer); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/BooleanArrayThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrifty.Codecs.Metadata; 6 | using Thrift.Protocol; 7 | 8 | namespace Thrifty.Codecs.Internal.Builtin 9 | { 10 | public class BooleanArrayThriftCodec : AbstractThriftCodec 11 | { 12 | public override ThriftType Type 13 | { 14 | get { return ThriftType.Array(ThriftType.Bool); } 15 | } 16 | 17 | protected override bool[] OnRead(TProtocolReader reader) 18 | { 19 | return reader.ReadBoolArray(); 20 | } 21 | 22 | protected override void OnWrite(bool[] value, TProtocolWriter writer) 23 | { 24 | writer.WriteBoolArray(value); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/BooleanThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Codecs.Metadata; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Thrift.Protocol; 7 | 8 | namespace Thrifty.Codecs.Internal.Builtin 9 | { 10 | public class BooleanThriftCodec : AbstractThriftCodec 11 | { 12 | public override ThriftType Type 13 | { 14 | get { return ThriftType.Bool; } 15 | } 16 | 17 | protected override bool OnRead(TProtocolReader reader) 18 | { 19 | return reader.ReadBool(); 20 | } 21 | 22 | protected override void OnWrite(bool value, TProtocolWriter writer) 23 | { 24 | writer.WriteBool(value); 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/ByteBufferThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrifty.Codecs.Metadata; 6 | 7 | namespace Thrifty.Codecs.Internal.Builtin 8 | { 9 | public class ByteBufferThriftCodec : AbstractThriftCodec 10 | { 11 | public override ThriftType Type { get { return ThriftType.Binary; } } 12 | 13 | protected override byte[] OnRead(TProtocolReader reader) 14 | { 15 | return reader.ReadBinary(); 16 | } 17 | 18 | protected override void OnWrite(byte[] value, TProtocolWriter writer) 19 | { 20 | writer.WriteBinary(value); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/ByteThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrifty.Codecs.Metadata; 6 | 7 | namespace Thrifty.Codecs.Internal.Builtin 8 | { 9 | public class ByteThriftCodec : AbstractThriftCodec 10 | { 11 | public override ThriftType Type { get { return ThriftType.Byte; } } 12 | 13 | protected override byte OnRead(TProtocolReader reader) 14 | { 15 | return reader.ReadByte(); 16 | } 17 | 18 | protected override void OnWrite(byte value, TProtocolWriter writer) 19 | { 20 | writer.WriteByte(value); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/DateTimeArrayThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Codecs.Metadata; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty.Codecs.Internal.Builtin 8 | { 9 | public class DateTimeArrayThriftCodec : AbstractThriftCodec 10 | { 11 | public override ThriftType Type { get { return ThriftType.Array(ThriftType.DateTime); } } 12 | 13 | protected override DateTime[] OnRead(TProtocolReader reader) 14 | { 15 | var longArray = reader.ReadI64Array(); 16 | if (longArray == null) 17 | { 18 | return null; 19 | } 20 | else 21 | { 22 | DateTime[] result = new DateTime[longArray.Length]; 23 | for (var i = 0; i < longArray.Length; i++) 24 | { 25 | result[i] = DateTimeThriftCodec.FromLongValue(longArray[i]); 26 | } 27 | return result; 28 | } 29 | } 30 | 31 | protected override void OnWrite(DateTime[] value, TProtocolWriter writer) 32 | { 33 | if (value == null) 34 | { 35 | writer.WriteI64Array(null); 36 | } 37 | else 38 | { 39 | long[] result = new long[value.Length]; 40 | for (var i = 0; i < value.Length; i++) 41 | { 42 | result[i] = DateTimeThriftCodec.ToLongValue(value[i]); 43 | } 44 | writer.WriteI64Array(result); 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/DateTimeThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Codecs.Metadata; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty.Codecs.Internal.Builtin 8 | { 9 | public class DateTimeThriftCodec : AbstractThriftCodec 10 | { 11 | private static readonly DateTime Jan1st1970 = new DateTime 12 | (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 13 | 14 | public override ThriftType Type { get { return ThriftType.DateTime; } } 15 | 16 | protected override DateTime OnRead(TProtocolReader reader) 17 | { 18 | long value = reader.ReadI64(); 19 | return FromLongValue(value); 20 | } 21 | 22 | 23 | protected override void OnWrite(DateTime value, TProtocolWriter writer) 24 | { 25 | //if (value.Kind != DateTimeKind.Utc) 26 | //{ 27 | // throw new ArgumentException("datetime thrift field invalid, only the utc datetime type are supported."); 28 | //} 29 | long longValue = ToLongValue(value); 30 | writer.WriteI64(longValue); 31 | } 32 | 33 | internal static long ToLongValue(DateTime value) 34 | { 35 | var r = (value.ToUniversalTime().Ticks - Jan1st1970.Ticks) / 10000; 36 | return r; 37 | } 38 | 39 | internal static DateTime FromLongValue(long value) 40 | { 41 | var r = new DateTime((value * 10000 + Jan1st1970.Ticks), DateTimeKind.Utc); 42 | return r; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/DecimalThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Codecs.Internal.Builtin; 2 | using Thrifty.Codecs.Metadata; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Thrifty.Codecs.Internal.Builtin 10 | { 11 | public class DecimalThriftCodec : AbstractThriftCodec 12 | { 13 | public override ThriftType Type { get { return ThriftType.Decimal; } } 14 | 15 | protected override Decimal OnRead(TProtocolReader reader) 16 | { 17 | string v = reader.ReadString(); 18 | Decimal dc = default(Decimal); 19 | Decimal.TryParse(v, out dc); 20 | return dc; 21 | } 22 | 23 | protected override void OnWrite(Decimal value, TProtocolWriter writer) 24 | { 25 | writer.WriteString(value.ToString()); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/DoubleArrayThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrifty.Codecs.Metadata; 6 | 7 | namespace Thrifty.Codecs.Internal.Builtin 8 | { 9 | public class DoubleArrayThriftCodec : AbstractThriftCodec 10 | { 11 | public override ThriftType Type { get { return ThriftType.Array(ThriftType.Double); } } 12 | 13 | protected override double[] OnRead(TProtocolReader reader) 14 | { 15 | return reader.ReadDoubleArray(); 16 | } 17 | 18 | protected override void OnWrite(double[] value, TProtocolWriter writer) 19 | { 20 | writer.WriteDoubleArray(value); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/DoubleThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrifty.Codecs.Metadata; 6 | 7 | namespace Thrifty.Codecs.Internal.Builtin 8 | { 9 | public class DoubleThriftCodec : AbstractThriftCodec 10 | { 11 | public override ThriftType Type { get { return ThriftType.Double; } } 12 | 13 | protected override double OnRead(TProtocolReader reader) 14 | { 15 | return reader.ReadDouble(); 16 | } 17 | 18 | protected override void OnWrite(double value, TProtocolWriter writer) 19 | { 20 | writer.WriteDouble(value); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/FloatArrayThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Codecs.Metadata; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty.Codecs.Internal.Builtin 8 | { 9 | public class FloatArrayThriftCodec : AbstractThriftCodec 10 | { 11 | public override ThriftType Type { get { return ThriftType.Array(ThriftType.Float); } } 12 | 13 | protected override float[] OnRead(TProtocolReader reader) 14 | { 15 | return reader.ReadDoubleArray().Select(d => (float)d).ToArray(); ; 16 | } 17 | 18 | protected override void OnWrite(float[] value, TProtocolWriter writer) 19 | { 20 | writer.WriteDoubleArray(value.Select(f=>(double)f).ToArray()); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/FloatThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Codecs.Metadata; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty.Codecs.Internal.Builtin 8 | { 9 | public class FloatThriftCodec : AbstractThriftCodec 10 | { 11 | public override ThriftType Type { get { return ThriftType.Float; } } 12 | 13 | protected override float OnRead(TProtocolReader reader) 14 | { 15 | return (float)reader.ReadDouble(); 16 | } 17 | 18 | protected override void OnWrite(float value, TProtocolWriter writer) 19 | { 20 | writer.WriteDouble(value); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/GuidThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Codecs.Internal; 2 | using Thrifty.Codecs.Internal.Builtin; 3 | using Thrifty.Codecs.Metadata; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace Thrifty.Codecs.Internal.Builtin 11 | { 12 | public class GuidThriftCodec : AbstractThriftCodec 13 | { 14 | public override ThriftType Type { get { return ThriftType.Guid; } } 15 | 16 | protected override Guid OnRead(TProtocolReader reader) 17 | { 18 | string v = reader.ReadString(); 19 | Guid id = Guid.Empty; 20 | Guid.TryParse(v, out id); 21 | return id; 22 | } 23 | 24 | protected override void OnWrite(Guid value, TProtocolWriter writer) 25 | { 26 | writer.WriteString(value.ToString()); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/IntArrayThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrifty.Codecs.Metadata; 6 | 7 | namespace Thrifty.Codecs.Internal.Builtin 8 | { 9 | public class IntArrayThriftCodec : AbstractThriftCodec 10 | { 11 | public override ThriftType Type { get { return ThriftType.Array(ThriftType.I32); } } 12 | 13 | protected override int[] OnRead(TProtocolReader reader) 14 | { 15 | return reader.ReadI32Array(); 16 | } 17 | 18 | protected override void OnWrite(int[] value, TProtocolWriter writer) 19 | { 20 | writer.WriteI32Array(value); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/IntThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrifty.Codecs.Metadata; 6 | 7 | namespace Thrifty.Codecs.Internal.Builtin 8 | { 9 | public class IntThriftCodec : AbstractThriftCodec 10 | { 11 | public override ThriftType Type { get { return ThriftType.I32; } } 12 | 13 | protected override int OnRead(TProtocolReader reader) 14 | { 15 | return reader.ReadI32(); 16 | } 17 | 18 | protected override void OnWrite(int value, TProtocolWriter writer) 19 | { 20 | writer.WriteI32(value); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/ListThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Codecs.Metadata; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty.Codecs.Internal.Builtin 8 | { 9 | public class ListThriftCodec : AbstractThriftCodec> 10 | { 11 | private IThriftCodec elementCodec; 12 | private ThriftType type; 13 | private bool _isArray; 14 | 15 | public ListThriftCodec(ThriftType type, IThriftCodec elementCodec) 16 | { 17 | Guard.ArgumentNotNull(type, nameof(type)); 18 | Guard.ArgumentNotNull(elementCodec, nameof(elementCodec)); 19 | 20 | this.type = type; 21 | this.elementCodec = elementCodec; 22 | this._isArray = type.CSharpType.IsArray; 23 | } 24 | 25 | 26 | public override ThriftType Type 27 | { 28 | get { return this.type; } 29 | } 30 | 31 | protected override IEnumerable OnRead(TProtocolReader reader) 32 | { 33 | var list = reader.ReadList(elementCodec); 34 | return _isArray ? list.ToArray() : list; 35 | } 36 | 37 | protected override void OnWrite(IEnumerable value, TProtocolWriter writer) 38 | { 39 | writer.WriteList(elementCodec, value.ToList()); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/LongArrayThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrifty.Codecs.Metadata; 6 | 7 | namespace Thrifty.Codecs.Internal.Builtin 8 | { 9 | public class LongArrayThriftCodec : AbstractThriftCodec 10 | { 11 | public override ThriftType Type { get { return ThriftType.Array(ThriftType.I64); } } 12 | 13 | protected override long[] OnRead(TProtocolReader reader) 14 | { 15 | return reader.ReadI64Array(); 16 | } 17 | 18 | protected override void OnWrite(long[] value, TProtocolWriter writer) 19 | { 20 | writer.WriteI64Array(value); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/LongThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrifty.Codecs.Metadata; 6 | 7 | namespace Thrifty.Codecs.Internal.Builtin 8 | { 9 | public class LongThriftCodec : AbstractThriftCodec 10 | { 11 | public override ThriftType Type { get { return ThriftType.I64; } } 12 | 13 | protected override long OnRead(TProtocolReader reader) 14 | { 15 | return reader.ReadI64(); 16 | } 17 | 18 | protected override void OnWrite(long value, TProtocolWriter writer) 19 | { 20 | writer.WriteI64(value); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/MapThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrifty.Codecs.Metadata; 6 | 7 | namespace Thrifty.Codecs.Internal.Builtin 8 | { 9 | public class MapThriftCodec : AbstractThriftCodec> 10 | { 11 | private readonly ThriftType _thriftType; 12 | private readonly IThriftCodec _keyCodec; 13 | private readonly IThriftCodec _valueCodec; 14 | 15 | public MapThriftCodec(ThriftType type, IThriftCodec keyCodec, IThriftCodec valueCodec) 16 | { 17 | Guard.ArgumentNotNull(type, nameof(type)); 18 | Guard.ArgumentNotNull(keyCodec, nameof(keyCodec)); 19 | Guard.ArgumentNotNull(valueCodec, nameof(valueCodec)); 20 | 21 | this._thriftType = type; 22 | this._keyCodec = keyCodec; 23 | this._valueCodec = valueCodec; 24 | } 25 | 26 | public override ThriftType Type { get { return this._thriftType; } } 27 | 28 | protected override IDictionary OnRead(TProtocolReader reader) 29 | { 30 | return reader.ReadMap(_keyCodec, _valueCodec); 31 | } 32 | 33 | protected override void OnWrite(IDictionary value, TProtocolWriter writer) 34 | { 35 | writer.WriteMap(_keyCodec, _valueCodec, value); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/SetThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrifty.Codecs.Metadata; 6 | 7 | namespace Thrifty.Codecs.Internal.Builtin 8 | { 9 | public class SetThriftCodec : AbstractThriftCodec> 10 | { 11 | private readonly IThriftCodec _elementCodec; 12 | private readonly ThriftType _type; 13 | 14 | public SetThriftCodec(ThriftType type, IThriftCodec elementCodec) 15 | { 16 | Guard.ArgumentNotNull(type, nameof(type)); 17 | Guard.ArgumentNotNull(elementCodec, nameof(elementCodec)); 18 | 19 | this._type = type; 20 | this._elementCodec = elementCodec; 21 | } 22 | public override ThriftType Type { get { return _type; } } 23 | 24 | protected override ISet OnRead(TProtocolReader reader) 25 | { 26 | return reader.ReadSet(_elementCodec); 27 | } 28 | 29 | protected override void OnWrite(ISet value, TProtocolWriter writer) 30 | { 31 | writer.WriteSet(_elementCodec, value); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/ShortArrayThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrifty.Codecs.Metadata; 6 | 7 | namespace Thrifty.Codecs.Internal.Builtin 8 | { 9 | public class ShortArrayThriftCodec : AbstractThriftCodec 10 | { 11 | public override ThriftType Type { get { return ThriftType.Array(ThriftType.I16); } } 12 | 13 | protected override short[] OnRead(TProtocolReader reader) 14 | { 15 | return reader.ReadI16Array(); 16 | } 17 | 18 | protected override void OnWrite(short[] value, TProtocolWriter writer) 19 | { 20 | writer.WriteI16Array(value); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/ShortThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrifty.Codecs.Metadata; 6 | 7 | namespace Thrifty.Codecs.Internal.Builtin 8 | { 9 | public class ShortThriftCodec : AbstractThriftCodec 10 | { 11 | public override ThriftType Type { get { return ThriftType.I16; } } 12 | 13 | protected override short OnRead(TProtocolReader reader) 14 | { 15 | return reader.ReadI16(); 16 | } 17 | 18 | protected override void OnWrite(short value, TProtocolWriter writer) 19 | { 20 | writer.WriteI16(value); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/StringThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrifty.Codecs.Metadata; 6 | 7 | namespace Thrifty.Codecs.Internal.Builtin 8 | { 9 | public class StringThriftCodec : AbstractThriftCodec 10 | { 11 | public override ThriftType Type { get { return ThriftType.String; } } 12 | 13 | protected override string OnRead(TProtocolReader reader) 14 | { 15 | return reader.ReadString(); 16 | } 17 | 18 | protected override void OnWrite(string value, TProtocolWriter writer) 19 | { 20 | writer.WriteString(value); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Builtin/VoidThriftCodec.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrifty.Codecs.Metadata; 6 | using Thrift.Protocol; 7 | 8 | namespace Thrifty.Codecs.Internal.Builtin 9 | { 10 | public class VoidThriftCodec : IThriftCodec 11 | { 12 | public ThriftType Type { get { return ThriftType.Void; } } 13 | 14 | public object Read(TProtocol protocol) 15 | { 16 | Guard.ArgumentNotNull(protocol, nameof(protocol)); 17 | return null; 18 | } 19 | 20 | public object ReadObject(TProtocol protocol) 21 | { 22 | Guard.ArgumentNotNull(protocol, nameof(protocol)); 23 | return null; 24 | } 25 | 26 | public void Write(object value, TProtocol protocol) 27 | { 28 | Guard.ArgumentNotNull(protocol, nameof(protocol)); 29 | } 30 | 31 | public void WriteObject(object value, TProtocol protocol) 32 | { 33 | Guard.ArgumentNotNull(protocol, nameof(protocol)); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/IThriftCodecFactory.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Codecs.Metadata; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty.Codecs.Internal 8 | { 9 | /// 10 | /// Implementations of this interface are expected to be thread safe. 11 | /// 12 | public interface IThriftCodecFactory 13 | { 14 | IThriftCodec GenerateThriftTypeCodec(ThriftCodecManager codecManager, ThriftStructMetadata metadata); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Internal/Reflection/ReflectionThriftCodecFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrifty.Codecs.Metadata; 6 | 7 | namespace Thrifty.Codecs.Internal.Reflection 8 | { 9 | public class ReflectionThriftCodecFactory : IThriftCodecFactory 10 | { 11 | public IThriftCodec GenerateThriftTypeCodec(ThriftCodecManager codecManager, ThriftStructMetadata metadata) 12 | { 13 | switch (metadata.MetadataType) 14 | { 15 | case MetadataType.Struct: 16 | var type = metadata.StructType; 17 | var codecType = typeof(ReflectionThriftStructCodec<>).MakeGenericType(type); 18 | return (IThriftCodec)Activator.CreateInstance(codecType, codecManager, metadata); 19 | case MetadataType.Union: 20 | default: 21 | throw new ThriftyException($"encountered type {metadata.MetadataType}"); 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Metadata/DefaultThriftTypeReference.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Codecs.Metadata 7 | { 8 | public class DefaultThriftTypeReference : IThriftTypeReference 9 | { 10 | private ThriftType thriftType; 11 | 12 | public DefaultThriftTypeReference(ThriftType thriftType) 13 | { 14 | this.thriftType = thriftType; 15 | } 16 | 17 | public Type CSharpType 18 | { 19 | get { return this.thriftType.CSharpType; } 20 | } 21 | 22 | public ThriftProtocolType ProtocolType 23 | { 24 | get { return this.thriftType.ProtocolType; } 25 | } 26 | 27 | public bool Recursive 28 | { 29 | get { return false; } 30 | } 31 | 32 | public ThriftType Get() 33 | { 34 | return this.thriftType; 35 | } 36 | 37 | public override int GetHashCode() 38 | { 39 | return thriftType.GetHashCode(); 40 | } 41 | 42 | 43 | public override bool Equals(object obj) 44 | { 45 | if (obj == null) 46 | { 47 | return false; 48 | } 49 | if (Object.ReferenceEquals(this, obj)) 50 | { 51 | return true; 52 | } 53 | 54 | if (obj == null || !obj.GetType().Equals(typeof(DefaultThriftTypeReference))) 55 | { 56 | return false; 57 | } 58 | 59 | DefaultThriftTypeReference that = (DefaultThriftTypeReference)obj; 60 | 61 | return this.thriftType.Equals(that.thriftType); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Metadata/DependencyInjection/ConstructorInjection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Thrifty.Codecs.Metadata 9 | { 10 | public class ConstructorInjection 11 | { 12 | public ConstructorInjection(ConstructorInfo constructor, IEnumerable parameters) 13 | { 14 | this.Constructor = constructor; 15 | this.Parameters = parameters ?? Enumerable.Empty(); 16 | } 17 | 18 | public ConstructorInjection(ConstructorInfo constructor, params ParameterInjection[] parameters) 19 | :this(constructor, (IEnumerable)parameters) 20 | { 21 | } 22 | 23 | public ConstructorInfo Constructor { get; } 24 | 25 | public IEnumerable Parameters { get; } 26 | 27 | public override String ToString() 28 | { 29 | StringBuilder sb = new StringBuilder(); 30 | sb.Append("ConstructorInjection"); 31 | sb.Append("{constructor=").Append($"{this.Constructor.Name}({String.Join(", ", this.Constructor.GetParameters().Select(p => p.ParameterType.Name).ToArray())})"); 32 | sb.Append('}'); 33 | return sb.ToString(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Metadata/DependencyInjection/FieldInjection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Thrifty.Codecs.Metadata 9 | { 10 | public class FieldInjection : Injection 11 | { 12 | public FieldInjection(PropertyInfo field, ThriftFieldAttribute annotation, FieldKind fieldKind) 13 | : base(annotation, fieldKind) 14 | { 15 | this.Field = field; 16 | this.CSharpType = field.PropertyType; 17 | } 18 | 19 | public override Type CSharpType { get; } 20 | 21 | public PropertyInfo Field { get; } 22 | 23 | public override string ExtractName() 24 | { 25 | return this.Field.Name; 26 | } 27 | 28 | public String toString() 29 | { 30 | StringBuilder sb = new StringBuilder(); 31 | sb.Append("FieldInjection"); 32 | sb.Append("{field=").Append(this.Field.Name); 33 | sb.Append('}'); 34 | return sb.ToString(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Metadata/DependencyInjection/Injection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Codecs.Metadata 7 | { 8 | public abstract class Injection : FieldMetadata 9 | { 10 | protected Injection(ThriftFieldAttribute annotation, FieldKind fieldKind) 11 | :base(annotation, fieldKind) 12 | { 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Metadata/Extractor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Codecs.Metadata 7 | { 8 | public abstract class Extractor : FieldMetadata 9 | { 10 | protected Extractor(ThriftFieldAttribute annotation, FieldKind fieldKind) : base(annotation, fieldKind) 11 | { 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Metadata/FieldExtractor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Thrifty.Codecs.Metadata 9 | { 10 | public class FieldExtractor : Extractor 11 | { 12 | public FieldExtractor(PropertyInfo field, ThriftFieldAttribute annotation, FieldKind fieldKind) 13 | : base(annotation, fieldKind) 14 | { 15 | Guard.ArgumentNotNull(field, nameof(field)); 16 | 17 | this.CSharpType = field.PropertyType; 18 | this.Field = field; 19 | } 20 | 21 | public PropertyInfo Field { get; } 22 | 23 | public override Type CSharpType { get; } 24 | 25 | public override String ToString() 26 | { 27 | StringBuilder sb = new StringBuilder(); 28 | sb.Append("FieldExtractor"); 29 | sb.Append("{field=").Append(this.Field.Name); 30 | sb.Append('}'); 31 | return sb.ToString(); 32 | } 33 | 34 | public override string ExtractName() 35 | { 36 | return this.Field.Name; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Metadata/FieldKind.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Codecs.Metadata 7 | { 8 | public enum FieldKind 9 | { 10 | ThriftField, 11 | ThriftUnionId 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Metadata/IThriftExtraction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Codecs.Metadata 7 | { 8 | /// 9 | /// ThriftExtraction contains information an extraction point for a single thrift field. 10 | /// Implementations of this interface are expected to be thread safe. 11 | /// 12 | public interface IThriftExtraction 13 | { 14 | short Id { get; } 15 | 16 | String Name { get; } 17 | 18 | FieldKind FieldKind { get; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Metadata/IThriftInjection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Codecs.Metadata 7 | { 8 | /// 9 | /// ThriftInjection contains information an injection point for a single thrift field. 10 | /// Implementation of this interface are expected to be thread safe. 11 | /// 12 | public interface IThriftInjection 13 | { 14 | short Id { get; } 15 | 16 | String Name { get; } 17 | 18 | FieldKind FieldKind { get; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Metadata/IThriftTypeReference.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Codecs.Metadata 7 | { 8 | /// 9 | /// An interface to either a resolved or the information to compute one. 10 | /// Used when computing struct/union metadata, as a placeholder for field types that might not be directly resolvable yet (in cases of recursive types). 11 | /// 12 | public interface IThriftTypeReference 13 | { 14 | Type CSharpType { get; } 15 | 16 | ThriftProtocolType ProtocolType { get; } 17 | 18 | bool Recursive { get; } 19 | 20 | ThriftType Get(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Metadata/MetadataWarningException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Codecs.Metadata 7 | { 8 | public class MetadataWarningException : ThriftyException 9 | { 10 | public MetadataWarningException(String message) 11 | : base($"Warning: {message}") 12 | { 13 | } 14 | 15 | public MetadataWarningException(string message, Exception cause) 16 | : base($"Warning: {message}", cause) 17 | { 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Metadata/MethodExtractor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Reflection; 6 | using System.Text; 7 | 8 | namespace Thrifty.Codecs.Metadata 9 | { 10 | public class MethodExtractor : Extractor 11 | { 12 | 13 | public MethodExtractor(Type thriftStructType, MethodInfo method, ThriftFieldAttribute annotation, FieldKind fieldKind) 14 | : base(annotation, fieldKind) 15 | { 16 | this.CSharpType = thriftStructType; 17 | this.Method = method; 18 | } 19 | 20 | public MethodInfo Method { get; } 21 | 22 | public override Type CSharpType { get; } 23 | 24 | 25 | 26 | public override String ExtractName() 27 | { 28 | return this.Method.Name; 29 | } 30 | 31 | public override String ToString() 32 | { 33 | StringBuilder sb = new StringBuilder(); 34 | sb.Append("MethodExtractor"); 35 | sb.Append("{method=").Append(Method.Name); 36 | sb.Append('}'); 37 | return sb.ToString(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Metadata/MethodInjection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Thrifty.Codecs.Metadata 9 | { 10 | public class MethodInjection 11 | { 12 | private IEnumerable parameters; 13 | 14 | public MethodInjection(MethodInfo method, IEnumerable parameters) 15 | { 16 | this.Method = method; 17 | this.parameters = parameters; 18 | } 19 | 20 | public MethodInfo Method { get; } 21 | 22 | public IEnumerable getParameters() 23 | { 24 | return parameters; 25 | } 26 | 27 | public override String ToString() 28 | { 29 | StringBuilder sb = new StringBuilder(); 30 | sb.Append("MethodInjection"); 31 | sb.Append("{method=").Append(String.Format($"{Method.DeclaringType}.{Method.Name}")); 32 | sb.Append(", parameters=").Append(String.Join(", ", parameters)); 33 | sb.Append('}'); 34 | return sb.ToString(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Metadata/ThriftConstructorInjection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Thrifty.Codecs.Metadata 9 | { 10 | public class ThriftConstructorInjection 11 | { 12 | public ThriftConstructorInjection(ConstructorInfo constructor, params ThriftParameterInjection[] parameters) 13 | :this(constructor, (IEnumerable)parameters) 14 | { 15 | 16 | } 17 | 18 | public ThriftConstructorInjection(ConstructorInfo constructor, IEnumerable parameters) 19 | { 20 | Guard.ArgumentNotNull(constructor, nameof(constructor)); 21 | 22 | this.Constructor = constructor; 23 | this.Parameters = parameters ?? Enumerable.Empty(); 24 | } 25 | 26 | public ConstructorInfo Constructor { get; } 27 | 28 | public IEnumerable Parameters { get; } 29 | 30 | public override string ToString() 31 | { 32 | StringBuilder sb = new StringBuilder(); 33 | sb.Append(this.Constructor.Name); 34 | sb.Append('('); 35 | sb.Append(String.Join(", ", Parameters.Select(p => p.CSharpType.Name))); 36 | sb.Append(')'); 37 | return sb.ToString(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/Metadata/ThriftMethodInjection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Thrifty.Codecs.Metadata 9 | { 10 | public class ThriftMethodInjection 11 | { 12 | public ThriftMethodInjection(MethodInfo method, params ThriftParameterInjection[] parameters) 13 | :this(method, (IEnumerable)parameters) 14 | { 15 | } 16 | 17 | public ThriftMethodInjection(MethodInfo method, IEnumerable parameters) 18 | { 19 | Guard.ArgumentNotNull(method, nameof(method)); 20 | 21 | this.Method = method; 22 | this.Parameters = parameters; 23 | } 24 | 25 | public MethodInfo Method { get; } 26 | public IEnumerable Parameters { get; } 27 | 28 | public override string ToString() 29 | { 30 | StringBuilder sb = new StringBuilder(); 31 | sb.Append(this.Method.Name); 32 | sb.Append('('); 33 | sb.Append(String.Join(", ", this.Parameters.Select(p => p.CSharpType.Name))); 34 | sb.Append(')'); 35 | return sb.ToString(); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Codecs/ThriftOrderAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Codecs 7 | { 8 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Method | AttributeTargets.Property)] 9 | public class ThriftOrderAttribute : Attribute 10 | { 11 | public ThriftOrderAttribute(int order) 12 | { 13 | this.Order = order; 14 | } 15 | 16 | public int Order { get; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Thrifty.Services")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("316f1e1f-26b9-4bb0-a95a-7c53236f2f68")] 20 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Services/INiftyClientChannelAware.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Nifty.Client; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty.Services 8 | { 9 | public interface INiftyClientChannelAware 10 | { 11 | INiftyClientChannel ClientChannel { get; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Services/IThriftClientFactory.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Nifty.Client; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty.Services 8 | { 9 | public interface IThriftClientFactory 10 | { 11 | Object CreateClient( 12 | INiftyClientChannel channel, 13 | Type clientType, 14 | ThriftClientMetadata clientMetadata, 15 | IEnumerable clientHandlers, 16 | string clientDescription); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Services/ThriftClientConfig.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Nifty.Client; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Net; 6 | using System.Threading.Tasks; 7 | 8 | namespace Thrifty.Services 9 | { 10 | public class ThriftClientConfig 11 | { 12 | public static readonly TimeSpan DEFAULT_CONNECT_TIMEOUT = TimeSpan.FromMilliseconds(500); 13 | public static readonly TimeSpan DEFAULT_RECEIVE_TIMEOUT = TimeSpan.FromMinutes(1); 14 | public static readonly TimeSpan DEFAULT_READ_TIMEOUT = TimeSpan.FromSeconds(10); 15 | public static readonly TimeSpan DEFAULT_WRITE_TIMEOUT = TimeSpan.FromMinutes(1); 16 | // Default max frame size of 16 MB 17 | public static readonly int DEFAULT_MAX_FRAME_SIZE = 16777216; 18 | 19 | public int MaxFrameSize { get; set; } = DEFAULT_MAX_FRAME_SIZE; 20 | public TimeSpan ConnectTimeout { get; set; } = DEFAULT_CONNECT_TIMEOUT; 21 | public TimeSpan ReceiveTimeout { get; set; } = DEFAULT_RECEIVE_TIMEOUT; 22 | public TimeSpan ReadTimeout { get; set; } = DEFAULT_READ_TIMEOUT; 23 | public TimeSpan WriteTimeout { get; set; } = DEFAULT_WRITE_TIMEOUT; 24 | public EndPoint SocksProxy { get; set; } 25 | 26 | public ClientSslConfig SslConfig { get; set; } 27 | 28 | public static ThriftClientConfig CreateForDebug() 29 | { 30 | return new ThriftClientConfig 31 | { 32 | ConnectTimeout = TimeSpan.FromMinutes(5), 33 | ReceiveTimeout = TimeSpan.FromMinutes(5), 34 | ReadTimeout = TimeSpan.FromMinutes(5), 35 | WriteTimeout = TimeSpan.FromMinutes(5) 36 | }; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Services/ThriftClientEventHandler.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Nifty.Client; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty.Services 8 | { 9 | public abstract class ThriftClientEventHandler 10 | { 11 | public virtual Object GetContext(String methodName, IClientRequestContext requestContext) 12 | { 13 | return null; 14 | } 15 | 16 | public virtual void PreWrite(Object context, String methodName, Object[] args) { } 17 | public virtual void PostWrite(Object context, String methodName, Object[] args) { } 18 | public virtual void PreRead(Object context, String methodName) { } 19 | public virtual void PreReadException(Object context, String methodName, Exception t) { } 20 | public virtual void PostRead(Object context, String methodName, Object result) { } 21 | public virtual void PostReadException(Object context, String methodName, Exception t) { } 22 | public virtual void Done(Object context, String methodName) { } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Services/ThriftEventHandler.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Codecs; 2 | using Thrifty.Nifty.Core; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace Thrifty.Services 9 | { 10 | public abstract class ThriftEventHandler 11 | { 12 | public virtual Object GetContext(String methodName, IRequestContext requestContext) 13 | { 14 | return null; 15 | } 16 | 17 | public virtual void PreRead(Object context, String methodName) { } 18 | public virtual void PostRead(Object context, String methodName, Object[] args) { } 19 | public virtual void PreWrite(Object context, String methodName, Object result) { } 20 | public virtual void PreWriteException(Object context, String methodName, Exception t) { } 21 | public virtual void PostWrite(Object context, String methodName, Object result) { } 22 | public virtual void PostWriteException(Object context, String methodName, Exception t) { } 23 | public virtual void DeclaredUserException(Object o, String methodName, Exception t, IThriftCodec exceptionCodec){ } 24 | public virtual void UndeclaredUserException(Object o, String methodName, Exception t) { } 25 | public virtual void Done(Object context, String methodName) { } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Thrifty.Services/Services/ThriftMethodHandler.ParameterHandler.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Codecs; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty.Services 8 | { 9 | partial class ThriftMethodHandler 10 | { 11 | public class ParameterHandler 12 | { 13 | internal ParameterHandler(short id, String name, IThriftCodec codec) 14 | { 15 | this.Id = id; 16 | this.Name = name; 17 | this.Codec = codec; 18 | } 19 | 20 | public short Id { get; } 21 | 22 | public string Name { get; } 23 | 24 | public IThriftCodec Codec { get; } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/Ribbon.Test/Just4Fun/IProcedure.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Ribbon.Test.Just4Fun 7 | { 8 | /// 9 | /// 过程标记 10 | /// 11 | public interface IProcedure 12 | { 13 | 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/Ribbon.Test/Just4Fun/IProcedureDiscovery.cs: -------------------------------------------------------------------------------- 1 | namespace Ribbon.Test.Just4Fun 2 | { 3 | /// 4 | /// 远程过程发现 5 | /// 6 | public interface IProcedureDiscovery 7 | { 8 | /// 9 | /// 获取一个远程过程对应的全部服务实例 10 | /// 11 | /// 远程过程 12 | /// 服务实例 13 | IServer[] GetInstances() where T : IProcedure; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/Ribbon.Test/Just4Fun/IProcedureParameter.cs: -------------------------------------------------------------------------------- 1 | namespace Ribbon.Test.Just4Fun 2 | { 3 | /// 4 | /// 远程过程参数 5 | /// 6 | public interface IProcedureParameter 7 | { 8 | /// 9 | /// 参数名 10 | /// 11 | string Name { get; } 12 | /// 13 | /// 参数值 14 | /// 15 | object Value { get; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/Ribbon.Test/Just4Fun/IRemoteProcedure.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace Ribbon.Test.Just4Fun 5 | { 6 | /// 7 | /// 远程过程 8 | /// 9 | public interface IRemoteProcedure 10 | { 11 | /// 12 | /// 版本 13 | /// 14 | string Version { get; } 15 | /// 16 | /// 调用的接口 17 | /// 18 | Type Interface { get; } 19 | /// 20 | /// 调用的方法 21 | /// 22 | MethodInfo Method { get; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/Ribbon.Test/Just4Fun/IRemoteProcedureCaller.cs: -------------------------------------------------------------------------------- 1 | namespace Ribbon.Test.Just4Fun 2 | { 3 | /// 4 | /// 远程方法调用器 5 | /// 6 | public interface IRemoteProcedureCaller 7 | { 8 | /// 9 | /// 在某个服务器上调用远程过程 10 | /// 11 | /// 服务器 12 | /// 远程过程 13 | /// 调用的过程参数 14 | /// 远程过程返回值 15 | object Call(IServer server, IRemoteProcedure procedure, IProcedureParameter[] parameters); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/Ribbon.Test/Just4Fun/IServer.cs: -------------------------------------------------------------------------------- 1 | namespace Ribbon.Test.Just4Fun 2 | { 3 | /// 4 | /// 服务器实例 5 | /// 6 | public interface IServer 7 | { 8 | /// 9 | /// 主机地址 10 | /// 11 | string Host { get; } 12 | /// 13 | /// 端口 14 | /// 15 | int Port { get; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/Ribbon.Test/Just4Fun/IServerSelector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Ribbon.Test.Just4Fun 7 | { 8 | /// 9 | /// 服务器选择器 10 | /// 11 | public interface IServerSelector 12 | { 13 | /// 14 | /// 选择一个服务器 15 | /// 16 | /// 全部的服务器 17 | /// 18 | IServer Select(IEnumerable servers); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/Ribbon.Test/Just4Fun/IServiceInstance.cs: -------------------------------------------------------------------------------- 1 | namespace Ribbon.Test.Just4Fun 2 | { 3 | /// 4 | /// 服务实例 5 | /// 6 | public interface IServiceInstance 7 | { 8 | /// 9 | /// 服务器 10 | /// 11 | IServer Server { get; } 12 | /// 13 | /// 全部可用的远程过程 14 | /// 15 | IRemoteProcedure[] Procedures { get; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/Ribbon.Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Ribbon.Test")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("f8cb6f2f-e81e-42af-901a-60fa6b86d032")] 20 | -------------------------------------------------------------------------------- /test/Ribbon.Test/Ribbon.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net461 5 | Ribbon.Test 6 | Exe 7 | Ribbon.Test 8 | false 9 | false 10 | false 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /test/Swifty.Benchmark/LogCase/LogCase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Thrifty.Benchmark 6 | { 7 | [ThriftService] 8 | public interface ISimpleCase 9 | { 10 | [ThriftMethod] 11 | List GetMessages(); 12 | 13 | [ThriftMethod] 14 | ResultCode Log(List messages); 15 | } 16 | 17 | public class LogCase : ISimpleCase 18 | { 19 | public List GetMessages() 20 | { 21 | return new List 22 | { 23 | new LogEntry { Category = "c1", Message = Guid.NewGuid().ToString() }, 24 | new LogEntry { Category = "c2", Message = Guid.NewGuid().ToString() }, 25 | new LogEntry { Category = "c3", Message = Guid.NewGuid().ToString() } 26 | 27 | }; 28 | } 29 | 30 | public ResultCode Log(List messages) 31 | { 32 | return ResultCode.TRY_LATER; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /test/Swifty.Benchmark/LogCase/LogEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Benchmark 7 | { 8 | [ThriftStruct] 9 | public class LogEntry 10 | { 11 | [ThriftField(1)] 12 | public string Category { get; set; } 13 | 14 | [ThriftField(2)] 15 | public string Message { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/Swifty.Benchmark/LogCase/ResultCode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Benchmark 7 | { 8 | public enum ResultCode 9 | { 10 | OK, 11 | TRY_LATER 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/Swifty.Benchmark/LogTester1.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Attributes; 2 | using BenchmarkDotNet.Attributes.Jobs; 3 | using BenchmarkDotNet.Engines; 4 | using Microsoft.Extensions.Logging; 5 | using Thrifty.MicroServices.Client; 6 | using Thrifty.MicroServices.Commons; 7 | using Thrifty.MicroServices.Server; 8 | using Thrifty.Services; 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Text; 12 | using System.Threading.Tasks; 13 | 14 | namespace Thrifty.Benchmark 15 | { 16 | public class LogTester1 : LogTester 17 | { 18 | protected override int Port => 5555; 19 | 20 | 21 | [Benchmark(Description = "LogCase.GetMessages (Direct)")] 22 | public override void RunGetMessages() 23 | { 24 | base.RunGetMessages(); 25 | } 26 | 27 | 28 | [Benchmark(Description = "LogCase.Log (Direct)")] 29 | public override void RunLog() 30 | { 31 | base.RunLog(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /test/Swifty.Benchmark/LogTester2.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Attributes; 2 | using BenchmarkDotNet.Attributes.Jobs; 3 | using BenchmarkDotNet.Engines; 4 | using Microsoft.Extensions.Logging; 5 | using Thrifty.MicroServices.Client; 6 | using Thrifty.MicroServices.Commons; 7 | using Thrifty.MicroServices.Server; 8 | using Thrifty.Services; 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Text; 12 | using System.Threading.Tasks; 13 | 14 | namespace Thrifty.Benchmark 15 | { 16 | public class LogTester2 : LogTester 17 | { 18 | protected override int Port => 6666; 19 | 20 | protected override string EurekaAddress => "http://localhost:8761/eureka/"; 21 | 22 | [Benchmark(Description = "LogCase.GetMessages (Eureka)")] 23 | public override void RunGetMessages() 24 | { 25 | base.RunGetMessages(); 26 | } 27 | 28 | 29 | [Benchmark(Description = "LogCase.Log (Eureka)")] 30 | public override void RunLog() 31 | { 32 | base.RunLog(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /test/Swifty.Benchmark/LogTester3.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Attributes; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Thrifty.Benchmark 7 | { 8 | public class LogTester3 : LogTester 9 | { 10 | protected override int Port => 6666; 11 | 12 | protected override bool EnableConnectionPool => true; 13 | 14 | protected override string EurekaAddress => "http://localhost:8761/eureka/"; 15 | 16 | [Benchmark(Description = "LogCase.GetMessages (Eureka)")] 17 | public override void RunGetMessages() 18 | { 19 | base.RunGetMessages(); 20 | } 21 | 22 | 23 | [Benchmark(Description = "LogCase.Log (Eureka)")] 24 | public override void RunLog() 25 | { 26 | base.RunLog(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/Swifty.Benchmark/Program.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Running; 2 | using System; 3 | using System.Reflection; 4 | using System.Text; 5 | 6 | namespace Thrifty.Benchmark 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | Console.OutputEncoding = Encoding.UTF8; 13 | 14 | ConsoleKeyInfo info; 15 | Console.WriteLine("按任意键开始测试, 退出按 Esc"); 16 | while ((info = Console.ReadKey()) != null) 17 | { 18 | switch (info) 19 | { 20 | case ConsoleKeyInfo n when n.Key == ConsoleKey.Escape: 21 | break; 22 | default: 23 | BenchmarkSwitcher.FromAssembly(typeof(Program).GetTypeInfo().Assembly).Run(args); 24 | break; 25 | } 26 | Console.WriteLine("按任意键开始测试, 退出按 Esc"); 27 | } 28 | } 29 | 30 | 31 | } 32 | } -------------------------------------------------------------------------------- /test/Swifty.Benchmark/Thrifty.Benchmark.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp1.1 6 | 1.1.2 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /test/Swifty.Tests/AssertEx.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Xunit; 6 | 7 | namespace Thrifty.Tests 8 | { 9 | public static class AssertEx 10 | { 11 | public static void Equals(IDictionary d1, IDictionary d2) 12 | { 13 | Assert.NotNull(d1); 14 | Assert.NotNull(d2); 15 | Assert.Equal(d1.Count, d2.Count); 16 | foreach (var kp in d1) 17 | { 18 | Assert.True(d2.ContainsKey(kp.Key), $"expected key was not found: {kp.Key}"); 19 | Assert.Equal(kp.Value, d2[kp.Key]); 20 | } 21 | } 22 | 23 | public static void Equals(IEnumerable d1, IEnumerable d2) 24 | { 25 | Assert.NotNull(d1); 26 | Assert.NotNull(d2); 27 | Assert.Equal(d1.Count(), d2.Count()); 28 | int index = 0; 29 | var d2Array = d2.ToArray(); 30 | foreach (var v in d1) 31 | { 32 | Assert.Equal(v, d2Array.ElementAt(index)); 33 | index++; 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /test/Swifty.Tests/MicroServices/Server/ThriftyTypeMetadataTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Thrifty.Services.Metadata; 6 | 7 | namespace Thrifty.Tests.MicroServices.Server 8 | { 9 | using Thrifty.MicroServices.Commons; 10 | using Thrifty.MicroServices.Server; 11 | using Thrifty.Tests.MicroServices.Stup; 12 | using Xunit; 13 | 14 | public class ThriftyTypeMetadataTest 15 | { 16 | [Fact] 17 | public void Initial_Success() 18 | { 19 | new ThriftyServiceMetadata(typeof(IServiceStup), "2.0.0"); 20 | } 21 | 22 | [Fact] 23 | public void Initial_NotInterface_ThrowEx() 24 | { 25 | Assert.Throws(() => new ThriftyServiceMetadata(this.GetType())); 26 | } 27 | 28 | [Fact] 29 | public void GetProperties_Success() 30 | { 31 | var swiftMetadata = new ThriftyServiceMetadata(typeof(IServiceStup), "1.1"); 32 | 33 | //这个测试有点.... 34 | Assert.Equal(swiftMetadata.ServiceName, ThriftServiceMetadata.ParseServiceName(typeof(IServiceStup))); 35 | Assert.Equal(swiftMetadata.Version, "1.1"); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/Swifty.Tests/MicroServices/Stup/INoServiceInterface.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Tests.MicroServices.Stup 7 | { 8 | public interface INoServiceInterface 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/Swifty.Tests/MicroServices/Stup/IServiceStup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Tests.MicroServices.Stup 7 | { 8 | [ThriftService()] 9 | public interface IServiceStup 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/Swifty.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using Xunit; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("Thrifty.Tests")] 12 | [assembly: AssemblyTrademark("")] 13 | 14 | // Setting ComVisible to false makes the types in this assembly not visible 15 | // to COM components. If you need to access a type in this assembly from 16 | // COM, set the ComVisible attribute to true on that type. 17 | [assembly: ComVisible(false)] 18 | 19 | // The following GUID is for the ID of the typelib if this project is exposed to COM 20 | [assembly: Guid("362db1bc-6f31-42fa-a2a6-de8f5e5a9d76")] 21 | [assembly: CollectionBehavior(DisableTestParallelization = true, MaxParallelThreads =1)] 22 | -------------------------------------------------------------------------------- /test/Swifty.Tests/Services/Codecs/Internal/EnumThriftCodecTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Thrifty.Services; 8 | using Thrifty.Tests.TestModel.Codecs; 9 | 10 | using Xunit; 11 | 12 | namespace Thrifty.Tests.Services.Codecs.Internal 13 | { 14 | public class EnumThriftCodecTest 15 | { 16 | [Fact(DisplayName = "EnumThriftCodec enum枚举类型序列化")] 17 | public void EnumFielReadAndWritedTest() 18 | { 19 | var enumStruct = new EnumStruct() 20 | { 21 | DefaultEnum = DefaultEnum.Node2, 22 | ComplexEnum = ComplexEnum.Node1, 23 | //ErrorEnum = ErrorEnum.Node1, 24 | }; 25 | 26 | ThriftSerializer serializer = new ThriftSerializer(); 27 | var bytes = serializer.Serialize(enumStruct); 28 | 29 | var obj = serializer.Deserialize(bytes); 30 | 31 | Assert.NotNull(obj); 32 | Assert.Equal(DefaultEnum.Node2, obj.DefaultEnum); 33 | Assert.Equal(ComplexEnum.Node1, obj.ComplexEnum); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /test/Swifty.Tests/Services/ExceptionServerTest.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Services; 2 | using Thrifty.Tests.TestModel.Services; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using Thrift.Protocol; 8 | using Xunit; 9 | 10 | namespace Thrifty.Tests.Services 11 | { 12 | [Collection("ExceptionServerTest")] 13 | public class ExceptionServerTest 14 | { 15 | [Fact(DisplayName ="Server Exception: 普通异常")] 16 | public void TestServerException() 17 | { 18 | using (ScopedServer server = new ScopedServer(new TBinaryProtocol.Factory(), new ExceptionService())) 19 | { 20 | using (ThriftClientManager manager = new ThriftClientManager()) 21 | { 22 | using (var client = server.CreateScribeClient(manager, server, new TBinaryProtocol.Factory())) 23 | { 24 | ThriftyException ex = Assert.Throws(() => client.ThrowArgumentException()); 25 | Assert.Contains(ExceptionService.ExceptionMessage, ex.Message); 26 | } 27 | 28 | manager.CloseAsync(TimeSpan.FromSeconds(3)); 29 | } 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Codecs/BaseServiceImplementation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Tests.Services.Codecs 7 | { 8 | public class BaseServiceImplementation : IBaseService 9 | { 10 | public void FooBase() 11 | { 12 | throw new NotImplementedException(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Codecs/CombinedServiceImplementation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Tests.Services.Codecs 7 | { 8 | public class CombinedServiceImplementation : ICombinedService 9 | { 10 | public void FooBase() 11 | { 12 | throw new NotImplementedException(); 13 | } 14 | 15 | public void FooCombined() 16 | { 17 | throw new NotImplementedException(); 18 | } 19 | 20 | public void FooOne() 21 | { 22 | throw new NotImplementedException(); 23 | } 24 | 25 | public void FooTwo() 26 | { 27 | throw new NotImplementedException(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Codecs/DerivedStruct.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Tests.Services.Codecs 7 | { 8 | [ThriftStruct] 9 | public class DerivedStruct : SimpleStruct 10 | { 11 | [ThriftField(99)] 12 | public String PropertyExtend { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Codecs/EnumStruct.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty.Tests.TestModel.Codecs 8 | { 9 | [ThriftStruct("enumstruct")] 10 | public class EnumStruct 11 | { 12 | [ThriftField(1)] 13 | public DefaultEnum DefaultEnum { get; set; } 14 | [ThriftField(2)] 15 | public ComplexEnum ComplexEnum { get; set; } 16 | //[ThriftField(3)] 17 | //public ErrorEnum ErrorEnum { get; set; } 18 | } 19 | 20 | public enum DefaultEnum 21 | { 22 | Node1, 23 | Node2, 24 | Node3 25 | } 26 | 27 | public enum ComplexEnum 28 | { 29 | Node1 = 85, 30 | Node2 = 66, 31 | Node3 = 13 32 | } 33 | 34 | public enum ErrorEnum 35 | { 36 | Node1 = -22, 37 | Node2 = -20, 38 | Node3 = 5, 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Codecs/IBaseService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Tests.Services.Codecs 7 | { 8 | [ThriftService("BaseService")] 9 | public interface IBaseService 10 | { 11 | [ThriftMethod] 12 | void FooBase(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Codecs/ICombinedService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Tests.Services.Codecs 7 | { 8 | [ThriftService("CombinedService")] 9 | public interface ICombinedService : IDerivedServiceOne, IDerivedServiceTwo 10 | { 11 | [ThriftMethod] 12 | void FooCombined(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Codecs/IDerivedServiceOne.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Tests.Services.Codecs 7 | { 8 | [ThriftService("DerivedServiceOne")] 9 | public interface IDerivedServiceOne : IBaseService 10 | { 11 | [ThriftMethod] 12 | void FooOne(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Codecs/IDerivedServiceTwo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Tests.Services.Codecs 7 | { 8 | [ThriftService("DerivedServiceTwo")] 9 | public interface IDerivedServiceTwo : IBaseService 10 | { 11 | [ThriftMethod] 12 | void FooTwo(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Codecs/MultipleDerivedServiceImplementation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Tests.Services.Codecs 7 | { 8 | public class MultipleDerivedServiceImplementation : IDerivedServiceOne, IDerivedServiceTwo 9 | { 10 | public void FooBase() 11 | { 12 | throw new NotImplementedException(); 13 | } 14 | 15 | public void FooOne() 16 | { 17 | throw new NotImplementedException(); 18 | } 19 | 20 | public void FooTwo() 21 | { 22 | throw new NotImplementedException(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Codecs/MultipleDerivedServiceImplementationWithExplicitAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Tests.Services.Codecs 7 | { 8 | [ThriftService("MultipleDerivedServiceImplementation")] 9 | public class MultipleDerivedServiceImplementationWithExplicitAttribute : IDerivedServiceOne, IDerivedServiceTwo 10 | { 11 | public void FooBase() 12 | { 13 | throw new NotImplementedException(); 14 | } 15 | 16 | public void FooOne() 17 | { 18 | throw new NotImplementedException(); 19 | } 20 | 21 | public void FooTwo() 22 | { 23 | throw new NotImplementedException(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Codecs/RecursiveStruct.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Tests.Services.Codecs 7 | { 8 | [ThriftStruct] 9 | public class ListRecursiveStruct 10 | { 11 | [ThriftField(1)] 12 | public IList List { get; set; } 13 | } 14 | 15 | [ThriftStruct] 16 | public class Struct2 17 | { 18 | [ThriftField(1, Recursive = ThriftFieldAttribute.Recursiveness.True)] 19 | public ListRecursiveStruct Parent { get; set; } 20 | } 21 | 22 | [ThriftStruct] 23 | public class InvalidRecursiveStruct 24 | { 25 | [ThriftField(1)] 26 | public InvalidRecursiveStruct Parent { get; set; } 27 | } 28 | 29 | [ThriftStruct] 30 | public class RecursiveStruct 31 | { 32 | [ThriftField(1, Recursive = ThriftFieldAttribute.Recursiveness.True)] 33 | public InvalidRecursiveStruct Parent { get; set; } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Codecs/SingleDerivedServiceImplementation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Tests.Services.Codecs 7 | { 8 | public class SingleDerivedServiceImplementation : IDerivedServiceOne 9 | { 10 | public void FooBase() 11 | { 12 | throw new NotImplementedException(); 13 | } 14 | 15 | public void FooOne() 16 | { 17 | throw new NotImplementedException(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Codecs/StructWithConstructor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty.Tests.Services.Codecs 8 | { 9 | [ThriftStruct] 10 | #pragma warning disable CS0659 // Type overrides Object.Equals(object o) but does not override Object.GetHashCode() 11 | public class StructWithConstructor 12 | #pragma warning restore CS0659 // Type overrides Object.Equals(object o) but does not override Object.GetHashCode() 13 | { 14 | [ThriftField(1)] 15 | public String StringProperty { get; } 16 | 17 | [ThriftField(2)] 18 | public int IntProperty { get; set; } 19 | 20 | [ThriftConstructor] 21 | public StructWithConstructor([ThriftField(1)]String a, [ThriftField(2)]int b) 22 | { 23 | this.StringProperty = a; 24 | this.IntProperty = b; 25 | } 26 | 27 | public override bool Equals(object obj) 28 | { 29 | if (obj == null) 30 | { 31 | return false; 32 | } 33 | foreach (var property in this.GetType().GetTypeInfo().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public)) 34 | { 35 | object v1 = property.GetValue(this); 36 | object v2 = property.GetValue(obj); 37 | if (!Object.Equals(v1, v2)) 38 | { 39 | return false; 40 | } 41 | } 42 | return true; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Services/AsyncService.cs: -------------------------------------------------------------------------------- 1 | using Thrifty.Tests.Services.Codecs; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace Thrifty.Tests.TestModel.Services 9 | { 10 | [ThriftService] 11 | public interface IAsyncService : IDisposable 12 | { 13 | [ThriftMethod] 14 | void VerifyConnectionState(); 15 | 16 | [ThriftMethod(OneWay = true)] 17 | Task OneWayMethod(); 18 | 19 | [ThriftMethod] 20 | Task ExceptionMethod(); 21 | 22 | [ThriftMethod] 23 | Task TwoWayMethod(SimpleStruct structObjec); 24 | } 25 | 26 | public class AsyncService : IAsyncService 27 | { 28 | public const string ExceptionMessage = "async service exception"; 29 | public void Dispose() 30 | { 31 | } 32 | 33 | // [DebuggerStepThrough] 34 | public Task ExceptionMethod() 35 | { 36 | throw new Exception(ExceptionMessage); 37 | } 38 | 39 | public Task OneWayMethod() 40 | { 41 | return Task.FromResult(0); 42 | } 43 | 44 | public Task TwoWayMethod(SimpleStruct structObjec) 45 | { 46 | return Task.FromResult(structObjec); 47 | } 48 | 49 | public void VerifyConnectionState() 50 | { 51 | 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Services/IExceptionService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Thrift; 7 | 8 | namespace Thrifty.Tests.TestModel.Services 9 | { 10 | [ThriftService] 11 | public interface IExceptionService : IDisposable 12 | { 13 | [ThriftMethod] 14 | void ThrowArgumentException(); 15 | 16 | [ThriftMethod] 17 | void ThrowTException(); 18 | } 19 | 20 | public class ExceptionService : IExceptionService 21 | { 22 | public const string ExceptionMessage = "abcdefg"; 23 | public void Dispose() 24 | { 25 | } 26 | 27 | [DebuggerStepThrough] 28 | public void ThrowArgumentException() 29 | { 30 | throw new ArgumentException(ExceptionMessage); 31 | } 32 | 33 | [DebuggerStepThrough] 34 | public void ThrowTException() 35 | { 36 | throw new TException(ExceptionMessage); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Services/LogEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Tests.Services 7 | { 8 | [ThriftStruct] 9 | public class LogEntry 10 | { 11 | [ThriftField(1)] 12 | public string Category { get; set; } 13 | 14 | [ThriftField(2)] 15 | public string Message { get; set; } 16 | 17 | [ThriftConstructor] 18 | public LogEntry([ThriftField(2)]String message, [ThriftField(1)]String category) 19 | { 20 | this.Message = message; 21 | this.Category = category; 22 | } 23 | 24 | public LogEntry() 25 | { 26 | 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Services/OneWayService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty.Tests.TestModel.Services 8 | { 9 | [ThriftService] 10 | public interface IOneWayService : IDisposable 11 | { 12 | [ThriftMethod] 13 | void VerifyConnectionState(); 14 | 15 | [ThriftMethod(OneWay = true)] 16 | void OneWayMethod(); 17 | 18 | [ThriftMethod(OneWay = true)] 19 | void OneWayThrow(); 20 | } 21 | 22 | public class OneWayService : IOneWayService 23 | { 24 | public const string ExceptionMessage = "oneway excecption"; 25 | public void Dispose() 26 | { 27 | } 28 | 29 | public void VerifyConnectionState() 30 | { 31 | 32 | } 33 | 34 | [DebuggerStepThrough] 35 | public void OneWayThrow() 36 | { 37 | throw new ArgumentException("oneway excecption"); 38 | } 39 | 40 | public void OneWayMethod() 41 | { 42 | 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Services/ResultCode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Tests.Services 7 | { 8 | public enum ResultCode 9 | { 10 | OK, 11 | TRY_LATER 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Services/Scribe.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Thrifty.Tests.Services 7 | { 8 | [ThriftService("Scribe")] 9 | public interface IScribe : IDisposable 10 | { 11 | [ThriftMethod] 12 | List getMessages(); 13 | 14 | [ThriftMethod] 15 | ResultCode log(List messages); 16 | } 17 | 18 | public class ScribeTest : IScribe 19 | { 20 | public void Dispose() 21 | { 22 | GC.SuppressFinalize(this); 23 | } 24 | 25 | public List getMessages() 26 | { 27 | return new List 28 | { 29 | new LogEntry { Category = "c1", Message = Guid.NewGuid().ToString() }, 30 | new LogEntry { Category = "c2", Message = Guid.NewGuid().ToString() }, 31 | new LogEntry { Category = "c3", Message = Guid.NewGuid().ToString() } 32 | 33 | }; 34 | } 35 | 36 | public ResultCode log(List messages) 37 | { 38 | return ResultCode.TRY_LATER; 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /test/Swifty.Tests/TestModel/Services/SimpleService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace Thrifty.Tests.Services 8 | { 9 | [ThriftService("SimpleService")] 10 | public class SimpleService 11 | { 12 | [ThriftMethod] 13 | public void Sleep(int seconds) 14 | { 15 | Thread.Sleep(seconds * 1000); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/Swifty.Tests/Thrifty.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net461 5 | Thrifty.Tests 6 | ..\..\assembly.snk 7 | $(Configuration)=='release' 8 | true 9 | Thrifty.Tests 10 | false 11 | false 12 | false 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | --------------------------------------------------------------------------------