예제 #1
0
        private async Task <JimuServiceRoute> GetRoute(string path)
        {
            var queryResult = await _consul.KV.Keys(path);

            if (queryResult.Response == null)
            {
                return(null);
            }
            var data = (await _consul.KV.Get(path)).Response?.Value;

            if (data == null)
            {
                return(null);
            }
            var descriptor = JimuHelper.Deserialize <byte[], JimuServiceRouteDesc>(data);

            List <JimuAddress> addresses = new List <JimuAddress>(descriptor.AddressDescriptors.ToArray().Count());

            foreach (var addDesc in descriptor.AddressDescriptors)
            {
                //var addrType = Type.GetType(addDesc.Type);
                addresses.Add(JimuHelper.Deserialize(addDesc.Value, typeof(JimuAddress)) as JimuAddress);
            }

            return(new JimuServiceRoute
            {
                Address = addresses,
                ServiceDescriptor = descriptor.ServiceDescriptor
            });
        }
예제 #2
0
        public static async Task <JimuRemoteCallResultData> Invoke(string path, IDictionary <string, object> paras)
        {
            var remoteServiceInvoker = Host.Container.Resolve <IRemoteServiceCaller>();
            var result = await remoteServiceInvoker.InvokeAsync(path, paras);

            if (!string.IsNullOrEmpty(result.ExceptionMessage))
            {
                throw new JimuHttpStatusCodeException(400, $"{result.ToErrorString()}", path);
            }

            if (!string.IsNullOrEmpty(result.ErrorCode) || !string.IsNullOrEmpty(result.ErrorMsg))
            {
                if (int.TryParse(result.ErrorCode, out int erroCode) && erroCode > 200 && erroCode < 600)
                {
                    throw new JimuHttpStatusCodeException(erroCode, result.ToErrorString(), path);
                }

                return(new JimuRemoteCallResultData {
                    ErrorCode = result.ErrorCode, ErrorMsg = result.ErrorMsg
                });
            }
            //if (result.ResultType == typeof(JimuFile).ToString())
            if (result?.ResultType != null && result.ResultType.StartsWith("{\"ReturnType\":\"Jimu.JimuFile\""))
            {
                var file = JimuHelper.Deserialize(result.Result, typeof(JimuFile));
                result.Result = file;
            }

            return(result);
        }
예제 #3
0
        public override void ChannelRead(IChannelHandlerContext context, object message)
        {
            var buffer = (IByteBuffer)message;

            try
            {
                byte[] data = new byte[buffer.ReadableBytes];
                buffer.GetBytes(buffer.ReaderIndex, data);

                _logger.Debug($"received msg is: {Encoding.UTF8.GetString(data)}");
                var convertedMsg = JimuHelper.Deserialize <byte[], JimuTransportMsg>(data);
                if (convertedMsg.ContentType == typeof(JimuRemoteCallData).FullName)
                {
                    convertedMsg.Content = JimuHelper.Deserialize <string, JimuRemoteCallData>(convertedMsg.Content.ToString());
                }
                else if (convertedMsg.ContentType == typeof(JimuRemoteCallData).FullName)
                {
                    convertedMsg.Content = JimuHelper.Deserialize <string, JimuRemoteCallResultData>(convertedMsg.Content.ToString());
                }
                context.FireChannelRead(convertedMsg);
            }
            finally
            {
                buffer.Release();
            }
            //base.ChannelRead(context, message);
        }
        public override void ChannelRead(IChannelHandlerContext context, object message)
        {
            var buffer = (IByteBuffer)message;

            try
            {
                byte[] data = new byte[buffer.ReadableBytes];
                buffer.GetBytes(buffer.ReaderIndex, data);

                if (data.Length < 102400)
                {
                    _logger.Debug($"recevied msg is: {Encoding.UTF8.GetString(data)}");
                }
                else
                {
                    _logger.Debug($"recevied msg is (bigger than 100k, we don't show it)");
                }
                var convertedMsg = JimuHelper.Deserialize <byte[], JimuTransportMsg>(data);
                context.FireChannelRead(convertedMsg);
                //context.FireChannelRead(data);
            }
            catch (Exception ex)
            {
                _logger.Debug($"Deserialize msg failure");
                context.WriteAndFlushAsync(Encoding.UTF8.GetBytes($"failure, {ex.ToStackTraceString()}"));
            }
            finally
            {
                buffer.Release();
            }
            //base.ChannelRead(context, message);
        }
예제 #5
0
        Task InvokeService(RemoteCallerContext context)
        {
            try
            {
                var pureToken = context.RemoteInvokeMessage.Token;
                if (pureToken != null && pureToken.Trim().StartsWith("Bearer "))
                {
                    pureToken = pureToken.Trim().Substring(6).Trim();
                }
                var payload    = JWT.Decode(pureToken, Encoding.ASCII.GetBytes(_options.SecretKey), JwsAlgorithm.HS256);
                var payloadObj = JimuHelper.Deserialize(payload, typeof(IDictionary <string, object>)) as IDictionary <string, object>;
                if (_options.ValidateLifetime)
                {
                    //var exp = payloadObj["exp"];
                    if (payloadObj == null || ((Int64)payloadObj["exp"]).ToDate() < DateTime.Now)
                    {
                        var result = new JimuRemoteCallResultData
                        {
                            ErrorMsg  = "Token is Expired",
                            ErrorCode = "401"
                        };
                        return(context.Response.WriteAsync(context.TransportMessage.Id, result));
                    }
                }
                var serviceRoles = context.ServiceEntry.Descriptor.Roles;
                if (!string.IsNullOrEmpty(serviceRoles))
                {
                    var serviceRoleArr = serviceRoles.Split(',');
                    var roles          = payloadObj != null && payloadObj.ContainsKey("roles") ? payloadObj["roles"] + "" : "";
                    var authorize      = roles.Split(',').Any(role => serviceRoleArr.Any(x => x.Equals(role, StringComparison.InvariantCultureIgnoreCase)));
                    if (!authorize)
                    {
                        var result = new JimuRemoteCallResultData
                        {
                            ErrorMsg  = "Unauthorized",
                            ErrorCode = "401"
                        };
                        return(context.Response.WriteAsync(context.TransportMessage.Id, result));
                    }
                }
                context.RemoteInvokeMessage.Payload = new JimuPayload {
                    Items = payloadObj
                };
            }
            catch (Exception ex)
            {
                var result = new JimuRemoteCallResultData
                {
                    ErrorMsg  = $"Token is incorrect, exception is { ex.Message}",
                    ErrorCode = "401"
                };
                return(context.Response.WriteAsync(context.TransportMessage.Id, result));
            }

            return(_next(context));
        }
예제 #6
0
        public static IServiceHostClientBuilder UseConsulForDiscovery(this IServiceHostClientBuilder serviceHostBuilder,
                                                                      string ip, int port, string serviceCategory)
        {
            serviceHostBuilder.AddInitializer(container =>
            {
                var logger = container.Resolve <ILogger>();
                logger.Info($"[config]use consul for services discovery, consul ip: {ip}:{port}, service cateogry: {serviceCategory}");

                var clientDiscovery = container.Resolve <IClientServiceDiscovery>();
                clientDiscovery.AddRoutesGetter(async() =>
                {
                    var consul      = new ConsulClient(config => { config.Address = new Uri($"http://{ip}:{port}"); });
                    var queryResult = await consul.KV.Keys(serviceCategory);
                    var keys        = queryResult.Response;
                    if (keys == null)
                    {
                        return(null);
                    }

                    var routes = new List <JimuServiceRoute>();
                    foreach (var key in keys)
                    {
                        var data = (await consul.KV.Get(key)).Response?.Value;
                        if (data == null)
                        {
                            continue;
                        }

                        var descriptors = JimuHelper.Deserialize <byte[], List <JimuServiceRouteDesc> >(data);
                        if (descriptors != null && descriptors.Any())
                        {
                            foreach (var descriptor in descriptors)
                            {
                                List <JimuAddress> addresses =
                                    new List <JimuAddress>(descriptor.AddressDescriptors.ToArray().Count());
                                foreach (var addDesc in descriptor.AddressDescriptors)
                                {
                                    var addrType = Type.GetType(addDesc.Type);
                                    addresses.Add(JimuHelper.Deserialize(addDesc.Value, addrType) as JimuAddress);
                                }

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

                    return(routes);
                });
            });

            return(serviceHostBuilder);
        }
예제 #7
0
        public async Task <List <JimuServiceRoute> > RefreshRoutesAsync()
        {
            this._routes.Clear();
            foreach (var keyPattern in this.GetKey(""))
            {
                var queryResult = await _consul.KV.List(keyPattern);

                var response = queryResult.Response;
                if (response == null)
                {
                    continue;
                }
                foreach (var key in response)
                {
                    if (key.Value == null)
                    {
                        continue;
                    }

                    var descriptors = JimuHelper.Deserialize <byte[], List <JimuServiceRouteDesc> >(key.Value);
                    if (descriptors != null && descriptors.Any())
                    {
                        foreach (var descriptor in descriptors)
                        {
                            if (_routes.Any(x => x.ServiceDescriptor.Id == descriptor.ServiceDescriptor.Id))
                            {
                                continue;
                            }
                            List <JimuAddress> addresses = new List <JimuAddress>(descriptor.AddressDescriptors.ToArray().Count());
                            foreach (var addDesc in descriptor.AddressDescriptors)
                            {
                                //var addrType = Type.GetType(addDesc.Type);
                                addresses.Add(JimuHelper.Deserialize(addDesc.Value, typeof(JimuAddress)) as JimuAddress);
                            }

                            _routes.Add(new JimuServiceRoute
                            {
                                Address           = addresses,
                                ServiceDescriptor = descriptor.ServiceDescriptor
                            });
                        }
                    }
                }
            }


            return(_routes);
        }
예제 #8
0
        public async Task <List <JimuServiceRoute> > GetRoutesAsync()
        {
            if (_routes != null && _routes.Any())
            {
                return(_routes.ToList());
            }
            byte[] data = null;
            foreach (var key in GetKey())
            {
                data = (await _consul.KV.Get(key)).Response?.Value;
                if (data != null && data.Length > 0)
                {
                    break;
                }
            }

            if (data == null)
            {
                return(_routes);
            }

            var descriptors = JimuHelper.Deserialize <byte[], List <JimuServiceRouteDesc> >(data);

            if (descriptors != null && descriptors.Any())
            {
                foreach (var descriptor in descriptors)
                {
                    List <JimuAddress> addresses = new List <JimuAddress>(descriptor.AddressDescriptors.ToArray().Count());
                    foreach (var addDesc in descriptor.AddressDescriptors)
                    {
                        //var addrType = Type.GetType(addDesc.Type);
                        addresses.Add(JimuHelper.Deserialize(addDesc.Value, typeof(JimuAddress)) as JimuAddress);
                    }

                    _routes.Add(new JimuServiceRoute
                    {
                        Address           = addresses,
                        ServiceDescriptor = descriptor.ServiceDescriptor
                    });
                }
            }

            return(_routes);
        }
예제 #9
0
        public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
        {
            var serviceDiscovery = JimuClient.Host.Container.Resolve <IClientServiceDiscovery>();
            var routes           = serviceDiscovery.GetRoutesAsync().GetAwaiter().GetResult();
            var groupRoutes      = routes.GroupBy(x => x.ServiceDescriptor.RoutePath);

            swaggerDoc.Components.SecuritySchemes = new Dictionary <string, OpenApiSecurityScheme> {
                { "bearerAuth", new OpenApiSecurityScheme
                  {
                      Type         = SecuritySchemeType.Http,
                      In           = ParameterLocation.Header,
                      Scheme       = "bearer",
                      BearerFormat = "JWT",
                      Name         = "bearerAuth",
                      Reference    = new OpenApiReference()
                      {
                          Id   = "bearerAuth",
                          Type = ReferenceType.SecurityScheme
                      },
                      UnresolvedReference = false
                  } }
            };

            foreach (var gr in groupRoutes)
            {
                var route    = gr.Key;
                var pathItem = new OpenApiPathItem();
                foreach (var r in gr)
                {
                    var x         = r.ServiceDescriptor;
                    var paras     = new List <OpenApiParameter>();
                    var jimuParas = new List <JimuServiceParameterDesc>();
                    if (!string.IsNullOrEmpty(x.Parameters))
                    {
                        jimuParas = JimuHelper.Deserialize(TypeHelper.ReplaceTypeToJsType(x.Parameters), typeof(List <JimuServiceParameterDesc>)) as List <JimuServiceParameterDesc>;
                        paras     = GetParameters(route, jimuParas, x.HttpMethod);
                    }
                    var responses = new OpenApiResponses();
                    responses.Add("200", GetResponse(x.ReturnDesc));


                    OpenApiOperation operation = new OpenApiOperation
                    {
                        OperationId = x.RoutePath,
                        Parameters  = paras,
                        Responses   = responses,
                        Description = x.Comment,
                        Summary     = x.Comment,
                        Tags        = GetTags(x),
                        RequestBody = GetRequestBody(route, jimuParas, x.HttpMethod)
                    };
                    if (Enum.TryParse(typeof(OperationType), CultureInfo.CurrentCulture.TextInfo.ToTitleCase(x.HttpMethod.ToLower()), out var opType))
                    {
                        pathItem.AddOperation((OperationType)opType, operation);
                    }
                    if (!x.GetMetadata <bool>("AllowAnonymous"))
                    {
                        operation.Security = new List <OpenApiSecurityRequirement> {
                            new OpenApiSecurityRequirement {
                                {
                                    new OpenApiSecurityScheme {
                                        Reference = new OpenApiReference()
                                        {
                                            Id   = "bearerAuth",
                                            Type = ReferenceType.SecurityScheme
                                        },
                                        UnresolvedReference = true
                                    },
                                    new List <string>()
                                }
                            }
                        };
                    }
                }
                swaggerDoc.Paths.Add(route, pathItem);
            }
        }
예제 #10
0
        public override void DoInit(IContainer container)
        {
            if (_options != null)
            {
                var logger = container.Resolve <ILogger>();
                logger.Info($"[config]use consul for services discovery, consul ip: {_options.Ip}:{_options.Port}, service cateogry: {_options.ServiceGroups}");

                var clientDiscovery = container.Resolve <IClientServiceDiscovery>();
                clientDiscovery.AddRoutesGetter(async() =>
                {
                    var consul = new ConsulClient(config => { config.Address = new Uri($"http://{_options.Ip}:{_options.Port}"); });
                    HashSet <string> keyset = new HashSet <string>();
                    foreach (var group in _options.ServiceGroups.Split(','))
                    {
                        if (string.IsNullOrEmpty(group))
                        {
                            continue;
                        }
                        var queryResult = await consul.KV.Keys(group);
                        if (queryResult == null || queryResult.Response == null)
                        {
                            continue;
                        }

                        foreach (var key in queryResult.Response)
                        {
                            keyset.Add(key);
                        }
                    }
                    if (!keyset.Any())
                    {
                        return(null);
                    }

                    var routes = new List <JimuServiceRoute>();
                    foreach (var key in keyset)
                    {
                        var data = (await consul.KV.Get(key)).Response?.Value;
                        if (data == null)
                        {
                            continue;
                        }

                        var descriptors = JimuHelper.Deserialize <byte[], List <JimuServiceRouteDesc> >(data);
                        if (descriptors != null && descriptors.Any())
                        {
                            foreach (var descriptor in descriptors)
                            {
                                List <JimuAddress> addresses =
                                    new List <JimuAddress>(descriptor.AddressDescriptors.ToArray().Count());
                                foreach (var addDesc in descriptor.AddressDescriptors)
                                {
                                    //var addrType = Type.GetType(addDesc.Type);
                                    addresses.Add(JimuHelper.Deserialize(addDesc.Value, typeof(JimuAddress)) as JimuAddress);
                                }

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

                    return(routes);
                });
            }
            base.DoInit(container);
        }
예제 #11
0
        public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
        {
            var serviceDiscovery = JimuClient.Host.Container.Resolve <IClientServiceDiscovery>();
            var routes           = serviceDiscovery.GetRoutesAsync().GetAwaiter().GetResult();

            (from route in routes select route.ServiceDescriptor).OrderBy(x => x.RoutePath).ToList().ForEach(x =>
            {
                var subsIndex = x.RoutePath.IndexOf('?');
                subsIndex     = subsIndex < 0 ? x.RoutePath.Length : subsIndex;
                var route     = x.RoutePath.Substring(0, subsIndex);
                route         = route.StartsWith('/') ? route : "/" + route;

                var paras = new List <IParameter>();
                if (!string.IsNullOrEmpty(x.Parameters))
                {
                    var parameters = JimuHelper.Deserialize(TypeHelper.ReplaceTypeToJsType(x.Parameters), typeof(List <JimuServiceParameterDesc>)) as List <JimuServiceParameterDesc>;
                    paras          = GetParameters(parameters, x.HttpMethod);
                }

                if (x.GetMetadata <bool>("EnableAuthorization"))
                {
                    paras.Add(new NonBodyParameter
                    {
                        Name        = "Authorization",
                        Type        = "string",
                        In          = "header",
                        Description = "Token",
                        Required    = true,
                        Default     = "Bearer "
                    });
                }

                var response = new Dictionary <string, Response>();
                response.Add("200", GetResponse(x.ReturnDesc));

                if (x.HttpMethod == "GET")
                {
                    swaggerDoc.Paths.Add(route, new PathItem
                    {
                        Get = new Operation
                        {
                            Consumes = new List <string> {
                                "application/json"
                            },
                            OperationId = x.RoutePath,
                            Parameters  = paras,
                            Produces    = new List <string> {
                                "application/json"
                            },
                            Responses   = response,
                            Description = x.Comment,
                            Summary     = x.Comment,
                            Tags        = GetTags(x)
                        }
                    });
                }
                else
                {
                    swaggerDoc.Paths.Add(route, new PathItem
                    {
                        Post = new Operation
                        {
                            Consumes = new List <string> {
                                "application/json"
                            },
                            OperationId = x.RoutePath,
                            Parameters  = paras,
                            Produces    = new List <string> {
                                "application/json"
                            },
                            Responses   = response,
                            Description = x.Comment,
                            Summary     = x.Comment,
                            Tags        = GetTags(x)
                        }
                    });
                }
            });
        }
예제 #12
0
        public Task <JimuRemoteCallResultData> InvokeAsync(RemoteCallerContext context)
        {
            // get jwt token
            if (!string.IsNullOrEmpty(_options.TokenEndpointPath) &&
                context.Service.ServiceDescriptor.Id == _options.GetServiceId())
            {
                if (_options.CheckCredential == null)
                {
                    throw new Exception("JwtAuthorizationOptions.CheckCredential must be provided");
                }
                JwtAuthorizationContext jwtAuthorizationContext = new JwtAuthorizationContext(_options, context);

                _options.CheckCredential(jwtAuthorizationContext);
                if (jwtAuthorizationContext.IsRejected)
                {
                    return(Task.FromResult(new JimuRemoteCallResultData()
                    {
                        ErrorMsg = $"{jwtAuthorizationContext.Error}, {jwtAuthorizationContext.ErrorDescription}",
                        ErrorCode = "400"
                    }));
                }

                var payload = jwtAuthorizationContext.GetPayload();
                var token   = JWT.Encode(payload, Encoding.ASCII.GetBytes(_options.SecretKey), JwsAlgorithm.HS256);

                var result = new ExpandoObject() as IDictionary <string, object>;
                result["access_token"] = token;
                if (_options.ValidateLifetime)
                {
                    result["expired_in"] = payload["exp"];
                }

                return(Task.FromResult(new JimuRemoteCallResultData()
                {
                    Result = result
                }));
            }
            // jwt authentication, alse authentication the role

            if (context.Service != null && !context.Service.ServiceDescriptor.AllowAnonymous)
            {
                try
                {
                    var pureToken = context.Token;
                    if (pureToken != null && pureToken.Trim().StartsWith("Bearer "))
                    {
                        pureToken = pureToken.Trim().Substring(6).Trim();
                    }
                    var payload    = JWT.Decode(pureToken, Encoding.ASCII.GetBytes(_options.SecretKey), JwsAlgorithm.HS256);
                    var payloadObj = JimuHelper.Deserialize(payload, typeof(IDictionary <string, object>)) as IDictionary <string, object>;
                    if (_options.ValidateLifetime)
                    {
                        //var exp = payloadObj["exp"];
                        if (payloadObj == null || ((Int64)payloadObj["exp"]).ToDate() < DateTime.Now)
                        {
                            var result = new JimuRemoteCallResultData
                            {
                                ErrorMsg  = "Token is Expired",
                                ErrorCode = "401"
                            };
                            return(Task.FromResult(result));
                        }
                    }
                    var serviceRoles = context.Service.ServiceDescriptor.Roles;
                    if (!string.IsNullOrEmpty(serviceRoles))
                    {
                        var serviceRoleArr = serviceRoles.Split(',');
                        var roles          = payloadObj != null && payloadObj.ContainsKey("roles") ? payloadObj["roles"] + "" : "";
                        var authorize      = roles.Split(',').Any(role => serviceRoleArr.Any(x => x.Equals(role, StringComparison.InvariantCultureIgnoreCase)));
                        if (!authorize)
                        {
                            var result = new JimuRemoteCallResultData
                            {
                                ErrorMsg  = "Unauthorized",
                                ErrorCode = "401"
                            };
                            return(Task.FromResult(result));
                        }
                    }
                    context.PayLoad = new JimuPayload {
                        Items = payloadObj
                    };
                }
                catch (Exception ex)
                {
                    var result = new JimuRemoteCallResultData
                    {
                        ErrorMsg  = $"Token is incorrect, exception is { ex.Message}",
                        ErrorCode = "401"
                    };
                    return(Task.FromResult(result));
                }
                return(_next(context));
            }
            // service can be annoymouse request

            return(_next(context));
        }
예제 #13
0
        public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
        {
            var serviceDiscovery = JimuClient.Host.Container.Resolve <IClientServiceDiscovery>();
            var routes           = serviceDiscovery.GetRoutesAsync().GetAwaiter().GetResult();
            var groupRoutes      = routes.GroupBy(x => x.ServiceDescriptor.RoutePath);

            foreach (var gr in groupRoutes)
            {
                var route = gr.Key;
                //var subsIndex = origRoute.IndexOf('?');
                //subsIndex = subsIndex < 0 ? origRoute.Length : subsIndex;
                //var route = origRoute.Substring(0, subsIndex);
                //route = route.StartsWith('/') ? route : "/" + route;
                var pathItem = new PathItem();
                foreach (var r in gr)
                {
                    var x     = r.ServiceDescriptor;
                    var paras = new List <IParameter>();
                    if (!string.IsNullOrEmpty(x.Parameters))
                    {
                        var parameters = JimuHelper.Deserialize(TypeHelper.ReplaceTypeToJsType(x.Parameters), typeof(List <JimuServiceParameterDesc>)) as List <JimuServiceParameterDesc>;
                        paras = GetParameters(route, parameters, x.HttpMethod);
                    }

                    if (!x.GetMetadata <bool>("AllowAnonymous"))
                    {
                        paras.Add(new NonBodyParameter
                        {
                            Name        = "Authorization",
                            Type        = "string",
                            In          = "header",
                            Description = "Token",
                            Required    = true,
                            Default     = "Bearer "
                        });
                    }

                    var response = new Dictionary <string, Response>();
                    response.Add("200", GetResponse(x.ReturnDesc));

                    Operation operation = new Operation
                    {
                        Consumes = new List <string> {
                            "application/json"
                        },
                        OperationId = x.RoutePath,
                        Parameters  = paras,
                        Produces    = new List <string> {
                            "application/json"
                        },
                        Responses   = response,
                        Description = x.Comment,
                        Summary     = x.Comment,
                        Tags        = GetTags(x)
                    };
                    switch (x.HttpMethod.ToUpper())
                    {
                    case "GET":
                        pathItem.Get = operation;
                        break;

                    case "POST":
                        pathItem.Post = operation;
                        break;

                    case "PUT":
                        pathItem.Put = operation;
                        break;

                    case "DELETE":
                        pathItem.Delete = operation;
                        break;

                    case "HEAD":
                        pathItem.Head = operation;
                        break;

                    case "PATCH":
                        pathItem.Patch = operation;
                        break;

                    case "OPTIONS":
                        pathItem.Options = operation;
                        break;

                    default:
                        break;
                    }
                }
                swaggerDoc.Paths.Add(route, pathItem);
            }
        }