public void RecursiveTypeTest()
        {
            ThriftCatalog catalog = new ThriftCatalog();
            ThriftStructMetadataBuilder builder = new ThriftStructMetadataBuilder(catalog, typeof(RecursiveStruct));
            var metadata = builder.Build();

            Assert.Equal(1, metadata.Fields.Count());
        }
        public void InvalidRecursiveTypeTest()
        {
            ThriftCatalog catalog = new ThriftCatalog();

            Assert.Throws <ThriftyException>(() =>
            {
                ThriftStructMetadataBuilder builder = new ThriftStructMetadataBuilder(catalog, typeof(InvalidRecursiveStruct));
                builder.Build();
            });
        }
        public void ComplexTypeTest()
        {
            ThriftCatalog catalog = new ThriftCatalog();
            ThriftStructMetadataBuilder builder  = new ThriftStructMetadataBuilder(catalog, typeof(ComplexStruct));
            ThriftStructMetadata        metadata = builder.Build();

            var properties = typeof(ComplexStruct).GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.DeclaredOnly);

            Assert.Equal(properties.Length, metadata.Fields.Count());

            Assert.Equal(false, metadata.IsException);
            Assert.Equal(false, metadata.IsUnion);
            Assert.Equal(MetadataType.Struct, metadata.MetadataType);
            Assert.Equal(0, metadata.MethodInjections.Count());
            Assert.Equal(null, metadata.BuilderType);
        }
        private ThriftStructMetadata StructTest <T>()
        {
            ThriftCatalog catalog = new ThriftCatalog();
            ThriftStructMetadataBuilder builder  = new ThriftStructMetadataBuilder(catalog, typeof(T));
            ThriftStructMetadata        metadata = builder.Build();

            var properties = typeof(T).GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);

            Assert.Equal(properties.Length, metadata.Fields.Count());

            Assert.Equal(false, metadata.IsException);
            Assert.Equal(false, metadata.IsUnion);
            Assert.Equal(MetadataType.Struct, metadata.MetadataType);
            Assert.Equal(0, metadata.MethodInjections.Count());
            Assert.Equal(null, metadata.BuilderType);
            return(metadata);
        }
示例#5
0
        internal ThriftMethodMetadata(String serviceName, MethodInfo method, ThriftCatalog catalog)
        {
            Guard.ArgumentNullOrWhiteSpaceString(serviceName, nameof(serviceName));
            Guard.ArgumentNotNull(method, nameof(method));
            Guard.ArgumentNotNull(catalog, nameof(catalog));

            this.Order = (ThriftCatalog.GetMethodOrder(method) ?? int.MaxValue);

            ThriftMethodAttribute thriftMethod = method.GetCustomAttribute <ThriftMethodAttribute>();

            if (thriftMethod == null)
            {
                throw new ArgumentException($"Method '{method.DeclaringType.Name}.{method.Name}' is not annotated with {nameof(ThriftMethodAttribute)}.", nameof(method));
            }
            if (method.IsStatic)
            {
                throw new ArgumentException($"Method '{method.DeclaringType.Name}.{method.Name} is a static method.", nameof(method));
            }

            this.Name = String.IsNullOrWhiteSpace(thriftMethod.Name) ? method.Name : thriftMethod.Name.Trim();

            this.QualifiedName = GetQualifiedName(serviceName, Name);

            //this.QualifiedName = $"{serviceName}.{this.Name}";
            this.ReturnType = catalog.GetThriftType(method.ReturnType);

            var builder    = ImmutableList.CreateBuilder <ThriftFieldMetadata>();
            var parameters = method.GetParameters();
            int index      = 0;

            foreach (var p in parameters)
            {
                ThriftFieldMetadata fieldMetadata = CreateFieldMetadata(catalog, index, p);
                builder.Add(fieldMetadata);
                index++;
            }
            this.Parameters = builder.ToImmutableList();
            this.IsOneWay   = thriftMethod.OneWay;
            this.Method     = method;
            this.Exceptions = BuildExceptions(catalog, method);
        }
示例#6
0
        private static ThriftFieldMetadata CreateFieldMetadata(ThriftCatalog catalog, int index, ParameterInfo parameterInfo)
        {
            ThriftFieldAttribute thriftField   = parameterInfo.GetCustomAttribute <ThriftFieldAttribute>();
            short        parameterId           = short.MinValue;
            String       parameterName         = parameterInfo.Name;
            Requiredness parameterRequiredness = Requiredness.Unspecified;

            if (thriftField != null)
            {
                parameterId           = thriftField.Id;
                parameterRequiredness = thriftField.Required;
                if (!String.IsNullOrWhiteSpace(thriftField.Name))
                {
                    parameterName = thriftField.Name.Trim();
                }
            }
            if (parameterId == short.MinValue)
            {
                parameterId = (short)(index + 1);
            }
            ThriftType thriftType         = catalog.GetThriftType(parameterInfo.ParameterType);
            var        parameterInjection = new ThriftParameterInjection(parameterId, parameterName, index, parameterInfo.ParameterType);

            if (parameterRequiredness == Requiredness.Unspecified)
            {
                // There is only one field injection used to build metadata for method parameters, and if a
                // single injection point has UNSPECIFIED requiredness, that resolves to NONE.
                parameterRequiredness = Requiredness.None;
            }
            ThriftFieldMetadata fieldMetadata = new ThriftFieldMetadata(
                parameterId,
                false /* recursiveness */,
                parameterRequiredness,
                new DefaultThriftTypeReference(thriftType),
                parameterName,
                FieldKind.ThriftField,
                new IThriftInjection[] { parameterInjection });

            return(fieldMetadata);
        }
示例#7
0
        //private readonly IEnumerable<String> documentation;

        public ThriftServiceMetadata(Type serviceClass, ThriftCatalog catalog)
        {
            this.Name = ParseServiceName(serviceClass);

            var builder = ImmutableDictionary.CreateBuilder <String, ThriftMethodMetadata>();

            foreach (var method in serviceClass.FindAttributedMethods(typeof(ThriftMethodAttribute)))
            {
                ThriftMethodMetadata methodMetadata = new ThriftMethodMetadata(this.Name, method, catalog);
                if (builder.ContainsKey(methodMetadata.QualifiedName))
                {
                    throw new ThriftyException($"duplicate thrift method : {method.DeclaringType.FullName}.{method.Name} .");
                }
                builder[methodMetadata.QualifiedName] = methodMetadata;
            }
            this.Methods = builder.ToImmutable();

            //A multimap from order to method name. Sorted by key (order), with nulls (i.e. no order) last.
            //Within each key, values(ThriftMethodMetadata) are sorted by method name.

            this.DeclaredMethods = builder
                                   .OrderBy(kp => kp.Value.Order).ThenBy(kp => kp.Key)
                                   .ToArray()
                                   .ToImmutableDictionary(kp => kp.Key, kp => kp.Value);

            List <ThriftServiceMetadata> parentServices = new List <ThriftServiceMetadata>();

            foreach (var parent in serviceClass.GetTypeInfo().GetInterfaces())
            {
                var attributes = parent.GetEffectiveClassAnnotations <ThriftServiceAttribute>();
                if (attributes.Any())
                {
                    parentServices.Add(new ThriftServiceMetadata(parent, catalog));
                }
            }
            this.ParentServices = parentServices.ToImmutableList();
        }
示例#8
0
        private IDictionary <short, ThriftType> BuildExceptions(ThriftCatalog catalog, MethodInfo method)
        {
            var            exceptions     = ImmutableDictionary.CreateBuilder <short, ThriftType>();
            HashSet <Type> exceptionTypes = new HashSet <Type>();

            var exceptionAttributes = method.GetCustomAttributes <ThriftExceptionAttribute>(true);

            foreach (var thriftException in exceptionAttributes)
            {
                if (!exceptionTypes.Add(thriftException.ExceptionType))
                {
                    throw new ThriftyException($"ThriftExceptionAttribute on method {method.DeclaringType}.{method.Name} contains more than one value for {thriftException.ExceptionType} .");
                }
                if (exceptions.ContainsKey(thriftException.Id))
                {
                    throw new ThriftyException($"ThriftExceptionAttribute on method {method.DeclaringType}.{method.Name} has duplicate id: {thriftException.Id} .");
                }
                exceptions.Add(thriftException.Id, catalog.GetThriftType(thriftException.ExceptionType));
            }

            foreach (var exceptionType in exceptionAttributes.Select(a => a.ExceptionType))
            {
                if (exceptionType.GetTypeInfo().IsAssignableFrom(typeof(TException)))
                {
                    // the built-in exception types don't need special treatment
                    continue;
                }
                ThriftStructAttribute attribute = exceptionType.GetTypeInfo().GetCustomAttribute <ThriftStructAttribute>();
                if (attribute == null)
                {
                    throw new ThriftyException($"ThriftExceptionAttribute on method {method.DeclaringType}.{method.Name} with {exceptionType.FullName} need {nameof(ThriftStructAttribute)} .");
                }
            }

            return(exceptions.ToImmutableDictionary());
        }
示例#9
0
        public ThriftCodecManager(IEnumerable <IThriftCodec> codecs = null, IThriftCodecFactory factory = null, ThriftCatalog catalog = null)
        {
            _typeCodecs            = new ConcurrentDictionary <ThriftType, IThriftCodec>();
            _stack                 = new ThreadLocal <Stack <ThriftType> >(() => new Stack <ThriftType>());
            _deferredTypesWorkList = new ThreadLocal <Stack <ThriftType> >(() => new Stack <ThriftType>());
            this.Catalog           = catalog ?? new ThriftCatalog();
            this._factory          = factory ?? new ReflectionThriftCodecFactory();


            AddBuiltinCodec(new BooleanThriftCodec());
            AddBuiltinCodec(new ByteThriftCodec());
            AddBuiltinCodec(new ShortThriftCodec());
            AddBuiltinCodec(new IntThriftCodec());
            AddBuiltinCodec(new LongThriftCodec());
            AddBuiltinCodec(new DoubleThriftCodec());
            AddBuiltinCodec(new ByteBufferThriftCodec());
            AddBuiltinCodec(new StringThriftCodec());
            AddBuiltinCodec(new VoidThriftCodec());
            AddBuiltinCodec(new BooleanArrayThriftCodec());
            AddBuiltinCodec(new ShortArrayThriftCodec());
            AddBuiltinCodec(new IntArrayThriftCodec());
            AddBuiltinCodec(new LongArrayThriftCodec());
            AddBuiltinCodec(new DoubleArrayThriftCodec());
            AddBuiltinCodec(new FloatThriftCodec());
            AddBuiltinCodec(new FloatArrayThriftCodec());
            AddBuiltinCodec(new DateTimeThriftCodec());
            AddBuiltinCodec(new DateTimeArrayThriftCodec());
            AddBuiltinCodec(new GuidThriftCodec());
            AddBuiltinCodec(new DecimalThriftCodec());

            var codecArray = codecs ?? Enumerable.Empty <IThriftCodec>();

            foreach (var codec in codecArray)
            {
                AddCodec(codec);
            }
        }