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); }
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(); } }