Example #1
0
        public List <JimuServiceRoute> GetServiceRoutes()
        {
            //List<JimuServiceRoute> routes = new List<JimuServiceRoute>();
            var routesMap      = new Dictionary <string, JimuServiceRoute>();
            var serviceEntries = _serviceEntryContainer.GetServiceEntry();

            serviceEntries.ForEach(entry =>
            {
                var serviceRoute = new JimuServiceRoute
                {
                    Address = new List <JimuAddress> {
                        _serviceInvokeAddress
                    },
                    ServiceDescriptor = entry.Descriptor
                };
                routesMap[serviceRoute.ServiceDescriptor.Id] = serviceRoute;
            });
            var routes = new List <JimuServiceRoute>();

            foreach (var route in routesMap.Values)
            {
                routes.Add(route);
            }
            return(routes);
        }
Example #2
0
        public override Task <JimuAddress> GetAddressAsync(JimuServiceRoute serviceRoute)
        {
            var serverIndexHolder = _addresses.GetOrAdd(serviceRoute.ServiceDescriptor.Id,
                                                        key => new Lazy <ServerIndexHolder>(() => new ServerIndexHolder()));
            var address = serverIndexHolder.Value.GetAddress(serviceRoute.Address.Where(x => x.IsHealth).ToList());

            _logger.Debug($"{serviceRoute.ServiceDescriptor.Id}, request address: {serviceRoute.ServiceDescriptor.Id}: {address.Code}");
            return(Task.FromResult(address));
        }
Example #3
0
        public async Task <JimuRemoteCallResultData> InvokeAsync(string serviceIdOrPath, IDictionary <string, object> paras, JimuPayload payload = null, string token = null, string httpMethod = null)
        {
            if (paras == null)
            {
                paras = new ConcurrentDictionary <string, object>();
            }
            JimuServiceRoute service = null;

            if (!string.IsNullOrEmpty(httpMethod))
            {
                service = await GetServiceByPathAsync(serviceIdOrPath, paras, httpMethod);
            }
            if (service == null)
            {
                service = await GetServiceByIdAsync(serviceIdOrPath);
            }
            if (service == null)
            {
                return new JimuRemoteCallResultData
                       {
                           ErrorCode = "404",
                           ErrorMsg  = $"{serviceIdOrPath}, not found!"
                       }
            }
            ;

            if (token == null && _serviceTokenGetter?.GetToken != null)
            {
                token = _serviceTokenGetter.GetToken();
            }
            var result = await InvokeAsync(service, paras, payload, token);

            if (!string.IsNullOrEmpty(result.ExceptionMessage))
            {
                return new JimuRemoteCallResultData
                       {
                           ErrorCode = "500",
                           ErrorMsg  = $"{serviceIdOrPath}, {result.ToErrorString()}"
                       }
            }
            ;

            if (string.IsNullOrEmpty(result.ErrorCode) && string.IsNullOrEmpty(result.ErrorMsg))
            {
                return(result);
            }
            if (int.TryParse(result.ErrorCode, out var erroCode) && erroCode > 200 && erroCode < 600)
            {
                return new JimuRemoteCallResultData
                       {
                           ErrorCode = result.ErrorCode,
                           ErrorMsg  = $"{serviceIdOrPath}, {result.ToErrorString()}"
                       }
            }
            ;
            return(result);
        }
Example #4
0
        public JimuServiceDesc Parse(MethodInfo methodInfo)
        {
            JimuServiceDesc desc = new JimuServiceDesc();
            var             descriptorAttributes = methodInfo.GetCustomAttributes <JimuServiceDescAttribute>();

            foreach (var attr in descriptorAttributes)
            {
                attr.Apply(desc);
            }

            if (string.IsNullOrEmpty(desc.Comment))
            {
                var xml = GetXmlComment(methodInfo.DeclaringType);
                var key = XmlCommentsMemberNameHelper.GetMemberNameForMethod(methodInfo);
                if (xml != null && xml.TryGetValue(key, out var node))
                {
                    var summaryNode = node.SelectSingleNode("summary");
                    if (summaryNode != null)
                    {
                        desc.Comment = summaryNode.Value.Trim();
                    }
                }
            }

            desc.ReturnDesc = GetReturnDesc(methodInfo);

            if (string.IsNullOrEmpty(desc.HttpMethod))
            {
                desc.HttpMethod = GetHttpMethod(methodInfo);
            }

            desc.Parameters = JimuHelper.Serialize <string>(GetParameters(methodInfo));

            if (string.IsNullOrEmpty(desc.Id))
            {
                desc.Id = JimuHelper.GenerateServiceId(methodInfo);
            }

            var type          = methodInfo.DeclaringType;
            var routeTemplate = type.GetCustomAttribute <JimuAttribute>();

            if (routeTemplate != null)
            {
                if (string.IsNullOrEmpty(desc.RoutePath))
                {
                    var setPath = string.IsNullOrEmpty(desc.Rest) ? methodInfo.Name : desc.Rest;
                    desc.ServiceClassPath = JimuServiceRoute.ParseClassPath(routeTemplate.GetTemplate(type), type.Name, type.IsInterface);
                    desc.RoutePath        = JimuServiceRoute.ParseRoutePath(desc.HttpMethod, desc.ServiceClassPath, setPath, methodInfo.GetParameters().Select(x => x.Name).ToArray(), type.IsInterface);
                }
            }

            desc.Service        = methodInfo.DeclaringType.FullName;
            desc.ServiceComment = GetServiceComment(methodInfo);
            return(desc);
        }
Example #5
0
 public RemoteCallerContext(JimuServiceRoute service, IDictionary <string, object> paras, string token, JimuAddress jimuAddress)
 {
     if (paras == null)
     {
         paras = new ConcurrentDictionary <string, object>();
     }
     this.Service        = service;
     this.Paras          = paras;
     this.Token          = token;
     this.ServiceAddress = jimuAddress;
 }
Example #6
0
        public async Task <JimuRemoteCallResultData> InvokeAsync(JimuServiceRoute service, IDictionary <string, object> paras,
                                                                 string token)
        {
            if (paras == null)
            {
                paras = new ConcurrentDictionary <string, object>();
            }
            var address = await _addressSelector.GetAddressAsyn(service);

            if (_retryTimes < 0)
            {
                _retryTimes = service.Address.Count;
            }
            JimuRemoteCallResultData result = null;
            var retryPolicy = Policy.Handle <TransportException>()
                              .RetryAsync(_retryTimes,
                                          async(ex, count) =>
            {
                address = await _addressSelector.GetAddressAsyn(service);
                _logger.Debug(
                    $"FaultHandling,retry times: {count},serviceId: {service.ServiceDescriptor.Id},Address: {address.Code},RemoteServiceCaller excute retry by Polly for exception {ex.Message}");
            });
            var fallbackPolicy = Policy <JimuRemoteCallResultData> .Handle <TransportException>()
                                 .FallbackAsync(new JimuRemoteCallResultData()
            {
                ErrorCode = "500", ErrorMsg = "error occur when communicate with server. server maybe have been down."
            })
                                 .WrapAsync(retryPolicy);

            return(await fallbackPolicy.ExecuteAsync(async() =>
            {
                var client = _transportClientFactory.CreateClient(address);
                if (client == null)
                {
                    return new JimuRemoteCallResultData
                    {
                        ErrorCode = "400",
                        ErrorMsg = "Server unavailable!"
                    }
                }
                ;
                _logger.Debug($"invoke: serviceId:{service.ServiceDescriptor.Id}, parameters count: {paras.Count()}, token:{token}");
                //Polly.Policy.Handle<>()

                result = await client.SendAsync(new JimuRemoteCallData
                {
                    Parameters = paras,
                    ServiceId = service.ServiceDescriptor.Id,
                    Token = token,
                    Descriptor = service.ServiceDescriptor
                });
                return result;
            }));
        }
Example #7
0
        public async Task <JimuRemoteCallResultData> InvokeAsync(JimuServiceRoute service, IDictionary <string, object> paras, JimuPayload payload, string token)
        {
            var lastInvoke = GetLastInvoke();

            foreach (var mid in _middlewares)
            {
                lastInvoke = mid(lastInvoke);
            }

            return(await lastInvoke(new RemoteCallerContext(service, paras, payload, token, service.Address.First())));
        }
Example #8
0
 Task <JimuAddress> IAddressSelector.GetAddressAsyn(JimuServiceRoute serviceRoute)
 {
     if (serviceRoute == null)
     {
         throw new ArgumentNullException(nameof(serviceRoute));
     }
     if (!serviceRoute.Address.Any(x => x.IsHealth))
     {
         throw new ArgumentException($"{serviceRoute.ServiceDescriptor.Id},not available server");
     }
     return(GetAddressAsync(serviceRoute));
 }
Example #9
0
        public List <JimuServiceRoute> GetServiceRoutes()
        {
            List <JimuServiceRoute> routes = new List <JimuServiceRoute>();
            var serviceEntries             = _serviceEntryContainer.GetServiceEntry();

            serviceEntries.ForEach(entry =>
            {
                var serviceRoute = new JimuServiceRoute
                {
                    Address = new List <JimuAddress> {
                        _serviceInvokeAddress
                    },
                    ServiceDescriptor = entry.Descriptor
                };
                routes.Add(serviceRoute);
            });

            return(routes);
        }
Example #10
0
        public List <JimuServiceRoute> GetServiceRoutes()
        {
            if (!_serviceRoutes.Any())
            {
                var serviceEntries = _serviceEntryContainer.GetServiceEntry();
                serviceEntries.ForEach(entry =>
                {
                    var serviceRoute = new JimuServiceRoute
                    {
                        Address = new List <JimuAddress> {
                            _address
                        },
                        ServiceDescriptor = entry.Descriptor
                    };
                    _serviceRoutes.Add(serviceRoute);
                });
            }

            return(_serviceRoutes);
        }
Example #11
0
        public List <JimuServiceRoute> GetServiceRoutes()
        {
            List <JimuServiceRoute> routes = new List <JimuServiceRoute>();
            //if (!_serviceRoutes.Any())
            //{
            var serviceEntries = _serviceEntryContainer.GetServiceEntry();

            serviceEntries.ForEach(entry =>
            {
                var serviceRoute = new JimuServiceRoute
                {
                    Address = new List <JimuAddress> {
                        new JimuAddress(_ip, _port, "Http")
                    },
                    ServiceDescriptor = entry.Descriptor
                };
                routes.Add(serviceRoute);
            });
            //}

            return(routes);
        }
Example #12
0
        public List <JimuServiceRoute> GetServiceRoutes()
        {
            if (!_serviceRoutes.Any())
            {
                var serviceEntries = _serviceEntryContainer.GetServiceEntry();
                serviceEntries.ForEach(entry =>
                {
                    var serviceRoute = new JimuServiceRoute
                    {
                        Address = new List <JimuAddress> {
                            new HttpAddress(_ip, _port)
                            {
                                IsHealth = true
                            }
                        },
                        ServiceDescriptor = entry.Descriptor
                    };
                    _serviceRoutes.Add(serviceRoute);
                });
            }

            return(_serviceRoutes);
        }
Example #13
0
        public async Task <JimuRemoteCallResultData> InvokeAsync(JimuServiceRoute service, IDictionary <string, object> paras, JimuPayload payload, string token)
        {
            var context     = new RemoteCallerContext(service, paras, payload, token, service.Address.First());
            var operationId = _jimuApm.WriteRPCExecuteBefore(context);

            try
            {
                var lastInvoke = GetLastInvoke();

                foreach (var mid in _middlewares)
                {
                    lastInvoke = mid(lastInvoke);
                }
                var result = await lastInvoke(context);

                _jimuApm.WriteRPCExecuteAfter(operationId, context, result);
                return(result);
            }
            catch (Exception ex)
            {
                _jimuApm.WriteRPCExecuteError(operationId, context, ex);
                throw ex;
            }
        }
Example #14
0
        public override void DoInit(IContainer container)
        {
            if (_options != null)
            {
                var logger = container.Resolve <ILogger>();
                logger.Info($"[config]use jose.jwt for Auth");

                //while (!container.IsRegistered<IServer>() || !container.IsRegistered<IServiceDiscovery>())
                //{
                //    Thread.Sleep(200);
                //}
                var server = container.Resolve <IServer>();
                server.UseMiddleware <JwtAuthorizationMiddleware>(_options, container);

                if (string.IsNullOrEmpty(_options.TokenEndpointPath))
                {
                    return;
                }
                var discovery  = container.Resolve <IServiceDiscovery>();
                var addr       = new JimuAddress(_options.ServiceInvokeIp, Convert.ToInt32(_options.ServiceInvokePort), _options.Protocol);
                var tokenRoute =
                    new JimuServiceRoute
                {
                    Address = new List <JimuAddress> {
                        addr
                    },
                    ServiceDescriptor = new JimuServiceDesc
                    {
                        Id         = _options.GetServiceId(),
                        Service    = "Token",
                        RoutePath  = JimuServiceRoute.ParseRoutePath("", "", _options.TokenEndpointPath, new[] { "username", "password" }, false),
                        Parameters = JimuHelper.Serialize <string>(new List <JimuServiceParameterDesc> {
                            new JimuServiceParameterDesc
                            {
                                Comment = "username",
                                Format  = "System.String",
                                Name    = "username",
                                Type    = "object"
                            },
                            new JimuServiceParameterDesc
                            {
                                Comment = "password",
                                Format  = "System.String",
                                Name    = "password",
                                Type    = "object"
                            },
                        }),
                        ReturnDesc = JimuHelper.Serialize <string>(new JimuServiceReturnDesc
                        {
                            Comment      = "Token",
                            ReturnType   = "object",
                            ReturnFormat = "{\"access_token\":\"System.String | token\", \"expired_in\":\"System.Int32 | expired timestamp which is the number of seconds between 1970-01-01 and expired datetime\"}"
                        })
                    }
                };
                //discovery.ClearServiceAsync(tokenRoute.First().ServiceDescriptor.Id).Wait();
                ////discovery.SetRoutesAsync(tokenRoute);
                //discovery.AddRouteAsync(tokenRoute).Wait();
                discovery.OnBeforeSetRoutes += (routes) =>
                {
                    routes.Add(tokenRoute);
                };
            }

            base.DoInit(container);
        }
Example #15
0
        public override void DoInit(IContainer container)
        {
            if (_options != null)
            {
                var loggerFactory = container.Resolve <ILoggerFactory>();
                var logger        = loggerFactory.Create(this.GetType());
                logger.Info($"[config]use jose.jwt for Auth");

                //while (!container.IsRegistered<IRemoteServiceCaller>() || !container.IsRegistered<IClientServiceDiscovery>())
                //{
                //    Thread.Sleep(100);
                //}

                var caller = container.Resolve <IRemoteServiceCaller>();
                caller.UseMiddleware <JwtAuthorizationMiddleware>(_options);

                if (string.IsNullOrEmpty(_options.TokenEndpointPath))
                {
                    return;
                }
                var discovery  = container.Resolve <IClientServiceDiscovery>();
                var addr       = new JimuAddress(_options.ServiceInvokeIp, Convert.ToInt32(_options.ServiceInvokePort), _options.Protocol);
                var tokenRoute = new List <JimuServiceRoute> {
                    new JimuServiceRoute
                    {
                        Address = new List <JimuAddress> {
                            addr
                        },
                        ServiceDescriptor = new JimuServiceDesc
                        {
                            Id               = _options.GetServiceId(),
                            Service          = "Token",
                            HttpMethod       = "POST",
                            AllowAnonymous   = true,
                            ServiceClassPath = "",
                            RoutePath        = JimuServiceRoute.ParseRoutePath("POST", "", _options.TokenEndpointPath, new[] { "username", "password", "grant_type" }, false),
                            Parameters       = JimuHelper.Serialize <string>(new List <JimuServiceParameterDesc> {
                                new JimuServiceParameterDesc
                                {
                                    Comment = "username",
                                    Name    = "username",
                                    Type    = "System.String"
                                },
                                new JimuServiceParameterDesc
                                {
                                    Comment = "password",
                                    Name    = "password",
                                    Type    = "System.String"
                                },
                                new JimuServiceParameterDesc
                                {
                                    Comment = "grant_type",
                                    Default = "password",
                                    Name    = "grant_type",
                                    Type    = "System.String"
                                },
                            }),
                            ReturnDesc = JimuHelper.Serialize <string>(new JimuServiceReturnDesc {
                                Comment    = "Token",
                                ReturnType = "object",
                                Properties = new List <JimuServiceParameterDesc>
                                {
                                    new JimuServiceParameterDesc {
                                        Comment = "token",
                                        Name    = "access_token",
                                        Type    = "System.String"
                                    },
                                    new JimuServiceParameterDesc {
                                        Comment = "expired timestamp which is the number of seconds between 1970-01-01 and expired datetime",
                                        Name    = "expired_in",
                                        Type    = "System.Int32"
                                    }
                                }
                            })
                        }
                    }
                };
                discovery.AddRoutesGetter(() =>
                {
                    return(Task.FromResult(tokenRoute));
                });
            }

            base.DoInit(container);
        }
Example #16
0
        public override void DoInit(IContainer container)
        {
            if (_options != null)
            {
                var logger = container.Resolve <ILogger>();
                logger.Info($"[config]use jose.jwt for Auth");

                while (!container.IsRegistered <IRemoteServiceCaller>() || !container.IsRegistered <IClientServiceDiscovery>())
                {
                    Thread.Sleep(100);
                }

                var caller = container.Resolve <IRemoteServiceCaller>();
                caller.UseMiddleware <JwtAuthorizationMiddleware>(_options);

                if (string.IsNullOrEmpty(_options.TokenEndpointPath))
                {
                    return;
                }
                var discovery  = container.Resolve <IClientServiceDiscovery>();
                var addr       = new JimuAddress(_options.ServerIp, _options.ServerPort, _options.Protocol);
                var tokenRoute = new List <JimuServiceRoute> {
                    new JimuServiceRoute
                    {
                        Address = new List <JimuAddress> {
                            addr
                        },
                        ServiceDescriptor = new JimuServiceDesc
                        {
                            Id         = _options.GetServiceId(),
                            RoutePath  = JimuServiceRoute.ParseRoutePath("", "", _options.TokenEndpointPath, new[] { "username", "password" }, false),
                            Parameters = JimuHelper.Serialize <string>(new List <JimuServiceParameterDesc> {
                                new JimuServiceParameterDesc
                                {
                                    Comment = "username",
                                    Format  = "System.String",
                                    Name    = "username",
                                    Type    = "object"
                                },
                                new JimuServiceParameterDesc
                                {
                                    Comment = "password",
                                    Format  = "System.String",
                                    Name    = "password",
                                    Type    = "object"
                                },
                            }),
                            ReturnDesc = JimuHelper.Serialize <string>(new JimuServiceReturnDesc {
                                Comment      = "Token",
                                ReturnType   = "object",
                                ReturnFormat = "{\"access_token\":\"System.String | token\", \"expired_in\":\"System.Int32 | expired timestamp which is the number of seconds between 1970-01-01 and expired datetime\"}"
                            })
                        }
                    }
                };
                discovery.AddRoutesGetter(() =>
                {
                    return(Task.FromResult(tokenRoute));
                });
            }

            base.DoInit(container);
        }
        public static IServiceHostClientBuilder UseInServerForDiscovery(this IServiceHostClientBuilder serviceHostBuilder, params JimuAddress[] address)
        {
            serviceHostBuilder.AddInitializer(container =>
            {
                var clientDiscovery = container.Resolve <IClientServiceDiscovery>();
                var remoteCaller    = container.Resolve <IRemoteServiceCaller>();
                var serializer      = container.Resolve <ISerializer>();
                var typeConverter   = container.Resolve <ITypeConvertProvider>();
                var logger          = container.Resolve <ILogger>();
                StringBuilder sb    = new StringBuilder();

                foreach (var addr in address)
                {
                    sb.AppendFormat(addr.Code + ",");
                    var service = new JimuServiceRoute
                    {
                        Address = new List <JimuAddress>
                        {
                            addr
                        },
                        ServiceDescriptor = new JimuServiceDesc {
                            Id = "Jimu.ServiceDiscovery.InServer.GetRoutesDescAsync"
                        }
                    };
                    clientDiscovery.AddRoutesGetter(async() =>
                    {
                        var result = await remoteCaller.InvokeAsync(service, null, null);
                        if (result == null || result.HasError)
                        {
                            return(null);
                        }

                        var routesDesc =
                            (List <JimuServiceRouteDesc>)typeConverter.Convert(result.Result,
                                                                               typeof(List <JimuServiceRouteDesc>));
                        var routes = new List <JimuServiceRoute>();
                        foreach (var desc in routesDesc)
                        {
                            List <JimuAddress> addresses =
                                new List <JimuAddress>(desc.AddressDescriptors.ToArray().Count());
                            foreach (var addDesc in desc.AddressDescriptors)
                            {
                                var addrType = Type.GetType(addDesc.Type);
                                addresses.Add(serializer.Deserialize(addDesc.Value, addrType) as JimuAddress);
                            }

                            routes.Add(new JimuServiceRoute()
                            {
                                ServiceDescriptor = desc.ServiceDescriptor,
                                Address           = addresses
                            });
                        }

                        return(routes);
                    });
                }
                if (sb.Length > 0)
                {
                    logger.Info($"[config]use in server for discovery, servers is {sb.ToString()}");
                }
            });

            return(serviceHostBuilder);
        }
Example #18
0
        public IServiceEntryContainer AddServices(Type[] types)
        {
            //var serviceTypes = types.Where(x =>
            //{
            //    var typeinfo = x.GetTypeInfo();
            //    return typeinfo.IsInterface && typeinfo.GetCustomAttribute<JimuServiceRouteAttribute>() != null;
            //}).Distinct();

            var serviceTypes = types
                               .Where(x => x.GetMethods().Any(y => y.GetCustomAttribute <JimuServiceAttribute>() != null)).Distinct();

            foreach (var type in serviceTypes)
            {
                var routeTemplate = type.GetCustomAttribute <JimuServiceRouteAttribute>();
                foreach (var methodInfo in type.GetTypeInfo().GetMethods().Where(x => x.GetCustomAttributes <JimuServiceDescAttribute>().Any()))
                {
                    JimuServiceDesc desc = new JimuServiceDesc();
                    var             descriptorAttributes = methodInfo.GetCustomAttributes <JimuServiceDescAttribute>();
                    foreach (var attr in descriptorAttributes)
                    {
                        attr.Apply(desc);
                    }

                    desc.ReturnDesc = GetReturnDesc(methodInfo);

                    if (string.IsNullOrEmpty(desc.HttpMethod))
                    {
                        desc.HttpMethod = GetHttpMethod(methodInfo);
                    }

                    desc.Parameters = _serializer.Serialize <string>(GetParameters(methodInfo));

                    if (string.IsNullOrEmpty(desc.Id))
                    {
                        desc.Id = _serviceIdGenerate.GenerateServiceId(methodInfo);
                    }

                    var fastInvoker = GetHandler(desc.Id, methodInfo);
                    if (routeTemplate != null)
                    {
                        desc.RoutePath = JimuServiceRoute.ParseRoutePath(routeTemplate.RouteTemplate, type.Name,
                                                                         methodInfo.Name, methodInfo.GetParameters(), type.IsInterface);
                    }

                    var service = new JimuServiceEntry
                    {
                        Descriptor = desc,
                        Func       = (paras, payload) =>
                        {
                            var instance   = GetInstance(null, methodInfo.DeclaringType, payload);
                            var parameters = new List <object>();
                            foreach (var para in methodInfo.GetParameters())
                            {
                                paras.TryGetValue(para.Name, out var value);
                                var paraType  = para.ParameterType;
                                var parameter = _typeConvertProvider.Convert(value, paraType);
                                parameters.Add(parameter);
                            }

                            var result = fastInvoker(instance, parameters.ToArray());
                            return(Task.FromResult(result));
                        }
                    };

                    _services.Add(service);
                }
            }

            return(this);
        }
Example #19
0
 public abstract Task <JimuAddress> GetAddressAsync(JimuServiceRoute serviceRoute);