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); }
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)); }
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); }
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); }
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; }
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; })); }
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()))); }
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)); }
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); }
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); }
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); }
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); }
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; } }
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); }
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); }
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); }
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); }
public abstract Task <JimuAddress> GetAddressAsync(JimuServiceRoute serviceRoute);