private void ImplementRegisterRoute(ILProcessor il, TypeDefinition functionType, FieldDefinition serviceField, VariableDefinition modelVariable, PluginMetadata service, RouteMetadata route)
        {
            var key   = $"Handle_{serviceField.Name}_{route.Method.Name}";
            var isRpc = RouteHandlerFactory.IsRpc(route);

            // create private handler function
            var method = functionType.Methods.SingleOrDefault(x => x.Name == key);

            if (method == null)
            {
                var returnType = _module.ImportReference(isRpc ? _rpcReturnType : _busReturnType);
                method = new MethodDefinition(key, MethodAttributes.Private | MethodAttributes.HideBySig, returnType);
                method.Parameters.Add(new ParameterDefinition("message", ParameterAttributes.None, _messageType));
                method.Parameters.Add(new ParameterDefinition("cancellationToken", ParameterAttributes.None, _cancellationTokenType));
                functionType.Methods.Add(method);

                ImplementRouteHandler(method, serviceField, route, isRpc);
            }

            il.Emit(OpCodes.Ldloc, modelVariable);

            // RoutePatternParser.Parse("...")
            il.Emit(OpCodes.Ldstr, RouterPatternParser.UnParse(route.Route));
            var routePatternParserType = _routingModule.GetType("Toxon.Micro.RabbitBlog.Routing.Patterns.RouterPatternParser").Resolve();
            var patternParse           = _module.ImportReference(routePatternParserType.Methods.Single(x => x.Name == "Parse"));

            il.Emit(OpCodes.Call, patternParse);

            // new Func<...>(method)
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldftn, method);
            il.Emit(OpCodes.Newobj, _module.ImportReference(isRpc ? _rpcFuncConstructor : _busFuncConstructor));

            // ...
            il.Emit(OpCodes.Ldc_I4, (int)(isRpc ? RouteExecution.Synchronous : RouteExecution.Asynchronous));
            il.Emit(OpCodes.Ldc_I4, (int)(isRpc ? RouteMode.Capture : RouteMode.Observe));
            var cancellationTokenNone = _module.ImportReference(_cancellationTokenType.Resolve().Properties.Single(x => x.Name == "None").GetMethod);

            il.Emit(OpCodes.Call, cancellationTokenNone);

            // model.RegisterAsync(...)
            var registerMethod = _module.ImportReference(isRpc ? _rpcRegisterMethod : _busRegisterMethod);

            il.Emit(OpCodes.Callvirt, registerMethod);
        }
예제 #2
0
        private RouterEntry ToRouterEntry(PluginMetadata plugin, RouteMetadata metadata)
        {
            RouteTargetType targetType;
            string          target;

            if (RouteHandlerFactory.IsRpc(metadata))
            {
                targetType = RouteTargetType.Lambda;
                target     = _namingConventions.GetLambdaName(plugin);
            }
            else
            {
                targetType = RouteTargetType.Sqs;
                target     = _namingConventions.GetSqsName(plugin);
            }

            return(new RouterEntry(plugin.ServiceKey, metadata.Route, targetType, target));
        }
        private void AddService(YamlMappingNode functions, YamlMappingNode resources, ServiceProject service, PluginMetadata plugin)
        {
            var functionName = _namingConventions.GetLambdaName(plugin);

            var env = new YamlMappingNode
            {
                { "ROUTER_QUEUE_NAME", new YamlMappingNode {
                      { "Fn::GetAtt", new YamlSequenceNode("RouterQueue", "QueueName") }
                  } },
                { "ROUTER_FUNCTION_NAME", new YamlMappingNode {
                      { "Ref", "RouterLambdaFunction" }
                  } },
            };

            switch (plugin.ServiceType)
            {
            case ServiceType.MessageHandler:
                var routes = RouteDiscoverer.Discover(plugin);
                if (routes.Any(x => !RouteHandlerFactory.IsRpc(x)))
                {
                    var queueName    = _namingConventions.GetSqsName(plugin);
                    var queueRefName = ToTitleCase(plugin.ServiceKey.Replace('.', '-'));

                    functions.Add(functionName + "-queue", new YamlMappingNode
                    {
                        { "name", functionName + "-queue" },
                        { "handler", "Toxon.Micro.RabbitBlog.Serverless.ServiceEntry::Toxon.Micro.RabbitBlog.Serverless.ServiceEntry.FunctionImpl::HandleQueueAsync" },
                        { "environment", env },
                        { "memorySize", "512" },
                        { "timeout", "60" },
                        { "events", new YamlSequenceNode(BuildSqsEvent(queueRefName)) },
                        {
                            "package", new YamlMappingNode
                            {
                                { "artifact", $"artifacts/{service.Name}-service.zip" },
                            }
                        },
                    });
                    resources.Add(queueRefName, BuildQueue(queueName));
                }

                if (routes.Any(RouteHandlerFactory.IsRpc))
                {
                    functions.Add(functionName, new YamlMappingNode
                    {
                        { "name", functionName },
                        { "handler", "Toxon.Micro.RabbitBlog.Serverless.ServiceEntry::Toxon.Micro.RabbitBlog.Serverless.ServiceEntry.FunctionImpl::HandleDirectAsync" },
                        { "environment", env },
                        { "memorySize", "512" },
                        { "timeout", "60" },
                        {
                            "package", new YamlMappingNode
                            {
                                { "artifact", $"artifacts/{service.Name}-service.zip" },
                            }
                        },
                    });
                }
                break;

            case ServiceType.Http:
                functions.Add(functionName, new YamlMappingNode
                {
                    { "name", functionName },
                    { "handler", "Toxon.Micro.RabbitBlog.Serverless.HttpEntry::Toxon.Micro.RabbitBlog.Serverless.HttpEntry.FunctionImpl::FunctionHandlerAsync" },
                    { "environment", env },
                    { "memorySize", "512" },
                    { "timeout", "60" },
                    { "events", new YamlSequenceNode(BuildHttpEvent()) },
                    {
                        "package", new YamlMappingNode
                        {
                            { "artifact", $"artifacts/{service.Name}-http.zip" },
                        }
                    },
                });
                break;

            default: throw new ArgumentOutOfRangeException();
            }
        }