You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by GitBox <gi...@apache.org> on 2021/06/18 21:11:14 UTC

[GitHub] [skywalking] wu-sheng commented on a change in pull request #7130: Feature: support endpoint name grouping by OpenAPI definitions.

wu-sheng commented on a change in pull request #7130:
URL: https://github.com/apache/skywalking/pull/7130#discussion_r654194120



##########
File path: docs/en/setup/backend/endpoint-grouping-rules.md
##########
@@ -1,15 +1,319 @@
 # Group Parameterized Endpoints
-In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution, 
+In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution,
 or configuration of meter system.
 
-There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name, 
+There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name,
 such as putting order id in the URI, like `/prod/ORDER123` and `/prod/ORDER123`. But logically, people expect they could
 have an endpoint name like `prod/{order-id}`. This is the feature of parameterized endpoint grouping designed for.
 
+If the incoming endpoint name hit the rules, SkyWalking will grouping the endpoint by rules.
+
+SkyWalking provides 2 ways to support endpoint grouping:
+1. Endpoint name grouping by OpenAPI definitions.
+2. Endpoint name grouping by custom configuration.
+
+The 2 grouping features can work together in sequence.
+## Endpoint name grouping by OpenAPI definitions
+The OpenAPI definitions are the documents based on The [OpenAPI Specification (OAS)](https://github.com/OAI/OpenAPI-Specification) which used to define a standard, language-agnostic interface for HTTP APIs.
+SkyWalking now support `OAS v2.0+)`, could parse the documents `(yaml)` and build the grouping rules from them automatically.
+
+
+### How to use
+1. Add some `Specification Extensions` for SkyWalking in the OpenAPI definition documents:<br />
+   \${METHOD} is a reserved placeholder which represents the HTTP method eg. `POST/GET...` <br />
+   \${PATH} is a reserved placeholder which represents the path eg. `/products/{id}`.
+
+   | Extension Name | Required | Description | Default Value |
+      |-----|-----|-----|-----|
+   | x-sw-service-name | true | The service name to which these endpoints belong | |
+   | x-sw-endpoint-name-match-rule | false | The rule used to match the endpoint.| \${METHOD}:\${PATH} |
+   | x-sw-endpoint-name-format | false | The endpoint name after grouping.| \${METHOD}:\${PATH} |
+
+   These extensions are under `OpenAPI Object`.
+   We highly recommend using the default config, the custom config would be considered as part of the match rules (regex pattern).
+   We provide some cases in `org.apache.skywalking.oap.server.core.config.group.openapi.EndpointGroupingRuleReader4OpenapiTest`, you could validate your custom config as well.
+
+2. Put the OpenAPI definition documents into folder `openapi-definitions`, SkyWalking could read all documents or documents in subfolders from it, so you can organize these documents by yourself. For example:
+  ```
+├── openapi-definitions
+│   ├── serviceA-api-v1
+│   │   ├── customerAPI-v1.yaml
+│   │   └── productAPI-v1.yaml
+│   └── serviceB-api-v2
+│       └── productAPI-v2.yaml
+```
+3. Turn the feature on by setting the `Core Module` configuration `${SW_CORE_ENABLE_ENDPOINT_NAME_GROUPING_BY_OPAENAPI:true}`
+
+### Rules match priority 
+We recommend designing the API path as clear as possible. If the API path is fuzzy and an endpoint name might match multiple paths, SkyWalking would follow the match priority to select one as below orders:
+1. The exact path matched first. 
+   Eg. `/products or /products/inventory`
+2. The path which has the less variables.
+   Eg. `/products/{var1}/{var2} and /products/{var1}/abc`, endpoint name `/products/123/abc` will match the second one.
+3. If the paths have the same number of variables, match the longest path, and the vars are considered to be `1`.
+   Eg. `/products/abc/{var1} and products/{var12345}/ef`, endpoint name `/products/abc/ef` will match the first one, because `length("abc") = 3` is larger than `length("ef") = 2`.
+### Examples
+If we have an OpenAPI definition doc `productAPI-v2.yaml` like this:
+```yaml
+
+openapi: 3.0.0
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+
+tags:
+  - name: product
+    description: product
+  - name: relatedProducts
+    description: Related Products
+
+paths:
+  /products:
+    get:
+      tags:
+        - product
+      summary: Get all products list
+      description: Get all products list.
+      operationId: getProducts
+      responses:
+        "200":
+          description: Success
+          content:
+            application/json:
+              schema:
+                type: array
+                items:
+                  $ref: "#/components/schemas/Product"
+  /products/{region}/{country}:
+    get:
+      tags:
+        - product
+      summary: Get products regional
+      description: Get products regional with the given id.
+      operationId: getProductRegional
+      parameters:
+        - name: region
+          in: path
+          description: Products region
+          required: true
+          schema:
+            type: string
+        - name: country
+          in: path
+          description: Products country
+          required: true
+          schema:
+            type: string
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/Product"
+        "400":
+          description: Invalid parameters supplied
+  /products/{id}:
+    get:
+      tags:
+        - product
+      summary: Get product details
+      description: Get product details with the given id.
+      operationId: getProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ProductDetails"
+        "400":
+          description: Invalid product id
+    post:
+      tags:
+        - product
+      summary: Update product details
+      description: Update product details with the given id.
+      operationId: updateProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+        - name: name
+          in: query
+          description: Product name
+          required: true
+          schema:
+            type: string
+      responses:
+        "200":
+          description: successful operation
+    delete:
+      tags:
+        - product
+      summary: Delete product details
+      description: Delete product details with the given id.
+      operationId: deleteProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+  /products/{id}/relatedProducts:
+    get:
+      tags:
+        - relatedProducts
+      summary: Get related products
+      description: Get related products with the given product id.
+      operationId: getRelatedProducts
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/RelatedProducts"
+        "400":
+          description: Invalid product id
+
+components:
+  schemas:
+    Product:
+      type: object
+      description: Product id and name
+      properties:
+        id:
+          type: integer
+          format: int64
+          description: Product id
+        name:
+          type: string
+          description: Product name
+      required:
+        - id
+        - name
+    ProductDetails:
+      type: object
+      description: Product details
+      properties:
+        id:
+          type: integer
+          format: int64
+          description: Product id
+        name:
+          type: string
+          description: Product name
+        description:
+          type: string
+          description: Product description
+      required:
+        - id
+        - name
+    RelatedProducts:
+      type: object
+      description: Related Products
+      properties:
+        id:
+          type: integer
+          format: int32
+          description: Product id
+        relatedProducts:
+          type: array
+          description: List of related products
+          items:
+            $ref: "#/components/schemas/Product"
+
+
+```
+
+Here give some scenario we might use:
+1. Only set the `x-sw-service-name`, `x-sw-endpoint-name-match-rule` and `x-sw-endpoint-name-format` are default:

Review comment:
       I think these 3 scenarios are strange to describe.

##########
File path: docs/en/setup/backend/endpoint-grouping-rules.md
##########
@@ -1,15 +1,319 @@
 # Group Parameterized Endpoints
-In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution, 
+In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution,
 or configuration of meter system.
 
-There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name, 
+There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name,
 such as putting order id in the URI, like `/prod/ORDER123` and `/prod/ORDER123`. But logically, people expect they could
 have an endpoint name like `prod/{order-id}`. This is the feature of parameterized endpoint grouping designed for.
 
+If the incoming endpoint name hit the rules, SkyWalking will grouping the endpoint by rules.
+
+SkyWalking provides 2 ways to support endpoint grouping:
+1. Endpoint name grouping by OpenAPI definitions.
+2. Endpoint name grouping by custom configuration.
+
+The 2 grouping features can work together in sequence.
+## Endpoint name grouping by OpenAPI definitions
+The OpenAPI definitions are the documents based on The [OpenAPI Specification (OAS)](https://github.com/OAI/OpenAPI-Specification) which used to define a standard, language-agnostic interface for HTTP APIs.
+SkyWalking now support `OAS v2.0+)`, could parse the documents `(yaml)` and build the grouping rules from them automatically.
+
+
+### How to use
+1. Add some `Specification Extensions` for SkyWalking in the OpenAPI definition documents:<br />
+   \${METHOD} is a reserved placeholder which represents the HTTP method eg. `POST/GET...` <br />
+   \${PATH} is a reserved placeholder which represents the path eg. `/products/{id}`.
+
+   | Extension Name | Required | Description | Default Value |
+      |-----|-----|-----|-----|
+   | x-sw-service-name | true | The service name to which these endpoints belong | |
+   | x-sw-endpoint-name-match-rule | false | The rule used to match the endpoint.| \${METHOD}:\${PATH} |
+   | x-sw-endpoint-name-format | false | The endpoint name after grouping.| \${METHOD}:\${PATH} |
+
+   These extensions are under `OpenAPI Object`.
+   We highly recommend using the default config, the custom config would be considered as part of the match rules (regex pattern).
+   We provide some cases in `org.apache.skywalking.oap.server.core.config.group.openapi.EndpointGroupingRuleReader4OpenapiTest`, you could validate your custom config as well.
+
+2. Put the OpenAPI definition documents into folder `openapi-definitions`, SkyWalking could read all documents or documents in subfolders from it, so you can organize these documents by yourself. For example:
+  ```
+├── openapi-definitions
+│   ├── serviceA-api-v1
+│   │   ├── customerAPI-v1.yaml
+│   │   └── productAPI-v1.yaml
+│   └── serviceB-api-v2
+│       └── productAPI-v2.yaml
+```
+3. Turn the feature on by setting the `Core Module` configuration `${SW_CORE_ENABLE_ENDPOINT_NAME_GROUPING_BY_OPAENAPI:true}`
+
+### Rules match priority 
+We recommend designing the API path as clear as possible. If the API path is fuzzy and an endpoint name might match multiple paths, SkyWalking would follow the match priority to select one as below orders:
+1. The exact path matched first. 
+   Eg. `/products or /products/inventory`
+2. The path which has the less variables.
+   Eg. `/products/{var1}/{var2} and /products/{var1}/abc`, endpoint name `/products/123/abc` will match the second one.
+3. If the paths have the same number of variables, match the longest path, and the vars are considered to be `1`.
+   Eg. `/products/abc/{var1} and products/{var12345}/ef`, endpoint name `/products/abc/ef` will match the first one, because `length("abc") = 3` is larger than `length("ef") = 2`.
+### Examples
+If we have an OpenAPI definition doc `productAPI-v2.yaml` like this:
+```yaml
+
+openapi: 3.0.0
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+
+tags:
+  - name: product
+    description: product
+  - name: relatedProducts
+    description: Related Products
+
+paths:
+  /products:
+    get:
+      tags:
+        - product
+      summary: Get all products list
+      description: Get all products list.
+      operationId: getProducts
+      responses:
+        "200":
+          description: Success
+          content:
+            application/json:
+              schema:
+                type: array
+                items:
+                  $ref: "#/components/schemas/Product"
+  /products/{region}/{country}:
+    get:
+      tags:
+        - product
+      summary: Get products regional
+      description: Get products regional with the given id.
+      operationId: getProductRegional
+      parameters:
+        - name: region
+          in: path
+          description: Products region
+          required: true
+          schema:
+            type: string
+        - name: country
+          in: path
+          description: Products country
+          required: true
+          schema:
+            type: string
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/Product"
+        "400":
+          description: Invalid parameters supplied
+  /products/{id}:
+    get:
+      tags:
+        - product
+      summary: Get product details
+      description: Get product details with the given id.
+      operationId: getProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ProductDetails"
+        "400":
+          description: Invalid product id
+    post:
+      tags:
+        - product
+      summary: Update product details
+      description: Update product details with the given id.
+      operationId: updateProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+        - name: name
+          in: query
+          description: Product name
+          required: true
+          schema:
+            type: string
+      responses:
+        "200":
+          description: successful operation
+    delete:
+      tags:
+        - product
+      summary: Delete product details
+      description: Delete product details with the given id.
+      operationId: deleteProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+  /products/{id}/relatedProducts:
+    get:
+      tags:
+        - relatedProducts
+      summary: Get related products
+      description: Get related products with the given product id.
+      operationId: getRelatedProducts
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/RelatedProducts"
+        "400":
+          description: Invalid product id
+
+components:
+  schemas:
+    Product:
+      type: object
+      description: Product id and name
+      properties:
+        id:
+          type: integer
+          format: int64
+          description: Product id
+        name:
+          type: string
+          description: Product name
+      required:
+        - id
+        - name
+    ProductDetails:
+      type: object
+      description: Product details
+      properties:
+        id:
+          type: integer
+          format: int64
+          description: Product id
+        name:
+          type: string
+          description: Product name
+        description:
+          type: string
+          description: Product description
+      required:
+        - id
+        - name
+    RelatedProducts:
+      type: object
+      description: Related Products
+      properties:
+        id:
+          type: integer
+          format: int32
+          description: Product id
+        relatedProducts:
+          type: array
+          description: List of related products
+          items:
+            $ref: "#/components/schemas/Product"
+
+
+```
+
+Here give some scenario we might use:
+1. Only set the `x-sw-service-name`, `x-sw-endpoint-name-match-rule` and `x-sw-endpoint-name-format` are default:
+``` yaml
+openapi: 3.0.0
+x-sw-service-name: serviceB
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+  ...
+```
+2. Set the `x-sw-service-name` , `x-sw-endpoint-name-match-rule` and `x-sw-endpoint-name-format` :
+``` yaml
+openapi: 3.0.0
+x-sw-service-name: serviceB
+x-sw-endpoint-name-match-rule: "<${METHOD}>:${PATH}"
+x-sw-endpoint-name-format: "<${METHOD}>:${PATH}"
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+  ...
+```
+3. Set the `x-sw-service-name` , `x-sw-endpoint-name-match-rule` and `x-sw-endpoint-name-format` :
+``` yaml
+openapi: 3.0.0
+x-sw-service-name: serviceB
+x-sw-endpoint-name-match-rule: "<${METHOD}>:${PATH}"
+x-sw-endpoint-name-format: "<${METHOD}>:${PATH}"

Review comment:
       Move this as an example under the table should be good enough.
   
   ![image](https://user-images.githubusercontent.com/5441976/122521441-658e1d80-d047-11eb-8db3-4694f56981d3.png)
   
   

##########
File path: docs/en/setup/backend/endpoint-grouping-rules.md
##########
@@ -1,15 +1,319 @@
 # Group Parameterized Endpoints
-In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution, 
+In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution,
 or configuration of meter system.
 
-There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name, 
+There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name,
 such as putting order id in the URI, like `/prod/ORDER123` and `/prod/ORDER123`. But logically, people expect they could
 have an endpoint name like `prod/{order-id}`. This is the feature of parameterized endpoint grouping designed for.
 
+If the incoming endpoint name hit the rules, SkyWalking will grouping the endpoint by rules.
+
+SkyWalking provides 2 ways to support endpoint grouping:
+1. Endpoint name grouping by OpenAPI definitions.
+2. Endpoint name grouping by custom configuration.
+
+The 2 grouping features can work together in sequence.
+## Endpoint name grouping by OpenAPI definitions
+The OpenAPI definitions are the documents based on The [OpenAPI Specification (OAS)](https://github.com/OAI/OpenAPI-Specification) which used to define a standard, language-agnostic interface for HTTP APIs.
+SkyWalking now support `OAS v2.0+)`, could parse the documents `(yaml)` and build the grouping rules from them automatically.
+
+
+### How to use
+1. Add some `Specification Extensions` for SkyWalking in the OpenAPI definition documents:<br />
+   \${METHOD} is a reserved placeholder which represents the HTTP method eg. `POST/GET...` <br />
+   \${PATH} is a reserved placeholder which represents the path eg. `/products/{id}`.
+
+   | Extension Name | Required | Description | Default Value |
+      |-----|-----|-----|-----|
+   | x-sw-service-name | true | The service name to which these endpoints belong | |
+   | x-sw-endpoint-name-match-rule | false | The rule used to match the endpoint.| \${METHOD}:\${PATH} |
+   | x-sw-endpoint-name-format | false | The endpoint name after grouping.| \${METHOD}:\${PATH} |
+
+   These extensions are under `OpenAPI Object`.
+   We highly recommend using the default config, the custom config would be considered as part of the match rules (regex pattern).
+   We provide some cases in `org.apache.skywalking.oap.server.core.config.group.openapi.EndpointGroupingRuleReader4OpenapiTest`, you could validate your custom config as well.
+
+2. Put the OpenAPI definition documents into folder `openapi-definitions`, SkyWalking could read all documents or documents in subfolders from it, so you can organize these documents by yourself. For example:
+  ```
+├── openapi-definitions
+│   ├── serviceA-api-v1
+│   │   ├── customerAPI-v1.yaml
+│   │   └── productAPI-v1.yaml
+│   └── serviceB-api-v2
+│       └── productAPI-v2.yaml
+```
+3. Turn the feature on by setting the `Core Module` configuration `${SW_CORE_ENABLE_ENDPOINT_NAME_GROUPING_BY_OPAENAPI:true}`
+
+### Rules match priority 
+We recommend designing the API path as clear as possible. If the API path is fuzzy and an endpoint name might match multiple paths, SkyWalking would follow the match priority to select one as below orders:
+1. The exact path matched first. 
+   Eg. `/products or /products/inventory`
+2. The path which has the less variables.
+   Eg. `/products/{var1}/{var2} and /products/{var1}/abc`, endpoint name `/products/123/abc` will match the second one.
+3. If the paths have the same number of variables, match the longest path, and the vars are considered to be `1`.
+   Eg. `/products/abc/{var1} and products/{var12345}/ef`, endpoint name `/products/abc/ef` will match the first one, because `length("abc") = 3` is larger than `length("ef") = 2`.
+### Examples
+If we have an OpenAPI definition doc `productAPI-v2.yaml` like this:
+```yaml
+
+openapi: 3.0.0
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+
+tags:
+  - name: product
+    description: product
+  - name: relatedProducts
+    description: Related Products
+
+paths:
+  /products:
+    get:
+      tags:
+        - product
+      summary: Get all products list
+      description: Get all products list.
+      operationId: getProducts
+      responses:
+        "200":
+          description: Success
+          content:
+            application/json:
+              schema:
+                type: array
+                items:
+                  $ref: "#/components/schemas/Product"
+  /products/{region}/{country}:
+    get:
+      tags:
+        - product
+      summary: Get products regional
+      description: Get products regional with the given id.
+      operationId: getProductRegional
+      parameters:
+        - name: region
+          in: path
+          description: Products region
+          required: true
+          schema:
+            type: string
+        - name: country
+          in: path
+          description: Products country
+          required: true
+          schema:
+            type: string
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/Product"
+        "400":
+          description: Invalid parameters supplied
+  /products/{id}:
+    get:
+      tags:
+        - product
+      summary: Get product details
+      description: Get product details with the given id.
+      operationId: getProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ProductDetails"
+        "400":
+          description: Invalid product id
+    post:
+      tags:
+        - product
+      summary: Update product details
+      description: Update product details with the given id.
+      operationId: updateProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+        - name: name
+          in: query
+          description: Product name
+          required: true
+          schema:
+            type: string
+      responses:
+        "200":
+          description: successful operation
+    delete:
+      tags:
+        - product
+      summary: Delete product details
+      description: Delete product details with the given id.
+      operationId: deleteProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+  /products/{id}/relatedProducts:
+    get:
+      tags:
+        - relatedProducts
+      summary: Get related products
+      description: Get related products with the given product id.
+      operationId: getRelatedProducts
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/RelatedProducts"
+        "400":
+          description: Invalid product id
+
+components:
+  schemas:
+    Product:
+      type: object
+      description: Product id and name
+      properties:
+        id:
+          type: integer
+          format: int64
+          description: Product id
+        name:
+          type: string
+          description: Product name
+      required:
+        - id
+        - name
+    ProductDetails:
+      type: object
+      description: Product details
+      properties:
+        id:
+          type: integer
+          format: int64
+          description: Product id
+        name:
+          type: string
+          description: Product name
+        description:
+          type: string
+          description: Product description
+      required:
+        - id
+        - name
+    RelatedProducts:
+      type: object
+      description: Related Products
+      properties:
+        id:
+          type: integer
+          format: int32
+          description: Product id
+        relatedProducts:
+          type: array
+          description: List of related products
+          items:
+            $ref: "#/components/schemas/Product"
+
+
+```
+
+Here give some scenario we might use:
+1. Only set the `x-sw-service-name`, `x-sw-endpoint-name-match-rule` and `x-sw-endpoint-name-format` are default:
+``` yaml
+openapi: 3.0.0
+x-sw-service-name: serviceB
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+  ...
+```
+2. Set the `x-sw-service-name` , `x-sw-endpoint-name-match-rule` and `x-sw-endpoint-name-format` :
+``` yaml
+openapi: 3.0.0
+x-sw-service-name: serviceB
+x-sw-endpoint-name-match-rule: "<${METHOD}>:${PATH}"
+x-sw-endpoint-name-format: "<${METHOD}>:${PATH}"
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+  ...
+```
+3. Set the `x-sw-service-name` , `x-sw-endpoint-name-match-rule` and `x-sw-endpoint-name-format` :
+``` yaml
+openapi: 3.0.0
+x-sw-service-name: serviceB
+x-sw-endpoint-name-match-rule: "<${METHOD}>:${PATH}"
+x-sw-endpoint-name-format: "<${METHOD}>:${PATH}"
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+  ...
+```
+
+   | Incoming Endpiont | Incoming Service | x-sw-endpoint-name-match-rule | x-sw-endpoint-name-format | Matched | Grouping Result |
+   |-----|-----|-----|-----|-----|-----|
+   | GET:/products | serviceB | default | default | true | GET:/products |
+   | GET:/products/123 | serviceB | default |default |  true | GET:/products{id} |
+   | GET:/products/asia/cn | serviceB | default | default | true | GET:/products/{region}/{country} |
+   | GET:/products/123/abc/efg | serviceB | default |default |  false | GET:/products/123/abc/efg | 
+   | \<GET\>:/products/123 | serviceB | default | default | false | \<GET\>:/products/123|
+   | GET:/products/123 | serviceC | default | default | false | GET:/products/123 |
+   | \<GET\>:/products/123 | serviceB | \<\${METHOD}\>:\${PATH} | \<\${METHOD}>:\${PATH} | true | \<GET\>:/products/{id} |
+   | GET:/products/123 | serviceB | default | ${PATH}:\<\${METHOD}\> | true | /products/{id}:\<GET\> |
+   | /products/123:\<GET\> | serviceB | ${PATH}:\<\${METHOD}\> | default | true | GET:/products/{id} |
+<br />

Review comment:
       ```suggestion
   
   ```

##########
File path: docs/en/setup/backend/endpoint-grouping-rules.md
##########
@@ -1,15 +1,319 @@
 # Group Parameterized Endpoints
-In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution, 
+In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution,
 or configuration of meter system.
 
-There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name, 
+There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name,
 such as putting order id in the URI, like `/prod/ORDER123` and `/prod/ORDER123`. But logically, people expect they could
 have an endpoint name like `prod/{order-id}`. This is the feature of parameterized endpoint grouping designed for.
 
+If the incoming endpoint name hit the rules, SkyWalking will grouping the endpoint by rules.
+
+SkyWalking provides 2 ways to support endpoint grouping:
+1. Endpoint name grouping by OpenAPI definitions.
+2. Endpoint name grouping by custom configuration.
+
+The 2 grouping features can work together in sequence.
+## Endpoint name grouping by OpenAPI definitions
+The OpenAPI definitions are the documents based on The [OpenAPI Specification (OAS)](https://github.com/OAI/OpenAPI-Specification) which used to define a standard, language-agnostic interface for HTTP APIs.
+SkyWalking now support `OAS v2.0+)`, could parse the documents `(yaml)` and build the grouping rules from them automatically.
+
+
+### How to use
+1. Add some `Specification Extensions` for SkyWalking in the OpenAPI definition documents:<br />
+   \${METHOD} is a reserved placeholder which represents the HTTP method eg. `POST/GET...` <br />
+   \${PATH} is a reserved placeholder which represents the path eg. `/products/{id}`.
+
+   | Extension Name | Required | Description | Default Value |
+      |-----|-----|-----|-----|
+   | x-sw-service-name | true | The service name to which these endpoints belong | |
+   | x-sw-endpoint-name-match-rule | false | The rule used to match the endpoint.| \${METHOD}:\${PATH} |
+   | x-sw-endpoint-name-format | false | The endpoint name after grouping.| \${METHOD}:\${PATH} |
+
+   These extensions are under `OpenAPI Object`.
+   We highly recommend using the default config, the custom config would be considered as part of the match rules (regex pattern).
+   We provide some cases in `org.apache.skywalking.oap.server.core.config.group.openapi.EndpointGroupingRuleReader4OpenapiTest`, you could validate your custom config as well.
+
+2. Put the OpenAPI definition documents into folder `openapi-definitions`, SkyWalking could read all documents or documents in subfolders from it, so you can organize these documents by yourself. For example:
+  ```
+├── openapi-definitions
+│   ├── serviceA-api-v1
+│   │   ├── customerAPI-v1.yaml
+│   │   └── productAPI-v1.yaml
+│   └── serviceB-api-v2
+│       └── productAPI-v2.yaml
+```
+3. Turn the feature on by setting the `Core Module` configuration `${SW_CORE_ENABLE_ENDPOINT_NAME_GROUPING_BY_OPAENAPI:true}`
+
+### Rules match priority 
+We recommend designing the API path as clear as possible. If the API path is fuzzy and an endpoint name might match multiple paths, SkyWalking would follow the match priority to select one as below orders:
+1. The exact path matched first. 
+   Eg. `/products or /products/inventory`
+2. The path which has the less variables.
+   Eg. `/products/{var1}/{var2} and /products/{var1}/abc`, endpoint name `/products/123/abc` will match the second one.
+3. If the paths have the same number of variables, match the longest path, and the vars are considered to be `1`.
+   Eg. `/products/abc/{var1} and products/{var12345}/ef`, endpoint name `/products/abc/ef` will match the first one, because `length("abc") = 3` is larger than `length("ef") = 2`.
+### Examples
+If we have an OpenAPI definition doc `productAPI-v2.yaml` like this:
+```yaml
+
+openapi: 3.0.0
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+
+tags:
+  - name: product
+    description: product
+  - name: relatedProducts
+    description: Related Products
+
+paths:
+  /products:
+    get:
+      tags:
+        - product
+      summary: Get all products list
+      description: Get all products list.
+      operationId: getProducts
+      responses:
+        "200":
+          description: Success
+          content:
+            application/json:
+              schema:
+                type: array
+                items:
+                  $ref: "#/components/schemas/Product"
+  /products/{region}/{country}:
+    get:
+      tags:
+        - product
+      summary: Get products regional
+      description: Get products regional with the given id.
+      operationId: getProductRegional
+      parameters:
+        - name: region
+          in: path
+          description: Products region
+          required: true
+          schema:
+            type: string
+        - name: country
+          in: path
+          description: Products country
+          required: true
+          schema:
+            type: string
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/Product"
+        "400":
+          description: Invalid parameters supplied
+  /products/{id}:
+    get:
+      tags:
+        - product
+      summary: Get product details
+      description: Get product details with the given id.
+      operationId: getProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ProductDetails"
+        "400":
+          description: Invalid product id
+    post:
+      tags:
+        - product
+      summary: Update product details
+      description: Update product details with the given id.
+      operationId: updateProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+        - name: name
+          in: query
+          description: Product name
+          required: true
+          schema:
+            type: string
+      responses:
+        "200":
+          description: successful operation
+    delete:
+      tags:
+        - product
+      summary: Delete product details
+      description: Delete product details with the given id.
+      operationId: deleteProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+  /products/{id}/relatedProducts:
+    get:
+      tags:
+        - relatedProducts
+      summary: Get related products
+      description: Get related products with the given product id.
+      operationId: getRelatedProducts
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/RelatedProducts"
+        "400":
+          description: Invalid product id
+
+components:
+  schemas:
+    Product:
+      type: object
+      description: Product id and name
+      properties:
+        id:
+          type: integer
+          format: int64
+          description: Product id
+        name:
+          type: string
+          description: Product name
+      required:
+        - id
+        - name
+    ProductDetails:
+      type: object
+      description: Product details
+      properties:
+        id:
+          type: integer
+          format: int64
+          description: Product id
+        name:
+          type: string
+          description: Product name
+        description:
+          type: string
+          description: Product description
+      required:
+        - id
+        - name
+    RelatedProducts:
+      type: object
+      description: Related Products
+      properties:
+        id:
+          type: integer
+          format: int32
+          description: Product id
+        relatedProducts:
+          type: array
+          description: List of related products
+          items:
+            $ref: "#/components/schemas/Product"
+
+
+```
+
+Here give some scenario we might use:
+1. Only set the `x-sw-service-name`, `x-sw-endpoint-name-match-rule` and `x-sw-endpoint-name-format` are default:
+``` yaml
+openapi: 3.0.0
+x-sw-service-name: serviceB
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+  ...
+```
+2. Set the `x-sw-service-name` , `x-sw-endpoint-name-match-rule` and `x-sw-endpoint-name-format` :
+``` yaml
+openapi: 3.0.0
+x-sw-service-name: serviceB
+x-sw-endpoint-name-match-rule: "<${METHOD}>:${PATH}"
+x-sw-endpoint-name-format: "<${METHOD}>:${PATH}"
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+  ...
+```
+3. Set the `x-sw-service-name` , `x-sw-endpoint-name-match-rule` and `x-sw-endpoint-name-format` :
+``` yaml
+openapi: 3.0.0
+x-sw-service-name: serviceB
+x-sw-endpoint-name-match-rule: "<${METHOD}>:${PATH}"
+x-sw-endpoint-name-format: "<${METHOD}>:${PATH}"
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+  ...
+```
+
+   | Incoming Endpiont | Incoming Service | x-sw-endpoint-name-match-rule | x-sw-endpoint-name-format | Matched | Grouping Result |
+   |-----|-----|-----|-----|-----|-----|
+   | GET:/products | serviceB | default | default | true | GET:/products |
+   | GET:/products/123 | serviceB | default |default |  true | GET:/products{id} |
+   | GET:/products/asia/cn | serviceB | default | default | true | GET:/products/{region}/{country} |
+   | GET:/products/123/abc/efg | serviceB | default |default |  false | GET:/products/123/abc/efg | 
+   | \<GET\>:/products/123 | serviceB | default | default | false | \<GET\>:/products/123|
+   | GET:/products/123 | serviceC | default | default | false | GET:/products/123 |
+   | \<GET\>:/products/123 | serviceB | \<\${METHOD}\>:\${PATH} | \<\${METHOD}>:\${PATH} | true | \<GET\>:/products/{id} |
+   | GET:/products/123 | serviceB | default | ${PATH}:\<\${METHOD}\> | true | /products/{id}:\<GET\> |
+   | /products/123:\<GET\> | serviceB | ${PATH}:\<\${METHOD}\> | default | true | GET:/products/{id} |

Review comment:
       This table is better than the above 3 cases. 

##########
File path: docs/en/setup/backend/endpoint-grouping-rules.md
##########
@@ -1,15 +1,319 @@
 # Group Parameterized Endpoints
-In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution, 
+In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution,
 or configuration of meter system.
 
-There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name, 
+There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name,
 such as putting order id in the URI, like `/prod/ORDER123` and `/prod/ORDER123`. But logically, people expect they could
 have an endpoint name like `prod/{order-id}`. This is the feature of parameterized endpoint grouping designed for.
 
+If the incoming endpoint name hit the rules, SkyWalking will grouping the endpoint by rules.
+
+SkyWalking provides 2 ways to support endpoint grouping:
+1. Endpoint name grouping by OpenAPI definitions.
+2. Endpoint name grouping by custom configuration.
+
+The 2 grouping features can work together in sequence.
+## Endpoint name grouping by OpenAPI definitions
+The OpenAPI definitions are the documents based on The [OpenAPI Specification (OAS)](https://github.com/OAI/OpenAPI-Specification) which used to define a standard, language-agnostic interface for HTTP APIs.
+SkyWalking now support `OAS v2.0+)`, could parse the documents `(yaml)` and build the grouping rules from them automatically.
+
+
+### How to use
+1. Add some `Specification Extensions` for SkyWalking in the OpenAPI definition documents:<br />
+   \${METHOD} is a reserved placeholder which represents the HTTP method eg. `POST/GET...` <br />
+   \${PATH} is a reserved placeholder which represents the path eg. `/products/{id}`.
+
+   | Extension Name | Required | Description | Default Value |
+      |-----|-----|-----|-----|
+   | x-sw-service-name | true | The service name to which these endpoints belong | |
+   | x-sw-endpoint-name-match-rule | false | The rule used to match the endpoint.| \${METHOD}:\${PATH} |
+   | x-sw-endpoint-name-format | false | The endpoint name after grouping.| \${METHOD}:\${PATH} |
+
+   These extensions are under `OpenAPI Object`.
+   We highly recommend using the default config, the custom config would be considered as part of the match rules (regex pattern).
+   We provide some cases in `org.apache.skywalking.oap.server.core.config.group.openapi.EndpointGroupingRuleReader4OpenapiTest`, you could validate your custom config as well.
+
+2. Put the OpenAPI definition documents into folder `openapi-definitions`, SkyWalking could read all documents or documents in subfolders from it, so you can organize these documents by yourself. For example:
+  ```
+├── openapi-definitions
+│   ├── serviceA-api-v1
+│   │   ├── customerAPI-v1.yaml
+│   │   └── productAPI-v1.yaml
+│   └── serviceB-api-v2
+│       └── productAPI-v2.yaml
+```
+3. Turn the feature on by setting the `Core Module` configuration `${SW_CORE_ENABLE_ENDPOINT_NAME_GROUPING_BY_OPAENAPI:true}`
+
+### Rules match priority 
+We recommend designing the API path as clear as possible. If the API path is fuzzy and an endpoint name might match multiple paths, SkyWalking would follow the match priority to select one as below orders:
+1. The exact path matched first. 
+   Eg. `/products or /products/inventory`
+2. The path which has the less variables.
+   Eg. `/products/{var1}/{var2} and /products/{var1}/abc`, endpoint name `/products/123/abc` will match the second one.
+3. If the paths have the same number of variables, match the longest path, and the vars are considered to be `1`.
+   Eg. `/products/abc/{var1} and products/{var12345}/ef`, endpoint name `/products/abc/ef` will match the first one, because `length("abc") = 3` is larger than `length("ef") = 2`.
+### Examples
+If we have an OpenAPI definition doc `productAPI-v2.yaml` like this:
+```yaml
+
+openapi: 3.0.0
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+
+tags:
+  - name: product
+    description: product
+  - name: relatedProducts
+    description: Related Products
+
+paths:
+  /products:
+    get:
+      tags:
+        - product
+      summary: Get all products list
+      description: Get all products list.
+      operationId: getProducts
+      responses:
+        "200":
+          description: Success
+          content:
+            application/json:
+              schema:
+                type: array
+                items:
+                  $ref: "#/components/schemas/Product"
+  /products/{region}/{country}:
+    get:
+      tags:
+        - product
+      summary: Get products regional
+      description: Get products regional with the given id.
+      operationId: getProductRegional
+      parameters:
+        - name: region
+          in: path
+          description: Products region
+          required: true
+          schema:
+            type: string
+        - name: country
+          in: path
+          description: Products country
+          required: true
+          schema:
+            type: string
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/Product"
+        "400":
+          description: Invalid parameters supplied
+  /products/{id}:
+    get:
+      tags:
+        - product
+      summary: Get product details
+      description: Get product details with the given id.
+      operationId: getProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ProductDetails"
+        "400":
+          description: Invalid product id
+    post:
+      tags:
+        - product
+      summary: Update product details
+      description: Update product details with the given id.
+      operationId: updateProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+        - name: name
+          in: query
+          description: Product name
+          required: true
+          schema:
+            type: string
+      responses:
+        "200":
+          description: successful operation
+    delete:
+      tags:
+        - product
+      summary: Delete product details
+      description: Delete product details with the given id.
+      operationId: deleteProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+  /products/{id}/relatedProducts:
+    get:
+      tags:
+        - relatedProducts
+      summary: Get related products
+      description: Get related products with the given product id.
+      operationId: getRelatedProducts
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/RelatedProducts"
+        "400":
+          description: Invalid product id
+
+components:
+  schemas:
+    Product:
+      type: object
+      description: Product id and name
+      properties:
+        id:
+          type: integer
+          format: int64
+          description: Product id
+        name:
+          type: string
+          description: Product name
+      required:
+        - id
+        - name
+    ProductDetails:
+      type: object
+      description: Product details
+      properties:
+        id:
+          type: integer
+          format: int64
+          description: Product id
+        name:
+          type: string
+          description: Product name
+        description:
+          type: string
+          description: Product description
+      required:
+        - id
+        - name
+    RelatedProducts:
+      type: object
+      description: Related Products
+      properties:
+        id:
+          type: integer
+          format: int32
+          description: Product id
+        relatedProducts:
+          type: array
+          description: List of related products
+          items:
+            $ref: "#/components/schemas/Product"
+
+
+```
+
+Here give some scenario we might use:
+1. Only set the `x-sw-service-name`, `x-sw-endpoint-name-match-rule` and `x-sw-endpoint-name-format` are default:
+``` yaml
+openapi: 3.0.0
+x-sw-service-name: serviceB
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+  ...
+```
+2. Set the `x-sw-service-name` , `x-sw-endpoint-name-match-rule` and `x-sw-endpoint-name-format` :
+``` yaml
+openapi: 3.0.0
+x-sw-service-name: serviceB
+x-sw-endpoint-name-match-rule: "<${METHOD}>:${PATH}"
+x-sw-endpoint-name-format: "<${METHOD}>:${PATH}"
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+  ...
+```
+3. Set the `x-sw-service-name` , `x-sw-endpoint-name-match-rule` and `x-sw-endpoint-name-format` :
+``` yaml
+openapi: 3.0.0
+x-sw-service-name: serviceB
+x-sw-endpoint-name-match-rule: "<${METHOD}>:${PATH}"
+x-sw-endpoint-name-format: "<${METHOD}>:${PATH}"
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+  ...
+```
+
+   | Incoming Endpiont | Incoming Service | x-sw-endpoint-name-match-rule | x-sw-endpoint-name-format | Matched | Grouping Result |
+   |-----|-----|-----|-----|-----|-----|
+   | GET:/products | serviceB | default | default | true | GET:/products |
+   | GET:/products/123 | serviceB | default |default |  true | GET:/products{id} |
+   | GET:/products/asia/cn | serviceB | default | default | true | GET:/products/{region}/{country} |
+   | GET:/products/123/abc/efg | serviceB | default |default |  false | GET:/products/123/abc/efg | 
+   | \<GET\>:/products/123 | serviceB | default | default | false | \<GET\>:/products/123|
+   | GET:/products/123 | serviceC | default | default | false | GET:/products/123 |
+   | \<GET\>:/products/123 | serviceB | \<\${METHOD}\>:\${PATH} | \<\${METHOD}>:\${PATH} | true | \<GET\>:/products/{id} |
+   | GET:/products/123 | serviceB | default | ${PATH}:\<\${METHOD}\> | true | /products/{id}:\<GET\> |
+   | /products/123:\<GET\> | serviceB | ${PATH}:\<\${METHOD}\> | default | true | GET:/products/{id} |

Review comment:
       I am wondering the point of `\` too

##########
File path: docs/en/setup/backend/endpoint-grouping-rules.md
##########
@@ -1,15 +1,319 @@
 # Group Parameterized Endpoints
-In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution, 
+In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution,
 or configuration of meter system.
 
-There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name, 
+There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name,
 such as putting order id in the URI, like `/prod/ORDER123` and `/prod/ORDER123`. But logically, people expect they could
 have an endpoint name like `prod/{order-id}`. This is the feature of parameterized endpoint grouping designed for.
 
+If the incoming endpoint name hit the rules, SkyWalking will grouping the endpoint by rules.
+
+SkyWalking provides 2 ways to support endpoint grouping:
+1. Endpoint name grouping by OpenAPI definitions.
+2. Endpoint name grouping by custom configuration.
+
+The 2 grouping features can work together in sequence.
+## Endpoint name grouping by OpenAPI definitions
+The OpenAPI definitions are the documents based on The [OpenAPI Specification (OAS)](https://github.com/OAI/OpenAPI-Specification) which used to define a standard, language-agnostic interface for HTTP APIs.
+SkyWalking now support `OAS v2.0+)`, could parse the documents `(yaml)` and build the grouping rules from them automatically.
+
+
+### How to use
+1. Add some `Specification Extensions` for SkyWalking in the OpenAPI definition documents:<br />
+   \${METHOD} is a reserved placeholder which represents the HTTP method eg. `POST/GET...` <br />
+   \${PATH} is a reserved placeholder which represents the path eg. `/products/{id}`.
+
+   | Extension Name | Required | Description | Default Value |
+      |-----|-----|-----|-----|
+   | x-sw-service-name | true | The service name to which these endpoints belong | |
+   | x-sw-endpoint-name-match-rule | false | The rule used to match the endpoint.| \${METHOD}:\${PATH} |
+   | x-sw-endpoint-name-format | false | The endpoint name after grouping.| \${METHOD}:\${PATH} |
+
+   These extensions are under `OpenAPI Object`.
+   We highly recommend using the default config, the custom config would be considered as part of the match rules (regex pattern).
+   We provide some cases in `org.apache.skywalking.oap.server.core.config.group.openapi.EndpointGroupingRuleReader4OpenapiTest`, you could validate your custom config as well.
+
+2. Put the OpenAPI definition documents into folder `openapi-definitions`, SkyWalking could read all documents or documents in subfolders from it, so you can organize these documents by yourself. For example:
+  ```
+├── openapi-definitions
+│   ├── serviceA-api-v1
+│   │   ├── customerAPI-v1.yaml
+│   │   └── productAPI-v1.yaml
+│   └── serviceB-api-v2
+│       └── productAPI-v2.yaml
+```
+3. Turn the feature on by setting the `Core Module` configuration `${SW_CORE_ENABLE_ENDPOINT_NAME_GROUPING_BY_OPAENAPI:true}`
+
+### Rules match priority 
+We recommend designing the API path as clear as possible. If the API path is fuzzy and an endpoint name might match multiple paths, SkyWalking would follow the match priority to select one as below orders:
+1. The exact path matched first. 
+   Eg. `/products or /products/inventory`
+2. The path which has the less variables.
+   Eg. `/products/{var1}/{var2} and /products/{var1}/abc`, endpoint name `/products/123/abc` will match the second one.
+3. If the paths have the same number of variables, match the longest path, and the vars are considered to be `1`.
+   Eg. `/products/abc/{var1} and products/{var12345}/ef`, endpoint name `/products/abc/ef` will match the first one, because `length("abc") = 3` is larger than `length("ef") = 2`.
+### Examples
+If we have an OpenAPI definition doc `productAPI-v2.yaml` like this:
+```yaml
+
+openapi: 3.0.0
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+
+tags:
+  - name: product
+    description: product
+  - name: relatedProducts
+    description: Related Products
+
+paths:
+  /products:
+    get:
+      tags:
+        - product
+      summary: Get all products list
+      description: Get all products list.
+      operationId: getProducts
+      responses:
+        "200":
+          description: Success
+          content:
+            application/json:
+              schema:
+                type: array
+                items:
+                  $ref: "#/components/schemas/Product"
+  /products/{region}/{country}:
+    get:
+      tags:
+        - product
+      summary: Get products regional
+      description: Get products regional with the given id.
+      operationId: getProductRegional
+      parameters:
+        - name: region
+          in: path
+          description: Products region
+          required: true
+          schema:
+            type: string
+        - name: country
+          in: path
+          description: Products country
+          required: true
+          schema:
+            type: string
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/Product"
+        "400":
+          description: Invalid parameters supplied
+  /products/{id}:
+    get:
+      tags:
+        - product
+      summary: Get product details
+      description: Get product details with the given id.
+      operationId: getProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ProductDetails"
+        "400":
+          description: Invalid product id
+    post:
+      tags:
+        - product
+      summary: Update product details
+      description: Update product details with the given id.
+      operationId: updateProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+        - name: name
+          in: query
+          description: Product name
+          required: true
+          schema:
+            type: string
+      responses:
+        "200":
+          description: successful operation
+    delete:
+      tags:
+        - product
+      summary: Delete product details
+      description: Delete product details with the given id.
+      operationId: deleteProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+  /products/{id}/relatedProducts:
+    get:
+      tags:
+        - relatedProducts
+      summary: Get related products
+      description: Get related products with the given product id.
+      operationId: getRelatedProducts
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/RelatedProducts"
+        "400":
+          description: Invalid product id
+
+components:
+  schemas:
+    Product:
+      type: object
+      description: Product id and name
+      properties:
+        id:
+          type: integer
+          format: int64
+          description: Product id
+        name:
+          type: string
+          description: Product name
+      required:
+        - id
+        - name
+    ProductDetails:
+      type: object
+      description: Product details
+      properties:
+        id:
+          type: integer
+          format: int64
+          description: Product id
+        name:
+          type: string
+          description: Product name
+        description:
+          type: string
+          description: Product description
+      required:
+        - id
+        - name
+    RelatedProducts:
+      type: object
+      description: Related Products
+      properties:
+        id:
+          type: integer
+          format: int32
+          description: Product id
+        relatedProducts:
+          type: array
+          description: List of related products
+          items:
+            $ref: "#/components/schemas/Product"
+
+
+```
+
+Here give some scenario we might use:
+1. Only set the `x-sw-service-name`, `x-sw-endpoint-name-match-rule` and `x-sw-endpoint-name-format` are default:
+``` yaml
+openapi: 3.0.0
+x-sw-service-name: serviceB
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+  ...
+```
+2. Set the `x-sw-service-name` , `x-sw-endpoint-name-match-rule` and `x-sw-endpoint-name-format` :
+``` yaml
+openapi: 3.0.0
+x-sw-service-name: serviceB
+x-sw-endpoint-name-match-rule: "<${METHOD}>:${PATH}"
+x-sw-endpoint-name-format: "<${METHOD}>:${PATH}"
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+  ...
+```
+3. Set the `x-sw-service-name` , `x-sw-endpoint-name-match-rule` and `x-sw-endpoint-name-format` :
+``` yaml
+openapi: 3.0.0
+x-sw-service-name: serviceB
+x-sw-endpoint-name-match-rule: "<${METHOD}>:${PATH}"
+x-sw-endpoint-name-format: "<${METHOD}>:${PATH}"
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+  ...
+```
+
+   | Incoming Endpiont | Incoming Service | x-sw-endpoint-name-match-rule | x-sw-endpoint-name-format | Matched | Grouping Result |
+   |-----|-----|-----|-----|-----|-----|
+   | GET:/products | serviceB | default | default | true | GET:/products |
+   | GET:/products/123 | serviceB | default |default |  true | GET:/products{id} |
+   | GET:/products/asia/cn | serviceB | default | default | true | GET:/products/{region}/{country} |
+   | GET:/products/123/abc/efg | serviceB | default |default |  false | GET:/products/123/abc/efg | 
+   | \<GET\>:/products/123 | serviceB | default | default | false | \<GET\>:/products/123|
+   | GET:/products/123 | serviceC | default | default | false | GET:/products/123 |
+   | \<GET\>:/products/123 | serviceB | \<\${METHOD}\>:\${PATH} | \<\${METHOD}>:\${PATH} | true | \<GET\>:/products/{id} |
+   | GET:/products/123 | serviceB | default | ${PATH}:\<\${METHOD}\> | true | /products/{id}:\<GET\> |
+   | /products/123:\<GET\> | serviceB | ${PATH}:\<\${METHOD}\> | default | true | GET:/products/{id} |

Review comment:
       Could you put a screenshot here to demonstrate what will be seen?

##########
File path: docs/en/setup/backend/endpoint-grouping-rules.md
##########
@@ -1,15 +1,319 @@
 # Group Parameterized Endpoints
-In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution, 
+In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution,
 or configuration of meter system.
 
-There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name, 
+There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name,
 such as putting order id in the URI, like `/prod/ORDER123` and `/prod/ORDER123`. But logically, people expect they could
 have an endpoint name like `prod/{order-id}`. This is the feature of parameterized endpoint grouping designed for.
 
+If the incoming endpoint name hit the rules, SkyWalking will grouping the endpoint by rules.
+
+SkyWalking provides 2 ways to support endpoint grouping:
+1. Endpoint name grouping by OpenAPI definitions.
+2. Endpoint name grouping by custom configuration.
+
+The 2 grouping features can work together in sequence.
+## Endpoint name grouping by OpenAPI definitions
+The OpenAPI definitions are the documents based on The [OpenAPI Specification (OAS)](https://github.com/OAI/OpenAPI-Specification) which used to define a standard, language-agnostic interface for HTTP APIs.
+SkyWalking now support `OAS v2.0+)`, could parse the documents `(yaml)` and build the grouping rules from them automatically.
+
+
+### How to use
+1. Add some `Specification Extensions` for SkyWalking in the OpenAPI definition documents:<br />
+   \${METHOD} is a reserved placeholder which represents the HTTP method eg. `POST/GET...` <br />
+   \${PATH} is a reserved placeholder which represents the path eg. `/products/{id}`.
+
+   | Extension Name | Required | Description | Default Value |
+      |-----|-----|-----|-----|
+   | x-sw-service-name | true | The service name to which these endpoints belong | |
+   | x-sw-endpoint-name-match-rule | false | The rule used to match the endpoint.| \${METHOD}:\${PATH} |
+   | x-sw-endpoint-name-format | false | The endpoint name after grouping.| \${METHOD}:\${PATH} |
+
+   These extensions are under `OpenAPI Object`.
+   We highly recommend using the default config, the custom config would be considered as part of the match rules (regex pattern).
+   We provide some cases in `org.apache.skywalking.oap.server.core.config.group.openapi.EndpointGroupingRuleReader4OpenapiTest`, you could validate your custom config as well.
+
+2. Put the OpenAPI definition documents into folder `openapi-definitions`, SkyWalking could read all documents or documents in subfolders from it, so you can organize these documents by yourself. For example:
+  ```
+├── openapi-definitions
+│   ├── serviceA-api-v1
+│   │   ├── customerAPI-v1.yaml
+│   │   └── productAPI-v1.yaml
+│   └── serviceB-api-v2
+│       └── productAPI-v2.yaml
+```
+3. Turn the feature on by setting the `Core Module` configuration `${SW_CORE_ENABLE_ENDPOINT_NAME_GROUPING_BY_OPAENAPI:true}`
+
+### Rules match priority 
+We recommend designing the API path as clear as possible. If the API path is fuzzy and an endpoint name might match multiple paths, SkyWalking would follow the match priority to select one as below orders:
+1. The exact path matched first. 
+   Eg. `/products or /products/inventory`
+2. The path which has the less variables.
+   Eg. `/products/{var1}/{var2} and /products/{var1}/abc`, endpoint name `/products/123/abc` will match the second one.
+3. If the paths have the same number of variables, match the longest path, and the vars are considered to be `1`.
+   Eg. `/products/abc/{var1} and products/{var12345}/ef`, endpoint name `/products/abc/ef` will match the first one, because `length("abc") = 3` is larger than `length("ef") = 2`.
+### Examples
+If we have an OpenAPI definition doc `productAPI-v2.yaml` like this:
+```yaml
+
+openapi: 3.0.0
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+
+tags:
+  - name: product
+    description: product
+  - name: relatedProducts
+    description: Related Products
+
+paths:
+  /products:
+    get:
+      tags:
+        - product
+      summary: Get all products list
+      description: Get all products list.
+      operationId: getProducts
+      responses:
+        "200":
+          description: Success
+          content:
+            application/json:
+              schema:
+                type: array
+                items:
+                  $ref: "#/components/schemas/Product"
+  /products/{region}/{country}:
+    get:
+      tags:
+        - product
+      summary: Get products regional
+      description: Get products regional with the given id.
+      operationId: getProductRegional
+      parameters:
+        - name: region
+          in: path
+          description: Products region
+          required: true
+          schema:
+            type: string
+        - name: country
+          in: path
+          description: Products country
+          required: true
+          schema:
+            type: string
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/Product"
+        "400":
+          description: Invalid parameters supplied
+  /products/{id}:
+    get:
+      tags:
+        - product
+      summary: Get product details
+      description: Get product details with the given id.
+      operationId: getProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/ProductDetails"
+        "400":
+          description: Invalid product id
+    post:
+      tags:
+        - product
+      summary: Update product details
+      description: Update product details with the given id.
+      operationId: updateProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+        - name: name
+          in: query
+          description: Product name
+          required: true
+          schema:
+            type: string
+      responses:
+        "200":
+          description: successful operation
+    delete:
+      tags:
+        - product
+      summary: Delete product details
+      description: Delete product details with the given id.
+      operationId: deleteProduct
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+  /products/{id}/relatedProducts:
+    get:
+      tags:
+        - relatedProducts
+      summary: Get related products
+      description: Get related products with the given product id.
+      operationId: getRelatedProducts
+      parameters:
+        - name: id
+          in: path
+          description: Product id
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        "200":
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/RelatedProducts"
+        "400":
+          description: Invalid product id
+
+components:
+  schemas:
+    Product:
+      type: object
+      description: Product id and name
+      properties:
+        id:
+          type: integer
+          format: int64
+          description: Product id
+        name:
+          type: string
+          description: Product name
+      required:
+        - id
+        - name
+    ProductDetails:
+      type: object
+      description: Product details
+      properties:
+        id:
+          type: integer
+          format: int64
+          description: Product id
+        name:
+          type: string
+          description: Product name
+        description:
+          type: string
+          description: Product description
+      required:
+        - id
+        - name
+    RelatedProducts:
+      type: object
+      description: Related Products
+      properties:
+        id:
+          type: integer
+          format: int32
+          description: Product id
+        relatedProducts:
+          type: array
+          description: List of related products
+          items:
+            $ref: "#/components/schemas/Product"
+
+
+```
+
+Here give some scenario we might use:
+1. Only set the `x-sw-service-name`, `x-sw-endpoint-name-match-rule` and `x-sw-endpoint-name-format` are default:
+``` yaml
+openapi: 3.0.0
+x-sw-service-name: serviceB
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+  ...
+```
+2. Set the `x-sw-service-name` , `x-sw-endpoint-name-match-rule` and `x-sw-endpoint-name-format` :
+``` yaml
+openapi: 3.0.0
+x-sw-service-name: serviceB
+x-sw-endpoint-name-match-rule: "<${METHOD}>:${PATH}"
+x-sw-endpoint-name-format: "<${METHOD}>:${PATH}"
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+  ...
+```
+3. Set the `x-sw-service-name` , `x-sw-endpoint-name-match-rule` and `x-sw-endpoint-name-format` :
+``` yaml
+openapi: 3.0.0
+x-sw-service-name: serviceB
+x-sw-endpoint-name-match-rule: "<${METHOD}>:${PATH}"
+x-sw-endpoint-name-format: "<${METHOD}>:${PATH}"
+
+info:
+  description: OpenAPI definition for SkyWalking test.
+  version: v2
+  title: Product API
+  ...
+```
+
+   | Incoming Endpiont | Incoming Service | x-sw-endpoint-name-match-rule | x-sw-endpoint-name-format | Matched | Grouping Result |
+   |-----|-----|-----|-----|-----|-----|
+   | GET:/products | serviceB | default | default | true | GET:/products |
+   | GET:/products/123 | serviceB | default |default |  true | GET:/products{id} |
+   | GET:/products/asia/cn | serviceB | default | default | true | GET:/products/{region}/{country} |
+   | GET:/products/123/abc/efg | serviceB | default |default |  false | GET:/products/123/abc/efg | 
+   | \<GET\>:/products/123 | serviceB | default | default | false | \<GET\>:/products/123|
+   | GET:/products/123 | serviceC | default | default | false | GET:/products/123 |
+   | \<GET\>:/products/123 | serviceB | \<\${METHOD}\>:\${PATH} | \<\${METHOD}>:\${PATH} | true | \<GET\>:/products/{id} |
+   | GET:/products/123 | serviceB | default | ${PATH}:\<\${METHOD}\> | true | /products/{id}:\<GET\> |
+   | /products/123:\<GET\> | serviceB | ${PATH}:\<\${METHOD}\> | default | true | GET:/products/{id} |

Review comment:
       @kezhenxu94 From the preview, it seems better to keep the current way?

##########
File path: docs/en/setup/backend/endpoint-grouping-rules.md
##########
@@ -1,15 +1,293 @@
 # Group Parameterized Endpoints
-In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution, 
+In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution,
 or configuration of meter system.
 
-There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name, 
+There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name,
 such as putting order id in the URI, like `/prod/ORDER123` and `/prod/ORDER123`. But logically, people expect they could
 have an endpoint name like `prod/{order-id}`. This is the feature of parameterized endpoint grouping designed for.
 
+If the incoming endpoint name hit the rules, SkyWalking will grouping the endpoint by rules.
+
+SkyWalking provides 2 ways to support endpoint grouping:
+1. Endpoint name grouping by OpenAPI definitions.
+2. Endpoint name grouping by custom configuration.
+
+The 2 grouping features can work together in sequence.
+## Endpoint name grouping by OpenAPI definitions
+The OpenAPI definitions are the documents based on The [OpenAPI Specification (OAS)](https://github.com/OAI/OpenAPI-Specification) which used to define a standard, language-agnostic interface for HTTP APIs.
+SkyWalking now support `OAS v2.0+)`, could parse the documents `(yaml)` and build the grouping rules from them automatically.
+
+
+### How to use
+1. Add some `Specification Extensions` for SkyWalking in the OpenAPI definition documents:<br />
+   `${METHOD}` is a reserved placeholder which represents the HTTP method eg. `POST/GET...` <br />
+   `${PATH}` is a reserved placeholder which represents the path eg. `/products/{id}`.
+
+   | Extension Name | Required | Description | Default Value |
+   |-----|-----|-----|-----|
+   | x-sw-service-name | true | The service name to which these endpoints belong | |

Review comment:
       We should make this optional, and the default should be the folder name. The reason I am asking this is, once all things are not required, `x-sw-endpoint-name-match-rule`'s default value matched our ALS rule(@kezhenxu94 it is matched, right?), we could only ask for standard OpenAPI spec file in the right folder, nothing more.

##########
File path: docs/en/setup/backend/endpoint-grouping-rules.md
##########
@@ -1,15 +1,293 @@
 # Group Parameterized Endpoints
-In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution, 
+In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution,
 or configuration of meter system.
 
-There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name, 
+There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name,
 such as putting order id in the URI, like `/prod/ORDER123` and `/prod/ORDER123`. But logically, people expect they could
 have an endpoint name like `prod/{order-id}`. This is the feature of parameterized endpoint grouping designed for.
 
+If the incoming endpoint name hit the rules, SkyWalking will grouping the endpoint by rules.
+
+SkyWalking provides 2 ways to support endpoint grouping:
+1. Endpoint name grouping by OpenAPI definitions.
+2. Endpoint name grouping by custom configuration.
+
+The 2 grouping features can work together in sequence.
+## Endpoint name grouping by OpenAPI definitions
+The OpenAPI definitions are the documents based on The [OpenAPI Specification (OAS)](https://github.com/OAI/OpenAPI-Specification) which used to define a standard, language-agnostic interface for HTTP APIs.
+SkyWalking now support `OAS v2.0+)`, could parse the documents `(yaml)` and build the grouping rules from them automatically.
+
+
+### How to use
+1. Add some `Specification Extensions` for SkyWalking in the OpenAPI definition documents:<br />
+   `${METHOD}` is a reserved placeholder which represents the HTTP method eg. `POST/GET...` <br />
+   `${PATH}` is a reserved placeholder which represents the path eg. `/products/{id}`.
+
+   | Extension Name | Required | Description | Default Value |
+   |-----|-----|-----|-----|
+   | x-sw-service-name | true | The service name to which these endpoints belong | |

Review comment:
       > But if the folder is nested,
   
   What do you mean `folder nested`? I think you should require a folder as the service name, but could use `x-sw-service-name` to override.

##########
File path: oap-server/server-library/library-util/src/main/java/org/apache/skywalking/oap/server/library/util/ResourceUtils.java
##########
@@ -58,12 +60,39 @@ public static InputStream readToStream(String fileName) throws FileNotFoundExcep
             throw new FileNotFoundException("path not found: " + parentPath);
         }
         final Set<String> nameSet = new HashSet<>(Arrays.asList(fileNames));
-        final File[] listFiles = Objects.requireNonNull(new File(url.getPath())
-            .listFiles((dir, name) -> nameSet.contains(name)), "No files in " + parentPath);
+        final File[] listFiles = Objects.requireNonNull(
+            new File(url.getPath())
+                .listFiles((dir, name) -> nameSet.contains(name)), "No files in " + parentPath);
 
         if (listFiles.length == 0) {
             throw new FileNotFoundException("files not found:" + nameSet);
         }
         return listFiles;
     }
+
+    public static List<File> getPathFilesRecursive(String path) throws FileNotFoundException {

Review comment:
       Notice, this kind of `Recursive` could easily cause OOM. Like I commented https://github.com/apache/skywalking/pull/7130#discussion_r654422789, please make the structure solid.

##########
File path: docs/en/setup/backend/endpoint-grouping-rules.md
##########
@@ -1,15 +1,293 @@
 # Group Parameterized Endpoints
-In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution, 
+In most cases, the endpoint should be detected automatically through the language agents, service mesh observability solution,
 or configuration of meter system.
 
-There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name, 
+There are some special cases, especially when people use REST style URI, the application codes put the parameter in the endpoint name,
 such as putting order id in the URI, like `/prod/ORDER123` and `/prod/ORDER123`. But logically, people expect they could
 have an endpoint name like `prod/{order-id}`. This is the feature of parameterized endpoint grouping designed for.
 
+If the incoming endpoint name hit the rules, SkyWalking will grouping the endpoint by rules.
+
+SkyWalking provides 2 ways to support endpoint grouping:
+1. Endpoint name grouping by OpenAPI definitions.
+2. Endpoint name grouping by custom configuration.
+
+The 2 grouping features can work together in sequence.
+## Endpoint name grouping by OpenAPI definitions
+The OpenAPI definitions are the documents based on The [OpenAPI Specification (OAS)](https://github.com/OAI/OpenAPI-Specification) which used to define a standard, language-agnostic interface for HTTP APIs.
+SkyWalking now support `OAS v2.0+)`, could parse the documents `(yaml)` and build the grouping rules from them automatically.
+
+
+### How to use
+1. Add some `Specification Extensions` for SkyWalking in the OpenAPI definition documents:<br />
+   `${METHOD}` is a reserved placeholder which represents the HTTP method eg. `POST/GET...` <br />
+   `${PATH}` is a reserved placeholder which represents the path eg. `/products/{id}`.
+
+   | Extension Name | Required | Description | Default Value |
+   |-----|-----|-----|-----|
+   | x-sw-service-name | true | The service name to which these endpoints belong | |

Review comment:
       Read https://github.com/apache/skywalking/pull/7130#discussion_r654422789

##########
File path: oap-server/server-library/library-util/src/main/java/org/apache/skywalking/oap/server/library/util/ResourceUtils.java
##########
@@ -58,12 +60,39 @@ public static InputStream readToStream(String fileName) throws FileNotFoundExcep
             throw new FileNotFoundException("path not found: " + parentPath);
         }
         final Set<String> nameSet = new HashSet<>(Arrays.asList(fileNames));
-        final File[] listFiles = Objects.requireNonNull(new File(url.getPath())
-            .listFiles((dir, name) -> nameSet.contains(name)), "No files in " + parentPath);
+        final File[] listFiles = Objects.requireNonNull(
+            new File(url.getPath())
+                .listFiles((dir, name) -> nameSet.contains(name)), "No files in " + parentPath);
 
         if (listFiles.length == 0) {
             throw new FileNotFoundException("files not found:" + nameSet);
         }
         return listFiles;
     }
+
+    public static List<File> getPathFilesRecursive(String path) throws FileNotFoundException {

Review comment:
       We should have depth as a parameter, as in this OpenAPI case, we only need recursive depth as `1`, which means current folder and one more(service name folder).




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org