Example #1
0
        public void Initialize(ExtensionConfigContext extensionConfigContext)
        {
            _log?.LogInformation("Availability Monitoring Extension is initializing:"
                                 + " {{Version=\"{Version}\"}}",
                                 this.GetType().Assembly.GetName().Version);

            Validate.NotNull(extensionConfigContext, nameof(extensionConfigContext));

            // A Coded Availablity Test is defined as such by returning a value that is bound by AvailabilityTestResult-Attribute.
            // A paramater bound by AvailabilityTestInfo-Attribute is optional.
            // Such parameter can be used to programmatically get information about the current availablity test, or it can be omitted.

            // FluentBindingRule<T> is marked as Obsolete, yet it is the type returned from AddBindingRule(..)
            // We could use "var", but one should NEVER use "var" except in Lync expressions
            // or when the type is clear from the *same* line to an unfamiliar reader.
            // Neither is the case, so we use the type explicitly and work around the obsolete-warning by disabling it.
#pragma warning disable CS0618
            FluentBindingRule <AvailabilityTestResultAttribute> testResultRule = extensionConfigContext.AddBindingRule <AvailabilityTestResultAttribute>();
            FluentBindingRule <AvailabilityTestInfoAttribute>   testInfoRule   = extensionConfigContext.AddBindingRule <AvailabilityTestInfoAttribute>();
#pragma warning restore CS0618

            // This binding is used to get and process the return value of the function:
            testResultRule.BindToCollector <AvailabilityTestResultAttribute, AvailabilityTelemetry>(CreateAvailabilityTelemetryAsyncCollector);
            testResultRule.BindToCollector <AvailabilityTestResultAttribute, bool>(CreateBoolAsyncCollector);
            extensionConfigContext.AddConverter <string, AvailabilityTelemetry>(Convert.StringToAvailabilityTelemetry);

            // This is an optional In-parameter that allows user code to get runtime info about the availablity test:
            testInfoRule.BindToInput <AvailabilityTestInfo>(CreateAvailabilityTestInfo);
            extensionConfigContext.AddConverter <AvailabilityTestInfo, string>(Convert.AvailabilityTestInfoToString);
        }
Example #2
0
#pragma warning disable CS0618
        public static void BindToCollector <TAttribute, TMessage>(
            this FluentBindingRule <TAttribute> bindingRule,
            Func <TAttribute, ValueBindingContext, Task <IAsyncCollector <TMessage> > > asyncCollectorFactory)
            where TAttribute : Attribute
#pragma warning restore CS0618
        {
            // We could speed this up 10x - 100x by creating and caching delegates to the methods we accell vie reflection.
            // However, since this is a temp workaround until the methods are available in the SDK, we will avoid the complexity.

#pragma warning disable CS0618
            Type fluentBindingRuleType = typeof(FluentBindingRule <TAttribute>);
#pragma warning restore CS0618

            // First, reflect to invoke the method
            //     public static PatternMatcher New<TSource, TDest>(Func<TSource, ValueBindingContext, Task<TDest>> func)
            // on the PatternMatcher class:

            Type       patternMatcherType         = fluentBindingRuleType.Assembly.GetType(PatternMatcherTypeName);
            MethodInfo patternMatcherFactoryBound = null;
            {
                Type[] genericMethodParamTypes = new Type[] { typeof(TAttribute), typeof(IAsyncCollector <TMessage>) };
                Type   requiredParamType       = typeof(Func <TAttribute, ValueBindingContext, Task <IAsyncCollector <TMessage> > >);

                foreach (MethodInfo method in patternMatcherType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static))
                {
                    if (method.IsGenericMethod && method.GetParameters().Length == 1 && method.GetGenericArguments().Length == 2)
                    {
                        MethodInfo methodBound = method.MakeGenericMethod(genericMethodParamTypes);
                        if (methodBound.GetParameters()[0].ParameterType.Equals(requiredParamType))
                        {
                            patternMatcherFactoryBound = methodBound;
                            break;
                        }
                    }
                }
            }

            // Create a PatternMatcher instance that wraps asyncCollectorFactory:
            object patternMatcherInstance = patternMatcherFactoryBound.Invoke(obj: null, parameters: new object[] { asyncCollectorFactory });

            // Next, reflect to invoke
            //     private void BindToCollector<TMessage>(PatternMatcher pm)
            // in the FluentBindingRule<TAttribute> class:

            MethodInfo bindToCollectorMethodGeneric = fluentBindingRuleType.GetMethod(
                FluentBindingRuleBindToCollectorMethodName,
                BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
                binder: null,
                new Type[] { patternMatcherType },
                NoParameterModifiers);

            MethodInfo bindToCollectorMethodBound = bindToCollectorMethodGeneric.MakeGenericMethod(new Type[] { typeof(TMessage) });

            // Bind asyncCollectorFactory wrapped into the patternMatcherInstance to the binding rule:
            bindToCollectorMethodBound.Invoke(obj: bindingRule, parameters: new object[] { patternMatcherInstance });
        }
#pragma warning disable CS0618 // Type or member is obsolete. FluentBindingRule is "Not ready for public consumption."
        private void RegisterCommonConverters <T>(FluentBindingRule <T> rule) where T : Attribute
#pragma warning restore CS0618 // Type or member is obsolete
        {
            //  Converter manager already has Stream-->Byte[],String,TextReader
            rule.AddConverter <BlobBaseClient, Stream>(ConvertToStreamAsync);
            // Blob type is a property of an existing blob.
            rule.AddConverter(new StorageBlobConverter <AppendBlobClient>());
            rule.AddConverter(new StorageBlobConverter <BlockBlobClient>());
            rule.AddConverter(new StorageBlobConverter <PageBlobClient>());
        }
Example #4
0
        /// <summary>
        /// Initializes the SQL binding rules
        /// </summary>
        /// <param name="context"> The config context </param>
        /// <exception cref="ArgumentNullException">
        /// Thrown if context is null
        /// </exception>
        public void Initialize(ExtensionConfigContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            ILogger logger = this._loggerFactory.CreateLogger(LogCategories.Bindings);

            TelemetryInstance.Initialize(this._configuration, logger);
#pragma warning disable CS0618 // Fine to use this for our stuff
            FluentBindingRule <SqlAttribute> inputOutputRule = context.AddBindingRule <SqlAttribute>();
            var converter = new SqlConverter(this._configuration);
            inputOutputRule.BindToInput(converter);
            inputOutputRule.BindToInput <string>(typeof(SqlGenericsConverter <string>), this._configuration, logger);
            inputOutputRule.BindToCollector <OpenType>(typeof(SqlAsyncCollectorBuilder <>), this._configuration, logger);
            inputOutputRule.BindToInput <OpenType>(typeof(SqlGenericsConverter <>), this._configuration, logger);
        }
Example #5
0
        public static void BindToCollector <TAttribute, TMessage>(this FluentBindingRule <TAttribute> rule, Func <TAttribute, ValueBindingContext, Task <IAsyncCollector <TMessage> > > buildFromAttribute) where TAttribute : Attribute
        {
            // TEMP: temporary workaround code effectively adding a ValueBindingContext collector overload,
            // until it's added to the SDK
            Type patternMatcherType          = typeof(FluentBindingRule <>).Assembly.GetType("Microsoft.Azure.WebJobs.Host.Bindings.PatternMatcher");
            var  patternMatcherNewMethodInfo = patternMatcherType.GetMethods()[4]; // TODO: get this method properly via reflection

            patternMatcherNewMethodInfo = patternMatcherNewMethodInfo.MakeGenericMethod(new Type[] { typeof(TAttribute), typeof(IAsyncCollector <TMessage>) });
            var patternMatcherInstance = patternMatcherNewMethodInfo.Invoke(null, new object[] { buildFromAttribute });

            MethodInfo bindToCollectorMethod = typeof(FluentBindingRule <TAttribute>).GetMethod(
                "BindToCollector",
                System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic,
                binder: null,
                new Type[] { patternMatcherType },
                modifiers: null);

            bindToCollectorMethod = bindToCollectorMethod.MakeGenericMethod(new Type[] { typeof(TMessage) });
            bindToCollectorMethod.Invoke(rule, new object[] { patternMatcherInstance });
        }
Example #6
0
        public void Initialize(ExtensionConfigContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var extensions = context.Config.GetService <IExtensionRegistry>();

            // register trigger binding provider
            var triggerBindingProvider = new EdgeHubTriggerBindingProvider();

            extensions.RegisterExtension <ITriggerBindingProvider>(triggerBindingProvider);

            extensions.RegisterBindingRules <EdgeHubAttribute>();
            FluentBindingRule <EdgeHubAttribute> rule = context.AddBindingRule <EdgeHubAttribute>();

            rule.BindToCollector <Message>(typeof(EdgeHubCollectorBuilder));

            context.AddConverter <Message, string>(this.MessageConverter);
            context.AddConverter <string, Message>(this.ConvertToMessage);
        }